diff --git a/pom.xml b/pom.xml index 380c401cc..cb31c5789 100644 --- a/pom.xml +++ b/pom.xml @@ -21,12 +21,28 @@ - - org.spigot - spigot1.8 - 1.8 - system - E:/spigot_server.jar + org.bukkit + bukkit + 1.8.8-R0.1-SNAPSHOT + provided + + + io.netty + netty-all + 4.0.20.Final + provided + + + com.google.code.gson + gson + 2.4 + provided + + + com.google.guava + guava + 18.0 + provided diff --git a/src/main/java/us/myles/ViaVersion/Core.java b/src/main/java/us/myles/ViaVersion/Core.java index ae625b612..9eed8619a 100644 --- a/src/main/java/us/myles/ViaVersion/Core.java +++ b/src/main/java/us/myles/ViaVersion/Core.java @@ -5,15 +5,12 @@ import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; -import net.minecraft.server.v1_8_R3.*; import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.java.JavaPlugin; import us.myles.ViaVersion.handlers.ViaVersionInitializer; -import java.lang.reflect.Field; import java.util.List; import java.util.UUID; import java.util.concurrent.Callable; @@ -23,10 +20,6 @@ public class Core extends JavaPlugin { @Override public void onEnable() { System.out.println("ViaVersion enabled, injecting. (Allows 1.8 to be accessed via 1.9)"); - /* Obvious message here: - If loading this plugin nobody will be on 1.9 cause only 1.8 so we're fine, as for reloading ugh. - Clients might crash cause of it being a bum maybe? :P - */ try { injectPacketHandler(); } catch (Exception e) { @@ -36,39 +29,37 @@ public class Core extends JavaPlugin { } public void injectPacketHandler() throws Exception { - MinecraftServer server = MinecraftServer.getServer(); - ServerConnection connection = server.getServerConnection(); + Class serverClazz = ReflectionUtil.nms("MinecraftServer"); + Object server = ReflectionUtil.invokeStatic(serverClazz, "getServer"); + Object connection = serverClazz.getDeclaredMethod("getServerConnection").invoke(server); - List futures = getPrivateField(connection, "g", List.class); - if(futures.size() == 0){ + List futures = ReflectionUtil.get(connection, "g", List.class); + if (futures.size() == 0) { throw new Exception("Could not find server to inject (late bind?)"); } for (ChannelFuture future : futures) { ChannelPipeline pipeline = future.channel().pipeline(); ChannelHandler bootstrapAcceptor = pipeline.first(); - ChannelInitializer oldInit = getPrivateField(bootstrapAcceptor, "childHandler", ChannelInitializer.class); + ChannelInitializer oldInit = ReflectionUtil.get(bootstrapAcceptor, "childHandler", ChannelInitializer.class); ChannelInitializer newInit = new ViaVersionInitializer(oldInit); - setPrivateField(bootstrapAcceptor, "childHandler", newInit); + ReflectionUtil.set(bootstrapAcceptor, "childHandler", newInit); } } public static Entity getEntity(final UUID player, final int id) { - try { return Bukkit.getScheduler().callSyncMethod(getPlugin(Core.class), new Callable() { @Override public Entity call() throws Exception { Player p = Bukkit.getPlayer(player); if (p == null) return null; - WorldServer ws = ((CraftWorld) p.getWorld()).getHandle(); - for (Entity e : ws.entityList) { - if (e.getId() == id) { + for (Entity e : p.getWorld().getEntities()) { + if (e.getEntityId() == id) { return e; } } - System.out.println("Couldn't find in the world!!"); return null; } }).get(10, TimeUnit.SECONDS); @@ -77,41 +68,5 @@ public class Core extends JavaPlugin { e.printStackTrace(); return null; } - - } - - public static T getPrivateField(Object o, String f, Class t) throws NoSuchFieldException, IllegalAccessException { - Field field = o.getClass().getDeclaredField(f); - field.setAccessible(true); - return (T) field.get(o); - } - - public static void setPrivateField(Object o, String f, Object value) throws NoSuchFieldException, IllegalAccessException { - Field field = o.getClass().getDeclaredField(f); - field.setAccessible(true); - field.set(o, value); - } - - @Override - public void onDisable() { - - } - - public static ItemStack getHandItem(final ConnectionInfo info) { - try { - return Bukkit.getScheduler().callSyncMethod(getPlugin(Core.class), new Callable() { - @Override - public ItemStack call() throws Exception { - if (info.getPlayer() != null) { - return info.getPlayer().getItemInHand(); - } - return null; - } - }).get(10, TimeUnit.SECONDS); - } catch (Exception e) { - System.out.println("Error fetching hand item "); - e.printStackTrace(); - return null; - } } } diff --git a/src/main/java/us/myles/ViaVersion/PacketUtil.java b/src/main/java/us/myles/ViaVersion/PacketUtil.java index dad6bdc95..f7c0e89d3 100644 --- a/src/main/java/us/myles/ViaVersion/PacketUtil.java +++ b/src/main/java/us/myles/ViaVersion/PacketUtil.java @@ -338,4 +338,22 @@ public class PacketUtil { return output; } + public static void writeItem(Object value, ByteBuf output) { + try { + Class serializer = ReflectionUtil.nms("PacketDataSerializer"); + Object init = serializer.getDeclaredConstructor(ByteBuf.class).newInstance(output); + Method toCall = init.getClass().getDeclaredMethod("a", ReflectionUtil.nms("ItemStack")); + toCall.invoke(init, value); + } 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(); + } + } } diff --git a/src/main/java/us/myles/ViaVersion/ReflectionUtil.java b/src/main/java/us/myles/ViaVersion/ReflectionUtil.java new file mode 100644 index 000000000..a77c32ed0 --- /dev/null +++ b/src/main/java/us/myles/ViaVersion/ReflectionUtil.java @@ -0,0 +1,41 @@ +package us.myles.ViaVersion; + +import org.bukkit.Bukkit; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class ReflectionUtil { + private static String BASE = Bukkit.getServer().getClass().getPackage().getName(); + private static String NMS = BASE.replace("org.bukkit.craftbukkit", "net.minecraft.server"); + + public static Class nms(String className) throws ClassNotFoundException { + return Class.forName(NMS + "." + className); + } + public static Class obc(String className) throws ClassNotFoundException { + return Class.forName(BASE + "." + className); + } + + public static Object invokeStatic(Class clazz, String method) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Method m = clazz.getDeclaredMethod(method); + return m.invoke(null); + } + + public static Object invoke(Object o, String method) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + Method m = o.getClass().getDeclaredMethod(method); + return m.invoke(o); + } + + public static T get(Object o, String f, Class t) throws NoSuchFieldException, IllegalAccessException { + Field field = o.getClass().getDeclaredField(f); + field.setAccessible(true); + return (T) field.get(o); + } + + public static void set(Object o, String f, Object value) throws NoSuchFieldException, IllegalAccessException { + Field field = o.getClass().getDeclaredField(f); + field.setAccessible(true); + field.set(o, value); + } +} diff --git a/src/main/java/us/myles/ViaVersion/handlers/ViaOutboundPacketHandler.java b/src/main/java/us/myles/ViaVersion/handlers/ViaOutboundPacketHandler.java index 6e787b300..817731e67 100644 --- a/src/main/java/us/myles/ViaVersion/handlers/ViaOutboundPacketHandler.java +++ b/src/main/java/us/myles/ViaVersion/handlers/ViaOutboundPacketHandler.java @@ -1,15 +1,14 @@ package us.myles.ViaVersion.handlers; +import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelOutboundHandlerAdapter; import io.netty.channel.ChannelPromise; -import net.minecraft.server.v1_8_R3.Packet; -import net.minecraft.server.v1_8_R3.PacketPlayOutMapChunk; -import net.minecraft.server.v1_8_R3.PacketPlayOutMapChunkBulk; -import net.minecraft.server.v1_8_R3.World; import us.myles.ViaVersion.ConnectionInfo; -import us.myles.ViaVersion.Core; +import us.myles.ViaVersion.ReflectionUtil; + +import java.lang.reflect.Constructor; public class ViaOutboundPacketHandler extends ChannelOutboundHandlerAdapter { private final ConnectionInfo info; @@ -17,21 +16,26 @@ public class ViaOutboundPacketHandler extends ChannelOutboundHandlerAdapter { public ViaOutboundPacketHandler(Channel c, ConnectionInfo info) { this.info = info; } + @Override public void write(ChannelHandlerContext channelHandlerContext, Object o, ChannelPromise channelPromise) throws Exception { - if(o instanceof Packet){ + if (!(o instanceof ByteBuf)) { info.setLastPacket(o); /* This transformer is more for fixing issues which we find hard at byte level :) */ - if(o instanceof PacketPlayOutMapChunkBulk){ - PacketPlayOutMapChunkBulk bulk = (PacketPlayOutMapChunkBulk) o; - int[] locX = Core.getPrivateField(bulk, "a", int[].class); - int[] locZ = Core.getPrivateField(bulk, "b", int[].class); + if (o.getClass().getName().endsWith("PacketPlayOutMapChunkBulk")) { + int[] locX = ReflectionUtil.get(o, "a", int[].class); + int[] locZ = ReflectionUtil.get(o, "b", int[].class); - World world = Core.getPrivateField(bulk, "world", World.class); - for(int i = 0;i 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]; - channelHandlerContext.write(new PacketPlayOutMapChunk(world.getChunkAt(x, z), true, 65535)); // magic was 65535 + // 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; } diff --git a/src/main/java/us/myles/ViaVersion/metadata/MetaIndex.java b/src/main/java/us/myles/ViaVersion/metadata/MetaIndex.java index ae4fb7405..90b5e5ff7 100644 --- a/src/main/java/us/myles/ViaVersion/metadata/MetaIndex.java +++ b/src/main/java/us/myles/ViaVersion/metadata/MetaIndex.java @@ -1,8 +1,5 @@ package us.myles.ViaVersion.metadata; -import net.minecraft.server.v1_8_R3.Entity; -import net.minecraft.server.v1_8_R3.EntityPlayer; -import net.minecraft.server.v1_8_R3.EntityTypes; import org.bukkit.entity.*; public enum MetaIndex { @@ -164,11 +161,10 @@ public enum MetaIndex { public static MetaIndex getIndex(Entity entity, int index) { EntityType type; - if (entity instanceof EntityPlayer) { + if (entity instanceof Player) { type = EntityType.PLAYER; } else { - int entityID = EntityTypes.a(entity); - type = EntityType.fromId(entityID); + type = entity.getType(); } return getIndex(type, index); } diff --git a/src/main/java/us/myles/ViaVersion/transformers/IncomingTransformer.java b/src/main/java/us/myles/ViaVersion/transformers/IncomingTransformer.java index 183fafe05..d5aab2b3b 100644 --- a/src/main/java/us/myles/ViaVersion/transformers/IncomingTransformer.java +++ b/src/main/java/us/myles/ViaVersion/transformers/IncomingTransformer.java @@ -2,17 +2,15 @@ package us.myles.ViaVersion.transformers; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; -import net.minecraft.server.v1_8_R3.ItemStack; -import net.minecraft.server.v1_8_R3.PacketDataSerializer; -import net.minecraft.server.v1_8_R3.PacketPlayOutSetSlot; import us.myles.ViaVersion.CancelException; import us.myles.ViaVersion.ConnectionInfo; import us.myles.ViaVersion.PacketUtil; +import us.myles.ViaVersion.ReflectionUtil; import us.myles.ViaVersion.handlers.ViaVersionInitializer; import us.myles.ViaVersion.packets.PacketType; import us.myles.ViaVersion.packets.State; -import java.io.IOException; +import java.lang.reflect.InvocationTargetException; public class IncomingTransformer { private final Channel channel; @@ -97,23 +95,29 @@ public class IncomingTransformer { byte button = input.readByte(); short action = input.readShort(); byte mode = input.readByte(); - PacketDataSerializer pds = new PacketDataSerializer(input); - ItemStack slotItem = null; - try { - slotItem = pds.i(); - } catch (IOException e) { - } if (slot == 45 && windowID == 0) { - channel.writeAndFlush(new PacketPlayOutSetSlot(windowID, slot, null)); // slot is empty - slot = -999; // we're evil, they'll throw item on the ground + try { + Class setSlot = ReflectionUtil.nms("PacketPlayOutSetSlot"); + Object setSlotPacket = setSlot.getConstructors()[1].newInstance(windowID, slot, null); + channel.writeAndFlush(setSlotPacket); // slot is empty + slot = -999; // we're evil, they'll throw item on the ground + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } output.writeByte(windowID); output.writeShort(slot); output.writeByte(button); output.writeShort(action); output.writeByte(mode); - PacketDataSerializer pdss = new PacketDataSerializer(output); - pdss.a(slotItem); + output.writeBytes(input); return; } if (packet == PacketType.PLAY_CLIENT_SETTINGS) { diff --git a/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java b/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java index 02bf805eb..cd9e0cfbf 100644 --- a/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java +++ b/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java @@ -4,16 +4,11 @@ import com.google.gson.Gson; import com.google.gson.JsonObject; import io.netty.buffer.ByteBuf; import io.netty.channel.Channel; -import net.minecraft.server.v1_8_R3.*; -import net.minecraft.server.v1_8_R3.ItemStack; -import org.bukkit.craftbukkit.v1_8_R3.inventory.CraftItemStack; -import org.bukkit.inventory.*; +import org.bukkit.Bukkit; +import org.bukkit.entity.Entity; import org.spacehq.mc.protocol.data.game.chunk.Column; import org.spacehq.mc.protocol.util.NetUtil; -import us.myles.ViaVersion.CancelException; -import us.myles.ViaVersion.ConnectionInfo; -import us.myles.ViaVersion.Core; -import us.myles.ViaVersion.PacketUtil; +import us.myles.ViaVersion.*; import us.myles.ViaVersion.handlers.ViaVersionInitializer; import us.myles.ViaVersion.metadata.MetaIndex; import us.myles.ViaVersion.metadata.NewType; @@ -22,6 +17,8 @@ import us.myles.ViaVersion.packets.PacketType; import us.myles.ViaVersion.packets.State; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.*; public class OutgoingTransformer { @@ -171,7 +168,7 @@ public class OutgoingTransformer { PacketUtil.writeVarInt(id, output); try { - List dw = Core.getPrivateField(info.getLastPacket(), "b", List.class); + List dw = ReflectionUtil.get(info.getLastPacket(), "b", List.class); // get entity via entityID, not preferred but we need it. Entity entity = Core.getEntity(info.getUUID(), id); if (entity != null) { @@ -262,12 +259,14 @@ public class OutgoingTransformer { short vZ = input.readShort(); output.writeShort(vZ); try { - DataWatcher dw = Core.getPrivateField(info.getLastPacket(), "l", DataWatcher.class); - transformMetadata(dw, output); + Object dataWatcher = ReflectionUtil.get(info.getLastPacket(), "l", ReflectionUtil.nms("DataWatcher")); + transformMetadata(dataWatcher, output); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); } return; } @@ -290,12 +289,14 @@ public class OutgoingTransformer { byte yaw = input.readByte(); output.writeByte(yaw); try { - DataWatcher dw = Core.getPrivateField(info.getLastPacket(), "i", DataWatcher.class); - transformMetadata(dw, output); + Object dataWatcher = ReflectionUtil.get(info.getLastPacket(), "i", ReflectionUtil.nms("DataWatcher")); + transformMetadata(dataWatcher, output); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); } return; @@ -326,9 +327,9 @@ public class OutgoingTransformer { byte[] data = new byte[size]; input.readBytes(data); boolean sk = false; - if (info.getLastPacket() instanceof PacketPlayOutMapChunkBulk) { + if (info.getLastPacket().getClass().getName().endsWith("PacketPlayOutMapChunkBulk")) { try { - sk = Core.getPrivateField(info.getLastPacket(), "d", boolean.class); + sk = ReflectionUtil.get(info.getLastPacket(), "d", boolean.class); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { @@ -351,113 +352,124 @@ public class OutgoingTransformer { output.writeBytes(input); } - private void transformMetadata(DataWatcher dw, ByteBuf output) { + private void transformMetadata(Object dw, ByteBuf output) { // get entity try { - transformMetadata(Core.getPrivateField(dw, "a", Entity.class), dw.b(), output); + Class nmsClass = ReflectionUtil.nms("Entity"); + Object nmsEntity = ReflectionUtil.get(dw, "a", nmsClass); + Class craftClass = ReflectionUtil.obc("entity.CraftEntity"); + Method bukkitMethod = craftClass.getDeclaredMethod("getEntity", ReflectionUtil.obc("CraftServer"), nmsClass); + + Object entity = bukkitMethod.invoke(null, Bukkit.getServer(), nmsEntity); + transformMetadata((Entity) entity, (List) ReflectionUtil.invoke(dw, "b"), output); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (ClassNotFoundException e) { + e.printStackTrace(); } } - private void transformMetadata(Entity entity, List dw, ByteBuf output) { - PacketDataSerializer packetdataserializer = new PacketDataSerializer(output); + private void transformMetadata(Entity entity, List dw, ByteBuf output) { + try { + if (dw != null) { + short id = -1; + int data = -1; - if (dw != null) { - short id = -1; - int data = -1; - - Iterator iterator = dw.iterator(); - while (iterator.hasNext()) { - DataWatcher.WatchableObject obj = iterator.next(); - MetaIndex metaIndex = MetaIndex.getIndex(entity, obj.a()); - 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()); - } - switch (metaIndex.getNewType()) { - case Byte: - // convert from int, byte - if (metaIndex.getOldType() == Type.Byte) { - packetdataserializer.writeByte(((Byte) obj.b()).byteValue()); - } - if (metaIndex.getOldType() == Type.Int) { - packetdataserializer.writeByte(((Integer) obj.b()).byteValue()); - } - break; - case OptUUID: - String owner = (String) obj.b(); - UUID toWrite = null; - if (owner.length() != 0) { - try { - toWrite = UUID.fromString(owner); - } catch (Exception ignored) { + Iterator iterator = dw.iterator(); + while (iterator.hasNext()) { + Object watchableObj = iterator.next(); // + MetaIndex metaIndex = MetaIndex.getIndex(entity, (int) ReflectionUtil.invoke(watchableObj, "a")); + 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()); } - } - packetdataserializer.writeBoolean(toWrite != null); - if (toWrite != null) - packetdataserializer.a(toWrite); - break; - case BlockID: - // if we have both sources :)) - if (metaIndex.getOldType() == Type.Byte) { - data = ((Byte) obj.b()).byteValue(); - } - if (metaIndex.getOldType() == Type.Short) { - id = ((Short) obj.b()).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) obj.b()).intValue(), output); - } - if (metaIndex.getOldType() == Type.Short) { - PacketUtil.writeVarInt(((Short) obj.b()).intValue(), output); - } - if (metaIndex.getOldType() == Type.Int) { - PacketUtil.writeVarInt(((Integer) obj.b()).intValue(), output); - } - break; - case Float: - packetdataserializer.writeFloat(((Float) obj.b()).floatValue()); - break; - case String: - packetdataserializer.a((String) obj.b()); - break; - case Boolean: - packetdataserializer.writeBoolean(((Byte) obj.b()).byteValue() != 0); - break; - case Slot: - ItemStack itemstack = (ItemStack) obj.b(); - packetdataserializer.a(itemstack); - break; - case Position: - BlockPosition blockposition = (BlockPosition) obj.b(); - packetdataserializer.writeInt(blockposition.getX()); - packetdataserializer.writeInt(blockposition.getY()); - packetdataserializer.writeInt(blockposition.getZ()); - break; - case Vector3F: - Vector3f vector3f = (Vector3f) obj.b(); - packetdataserializer.writeFloat(vector3f.getX()); - packetdataserializer.writeFloat(vector3f.getY()); - packetdataserializer.writeFloat(vector3f.getZ()); + 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) value, 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")); + } } } } + output.writeByte(255); + }catch(Exception e){ + e.printStackTrace(); } - output.writeByte(255); - }