diff --git a/pom.xml b/pom.xml index ae8e8ceb..d1f82b91 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ ${project.version} 2.0.7 - 1.17-R0.1-SNAPSHOT + 1.17.1-R0.1-SNAPSHOT diff --git a/src/main/java/com/comphenix/protocol/PacketType.java b/src/main/java/com/comphenix/protocol/PacketType.java index dc273026..f5ea08a6 100644 --- a/src/main/java/com/comphenix/protocol/PacketType.java +++ b/src/main/java/com/comphenix/protocol/PacketType.java @@ -11,6 +11,7 @@ import java.util.function.Consumer; import com.comphenix.protocol.PacketTypeLookup.ClassLookup; import com.comphenix.protocol.events.ConnectionSide; import com.comphenix.protocol.injector.packet.PacketRegistry; +import com.comphenix.protocol.utility.Constants; import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; import com.google.common.base.Preconditions; @@ -653,7 +654,7 @@ public class PacketType implements Serializable, Cloneable, Comparable> getIntLists() { + return structureModifier.withType( + List.class, + BukkitConverters.getListConverter( + MinecraftReflection.getIntArrayListClass(), + Converters.passthrough(int.class) + ) + ); + } + /** * Retrieve a read/write structure for the Map class. * @param keyConverter Converter for map keys diff --git a/src/main/java/com/comphenix/protocol/utility/MinecraftProtocolVersion.java b/src/main/java/com/comphenix/protocol/utility/MinecraftProtocolVersion.java index 40efd3c8..88575d5e 100644 --- a/src/main/java/com/comphenix/protocol/utility/MinecraftProtocolVersion.java +++ b/src/main/java/com/comphenix/protocol/utility/MinecraftProtocolVersion.java @@ -75,6 +75,7 @@ public class MinecraftProtocolVersion { map.put(new MinecraftVersion(1, 16, 5), 754); map.put(new MinecraftVersion(1, 17, 0), 755); + map.put(new MinecraftVersion(1, 17, 1), 756); return map; } diff --git a/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java b/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java index ac8653e8..f2026048 100644 --- a/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java +++ b/src/main/java/com/comphenix/protocol/utility/MinecraftReflection.java @@ -2250,17 +2250,21 @@ public class MinecraftReflection { return getMinecraftClass("world.entity.ai.attributes.AttributeBase", "AttributeBase"); } - public static Class getInt2ObjectMapClass() { + public static Class getFastUtilClass(String className) { try { - return getMinecraftLibraryClass("it.unimi.dsi.fastutil.ints.Int2ObjectMap"); + return getMinecraftLibraryClass("it.unimi.dsi.fastutil." + className); } catch (RuntimeException ex) { - try { - Class clazz = getMinecraftLibraryClass("org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.Int2ObjectMap"); - setMinecraftLibraryClass("it.unimi.dsi.fastutil.ints.Int2ObjectMap", clazz); - return clazz; - } catch (RuntimeException ignored) { - throw ex; - } + Class clazz = getMinecraftLibraryClass("org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil." + className); + setMinecraftLibraryClass("it.unimi.dsi.fastutil." + className, clazz); + return clazz; } } + + public static Class getInt2ObjectMapClass() { + return getFastUtilClass("ints.Int2ObjectMap"); + } + + public static Class getIntArrayListClass() { + return getFastUtilClass("ints.IntArrayList"); + } } diff --git a/src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java b/src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java index a9532083..0cf6bdd4 100644 --- a/src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java +++ b/src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java @@ -267,7 +267,86 @@ public class BukkitConverters { }; } - private static Map, Supplier>> LIST_SUPPLIERS = new ConcurrentHashMap<>(); + private static final Map, Supplier>> LIST_SUPPLIERS = new ConcurrentHashMap<>(); + + private static Object getGenericList(Class listClass, List specific, EquivalentConverter itemConverter) { + List newList; + Supplier> supplier = LIST_SUPPLIERS.get(listClass); + if (supplier == null) { + try { + Constructor ctor = listClass.getConstructor(); + newList = (List) ctor.newInstance(); + supplier = () -> { + try { + return (List) ctor.newInstance(); + } catch (ReflectiveOperationException ex) { + throw new RuntimeException(ex); + } + }; + } catch (ReflectiveOperationException ex) { + ex.printStackTrace(); + supplier = ArrayList::new; + newList = new ArrayList<>(); + } + + LIST_SUPPLIERS.put(listClass, supplier); + } else { + newList = supplier.get(); + } + + // Convert each object + for (T position : specific) { + if (position != null) { + Object converted = itemConverter.getGeneric(position); + if (converted != null) { + newList.add(converted); + } + } else { + newList.add(null); + } + } + + return newList; + } + + private static List getSpecificList(Object generic, EquivalentConverter itemConverter) { + if (generic instanceof Collection) { + List items = new ArrayList<>(); + + // Copy everything to a new list + for (Object item : (Collection) generic) { + T result = itemConverter.getSpecific(item); + + if (item != null) + items.add(result); + } + return items; + } + + // Not valid + return null; + } + + public static EquivalentConverter> getListConverter(final Class listClass, final EquivalentConverter itemConverter) { + return ignoreNull(new EquivalentConverter>() { + @Override + public List getSpecific(Object generic) { + return getSpecificList(generic, itemConverter); + } + + @Override + public Object getGeneric(List specific) { + return getGenericList(listClass, specific, itemConverter); + } + + @Override + public Class> getSpecificType() { + // Damn you Java + Class dummy = List.class; + return (Class>) dummy; + } + }); + } /** * Retrieve an equivalent converter for a list of generic items. @@ -280,61 +359,12 @@ public class BukkitConverters { return ignoreNull(new EquivalentConverter>() { @Override public List getSpecific(Object generic) { - if (generic instanceof Collection) { - List items = new ArrayList<>(); - - // Copy everything to a new list - for (Object item : (Collection) generic) { - T result = itemConverter.getSpecific(item); - - if (item != null) - items.add(result); - } - return items; - } - - // Not valid - return null; + return getSpecificList(generic, itemConverter); } @Override public Object getGeneric(List specific) { - List newList; - Supplier> supplier = LIST_SUPPLIERS.get(specific.getClass()); - if (supplier == null) { - try { - Constructor ctor = specific.getClass().getConstructor(); - newList = (List) ctor.newInstance(); - supplier = () -> { - try { - return (List) ctor.newInstance(); - } catch (ReflectiveOperationException ex) { - throw new RuntimeException(ex); - } - }; - } catch (ReflectiveOperationException ex) { - supplier = ArrayList::new; - newList = new ArrayList<>(); - } - - LIST_SUPPLIERS.put(specific.getClass(), supplier); - } else { - newList = supplier.get(); - } - - // Convert each object - for (T position : specific) { - if (position != null) { - Object converted = itemConverter.getGeneric(position); - if (converted != null) { - newList.add(converted); - } - } else { - newList.add(null); - } - } - - return newList; + return getGenericList(specific.getClass(), specific, itemConverter); } @Override diff --git a/src/test/java/com/comphenix/protocol/events/PacketContainerTest.java b/src/test/java/com/comphenix/protocol/events/PacketContainerTest.java index 300af14e..cf184f4c 100644 --- a/src/test/java/com/comphenix/protocol/events/PacketContainerTest.java +++ b/src/test/java/com/comphenix/protocol/events/PacketContainerTest.java @@ -385,6 +385,19 @@ public class PacketContainerTest { assertEquals("Test", copy.getStrings().read(0)); } + @Test + public void testIntList() { + PacketContainer destroy = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY); + destroy.getIntLists().write(0, new ArrayList() {{ + add(420); + add(69); + }}); + List back = destroy.getIntLists().read(0); + assertEquals(back.size(), 2); + assertEquals((int) back.get(0), 420); + assertEquals((int) back.get(1), 69); + } + @Test public void testAttributeList() { PacketContainer attribute = new PacketContainer(PacketType.Play.Server.UPDATE_ATTRIBUTES); diff --git a/src/test/java/com/comphenix/protocol/reflect/cloning/AggregateClonerTest.java b/src/test/java/com/comphenix/protocol/reflect/cloning/AggregateClonerTest.java index b7c76654..ca10131f 100644 --- a/src/test/java/com/comphenix/protocol/reflect/cloning/AggregateClonerTest.java +++ b/src/test/java/com/comphenix/protocol/reflect/cloning/AggregateClonerTest.java @@ -3,6 +3,7 @@ package com.comphenix.protocol.reflect.cloning; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import java.lang.reflect.Field; import java.util.Arrays; import java.util.List; @@ -20,7 +21,7 @@ public class AggregateClonerTest { @BeforeClass public static void initializeBukkit() { - BukkitInitialization.initializePackage(); + BukkitInitialization.initializeItemMeta(); } @Test @@ -29,7 +30,8 @@ public class AggregateClonerTest { assertEquals(input, AggregateCloner.DEFAULT.clone(input)); } - @Test + // @Test + // Usages of NonNullList were removed in 1.17.1 public void testNonNullList() { PacketContainer packet = new PacketContainer(PacketType.Play.Server.WINDOW_ITEMS);