10
10
import com .comphenix .protocol .injector .netty .NettyByteBufAdapter ;
11
11
import com .comphenix .protocol .reflect .FuzzyReflection ;
12
12
import com .comphenix .protocol .reflect .accessors .Accessors ;
13
+ import com .comphenix .protocol .reflect .accessors .FieldAccessor ;
13
14
import com .comphenix .protocol .reflect .accessors .MethodAccessor ;
15
+ import com .comphenix .protocol .reflect .fuzzy .FuzzyFieldContract ;
14
16
import com .comphenix .protocol .reflect .fuzzy .FuzzyMethodContract ;
15
17
import com .comphenix .protocol .wrappers .nbt .NbtCompound ;
16
18
import com .comphenix .protocol .wrappers .nbt .NbtFactory ;
@@ -31,6 +33,7 @@ public class StreamSerializer {
31
33
private static final StreamSerializer DEFAULT = new StreamSerializer ();
32
34
33
35
// Cached methods
36
+ private static FieldAccessor STREAM_CODEC ;
34
37
private static MethodAccessor READ_ITEM_METHOD ;
35
38
private static MethodAccessor WRITE_ITEM_METHOD ;
36
39
@@ -235,14 +238,35 @@ public ItemStack deserializeItemStackFromByteArray(byte[] input) {
235
238
Object serializer = MinecraftReflection .getPacketDataSerializer (buf );
236
239
237
240
if (READ_ITEM_METHOD == null ) {
238
- READ_ITEM_METHOD = Accessors .getMethodAccessor (FuzzyReflection
239
- .fromClass (serializer .getClass (), false )
240
- .getMethodByReturnTypeAndParameters ("readItemStack" , MinecraftReflection .getItemStackClass ()));
241
+ if (MinecraftVersion .v1_21_0 .atOrAbove ()) {
242
+ if (STREAM_CODEC == null ) {
243
+ STREAM_CODEC = Accessors .getFieldAccessor (FuzzyReflection
244
+ .fromClass (MinecraftReflection .getItemStackClass ())
245
+ .getFieldList (FuzzyFieldContract .newBuilder ()
246
+ .typeExact (MinecraftReflection .getStreamCodecClass ())
247
+ .build ()).get (1 )); //skip OPTIONAL_STREAM_CODEC
248
+ }
249
+
250
+ READ_ITEM_METHOD = Accessors .getMethodAccessor (FuzzyReflection .fromObject (STREAM_CODEC .get (null ), true )
251
+ .getMethod (FuzzyMethodContract .newBuilder ()
252
+ .parameterExactType (MinecraftReflection .getRegistryFriendlyByteBufClass ().get ())
253
+ .returnTypeExact (MinecraftReflection .getItemStackClass ())
254
+ .build ()));
255
+ } else {
256
+ READ_ITEM_METHOD = Accessors .getMethodAccessor (FuzzyReflection
257
+ .fromClass (serializer .getClass (), false )
258
+ .getMethodByReturnTypeAndParameters ("readItemStack" , MinecraftReflection .getItemStackClass ()));
259
+ }
241
260
}
242
261
243
262
try {
244
263
// unwrap the item
245
- Object nmsItem = READ_ITEM_METHOD .invoke (serializer );
264
+ Object nmsItem ;
265
+ if (MinecraftVersion .v1_21_0 .atOrAbove ()) {
266
+ nmsItem = READ_ITEM_METHOD .invoke (STREAM_CODEC .get (null ), serializer );
267
+ } else {
268
+ nmsItem = READ_ITEM_METHOD .invoke (serializer );
269
+ }
246
270
return nmsItem != null ? MinecraftReflection .getBukkitItemStack (nmsItem ) : null ;
247
271
} finally {
248
272
ReferenceCountUtil .safeRelease (buf );
@@ -262,19 +286,39 @@ public ItemStack deserializeItemStackFromByteArray(byte[] input) {
262
286
* @throws IOException If the operation fails due to reflection problems.
263
287
*/
264
288
public void serializeItemStack (DataOutputStream output , ItemStack stack ) throws IOException {
265
- // TODO this functionality was replaced by the CODEC field in the nms ItemStack
266
289
if (WRITE_ITEM_METHOD == null ) {
267
- WRITE_ITEM_METHOD = Accessors .getMethodAccessor (FuzzyReflection
268
- .fromClass (MinecraftReflection .getPacketDataSerializerClass (), true )
269
- .getMethodByParameters ("writeStack" , MinecraftReflection .getItemStackClass ()));
290
+ if (MinecraftVersion .v1_21_0 .atOrAbove ()) {
291
+ if (STREAM_CODEC == null ) {
292
+ STREAM_CODEC = Accessors .getFieldAccessor (FuzzyReflection
293
+ .fromClass (MinecraftReflection .getItemStackClass ())
294
+ .getFieldList (FuzzyFieldContract .newBuilder ()
295
+ .typeExact (MinecraftReflection .getStreamCodecClass ())
296
+ .build ()).get (1 )); //skip OPTIONAL_STREAM_CODEC
297
+ }
298
+
299
+ WRITE_ITEM_METHOD = Accessors .getMethodAccessor (FuzzyReflection .fromObject (STREAM_CODEC .get (null ), true )
300
+ .getMethod (FuzzyMethodContract .newBuilder ()
301
+ .parameterExactArray (MinecraftReflection .getRegistryFriendlyByteBufClass ().get (), MinecraftReflection .getItemStackClass ())
302
+ .returnTypeExact (void .class )
303
+ .build ()));
304
+ } else {
305
+ WRITE_ITEM_METHOD = Accessors .getMethodAccessor (FuzzyReflection
306
+ .fromClass (MinecraftReflection .getPacketDataSerializerClass (), true )
307
+ .getMethodByParameters ("writeStack" , MinecraftReflection .getItemStackClass ()));
308
+ }
270
309
}
271
310
272
311
ByteBuf buf = Unpooled .buffer ();
273
312
Object serializer = MinecraftReflection .getPacketDataSerializer (buf );
274
313
275
314
// Get the NMS version of the ItemStack and write it into the buffer
276
315
Object nmsItem = MinecraftReflection .getMinecraftItemStack (stack );
277
- WRITE_ITEM_METHOD .invoke (serializer , nmsItem );
316
+
317
+ if (MinecraftVersion .v1_21_0 .atOrAbove ()) {
318
+ WRITE_ITEM_METHOD .invoke (STREAM_CODEC .get (null ), serializer , nmsItem );
319
+ } else {
320
+ WRITE_ITEM_METHOD .invoke (serializer , nmsItem );
321
+ }
278
322
279
323
// write the serialized content to the stream
280
324
output .write (this .getBytesAndRelease (buf ));
0 commit comments