From c7592d281a7449a4ce2276ed3fcee6607f8dfcc4 Mon Sep 17 00:00:00 2001 From: JustRed23 Date: Sun, 1 Sep 2024 18:45:30 +0200 Subject: [PATCH 1/3] Fix serializing and deserializing of ItemStack on 1.21 --- .../protocol/utility/StreamSerializer.java | 57 ++++++++++++++++--- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/comphenix/protocol/utility/StreamSerializer.java b/src/main/java/com/comphenix/protocol/utility/StreamSerializer.java index 0d1f4de24..1561bcc61 100644 --- a/src/main/java/com/comphenix/protocol/utility/StreamSerializer.java +++ b/src/main/java/com/comphenix/protocol/utility/StreamSerializer.java @@ -10,6 +10,7 @@ import com.comphenix.protocol.injector.netty.NettyByteBufAdapter; import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.accessors.Accessors; +import com.comphenix.protocol.reflect.accessors.FieldAccessor; import com.comphenix.protocol.reflect.accessors.MethodAccessor; import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; import com.comphenix.protocol.wrappers.nbt.NbtCompound; @@ -31,6 +32,7 @@ public class StreamSerializer { private static final StreamSerializer DEFAULT = new StreamSerializer(); // Cached methods + private static FieldAccessor STREAM_CODEC; private static MethodAccessor READ_ITEM_METHOD; private static MethodAccessor WRITE_ITEM_METHOD; @@ -235,14 +237,33 @@ public ItemStack deserializeItemStackFromByteArray(byte[] input) { Object serializer = MinecraftReflection.getPacketDataSerializer(buf); if (READ_ITEM_METHOD == null) { - READ_ITEM_METHOD = Accessors.getMethodAccessor(FuzzyReflection - .fromClass(serializer.getClass(), false) - .getMethodByReturnTypeAndParameters("readItemStack", MinecraftReflection.getItemStackClass())); + if (MinecraftVersion.v1_21_0.atOrAbove()) { + if (STREAM_CODEC == null) { + STREAM_CODEC = Accessors.getFieldAccessor(FuzzyReflection + .fromClass(MinecraftReflection.getItemStackClass()) + .getFieldByType("STREAM_CODEC", MinecraftReflection.getStreamCodecClass())); + } + + READ_ITEM_METHOD = Accessors.getMethodAccessor(FuzzyReflection.fromObject(STREAM_CODEC.get(null), true) + .getMethod(FuzzyMethodContract.newBuilder() + .parameterExactType(MinecraftReflection.getRegistryFriendlyByteBufClass().get()) + .returnTypeExact(MinecraftReflection.getItemStackClass()) + .build())); + } else { + READ_ITEM_METHOD = Accessors.getMethodAccessor(FuzzyReflection + .fromClass(serializer.getClass(), false) + .getMethodByReturnTypeAndParameters("readItemStack", MinecraftReflection.getItemStackClass())); + } } try { // unwrap the item - Object nmsItem = READ_ITEM_METHOD.invoke(serializer); + Object nmsItem; + if (MinecraftVersion.v1_21_0.atOrAbove()) { + nmsItem = READ_ITEM_METHOD.invoke(STREAM_CODEC.get(null), serializer); + } else { + nmsItem = READ_ITEM_METHOD.invoke(serializer); + } return nmsItem != null ? MinecraftReflection.getBukkitItemStack(nmsItem) : null; } finally { ReferenceCountUtil.safeRelease(buf); @@ -262,11 +283,24 @@ public ItemStack deserializeItemStackFromByteArray(byte[] input) { * @throws IOException If the operation fails due to reflection problems. */ public void serializeItemStack(DataOutputStream output, ItemStack stack) throws IOException { - // TODO this functionality was replaced by the CODEC field in the nms ItemStack if (WRITE_ITEM_METHOD == null) { - WRITE_ITEM_METHOD = Accessors.getMethodAccessor(FuzzyReflection - .fromClass(MinecraftReflection.getPacketDataSerializerClass(), true) - .getMethodByParameters("writeStack", MinecraftReflection.getItemStackClass())); + if (MinecraftVersion.v1_21_0.atOrAbove()) { + if (STREAM_CODEC == null) { + STREAM_CODEC = Accessors.getFieldAccessor(FuzzyReflection + .fromClass(MinecraftReflection.getItemStackClass()) + .getFieldByType("STREAM_CODEC", MinecraftReflection.getStreamCodecClass())); + } + + WRITE_ITEM_METHOD = Accessors.getMethodAccessor(FuzzyReflection.fromObject(STREAM_CODEC.get(null), true) + .getMethod(FuzzyMethodContract.newBuilder() + .parameterExactArray(MinecraftReflection.getRegistryFriendlyByteBufClass().get(), MinecraftReflection.getItemStackClass()) + .returnTypeExact(void.class) + .build())); + } else { + WRITE_ITEM_METHOD = Accessors.getMethodAccessor(FuzzyReflection + .fromClass(MinecraftReflection.getPacketDataSerializerClass(), true) + .getMethodByParameters("writeStack", MinecraftReflection.getItemStackClass())); + } } ByteBuf buf = Unpooled.buffer(); @@ -274,7 +308,12 @@ public void serializeItemStack(DataOutputStream output, ItemStack stack) throws // Get the NMS version of the ItemStack and write it into the buffer Object nmsItem = MinecraftReflection.getMinecraftItemStack(stack); - WRITE_ITEM_METHOD.invoke(serializer, nmsItem); + + if (MinecraftVersion.v1_21_0.atOrAbove()) { + WRITE_ITEM_METHOD.invoke(STREAM_CODEC.get(null), serializer, nmsItem); + } else { + WRITE_ITEM_METHOD.invoke(serializer, nmsItem); + } // write the serialized content to the stream output.write(this.getBytesAndRelease(buf)); From f6887f7ef617000edbc5af5feceb59edf2a668bb Mon Sep 17 00:00:00 2001 From: JustRed23 Date: Sun, 1 Sep 2024 19:20:56 +0200 Subject: [PATCH 2/3] Fix incorrect STREAM_CODEC --- .../com/comphenix/protocol/utility/StreamSerializer.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/comphenix/protocol/utility/StreamSerializer.java b/src/main/java/com/comphenix/protocol/utility/StreamSerializer.java index 1561bcc61..e6a5ae967 100644 --- a/src/main/java/com/comphenix/protocol/utility/StreamSerializer.java +++ b/src/main/java/com/comphenix/protocol/utility/StreamSerializer.java @@ -12,6 +12,7 @@ import com.comphenix.protocol.reflect.accessors.Accessors; import com.comphenix.protocol.reflect.accessors.FieldAccessor; import com.comphenix.protocol.reflect.accessors.MethodAccessor; +import com.comphenix.protocol.reflect.fuzzy.FuzzyFieldContract; import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; import com.comphenix.protocol.wrappers.nbt.NbtCompound; import com.comphenix.protocol.wrappers.nbt.NbtFactory; @@ -241,7 +242,9 @@ public ItemStack deserializeItemStackFromByteArray(byte[] input) { if (STREAM_CODEC == null) { STREAM_CODEC = Accessors.getFieldAccessor(FuzzyReflection .fromClass(MinecraftReflection.getItemStackClass()) - .getFieldByType("STREAM_CODEC", MinecraftReflection.getStreamCodecClass())); + .getFieldList(FuzzyFieldContract.newBuilder() + .typeExact(MinecraftReflection.getStreamCodecClass()) + .build()).get(1)); //skip OPTIONAL_STREAM_CODEC } READ_ITEM_METHOD = Accessors.getMethodAccessor(FuzzyReflection.fromObject(STREAM_CODEC.get(null), true) @@ -288,7 +291,9 @@ public void serializeItemStack(DataOutputStream output, ItemStack stack) throws if (STREAM_CODEC == null) { STREAM_CODEC = Accessors.getFieldAccessor(FuzzyReflection .fromClass(MinecraftReflection.getItemStackClass()) - .getFieldByType("STREAM_CODEC", MinecraftReflection.getStreamCodecClass())); + .getFieldList(FuzzyFieldContract.newBuilder() + .typeExact(MinecraftReflection.getStreamCodecClass()) + .build()).get(1)); //skip OPTIONAL_STREAM_CODEC } WRITE_ITEM_METHOD = Accessors.getMethodAccessor(FuzzyReflection.fromObject(STREAM_CODEC.get(null), true) From 7feffbe7fa26c62b336fc593cfe411c06c8b1c05 Mon Sep 17 00:00:00 2001 From: JustRed23 Date: Mon, 23 Sep 2024 11:21:31 +0200 Subject: [PATCH 3/3] Re-enable tests --- .../com/comphenix/protocol/utility/StreamSerializerTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/com/comphenix/protocol/utility/StreamSerializerTest.java b/src/test/java/com/comphenix/protocol/utility/StreamSerializerTest.java index 1d73f7c24..301ad6877 100644 --- a/src/test/java/com/comphenix/protocol/utility/StreamSerializerTest.java +++ b/src/test/java/com/comphenix/protocol/utility/StreamSerializerTest.java @@ -60,7 +60,6 @@ public void testCompound() throws IOException { } @Test - @Disabled // TODO -- replaced with registry friendly bytebuf public void testItems() throws IOException { StreamSerializer serializer = new StreamSerializer(); ItemStack initial = new ItemStack(Material.STRING); @@ -72,7 +71,6 @@ public void testItems() throws IOException { } @Test - @Disabled // TODO -- replaced with registry friendly bytebuf public void testItemMeta() throws IOException { StreamSerializer serializer = new StreamSerializer(); ItemStack initial = new ItemStack(Material.BLUE_WOOL, 2);