From dfe2d22da35d9e533a0321e37d71e4b23a2b33d6 Mon Sep 17 00:00:00 2001 From: D3v1s0m Date: Thu, 14 Sep 2023 11:00:08 +0530 Subject: [PATCH 1/7] Fixed shoulder entity not getting removed --- .../entity/EntityPropertyRegistryImpl.java | 5 ++-- .../entity/properties/NBTProperty.java | 25 +++++++++++++------ 2 files changed, 21 insertions(+), 9 deletions(-) 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 c5b08dc..61e04c3 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java @@ -372,13 +372,14 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { // Player NBTProperty.NBTDecoder parrotVariantDecoder = (variant) -> { NBTCompound compound = new NBTCompound(); + if (variant == null) return compound; compound.setTag("id", new NBTString("minecraft:parrot")); compound.setTag("Variant", new NBTInt(variant.ordinal())); return compound; }; int shoulderIndex = skinLayersIndex+2; - register(new NBTProperty<>("shoulder_entity_left", ParrotVariant.class, shoulderIndex++, parrotVariantDecoder)); - register(new NBTProperty<>("shoulder_entity_right", ParrotVariant.class, shoulderIndex, parrotVariantDecoder)); + register(new NBTProperty<>("shoulder_entity_left", ParrotVariant.class, shoulderIndex++, parrotVariantDecoder, true)); + register(new NBTProperty<>("shoulder_entity_right", ParrotVariant.class, shoulderIndex, parrotVariantDecoder, true)); if (!ver.isNewerThanOrEquals(ServerVersion.V_1_13)) return; // Pufferfish 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 9829790..9faa28d 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 @@ -14,32 +14,43 @@ public class NBTProperty extends EntityPropertyImpl { private final EntityDataType type; private final NBTDecoder decoder; private final int index; + private final boolean allowNull; // This means that the decoder can have null input, not that the property can be null - public NBTProperty(String name, T defaultValue, Class clazz, int index, NBTDecoder decoder, EntityDataType type) { + public NBTProperty(String name, T defaultValue, Class clazz, int index, NBTDecoder decoder, boolean allowNull, EntityDataType type) { super(name, defaultValue, clazz); this.decoder = decoder; this.index = index; + this.allowNull = allowNull; this.type = type; } @SuppressWarnings("unchecked") - public NBTProperty(String name, T defaultValue, int index, NBTDecoder decoder) { - this(name, defaultValue, (Class) defaultValue.getClass(), index, decoder, EntityDataTypes.NBT); + public NBTProperty(String name, T defaultValue, int index, NBTDecoder decoder, boolean allowNull) { + this(name, defaultValue, (Class) defaultValue.getClass(), index, decoder, allowNull, EntityDataTypes.NBT); } @SuppressWarnings("unchecked") - public NBTProperty(String name, T defaultValue, int index, NBTDecoder decoder, EntityDataType type) { - this(name, defaultValue, (Class) defaultValue.getClass(), index, decoder, type); + public NBTProperty(String name, T defaultValue, int index, NBTDecoder decoder) { + this(name, defaultValue, (Class) defaultValue.getClass(), index, decoder, false, EntityDataTypes.NBT); + } + + @SuppressWarnings("unchecked") + public NBTProperty(String name, T defaultValue, int index, NBTDecoder decoder, boolean allowNull, EntityDataType type) { + this(name, defaultValue, (Class) defaultValue.getClass(), index, decoder, allowNull, type); + } + + public NBTProperty(String name, Class clazz, int index, NBTDecoder decoder, boolean allowNull) { + this(name, null, clazz, index, decoder, allowNull, EntityDataTypes.NBT); } public NBTProperty(String name, Class clazz, int index, NBTDecoder decoder) { - this(name, null, clazz, index, decoder, EntityDataTypes.NBT); + this(name, null, clazz, index, decoder, false, EntityDataTypes.NBT); } @Override public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { T value = entity.getProperty(this); - if (value == null) return; + if (value == null && !allowNull) return; properties.put(index, newEntityData(index, type, decoder.decode(value))); } From 9d17a5bdd3c9dac58b79d62526df3bc815f2bf9f Mon Sep 17 00:00:00 2001 From: D3v1s0m Date: Sun, 17 Sep 2023 21:22:48 +0530 Subject: [PATCH 2/7] changed look property a bit --- .../java/lol/pyr/znpcsplus/util/LookType.java | 7 +++++ .../java/lol/pyr/znpcsplus/ZNpcsPlus.java | 1 + .../citizens/model/traits/LookTrait.java | 3 ++- .../entity/EntityPropertyRegistryImpl.java | 3 ++- .../pyr/znpcsplus/entity/PacketEntity.java | 4 +++ .../serializers/LookTypeSerializer.java | 26 +++++++++++++++++++ .../java/lol/pyr/znpcsplus/npc/NpcImpl.java | 4 +++ .../pyr/znpcsplus/packets/PacketFactory.java | 1 + .../znpcsplus/packets/V1_8PacketFactory.java | 6 +++++ .../pyr/znpcsplus/tasks/NpcProcessorTask.java | 16 +++++++++--- 10 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 api/src/main/java/lol/pyr/znpcsplus/util/LookType.java create mode 100644 plugin/src/main/java/lol/pyr/znpcsplus/entity/serializers/LookTypeSerializer.java diff --git a/api/src/main/java/lol/pyr/znpcsplus/util/LookType.java b/api/src/main/java/lol/pyr/znpcsplus/util/LookType.java new file mode 100644 index 0000000..e6af244 --- /dev/null +++ b/api/src/main/java/lol/pyr/znpcsplus/util/LookType.java @@ -0,0 +1,7 @@ +package lol.pyr.znpcsplus.util; + +public enum LookType { + FIXED, + CLOSEST_PLAYER, + PER_PLAYER +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java index fbe9169..47928e6 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java @@ -276,6 +276,7 @@ public class ZNpcsPlus extends JavaPlugin { registerEnumParser(manager, OcelotType.class, incorrectUsageMessage); registerEnumParser(manager, PandaGene.class, incorrectUsageMessage); registerEnumParser(manager, PuffState.class, incorrectUsageMessage); + registerEnumParser(manager, LookType.class, incorrectUsageMessage); manager.registerCommand("npc", new MultiCommand(loadHelpMessage("root")) .addSubcommand("center", new CenterCommand(npcRegistry)) diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/LookTrait.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/LookTrait.java index 0854124..650b6a6 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/LookTrait.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/citizens/model/traits/LookTrait.java @@ -3,6 +3,7 @@ package lol.pyr.znpcsplus.conversion.citizens.model.traits; import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry; import lol.pyr.znpcsplus.conversion.citizens.model.SectionCitizensTrait; import lol.pyr.znpcsplus.npc.NpcImpl; +import lol.pyr.znpcsplus.util.LookType; import org.bukkit.configuration.ConfigurationSection; import org.jetbrains.annotations.NotNull; @@ -16,7 +17,7 @@ public class LookTrait extends SectionCitizensTrait { @Override public @NotNull NpcImpl apply(NpcImpl npc, ConfigurationSection section) { - if (section.getBoolean("enabled")) npc.setProperty(registry.getByName("look", Boolean.class), true); + if (section.getBoolean("enabled")) npc.setProperty(registry.getByName("look", LookType.class), LookType.CLOSEST_PLAYER); return npc; } } 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 61e04c3..a7c7b61 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java @@ -53,6 +53,7 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { registerSerializer(new Vector3fPropertySerializer()); registerSerializer(new BlockStatePropertySerializer()); registerSerializer(new IntegerPropertySerializer()); + registerSerializer(new LookTypeSerializer()); registerEnumSerializer(NpcPose.class); registerEnumSerializer(DyeColor.class); @@ -142,7 +143,7 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { register(new NameProperty(legacyNames, optionalComponents)); register(new DinnerboneProperty(legacyNames, optionalComponents)); - register(new DummyProperty<>("look", false)); + register(new DummyProperty<>("look", LookType.FIXED)); register(new GlowProperty(packetFactory)); register(new BitsetProperty("fire", 0, 0x01)); register(new BitsetProperty("invisible", 0, 0x20)); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/PacketEntity.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/PacketEntity.java index aef8b03..a827221 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/PacketEntity.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/PacketEntity.java @@ -60,6 +60,10 @@ public class PacketEntity implements PropertyHolder { else packetFactory.spawnEntity(player, this, properties); } + public void setHeadRotation(Player player, float yaw, float pitch) { + packetFactory.sendHeadRotation(player, this, yaw, pitch); + } + public void despawn(Player player) { packetFactory.destroyEntity(player, this, properties); } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/serializers/LookTypeSerializer.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/serializers/LookTypeSerializer.java new file mode 100644 index 0000000..0d06d9a --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/serializers/LookTypeSerializer.java @@ -0,0 +1,26 @@ +package lol.pyr.znpcsplus.entity.serializers; + +import lol.pyr.znpcsplus.entity.PropertySerializer; +import lol.pyr.znpcsplus.util.LookType; + +public class LookTypeSerializer implements PropertySerializer { + @Override + public String serialize(LookType property) { + return property.name(); + } + + @Override + public LookType deserialize(String property) { + if (property.equals("true")) return LookType.CLOSEST_PLAYER; + try { + return LookType.valueOf(property); + } catch (IllegalArgumentException ignored) { + return LookType.FIXED; + } + } + + @Override + public Class getTypeClass() { + return LookType.class; + } +} 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 c41f151..cd6c52b 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java @@ -83,6 +83,10 @@ public class NpcImpl extends Viewable implements Npc { hologram.setLocation(location.withY(location.getY() + type.getHologramOffset())); } + public void setHeadRotation(Player player, float yaw, float pitch) { + entity.setHeadRotation(player, yaw, pitch); + } + public HologramImpl getHologram() { return hologram; } 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 87df253..462a99d 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/packets/PacketFactory.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/packets/PacketFactory.java @@ -22,4 +22,5 @@ public interface PacketFactory { 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 sendHeadRotation(Player player, PacketEntity entity, float yaw, float pitch); } 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 b0ec7de..26f13f0 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 @@ -137,6 +137,12 @@ public class V1_8PacketFactory implements PacketFactory { sendPacket(player, new WrapperPlayServerEntityMetadata(entity.getEntityId(), data)); } + @Override + public void sendHeadRotation(Player player, PacketEntity entity, float yaw, float pitch) { + sendPacket(player, new WrapperPlayServerEntityHeadLook(entity.getEntityId(),yaw)); + sendPacket(player, new WrapperPlayServerEntityRotation(entity.getEntityId(), yaw, pitch, true)); + } + @Override public void sendEquipment(Player player, PacketEntity entity, Equipment equipment) { sendPacket(player, new WrapperPlayServerEntityEquipment(entity.getEntityId(), Collections.singletonList(equipment))); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java b/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java index 1e91139..8145730 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java @@ -8,6 +8,7 @@ import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl; import lol.pyr.znpcsplus.npc.NpcEntryImpl; import lol.pyr.znpcsplus.npc.NpcImpl; import lol.pyr.znpcsplus.npc.NpcRegistryImpl; +import lol.pyr.znpcsplus.util.LookType; import lol.pyr.znpcsplus.util.NpcLocation; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -28,13 +29,14 @@ public class NpcProcessorTask extends BukkitRunnable { public void run() { double distSq = NumberConversions.square(configManager.getConfig().viewDistance()); double lookPropertyDistSq = NumberConversions.square(configManager.getConfig().lookPropertyDistance()); - EntityPropertyImpl lookProperty = propertyRegistry.getByName("look", Boolean.class); + EntityPropertyImpl lookProperty = propertyRegistry.getByName("look", LookType.class); for (NpcEntryImpl entry : npcRegistry.getProcessable()) { NpcImpl npc = entry.getNpc(); if (!npc.isEnabled()) continue; double closestDist = Double.MAX_VALUE; Player closest = null; + LookType lookType = npc.getProperty(lookProperty); for (Player player : Bukkit.getOnlinePlayers()) { if (!player.getWorld().equals(npc.getWorld())) { if (npc.isVisibleTo(player)) npc.hide(player); @@ -60,12 +62,18 @@ public class NpcProcessorTask extends BukkitRunnable { closestDist = distance; closest = player; } + if (lookType.equals(LookType.PER_PLAYER) && lookPropertyDistSq >= distance) { + NpcLocation expected = npc.getLocation().lookingAt(player.getLocation().add(0, -npc.getType().getHologramOffset(), 0)); + if (!expected.equals(npc.getLocation())) npc.setHeadRotation(player, expected.getYaw(), expected.getPitch()); + } } } // look property - if (closest != null && npc.getProperty(lookProperty) && lookPropertyDistSq >= closestDist) { - NpcLocation expected = npc.getLocation().lookingAt(closest.getLocation().add(0, -npc.getType().getHologramOffset(), 0)); - if (!expected.equals(npc.getLocation())) npc.setLocation(expected); + if (lookType.equals(LookType.CLOSEST_PLAYER)) { + if (closest != null && lookPropertyDistSq >= closestDist) { + NpcLocation expected = npc.getLocation().lookingAt(closest.getLocation().add(0, -npc.getType().getHologramOffset(), 0)); + if (!expected.equals(npc.getLocation())) npc.setLocation(expected); + } } } } From d48e4bc2b2185ec8d815433d0a1a6ba35863126a Mon Sep 17 00:00:00 2001 From: D3v1s0m Date: Sun, 17 Sep 2023 21:53:20 +0530 Subject: [PATCH 3/7] adding toggle imports from ZNpcs --- .../conversion/znpcs/ZNpcImporter.java | 20 +++++++++++++++++++ .../conversion/znpcs/model/ZNpcsModel.java | 5 +++++ 2 files changed, 25 insertions(+) diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/ZNpcImporter.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/ZNpcImporter.java index 39ce7e7..09233b6 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/ZNpcImporter.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/ZNpcImporter.java @@ -28,13 +28,16 @@ import lol.pyr.znpcsplus.scheduling.TaskScheduler; import lol.pyr.znpcsplus.skin.Skin; import lol.pyr.znpcsplus.skin.cache.MojangSkinCache; import lol.pyr.znpcsplus.skin.descriptor.FetchingDescriptor; +import lol.pyr.znpcsplus.skin.descriptor.MirrorDescriptor; import lol.pyr.znpcsplus.skin.descriptor.PrefetchedDescriptor; import lol.pyr.znpcsplus.util.BungeeConnector; import lol.pyr.znpcsplus.util.ItemSerializationUtil; +import lol.pyr.znpcsplus.util.LookType; import lol.pyr.znpcsplus.util.NpcLocation; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import org.bukkit.DyeColor; import org.bukkit.inventory.ItemStack; import java.io.BufferedReader; @@ -129,6 +132,23 @@ public class ZNpcImporter implements DataImporter { npc.setProperty(propertyRegistry.getByName("skin", SkinDescriptor.class), new PrefetchedDescriptor(new Skin(model.getSkin(), model.getSignature()))); } + Map toggleValues = model.getNpcToggleValues(); + if (toggleValues != null) { + if (toggleValues.containsKey("look")) { + npc.setProperty(propertyRegistry.getByName("look", LookType.class), LookType.CLOSEST_PLAYER); + } + if (toggleValues.containsKey("mirror")) { + npc.setProperty(propertyRegistry.getByName("skin", SkinDescriptor.class), new MirrorDescriptor(skinCache)); + } + if (toggleValues.containsKey("glow")) { + try { + npc.setProperty(propertyRegistry.getByName("glow", DyeColor.class), DyeColor.valueOf((String) toggleValues.get("glow"))); + } catch (IllegalArgumentException e) { + npc.setProperty(propertyRegistry.getByName("glow", DyeColor.class), DyeColor.WHITE); + } + } + } + NpcEntryImpl entry = new NpcEntryImpl(String.valueOf(model.getId()), npc); entry.enableEverything(); entries.add(entry); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/model/ZNpcsModel.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/model/ZNpcsModel.java index 4502b23..60ec99b 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/model/ZNpcsModel.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/model/ZNpcsModel.java @@ -19,6 +19,7 @@ public class ZNpcsModel { private List hologramLines; private List clickActions; private Map npcEquip; + private Map npcToggleValues; private Map customizationMap; public int getId() { @@ -57,6 +58,10 @@ public class ZNpcsModel { return npcEquip; } + public Map getNpcToggleValues() { + return npcToggleValues; + } + public Map getCustomizationMap() { return customizationMap; } From 28ed99a3b74641229b5063b83b02533ccfbc540f Mon Sep 17 00:00:00 2001 From: D3v1s0m Date: Sun, 17 Sep 2023 22:08:33 +0530 Subject: [PATCH 4/7] ignore saving npc location for closest player look type, used packet instead --- plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java | 6 ++++++ .../main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) 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 cd6c52b..fb17ad4 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java @@ -87,6 +87,12 @@ public class NpcImpl extends Viewable implements Npc { entity.setHeadRotation(player, yaw, pitch); } + public void setHeadRotation(float yaw, float pitch) { + for (Player player : getViewers()) { + entity.setHeadRotation(player, yaw, pitch); + } + } + public HologramImpl getHologram() { return hologram; } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java b/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java index 8145730..5576028 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java @@ -72,7 +72,7 @@ public class NpcProcessorTask extends BukkitRunnable { if (lookType.equals(LookType.CLOSEST_PLAYER)) { if (closest != null && lookPropertyDistSq >= closestDist) { NpcLocation expected = npc.getLocation().lookingAt(closest.getLocation().add(0, -npc.getType().getHologramOffset(), 0)); - if (!expected.equals(npc.getLocation())) npc.setLocation(expected); + if (!expected.equals(npc.getLocation())) npc.setHeadRotation(expected.getYaw(), expected.getPitch()); } } } From ec4d40563f1cf7ae86708040981eb433443541f6 Mon Sep 17 00:00:00 2001 From: D3v1s0m Date: Mon, 18 Sep 2023 12:02:16 +0530 Subject: [PATCH 5/7] added common serializer for primitive data types --- .../entity/EntityPropertyRegistryImpl.java | 14 +++++++-- .../entity/PrimitivePropertySerializer.java | 30 +++++++++++++++++++ .../IntegerPropertySerializer.java | 25 ---------------- 3 files changed, 42 insertions(+), 27 deletions(-) create mode 100644 plugin/src/main/java/lol/pyr/znpcsplus/entity/PrimitivePropertySerializer.java delete mode 100644 plugin/src/main/java/lol/pyr/znpcsplus/entity/serializers/IntegerPropertySerializer.java 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 a7c7b61..d3cd5ce 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java @@ -44,7 +44,6 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { private final Map> byName = new HashMap<>(); public EntityPropertyRegistryImpl(MojangSkinCache skinCache) { - registerSerializer(new BooleanPropertySerializer()); registerSerializer(new ComponentPropertySerializer()); registerSerializer(new NamedTextColorPropertySerializer()); registerSerializer(new SkinDescriptorSerializer(skinCache)); @@ -52,7 +51,6 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { registerSerializer(new ColorPropertySerializer()); registerSerializer(new Vector3fPropertySerializer()); registerSerializer(new BlockStatePropertySerializer()); - registerSerializer(new IntegerPropertySerializer()); registerSerializer(new LookTypeSerializer()); registerEnumSerializer(NpcPose.class); @@ -77,6 +75,8 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { registerEnumSerializer(PandaGene.class); registerEnumSerializer(PuffState.class); + registerPrimitiveSerializers(Integer.class, Boolean.class, Double.class, Float.class, Long.class, Short.class, Byte.class, String.class); + /* registerType("using_item", false); // TODO: fix it for 1.8 and add new property to use offhand item and riptide animation @@ -517,6 +517,16 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { serializerMap.put(clazz, new EnumPropertySerializer<>(clazz)); } + private void registerPrimitiveSerializers(Class... classes) { + for (Class clazz : classes) { + registerPrimitiveSerializer(clazz); + } + } + + private void registerPrimitiveSerializer(Class clazz) { + serializerMap.put(clazz, new PrimitivePropertySerializer<>(clazz)); + } + private void register(EntityPropertyImpl property) { if (byName.containsKey(property.getName())) throw new IllegalArgumentException("Duplicate property name: " + property.getName()); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/PrimitivePropertySerializer.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/PrimitivePropertySerializer.java new file mode 100644 index 0000000..ad18eaf --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/PrimitivePropertySerializer.java @@ -0,0 +1,30 @@ +package lol.pyr.znpcsplus.entity; + +import java.lang.reflect.InvocationTargetException; + +public class PrimitivePropertySerializer implements PropertySerializer { + private final Class clazz; + + public PrimitivePropertySerializer(Class clazz) { + this.clazz = clazz; + } + + @Override + public String serialize(T property) { + return String.valueOf(property); + } + + @Override + public T deserialize(String property) { + try { + return clazz.getConstructor(String.class).newInstance(property); + } catch (InvocationTargetException | InstantiationException | IllegalAccessException | NoSuchMethodException e) { + throw new NullPointerException("Failed to deserialize property " + property + " of type " + clazz.getName() + "!"); + } + } + + @Override + public Class getTypeClass() { + return clazz; + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/serializers/IntegerPropertySerializer.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/serializers/IntegerPropertySerializer.java deleted file mode 100644 index e918668..0000000 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/serializers/IntegerPropertySerializer.java +++ /dev/null @@ -1,25 +0,0 @@ -package lol.pyr.znpcsplus.entity.serializers; - -import lol.pyr.znpcsplus.entity.PropertySerializer; - -public class IntegerPropertySerializer implements PropertySerializer { - @Override - public String serialize(Integer property) { - return String.valueOf(property); - } - - @Override - public Integer deserialize(String property) { - try { - return Integer.parseInt(property); - } catch (NumberFormatException e) { - e.printStackTrace(); - } - return null; - } - - @Override - public Class getTypeClass() { - return Integer.class; - } -} From 2588289a19614d5c30aaa770d2cd45796e889ba7 Mon Sep 17 00:00:00 2001 From: D3v1s0m Date: Mon, 18 Sep 2023 12:19:33 +0530 Subject: [PATCH 6/7] added look_distance and view_distance properties for all npcs --- .../src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java | 2 +- .../znpcsplus/entity/EntityPropertyRegistryImpl.java | 9 ++++++++- .../main/java/lol/pyr/znpcsplus/npc/NpcTypeImpl.java | 2 +- .../lol/pyr/znpcsplus/tasks/NpcProcessorTask.java | 12 +++++++----- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java index 47928e6..4fae9cf 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java @@ -127,7 +127,7 @@ public class ZNpcsPlus extends JavaPlugin { ConfigManager configManager = new ConfigManager(getDataFolder()); MojangSkinCache skinCache = new MojangSkinCache(configManager); - EntityPropertyRegistryImpl propertyRegistry = new EntityPropertyRegistryImpl(skinCache); + EntityPropertyRegistryImpl propertyRegistry = new EntityPropertyRegistryImpl(skinCache, configManager); PacketFactory packetFactory = setupPacketFactory(scheduler, propertyRegistry); propertyRegistry.registerTypes(packetFactory); 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 d3cd5ce..eaaea72 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java @@ -10,6 +10,7 @@ import com.github.retrooper.packetevents.protocol.player.EquipmentSlot; import lol.pyr.znpcsplus.api.entity.EntityProperty; import lol.pyr.znpcsplus.api.entity.EntityPropertyRegistry; import lol.pyr.znpcsplus.api.skin.SkinDescriptor; +import lol.pyr.znpcsplus.config.ConfigManager; import lol.pyr.znpcsplus.entity.properties.*; import lol.pyr.znpcsplus.entity.properties.villager.VillagerLevelProperty; import lol.pyr.znpcsplus.entity.properties.villager.VillagerProfessionProperty; @@ -42,8 +43,9 @@ import java.util.stream.Collectors; public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { private final Map, PropertySerializer> serializerMap = new HashMap<>(); private final Map> byName = new HashMap<>(); + private final ConfigManager configManager; - public EntityPropertyRegistryImpl(MojangSkinCache skinCache) { + public EntityPropertyRegistryImpl(MojangSkinCache skinCache, ConfigManager configManager) { registerSerializer(new ComponentPropertySerializer()); registerSerializer(new NamedTextColorPropertySerializer()); registerSerializer(new SkinDescriptorSerializer(skinCache)); @@ -77,6 +79,8 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { registerPrimitiveSerializers(Integer.class, Boolean.class, Double.class, Float.class, Long.class, Short.class, Byte.class, String.class); + this.configManager = configManager; + /* registerType("using_item", false); // TODO: fix it for 1.8 and add new property to use offhand item and riptide animation @@ -144,6 +148,9 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { register(new DinnerboneProperty(legacyNames, optionalComponents)); register(new DummyProperty<>("look", LookType.FIXED)); + register(new DummyProperty<>("look_distance", configManager.getConfig().lookPropertyDistance())); + register(new DummyProperty<>("view_distance", configManager.getConfig().viewDistance())); + register(new GlowProperty(packetFactory)); register(new BitsetProperty("fire", 0, 0x01)); register(new BitsetProperty("invisible", 0, 0x20)); 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 3bc2af7..259341c 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeImpl.java @@ -110,7 +110,7 @@ public class NpcTypeImpl implements NpcType { public NpcTypeImpl build() { ServerVersion version = PacketEvents.getAPI().getServerManager().getVersion(); - addProperties("fire", "invisible", "silent", "look", + addProperties("fire", "invisible", "silent", "look", "look_distance", "view_distance", "potion_color", "potion_ambient", "dinnerbone"); // TODO: make this look nicer after completing the rest of the properties if (version.isNewerThanOrEquals(ServerVersion.V_1_9)) addProperties("glow"); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java b/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java index 5576028..2f45c55 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/tasks/NpcProcessorTask.java @@ -27,9 +27,10 @@ public class NpcProcessorTask extends BukkitRunnable { } public void run() { - double distSq = NumberConversions.square(configManager.getConfig().viewDistance()); - double lookPropertyDistSq = NumberConversions.square(configManager.getConfig().lookPropertyDistance()); + EntityPropertyImpl viewDistanceProperty = propertyRegistry.getByName("view_distance", Integer.class); // Not sure why this is an Integer, but it is EntityPropertyImpl lookProperty = propertyRegistry.getByName("look", LookType.class); + EntityPropertyImpl lookDistanceProperty = propertyRegistry.getByName("look_distance", Double.class); + double lookDistance; for (NpcEntryImpl entry : npcRegistry.getProcessable()) { NpcImpl npc = entry.getNpc(); if (!npc.isEnabled()) continue; @@ -37,6 +38,7 @@ public class NpcProcessorTask extends BukkitRunnable { double closestDist = Double.MAX_VALUE; Player closest = null; LookType lookType = npc.getProperty(lookProperty); + lookDistance = NumberConversions.square(npc.getProperty(lookDistanceProperty)); for (Player player : Bukkit.getOnlinePlayers()) { if (!player.getWorld().equals(npc.getWorld())) { if (npc.isVisibleTo(player)) npc.hide(player); @@ -45,7 +47,7 @@ public class NpcProcessorTask extends BukkitRunnable { double distance = player.getLocation().distanceSquared(npc.getBukkitLocation()); // visibility - boolean inRange = distance <= distSq; + boolean inRange = distance <= NumberConversions.square(npc.getProperty(viewDistanceProperty)); if (!inRange && npc.isVisibleTo(player)) { NpcDespawnEvent event = new NpcDespawnEvent(player, entry); Bukkit.getPluginManager().callEvent(event); @@ -62,7 +64,7 @@ public class NpcProcessorTask extends BukkitRunnable { closestDist = distance; closest = player; } - if (lookType.equals(LookType.PER_PLAYER) && lookPropertyDistSq >= distance) { + if (lookType.equals(LookType.PER_PLAYER) && lookDistance >= distance) { NpcLocation expected = npc.getLocation().lookingAt(player.getLocation().add(0, -npc.getType().getHologramOffset(), 0)); if (!expected.equals(npc.getLocation())) npc.setHeadRotation(player, expected.getYaw(), expected.getPitch()); } @@ -70,7 +72,7 @@ public class NpcProcessorTask extends BukkitRunnable { } // look property if (lookType.equals(LookType.CLOSEST_PLAYER)) { - if (closest != null && lookPropertyDistSq >= closestDist) { + if (closest != null && lookDistance >= closestDist) { NpcLocation expected = npc.getLocation().lookingAt(closest.getLocation().add(0, -npc.getType().getHologramOffset(), 0)); if (!expected.equals(npc.getLocation())) npc.setHeadRotation(expected.getYaw(), expected.getPitch()); } From bedb6250ca332364cd2cdb282183dc44fcd853e4 Mon Sep 17 00:00:00 2001 From: D3v1s0m Date: Mon, 18 Sep 2023 12:43:20 +0530 Subject: [PATCH 7/7] disabled dinnerbone for player npc --- plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 259341c..56cbd06 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcTypeImpl.java @@ -111,7 +111,8 @@ public class NpcTypeImpl implements NpcType { public NpcTypeImpl build() { ServerVersion version = PacketEvents.getAPI().getServerManager().getVersion(); addProperties("fire", "invisible", "silent", "look", "look_distance", "view_distance", - "potion_color", "potion_ambient", "dinnerbone"); + "potion_color", "potion_ambient"); + if (!type.equals(EntityTypes.PLAYER)) addProperties("dinnerbone"); // TODO: make this look nicer after completing the rest of the properties if (version.isNewerThanOrEquals(ServerVersion.V_1_9)) addProperties("glow"); if (version.isNewerThanOrEquals(ServerVersion.V_1_14)) {