From 95432d438e89db28db04b4770e91e4ee0c932aff Mon Sep 17 00:00:00 2001 From: D3v1s0m Date: Thu, 15 May 2025 23:33:06 +0530 Subject: [PATCH] chore: bump PacketEvents to 2.8.0 fix: baby property and a mem leak add: zombie related properties --- .../api/NpcPropertyRegistryProvider.java | 6 ++- .../api/entity/EntityPropertyRegistry.java | 16 +++++- .../lol/pyr/znpcsplus/util/ZombieType.java | 11 ++++ plugin/build.gradle | 2 +- .../java/lol/pyr/znpcsplus/ZNpcsPlus.java | 4 +- .../commands/property/PropertySetCommand.java | 1 + .../znpcsplus/entity/EntityPropertyImpl.java | 10 ++-- .../entity/EntityPropertyRegistryImpl.java | 50 +++++++++++++++---- .../entity/properties/BitsetProperty.java | 21 +++++--- .../entity/properties/BooleanProperty.java | 2 +- .../properties/CamelSittingProperty.java | 2 +- .../entity/properties/CustomTypeProperty.java | 2 +- .../entity/properties/DinnerboneProperty.java | 14 +++--- .../entity/properties/DummyProperty.java | 2 +- .../properties/EncodedByteProperty.java | 2 +- .../properties/EncodedIntegerProperty.java | 2 +- .../properties/EncodedStringProperty.java | 2 +- .../properties/EntitySittingProperty.java | 2 +- .../entity/properties/EquipmentProperty.java | 2 +- .../properties/ForceBodyRotationProperty.java | 7 +-- .../entity/properties/GlowProperty.java | 10 ++-- .../entity/properties/HealthProperty.java | 4 +- .../properties/HologramItemProperty.java | 2 +- .../entity/properties/HorseColorProperty.java | 10 ++-- .../entity/properties/HorseStyleProperty.java | 10 ++-- .../entity/properties/IntegerProperty.java | 2 +- .../entity/properties/LegacyBabyProperty.java | 29 +++++++++++ .../entity/properties/NBTProperty.java | 2 +- .../entity/properties/NameProperty.java | 13 +++-- .../properties/OptionalBlockPosProperty.java | 6 +-- .../entity/properties/RabbitTypeProperty.java | 22 +++++--- .../entity/properties/RotationProperty.java | 2 +- .../entity/properties/TargetNpcProperty.java | 2 +- .../TropicalFishVariantProperty.java | 13 +++-- .../attributes/AttributeProperty.java | 4 +- .../villager/VillagerDataProperty.java | 4 +- .../java/lol/pyr/znpcsplus/npc/NpcImpl.java | 8 +-- .../lol/pyr/znpcsplus/npc/NpcTypeImpl.java | 24 +++++++++ .../znpcsplus/npc/NpcTypeRegistryImpl.java | 2 +- .../pyr/znpcsplus/packets/PacketFactory.java | 2 +- .../znpcsplus/packets/V1_8PacketFactory.java | 6 +-- .../java/lol/pyr/znpcsplus/util/Viewable.java | 3 ++ 42 files changed, 243 insertions(+), 97 deletions(-) create mode 100644 api/src/main/java/lol/pyr/znpcsplus/util/ZombieType.java create mode 100644 plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/LegacyBabyProperty.java diff --git a/api/src/main/java/lol/pyr/znpcsplus/api/NpcPropertyRegistryProvider.java b/api/src/main/java/lol/pyr/znpcsplus/api/NpcPropertyRegistryProvider.java index 83b3e2c..bcfd0b5 100644 --- a/api/src/main/java/lol/pyr/znpcsplus/api/NpcPropertyRegistryProvider.java +++ b/api/src/main/java/lol/pyr/znpcsplus/api/NpcPropertyRegistryProvider.java @@ -2,6 +2,8 @@ package lol.pyr.znpcsplus.api; import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry; import org.bukkit.Bukkit; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.ServicePriority; /** * Provider for the registered entity property registry instance @@ -30,10 +32,12 @@ public class NpcPropertyRegistryProvider { * Internal method used to register the main instance of the plugin as the entity property registry provider * You probably shouldn't call this method under any circumstances * + * @param plugin Instance of the ZNPCsPlus plugin * @param api Instance of the ZNPCsPlus entity property registry */ - public static void register(EntityPropertyRegistry api) { + public static void register(Plugin plugin, EntityPropertyRegistry api) { NpcPropertyRegistryProvider.registry = api; + Bukkit.getServicesManager().register(EntityPropertyRegistry.class, registry, plugin, ServicePriority.Normal); } /** diff --git a/api/src/main/java/lol/pyr/znpcsplus/api/entity/EntityPropertyRegistry.java b/api/src/main/java/lol/pyr/znpcsplus/api/entity/EntityPropertyRegistry.java index 69e7adf..13c094f 100644 --- a/api/src/main/java/lol/pyr/znpcsplus/api/entity/EntityPropertyRegistry.java +++ b/api/src/main/java/lol/pyr/znpcsplus/api/entity/EntityPropertyRegistry.java @@ -31,11 +31,25 @@ public interface EntityPropertyRegistry { */ EntityProperty getByName(String name, Class type); + /** + * Register a dummy property that can be used to store unique information per npc
+ * Note: Properties registered this way will be player-modifiable by default + * + * @param name The name of the new property + * @param type The type of the new property + * @deprecated Use {@link #registerDummy(String, Class, boolean)} instead + */ + @Deprecated + default void registerDummy(String name, Class type) { + registerDummy(name, type, true); + } + /** * Register a dummy property that can be used to store unique information per npc * * @param name The name of the new property * @param type The type of the new property + * @param playerModifiable Whether this property can be modified by players using commands */ - void registerDummy(String name, Class type); + void registerDummy(String name, Class type, boolean playerModifiable); } diff --git a/api/src/main/java/lol/pyr/znpcsplus/util/ZombieType.java b/api/src/main/java/lol/pyr/znpcsplus/util/ZombieType.java new file mode 100644 index 0000000..8751b82 --- /dev/null +++ b/api/src/main/java/lol/pyr/znpcsplus/util/ZombieType.java @@ -0,0 +1,11 @@ +package lol.pyr.znpcsplus.util; + +public enum ZombieType { + ZOMBIE, + FARMER, + LIBRARIAN, + PRIEST, + BLACKSMITH, + BUTCHER, + HUSK +} diff --git a/plugin/build.gradle b/plugin/build.gradle index b778a35..e7af00f 100644 --- a/plugin/build.gradle +++ b/plugin/build.gradle @@ -19,7 +19,7 @@ dependencies { compileOnly "me.clip:placeholderapi:2.11.6" // Placeholder support implementation "com.google.code.gson:gson:2.10.1" // JSON parsing implementation "org.bstats:bstats-bukkit:3.0.2" // Plugin stats - implementation "com.github.retrooper:packetevents-spigot:2.7.0" // Packets + implementation "com.github.retrooper:packetevents-spigot:2.8.0" // Packets implementation "space.arim.dazzleconf:dazzleconf-ext-snakeyaml:1.2.1" // Configs implementation "lol.pyr:director-adventure:2.1.2" // Commands diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java index 2a12c2d..ed39bb4 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java @@ -97,7 +97,7 @@ public class ZNpcsPlus { skinCache = new MojangSkinCache(configManager, new File(getDataFolder(), "skins")); propertyRegistry = new EntityPropertyRegistryImpl(skinCache, configManager); - NpcPropertyRegistryProvider.register(propertyRegistry); + NpcPropertyRegistryProvider.register(bootstrap, propertyRegistry); shutdownTasks.add(NpcPropertyRegistryProvider::unregister); } @@ -130,7 +130,7 @@ public class ZNpcsPlus { PacketFactory packetFactory = setupPacketFactory(scheduler, propertyRegistry, configManager); - propertyRegistry.registerTypes(bootstrap, packetFactory, textSerializer, scheduler); + propertyRegistry.registerTypes(packetFactory, textSerializer, scheduler); BungeeConnector bungeeConnector = new BungeeConnector(bootstrap); ActionRegistryImpl actionRegistry = new ActionRegistryImpl(); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/commands/property/PropertySetCommand.java b/plugin/src/main/java/lol/pyr/znpcsplus/commands/property/PropertySetCommand.java index 53a5e25..3d9b228 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/commands/property/PropertySetCommand.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/commands/property/PropertySetCommand.java @@ -45,6 +45,7 @@ public class PropertySetCommand implements CommandHandler { // TODO: find a way to do this better & rewrite this mess if (!npc.getType().getAllowedProperties().contains(property)) context.halt(Component.text("Property " + property.getName() + " not allowed for npc type " + npc.getType().getName(), NamedTextColor.RED)); + if (!property.isPlayerModifiable()) context.halt(Component.text("This property is not modifiable by players", NamedTextColor.RED)); Class type = property.getType(); Object value; String valueName; diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyImpl.java index 25786d4..dcfdf5f 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyImpl.java @@ -47,16 +47,16 @@ public abstract class EntityPropertyImpl implements EntityProperty { dependencies.add(property); } - protected static EntityData newEntityData(int index, EntityDataType type, V value) { - return new EntityData(index, type, value); + protected static EntityData newEntityData(int index, EntityDataType type, V value) { + return new EntityData<>(index, type, value); } - public List applyStandalone(Player player, PacketEntity packetEntity, boolean isSpawned) { - Map map = new HashMap<>(); + public List> applyStandalone(Player player, PacketEntity packetEntity, boolean isSpawned) { + Map> map = new HashMap<>(); apply(player, packetEntity, isSpawned, map); for (EntityPropertyImpl property : dependencies) property.apply(player, packetEntity, isSpawned, map); return new ArrayList<>(map.values()); } - abstract public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties); + abstract public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties); } \ No newline at end of file diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java index 4a43cd4..28053e6 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java @@ -10,7 +10,6 @@ import com.github.retrooper.packetevents.protocol.nbt.NBTInt; import com.github.retrooper.packetevents.protocol.nbt.NBTString; import com.github.retrooper.packetevents.protocol.player.EquipmentSlot; import com.github.retrooper.packetevents.protocol.world.BlockFace; -import lol.pyr.znpcsplus.ZNpcsPlusBootstrap; import lol.pyr.znpcsplus.api.entity.EntityProperty; import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry; import lol.pyr.znpcsplus.api.skin.SkinDescriptor; @@ -109,7 +108,7 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { */ } - public void registerTypes(ZNpcsPlusBootstrap plugin, PacketFactory packetFactory, LegacyComponentSerializer textSerializer, TaskScheduler taskScheduler) { + public void registerTypes(PacketFactory packetFactory, LegacyComponentSerializer textSerializer, TaskScheduler taskScheduler) { ServerVersion ver = PacketEvents.getAPI().getServerManager().getVersion(); boolean legacyBooleans = ver.isOlderThan(ServerVersion.V_1_9); boolean legacyNames = ver.isOlderThan(ServerVersion.V_1_9); @@ -133,7 +132,7 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { register(new DummyProperty<>("permission_required", false)); - register(new ForceBodyRotationProperty(plugin, taskScheduler)); + register(new ForceBodyRotationProperty(taskScheduler)); register(new DummyProperty<>("player_knockback", false)); register(new DummyProperty<>("player_knockback_exempt_permission", String.class)); @@ -192,7 +191,7 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) babyIndex = 11; else babyIndex = 12; if (ver.isOlderThan(ServerVersion.V_1_9)) { - register(new EncodedByteProperty<>("baby", false, babyIndex, obj -> (byte) (obj ? -1 : 0))); + register(new LegacyBabyProperty(babyIndex)); } else { register(new BooleanProperty("baby", babyIndex, false, legacyBooleans)); } @@ -286,7 +285,9 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { else horseIndex = 16; int horseEating = ver.isNewerThanOrEquals(ServerVersion.V_1_12) ? 0x10 : 0x20; register(new BitsetProperty("is_tame", horseIndex, 0x02, false, legacyBooleans)); - register(new BitsetProperty("is_saddled", horseIndex, 0x04, false, legacyBooleans)); + if (ver.isOlderThan(ServerVersion.V_1_21)) { + register(new BitsetProperty("is_saddled", horseIndex, 0x04, false, legacyBooleans)); + } register(new BitsetProperty("is_eating", horseIndex, horseEating, false, legacyBooleans)); register(new BitsetProperty("is_rearing", horseIndex, horseEating << 1, false, legacyBooleans)); register(new BitsetProperty("has_mouth_open", horseIndex, horseEating << 2, false, legacyBooleans)); @@ -354,10 +355,14 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { // Chested Horse if (ver.isOlderThan(ServerVersion.V_1_11)) { register(new BitsetProperty("has_chest", horseIndex, 0x08, false, legacyBooleans)); - linkProperties("is_saddled", "has_chest", "is_eating", "is_rearing", "has_mouth_open"); + linkProperties("is_tame", "is_saddled", "has_chest", "is_eating", "is_rearing", "has_mouth_open"); } else { register(new BooleanProperty("has_chest", horseVariantIndex, false, legacyBooleans)); - linkProperties("is_saddled", "is_eating", "is_rearing", "has_mouth_open"); + if (ver.isOlderThan(ServerVersion.V_1_21)){ + linkProperties("is_tame", "is_saddled", "is_eating", "is_rearing", "has_mouth_open"); + } else { + linkProperties("is_tame", "is_eating", "is_rearing", "has_mouth_open"); + } } // Slime, Magma Cube and Phantom @@ -459,6 +464,33 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { else register(new EncodedIntegerProperty<>("skeleton_type", SkeletonType.NORMAL, ver.isOlderThan(ServerVersion.V_1_10) ? 11 : 12, Enum::ordinal)); } + // Zombie + int zombieIndex; + if (ver.isNewerThanOrEquals(ServerVersion.V_1_17)) zombieIndex = 17; + else if (ver.isNewerThanOrEquals(ServerVersion.V_1_16)) zombieIndex = 16; + else if (ver.isNewerThanOrEquals(ServerVersion.V_1_10)) zombieIndex = 13; + else if (ver.isNewerThanOrEquals(ServerVersion.V_1_9)) zombieIndex = 12; + else zombieIndex = 13; + + if (ver.isOlderThan(ServerVersion.V_1_9)) { + register(new EncodedByteProperty<>("zombie_is_villager", false, zombieIndex++, b -> (byte) (b ? 1 : 0))); + } else if (ver.isOlderThan(ServerVersion.V_1_11)) { + register(new EncodedIntegerProperty<>("zombie_type", ZombieType.ZOMBIE, zombieIndex++, Enum::ordinal)); + } else { + zombieIndex++; // Not a mistake, this is field unused in 1.11+ + } + if (ver.isOlderThan(ServerVersion.V_1_9)) { + register(new EncodedByteProperty<>("is_converting", false, zombieIndex++, b -> (byte) (b ? 1 : 0))); + } else if (ver.isOlderThan(ServerVersion.V_1_11)) { + register(new BooleanProperty("is_converting", zombieIndex++, false, legacyBooleans)); + } + if (ver.isNewerThanOrEquals(ServerVersion.V_1_9) && ver.isOlderThan(ServerVersion.V_1_14)) { + register(new BooleanProperty("zombie_hands_held_up", zombieIndex++, false, legacyBooleans)); + } + if (ver.isNewerThanOrEquals(ServerVersion.V_1_13)) { + register(new BooleanProperty("zombie_becoming_drowned", zombieIndex++, false, legacyBooleans)); + } + if (!ver.isNewerThanOrEquals(ServerVersion.V_1_9)) return; // Shulker int shulkerIndex; @@ -758,8 +790,8 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { } @Override - public void registerDummy(String name, Class type) { - register(new DummyProperty<>(name, type)); + public void registerDummy(String name, Class type, boolean playerModifiable) { + register(new DummyProperty<>(name, type, playerModifiable)); } public EntityPropertyImpl getByName(String name) { diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/BitsetProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/BitsetProperty.java index 1a1e5f2..eb01483 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/BitsetProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/BitsetProperty.java @@ -31,13 +31,22 @@ public class BitsetProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { - EntityData oldData = properties.get(index); + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { + EntityData oldData = properties.get(index); boolean enabled = entity.getProperty(this); if (inverted) enabled = !enabled; - properties.put(index, - integer ? newEntityData(index, EntityDataTypes.INT, (oldData == null ? 0 : (int) oldData.getValue()) | (enabled ? bitmask : 0)) : - newEntityData(index, EntityDataTypes.BYTE, (byte) ((oldData == null ? 0 : (byte) oldData.getValue()) | (enabled ? bitmask : 0)))); - + if (integer) { + int oldValue = 0; + if (oldData != null && oldData.getValue() instanceof Number) { + oldValue = ((Number) oldData.getValue()).intValue(); + } + properties.put(index, newEntityData(index, EntityDataTypes.INT, oldValue | (enabled ? bitmask : 0))); + } else { + byte oldValue = 0; + if (oldData != null && oldData.getValue() instanceof Number) { + oldValue = ((Number) oldData.getValue()).byteValue(); + } + properties.put(index, newEntityData(index, EntityDataTypes.BYTE, (byte) (oldValue | (enabled ? bitmask : 0)))); + } } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/BooleanProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/BooleanProperty.java index 5cdb880..bddc0bf 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/BooleanProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/BooleanProperty.java @@ -25,7 +25,7 @@ public class BooleanProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { boolean enabled = entity.getProperty(this); if (inverted) enabled = !enabled; if (legacy) properties.put(index, newEntityData(index, EntityDataTypes.BYTE, (byte) (enabled ? 1 : 0))); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/CamelSittingProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/CamelSittingProperty.java index 2732c21..0afa31d 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/CamelSittingProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/CamelSittingProperty.java @@ -20,7 +20,7 @@ public class CamelSittingProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { boolean value = entity.getProperty(this); if (value) { properties.put(poseIndex, newEntityData(poseIndex, EntityDataTypes.ENTITY_POSE, EntityPose.SITTING)); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/CustomTypeProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/CustomTypeProperty.java index 9946778..0d142d2 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/CustomTypeProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/CustomTypeProperty.java @@ -22,7 +22,7 @@ public class CustomTypeProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { properties.put(index, newEntityData(index, type, decoder.decode(entity.getProperty(this)))); } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/DinnerboneProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/DinnerboneProperty.java index dab1770..9df06f1 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/DinnerboneProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/DinnerboneProperty.java @@ -1,7 +1,6 @@ package lol.pyr.znpcsplus.entity.properties; import com.github.retrooper.packetevents.protocol.entity.data.EntityData; -import com.github.retrooper.packetevents.protocol.entity.data.EntityDataType; import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes; import com.github.retrooper.packetevents.util.adventure.AdventureSerializer; import lol.pyr.znpcsplus.entity.EntityPropertyImpl; @@ -16,20 +15,21 @@ import java.util.Optional; public class DinnerboneProperty extends EntityPropertyImpl { private final boolean optional; private final Object serialized; - private final EntityDataType type; public DinnerboneProperty(boolean legacy, boolean optional) { super("dinnerbone", false, Boolean.class); this.optional = optional; Component name = Component.text("Dinnerbone"); - Object serialized = legacy ? AdventureSerializer.getLegacyGsonSerializer().serialize(name) : + this.serialized = legacy ? AdventureSerializer.serializer().legacy().serialize(name) : optional ? name : LegacyComponentSerializer.legacySection().serialize(name); - this.serialized = optional ? Optional.of(serialized) : serialized; - this.type = optional ? EntityDataTypes.OPTIONAL_ADV_COMPONENT : EntityDataTypes.STRING; } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { - properties.put(2, new EntityData(2, type, entity.getProperty(this) ? serialized : optional ? null : "")); + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { + if (optional) { + properties.put(2, new EntityData<>(2, EntityDataTypes.OPTIONAL_ADV_COMPONENT, entity.getProperty(this) ? Optional.of((Component) serialized) : Optional.empty())); + } else { + properties.put(2, new EntityData<>(2, EntityDataTypes.STRING, entity.getProperty(this) ? (String) serialized : "")); + } } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/DummyProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/DummyProperty.java index eba69a5..78d3308 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/DummyProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/DummyProperty.java @@ -28,6 +28,6 @@ public class DummyProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EncodedByteProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EncodedByteProperty.java index af64b11..19fa125 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EncodedByteProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EncodedByteProperty.java @@ -36,7 +36,7 @@ public class EncodedByteProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { T value = entity.getProperty(this); if (value == null) return; properties.put(index, newEntityData(index, type, decoder.decode(value))); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EncodedIntegerProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EncodedIntegerProperty.java index d089547..896faa1 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EncodedIntegerProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EncodedIntegerProperty.java @@ -36,7 +36,7 @@ public class EncodedIntegerProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { T value = entity.getProperty(this); if (value == null) return; properties.put(index, newEntityData(index, type, decoder.decode(value))); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EncodedStringProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EncodedStringProperty.java index 84e0cd1..2ebc088 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EncodedStringProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EncodedStringProperty.java @@ -36,7 +36,7 @@ public class EncodedStringProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { T value = entity.getProperty(this); if (value == null) return; properties.put(index, newEntityData(index, type, decoder.decode(value))); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EntitySittingProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EntitySittingProperty.java index 5e59221..a3e6f82 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EntitySittingProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EntitySittingProperty.java @@ -22,7 +22,7 @@ public class EntitySittingProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { boolean sitting = entity.getProperty(this); if (sitting) { if (entity.getVehicle() == null) { diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EquipmentProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EquipmentProperty.java index c0219a7..1bef980 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EquipmentProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EquipmentProperty.java @@ -22,7 +22,7 @@ public class EquipmentProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { packetFactory.sendEquipment(player, entity, new Equipment(slot, entity.getProperty(this))); } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/ForceBodyRotationProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/ForceBodyRotationProperty.java index b642193..56654b5 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/ForceBodyRotationProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/ForceBodyRotationProperty.java @@ -1,7 +1,6 @@ package lol.pyr.znpcsplus.entity.properties; import com.github.retrooper.packetevents.protocol.entity.data.EntityData; -import lol.pyr.znpcsplus.ZNpcsPlusBootstrap; import lol.pyr.znpcsplus.entity.PacketEntity; import lol.pyr.znpcsplus.scheduling.TaskScheduler; import org.bukkit.entity.Player; @@ -9,17 +8,15 @@ import org.bukkit.entity.Player; import java.util.Map; public class ForceBodyRotationProperty extends DummyProperty { - private final ZNpcsPlusBootstrap plugin; private final TaskScheduler scheduler; - public ForceBodyRotationProperty(ZNpcsPlusBootstrap plugin, TaskScheduler scheduler) { + public ForceBodyRotationProperty(TaskScheduler scheduler) { super("force_body_rotation", false); - this.plugin = plugin; this.scheduler = scheduler; } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { if (entity.getProperty(this)) { scheduler.runLaterAsync(() -> entity.swingHand(player, false), 2L); scheduler.runLaterAsync(() -> entity.swingHand(player, false), 6L); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/GlowProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/GlowProperty.java index b20d2e5..87c15bf 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/GlowProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/GlowProperty.java @@ -19,10 +19,14 @@ public class GlowProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { NamedColor value = entity.getProperty(this); - EntityData oldData = properties.get(0); - byte oldValue = oldData == null ? 0 : (byte) oldData.getValue(); + EntityData oldData = properties.get(0); +// byte oldValue = oldData == null ? 0 : (byte) oldData.getValue(); + byte oldValue = 0; + if (oldData != null && oldData.getValue() instanceof Number) { + oldValue = ((Number) oldData.getValue()).byteValue(); + } properties.put(0, newEntityData(0, EntityDataTypes.BYTE, (byte) (oldValue | (value == null ? 0 : 0x40)))); // the team is already created with the right glow color in the packet factory if the npc isnt spawned yet if (isSpawned) { diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/HealthProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/HealthProperty.java index 82615c5..0e6aede 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/HealthProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/HealthProperty.java @@ -18,10 +18,10 @@ public class HealthProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { float health = entity.getProperty(this); health = (float) Attributes.MAX_HEALTH.sanitizeValue(health); - properties.put(index, new EntityData(index, EntityDataTypes.FLOAT, health)); + properties.put(index, new EntityData<>(index, EntityDataTypes.FLOAT, health)); } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/HologramItemProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/HologramItemProperty.java index f97cbc4..778a2ba 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/HologramItemProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/HologramItemProperty.java @@ -17,7 +17,7 @@ public class HologramItemProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { properties.put(8, newEntityData(8, EntityDataTypes.ITEMSTACK, entity.getProperty(this))); properties.put(5, newEntityData(5, EntityDataTypes.BOOLEAN, true)); } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/HorseColorProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/HorseColorProperty.java index b7b12ed..fed043d 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/HorseColorProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/HorseColorProperty.java @@ -18,9 +18,13 @@ public class HorseColorProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { - EntityData oldData = properties.get(index); + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { + EntityData oldData = properties.get(index); HorseColor value = entity.getProperty(this); - properties.put(index, newEntityData(index, EntityDataTypes.INT, value.ordinal() | (oldData == null ? 0 : ((int) oldData.getValue() & 0xFF00)))); + int oldValue = (oldData != null && oldData.getValue() instanceof Integer) ? (Integer) oldData.getValue() : 0; + + int newValue = value.ordinal() | (oldValue & 0xFF00); + properties.put(index, newEntityData(index, EntityDataTypes.INT, newValue)); + } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/HorseStyleProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/HorseStyleProperty.java index ebb1b53..ce0acc3 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/HorseStyleProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/HorseStyleProperty.java @@ -18,9 +18,13 @@ public class HorseStyleProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { - EntityData oldData = properties.get(index); + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { + EntityData oldData = properties.get(index); HorseStyle value = entity.getProperty(this); - properties.put(index, newEntityData(index, EntityDataTypes.INT, (oldData == null ? 0 : ((int) oldData.getValue() & 0x00FF)) | (value.ordinal() << 8))); + + int oldValue = (oldData != null && oldData.getValue() instanceof Integer) ? (Integer) oldData.getValue() : 0; + int newValue = (oldValue & 0x00FF) | (value.ordinal() << 8); + properties.put(index, newEntityData(index, EntityDataTypes.INT, newValue)); + } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/IntegerProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/IntegerProperty.java index 26f42c4..47607ad 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/IntegerProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/IntegerProperty.java @@ -23,7 +23,7 @@ public class IntegerProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { properties.put(index, legacy ? newEntityData(index, EntityDataTypes.BYTE, (byte) entity.getProperty(this).intValue()) : newEntityData(index, EntityDataTypes.INT, entity.getProperty(this))); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/LegacyBabyProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/LegacyBabyProperty.java new file mode 100644 index 0000000..3d9f0e7 --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/LegacyBabyProperty.java @@ -0,0 +1,29 @@ +package lol.pyr.znpcsplus.entity.properties; + +import com.github.retrooper.packetevents.protocol.entity.data.EntityData; +import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes; +import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; +import lol.pyr.znpcsplus.entity.EntityPropertyImpl; +import lol.pyr.znpcsplus.entity.PacketEntity; +import org.bukkit.entity.Player; + +import java.util.Map; + +public class LegacyBabyProperty extends EntityPropertyImpl { + private final int index; + + public LegacyBabyProperty(int index) { + super("baby", false, Boolean.class); + this.index = index; + } + + @Override + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { + boolean isBaby = entity.getProperty(this); + if (entity.getType().equals(EntityTypes.ZOMBIE)) { + properties.put(index, newEntityData(index, EntityDataTypes.BYTE, (byte) (isBaby ? 1 : 0))); + } else { + properties.put(index, newEntityData(index, EntityDataTypes.BYTE, (byte) (isBaby ? -1 : 0))); + } + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/NBTProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/NBTProperty.java index 9faa28d..28bd952 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/NBTProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/NBTProperty.java @@ -48,7 +48,7 @@ public class NBTProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { T value = entity.getProperty(this); if (value == null && !allowNull) return; properties.put(index, newEntityData(index, type, decoder.decode(value))); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/NameProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/NameProperty.java index 779c4ff..d0e9400 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/NameProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/NameProperty.java @@ -27,14 +27,17 @@ public class NameProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { Component value = entity.getProperty(this); if (value != null) { value = PapiUtil.set(legacySerializer, player, value); - Object serialized = legacySerialization ? AdventureSerializer.getLegacyGsonSerializer().serialize(value) : - optional ? value : LegacyComponentSerializer.legacySection().serialize(value); - if (optional) properties.put(2, new EntityData(2, EntityDataTypes.OPTIONAL_ADV_COMPONENT, Optional.of(serialized))); - else properties.put(2, new EntityData(2, EntityDataTypes.STRING, serialized)); + if (legacySerialization) { + properties.put(2, newEntityData(2, EntityDataTypes.STRING, AdventureSerializer.serializer().asJson(value))); + } else if (optional) { + properties.put(2, newEntityData(2, EntityDataTypes.OPTIONAL_ADV_COMPONENT, Optional.of(value))); + } else { + properties.put(2, newEntityData(2, EntityDataTypes.STRING, LegacyComponentSerializer.legacySection().serialize(value))); + } } if (legacySerialization) properties.put(3, newEntityData(3, EntityDataTypes.BYTE, (byte) (value != null ? 1 : 0))); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/OptionalBlockPosProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/OptionalBlockPosProperty.java index c9eb536..8b233b2 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/OptionalBlockPosProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/OptionalBlockPosProperty.java @@ -19,10 +19,10 @@ public class OptionalBlockPosProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { Vector3i value = entity.getProperty(this); - if (value == null) properties.put(index, new EntityData(index, EntityDataTypes.OPTIONAL_BLOCK_POSITION, Optional.empty())); - else properties.put(index, new EntityData(index, EntityDataTypes.OPTIONAL_BLOCK_POSITION, + if (value == null) properties.put(index, new EntityData<>(index, EntityDataTypes.OPTIONAL_BLOCK_POSITION, Optional.empty())); + else properties.put(index, new EntityData<>(index, EntityDataTypes.OPTIONAL_BLOCK_POSITION, Optional.of(new com.github.retrooper.packetevents.util.Vector3i(value.getX(), value.getY(), value.getZ())))); } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/RabbitTypeProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/RabbitTypeProperty.java index 992bd8d..a5b6ead 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/RabbitTypeProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/RabbitTypeProperty.java @@ -1,7 +1,6 @@ package lol.pyr.znpcsplus.entity.properties; import com.github.retrooper.packetevents.protocol.entity.data.EntityData; -import com.github.retrooper.packetevents.protocol.entity.data.EntityDataType; import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes; import com.github.retrooper.packetevents.util.adventure.AdventureSerializer; import lol.pyr.znpcsplus.entity.EntityPropertyImpl; @@ -17,31 +16,38 @@ import java.util.Optional; public class RabbitTypeProperty extends EntityPropertyImpl { private final int index; private final boolean legacyBooleans; + private final boolean optional; private final Object serialized; - private final EntityDataType type; public RabbitTypeProperty(int index, boolean legacyBooleans, boolean legacyNames, boolean optional) { super("rabbit_type", RabbitType.BROWN, RabbitType.class); this.index = index; this.legacyBooleans = legacyBooleans; + this.optional = optional; Component name = Component.text("Toast"); - Object serialized = legacyNames ? AdventureSerializer.getLegacyGsonSerializer().serialize(name) : + this.serialized = legacyNames ? AdventureSerializer.serializer().legacy().serialize(name) : optional ? name : LegacyComponentSerializer.legacySection().serialize(name); - this.serialized = optional ? Optional.of(serialized) : serialized; - this.type = optional ? EntityDataTypes.OPTIONAL_ADV_COMPONENT : EntityDataTypes.STRING; } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { RabbitType rabbitType = entity.getProperty(this); if (rabbitType == null) return; if (!rabbitType.equals(RabbitType.TOAST)) { properties.put(index, legacyBooleans ? newEntityData(index, EntityDataTypes.BYTE, (byte) rabbitType.getId()) : newEntityData(index, EntityDataTypes.INT, rabbitType.getId())); - properties.put(2, new EntityData(2, type, null)); + if (optional) { + properties.put(2, new EntityData<>(2, EntityDataTypes.OPTIONAL_ADV_COMPONENT, Optional.empty())); + } else { + properties.put(2, new EntityData<>(2, EntityDataTypes.STRING, "")); + } } else { - properties.put(2, new EntityData(2, type, serialized)); + if (optional) { + properties.put(2, newEntityData(2, EntityDataTypes.OPTIONAL_ADV_COMPONENT, Optional.of((Component) serialized))); + } else { + properties.put(2, newEntityData(2, EntityDataTypes.STRING, (String) serialized)); + } } } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/RotationProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/RotationProperty.java index 412197d..2754a2d 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/RotationProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/RotationProperty.java @@ -18,7 +18,7 @@ public class RotationProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { Vector3f vec = entity.getProperty(this); properties.put(index, newEntityData(index, EntityDataTypes.ROTATION, new com.github.retrooper.packetevents.util.Vector3f(vec.getX(), vec.getY(), vec.getZ()))); } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/TargetNpcProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/TargetNpcProperty.java index fbe4beb..5fc53c4 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/TargetNpcProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/TargetNpcProperty.java @@ -18,7 +18,7 @@ public class TargetNpcProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { NpcEntryImpl value = entity.getProperty(this); if (value == null) return; if (value.getNpc().getEntity().getEntityId() == entity.getEntityId()) return; diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/TropicalFishVariantProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/TropicalFishVariantProperty.java index 99c8d68..aa83c15 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/TropicalFishVariantProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/TropicalFishVariantProperty.java @@ -25,15 +25,14 @@ public class TropicalFishVariantProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { T value = entity.getProperty(this); - if (value == null) { - return; - } - EntityData oldData = properties.get(index); + if (value == null) return; + + EntityData oldData = properties.get(index); TropicalFishVariant.Builder builder; - if (oldData != null && oldData.getType() == EntityDataTypes.INT && oldData.getValue() != null) { - int oldVal = (int) oldData.getValue(); + if (oldData != null && oldData.getType() == EntityDataTypes.INT && oldData.getValue() instanceof Integer) { + int oldVal = (Integer) oldData.getValue(); builder = TropicalFishVariant.Builder.fromInt(oldVal); } else { builder = new TropicalFishVariant.Builder(); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/attributes/AttributeProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/attributes/AttributeProperty.java index 30ae5af..e1aba38 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/attributes/AttributeProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/attributes/AttributeProperty.java @@ -35,13 +35,13 @@ public class AttributeProperty extends EntityPropertyImpl { } @Override - public List applyStandalone(Player player, PacketEntity packetEntity, boolean isSpawned) { + public List> applyStandalone(Player player, PacketEntity packetEntity, boolean isSpawned) { apply(player, packetEntity, isSpawned, Collections.emptyList()); return Collections.emptyList(); } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { } public void apply(Player player, PacketEntity entity, boolean isSpawned, List properties) { diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/villager/VillagerDataProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/villager/VillagerDataProperty.java index e86973b..36d55ad 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/villager/VillagerDataProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/villager/VillagerDataProperty.java @@ -21,8 +21,8 @@ public abstract class VillagerDataProperty extends EntityPropertyImpl { } @Override - public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { - EntityData oldData = properties.get(index); + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map> properties) { + EntityData oldData = properties.get(index); VillagerData old = oldData == null ? new VillagerData(VillagerTypes.PLAINS, VillagerProfessions.NONE, 1) : (VillagerData) oldData.getValue(); properties.put(index, newEntityData(index, EntityDataTypes.VILLAGER_DATA, apply(old, entity.getProperty(this)))); } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java index 2be57a3..97c82f5 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java @@ -159,7 +159,7 @@ public class NpcImpl extends Viewable implements Npc { private void UNSAFE_refreshProperty(EntityPropertyImpl property) { if (!type.isAllowedProperty(property)) return; for (Player viewer : getViewers()) { - List data = property.applyStandalone(viewer, entity, true); + List> data = property.applyStandalone(viewer, entity, true); if (!data.isEmpty()) packetFactory.sendMetadata(viewer, entity, data); } } @@ -232,7 +232,8 @@ public class NpcImpl extends Viewable implements Npc { } @Override - public void addAction(InteractionAction action) { + public void addAction(InteractionAction action) throws IllegalArgumentException { + if (action == null) throw new IllegalArgumentException("action can not be null"); actions.add(action); } @@ -242,7 +243,8 @@ public class NpcImpl extends Viewable implements Npc { } @Override - public void editAction(int index, InteractionAction action) { + public void editAction(int index, InteractionAction action) throws IllegalArgumentException { + if (action == null) throw new IllegalArgumentException("action can not be null"); actions.set(index, action); } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeImpl.java index b2eae03..a599306 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeImpl.java @@ -180,6 +180,11 @@ public class NpcTypeImpl implements NpcType { if (version.isNewerThanOrEquals(ServerVersion.V_1_20_5)) { if (EntityTypes.isTypeInstanceOf(type, EntityTypes.WOLF)) { addProperties("wolf_variant"); + if (version.isNewerThanOrEquals(ServerVersion.V_1_21)) { + addProperties("body"); + } else { + addProperties("chestplate"); + } } } if (version.isNewerThanOrEquals(ServerVersion.V_1_21_4)) { @@ -187,6 +192,25 @@ public class NpcTypeImpl implements NpcType { addProperties("creaking_crumbling"); } } + if (EntityTypes.isTypeInstanceOf(type, EntityTypes.ZOMBIE)) { + if (version.isOlderThan(ServerVersion.V_1_9)) { + addProperties("zombie_is_villager"); + } else if (version.isOlderThan(ServerVersion.V_1_11)) { + addProperties("zombie_type"); + } + + if (version.isOlderThan(ServerVersion.V_1_11)) { + addProperties("is_converting"); + } + + if (version.isNewerThanOrEquals(ServerVersion.V_1_9) && version.isOlderThan(ServerVersion.V_1_14)) { + addProperties("zombie_hands_held_up"); + } + + if (version.isNewerThanOrEquals(ServerVersion.V_1_13)) { + addProperties("zombie_becoming_drowned"); + } + } return new NpcTypeImpl(name, type, hologramOffset, new HashSet<>(allowedProperties), defaultProperties); } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeRegistryImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeRegistryImpl.java index 7c480a7..8b877a3 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeRegistryImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeRegistryImpl.java @@ -306,7 +306,7 @@ public class NpcTypeRegistryImpl implements NpcTypeRegistry { register(builder(p, "trader_llama", EntityTypes.TRADER_LLAMA) .setHologramOffset(-0.105) - .addProperties("llama_variant")); + .addProperties("carpet_color", "llama_variant", "body")); register(builder(p, "wandering_trader", EntityTypes.WANDERING_TRADER) .setHologramOffset(-0.025) diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/packets/PacketFactory.java b/plugin/src/main/java/lol/pyr/znpcsplus/packets/PacketFactory.java index 1d3ba41..7cfdc93 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/packets/PacketFactory.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/packets/PacketFactory.java @@ -22,7 +22,7 @@ public interface PacketFactory { void removeTeam(Player player, PacketEntity entity); void sendAllMetadata(Player player, PacketEntity entity, PropertyHolder properties); void sendEquipment(Player player, PacketEntity entity, Equipment equipment); - void sendMetadata(Player player, PacketEntity entity, List data); + void sendMetadata(Player player, PacketEntity entity, List> data); void sendHeadRotation(Player player, PacketEntity entity, float yaw, float pitch); void sendHandSwing(Player player, PacketEntity entity, boolean offHand); void setPassengers(Player player, int vehicle, int... passengers); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java index e288aa2..085f338 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/packets/V1_8PacketFactory.java @@ -135,13 +135,13 @@ public class V1_8PacketFactory implements PacketFactory { @Override public void sendAllMetadata(Player player, PacketEntity entity, PropertyHolder properties) { - Map datas = new HashMap<>(); + Map> datas = new HashMap<>(); for (EntityProperty property : properties.getAppliedProperties()) ((EntityPropertyImpl) property).apply(player, entity, false, datas); sendMetadata(player, entity, new ArrayList<>(datas.values())); } @Override - public void sendMetadata(Player player, PacketEntity entity, List data) { + public void sendMetadata(Player player, PacketEntity entity, List> data) { sendPacket(player, new WrapperPlayServerEntityMetadata(entity.getEntityId(), data)); } @@ -180,7 +180,7 @@ public class V1_8PacketFactory implements PacketFactory { return future; } - protected void add(Map map, EntityData data) { + protected void add(Map> map, EntityData data) { map.put(data.getIndex(), data); } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java b/plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java index 08b62fe..cc222a8 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java @@ -52,6 +52,9 @@ public abstract class Viewable { queueVisibilityTask(() -> { UNSAFE_hideAll(); viewers.clear(); + synchronized (all) { + all.removeIf(reference -> reference.get() == null || reference.get() == this); + } }); }