fix some properties removing others when being applied standalone

This commit is contained in:
Pyrbu 2023-07-24 02:33:29 +02:00
parent 792b962e49
commit c8abf4f3fb
10 changed files with 60 additions and 24 deletions

@ -14,6 +14,7 @@ public abstract class EntityPropertyImpl<T> implements EntityProperty<T> {
private final String name; private final String name;
private final T defaultValue; private final T defaultValue;
private final Class<T> clazz; private final Class<T> clazz;
private final List<EntityPropertyImpl<?>> dependencies = new ArrayList<>();
protected EntityPropertyImpl(String name, T defaultValue, Class<T> clazz) { protected EntityPropertyImpl(String name, T defaultValue, Class<T> clazz) {
this.name = name.toLowerCase(); this.name = name.toLowerCase();
@ -35,20 +36,20 @@ public abstract class EntityPropertyImpl<T> implements EntityProperty<T> {
return clazz; return clazz;
} }
public void addDependency(EntityPropertyImpl<?> property) {
dependencies.add(property);
}
protected static <V> EntityData newEntityData(int index, EntityDataType<V> type, V value) { protected static <V> EntityData newEntityData(int index, EntityDataType<V> type, V value) {
return new EntityData(index, type, value); return new EntityData(index, type, value);
} }
public List<EntityData> makeStandaloneData(T value, Player player, PacketEntity packetEntity, boolean isSpawned) { public List<EntityData> applyStandalone(Player player, PacketEntity packetEntity, boolean isSpawned) {
Map<Integer, EntityData> map = new HashMap<>(); Map<Integer, EntityData> 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()); return new ArrayList<>(map.values());
} }
abstract public void apply(T value, Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties); abstract public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties);
@SuppressWarnings("unchecked")
public void UNSAFE_apply(Object value, Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
apply((T) value, player, entity, isSpawned, properties);
}
} }

@ -11,10 +11,7 @@ import lol.pyr.znpcsplus.skin.cache.MojangSkinCache;
import lol.pyr.znpcsplus.util.*; import lol.pyr.znpcsplus.util.*;
import org.bukkit.DyeColor; import org.bukkit.DyeColor;
import java.util.Collection; import java.util.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -252,10 +249,12 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
register(new NameProperty()); register(new NameProperty());
register(new DummyProperty<>("look", false)); register(new DummyProperty<>("look", false));
register(new DummyProperty<>("skin", SkinDescriptor.class));
register(new GlowProperty(packetFactory)); register(new GlowProperty(packetFactory));
register(new EffectsProperty("fire", 0x01)); register(new EffectsProperty("fire", 0x01));
register(new EffectsProperty("invisible", 0x20)); register(new EffectsProperty("invisible", 0x20));
register(new DummyProperty<>("skin", SkinDescriptor.class)); linkProperties("glow", "fire", "invisible");
} }
private void registerSerializer(PropertySerializer<?> serializer) { private void registerSerializer(PropertySerializer<?> serializer) {
@ -272,6 +271,19 @@ public class EntityPropertyRegistryImpl implements EntityPropertyRegistry {
byName.put(property.getName(), property); byName.put(property.getName(), property);
} }
private void linkProperties(String... names) {
linkProperties(Arrays.stream(names)
.map(this::getByName)
.collect(Collectors.toSet()));
}
private void linkProperties(Collection<EntityPropertyImpl<?>> properties) {
for (EntityPropertyImpl<?> property : properties) for (EntityPropertyImpl<?> dependency : properties) {
if (property.equals(dependency)) continue;
property.addDependency(dependency);
}
}
public <V> PropertySerializer<V> getSerializer(Class<V> type) { public <V> PropertySerializer<V> getSerializer(Class<V> type) {
return (PropertySerializer<V>) serializerMap.get(type); return (PropertySerializer<V>) serializerMap.get(type);
} }

@ -4,6 +4,7 @@ import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.manager.server.ServerVersion; 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.EntityType;
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; 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.api.entity.PropertyHolder;
import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.packets.PacketFactory;
import lol.pyr.znpcsplus.reflection.Reflections; import lol.pyr.znpcsplus.reflection.Reflections;
@ -11,9 +12,10 @@ import lol.pyr.znpcsplus.util.NpcLocation;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.Collection; import java.util.Collection;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
public class PacketEntity { public class PacketEntity implements PropertyHolder {
private final PacketFactory packetFactory; private final PacketFactory packetFactory;
private final PropertyHolder properties; private final PropertyHolder properties;
@ -75,4 +77,24 @@ public class PacketEntity {
return id; return id;
} }
} }
@Override
public <T> T getProperty(EntityProperty<T> key) {
return properties.getProperty(key);
}
@Override
public boolean hasProperty(EntityProperty<?> key) {
return properties.hasProperty(key);
}
@Override
public <T> void setProperty(EntityProperty<T> key, T value) {
properties.setProperty(key, value);
}
@Override
public Set<EntityProperty<?>> getAppliedProperties() {
return properties.getAppliedProperties();
}
} }

@ -18,6 +18,6 @@ public class DummyProperty<T> extends EntityPropertyImpl<T> {
} }
@Override @Override
public void apply(T value, Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) { public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
} }
} }

@ -17,9 +17,9 @@ public class EffectsProperty extends EntityPropertyImpl<Boolean> {
} }
@Override @Override
public void apply(Boolean enabled, Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) { public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
EntityData oldData = properties.get(0); EntityData oldData = properties.get(0);
byte oldValue = oldData == null ? 0 : (byte) oldData.getValue(); 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))));
} }
} }

@ -22,7 +22,7 @@ public class EquipmentProperty extends EntityPropertyImpl<ItemStack> {
} }
@Override @Override
public void apply(ItemStack value, Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) { public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
packetFactory.sendEquipment(player, entity, new Equipment(slot, value)); packetFactory.sendEquipment(player, entity, new Equipment(slot, entity.getProperty(this)));
} }
} }

@ -19,7 +19,8 @@ public class GlowProperty extends EntityPropertyImpl<NamedTextColor> {
} }
@Override @Override
public void apply(NamedTextColor value, Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) { public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
NamedTextColor value = entity.getProperty(this);
EntityData oldData = properties.get(0); EntityData oldData = properties.get(0);
byte oldValue = oldData == null ? 0 : (byte) oldData.getValue(); byte oldValue = oldData == null ? 0 : (byte) oldData.getValue();
properties.put(0, newEntityData(0, EntityDataTypes.BYTE, (byte) (oldValue | (value == null ? 0 : 0x40)))); properties.put(0, newEntityData(0, EntityDataTypes.BYTE, (byte) (oldValue | (value == null ? 0 : 0x40))));

@ -26,7 +26,8 @@ public class NameProperty extends EntityPropertyImpl<Component> {
} }
@Override @Override
public void apply(Component value, Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) { public void apply(Player player, PacketEntity entity, boolean isSpawned, Map<Integer, EntityData> properties) {
Component value = entity.getProperty(this);
if (value != null) { if (value != null) {
String serialized = legacy ? String serialized = legacy ?
AdventureSerializer.getLegacyGsonSerializer().serialize(value) : AdventureSerializer.getLegacyGsonSerializer().serialize(value) :

@ -122,7 +122,7 @@ public class NpcImpl extends Viewable implements Npc {
private <T> void UNSAFE_refreshProperty(EntityPropertyImpl<T> property) { private <T> void UNSAFE_refreshProperty(EntityPropertyImpl<T> property) {
for (Player viewer : getViewers()) { for (Player viewer : getViewers()) {
List<EntityData> data = property.makeStandaloneData(getProperty(property), viewer, entity, true); List<EntityData> data = property.applyStandalone(viewer, entity, true);
if (data.size() > 0) packetFactory.sendMetadata(viewer, entity, data); if (data.size() > 0) packetFactory.sendMetadata(viewer, entity, data);
} }
} }

@ -249,8 +249,7 @@ public class V1_8PacketFactory implements PacketFactory {
@Override @Override
public void sendAllMetadata(Player player, PacketEntity entity, PropertyHolder properties) { public void sendAllMetadata(Player player, PacketEntity entity, PropertyHolder properties) {
Map<Integer, EntityData> datas = new HashMap<>(); Map<Integer, EntityData> datas = new HashMap<>();
for (EntityProperty<?> property : properties.getAppliedProperties()) for (EntityProperty<?> property : properties.getAppliedProperties()) ((EntityPropertyImpl<?>) property).apply(player, entity, false, datas);
((EntityPropertyImpl<?>) property).UNSAFE_apply(properties.getProperty(property), player, entity, false, datas);
sendMetadata(player, entity, new ArrayList<>(datas.values())); sendMetadata(player, entity, new ArrayList<>(datas.values()));
} }