diff --git a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/entity/DataWatcher.java b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/entity/DataWatcher.java index 2b988d6eb..6cb20322a 100644 --- a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/entity/DataWatcher.java +++ b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/entity/DataWatcher.java @@ -13,9 +13,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; +import java.util.*; /** * A class representing the n.m.s.DataWatcher class to make work with it much easier @@ -23,16 +21,6 @@ @ToString public class DataWatcher implements EntityData { - /** NMS Fields */ - public static Class DataWatcher; - private static Constructor newDataWatcher; - private static Method DataWatcher_register; - private static Method DataWatcher_markDirty; - public static Method DataWatcher_packDirty; - - private static Class DataWatcherObject; - private static Constructor newDataWatcherObject; - private static Object DataWatcherSerializer_BYTE; private static Object DataWatcherSerializer_FLOAT; private static Object DataWatcherSerializer_STRING; @@ -41,6 +29,15 @@ public class DataWatcher implements EntityData { private static final int armorStandFlagsPosition = EntityData.getArmorStandFlagsPosition(BukkitReflection.getMinorVersion()); + /** 1.19.3+ */ + private static Constructor newDataWatcher$Item; + + /** 1.19.2- */ + public static Class DataWatcher; + private static Constructor newDataWatcher; + private static Method DataWatcher_register; + private static Constructor newDataWatcherObject; + /** Watched data */ private final Map dataValues = new HashMap<>(); @@ -52,58 +49,65 @@ public class DataWatcher implements EntityData { */ public static void load() throws ReflectiveOperationException { int minorVersion = BukkitReflection.getMinorVersion(); - DataWatcher = BukkitReflection.getClass("network.syncher.SynchedEntityData", "network.syncher.DataWatcher", "DataWatcher"); - if (minorVersion >= 7) { - ComponentConverter.ensureAvailable(); - newDataWatcher = DataWatcher.getConstructor(BukkitReflection.getClass("world.entity.Entity", "Entity")); - } else { - newDataWatcher = DataWatcher.getConstructor(); - } if (minorVersion >= 9) { - DataWatcherObject = BukkitReflection.getClass("network.syncher.EntityDataAccessor", - "network.syncher.DataWatcherObject", "DataWatcherObject"); - Class dataWatcherRegistry = BukkitReflection.getClass("network.syncher.EntityDataSerializers", - "network.syncher.DataWatcherRegistry", "DataWatcherRegistry"); + loadSerializers(); + } + if (BukkitReflection.is1_19_3Plus()) { + Class dataWatcher$Item = BukkitReflection.getClass("network.syncher.SynchedEntityData$DataValue", "network.syncher.DataWatcher$c"); Class dataWatcherSerializer = BukkitReflection.getClass("network.syncher.EntityDataSerializer", "network.syncher.DataWatcherSerializer", "DataWatcherSerializer"); - DataWatcher_register = ReflectionUtils.getMethod( - DataWatcher, - new String[]{"define", "register", "a", "m_135372_"}, // {Mojang, Bukkit, Bukkit 1.18+, Mohist 1.18.2} - DataWatcherObject, Object.class - ); - newDataWatcherObject = DataWatcherObject.getConstructor(int.class, dataWatcherSerializer); - DataWatcherSerializer_BYTE = ReflectionUtils.getField(dataWatcherRegistry, "BYTE", "a", "f_135027_").get(null); // Mohist 1.18.2 - DataWatcherSerializer_FLOAT = ReflectionUtils.getField(dataWatcherRegistry, "FLOAT", "c", "f_135029_").get(null); // Mohist 1.18.2 - DataWatcherSerializer_STRING = ReflectionUtils.getField(dataWatcherRegistry, "STRING", "d", "f_135030_").get(null); // Mohist 1.18.2 - if (BukkitReflection.is1_19_3Plus()) { - DataWatcherSerializer_OPTIONAL_COMPONENT = ReflectionUtils.getField(dataWatcherRegistry, "OPTIONAL_COMPONENT", "g").get(null); - if (BukkitReflection.is1_19_4Plus()) { - DataWatcherSerializer_BOOLEAN = ReflectionUtils.getField(dataWatcherRegistry, "BOOLEAN", "k").get(null); - } else { - DataWatcherSerializer_BOOLEAN = ReflectionUtils.getField(dataWatcherRegistry, "BOOLEAN", "j").get(null); - } + newDataWatcher$Item = dataWatcher$Item.getConstructor(int.class, dataWatcherSerializer, Object.class); + } else { + DataWatcher = BukkitReflection.getClass("network.syncher.SynchedEntityData", "network.syncher.DataWatcher", "DataWatcher"); + if (minorVersion >= 7) { + ComponentConverter.ensureAvailable(); + newDataWatcher = DataWatcher.getConstructor(BukkitReflection.getClass("world.entity.Entity", "Entity")); } else { - if (minorVersion >= 13) { - DataWatcherSerializer_OPTIONAL_COMPONENT = ReflectionUtils.getField(dataWatcherRegistry, - "OPTIONAL_COMPONENT", "f", "f_135032_").get(null); // Mohist 1.18.2 - DataWatcherSerializer_BOOLEAN = ReflectionUtils.getField(dataWatcherRegistry, - "BOOLEAN", "i", "f_135035_").get(null); // Mohist 1.18.2 - } else { - DataWatcherSerializer_BOOLEAN = dataWatcherRegistry.getDeclaredField("h").get(null); - } + newDataWatcher = DataWatcher.getConstructor(); + } + if (minorVersion >= 9) { + Class dataWatcherObject = BukkitReflection.getClass("network.syncher.EntityDataAccessor", + "network.syncher.DataWatcherObject", "DataWatcherObject"); + Class dataWatcherSerializer = BukkitReflection.getClass("network.syncher.EntityDataSerializer", + "network.syncher.DataWatcherSerializer", "DataWatcherSerializer"); + DataWatcher_register = ReflectionUtils.getMethod( + DataWatcher, + new String[]{"define", "register", "a", "m_135372_"}, // {Mojang, Bukkit, Bukkit 1.18+, Mohist 1.18.2} + dataWatcherObject, Object.class + ); + newDataWatcherObject = dataWatcherObject.getConstructor(int.class, dataWatcherSerializer); + } else { + DataWatcher_register = ReflectionUtils.getMethod( + DataWatcher, + new String[]{"func_75682_a", "a"}, int.class, // {Thermos 1.7.10, Bukkit} + Object.class + ); } - } else { - DataWatcher_register = ReflectionUtils.getMethod( - DataWatcher, - new String[]{"func_75682_a", "a"}, int.class, // {Thermos 1.7.10, Bukkit} - Object.class - ); - } - if (minorVersion >= 19) { - DataWatcher_packDirty = ReflectionUtils.getMethod(DataWatcher, new String[] {"packDirty", "b"}); // {Mojang, Bukkit} } + } + + private static void loadSerializers() throws ReflectiveOperationException { + Class dataWatcherRegistry = BukkitReflection.getClass("network.syncher.EntityDataSerializers", + "network.syncher.DataWatcherRegistry", "DataWatcherRegistry"); + DataWatcherSerializer_BYTE = ReflectionUtils.getField(dataWatcherRegistry, "BYTE", "a", "f_135027_").get(null); // Mohist 1.18.2 + DataWatcherSerializer_FLOAT = ReflectionUtils.getField(dataWatcherRegistry, "FLOAT", "c", "f_135029_").get(null); // Mohist 1.18.2 + DataWatcherSerializer_STRING = ReflectionUtils.getField(dataWatcherRegistry, "STRING", "d", "f_135030_").get(null); // Mohist 1.18.2 if (BukkitReflection.is1_19_3Plus()) { - DataWatcher_markDirty = ReflectionUtils.getMethods(DataWatcher, void.class, DataWatcherObject).get(0); + DataWatcherSerializer_OPTIONAL_COMPONENT = ReflectionUtils.getField(dataWatcherRegistry, "OPTIONAL_COMPONENT", "g").get(null); + if (BukkitReflection.is1_19_4Plus()) { + DataWatcherSerializer_BOOLEAN = ReflectionUtils.getField(dataWatcherRegistry, "BOOLEAN", "k").get(null); + } else { + DataWatcherSerializer_BOOLEAN = ReflectionUtils.getField(dataWatcherRegistry, "BOOLEAN", "j").get(null); + } + } else { + if (BukkitReflection.getMinorVersion() >= 13) { + DataWatcherSerializer_OPTIONAL_COMPONENT = ReflectionUtils.getField(dataWatcherRegistry, + "OPTIONAL_COMPONENT", "f", "f_135032_").get(null); // Mohist 1.18.2 + DataWatcherSerializer_BOOLEAN = ReflectionUtils.getField(dataWatcherRegistry, + "BOOLEAN", "i", "f_135035_").get(null); // Mohist 1.18.2 + } else { + DataWatcherSerializer_BOOLEAN = dataWatcherRegistry.getDeclaredField("h").get(null); + } } } @@ -211,19 +215,27 @@ public void setWitherInvulnerableTime(int time) { * @return an instance of NMS.DataWatcher with same data */ @SneakyThrows - public @NotNull Object build() { - Object nmsWatcher; - if (newDataWatcher.getParameterCount() == 1) { //1.7+ - nmsWatcher = newDataWatcher.newInstance(new Object[] {null}); + @NotNull + public Object build() { + if (BukkitReflection.is1_19_3Plus()) { + List items = new ArrayList<>(); + for (Item item : dataValues.values()) { + items.add(newDataWatcher$Item.newInstance(item.position, item.serializer, item.value)); + } + return items; } else { - nmsWatcher = newDataWatcher.newInstance(); - } - for (Item item : dataValues.values()) { - Object nmsObject = item.createObject(); - DataWatcher_register.invoke(nmsWatcher, nmsObject, item.getValue()); - if (BukkitReflection.is1_19_3Plus()) DataWatcher_markDirty.invoke(nmsWatcher, nmsObject); + Object nmsWatcher; + if (newDataWatcher.getParameterCount() == 1) { //1.7+ + nmsWatcher = newDataWatcher.newInstance(new Object[] {null}); + } else { + nmsWatcher = newDataWatcher.newInstance(); + } + for (Item item : dataValues.values()) { + Object nmsObject = item.createObject(); + DataWatcher_register.invoke(nmsWatcher, nmsObject, item.getValue()); + } + return nmsWatcher; } - return nmsWatcher; } /** @@ -241,7 +253,7 @@ private static class Item { private final Object serializer; /** Item value */ - @NotNull + @NonNull private final Object value; /** diff --git a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/entity/PacketEntityView.java b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/entity/PacketEntityView.java index 668279858..50cff5e76 100644 --- a/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/entity/PacketEntityView.java +++ b/bukkit/src/main/java/me/neznamy/tab/platforms/bukkit/entity/PacketEntityView.java @@ -116,7 +116,7 @@ private static void loadEntityMetadata() throws ReflectiveOperationException { "network.protocol.game.PacketPlayOutEntityMetadata", "PacketPlayOutEntityMetadata", "Packet40EntityMetadata"); if (BukkitReflection.is1_19_3Plus()) { Constructor constructor = entityMetadataClass.getConstructor(int.class, List.class); - newEntityMetadata = (entityId, data) -> constructor.newInstance(entityId, DataWatcher.DataWatcher_packDirty.invoke(data.build())); + newEntityMetadata = (entityId, data) -> constructor.newInstance(entityId, data.build()); } else { Constructor constructor = entityMetadataClass.getConstructor(int.class, DataWatcher.DataWatcher, boolean.class); newEntityMetadata = (entityId, data) -> constructor.newInstance(entityId, data.build(), true); diff --git a/shared/src/main/java/me/neznamy/tab/shared/util/ReflectionUtils.java b/shared/src/main/java/me/neznamy/tab/shared/util/ReflectionUtils.java index 78c99e5a9..4e4019966 100644 --- a/shared/src/main/java/me/neznamy/tab/shared/util/ReflectionUtils.java +++ b/shared/src/main/java/me/neznamy/tab/shared/util/ReflectionUtils.java @@ -262,7 +262,7 @@ public static Method getOnlyMethod(@NotNull Class clazz, @NotNull Class re */ @NotNull public static Field getOnlyField(@NotNull Class clazz) { - Field[] fields = clazz.getDeclaredFields(); + Field[] fields = Arrays.stream(clazz.getDeclaredFields()).filter(f -> !Modifier.isStatic(f.getModifiers())).toArray(Field[]::new); if (fields.length != 1) { throw new IllegalStateException("Class " + clazz.getName() + " is expected to have 1 field, but has " + fields.length + ": " + Arrays.stream(fields).map(Field::getName).collect(Collectors.toList()));