From 79e5555d4298c8f4602aa0f0d8565e4cfa9ec694 Mon Sep 17 00:00:00 2001 From: Paulomart Date: Wed, 2 Mar 2016 13:31:15 +0100 Subject: [PATCH 01/14] Drop MetadataPacket where metadata could not be rewritten --- .../myles/ViaVersion/transformers/OutgoingTransformer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java b/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java index 9a5dcc412..d05c602b0 100644 --- a/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java +++ b/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java @@ -516,7 +516,7 @@ public class OutgoingTransformer { return line; } - private void transformMetadata(int entityID, Object dw, ByteBuf output) { + private void transformMetadata(int entityID, Object dw, ByteBuf output) throws CancelException { // get entity try { transformMetadata(entityID, (List) ReflectionUtil.invoke(dw, "b"), output); @@ -529,11 +529,11 @@ public class OutgoingTransformer { } } - private void transformMetadata(int entityID, List dw, ByteBuf output) { + private void transformMetadata(int entityID, List dw, ByteBuf output) throws CancelException { EntityType type = clientEntityTypes.get(entityID); if (type == null) { System.out.println("Unable to get entity for ID: " + entityID); - return; + throw new CancelException(); } if (dw != null) { short id = -1; From 318db73f3c7b48eaa5421cd4da460950fc5388a7 Mon Sep 17 00:00:00 2001 From: Myles Date: Wed, 2 Mar 2016 15:21:07 +0000 Subject: [PATCH 02/14] This is a huge commit, adds ProtocolLib support. (To the best extent I can): Channels now work as proxies for the minecraft encoder and decoder, this allows better compatibility when transforming packets. ConnectionInfo now holds an activate state to deactivate. Now only 2 handlers We now use info.getChannel().pipeline().writeAndFlush to ensure we catch it ourselves. Fix EntityMetadata from last commit so it sends empty metadata instead of cancelling whole packet. Warn if they reload and don't reinject. --- .../us/myles/ViaVersion/ConnectionInfo.java | 15 +++- .../us/myles/ViaVersion/ViaVersionPlugin.java | 15 ++-- .../ViaVersion/handlers/ViaDecodeHandler.java | 48 +++++++++++++ .../ViaVersion/handlers/ViaEncodeHandler.java | 72 +++++++++++++++++++ .../handlers/ViaInboundHandler.java | 51 ------------- .../handlers/ViaOutboundHandler.java | 53 -------------- .../handlers/ViaOutboundPacketHandler.java | 43 ----------- .../handlers/ViaVersionInitializer.java | 12 ++-- .../transformers/IncomingTransformer.java | 6 +- .../transformers/OutgoingTransformer.java | 5 +- .../us/myles/ViaVersion/util/PacketUtil.java | 35 +++++---- src/main/resources/plugin.yml | 4 +- 12 files changed, 176 insertions(+), 183 deletions(-) create mode 100644 src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java create mode 100644 src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java delete mode 100644 src/main/java/us/myles/ViaVersion/handlers/ViaInboundHandler.java delete mode 100644 src/main/java/us/myles/ViaVersion/handlers/ViaOutboundHandler.java delete mode 100644 src/main/java/us/myles/ViaVersion/handlers/ViaOutboundPacketHandler.java diff --git a/src/main/java/us/myles/ViaVersion/ConnectionInfo.java b/src/main/java/us/myles/ViaVersion/ConnectionInfo.java index 7e1dd89cb..4516fe804 100644 --- a/src/main/java/us/myles/ViaVersion/ConnectionInfo.java +++ b/src/main/java/us/myles/ViaVersion/ConnectionInfo.java @@ -9,11 +9,12 @@ import java.util.UUID; public class ConnectionInfo { private final SocketChannel channel; - private int protocol = 0; - private State state = State.HANDSHAKE; - private int compression = 0; private Object lastPacket; private java.util.UUID UUID; + private State state = State.HANDSHAKE; + private int protocol = 0; + private int compression = 0; + private boolean active = true; public ConnectionInfo(SocketChannel socketChannel) { this.channel = socketChannel; @@ -66,4 +67,12 @@ public class ConnectionInfo { public SocketChannel getChannel() { return channel; } + + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } } diff --git a/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java b/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java index 20af1c3d3..ae16e3305 100644 --- a/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java +++ b/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java @@ -34,14 +34,17 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI { @Override public void onEnable() { ViaVersion.setInstance(this); - System.out.println("ViaVersion enabled, injecting. (Allows 1.8 to be accessed via 1.9)"); + if(System.getProperty("ViaVersion") != null){ + getLogger().severe("ViaVersion is already loaded, we don't support reloads. Please reboot if you wish to update."); + return; + } + + getLogger().info("ViaVersion enabled, injecting. (Allows 1.8 to be accessed via 1.9)"); try { injectPacketHandler(); + System.setProperty("ViaVersion", getDescription().getVersion()); } catch (Exception e) { - if(Bukkit.getPluginManager().getPlugin("ProtocolLib") != null){ - System.out.println("This plugin is not compatible with protocol lib."); - } - System.out.println("Unable to inject handlers, are you on 1.8? "); + getLogger().severe("Unable to inject handlers, are you on 1.8? "); e.printStackTrace(); } Bukkit.getPluginManager().registerEvents(new Listener() { @@ -59,7 +62,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI { List futures = ReflectionUtil.get(connection, "g", List.class); if (futures.size() == 0) { - throw new Exception("Could not find server to inject (late bind?)"); + throw new Exception("Could not find server to inject (Please ensure late-bind in your spigot.yml is false)"); } for (ChannelFuture future : futures) { diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java new file mode 100644 index 000000000..7b607d009 --- /dev/null +++ b/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java @@ -0,0 +1,48 @@ +package us.myles.ViaVersion.handlers; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.handler.codec.ByteToMessageDecoder; +import us.myles.ViaVersion.CancelException; +import us.myles.ViaVersion.ConnectionInfo; +import us.myles.ViaVersion.util.PacketUtil; +import us.myles.ViaVersion.transformers.IncomingTransformer; + +import java.util.List; + +public class ViaDecodeHandler extends ByteToMessageDecoder { + private final IncomingTransformer incomingTransformer; + private final ByteToMessageDecoder minecraftDecoder; + private final ConnectionInfo info; + + public ViaDecodeHandler(ConnectionInfo info, ByteToMessageDecoder minecraftDecoder) { + this.info = info; + this.minecraftDecoder = minecraftDecoder; + this.incomingTransformer = new IncomingTransformer(info); + } + + @Override + protected void decode(ChannelHandlerContext ctx, ByteBuf bytebuf, List list) throws Exception { + // use transformers + if(bytebuf.readableBytes() > 0) { + if(info.isActive()) { + int id = PacketUtil.readVarInt(bytebuf); + // Transform + ByteBuf newPacket = ctx.alloc().buffer(); + try { + incomingTransformer.transform(id, bytebuf, newPacket); + bytebuf = newPacket; + } catch (CancelException e) { + return; + } + } + // call minecraft decoder + list.addAll(PacketUtil.callDecode(this.minecraftDecoder, ctx, bytebuf)); + } + } + + +} diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java new file mode 100644 index 000000000..6dff7a4e4 --- /dev/null +++ b/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java @@ -0,0 +1,72 @@ +package us.myles.ViaVersion.handlers; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; +import io.netty.handler.codec.MessageToByteEncoder; +import us.myles.ViaVersion.CancelException; +import us.myles.ViaVersion.ConnectionInfo; +import us.myles.ViaVersion.transformers.OutgoingTransformer; +import us.myles.ViaVersion.util.PacketUtil; +import us.myles.ViaVersion.util.ReflectionUtil; + +import java.lang.reflect.Constructor; + +public class ViaEncodeHandler extends MessageToByteEncoder { + private final ConnectionInfo info; + private final MessageToByteEncoder minecraftEncoder; + private final OutgoingTransformer outgoingTransformer; + + public ViaEncodeHandler(ConnectionInfo info, MessageToByteEncoder minecraftEncoder) { + this.info = info; + this.minecraftEncoder = minecraftEncoder; + this.outgoingTransformer = new OutgoingTransformer(info); + } + + + @Override + protected void encode(ChannelHandlerContext ctx, Object o, ByteBuf bytebuf) throws Exception { + // handle the packet type + if (o == null) return; + if (!(o instanceof ByteBuf)) { + info.setLastPacket(o); + /* This transformer is more for fixing issues which we find hard at packet level :) */ + if (o.getClass().getName().endsWith("PacketPlayOutMapChunkBulk")) { + int[] locX = ReflectionUtil.get(o, "a", int[].class); + int[] locZ = ReflectionUtil.get(o, "b", int[].class); + + Object world = ReflectionUtil.get(o, "world", ReflectionUtil.nms("World")); + Class mapChunk = ReflectionUtil.nms("PacketPlayOutMapChunk"); + Constructor constructor = mapChunk.getDeclaredConstructor(ReflectionUtil.nms("Chunk"), boolean.class, int.class); + for (int i = 0; i < locX.length; i++) { + int x = locX[i]; + int z = locZ[i]; + // world invoke function + Object chunk = ReflectionUtil.nms("World").getDeclaredMethod("getChunkAt", int.class, int.class).invoke(world, x, z); + Object packet = constructor.newInstance(chunk, true, 65535); + ctx.pipeline().writeAndFlush(packet); + } + bytebuf.clear(); + return; + } + // call minecraft encoder + PacketUtil.callEncode(this.minecraftEncoder, ctx, o, bytebuf); + } + if (bytebuf.readableBytes() == 0) { + return; + } + if(info.isActive()) { + int id = PacketUtil.readVarInt(bytebuf); + // Transform + ByteBuf oldPacket = bytebuf.copy(); + bytebuf.clear(); + try { + outgoingTransformer.transform(id, oldPacket, bytebuf); + } catch (CancelException e) { + return; + } finally { + oldPacket.release(); + } + } + } + +} diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaInboundHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaInboundHandler.java deleted file mode 100644 index 8423e5dc4..000000000 --- a/src/main/java/us/myles/ViaVersion/handlers/ViaInboundHandler.java +++ /dev/null @@ -1,51 +0,0 @@ -package us.myles.ViaVersion.handlers; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; -import us.myles.ViaVersion.CancelException; -import us.myles.ViaVersion.ConnectionInfo; -import us.myles.ViaVersion.util.PacketUtil; -import us.myles.ViaVersion.transformers.IncomingTransformer; - -@ChannelHandler.Sharable -public class ViaInboundHandler extends ChannelInboundHandlerAdapter { - private final IncomingTransformer incomingTransformer; - - public ViaInboundHandler(ConnectionInfo info) { - this.incomingTransformer = new IncomingTransformer(info); - } - - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - boolean compression = ctx.pipeline().get("compress") != null; - - if (msg instanceof ByteBuf) { - ByteBuf bytebuf = (ByteBuf) msg; - if (compression) { - // decompress :) - bytebuf = PacketUtil.decompress(ctx, bytebuf); - } - int id = PacketUtil.readVarInt(bytebuf); - // Transform - ByteBuf newPacket = ctx.alloc().buffer(); - try { - incomingTransformer.transform(id, bytebuf, newPacket); - } catch (CancelException e) { - return; - } finally { - bytebuf.release(); - } - if (compression) { - // recompress :) - newPacket = PacketUtil.compress(ctx, newPacket); - } - msg = newPacket; - } - super.channelRead(ctx, msg); - } - - -} diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaOutboundHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaOutboundHandler.java deleted file mode 100644 index c42b00dfb..000000000 --- a/src/main/java/us/myles/ViaVersion/handlers/ViaOutboundHandler.java +++ /dev/null @@ -1,53 +0,0 @@ -package us.myles.ViaVersion.handlers; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.*; -import us.myles.ViaVersion.CancelException; -import us.myles.ViaVersion.ConnectionInfo; -import us.myles.ViaVersion.util.PacketUtil; -import us.myles.ViaVersion.transformers.OutgoingTransformer; - -@ChannelHandler.Sharable -public class ViaOutboundHandler extends ChannelOutboundHandlerAdapter { - private final OutgoingTransformer outgoingTransformer; - private final ConnectionInfo info; - - public ViaOutboundHandler(ConnectionInfo info) { - this.info = info; - this.outgoingTransformer = new OutgoingTransformer(info); - } - - @Override - public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise channelPromise) throws Exception { - try { - if (channelPromise.isDone()) return; // don't break any <3s - boolean compression = ctx.pipeline().get("compress") != null; - if (msg instanceof ByteBuf) { - ByteBuf bytebuf = (ByteBuf) msg; - if (compression) { - // decompress :) - bytebuf = PacketUtil.decompress(ctx, bytebuf); - } - int id = PacketUtil.readVarInt(bytebuf); - // Transform - ByteBuf newPacket = ctx.alloc().buffer(); - try { - outgoingTransformer.transform(id, bytebuf, newPacket); - } catch (CancelException e) { - return; - } finally { - bytebuf.release(); - } - if (compression) { - // recompress :) - newPacket = PacketUtil.compress(ctx, newPacket); - } - msg = newPacket; - } - super.write(ctx, msg, channelPromise); - } catch (Exception e) { - e.printStackTrace(); - } - } - -} diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaOutboundPacketHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaOutboundPacketHandler.java deleted file mode 100644 index 45ed2b823..000000000 --- a/src/main/java/us/myles/ViaVersion/handlers/ViaOutboundPacketHandler.java +++ /dev/null @@ -1,43 +0,0 @@ -package us.myles.ViaVersion.handlers; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.*; -import us.myles.ViaVersion.ConnectionInfo; -import us.myles.ViaVersion.util.ReflectionUtil; - -import java.lang.reflect.Constructor; - -@ChannelHandler.Sharable -public class ViaOutboundPacketHandler extends ChannelOutboundHandlerAdapter { - private final ConnectionInfo info; - - public ViaOutboundPacketHandler(ConnectionInfo info) { - this.info = info; - } - - @Override - public void write(ChannelHandlerContext channelHandlerContext, Object o, ChannelPromise channelPromise) throws Exception { - if (!(o instanceof ByteBuf)) { - info.setLastPacket(o); - /* This transformer is more for fixing issues which we find hard at byte level :) */ - if (o.getClass().getName().endsWith("PacketPlayOutMapChunkBulk")) { - int[] locX = ReflectionUtil.get(o, "a", int[].class); - int[] locZ = ReflectionUtil.get(o, "b", int[].class); - - Object world = ReflectionUtil.get(o, "world", ReflectionUtil.nms("World")); - Class mapChunk = ReflectionUtil.nms("PacketPlayOutMapChunk"); - Constructor constructor = mapChunk.getDeclaredConstructor(ReflectionUtil.nms("Chunk"), boolean.class, int.class); - for (int i = 0; i < locX.length; i++) { - int x = locX[i]; - int z = locZ[i]; - // world invoke function - Object chunk = ReflectionUtil.nms("World").getDeclaredMethod("getChunkAt", int.class, int.class).invoke(world, x, z); - Object packet = constructor.newInstance(chunk, true, 65535); - channelHandlerContext.write(packet); - } - return; - } - } - super.write(channelHandlerContext, o, channelPromise); - } -} diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaVersionInitializer.java b/src/main/java/us/myles/ViaVersion/handlers/ViaVersionInitializer.java index cb915227a..585ce7c48 100644 --- a/src/main/java/us/myles/ViaVersion/handlers/ViaVersionInitializer.java +++ b/src/main/java/us/myles/ViaVersion/handlers/ViaVersionInitializer.java @@ -3,6 +3,8 @@ package us.myles.ViaVersion.handlers; import io.netty.channel.Channel; import io.netty.channel.ChannelInitializer; import io.netty.channel.socket.SocketChannel; +import io.netty.handler.codec.ByteToMessageDecoder; +import io.netty.handler.codec.MessageToByteEncoder; import us.myles.ViaVersion.ConnectionInfo; import java.lang.reflect.Method; @@ -27,12 +29,10 @@ public class ViaVersionInitializer extends ChannelInitializer { // Add originals this.method.invoke(this.oldInit, socketChannel); // Add our transformers - ViaInboundHandler inbound = new ViaInboundHandler(info); - ViaOutboundHandler outbound = new ViaOutboundHandler(info); - ViaOutboundPacketHandler outbound2 = new ViaOutboundPacketHandler(info); - socketChannel.pipeline().addBefore("decoder", "via_incoming", inbound); - socketChannel.pipeline().addBefore("packet_handler", "via_outgoing2", outbound2); - socketChannel.pipeline().addBefore("encoder", "via_outgoing", outbound); + ViaEncodeHandler encoder = new ViaEncodeHandler(info, (MessageToByteEncoder) socketChannel.pipeline().get("encoder")); + ViaDecodeHandler decoder = new ViaDecodeHandler(info, (ByteToMessageDecoder) socketChannel.pipeline().get("decoder")); + socketChannel.pipeline().replace("encoder", "encoder", encoder); + socketChannel.pipeline().replace("decoder", "decoder", decoder); } } diff --git a/src/main/java/us/myles/ViaVersion/transformers/IncomingTransformer.java b/src/main/java/us/myles/ViaVersion/transformers/IncomingTransformer.java index 0fde66d16..b7c99669d 100644 --- a/src/main/java/us/myles/ViaVersion/transformers/IncomingTransformer.java +++ b/src/main/java/us/myles/ViaVersion/transformers/IncomingTransformer.java @@ -45,9 +45,7 @@ public class IncomingTransformer { if (protVer <= 102) { // not 1.9, remove pipes - info.getChannel().pipeline().remove("via_incoming"); - info.getChannel().pipeline().remove("via_outgoing"); - info.getChannel().pipeline().remove("via_outgoing2"); + info.setActive(false); } String serverAddress = PacketUtil.readString(input); PacketUtil.writeString(serverAddress, output); @@ -105,7 +103,7 @@ public class IncomingTransformer { try { Class setSlot = ReflectionUtil.nms("PacketPlayOutSetSlot"); Object setSlotPacket = setSlot.getConstructors()[1].newInstance(windowID, slot, null); - info.getChannel().writeAndFlush(setSlotPacket); // slot is empty + info.getChannel().pipeline().writeAndFlush(setSlotPacket); // slot is empty slot = -999; // we're evil, they'll throw item on the ground } catch (ClassNotFoundException e) { e.printStackTrace(); diff --git a/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java b/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java index d05c602b0..3f28e184f 100644 --- a/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java +++ b/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java @@ -290,7 +290,6 @@ public class OutgoingTransformer { int id = PacketUtil.readVarInt(input); clientEntityTypes.put(id, EntityType.EXPERIENCE_ORB); PacketUtil.writeVarInt(id, output); - double x = input.readInt(); output.writeDouble(x / 32D); double y = input.readInt(); @@ -309,7 +308,6 @@ public class OutgoingTransformer { PacketUtil.writeVarInt(id, output); PacketUtil.writeUUID(getUUID(id), output); - String title = PacketUtil.readString(input); PacketUtil.writeString(title, output); @@ -533,7 +531,8 @@ public class OutgoingTransformer { EntityType type = clientEntityTypes.get(entityID); if (type == null) { System.out.println("Unable to get entity for ID: " + entityID); - throw new CancelException(); + output.writeByte(255); + return; } if (dw != null) { short id = -1; diff --git a/src/main/java/us/myles/ViaVersion/util/PacketUtil.java b/src/main/java/us/myles/ViaVersion/util/PacketUtil.java index 8da0ede76..b6d1fa0da 100644 --- a/src/main/java/us/myles/ViaVersion/util/PacketUtil.java +++ b/src/main/java/us/myles/ViaVersion/util/PacketUtil.java @@ -42,29 +42,38 @@ public class PacketUtil { } } - public static ByteBuf decompress(ChannelHandlerContext ctx, ByteBuf msg) { - ByteToMessageDecoder x = (ByteToMessageDecoder) ctx.pipeline().get("decompress"); + public static List callDecode(ByteToMessageDecoder decoder, ChannelHandlerContext ctx, Object input) { List output = new ArrayList(); try { - PacketUtil.DECODE_METHOD.invoke(x, ctx, msg, output); + PacketUtil.DECODE_METHOD.invoke(decoder, ctx, input, output); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } + return output; + } + + public static void callEncode(MessageToByteEncoder encoder, ChannelHandlerContext ctx, Object msg, ByteBuf output) { + try { + PacketUtil.ENCODE_METHOD.invoke(encoder, ctx, msg, output); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + + public static ByteBuf decompress(ChannelHandlerContext ctx, ByteBuf msg) { + ByteToMessageDecoder x = (ByteToMessageDecoder) ctx.pipeline().get("decompress"); + List output = callDecode(x, ctx, msg); return output.size() == 0 ? null : (ByteBuf) output.get(0); } public static ByteBuf compress(ChannelHandlerContext ctx, ByteBuf msg) { MessageToByteEncoder x = (MessageToByteEncoder) ctx.pipeline().get("compress"); ByteBuf output = ctx.alloc().buffer(); - try { - PacketUtil.ENCODE_METHOD.invoke(x, ctx, msg, output); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } + callEncode(x, ctx, msg, output); return output; } @@ -185,9 +194,9 @@ public class PacketUtil { } public static void writeVarIntArray(List integers, ByteBuf output) { - writeVarInt(integers.size(),output); - for (Integer i : integers){ - writeVarInt(i,output); + writeVarInt(integers.size(), output); + for (Integer i : integers) { + writeVarInt(i, output); } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 5f2537806..9cf47154c 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,4 +1,6 @@ name: ViaVersion main: us.myles.ViaVersion.ViaVersionPlugin author: _MylesC -version: 0.3.7 \ No newline at end of file +version: 0.3.7 +load: startup +loadbefore: [ProtocolLib, ProxyPipe] \ No newline at end of file From 6c96271925587b5e9dea70f5896993cca3000b3d Mon Sep 17 00:00:00 2001 From: Myles Date: Wed, 2 Mar 2016 15:26:32 +0000 Subject: [PATCH 03/14] Bump the version, we now support ProtocolLib (hopefully it works properly) --- README.md | 4 ++-- src/main/resources/plugin.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3680556e1..6c38e17da 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# ViaVersion 0.3.7 +# ViaVersion 0.4.0 **Allows the connection of 1.8 clients to 1.9** This plugin modifies netty to allow connection of 1.9 clients to 1.8, -**Don't use late bind nor ProtocolLib** +**Don't use late bind* **As of this point it doesn't have everything, I need to fix:** diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 9cf47154c..70a1c3ed8 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: ViaVersion main: us.myles.ViaVersion.ViaVersionPlugin author: _MylesC -version: 0.3.7 +version: 0.4.0 load: startup loadbefore: [ProtocolLib, ProxyPipe] \ No newline at end of file From ccd6987f1122b3b82ea0252470af152da0a3974d Mon Sep 17 00:00:00 2001 From: Myles Date: Wed, 2 Mar 2016 17:03:32 +0000 Subject: [PATCH 04/14] Bump to 0.4.1, Fixes bungee issues :) (Some chunk stuff, me being an idiot) --- README.md | 2 +- src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java | 1 - .../java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java | 5 +---- .../java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java | 4 ++-- src/main/resources/plugin.yml | 2 +- 5 files changed, 5 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 6c38e17da..01fe4e297 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ViaVersion 0.4.0 +# ViaVersion 0.4.1 **Allows the connection of 1.8 clients to 1.9** This plugin modifies netty to allow connection of 1.9 clients to 1.8, diff --git a/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java b/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java index ae16e3305..0bdaf7820 100644 --- a/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java +++ b/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java @@ -6,7 +6,6 @@ import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import org.bukkit.Bukkit; -import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java index 7b607d009..c689c3db4 100644 --- a/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java +++ b/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java @@ -1,15 +1,12 @@ package us.myles.ViaVersion.handlers; import io.netty.buffer.ByteBuf; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; import io.netty.handler.codec.ByteToMessageDecoder; import us.myles.ViaVersion.CancelException; import us.myles.ViaVersion.ConnectionInfo; -import us.myles.ViaVersion.util.PacketUtil; import us.myles.ViaVersion.transformers.IncomingTransformer; +import us.myles.ViaVersion.util.PacketUtil; import java.util.List; diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java index 6dff7a4e4..41930556c 100644 --- a/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java +++ b/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java @@ -26,11 +26,10 @@ public class ViaEncodeHandler extends MessageToByteEncoder { @Override protected void encode(ChannelHandlerContext ctx, Object o, ByteBuf bytebuf) throws Exception { // handle the packet type - if (o == null) return; if (!(o instanceof ByteBuf)) { info.setLastPacket(o); /* This transformer is more for fixing issues which we find hard at packet level :) */ - if (o.getClass().getName().endsWith("PacketPlayOutMapChunkBulk")) { + if (o.getClass().getName().endsWith("PacketPlayOutMapChunkBulk") && info.isActive()) { int[] locX = ReflectionUtil.get(o, "a", int[].class); int[] locZ = ReflectionUtil.get(o, "b", int[].class); @@ -62,6 +61,7 @@ public class ViaEncodeHandler extends MessageToByteEncoder { try { outgoingTransformer.transform(id, oldPacket, bytebuf); } catch (CancelException e) { + bytebuf.clear(); return; } finally { oldPacket.release(); diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 70a1c3ed8..312dbc5e0 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: ViaVersion main: us.myles.ViaVersion.ViaVersionPlugin author: _MylesC -version: 0.4.0 +version: 0.4.1 load: startup loadbefore: [ProtocolLib, ProxyPipe] \ No newline at end of file From 4cdfd7270063cec71d3c78e73fd12d60780933ca Mon Sep 17 00:00:00 2001 From: Myles Date: Wed, 2 Mar 2016 18:41:47 +0000 Subject: [PATCH 05/14] Ensure no bytes are left on the bytebufs and ensure it is cancelled properly. Update Version to 0.4.2 --- README.md | 2 +- .../ViaVersion/handlers/ViaDecodeHandler.java | 15 ++++++++++++--- .../ViaVersion/handlers/ViaEncodeHandler.java | 18 +++++++++++++----- src/main/resources/plugin.yml | 2 +- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 01fe4e297..bc2c9fdd7 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ViaVersion 0.4.1 +# ViaVersion 0.4.2 **Allows the connection of 1.8 clients to 1.9** This plugin modifies netty to allow connection of 1.9 clients to 1.8, diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java index c689c3db4..72d7eb0b0 100644 --- a/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java +++ b/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java @@ -24,8 +24,8 @@ public class ViaDecodeHandler extends ByteToMessageDecoder { @Override protected void decode(ChannelHandlerContext ctx, ByteBuf bytebuf, List list) throws Exception { // use transformers - if(bytebuf.readableBytes() > 0) { - if(info.isActive()) { + if (bytebuf.readableBytes() > 0) { + if (info.isActive()) { int id = PacketUtil.readVarInt(bytebuf); // Transform ByteBuf newPacket = ctx.alloc().buffer(); @@ -33,7 +33,8 @@ public class ViaDecodeHandler extends ByteToMessageDecoder { incomingTransformer.transform(id, bytebuf, newPacket); bytebuf = newPacket; } catch (CancelException e) { - return; + bytebuf.readBytes(bytebuf.readableBytes()); + throw e; } } // call minecraft decoder @@ -41,5 +42,13 @@ public class ViaDecodeHandler extends ByteToMessageDecoder { } } + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + if (!(cause.getCause() instanceof CancelException)) { + if (cause instanceof Exception) { + throw (Exception) cause; + } + } + } } diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java index 41930556c..a3f2a814e 100644 --- a/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java +++ b/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java @@ -44,14 +44,14 @@ public class ViaEncodeHandler extends MessageToByteEncoder { Object packet = constructor.newInstance(chunk, true, 65535); ctx.pipeline().writeAndFlush(packet); } - bytebuf.clear(); - return; + bytebuf.readBytes(bytebuf.readableBytes()); + throw new CancelException(); } // call minecraft encoder PacketUtil.callEncode(this.minecraftEncoder, ctx, o, bytebuf); } if (bytebuf.readableBytes() == 0) { - return; + throw new CancelException(); } if(info.isActive()) { int id = PacketUtil.readVarInt(bytebuf); @@ -61,12 +61,20 @@ public class ViaEncodeHandler extends MessageToByteEncoder { try { outgoingTransformer.transform(id, oldPacket, bytebuf); } catch (CancelException e) { - bytebuf.clear(); - return; + bytebuf.readBytes(bytebuf.readableBytes()); + throw e; } finally { oldPacket.release(); } } } + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + if(!(cause.getCause() instanceof CancelException)) { + if(cause instanceof Exception){ + throw (Exception) cause; + } + } + } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 312dbc5e0..a596db287 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: ViaVersion main: us.myles.ViaVersion.ViaVersionPlugin author: _MylesC -version: 0.4.1 +version: 0.4.2 load: startup loadbefore: [ProtocolLib, ProxyPipe] \ No newline at end of file From ea6c648e4f2d064ad06c0a76224552b56a2e7fbc Mon Sep 17 00:00:00 2001 From: Myles Date: Wed, 2 Mar 2016 19:12:38 +0000 Subject: [PATCH 06/14] Fix spam, update to version 0.4.3 --- README.md | 2 +- .../myles/ViaVersion/handlers/ViaDecodeHandler.java | 10 +++++++--- .../myles/ViaVersion/handlers/ViaEncodeHandler.java | 12 ++++++++---- src/main/resources/plugin.yml | 2 +- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index bc2c9fdd7..9f045e42c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ViaVersion 0.4.2 +# ViaVersion 0.4.3 **Allows the connection of 1.8 clients to 1.9** This plugin modifies netty to allow connection of 1.9 clients to 1.8, diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java index 72d7eb0b0..398f196e6 100644 --- a/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java +++ b/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java @@ -44,9 +44,13 @@ public class ViaDecodeHandler extends ByteToMessageDecoder { @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { - if (!(cause.getCause() instanceof CancelException)) { - if (cause instanceof Exception) { - throw (Exception) cause; + if (!(cause.getCause().getCause() instanceof CancelException)) { + if (!(cause.getCause() instanceof CancelException)) { + if (!(cause instanceof CancelException)) { + System.out.println("throwing"); + if (cause instanceof Exception) + throw (Exception) cause; + } } } } diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java index a3f2a814e..d78195a5b 100644 --- a/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java +++ b/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java @@ -53,7 +53,7 @@ public class ViaEncodeHandler extends MessageToByteEncoder { if (bytebuf.readableBytes() == 0) { throw new CancelException(); } - if(info.isActive()) { + if (info.isActive()) { int id = PacketUtil.readVarInt(bytebuf); // Transform ByteBuf oldPacket = bytebuf.copy(); @@ -71,9 +71,13 @@ public class ViaEncodeHandler extends MessageToByteEncoder { @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { - if(!(cause.getCause() instanceof CancelException)) { - if(cause instanceof Exception){ - throw (Exception) cause; + if (!(cause.getCause().getCause() instanceof CancelException)) { + if (!(cause.getCause() instanceof CancelException)) { + if (!(cause instanceof CancelException)) { + System.out.println("throwing"); + if (cause instanceof Exception) + throw (Exception) cause; + } } } } diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index a596db287..6ae0c6667 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: ViaVersion main: us.myles.ViaVersion.ViaVersionPlugin author: _MylesC -version: 0.4.2 +version: 0.4.3 load: startup loadbefore: [ProtocolLib, ProxyPipe] \ No newline at end of file From 785f0664da323acc6c255d648a1a5e1a4b0d0407 Mon Sep 17 00:00:00 2001 From: Myles Date: Wed, 2 Mar 2016 19:42:14 +0000 Subject: [PATCH 07/14] Fix wither & add more debug info to missing metaindex --- .../us/myles/ViaVersion/metadata/MetaIndex.java | 2 ++ .../transformers/OutgoingTransformer.java | 17 +++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/main/java/us/myles/ViaVersion/metadata/MetaIndex.java b/src/main/java/us/myles/ViaVersion/metadata/MetaIndex.java index 20116e829..0224f5401 100644 --- a/src/main/java/us/myles/ViaVersion/metadata/MetaIndex.java +++ b/src/main/java/us/myles/ViaVersion/metadata/MetaIndex.java @@ -88,6 +88,8 @@ public enum MetaIndex { WITHER_TARGET2(Wither.class, 18, Type.Int, 12, NewType.VarInt), WITHER_TARGET3(Wither.class, 19, Type.Int, 13, NewType.VarInt), WITHER_INVULN_TIME(Wither.class, 20, Type.Int, 14, NewType.VarInt), + // wither skull + WITHERSKULL_INVULN(WitherSkull.class, 10, Type.Byte, 5, NewType.Boolean), // guardian GUARDIAN_INFO(Guardian.class, 16, Type.Int, 11, NewType.Byte), GUARDIAN_TARGET(Guardian.class, 17, Type.Int, 12, NewType.VarInt), diff --git a/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java b/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java index 3f28e184f..1f2fca030 100644 --- a/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java +++ b/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java @@ -551,6 +551,17 @@ public class OutgoingTransformer { } catch (IllegalAccessException e) { e.printStackTrace(); } + if (metaIndex == null) { + try { + System.out.println("Meta Data for " + type + ": Not found, ID: " + (int) ReflectionUtil.invoke(watchableObj, "a")); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } try { if (metaIndex.getNewType() != NewType.Discontinued) { if (metaIndex.getNewType() != NewType.BlockID || id != -1 && data == -1 || id == -1 && data != -1) { // block ID is only written if we have both parts @@ -635,8 +646,10 @@ public class OutgoingTransformer { } catch (Exception e) { if (type != null) { System.out.println("An error occurred with entity meta data for " + type); - System.out.println("Old ID: " + metaIndex.getIndex() + " New ID: " + metaIndex.getNewIndex()); - System.out.println("Old Type: " + metaIndex.getOldType() + " New Type: " + metaIndex.getNewType()); + if (metaIndex != null) { + System.out.println("Old ID: " + metaIndex.getIndex() + " New ID: " + metaIndex.getNewIndex()); + System.out.println("Old Type: " + metaIndex.getOldType() + " New Type: " + metaIndex.getNewType()); + } } e.printStackTrace(); } From e8cc25baadcd02e91db139ce6cddb0f906b7eb2f Mon Sep 17 00:00:00 2001 From: Myles Date: Wed, 2 Mar 2016 20:19:47 +0000 Subject: [PATCH 08/14] Should fix any ClosedConnection output --- .../myles/ViaVersion/handlers/ViaDecodeHandler.java | 11 +++++++---- .../myles/ViaVersion/handlers/ViaEncodeHandler.java | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java index 398f196e6..4c94d4117 100644 --- a/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java +++ b/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java @@ -8,6 +8,7 @@ import us.myles.ViaVersion.ConnectionInfo; import us.myles.ViaVersion.transformers.IncomingTransformer; import us.myles.ViaVersion.util.PacketUtil; +import java.nio.channels.ClosedChannelException; import java.util.List; public class ViaDecodeHandler extends ByteToMessageDecoder { @@ -44,10 +45,12 @@ public class ViaDecodeHandler extends ByteToMessageDecoder { @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { - if (!(cause.getCause().getCause() instanceof CancelException)) { - if (!(cause.getCause() instanceof CancelException)) { - if (!(cause instanceof CancelException)) { - System.out.println("throwing"); + if (!(cause.getCause().getCause() instanceof CancelException) + && !(cause.getCause().getCause() instanceof ClosedChannelException)) { + if (!(cause.getCause() instanceof CancelException) + && !(cause.getCause() instanceof ClosedChannelException)) { + if (!(cause instanceof CancelException) + && !(cause instanceof ClosedChannelException)) { if (cause instanceof Exception) throw (Exception) cause; } diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java index d78195a5b..a09aa26b3 100644 --- a/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java +++ b/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java @@ -10,6 +10,7 @@ import us.myles.ViaVersion.util.PacketUtil; import us.myles.ViaVersion.util.ReflectionUtil; import java.lang.reflect.Constructor; +import java.nio.channels.ClosedChannelException; public class ViaEncodeHandler extends MessageToByteEncoder { private final ConnectionInfo info; @@ -71,10 +72,12 @@ public class ViaEncodeHandler extends MessageToByteEncoder { @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { - if (!(cause.getCause().getCause() instanceof CancelException)) { - if (!(cause.getCause() instanceof CancelException)) { - if (!(cause instanceof CancelException)) { - System.out.println("throwing"); + if (!(cause.getCause().getCause() instanceof CancelException) + && !(cause.getCause().getCause() instanceof ClosedChannelException)) { + if (!(cause.getCause() instanceof CancelException) + && !(cause.getCause() instanceof ClosedChannelException)) { + if (!(cause instanceof CancelException) + && !(cause instanceof ClosedChannelException)) { if (cause instanceof Exception) throw (Exception) cause; } From 222dee6fdafc034988aa1be1d965b5c36d9dcc78 Mon Sep 17 00:00:00 2001 From: Paulomart Date: Wed, 2 Mar 2016 21:39:37 +0100 Subject: [PATCH 09/14] Rewrite Metadata system to read the data from the bytebuf instead of using the last sent packet. --- .../ViaVersion/metadata/MetadataRewriter.java | 183 ++++++++++++++++++ .../us/myles/ViaVersion/metadata/Type.java | 4 + .../transformers/OutgoingTransformer.java | 180 +---------------- .../us/myles/ViaVersion/util/PacketUtil.java | 20 ++ 4 files changed, 216 insertions(+), 171 deletions(-) create mode 100644 src/main/java/us/myles/ViaVersion/metadata/MetadataRewriter.java diff --git a/src/main/java/us/myles/ViaVersion/metadata/MetadataRewriter.java b/src/main/java/us/myles/ViaVersion/metadata/MetadataRewriter.java new file mode 100644 index 000000000..7a4d6770d --- /dev/null +++ b/src/main/java/us/myles/ViaVersion/metadata/MetadataRewriter.java @@ -0,0 +1,183 @@ +package us.myles.ViaVersion.metadata; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.UUID; + +import org.bukkit.entity.EntityType; +import org.bukkit.util.EulerAngle; +import org.bukkit.util.Vector; + +import io.netty.buffer.ByteBuf; + +import us.myles.ViaVersion.util.PacketUtil; + +public class MetadataRewriter { + + public static void writeMetadata1_9(EntityType type, List list, ByteBuf output) { + short id = -1; + int data = -1; + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + Entry entry = iterator.next(); // + MetaIndex metaIndex = entry.index; + try { + if (metaIndex.getNewType() != NewType.Discontinued) { + if (metaIndex.getNewType() != NewType.BlockID || id != -1 && data == -1 || id == -1 && data != -1) { // block ID is only written if we have both parts + output.writeByte(metaIndex.getNewIndex()); + output.writeByte(metaIndex.getNewType().getTypeID()); + } + Object value = entry.value; + switch (metaIndex.getNewType()) { + case Byte: + // convert from int, byte + if (metaIndex.getOldType() == Type.Byte) { + output.writeByte(((Byte) value).byteValue()); + } + if (metaIndex.getOldType() == Type.Int) { + output.writeByte(((Integer) value).byteValue()); + } + break; + case OptUUID: + String owner = (String) value; + UUID toWrite = null; + if (owner.length() != 0) { + try { + toWrite = UUID.fromString(owner); + } catch (Exception ignored) { + } + } + output.writeBoolean(toWrite != null); + if (toWrite != null) + PacketUtil.writeUUID((UUID) toWrite, output); + break; + case BlockID: + // if we have both sources :)) + if (metaIndex.getOldType() == Type.Byte) { + data = ((Byte) value).byteValue(); + } + if (metaIndex.getOldType() == Type.Short) { + id = ((Short) value).shortValue(); + } + if (id != -1 && data != -1) { + int combined = id << 4 | data; + data = -1; + id = -1; + PacketUtil.writeVarInt(combined, output); + } + break; + case VarInt: + // convert from int, short, byte + if (metaIndex.getOldType() == Type.Byte) { + PacketUtil.writeVarInt(((Byte) value).intValue(), output); + } + if (metaIndex.getOldType() == Type.Short) { + PacketUtil.writeVarInt(((Short) value).intValue(), output); + } + if (metaIndex.getOldType() == Type.Int) { + PacketUtil.writeVarInt(((Integer) value).intValue(), output); + } + break; + case Float: + output.writeFloat(((Float) value).floatValue()); + break; + case String: + PacketUtil.writeString((String) value, output); + break; + case Boolean: + output.writeBoolean(((Byte) value).byteValue() != 0); + break; + case Slot: + PacketUtil.writeItem(value, output); + break; + case Position: + Vector vector = (Vector) value; + output.writeInt((int) vector.getX()); + output.writeInt((int) vector.getY()); + output.writeInt((int) vector.getZ()); + break; + case Vector3F: + EulerAngle angle = (EulerAngle) value; + output.writeFloat((float) angle.getX()); + output.writeFloat((float) angle.getY()); + output.writeFloat((float) angle.getZ()); + break; + default: + System.out.println("[Out] Unhandled MetaDataType: " + metaIndex.getNewType()); + break; + } + } + } catch (Exception e) { + if (type != null) { + System.out.println("An error occurred with entity meta data for " + type); + if (metaIndex != null) { + System.out.println("Old ID: " + metaIndex.getIndex() + " New ID: " + metaIndex.getNewIndex()); + System.out.println("Old Type: " + metaIndex.getOldType() + " New Type: " + metaIndex.getNewType()); + } + } + e.printStackTrace(); + } + } + output.writeByte(255); + } + + public static List readMetadata1_8(EntityType entityType, ByteBuf buf) { + List entries = new ArrayList<>(); + byte item; + while ((item = buf.readByte()) != 127) { + Type type = Type.byId((item & 0xE0) >> 5); + int id = item & 0x1F; + MetaIndex index = MetaIndex.getIndex(entityType, id); + switch (type) { + case Byte: + entries.add(new Entry(index, buf.readByte())); + break; + case Short: + entries.add(new Entry(index, buf.readShort())); + break; + case Int: + entries.add(new Entry(index, buf.readInt())); + break; + case Float: + entries.add(new Entry(index, buf.readFloat())); + break; + case String: + entries.add(new Entry(index, PacketUtil.readString(buf))); + break; + case Slot: + entries.add(new Entry(index, PacketUtil.readItem(buf))); + break; + case Position: { + int x = buf.readInt(); + int y = buf.readInt(); + int z = buf.readInt(); + entries.add(new Entry(index, new Vector(x, y, z))); + break; + } + case Rotation: { + float x = buf.readFloat(); + float y = buf.readFloat(); + float z = buf.readFloat(); + entries.add(new Entry(index, new EulerAngle(x, y, z))); + break; + } + default: + System.out.println("[Out] Unhandled MetaDataType: " + type); + break; + } + } + return entries; + } + + public static class Entry { + + private MetaIndex index; + private Object value; + + private Entry(MetaIndex index, Object value) { + this.index = index; + this.value = value; + } + } +} diff --git a/src/main/java/us/myles/ViaVersion/metadata/Type.java b/src/main/java/us/myles/ViaVersion/metadata/Type.java index 48ceb3ac5..94c2300a0 100644 --- a/src/main/java/us/myles/ViaVersion/metadata/Type.java +++ b/src/main/java/us/myles/ViaVersion/metadata/Type.java @@ -18,4 +18,8 @@ public enum Type { public int getTypeID() { return typeID; } + + public static Type byId(int id) { + return values()[id]; + } } diff --git a/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java b/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java index 1f2fca030..5975630ef 100644 --- a/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java +++ b/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java @@ -10,9 +10,7 @@ import us.myles.ViaVersion.CancelException; import us.myles.ViaVersion.ConnectionInfo; import us.myles.ViaVersion.ViaVersionPlugin; import us.myles.ViaVersion.api.ViaVersion; -import us.myles.ViaVersion.metadata.MetaIndex; -import us.myles.ViaVersion.metadata.NewType; -import us.myles.ViaVersion.metadata.Type; +import us.myles.ViaVersion.metadata.MetadataRewriter; import us.myles.ViaVersion.packets.PacketType; import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion.sounds.SoundEffect; @@ -21,7 +19,6 @@ import us.myles.ViaVersion.util.PacketUtil; import us.myles.ViaVersion.util.ReflectionUtil; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; import java.util.*; import static us.myles.ViaVersion.util.PacketUtil.*; @@ -211,15 +208,7 @@ public class OutgoingTransformer { int id = PacketUtil.readVarInt(input); PacketUtil.writeVarInt(id, output); - try { - List dw = ReflectionUtil.get(info.getLastPacket(), "b", List.class); - // get entity via entityID, not preferred but we need it. - transformMetadata(id, dw, output); - } catch (NoSuchFieldException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } + transformMetadata(id, input, output); return; } @@ -358,16 +347,8 @@ public class OutgoingTransformer { output.writeShort(vY); short vZ = input.readShort(); output.writeShort(vZ); - try { - Object dataWatcher = ReflectionUtil.get(info.getLastPacket(), "l", ReflectionUtil.nms("DataWatcher")); - transformMetadata(id, dataWatcher, output); - } catch (NoSuchFieldException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } + + transformMetadata(id, input, output); return; } if (packet == PacketType.PLAY_UPDATE_SIGN) { @@ -411,16 +392,8 @@ public class OutgoingTransformer { output.writeByte(pitch); byte yaw = input.readByte(); output.writeByte(yaw); - try { - Object dataWatcher = ReflectionUtil.get(info.getLastPacket(), "i", ReflectionUtil.nms("DataWatcher")); - transformMetadata(id, dataWatcher, output); - } catch (NoSuchFieldException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - } + + transformMetadata(id, input, output); return; } @@ -514,150 +487,15 @@ public class OutgoingTransformer { return line; } - private void transformMetadata(int entityID, Object dw, ByteBuf output) throws CancelException { - // get entity - try { - transformMetadata(entityID, (List) ReflectionUtil.invoke(dw, "b"), output); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } - } - - private void transformMetadata(int entityID, List dw, ByteBuf output) throws CancelException { + private void transformMetadata(int entityID, ByteBuf input, ByteBuf output) throws CancelException { EntityType type = clientEntityTypes.get(entityID); if (type == null) { System.out.println("Unable to get entity for ID: " + entityID); output.writeByte(255); return; } - if (dw != null) { - short id = -1; - int data = -1; - - Iterator iterator = dw.iterator(); - while (iterator.hasNext()) { - Object watchableObj = iterator.next(); // - MetaIndex metaIndex = null; - try { - metaIndex = MetaIndex.getIndex(type, (int) ReflectionUtil.invoke(watchableObj, "a")); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - if (metaIndex == null) { - try { - System.out.println("Meta Data for " + type + ": Not found, ID: " + (int) ReflectionUtil.invoke(watchableObj, "a")); - } catch (NoSuchMethodException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - try { - if (metaIndex.getNewType() != NewType.Discontinued) { - if (metaIndex.getNewType() != NewType.BlockID || id != -1 && data == -1 || id == -1 && data != -1) { // block ID is only written if we have both parts - output.writeByte(metaIndex.getNewIndex()); - output.writeByte(metaIndex.getNewType().getTypeID()); - } - Object value = ReflectionUtil.invoke(watchableObj, "b"); - switch (metaIndex.getNewType()) { - case Byte: - // convert from int, byte - if (metaIndex.getOldType() == Type.Byte) { - output.writeByte(((Byte) value).byteValue()); - } - if (metaIndex.getOldType() == Type.Int) { - output.writeByte(((Integer) value).byteValue()); - } - break; - case OptUUID: - String owner = (String) value; - UUID toWrite = null; - if (owner.length() != 0) { - try { - toWrite = UUID.fromString(owner); - } catch (Exception ignored) { - } - } - output.writeBoolean(toWrite != null); - if (toWrite != null) - PacketUtil.writeUUID((UUID) toWrite, output); - break; - case BlockID: - // if we have both sources :)) - if (metaIndex.getOldType() == Type.Byte) { - data = ((Byte) value).byteValue(); - } - if (metaIndex.getOldType() == Type.Short) { - id = ((Short) value).shortValue(); - } - if (id != -1 && data != -1) { - int combined = id << 4 | data; - data = -1; - id = -1; - PacketUtil.writeVarInt(combined, output); - } - break; - case VarInt: - // convert from int, short, byte - if (metaIndex.getOldType() == Type.Byte) { - PacketUtil.writeVarInt(((Byte) value).intValue(), output); - } - if (metaIndex.getOldType() == Type.Short) { - PacketUtil.writeVarInt(((Short) value).intValue(), output); - } - if (metaIndex.getOldType() == Type.Int) { - PacketUtil.writeVarInt(((Integer) value).intValue(), output); - } - break; - case Float: - output.writeFloat(((Float) value).floatValue()); - break; - case String: - PacketUtil.writeString((String) value, output); - break; - case Boolean: - output.writeBoolean(((Byte) value).byteValue() != 0); - break; - case Slot: - PacketUtil.writeItem(value, output); - break; - case Position: - output.writeInt((int) ReflectionUtil.invoke(value, "getX")); - output.writeInt((int) ReflectionUtil.invoke(value, "getY")); - output.writeInt((int) ReflectionUtil.invoke(value, "getZ")); - break; - case Vector3F: - output.writeFloat((float) ReflectionUtil.invoke(value, "getX")); - output.writeFloat((float) ReflectionUtil.invoke(value, "getY")); - output.writeFloat((float) ReflectionUtil.invoke(value, "getZ")); - } - - } - } catch (Exception e) { - if (type != null) { - System.out.println("An error occurred with entity meta data for " + type); - if (metaIndex != null) { - System.out.println("Old ID: " + metaIndex.getIndex() + " New ID: " + metaIndex.getNewIndex()); - System.out.println("Old Type: " + metaIndex.getOldType() + " New Type: " + metaIndex.getNewType()); - } - } - e.printStackTrace(); - } - } - } - output.writeByte(255); - - + List list = MetadataRewriter.readMetadata1_8(type, input); + MetadataRewriter.writeMetadata1_9(type, list, output); } diff --git a/src/main/java/us/myles/ViaVersion/util/PacketUtil.java b/src/main/java/us/myles/ViaVersion/util/PacketUtil.java index b6d1fa0da..1c2dde784 100644 --- a/src/main/java/us/myles/ViaVersion/util/PacketUtil.java +++ b/src/main/java/us/myles/ViaVersion/util/PacketUtil.java @@ -373,6 +373,26 @@ public class PacketUtil { } } + public static Object readItem(ByteBuf output) { + try { + Class serializer = ReflectionUtil.nms("PacketDataSerializer"); + Object init = serializer.getDeclaredConstructor(ByteBuf.class).newInstance(output); + Method toCall = init.getClass().getDeclaredMethod("i"); + return toCall.invoke(init); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + return null; + } + public static long[] readBlockPosition(ByteBuf buf) { long val = buf.readLong(); long x = (val >> 38); // signed From 27c2f4c07681d601680fbc256e308215522ed430 Mon Sep 17 00:00:00 2001 From: Myles Date: Wed, 2 Mar 2016 22:01:16 +0000 Subject: [PATCH 10/14] Bump version --- README.md | 4 +++- src/main/resources/plugin.yml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9f045e42c..bf5c70e9b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ViaVersion 0.4.3 +# ViaVersion 0.4.4 **Allows the connection of 1.8 clients to 1.9** This plugin modifies netty to allow connection of 1.9 clients to 1.8, @@ -35,6 +35,8 @@ Contributors: **SanderGielisse** +**Paulomart** + License: -------- diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 6ae0c6667..ca6ce1a54 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: ViaVersion main: us.myles.ViaVersion.ViaVersionPlugin author: _MylesC -version: 0.4.3 +version: 0.4.4 load: startup loadbefore: [ProtocolLib, ProxyPipe] \ No newline at end of file From 2e9987373d09b43fd0010bff9b5985c4c52663a2 Mon Sep 17 00:00:00 2001 From: gigosaurus Date: Wed, 2 Mar 2016 22:16:58 +0000 Subject: [PATCH 11/14] Fix PLAY_USE_BED's old ID --- src/main/java/us/myles/ViaVersion/packets/PacketType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/us/myles/ViaVersion/packets/PacketType.java b/src/main/java/us/myles/ViaVersion/packets/PacketType.java index 05aa898e8..e0dbd4066 100644 --- a/src/main/java/us/myles/ViaVersion/packets/PacketType.java +++ b/src/main/java/us/myles/ViaVersion/packets/PacketType.java @@ -96,7 +96,7 @@ public enum PacketType { PLAY_COMBAT_EVENT(State.PLAY, Direction.OUTGOING, 0x42, 0x2C), PLAY_PLAYER_LIST_ITEM(State.PLAY, Direction.OUTGOING, 0x38, 0x2D), PLAY_PLAYER_POSITION_LOOK(State.PLAY, Direction.OUTGOING, 0x08, 0x2E), - PLAY_USE_BED(State.PLAY, Direction.OUTGOING, 0x2F, 0x2F), + PLAY_USE_BED(State.PLAY, Direction.OUTGOING, 0x0A, 0x2F), PLAY_DESTROY_ENTITIES(State.PLAY, Direction.OUTGOING, 0x13, 0x30), PLAY_REMOVE_ENTITY_EFFECT(State.PLAY, Direction.OUTGOING, 0x1E, 0x31), PLAY_RESOURCE_PACK_SEND(State.PLAY, Direction.OUTGOING, 0x48, 0x32), From 3e30d989a0b0d4058d8bd1a9a2024bb12c0b3263 Mon Sep 17 00:00:00 2001 From: Myles Date: Wed, 2 Mar 2016 23:20:57 +0000 Subject: [PATCH 12/14] Print out stack traces instead of throwing them move. --- .../java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java | 5 +++-- .../java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java index 4c94d4117..ad39cd125 100644 --- a/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java +++ b/src/main/java/us/myles/ViaVersion/handlers/ViaDecodeHandler.java @@ -51,8 +51,9 @@ public class ViaDecodeHandler extends ByteToMessageDecoder { && !(cause.getCause() instanceof ClosedChannelException)) { if (!(cause instanceof CancelException) && !(cause instanceof ClosedChannelException)) { - if (cause instanceof Exception) - throw (Exception) cause; + if (cause instanceof Exception){ + cause.printStackTrace(); + } } } } diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java index a09aa26b3..4cc88c572 100644 --- a/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java +++ b/src/main/java/us/myles/ViaVersion/handlers/ViaEncodeHandler.java @@ -79,7 +79,7 @@ public class ViaEncodeHandler extends MessageToByteEncoder { if (!(cause instanceof CancelException) && !(cause instanceof ClosedChannelException)) { if (cause instanceof Exception) - throw (Exception) cause; + cause.printStackTrace(); } } } From 573dcc10b157bf2b0366532f827ff9634c8ef549 Mon Sep 17 00:00:00 2001 From: gigosaurus Date: Thu, 3 Mar 2016 00:06:13 +0000 Subject: [PATCH 13/14] Fix player entity meta data I'm not 100% confident that what I'm doing here is correct, but looking at http://wiki.vg/Pre-release_protocol#Spawn_Player I think I'm doing it right. fixes #58 --- .../us/myles/ViaVersion/transformers/OutgoingTransformer.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java b/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java index 5975630ef..ceda3a0f8 100644 --- a/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java +++ b/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java @@ -393,6 +393,9 @@ public class OutgoingTransformer { byte yaw = input.readByte(); output.writeByte(yaw); + // next field is Current Item, this was removed in 1.9 so we'll ignore it + input.readShort(); + transformMetadata(id, input, output); return; From 86d543d70071dfe41299f2647c76cfc08122b48b Mon Sep 17 00:00:00 2001 From: Myles Date: Thu, 3 Mar 2016 00:13:53 +0000 Subject: [PATCH 14/14] Add new contributor, update version to 0.4.5 :) --- README.md | 7 ++----- src/main/resources/plugin.yml | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index bf5c70e9b..4bd878f48 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ViaVersion 0.4.4 +# ViaVersion 0.4.5 **Allows the connection of 1.8 clients to 1.9** This plugin modifies netty to allow connection of 1.9 clients to 1.8, @@ -28,14 +28,11 @@ Contributors: -------- **Myself** (harhar) - **Matsv/StamBoom** - **HugoDaBosss** - **SanderGielisse** - **Paulomart** +**gigosaurus** License: -------- diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index ca6ce1a54..59982eef5 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: ViaVersion main: us.myles.ViaVersion.ViaVersionPlugin author: _MylesC -version: 0.4.4 +version: 0.4.5 load: startup loadbefore: [ProtocolLib, ProxyPipe] \ No newline at end of file