From 7dff86cb48b777ff7a6933d21f784c4fa4a414f3 Mon Sep 17 00:00:00 2001 From: Dan Mulloy Date: Mon, 2 Nov 2015 23:56:41 -0500 Subject: [PATCH] Fix the StreamSerializer String-based methods will still work, but deserializing from a data input stream has been deprecated since it depends on hacky code Fixes #31, Fixes #125 --- .../protocol/compat/netty/Netty.java | 12 +- .../protocol/compat/netty/NettyCompat.java | 5 +- .../protocol/compat/netty/WrappedByteBuf.java | 2 + .../netty/independent/IndependentNetty.java | 15 +- .../netty/independent/NettyByteBuf.java | 5 + .../protocol/utility/MinecraftMethods.java | 2 +- .../protocol/utility/StreamSerializer.java | 363 +++++++++++------- .../utility/StreamSerializerTest.java | 60 +-- .../compat/netty/shaded/ShadedByteBuf.java | 5 + .../compat/netty/shaded/ShadedNetty.java | 15 +- 10 files changed, 293 insertions(+), 191 deletions(-) diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/Netty.java b/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/Netty.java index 8d09ef18..f9ebf65c 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/Netty.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/Netty.java @@ -61,10 +61,6 @@ public class Netty { return getCompat().createPacketBuffer(); } - public static WrappedByteBuf allocateUnpooled() { - return getCompat().allocateUnpooled(); - } - public static Class getGenericFutureListenerArray() { return getCompat().getGenericFutureListenerArray(); } @@ -92,4 +88,12 @@ public class Netty { public static WrappedByteBuf packetWriter(DataOutputStream output) { return getCompat().packetWriter(output); } + + public static WrappedByteBuf copiedBuffer(byte[] array) { + return getCompat().copiedBuffer(array); + } + + public static WrappedByteBuf buffer() { + return getCompat().buffer(); + } } \ No newline at end of file diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/NettyCompat.java b/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/NettyCompat.java index a4a65d82..b9e40c01 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/NettyCompat.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/NettyCompat.java @@ -30,11 +30,14 @@ import com.comphenix.protocol.wrappers.WrappedServerPing.CompressedImage; * @author dmulloy2 */ +// TODO: Sort out packet readers/writers public interface NettyCompat { WrappedByteBuf createPacketBuffer(); - WrappedByteBuf allocateUnpooled(); + WrappedByteBuf copiedBuffer(byte[] array); + + WrappedByteBuf buffer(); Class getGenericFutureListenerArray(); diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/WrappedByteBuf.java b/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/WrappedByteBuf.java index b7dda6f3..30924b1c 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/WrappedByteBuf.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/WrappedByteBuf.java @@ -41,4 +41,6 @@ public interface WrappedByteBuf { void writeByte(int i); void writeBytes(byte[] bytes); + + byte[] array(); } \ No newline at end of file diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/independent/IndependentNetty.java b/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/independent/IndependentNetty.java index 5fcef282..43254048 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/independent/IndependentNetty.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/independent/IndependentNetty.java @@ -55,11 +55,6 @@ public class IndependentNetty implements NettyCompat { } } - @Override - public WrappedByteBuf allocateUnpooled() { - return new NettyByteBuf(UnpooledByteBufAllocator.DEFAULT.buffer()); - } - @Override public Class getGenericFutureListenerArray() { return GenericFutureListener[].class; @@ -97,4 +92,14 @@ public class IndependentNetty implements NettyCompat { public WrappedByteBuf packetWriter(DataOutputStream output) { return new NettyByteBuf(NettyByteBufAdapter.packetWriter(output)); } + + @Override + public WrappedByteBuf copiedBuffer(byte[] array) { + return new NettyByteBuf(Unpooled.copiedBuffer(array)); + } + + @Override + public WrappedByteBuf buffer() { + return new NettyByteBuf(Unpooled.buffer()); + } } \ No newline at end of file diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/independent/NettyByteBuf.java b/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/independent/NettyByteBuf.java index ce37d03b..564be26f 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/independent/NettyByteBuf.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/compat/netty/independent/NettyByteBuf.java @@ -75,4 +75,9 @@ public class NettyByteBuf implements WrappedByteBuf { public void writeBytes(byte[] bytes) { handle.get().writeBytes(bytes); } + + @Override + public byte[] array() { + return handle.get().array(); + } } \ No newline at end of file diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftMethods.java b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftMethods.java index af2d7d48..e95e0728 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftMethods.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftMethods.java @@ -174,7 +174,7 @@ public class MinecraftMethods { // Create our proxy object Object javaProxy = enhancer.create( new Class[] { MinecraftReflection.getByteBufClass() }, - new Object[] { Netty.allocateUnpooled().getHandle() } + new Object[] { Netty.buffer().getHandle() } ); Object lookPacket = new PacketContainer(PacketType.Play.Client.CLOSE_WINDOW).getHandle(); diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/utility/StreamSerializer.java b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/StreamSerializer.java index 45492b96..9d4e36ab 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/utility/StreamSerializer.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/StreamSerializer.java @@ -10,6 +10,7 @@ import java.io.IOException; import javax.annotation.Nonnull; +import org.apache.commons.lang.Validate; import org.bukkit.inventory.ItemStack; import org.yaml.snakeyaml.external.biz.base64Coder.Base64Coder; @@ -49,7 +50,23 @@ public class StreamSerializer { public static StreamSerializer getDefault() { return DEFAULT; } - + + /** + * Write a variable integer to an output stream. + * @param destination - the destination. + * @param value - the value to write. + * @throws IOException The destination stream threw an exception. + */ + public void serializeVarInt(@Nonnull DataOutputStream destination, int value) throws IOException { + Preconditions.checkNotNull(destination, "source cannot be NULL"); + + while ((value & 0xFFFFFF80) != 0) { + destination.writeByte(value & 0x7F | 0x80); + value >>>= 7; + } + destination.writeByte(value); + } + /** * Read a variable integer from an input stream. * @param source - the source. @@ -73,66 +90,49 @@ public class StreamSerializer { } /** - * Write a variable integer to an output stream. - * @param destination - the destination. - * @param value - the value to write. - * @throws IOException The destination stream threw an exception. - */ - public void serializeVarInt(@Nonnull DataOutputStream destination, int value) throws IOException { - Preconditions.checkNotNull(destination, "source cannot be NULL"); - - while ((value & 0xFFFFFF80) != 0) { - destination.writeByte(value & 0x7F | 0x80); - value >>>= 7; - } - destination.writeByte(value); - } - - /** - * Read or deserialize an item stack from an underlying input stream. + * Write or serialize a NBT compound to the given output stream. *

- * To supply a byte array, wrap it in a {@link java.io.ByteArrayInputStream ByteArrayInputStream} - * and {@link java.io.DataInputStream DataInputStream}. + * Note: An NBT compound can be written to a stream even if it's NULL. * - * @param input - the target input stream. - * @return The resulting item stack, or NULL if the serialized item stack was NULL. - * @throws IOException If the operation failed due to reflection or corrupt data. + * @param output - the target output stream. + * @param compound - the NBT compound to be serialized, or NULL to represent nothing. + * @throws IOException If the operation fails due to reflection problems. */ - public ItemStack deserializeItemStack(@Nonnull DataInputStream input) throws IOException { - if (input == null) - throw new IllegalArgumentException("Input stream cannot be NULL."); - Object nmsItem = null; + public void serializeCompound(@Nonnull DataOutputStream output, NbtCompound compound) throws IOException { + if (output == null) + throw new IllegalArgumentException("Output stream cannot be NULL."); + + // Get the NMS version of the compound + Object handle = compound != null ? NbtFactory.fromBase(compound).getHandle() : null; if (MinecraftReflection.isUsingNetty()) { - if (READ_ITEM_METHOD == null) { - READ_ITEM_METHOD = Accessors.getMethodAccessor( + if (WRITE_NBT_METHOD == null) { + WRITE_NBT_METHOD = Accessors.getMethodAccessor( FuzzyReflection.fromClass(MinecraftReflection.getPacketDataSerializerClass(), true). - getMethodByParameters("readItemStack", /* i */ - MinecraftReflection.getItemStackClass(), new Class[0]) + getMethodByParameters("writeNbtCompound", /* a */ + MinecraftReflection.getNBTCompoundClass()) ); } - nmsItem = READ_ITEM_METHOD.invoke(Netty.packetReader(input).getHandle()); + WrappedByteBuf buf = Netty.packetWriter(output); + buf.writeByte(NbtType.TAG_COMPOUND.getRawID()); + + WRITE_NBT_METHOD.invoke(buf.getHandle(), handle); } else { - if (READ_ITEM_METHOD == null) { - READ_ITEM_METHOD = Accessors.getMethodAccessor( - FuzzyReflection.fromClass(MinecraftReflection.getPacketClass()).getMethod( + if (WRITE_NBT_METHOD == null) { + WRITE_NBT_METHOD = Accessors.getMethodAccessor( + FuzzyReflection.fromClass(MinecraftReflection.getPacketClass(), true).getMethod( FuzzyMethodContract.newBuilder(). - parameterCount(1). - parameterDerivedOf(DataInput.class). - returnDerivedOf(MinecraftReflection.getItemStackClass()). + parameterCount(2). + parameterDerivedOf(MinecraftReflection.getNBTBaseClass(), 0). + parameterDerivedOf(DataOutput.class, 1). + returnTypeVoid(). build()) - ); + ); } - nmsItem = READ_ITEM_METHOD.invoke(null, input); + WRITE_NBT_METHOD.invoke(null, handle, output); } - - // Convert back to a Bukkit item stack - if (nmsItem != null) - return MinecraftReflection.getBukkitItemStack(nmsItem); - else - return null; } /** @@ -182,6 +182,47 @@ public class StreamSerializer { else return null; } + + /** + * Serialize a string using the standard Minecraft UTF-16 encoding. + *

+ * Note that strings cannot exceed 32767 characters, regardless if maximum lenght. + * @param output - the output stream. + * @param text - the string to serialize. + * @throws IOException If the data in the string cannot be written. + */ + public void serializeString(@Nonnull DataOutputStream output, String text) throws IOException { + if (output == null) + throw new IllegalArgumentException("output stream cannot be NULL."); + if (text == null) + throw new IllegalArgumentException("text cannot be NULL."); + + if (MinecraftReflection.isUsingNetty()) { + if (WRITE_STRING_METHOD == null) { + WRITE_STRING_METHOD = Accessors.getMethodAccessor( + FuzzyReflection.fromClass(MinecraftReflection.getPacketDataSerializerClass(), true). + getMethodByParameters("writeString", /* a */ + String.class) + ); + } + + WRITE_STRING_METHOD.invoke(Netty.packetWriter(output).getHandle(), text); + } else { + if (WRITE_STRING_METHOD == null) { + WRITE_STRING_METHOD = Accessors.getMethodAccessor( + FuzzyReflection.fromClass(MinecraftReflection.getPacketClass()).getMethod( + FuzzyMethodContract.newBuilder(). + parameterCount(2). + parameterExactType(String.class, 0). + parameterDerivedOf(DataOutput.class, 1). + returnTypeVoid(). + build()) + ); + } + + WRITE_STRING_METHOD.invoke(null, text, output); + } + } /** * Deserialize a string using the standard Minecraft UTF-16 encoding. @@ -226,21 +267,101 @@ public class StreamSerializer { return (String) READ_STRING_METHOD.invoke(null, input, maximumLength); } } - + + /** + * Serialize an item stack as a base-64 encoded string. + *

+ * Note: An ItemStack can be written to the serialized text even if it's NULL. + * + * @param stack - the item stack to serialize, or NULL to represent air/nothing. + * @return A base-64 representation of the given item stack. + * @throws IOException If the operation fails due to reflection problems. + */ + public String serializeItemStack(ItemStack stack) throws IOException { + Object nmsItem = MinecraftReflection.getMinecraftItemStack(stack); + byte[] bytes = null; + + if (MinecraftReflection.isUsingNetty()) { + WrappedByteBuf buf = Netty.buffer(); + Object serializer = MinecraftReflection.getPacketDataSerializer(buf.getHandle()); + + if (WRITE_ITEM_METHOD == null) { + WRITE_ITEM_METHOD = Accessors.getMethodAccessor( + FuzzyReflection.fromClass(MinecraftReflection.getPacketDataSerializerClass(), true). + getMethodByParameters("writeStack", // a() + MinecraftReflection.getItemStackClass())); + } + + WRITE_ITEM_METHOD.invoke(serializer, nmsItem); + + bytes = buf.array(); + } else { + if (WRITE_ITEM_METHOD == null) { + WRITE_ITEM_METHOD = Accessors.getMethodAccessor( + FuzzyReflection.fromClass(MinecraftReflection.getPacketClass()).getMethod( + FuzzyMethodContract.newBuilder(). + parameterCount(2). + parameterDerivedOf(MinecraftReflection.getItemStackClass(), 0). + parameterDerivedOf(DataOutput.class, 1). + build()) + ); + } + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + DataOutputStream dataOutput = new DataOutputStream(outputStream); + + WRITE_ITEM_METHOD.invoke(null, nmsItem, dataOutput); + + bytes = outputStream.toByteArray(); + } + + return Base64Coder.encodeLines(bytes); + } + /** * Deserialize an item stack from a base-64 encoded string. * @param input - base-64 encoded string. * @return A deserialized item stack, or NULL if the serialized ItemStack was also NULL. * @throws IOException If the operation failed due to reflection or corrupt data. */ - public ItemStack deserializeItemStack(@Nonnull String input) throws IOException { - if (input == null) - throw new IllegalArgumentException("Input text cannot be NULL."); - ByteArrayInputStream inputStream = new ByteArrayInputStream(Base64Coder.decodeLines(input)); - - return deserializeItemStack(new DataInputStream(inputStream)); + public ItemStack deserializeItemStack(String input) throws IOException { + Validate.notNull(input, "input cannot be null!"); + + Object nmsItem = null; + byte[] bytes = Base64Coder.decodeLines(input); + + if (MinecraftReflection.isUsingNetty()) { + WrappedByteBuf buf = Netty.copiedBuffer(bytes); + Object serializer = MinecraftReflection.getPacketDataSerializer(buf.getHandle()); + + if (READ_ITEM_METHOD == null) { + READ_ITEM_METHOD = Accessors.getMethodAccessor(FuzzyReflection.fromClass(MinecraftReflection.getPacketDataSerializerClass(), true). + getMethodByParameters("readItemStack", // i(ItemStack) + MinecraftReflection.getItemStackClass(), new Class[0])); + } + + nmsItem = READ_ITEM_METHOD.invoke(serializer); + } else { + if (READ_ITEM_METHOD == null) { + READ_ITEM_METHOD = Accessors.getMethodAccessor( + FuzzyReflection.fromClass(MinecraftReflection.getPacketClass()).getMethod( + FuzzyMethodContract.newBuilder(). + parameterCount(1). + parameterDerivedOf(DataInput.class). + returnDerivedOf(MinecraftReflection.getItemStackClass()). + build()) + ); + } + + ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes); + DataInputStream inputStream = new DataInputStream(byteStream); + + nmsItem = READ_ITEM_METHOD.invoke(null, inputStream); + } + + return nmsItem != null ? MinecraftReflection.getBukkitItemStack(nmsItem) : null; } - + /** * Write or serialize an item stack to the given output stream. *

@@ -253,9 +374,8 @@ public class StreamSerializer { * @param stack - the item stack that will be written, or NULL to represent air/nothing. * @throws IOException If the operation fails due to reflection problems. */ - public void serializeItemStack(@Nonnull DataOutputStream output, ItemStack stack) throws IOException { - if (output == null) - throw new IllegalArgumentException("Output stream cannot be NULL."); + public void serializeItemStack(DataOutputStream output, ItemStack stack) throws IOException { + Validate.notNull("output cannot be null!"); // Get the NMS version of the ItemStack Object nmsItem = MinecraftReflection.getMinecraftItemStack(stack); @@ -269,7 +389,12 @@ public class StreamSerializer { ); } - WRITE_ITEM_METHOD.invoke(Netty.packetWriter(output).getHandle(), nmsItem); + WrappedByteBuf buf = Netty.buffer(); + Object serializer = MinecraftReflection.getPacketDataSerializer(buf.getHandle()); + + WRITE_ITEM_METHOD.invoke(serializer, nmsItem); + + output.write(buf.array()); } else { if (WRITE_ITEM_METHOD == null) WRITE_ITEM_METHOD = Accessors.getMethodAccessor( @@ -284,110 +409,58 @@ public class StreamSerializer { WRITE_ITEM_METHOD.invoke(null, nmsItem, output); } } - + /** - * Write or serialize a NBT compound to the given output stream. + * Read or deserialize an item stack from an underlying input stream. *

- * Note: An NBT compound can be written to a stream even if it's NULL. + * To supply a byte array, wrap it in a {@link java.io.ByteArrayInputStream ByteArrayInputStream} + * and {@link java.io.DataInputStream DataInputStream}. * - * @param output - the target output stream. - * @param compound - the NBT compound to be serialized, or NULL to represent nothing. - * @throws IOException If the operation fails due to reflection problems. + * @param input - the target input stream. + * @return The resulting item stack, or NULL if the serialized item stack was NULL. + * @throws IOException If the operation failed due to reflection or corrupt data. + * @deprecated This is a pretty hacky solution for backwards compatibility. See {@link #deserializeItemStack(DataInputStream)} */ - public void serializeCompound(@Nonnull DataOutputStream output, NbtCompound compound) throws IOException { - if (output == null) - throw new IllegalArgumentException("Output stream cannot be NULL."); - - // Get the NMS version of the compound - Object handle = compound != null ? NbtFactory.fromBase(compound).getHandle() : null; + @Deprecated + public ItemStack deserializeItemStack(DataInputStream input) throws IOException { + Validate.notNull(input, "input cannot be null!"); + Object nmsItem = null; if (MinecraftReflection.isUsingNetty()) { - if (WRITE_NBT_METHOD == null) { - WRITE_NBT_METHOD = Accessors.getMethodAccessor( + if (READ_ITEM_METHOD == null) { + READ_ITEM_METHOD = Accessors.getMethodAccessor( FuzzyReflection.fromClass(MinecraftReflection.getPacketDataSerializerClass(), true). - getMethodByParameters("writeNbtCompound", /* a */ - MinecraftReflection.getNBTCompoundClass()) + getMethodByParameters("readItemStack", /* i */ + MinecraftReflection.getItemStackClass(), new Class[0]) ); } - WrappedByteBuf buf = Netty.packetWriter(output); - buf.writeByte(NbtType.TAG_COMPOUND.getRawID()); + byte[] bytes = new byte[8192]; + input.read(bytes); - WRITE_NBT_METHOD.invoke(buf.getHandle(), handle); + WrappedByteBuf buf = Netty.copiedBuffer(bytes); + Object serializer = MinecraftReflection.getPacketDataSerializer(buf.getHandle()); + + nmsItem = READ_ITEM_METHOD.invoke(serializer); } else { - if (WRITE_NBT_METHOD == null) { - WRITE_NBT_METHOD = Accessors.getMethodAccessor( - FuzzyReflection.fromClass(MinecraftReflection.getPacketClass(), true).getMethod( - FuzzyMethodContract.newBuilder(). - parameterCount(2). - parameterDerivedOf(MinecraftReflection.getNBTBaseClass(), 0). - parameterDerivedOf(DataOutput.class, 1). - returnTypeVoid(). - build()) - ); - } - - WRITE_NBT_METHOD.invoke(null, handle, output); - } - } - - /** - * Serialize a string using the standard Minecraft UTF-16 encoding. - *

- * Note that strings cannot exceed 32767 characters, regardless if maximum lenght. - * @param output - the output stream. - * @param text - the string to serialize. - * @throws IOException If the data in the string cannot be written. - */ - public void serializeString(@Nonnull DataOutputStream output, String text) throws IOException { - if (output == null) - throw new IllegalArgumentException("output stream cannot be NULL."); - if (text == null) - throw new IllegalArgumentException("text cannot be NULL."); - - if (MinecraftReflection.isUsingNetty()) { - if (WRITE_STRING_METHOD == null) { - WRITE_STRING_METHOD = Accessors.getMethodAccessor( - FuzzyReflection.fromClass(MinecraftReflection.getPacketDataSerializerClass(), true). - getMethodByParameters("writeString", /* a */ - String.class) - ); - } - - WRITE_STRING_METHOD.invoke(Netty.packetWriter(output).getHandle(), text); - } else { - if (WRITE_STRING_METHOD == null) { - WRITE_STRING_METHOD = Accessors.getMethodAccessor( + if (READ_ITEM_METHOD == null) { + READ_ITEM_METHOD = Accessors.getMethodAccessor( FuzzyReflection.fromClass(MinecraftReflection.getPacketClass()).getMethod( FuzzyMethodContract.newBuilder(). - parameterCount(2). - parameterExactType(String.class, 0). - parameterDerivedOf(DataOutput.class, 1). - returnTypeVoid(). + parameterCount(1). + parameterDerivedOf(DataInput.class). + returnDerivedOf(MinecraftReflection.getItemStackClass()). build()) - ); + ); } - WRITE_STRING_METHOD.invoke(null, text, output); + nmsItem = READ_ITEM_METHOD.invoke(null, input); } - } - /** - * Serialize an item stack as a base-64 encoded string. - *

- * Note: An ItemStack can be written to the serialized text even if it's NULL. - * - * @param stack - the item stack to serialize, or NULL to represent air/nothing. - * @return A base-64 representation of the given item stack. - * @throws IOException If the operation fails due to reflection problems. - */ - public String serializeItemStack(ItemStack stack) throws IOException { - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - DataOutputStream dataOutput = new DataOutputStream(outputStream); - - serializeItemStack(dataOutput, stack); - - // Serialize that array - return Base64Coder.encodeLines(outputStream.toByteArray()); + // Convert back to a Bukkit item stack + if (nmsItem != null) + return MinecraftReflection.getBukkitItemStack(nmsItem); + else + return null; } -} +} \ No newline at end of file diff --git a/ProtocolLib/src/test/java/com/comphenix/protocol/utility/StreamSerializerTest.java b/ProtocolLib/src/test/java/com/comphenix/protocol/utility/StreamSerializerTest.java index fead73fa..01b74431 100644 --- a/ProtocolLib/src/test/java/com/comphenix/protocol/utility/StreamSerializerTest.java +++ b/ProtocolLib/src/test/java/com/comphenix/protocol/utility/StreamSerializerTest.java @@ -10,8 +10,11 @@ import java.io.IOException; import net.minecraft.server.v1_8_R3.IntHashMap; +import org.bukkit.ChatColor; +import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; import org.junit.BeforeClass; import org.junit.Test; import org.junit.runner.RunWith; @@ -30,37 +33,24 @@ public class StreamSerializerTest { public static void initializeBukkit() throws IllegalAccessException { BukkitInitialization.initializeItemMeta(); } - + @Test public void testMinecraftReflection() { assertEquals(IntHashMap.class, MinecraftReflection.getIntHashMapClass()); } - - @Test - public void testSerializer() throws IOException { - ItemStack before = new ItemStack(Material.GOLD_AXE); - - StreamSerializer serializer = new StreamSerializer(); - String data = serializer.serializeItemStack(before); - ItemStack after = serializer.deserializeItemStack(data); - - assertEquals(before.getType(), after.getType()); - assertEquals(before.getAmount(), after.getAmount()); - } - + @Test public void testStrings() throws IOException { StreamSerializer serializer = new StreamSerializer(); String initial = "Hello - this is a ÆØÅ test."; - + // Buffer ByteArrayOutputStream buffer = new ByteArrayOutputStream(); serializer.serializeString(new DataOutputStream(buffer), initial); - - DataInputStream input = new DataInputStream( - new ByteArrayInputStream(buffer.toByteArray())); + + DataInputStream input = new DataInputStream(new ByteArrayInputStream(buffer.toByteArray())); String deserialized = serializer.deserializeString(input, 50); - + assertEquals(initial, deserialized); } @@ -75,11 +65,10 @@ public class StreamSerializerTest { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); serializer.serializeCompound(new DataOutputStream(buffer), initial); - - DataInputStream input = new DataInputStream( - new ByteArrayInputStream(buffer.toByteArray())); + + DataInputStream input = new DataInputStream(new ByteArrayInputStream(buffer.toByteArray())); NbtCompound deserialized = serializer.deserializeCompound(input); - + assertEquals(initial, deserialized); } @@ -88,13 +77,24 @@ public class StreamSerializerTest { StreamSerializer serializer = new StreamSerializer(); ItemStack initial = new ItemStack(Material.STRING); - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - serializer.serializeItemStack(new DataOutputStream(buffer), initial); - - DataInputStream input = new DataInputStream( - new ByteArrayInputStream(buffer.toByteArray())); - ItemStack deserialized = serializer.deserializeItemStack(input); - + String serialized = serializer.serializeItemStack(initial); + ItemStack deserialized = serializer.deserializeItemStack(serialized); + + assertEquals(initial, deserialized); + } + + @Test + public void testItemMeta() throws IOException { + StreamSerializer serializer = new StreamSerializer(); + ItemStack initial = new ItemStack(Material.WOOL, 2, DyeColor.BLUE.getWoolData()); + + ItemMeta meta = initial.getItemMeta(); + meta.setDisplayName(ChatColor.BLUE + "Blue Wool"); + initial.setItemMeta(meta); + + String serialized = serializer.serializeItemStack(initial); + ItemStack deserialized = serializer.deserializeItemStack(serialized); + assertEquals(initial, deserialized); } } \ No newline at end of file diff --git a/modules/v1_7_R4/src/main/java/com/comphenix/protocol/compat/netty/shaded/ShadedByteBuf.java b/modules/v1_7_R4/src/main/java/com/comphenix/protocol/compat/netty/shaded/ShadedByteBuf.java index 0cbb3a4c..27767cb9 100644 --- a/modules/v1_7_R4/src/main/java/com/comphenix/protocol/compat/netty/shaded/ShadedByteBuf.java +++ b/modules/v1_7_R4/src/main/java/com/comphenix/protocol/compat/netty/shaded/ShadedByteBuf.java @@ -75,4 +75,9 @@ public class ShadedByteBuf implements WrappedByteBuf { public void writeBytes(byte[] bytes) { handle.get().writeBytes(bytes); } + + @Override + public byte[] array() { + return handle.get().array(); + } } \ No newline at end of file diff --git a/modules/v1_7_R4/src/main/java/com/comphenix/protocol/compat/netty/shaded/ShadedNetty.java b/modules/v1_7_R4/src/main/java/com/comphenix/protocol/compat/netty/shaded/ShadedNetty.java index a225fccb..6651edb2 100644 --- a/modules/v1_7_R4/src/main/java/com/comphenix/protocol/compat/netty/shaded/ShadedNetty.java +++ b/modules/v1_7_R4/src/main/java/com/comphenix/protocol/compat/netty/shaded/ShadedNetty.java @@ -55,11 +55,6 @@ public class ShadedNetty implements NettyCompat { } } - @Override - public WrappedByteBuf allocateUnpooled() { - return new ShadedByteBuf(UnpooledByteBufAllocator.DEFAULT.buffer()); - } - @Override public Class getGenericFutureListenerArray() { return GenericFutureListener[].class; @@ -97,4 +92,14 @@ public class ShadedNetty implements NettyCompat { public WrappedByteBuf packetWriter(DataOutputStream output) { return new ShadedByteBuf(ShadedByteBufAdapter.packetWriter(output)); } + + @Override + public WrappedByteBuf copiedBuffer(byte[] array) { + return new ShadedByteBuf(Unpooled.copiedBuffer(array)); + } + + @Override + public WrappedByteBuf buffer() { + return new ShadedByteBuf(Unpooled.buffer()); + } } \ No newline at end of file