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 ffe4f48..9842fbb 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyImpl.java @@ -14,6 +14,7 @@ public abstract class EntityPropertyImpl implements EntityProperty { private final String name; private final T defaultValue; private final Class clazz; + private final List> dependencies = new ArrayList<>(); protected EntityPropertyImpl(String name, T defaultValue, Class clazz) { this.name = name.toLowerCase(); @@ -35,20 +36,20 @@ public abstract class EntityPropertyImpl implements EntityProperty { return clazz; } + public void addDependency(EntityPropertyImpl property) { + dependencies.add(property); + } + protected static EntityData newEntityData(int index, EntityDataType type, V value) { return new EntityData(index, type, value); } - public List makeStandaloneData(T value, Player player, PacketEntity packetEntity, boolean isSpawned) { + public List applyStandalone(Player player, PacketEntity packetEntity, boolean isSpawned) { Map map = new HashMap<>(); - apply(value, player, packetEntity, isSpawned, map); + apply(player, packetEntity, isSpawned, map); + for (EntityPropertyImpl property : dependencies) property.apply(player, packetEntity, isSpawned, map); return new ArrayList<>(map.values()); } - abstract public void apply(T value, Player player, PacketEntity entity, boolean isSpawned, Map properties); - - @SuppressWarnings("unchecked") - public void UNSAFE_apply(Object value, Player player, PacketEntity entity, boolean isSpawned, Map properties) { - apply((T) value, player, entity, isSpawned, 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 026bea6..b8a33f5 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/EntityPropertyRegistryImpl.java @@ -11,10 +11,7 @@ import lol.pyr.znpcsplus.skin.cache.MojangSkinCache; import lol.pyr.znpcsplus.util.*; import org.bukkit.DyeColor; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; /** @@ -252,10 +249,12 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { register(new NameProperty()); register(new DummyProperty<>("look", false)); + register(new DummyProperty<>("skin", SkinDescriptor.class)); + register(new GlowProperty(packetFactory)); register(new EffectsProperty("fire", 0x01)); register(new EffectsProperty("invisible", 0x20)); - register(new DummyProperty<>("skin", SkinDescriptor.class)); + linkProperties("glow", "fire", "invisible"); } private void registerSerializer(PropertySerializer serializer) { @@ -272,6 +271,19 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry { byName.put(property.getName(), property); } + private void linkProperties(String... names) { + linkProperties(Arrays.stream(names) + .map(this::getByName) + .collect(Collectors.toSet())); + } + + private void linkProperties(Collection> properties) { + for (EntityPropertyImpl property : properties) for (EntityPropertyImpl dependency : properties) { + if (property.equals(dependency)) continue; + property.addDependency(dependency); + } + } + public PropertySerializer getSerializer(Class type) { return (PropertySerializer) serializerMap.get(type); } 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 d933679..aef8b03 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/PacketEntity.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/PacketEntity.java @@ -4,6 +4,7 @@ import com.github.retrooper.packetevents.PacketEvents; import com.github.retrooper.packetevents.manager.server.ServerVersion; import com.github.retrooper.packetevents.protocol.entity.type.EntityType; import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; +import lol.pyr.znpcsplus.api.entity.EntityProperty; import lol.pyr.znpcsplus.api.entity.PropertyHolder; import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.reflection.Reflections; @@ -11,9 +12,10 @@ import lol.pyr.znpcsplus.util.NpcLocation; import org.bukkit.entity.Player; import java.util.Collection; +import java.util.Set; import java.util.UUID; -public class PacketEntity { +public class PacketEntity implements PropertyHolder { private final PacketFactory packetFactory; private final PropertyHolder properties; @@ -75,4 +77,24 @@ public class PacketEntity { return id; } } + + @Override + public T getProperty(EntityProperty key) { + return properties.getProperty(key); + } + + @Override + public boolean hasProperty(EntityProperty key) { + return properties.hasProperty(key); + } + + @Override + public void setProperty(EntityProperty key, T value) { + properties.setProperty(key, value); + } + + @Override + public Set> getAppliedProperties() { + return properties.getAppliedProperties(); + } } 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 e92897c..9e1306e 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 @@ -18,6 +18,6 @@ public class DummyProperty extends EntityPropertyImpl { } @Override - public void apply(T value, 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/EffectsProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EffectsProperty.java index 91171af..e031ad7 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EffectsProperty.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/EffectsProperty.java @@ -17,9 +17,9 @@ public class EffectsProperty extends EntityPropertyImpl { } @Override - public void apply(Boolean enabled, Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { EntityData oldData = properties.get(0); byte oldValue = oldData == null ? 0 : (byte) oldData.getValue(); - properties.put(0, newEntityData(0, EntityDataTypes.BYTE, (byte) (oldValue | (enabled ? bitmask : 0)))); + properties.put(0, newEntityData(0, EntityDataTypes.BYTE, (byte) (oldValue | (entity.getProperty(this) ? bitmask : 0)))); } } 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 25171d8..c0219a7 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(ItemStack value, Player player, PacketEntity entity, boolean isSpawned, Map properties) { - packetFactory.sendEquipment(player, entity, new Equipment(slot, value)); + 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/GlowProperty.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/properties/GlowProperty.java index b4221e6..13931d8 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,7 +19,8 @@ public class GlowProperty extends EntityPropertyImpl { } @Override - public void apply(NamedTextColor value, Player player, PacketEntity entity, boolean isSpawned, Map properties) { + public void apply(Player player, PacketEntity entity, boolean isSpawned, Map properties) { + NamedTextColor value = entity.getProperty(this); EntityData oldData = properties.get(0); byte oldValue = oldData == null ? 0 : (byte) oldData.getValue(); properties.put(0, newEntityData(0, EntityDataTypes.BYTE, (byte) (oldValue | (value == null ? 0 : 0x40)))); 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 d4cc7a3..9434aea 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 @@ -26,7 +26,8 @@ public class NameProperty extends EntityPropertyImpl { } @Override - public void apply(Component value, 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) { String serialized = legacy ? AdventureSerializer.getLegacyGsonSerializer().serialize(value) : 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 77316d5..619083f 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcImpl.java @@ -122,7 +122,7 @@ public class NpcImpl extends Viewable implements Npc { private void UNSAFE_refreshProperty(EntityPropertyImpl property) { for (Player viewer : getViewers()) { - List data = property.makeStandaloneData(getProperty(property), viewer, entity, true); + List data = property.applyStandalone(viewer, entity, true); if (data.size() > 0) packetFactory.sendMetadata(viewer, entity, data); } } 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 f416195..cbbc35b 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 @@ -249,8 +249,7 @@ public class V1_8PacketFactory implements PacketFactory { @Override public void sendAllMetadata(Player player, PacketEntity entity, PropertyHolder properties) { Map datas = new HashMap<>(); - for (EntityProperty property : properties.getAppliedProperties()) - ((EntityPropertyImpl) property).UNSAFE_apply(properties.getProperty(property), player, entity, false, datas); + for (EntityProperty property : properties.getAppliedProperties()) ((EntityPropertyImpl) property).apply(player, entity, false, datas); sendMetadata(player, entity, new ArrayList<>(datas.values())); }