make entity properties not static

This commit is contained in:
Pyrbu 2023-05-21 14:25:21 +01:00
parent c1cdf290cb
commit fa8247f285
23 changed files with 339 additions and 201 deletions

@ -2,4 +2,5 @@ package lol.pyr.znpcsplus.api.entity;
public interface EntityProperty<T> { public interface EntityProperty<T> {
T getDefaultValue(); T getDefaultValue();
String getName();
} }

@ -22,6 +22,7 @@ import lol.pyr.znpcsplus.commands.storage.LoadAllCommand;
import lol.pyr.znpcsplus.commands.storage.SaveAllCommand; import lol.pyr.znpcsplus.commands.storage.SaveAllCommand;
import lol.pyr.znpcsplus.config.ConfigManager; import lol.pyr.znpcsplus.config.ConfigManager;
import lol.pyr.znpcsplus.entity.EntityPropertyImpl; import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
import lol.pyr.znpcsplus.entity.EntityPropertyRegistry;
import lol.pyr.znpcsplus.interaction.ActionRegistry; import lol.pyr.znpcsplus.interaction.ActionRegistry;
import lol.pyr.znpcsplus.interaction.InteractionPacketListener; import lol.pyr.znpcsplus.interaction.InteractionPacketListener;
import lol.pyr.znpcsplus.metadata.*; import lol.pyr.znpcsplus.metadata.*;
@ -106,23 +107,24 @@ public class ZNpcsPlus extends JavaPlugin {
log(ChatColor.WHITE + " * Initializing components..."); log(ChatColor.WHITE + " * Initializing components...");
TaskScheduler scheduler = FoliaUtil.isFolia() ? new FoliaScheduler(this) : new SpigotScheduler(this); TaskScheduler scheduler = FoliaUtil.isFolia() ? new FoliaScheduler(this) : new SpigotScheduler(this);
MetadataFactory metadataFactory = setupMetadataFactory(); MetadataFactory metadataFactory = setupMetadataFactory();
PacketFactory packetFactory = setupPacketFactory(scheduler, metadataFactory);
BungeeConnector bungeeConnector = new BungeeConnector(this);
ConfigManager configManager = new ConfigManager(getDataFolder()); ConfigManager configManager = new ConfigManager(getDataFolder());
SkinCache skinCache = new SkinCache(configManager);
EntityPropertyRegistry propertyRegistry = new EntityPropertyRegistry(skinCache);
PacketFactory packetFactory = setupPacketFactory(scheduler, metadataFactory, propertyRegistry);
BungeeConnector bungeeConnector = new BungeeConnector(this);
ActionRegistry actionRegistry = new ActionRegistry(); ActionRegistry actionRegistry = new ActionRegistry();
NpcTypeRegistry typeRegistry = new NpcTypeRegistry(); NpcTypeRegistry typeRegistry = new NpcTypeRegistry();
NpcRegistryImpl npcRegistry = new NpcRegistryImpl(configManager, this, packetFactory, actionRegistry, scheduler, typeRegistry); NpcRegistryImpl npcRegistry = new NpcRegistryImpl(configManager, this, packetFactory, actionRegistry, scheduler, typeRegistry, propertyRegistry);
UserManager userManager = new UserManager(); UserManager userManager = new UserManager();
SkinCache skinCache = new SkinCache(configManager);
log(ChatColor.WHITE + " * Registerring components..."); log(ChatColor.WHITE + " * Registerring components...");
typeRegistry.registerDefault(packetEvents); typeRegistry.registerDefault(packetEvents, propertyRegistry);
actionRegistry.registerTypes(npcRegistry, scheduler, adventure, bungeeConnector, textSerializer); actionRegistry.registerTypes(npcRegistry, scheduler, adventure, bungeeConnector, textSerializer);
packetEvents.getEventManager().registerListener(new InteractionPacketListener(userManager, npcRegistry), PacketListenerPriority.MONITOR); packetEvents.getEventManager().registerListener(new InteractionPacketListener(userManager, npcRegistry), PacketListenerPriority.MONITOR);
new Metrics(this, PLUGIN_ID); new Metrics(this, PLUGIN_ID);
pluginManager.registerEvents(new UserListener(userManager), this); pluginManager.registerEvents(new UserListener(userManager), this);
getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
registerCommands(npcRegistry, skinCache, adventure, actionRegistry, typeRegistry); registerCommands(npcRegistry, skinCache, adventure, actionRegistry, typeRegistry, propertyRegistry);
log(ChatColor.WHITE + " * Starting tasks..."); log(ChatColor.WHITE + " * Starting tasks...");
if (configManager.getConfig().checkForUpdates()) { if (configManager.getConfig().checkForUpdates()) {
@ -168,13 +170,13 @@ public class ZNpcsPlus extends JavaPlugin {
for (Runnable runnable : shutdownTasks) runnable.run(); for (Runnable runnable : shutdownTasks) runnable.run();
} }
private PacketFactory setupPacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory) { private PacketFactory setupPacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory, EntityPropertyRegistry propertyRegistry) {
HashMap<ServerVersion, LazyLoader<? extends PacketFactory>> versions = new HashMap<>(); HashMap<ServerVersion, LazyLoader<? extends PacketFactory>> versions = new HashMap<>();
versions.put(ServerVersion.V_1_8, LazyLoader.of(() -> new V1_8PacketFactory(scheduler, metadataFactory, packetEvents))); versions.put(ServerVersion.V_1_8, LazyLoader.of(() -> new V1_8PacketFactory(scheduler, metadataFactory, packetEvents, propertyRegistry)));
versions.put(ServerVersion.V_1_9, LazyLoader.of(() -> new V1_9PacketFactory(scheduler, metadataFactory, packetEvents))); versions.put(ServerVersion.V_1_9, LazyLoader.of(() -> new V1_9PacketFactory(scheduler, metadataFactory, packetEvents, propertyRegistry)));
versions.put(ServerVersion.V_1_10, LazyLoader.of(() -> new V1_10PacketFactory(scheduler, metadataFactory, packetEvents))); versions.put(ServerVersion.V_1_10, LazyLoader.of(() -> new V1_10PacketFactory(scheduler, metadataFactory, packetEvents, propertyRegistry)));
versions.put(ServerVersion.V_1_14, LazyLoader.of(() -> new V1_14PacketFactory(scheduler, metadataFactory, packetEvents))); versions.put(ServerVersion.V_1_14, LazyLoader.of(() -> new V1_14PacketFactory(scheduler, metadataFactory, packetEvents, propertyRegistry)));
versions.put(ServerVersion.V_1_19, LazyLoader.of(() -> new V1_19PacketFactory(scheduler, metadataFactory, packetEvents))); versions.put(ServerVersion.V_1_19, LazyLoader.of(() -> new V1_19PacketFactory(scheduler, metadataFactory, packetEvents, propertyRegistry)));
ServerVersion version = packetEvents.getServerManager().getVersion(); ServerVersion version = packetEvents.getServerManager().getVersion();
if (versions.containsKey(version)) return versions.get(version).get(); if (versions.containsKey(version)) return versions.get(version).get();
@ -207,14 +209,14 @@ public class ZNpcsPlus extends JavaPlugin {
} }
private void registerCommands(NpcRegistryImpl npcRegistry, SkinCache skinCache, BukkitAudiences adventure, ActionRegistry actionRegistry, NpcTypeRegistry typeRegistry) { private void registerCommands(NpcRegistryImpl npcRegistry, SkinCache skinCache, BukkitAudiences adventure, ActionRegistry actionRegistry, NpcTypeRegistry typeRegistry, EntityPropertyRegistry propertyRegistry) {
// TODO: make the messages better // TODO: make the messages better
Message<CommandContext> incorrectUsageMessage = context -> context.send(Component.text("Incorrect usage: /" + context.getUsage(), NamedTextColor.RED)); Message<CommandContext> incorrectUsageMessage = context -> context.send(Component.text("Incorrect usage: /" + context.getUsage(), NamedTextColor.RED));
CommandManager manager = new CommandManager(this, adventure, incorrectUsageMessage); CommandManager manager = new CommandManager(this, adventure, incorrectUsageMessage);
manager.registerParser(NpcTypeImpl.class, new NpcTypeParser(incorrectUsageMessage, typeRegistry)); manager.registerParser(NpcTypeImpl.class, new NpcTypeParser(incorrectUsageMessage, typeRegistry));
manager.registerParser(NpcEntryImpl.class, new NpcEntryParser(npcRegistry, incorrectUsageMessage)); manager.registerParser(NpcEntryImpl.class, new NpcEntryParser(npcRegistry, incorrectUsageMessage));
manager.registerParser(EntityPropertyImpl.class, new EntityPropertyParser(incorrectUsageMessage)); manager.registerParser(EntityPropertyImpl.class, new EntityPropertyParser(incorrectUsageMessage, propertyRegistry));
manager.registerParser(Integer.class, new IntegerParser(incorrectUsageMessage)); manager.registerParser(Integer.class, new IntegerParser(incorrectUsageMessage));
manager.registerParser(Double.class, new DoubleParser(incorrectUsageMessage)); manager.registerParser(Double.class, new DoubleParser(incorrectUsageMessage));
manager.registerParser(Boolean.class, new BooleanParser(incorrectUsageMessage)); manager.registerParser(Boolean.class, new BooleanParser(incorrectUsageMessage));
@ -222,7 +224,7 @@ public class ZNpcsPlus extends JavaPlugin {
manager.registerCommand("npc", new MultiCommand() manager.registerCommand("npc", new MultiCommand()
.addSubcommand("create", new CreateCommand(npcRegistry, typeRegistry)) .addSubcommand("create", new CreateCommand(npcRegistry, typeRegistry))
.addSubcommand("skin", new SkinCommand(skinCache, npcRegistry, typeRegistry)) .addSubcommand("skin", new SkinCommand(skinCache, npcRegistry, typeRegistry, propertyRegistry))
.addSubcommand("delete", new DeleteCommand(npcRegistry, adventure)) .addSubcommand("delete", new DeleteCommand(npcRegistry, adventure))
.addSubcommand("move", new MoveCommand(npcRegistry)) .addSubcommand("move", new MoveCommand(npcRegistry))
.addSubcommand("properties", new PropertiesCommand(npcRegistry)) .addSubcommand("properties", new PropertiesCommand(npcRegistry))

@ -4,8 +4,12 @@ import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import lol.pyr.director.adventure.command.CommandContext; import lol.pyr.director.adventure.command.CommandContext;
import lol.pyr.director.adventure.command.CommandHandler; import lol.pyr.director.adventure.command.CommandHandler;
import lol.pyr.director.common.command.CommandExecutionException; import lol.pyr.director.common.command.CommandExecutionException;
import lol.pyr.znpcsplus.entity.EntityPropertyImpl; import lol.pyr.znpcsplus.api.skin.SkinDescriptor;
import lol.pyr.znpcsplus.npc.*; import lol.pyr.znpcsplus.entity.EntityPropertyRegistry;
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
import lol.pyr.znpcsplus.npc.NpcImpl;
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
import lol.pyr.znpcsplus.npc.NpcTypeRegistry;
import lol.pyr.znpcsplus.skin.cache.SkinCache; import lol.pyr.znpcsplus.skin.cache.SkinCache;
import lol.pyr.znpcsplus.skin.descriptor.FetchingDescriptor; import lol.pyr.znpcsplus.skin.descriptor.FetchingDescriptor;
import lol.pyr.znpcsplus.skin.descriptor.MirrorDescriptor; import lol.pyr.znpcsplus.skin.descriptor.MirrorDescriptor;
@ -20,11 +24,13 @@ public class SkinCommand implements CommandHandler {
private final SkinCache skinCache; private final SkinCache skinCache;
private final NpcRegistryImpl npcRegistry; private final NpcRegistryImpl npcRegistry;
private final NpcTypeRegistry typeRegistry; private final NpcTypeRegistry typeRegistry;
private final EntityPropertyRegistry propertyRegistry;
public SkinCommand(SkinCache skinCache, NpcRegistryImpl npcRegistry, NpcTypeRegistry typeRegistry) { public SkinCommand(SkinCache skinCache, NpcRegistryImpl npcRegistry, NpcTypeRegistry typeRegistry, EntityPropertyRegistry propertyRegistry) {
this.skinCache = skinCache; this.skinCache = skinCache;
this.npcRegistry = npcRegistry; this.npcRegistry = npcRegistry;
this.typeRegistry = typeRegistry; this.typeRegistry = typeRegistry;
this.propertyRegistry = propertyRegistry;
} }
@Override @Override
@ -35,7 +41,7 @@ public class SkinCommand implements CommandHandler {
String type = context.popString(); String type = context.popString();
if (type.equalsIgnoreCase("mirror")) { if (type.equalsIgnoreCase("mirror")) {
npc.setProperty(EntityPropertyImpl.SKIN, new MirrorDescriptor(skinCache)); npc.setProperty(propertyRegistry.getByName("skin", SkinDescriptor.class), new MirrorDescriptor(skinCache));
npc.respawn(); npc.respawn();
context.halt(Component.text("The NPC's skin will now mirror the player that it's being displayed to", NamedTextColor.GREEN)); context.halt(Component.text("The NPC's skin will now mirror the player that it's being displayed to", NamedTextColor.GREEN));
} }
@ -49,7 +55,7 @@ public class SkinCommand implements CommandHandler {
context.send(Component.text("Failed to fetch skin, are you sure the player name is valid?", NamedTextColor.RED)); context.send(Component.text("Failed to fetch skin, are you sure the player name is valid?", NamedTextColor.RED));
return; return;
} }
npc.setProperty(EntityPropertyImpl.SKIN, skin); npc.setProperty(propertyRegistry.getByName("skin", SkinDescriptor.class), skin);
npc.respawn(); npc.respawn();
context.send(Component.text("The NPC's skin has been set to \"" + name + "\"")); context.send(Component.text("The NPC's skin has been set to \"" + name + "\""));
}); });
@ -59,7 +65,7 @@ public class SkinCommand implements CommandHandler {
if (type.equalsIgnoreCase("dynamic")) { if (type.equalsIgnoreCase("dynamic")) {
context.ensureArgsNotEmpty(); context.ensureArgsNotEmpty();
String name = context.dumpAllArgs(); String name = context.dumpAllArgs();
npc.setProperty(EntityPropertyImpl.SKIN, new FetchingDescriptor(skinCache, name)); npc.setProperty(propertyRegistry.getByName("skin", SkinDescriptor.class), new FetchingDescriptor(skinCache, name));
npc.respawn(); npc.respawn();
context.halt(Component.text("The NPC's skin will now be resolved per-player from \"" + name + "\"")); context.halt(Component.text("The NPC's skin will now be resolved per-player from \"" + name + "\""));
} }

@ -2,41 +2,30 @@ package lol.pyr.znpcsplus.entity;
import lol.pyr.znpcsplus.api.entity.EntityProperty; 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.api.skin.SkinDescriptor;
import lol.pyr.znpcsplus.skin.BaseSkinDescriptor;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.minimessage.MiniMessage;
import java.util.HashMap;
import java.util.Map;
public class EntityPropertyImpl<T> implements EntityProperty<T> { public 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 PropertySerializer<T> serializer; private final PropertySerializer<T> serializer;
private final PropertyDeserializer<T> deserializer;
public EntityPropertyImpl(String name, Class<T> type, PropertySerializer<T> serializer, PropertyDeserializer<T> deserializer) { protected EntityPropertyImpl(String name, Class<T> type, PropertySerializer<T> serializer) {
this(name, null, type, serializer, deserializer); this(name, null, type, serializer);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public EntityPropertyImpl(String name, T defaultValue, PropertySerializer<T> serializer, PropertyDeserializer<T> deserializer) { protected EntityPropertyImpl(String name, T defaultValue, PropertySerializer<T> serializer) {
this(name, defaultValue, (Class<T>) defaultValue.getClass(), serializer, deserializer); this(name, defaultValue, (Class<T>) defaultValue.getClass(), serializer);
} }
private EntityPropertyImpl(String name, T defaultValue, Class<T> clazz, PropertySerializer<T> serializer, PropertyDeserializer<T> deserializer) { private EntityPropertyImpl(String name, T defaultValue, Class<T> clazz, PropertySerializer<T> serializer) {
this.name = name.toUpperCase(); this.name = name.toLowerCase();
this.defaultValue = defaultValue; this.defaultValue = defaultValue;
this.clazz = clazz; this.clazz = clazz;
this.serializer = serializer; this.serializer = serializer;
this.deserializer = deserializer;
BY_NAME.put(this.name, this);
} }
@Override
public String getName() { public String getName() {
return name; return name;
} }
@ -50,7 +39,7 @@ public class EntityPropertyImpl<T> implements EntityProperty<T> {
} }
public T deserialize(String str) { public T deserialize(String str) {
return deserializer.deserialize(str); return serializer.deserialize(str);
} }
@Override @Override
@ -61,42 +50,4 @@ public class EntityPropertyImpl<T> implements EntityProperty<T> {
public Class<T> getType() { public Class<T> getType() {
return clazz; return clazz;
} }
private final static Map<String, EntityPropertyImpl<?>> BY_NAME = new HashMap<>();
public static EntityPropertyImpl<?> getByName(String name) {
return BY_NAME.get(name.toUpperCase());
}
@FunctionalInterface
private interface PropertySerializer<T> {
String serialize(T property);
}
@FunctionalInterface
private interface PropertyDeserializer<T> {
T deserialize(String property);
}
private final static PropertySerializer<Boolean> BOOLEAN_SERIALIZER = Object::toString;
private final static PropertyDeserializer<Boolean> BOOLEAN_DESERIALIZER = Boolean::valueOf;
private final static PropertySerializer<NamedTextColor> COLOR_SERIALIZER = color -> String.valueOf(color.value());
private final static PropertyDeserializer<NamedTextColor> COLOR_DESERIALIZER = str -> NamedTextColor.namedColor(Integer.parseInt(str));
private final static PropertySerializer<Component> COMPONENT_SERIALIZER = component -> MiniMessage.miniMessage().serialize(component);
private final static PropertyDeserializer<Component> COMPONENT_DESERIALIZER = str -> MiniMessage.miniMessage().deserialize(str);
private final static PropertySerializer<SkinDescriptor> DESCRIPTOR_SERIALIZER = descriptor -> ((BaseSkinDescriptor) descriptor).serialize();
private final static PropertyDeserializer<SkinDescriptor> DESCRIPTOR_DESERIALIZER = property -> null; // TODO: An actual property registry // BaseSkinDescriptor::deserialize;
public static EntityPropertyImpl<NamedTextColor> GLOW = new EntityPropertyImpl<>("glow", NamedTextColor.class, COLOR_SERIALIZER, COLOR_DESERIALIZER);
public static EntityPropertyImpl<Boolean> SKIN_LAYERS = new EntityPropertyImpl<>("skin_layers", true, BOOLEAN_SERIALIZER, BOOLEAN_DESERIALIZER);
public static EntityPropertyImpl<Boolean> FIRE = new EntityPropertyImpl<>("fire", false, BOOLEAN_SERIALIZER, BOOLEAN_DESERIALIZER);
public static EntityPropertyImpl<Boolean> INVISIBLE = new EntityPropertyImpl<>("invisible", false, BOOLEAN_SERIALIZER, BOOLEAN_DESERIALIZER);
public static EntityPropertyImpl<Boolean> SILENT = new EntityPropertyImpl<>("silent", false, BOOLEAN_SERIALIZER, BOOLEAN_DESERIALIZER);
public static EntityPropertyImpl<SkinDescriptor> SKIN = new EntityPropertyImpl<>("skin", SkinDescriptor.class, DESCRIPTOR_SERIALIZER, DESCRIPTOR_DESERIALIZER);
public static EntityPropertyImpl<Component> NAME = new EntityPropertyImpl<>("name", Component.class, COMPONENT_SERIALIZER, COMPONENT_DESERIALIZER);
} }

@ -0,0 +1,57 @@
package lol.pyr.znpcsplus.entity;
import lol.pyr.znpcsplus.api.skin.SkinDescriptor;
import lol.pyr.znpcsplus.entity.serializers.BooleanPropertySerializer;
import lol.pyr.znpcsplus.entity.serializers.ComponentPropertySerializer;
import lol.pyr.znpcsplus.entity.serializers.NamedTextColorPropertySerializer;
import lol.pyr.znpcsplus.entity.serializers.SkinDescriptorSerializer;
import lol.pyr.znpcsplus.skin.cache.SkinCache;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@SuppressWarnings("unchecked")
public class EntityPropertyRegistry {
private final Map<Class<?>, PropertySerializer<?>> serializerMap = new HashMap<>();
private final List<EntityPropertyImpl<?>> properties = new ArrayList<>();
public EntityPropertyRegistry(SkinCache skinCache) {
registerSerializer(new BooleanPropertySerializer());
registerSerializer(new ComponentPropertySerializer());
registerSerializer(new NamedTextColorPropertySerializer());
registerSerializer(new SkinDescriptorSerializer(skinCache));
registerType("glow", NamedTextColor.class);
registerType("skin_layers", true);
registerType("fire", false);
registerType("invisible", false);
registerType("silent", false);
registerType("skin", SkinDescriptor.class);
registerType("name", Component.class);
}
private void registerSerializer(PropertySerializer<?> serializer) {
serializerMap.put(serializer.getTypeClass(), serializer);
}
private <T> void registerType(String name, Class<T> type) {
properties.add(new EntityPropertyImpl<>(name, type, (PropertySerializer<T>) serializerMap.get(type)));
}
private <T> void registerType(String name, T defaultValue) {
properties.add(new EntityPropertyImpl<>(name, defaultValue, (PropertySerializer<T>) serializerMap.get(defaultValue.getClass())));
}
public <T> EntityPropertyImpl<T> getByName(String name, Class<T> type) {
return (EntityPropertyImpl<T>) getByName(name);
}
public EntityPropertyImpl<?> getByName(String name) {
for (EntityPropertyImpl<?> property : properties) if (property.getName().equalsIgnoreCase(name)) return property;
return null;
}
}

@ -0,0 +1,7 @@
package lol.pyr.znpcsplus.entity;
public interface PropertySerializer<T> {
String serialize(T property);
T deserialize(String property);
Class<T> getTypeClass();
}

@ -0,0 +1,20 @@
package lol.pyr.znpcsplus.entity.serializers;
import lol.pyr.znpcsplus.entity.PropertySerializer;
public class BooleanPropertySerializer implements PropertySerializer<Boolean> {
@Override
public String serialize(Boolean property) {
return String.valueOf(property);
}
@Override
public Boolean deserialize(String property) {
return Boolean.valueOf(property);
}
@Override
public Class<Boolean> getTypeClass() {
return Boolean.class;
}
}

@ -0,0 +1,25 @@
package lol.pyr.znpcsplus.entity.serializers;
import lol.pyr.znpcsplus.entity.PropertySerializer;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class ComponentPropertySerializer implements PropertySerializer<Component> {
@Override
public String serialize(Component property) {
return Base64.getEncoder().encodeToString(MiniMessage.miniMessage().serialize(property).getBytes(StandardCharsets.UTF_8));
}
@Override
public Component deserialize(String property) {
return MiniMessage.miniMessage().deserialize(new String(Base64.getDecoder().decode(property), StandardCharsets.UTF_8));
}
@Override
public Class<Component> getTypeClass() {
return Component.class;
}
}

@ -0,0 +1,21 @@
package lol.pyr.znpcsplus.entity.serializers;
import lol.pyr.znpcsplus.entity.PropertySerializer;
import net.kyori.adventure.text.format.NamedTextColor;
public class NamedTextColorPropertySerializer implements PropertySerializer<NamedTextColor> {
@Override
public String serialize(NamedTextColor property) {
return String.valueOf(property.value());
}
@Override
public NamedTextColor deserialize(String property) {
return NamedTextColor.namedColor(Integer.parseInt(property));
}
@Override
public Class<NamedTextColor> getTypeClass() {
return NamedTextColor.class;
}
}

@ -0,0 +1,29 @@
package lol.pyr.znpcsplus.entity.serializers;
import lol.pyr.znpcsplus.api.skin.SkinDescriptor;
import lol.pyr.znpcsplus.entity.PropertySerializer;
import lol.pyr.znpcsplus.skin.BaseSkinDescriptor;
import lol.pyr.znpcsplus.skin.cache.SkinCache;
public class SkinDescriptorSerializer implements PropertySerializer<SkinDescriptor> {
private final SkinCache skinCache;
public SkinDescriptorSerializer(SkinCache skinCache) {
this.skinCache = skinCache;
}
@Override
public String serialize(SkinDescriptor property) {
return ((BaseSkinDescriptor) property).serialize();
}
@Override
public SkinDescriptor deserialize(String property) {
return BaseSkinDescriptor.deserialize(skinCache, property);
}
@Override
public Class<SkinDescriptor> getTypeClass() {
return SkinDescriptor.class;
}
}

@ -3,7 +3,6 @@ package lol.pyr.znpcsplus.hologram;
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.EntityProperty;
import lol.pyr.znpcsplus.api.entity.PropertyHolder; import lol.pyr.znpcsplus.api.entity.PropertyHolder;
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
import lol.pyr.znpcsplus.entity.PacketEntity; import lol.pyr.znpcsplus.entity.PacketEntity;
import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.packets.PacketFactory;
import lol.pyr.znpcsplus.util.NpcLocation; import lol.pyr.znpcsplus.util.NpcLocation;
@ -44,13 +43,13 @@ public class HologramLine implements PropertyHolder {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public <T> T getProperty(EntityProperty<T> key) { public <T> T getProperty(EntityProperty<T> key) {
if (key == EntityPropertyImpl.INVISIBLE) return (T) Boolean.TRUE; if (key.getName().equalsIgnoreCase("invisible")) return (T) Boolean.TRUE;
if (key == EntityPropertyImpl.NAME) return (T) text; if (key.getName().equalsIgnoreCase("name")) return (T) text;
return key.getDefaultValue(); return key.getDefaultValue();
} }
@Override @Override
public boolean hasProperty(EntityProperty<?> key) { public boolean hasProperty(EntityProperty<?> key) {
return key == EntityPropertyImpl.NAME || key == EntityPropertyImpl.INVISIBLE; return key.getName().equalsIgnoreCase("name") || key.getName().equalsIgnoreCase("invisible");
} }
} }

@ -8,8 +8,8 @@ import lol.pyr.znpcsplus.entity.PacketEntity;
import lol.pyr.znpcsplus.hologram.HologramImpl; import lol.pyr.znpcsplus.hologram.HologramImpl;
import lol.pyr.znpcsplus.interaction.InteractionAction; import lol.pyr.znpcsplus.interaction.InteractionAction;
import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.packets.PacketFactory;
import lol.pyr.znpcsplus.util.Viewable;
import lol.pyr.znpcsplus.util.NpcLocation; import lol.pyr.znpcsplus.util.NpcLocation;
import lol.pyr.znpcsplus.util.Viewable;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
@ -117,7 +117,7 @@ public class NpcImpl extends Viewable implements Npc {
if (value.equals(key.getDefaultValue())) removeProperty(key); if (value.equals(key.getDefaultValue())) removeProperty(key);
else propertyMap.put(key, value); else propertyMap.put(key, value);
UNSAFE_refreshMeta(); UNSAFE_refreshMeta();
if (key == EntityPropertyImpl.GLOW) UNSAFE_remakeTeam(); if (key.getName().equalsIgnoreCase("glow")) UNSAFE_remakeTeam();
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -128,7 +128,7 @@ public class NpcImpl extends Viewable implements Npc {
public void removeProperty(EntityPropertyImpl<?> key) { public void removeProperty(EntityPropertyImpl<?> key) {
propertyMap.remove(key); propertyMap.remove(key);
UNSAFE_refreshMeta(); UNSAFE_refreshMeta();
if (key == EntityPropertyImpl.GLOW) UNSAFE_remakeTeam(); if (key.getName().equalsIgnoreCase("glow")) UNSAFE_remakeTeam();
} }
public Set<EntityPropertyImpl<?>> getAppliedProperties() { public Set<EntityPropertyImpl<?>> getAppliedProperties() {

@ -4,6 +4,7 @@ import lol.pyr.znpcsplus.ZNpcsPlus;
import lol.pyr.znpcsplus.api.npc.NpcRegistry; import lol.pyr.znpcsplus.api.npc.NpcRegistry;
import lol.pyr.znpcsplus.api.npc.NpcType; import lol.pyr.znpcsplus.api.npc.NpcType;
import lol.pyr.znpcsplus.config.ConfigManager; import lol.pyr.znpcsplus.config.ConfigManager;
import lol.pyr.znpcsplus.entity.EntityPropertyRegistry;
import lol.pyr.znpcsplus.interaction.ActionRegistry; import lol.pyr.znpcsplus.interaction.ActionRegistry;
import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.packets.PacketFactory;
import lol.pyr.znpcsplus.scheduling.TaskScheduler; import lol.pyr.znpcsplus.scheduling.TaskScheduler;
@ -22,8 +23,8 @@ public class NpcRegistryImpl implements NpcRegistry {
private final PacketFactory packetFactory; private final PacketFactory packetFactory;
private final ConfigManager configManager; private final ConfigManager configManager;
public NpcRegistryImpl(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, TaskScheduler scheduler, NpcTypeRegistry typeRegistry) { public NpcRegistryImpl(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, TaskScheduler scheduler, NpcTypeRegistry typeRegistry, EntityPropertyRegistry propertyRegistry) {
storage = configManager.getConfig().storageType().create(configManager, plugin, packetFactory, actionRegistry, typeRegistry); storage = configManager.getConfig().storageType().create(configManager, plugin, packetFactory, actionRegistry, typeRegistry, propertyRegistry);
this.packetFactory = packetFactory; this.packetFactory = packetFactory;
this.configManager = configManager; this.configManager = configManager;

@ -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 lol.pyr.znpcsplus.entity.EntityPropertyImpl; import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
import lol.pyr.znpcsplus.entity.EntityPropertyRegistry;
import java.util.*; import java.util.*;
@ -14,7 +15,7 @@ public class NpcTypeImpl {
private final double hologramOffset; private final double hologramOffset;
private NpcTypeImpl(String name, EntityType type, double hologramOffset, Set<EntityPropertyImpl<?>> allowedProperties) { private NpcTypeImpl(String name, EntityType type, double hologramOffset, Set<EntityPropertyImpl<?>> allowedProperties) {
this.name = name.toUpperCase(); this.name = name.toLowerCase();
this.type = type; this.type = type;
this.hologramOffset = hologramOffset; this.hologramOffset = hologramOffset;
this.allowedProperties = allowedProperties; this.allowedProperties = allowedProperties;
@ -37,13 +38,15 @@ public class NpcTypeImpl {
} }
protected static final class Builder { protected static final class Builder {
private final EntityPropertyRegistry propertyRegistry;
private final String name; private final String name;
private final EntityType type; private final EntityType type;
private final List<EntityPropertyImpl<?>> allowedProperties = new ArrayList<>(); private final List<EntityPropertyImpl<?>> allowedProperties = new ArrayList<>();
private boolean globalProperties = true; private boolean globalProperties = true;
private double hologramOffset = 0; private double hologramOffset = 0;
Builder(String name, EntityType type) { Builder(EntityPropertyRegistry propertyRegistry, String name, EntityType type) {
this.propertyRegistry = propertyRegistry;
this.name = name; this.name = name;
this.type = type; this.type = type;
} }
@ -65,11 +68,11 @@ public class NpcTypeImpl {
public NpcTypeImpl build() { public NpcTypeImpl build() {
if (globalProperties) { if (globalProperties) {
allowedProperties.add(EntityPropertyImpl.FIRE); allowedProperties.add(propertyRegistry.getByName("fire"));
allowedProperties.add(EntityPropertyImpl.INVISIBLE); allowedProperties.add(propertyRegistry.getByName("invisible"));
allowedProperties.add(EntityPropertyImpl.SILENT); allowedProperties.add(propertyRegistry.getByName("silent"));
if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9)) if (PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9))
allowedProperties.add(EntityPropertyImpl.GLOW); allowedProperties.add(propertyRegistry.getByName("glow"));
} }
return new NpcTypeImpl(name, type, hologramOffset, new HashSet<>(allowedProperties)); return new NpcTypeImpl(name, type, hologramOffset, new HashSet<>(allowedProperties));
} }

@ -4,7 +4,7 @@ import com.github.retrooper.packetevents.PacketEventsAPI;
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.entity.EntityPropertyImpl; import lol.pyr.znpcsplus.entity.EntityPropertyRegistry;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import java.util.ArrayList; import java.util.ArrayList;
@ -24,110 +24,110 @@ public class NpcTypeRegistry {
return type; return type;
} }
public void registerDefault(PacketEventsAPI<Plugin> packetEvents) { public void registerDefault(PacketEventsAPI<Plugin> packetEvents, EntityPropertyRegistry propertyRegistry) {
ServerVersion version = packetEvents.getServerManager().getVersion(); ServerVersion version = packetEvents.getServerManager().getVersion();
register(new NpcTypeImpl.Builder("player", EntityTypes.PLAYER).setHologramOffset(-0.15D) register(new NpcTypeImpl.Builder(propertyRegistry, "player", EntityTypes.PLAYER).setHologramOffset(-0.15D)
.addProperties(EntityPropertyImpl.SKIN, EntityPropertyImpl.SKIN_LAYERS)); .addProperties(propertyRegistry.getByName("skin"), propertyRegistry.getByName("skin_layers")));
register(new NpcTypeImpl.Builder("armor_stand", EntityTypes.ARMOR_STAND)); register(new NpcTypeImpl.Builder(propertyRegistry, "armor_stand", EntityTypes.ARMOR_STAND));
register(new NpcTypeImpl.Builder("bat", EntityTypes.BAT).setHologramOffset(-1.365)); register(new NpcTypeImpl.Builder(propertyRegistry, "bat", EntityTypes.BAT).setHologramOffset(-1.365));
register(new NpcTypeImpl.Builder("blaze", EntityTypes.BLAZE)); register(new NpcTypeImpl.Builder(propertyRegistry, "blaze", EntityTypes.BLAZE));
register(new NpcTypeImpl.Builder("cat", EntityTypes.CAT)); register(new NpcTypeImpl.Builder(propertyRegistry, "cat", EntityTypes.CAT));
register(new NpcTypeImpl.Builder("cave_spider", EntityTypes.CAVE_SPIDER)); register(new NpcTypeImpl.Builder(propertyRegistry, "cave_spider", EntityTypes.CAVE_SPIDER));
register(new NpcTypeImpl.Builder("chicken", EntityTypes.CHICKEN)); register(new NpcTypeImpl.Builder(propertyRegistry, "chicken", EntityTypes.CHICKEN));
register(new NpcTypeImpl.Builder("cow", EntityTypes.COW)); register(new NpcTypeImpl.Builder(propertyRegistry, "cow", EntityTypes.COW));
register(new NpcTypeImpl.Builder("creeper", EntityTypes.CREEPER).setHologramOffset(-0.3D)); register(new NpcTypeImpl.Builder(propertyRegistry, "creeper", EntityTypes.CREEPER).setHologramOffset(-0.3D));
register(new NpcTypeImpl.Builder("donkey", EntityTypes.DONKEY)); register(new NpcTypeImpl.Builder(propertyRegistry, "donkey", EntityTypes.DONKEY));
register(new NpcTypeImpl.Builder("elder_guardian", EntityTypes.ELDER_GUARDIAN)); register(new NpcTypeImpl.Builder(propertyRegistry, "elder_guardian", EntityTypes.ELDER_GUARDIAN));
register(new NpcTypeImpl.Builder("ender_dragon", EntityTypes.ENDER_DRAGON)); register(new NpcTypeImpl.Builder(propertyRegistry, "ender_dragon", EntityTypes.ENDER_DRAGON));
register(new NpcTypeImpl.Builder("enderman", EntityTypes.ENDERMAN)); register(new NpcTypeImpl.Builder(propertyRegistry, "enderman", EntityTypes.ENDERMAN));
register(new NpcTypeImpl.Builder("endermite", EntityTypes.ENDERMITE)); register(new NpcTypeImpl.Builder(propertyRegistry, "endermite", EntityTypes.ENDERMITE));
register(new NpcTypeImpl.Builder("ghast", EntityTypes.GHAST)); register(new NpcTypeImpl.Builder(propertyRegistry, "ghast", EntityTypes.GHAST));
register(new NpcTypeImpl.Builder("giant", EntityTypes.GIANT)); register(new NpcTypeImpl.Builder(propertyRegistry, "giant", EntityTypes.GIANT));
register(new NpcTypeImpl.Builder("guardian", EntityTypes.GUARDIAN)); register(new NpcTypeImpl.Builder(propertyRegistry, "guardian", EntityTypes.GUARDIAN));
register(new NpcTypeImpl.Builder("horse", EntityTypes.HORSE)); register(new NpcTypeImpl.Builder(propertyRegistry, "horse", EntityTypes.HORSE));
register(new NpcTypeImpl.Builder("iron_golem", EntityTypes.IRON_GOLEM)); register(new NpcTypeImpl.Builder(propertyRegistry, "iron_golem", EntityTypes.IRON_GOLEM));
register(new NpcTypeImpl.Builder("magma_cube", EntityTypes.MAGMA_CUBE)); register(new NpcTypeImpl.Builder(propertyRegistry, "magma_cube", EntityTypes.MAGMA_CUBE));
register(new NpcTypeImpl.Builder("mooshroom", EntityTypes.MOOSHROOM)); register(new NpcTypeImpl.Builder(propertyRegistry, "mooshroom", EntityTypes.MOOSHROOM));
register(new NpcTypeImpl.Builder("mule", EntityTypes.MULE)); register(new NpcTypeImpl.Builder(propertyRegistry, "mule", EntityTypes.MULE));
register(new NpcTypeImpl.Builder("ocelot", EntityTypes.OCELOT)); register(new NpcTypeImpl.Builder(propertyRegistry, "ocelot", EntityTypes.OCELOT));
register(new NpcTypeImpl.Builder("pig", EntityTypes.PIG)); register(new NpcTypeImpl.Builder(propertyRegistry, "pig", EntityTypes.PIG));
register(new NpcTypeImpl.Builder("rabbit", EntityTypes.RABBIT)); register(new NpcTypeImpl.Builder(propertyRegistry, "rabbit", EntityTypes.RABBIT));
register(new NpcTypeImpl.Builder("sheep", EntityTypes.SHEEP)); register(new NpcTypeImpl.Builder(propertyRegistry, "sheep", EntityTypes.SHEEP));
register(new NpcTypeImpl.Builder("silverfish", EntityTypes.SILVERFISH)); register(new NpcTypeImpl.Builder(propertyRegistry, "silverfish", EntityTypes.SILVERFISH));
register(new NpcTypeImpl.Builder("skeleton", EntityTypes.SKELETON)); register(new NpcTypeImpl.Builder(propertyRegistry, "skeleton", EntityTypes.SKELETON));
register(new NpcTypeImpl.Builder("skeleton_horse", EntityTypes.SKELETON_HORSE)); register(new NpcTypeImpl.Builder(propertyRegistry, "skeleton_horse", EntityTypes.SKELETON_HORSE));
register(new NpcTypeImpl.Builder("slime", EntityTypes.SLIME)); register(new NpcTypeImpl.Builder(propertyRegistry, "slime", EntityTypes.SLIME));
register(new NpcTypeImpl.Builder("snow_golem", EntityTypes.SNOW_GOLEM)); register(new NpcTypeImpl.Builder(propertyRegistry, "snow_golem", EntityTypes.SNOW_GOLEM));
register(new NpcTypeImpl.Builder("spider", EntityTypes.SPIDER)); register(new NpcTypeImpl.Builder(propertyRegistry, "spider", EntityTypes.SPIDER));
register(new NpcTypeImpl.Builder("squid", EntityTypes.SQUID)); register(new NpcTypeImpl.Builder(propertyRegistry, "squid", EntityTypes.SQUID));
register(new NpcTypeImpl.Builder("villager", EntityTypes.VILLAGER)); register(new NpcTypeImpl.Builder(propertyRegistry, "villager", EntityTypes.VILLAGER));
register(new NpcTypeImpl.Builder("witch", EntityTypes.WITCH)); register(new NpcTypeImpl.Builder(propertyRegistry, "witch", EntityTypes.WITCH));
register(new NpcTypeImpl.Builder("wither", EntityTypes.WITHER)); register(new NpcTypeImpl.Builder(propertyRegistry, "wither", EntityTypes.WITHER));
register(new NpcTypeImpl.Builder("wither_skeleton", EntityTypes.WITHER_SKELETON)); register(new NpcTypeImpl.Builder(propertyRegistry, "wither_skeleton", EntityTypes.WITHER_SKELETON));
register(new NpcTypeImpl.Builder("wolf", EntityTypes.WOLF)); register(new NpcTypeImpl.Builder(propertyRegistry, "wolf", EntityTypes.WOLF));
register(new NpcTypeImpl.Builder("zombie", EntityTypes.ZOMBIE)); register(new NpcTypeImpl.Builder(propertyRegistry, "zombie", EntityTypes.ZOMBIE));
register(new NpcTypeImpl.Builder("zombie_horse", EntityTypes.ZOMBIE_HORSE)); register(new NpcTypeImpl.Builder(propertyRegistry, "zombie_horse", EntityTypes.ZOMBIE_HORSE));
register(new NpcTypeImpl.Builder("zombie_villager", EntityTypes.ZOMBIE_VILLAGER)); register(new NpcTypeImpl.Builder(propertyRegistry, "zombie_villager", EntityTypes.ZOMBIE_VILLAGER));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_9)) return; if (!version.isNewerThanOrEquals(ServerVersion.V_1_9)) return;
register(new NpcTypeImpl.Builder("shulker", EntityTypes.SHULKER)); register(new NpcTypeImpl.Builder(propertyRegistry, "shulker", EntityTypes.SHULKER));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_10)) return; if (!version.isNewerThanOrEquals(ServerVersion.V_1_10)) return;
register(new NpcTypeImpl.Builder("husk", EntityTypes.HUSK)); register(new NpcTypeImpl.Builder(propertyRegistry, "husk", EntityTypes.HUSK));
register(new NpcTypeImpl.Builder("polar_bear", EntityTypes.POLAR_BEAR)); register(new NpcTypeImpl.Builder(propertyRegistry, "polar_bear", EntityTypes.POLAR_BEAR));
register(new NpcTypeImpl.Builder("stray", EntityTypes.STRAY)); register(new NpcTypeImpl.Builder(propertyRegistry, "stray", EntityTypes.STRAY));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_11)) return; if (!version.isNewerThanOrEquals(ServerVersion.V_1_11)) return;
register(new NpcTypeImpl.Builder("evoker", EntityTypes.EVOKER)); register(new NpcTypeImpl.Builder(propertyRegistry, "evoker", EntityTypes.EVOKER));
register(new NpcTypeImpl.Builder("llama", EntityTypes.LLAMA)); register(new NpcTypeImpl.Builder(propertyRegistry, "llama", EntityTypes.LLAMA));
register(new NpcTypeImpl.Builder("vex", EntityTypes.VEX)); register(new NpcTypeImpl.Builder(propertyRegistry, "vex", EntityTypes.VEX));
register(new NpcTypeImpl.Builder("vindicator", EntityTypes.VINDICATOR)); register(new NpcTypeImpl.Builder(propertyRegistry, "vindicator", EntityTypes.VINDICATOR));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_12)) return; if (!version.isNewerThanOrEquals(ServerVersion.V_1_12)) return;
register(new NpcTypeImpl.Builder("illusioner", EntityTypes.ILLUSIONER)); register(new NpcTypeImpl.Builder(propertyRegistry, "illusioner", EntityTypes.ILLUSIONER));
register(new NpcTypeImpl.Builder("parrot", EntityTypes.PARROT)); register(new NpcTypeImpl.Builder(propertyRegistry, "parrot", EntityTypes.PARROT));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_13)) return; if (!version.isNewerThanOrEquals(ServerVersion.V_1_13)) return;
register(new NpcTypeImpl.Builder("cod", EntityTypes.COD)); register(new NpcTypeImpl.Builder(propertyRegistry, "cod", EntityTypes.COD));
register(new NpcTypeImpl.Builder("dolphin", EntityTypes.DOLPHIN)); register(new NpcTypeImpl.Builder(propertyRegistry, "dolphin", EntityTypes.DOLPHIN));
register(new NpcTypeImpl.Builder("drowned", EntityTypes.DROWNED)); register(new NpcTypeImpl.Builder(propertyRegistry, "drowned", EntityTypes.DROWNED));
register(new NpcTypeImpl.Builder("phantom", EntityTypes.PHANTOM)); register(new NpcTypeImpl.Builder(propertyRegistry, "phantom", EntityTypes.PHANTOM));
register(new NpcTypeImpl.Builder("pufferfish", EntityTypes.PUFFERFISH)); register(new NpcTypeImpl.Builder(propertyRegistry, "pufferfish", EntityTypes.PUFFERFISH));
register(new NpcTypeImpl.Builder("salmon", EntityTypes.SALMON)); register(new NpcTypeImpl.Builder(propertyRegistry, "salmon", EntityTypes.SALMON));
register(new NpcTypeImpl.Builder("tropical_fish", EntityTypes.TROPICAL_FISH)); register(new NpcTypeImpl.Builder(propertyRegistry, "tropical_fish", EntityTypes.TROPICAL_FISH));
register(new NpcTypeImpl.Builder("turtle", EntityTypes.TURTLE)); register(new NpcTypeImpl.Builder(propertyRegistry, "turtle", EntityTypes.TURTLE));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_14)) return; if (!version.isNewerThanOrEquals(ServerVersion.V_1_14)) return;
register(new NpcTypeImpl.Builder("fox", EntityTypes.FOX)); register(new NpcTypeImpl.Builder(propertyRegistry, "fox", EntityTypes.FOX));
register(new NpcTypeImpl.Builder("panda", EntityTypes.PANDA)); register(new NpcTypeImpl.Builder(propertyRegistry, "panda", EntityTypes.PANDA));
register(new NpcTypeImpl.Builder("pillager", EntityTypes.PILLAGER)); register(new NpcTypeImpl.Builder(propertyRegistry, "pillager", EntityTypes.PILLAGER));
register(new NpcTypeImpl.Builder("ravager", EntityTypes.RAVAGER)); register(new NpcTypeImpl.Builder(propertyRegistry, "ravager", EntityTypes.RAVAGER));
register(new NpcTypeImpl.Builder("trader_llama", EntityTypes.TRADER_LLAMA)); register(new NpcTypeImpl.Builder(propertyRegistry, "trader_llama", EntityTypes.TRADER_LLAMA));
register(new NpcTypeImpl.Builder("wandering_trader", EntityTypes.WANDERING_TRADER)); register(new NpcTypeImpl.Builder(propertyRegistry, "wandering_trader", EntityTypes.WANDERING_TRADER));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_15)) return; if (!version.isNewerThanOrEquals(ServerVersion.V_1_15)) return;
register(new NpcTypeImpl.Builder("bee", EntityTypes.BEE)); register(new NpcTypeImpl.Builder(propertyRegistry, "bee", EntityTypes.BEE));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_16)) return; if (!version.isNewerThanOrEquals(ServerVersion.V_1_16)) return;
register(new NpcTypeImpl.Builder("hoglin", EntityTypes.HOGLIN)); register(new NpcTypeImpl.Builder(propertyRegistry, "hoglin", EntityTypes.HOGLIN));
register(new NpcTypeImpl.Builder("piglin", EntityTypes.PIGLIN)); register(new NpcTypeImpl.Builder(propertyRegistry, "piglin", EntityTypes.PIGLIN));
register(new NpcTypeImpl.Builder("piglin_brute", EntityTypes.PIGLIN_BRUTE)); register(new NpcTypeImpl.Builder(propertyRegistry, "piglin_brute", EntityTypes.PIGLIN_BRUTE));
register(new NpcTypeImpl.Builder("strider", EntityTypes.STRIDER)); register(new NpcTypeImpl.Builder(propertyRegistry, "strider", EntityTypes.STRIDER));
register(new NpcTypeImpl.Builder("zoglin", EntityTypes.ZOGLIN)); register(new NpcTypeImpl.Builder(propertyRegistry, "zoglin", EntityTypes.ZOGLIN));
register(new NpcTypeImpl.Builder("zombified_piglin", EntityTypes.ZOMBIFIED_PIGLIN)); register(new NpcTypeImpl.Builder(propertyRegistry, "zombified_piglin", EntityTypes.ZOMBIFIED_PIGLIN));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_17)) return; if (!version.isNewerThanOrEquals(ServerVersion.V_1_17)) return;
register(new NpcTypeImpl.Builder("axolotl", EntityTypes.AXOLOTL)); register(new NpcTypeImpl.Builder(propertyRegistry, "axolotl", EntityTypes.AXOLOTL));
register(new NpcTypeImpl.Builder("glow_squid", EntityTypes.GLOW_SQUID)); register(new NpcTypeImpl.Builder(propertyRegistry, "glow_squid", EntityTypes.GLOW_SQUID));
register(new NpcTypeImpl.Builder("goat", EntityTypes.GOAT)); register(new NpcTypeImpl.Builder(propertyRegistry, "goat", EntityTypes.GOAT));
if (!version.isNewerThanOrEquals(ServerVersion.V_1_19)) return; if (!version.isNewerThanOrEquals(ServerVersion.V_1_19)) return;
register(new NpcTypeImpl.Builder("allay", EntityTypes.ALLAY)); register(new NpcTypeImpl.Builder(propertyRegistry, "allay", EntityTypes.ALLAY));
register(new NpcTypeImpl.Builder("frog", EntityTypes.FROG)); register(new NpcTypeImpl.Builder(propertyRegistry, "frog", EntityTypes.FROG));
register(new NpcTypeImpl.Builder("tadpole", EntityTypes.TADPOLE)); register(new NpcTypeImpl.Builder(propertyRegistry, "tadpole", EntityTypes.TADPOLE));
register(new NpcTypeImpl.Builder("warden", EntityTypes.WARDEN)); register(new NpcTypeImpl.Builder(propertyRegistry, "warden", EntityTypes.WARDEN));
} }
public Collection<NpcTypeImpl> getAll() { public Collection<NpcTypeImpl> getAll() {

@ -3,6 +3,7 @@ package lol.pyr.znpcsplus.packets;
import com.github.retrooper.packetevents.PacketEventsAPI; import com.github.retrooper.packetevents.PacketEventsAPI;
import com.github.retrooper.packetevents.protocol.entity.data.EntityData; import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
import lol.pyr.znpcsplus.api.entity.PropertyHolder; import lol.pyr.znpcsplus.api.entity.PropertyHolder;
import lol.pyr.znpcsplus.entity.EntityPropertyRegistry;
import lol.pyr.znpcsplus.entity.PacketEntity; import lol.pyr.znpcsplus.entity.PacketEntity;
import lol.pyr.znpcsplus.metadata.MetadataFactory; import lol.pyr.znpcsplus.metadata.MetadataFactory;
import lol.pyr.znpcsplus.scheduling.TaskScheduler; import lol.pyr.znpcsplus.scheduling.TaskScheduler;
@ -12,8 +13,8 @@ import org.bukkit.plugin.Plugin;
import java.util.Map; import java.util.Map;
public class V1_10PacketFactory extends V1_9PacketFactory { public class V1_10PacketFactory extends V1_9PacketFactory {
public V1_10PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory, PacketEventsAPI<Plugin> packetEvents) { public V1_10PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory, PacketEventsAPI<Plugin> packetEvents, EntityPropertyRegistry propertyRegistry) {
super(scheduler, metadataFactory, packetEvents); super(scheduler, metadataFactory, packetEvents, propertyRegistry);
} }
@Override @Override

@ -4,6 +4,7 @@ import com.github.retrooper.packetevents.PacketEventsAPI;
import com.github.retrooper.packetevents.util.Vector3d; import com.github.retrooper.packetevents.util.Vector3d;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity;
import lol.pyr.znpcsplus.api.entity.PropertyHolder; import lol.pyr.znpcsplus.api.entity.PropertyHolder;
import lol.pyr.znpcsplus.entity.EntityPropertyRegistry;
import lol.pyr.znpcsplus.entity.PacketEntity; import lol.pyr.znpcsplus.entity.PacketEntity;
import lol.pyr.znpcsplus.metadata.MetadataFactory; import lol.pyr.znpcsplus.metadata.MetadataFactory;
import lol.pyr.znpcsplus.scheduling.TaskScheduler; import lol.pyr.znpcsplus.scheduling.TaskScheduler;
@ -14,8 +15,8 @@ import org.bukkit.plugin.Plugin;
import java.util.Optional; import java.util.Optional;
public class V1_14PacketFactory extends V1_10PacketFactory { public class V1_14PacketFactory extends V1_10PacketFactory {
public V1_14PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory, PacketEventsAPI<Plugin> packetEvents) { public V1_14PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory, PacketEventsAPI<Plugin> packetEvents, EntityPropertyRegistry propertyRegistry) {
super(scheduler, metadataFactory, packetEvents); super(scheduler, metadataFactory, packetEvents, propertyRegistry);
} }
@Override @Override

@ -6,6 +6,7 @@ import com.github.retrooper.packetevents.protocol.player.GameMode;
import com.github.retrooper.packetevents.protocol.player.UserProfile; import com.github.retrooper.packetevents.protocol.player.UserProfile;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoRemove; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoRemove;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate;
import lol.pyr.znpcsplus.entity.EntityPropertyRegistry;
import lol.pyr.znpcsplus.entity.PacketEntity; import lol.pyr.znpcsplus.entity.PacketEntity;
import lol.pyr.znpcsplus.api.entity.PropertyHolder; import lol.pyr.znpcsplus.api.entity.PropertyHolder;
import lol.pyr.znpcsplus.metadata.MetadataFactory; import lol.pyr.znpcsplus.metadata.MetadataFactory;
@ -18,8 +19,8 @@ import java.util.EnumSet;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class V1_19PacketFactory extends V1_14PacketFactory { public class V1_19PacketFactory extends V1_14PacketFactory {
public V1_19PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory, PacketEventsAPI<Plugin> packetEvents) { public V1_19PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory, PacketEventsAPI<Plugin> packetEvents, EntityPropertyRegistry propertyRegistry) {
super(scheduler, metadataFactory, packetEvents); super(scheduler, metadataFactory, packetEvents, propertyRegistry);
} }
@Override @Override

@ -11,7 +11,8 @@ import com.github.retrooper.packetevents.util.Vector3d;
import com.github.retrooper.packetevents.wrapper.PacketWrapper; import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.play.server.*; import com.github.retrooper.packetevents.wrapper.play.server.*;
import lol.pyr.znpcsplus.api.entity.PropertyHolder; import lol.pyr.znpcsplus.api.entity.PropertyHolder;
import lol.pyr.znpcsplus.entity.EntityPropertyImpl; import lol.pyr.znpcsplus.api.skin.SkinDescriptor;
import lol.pyr.znpcsplus.entity.EntityPropertyRegistry;
import lol.pyr.znpcsplus.entity.PacketEntity; import lol.pyr.znpcsplus.entity.PacketEntity;
import lol.pyr.znpcsplus.metadata.MetadataFactory; import lol.pyr.znpcsplus.metadata.MetadataFactory;
import lol.pyr.znpcsplus.scheduling.TaskScheduler; import lol.pyr.znpcsplus.scheduling.TaskScheduler;
@ -29,11 +30,13 @@ public class V1_8PacketFactory implements PacketFactory {
protected final TaskScheduler scheduler; protected final TaskScheduler scheduler;
protected final MetadataFactory metadataFactory; protected final MetadataFactory metadataFactory;
protected final PacketEventsAPI<Plugin> packetEvents; protected final PacketEventsAPI<Plugin> packetEvents;
protected final EntityPropertyRegistry propertyRegistry;
public V1_8PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory, PacketEventsAPI<Plugin> packetEvents) { public V1_8PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory, PacketEventsAPI<Plugin> packetEvents, EntityPropertyRegistry propertyRegistry) {
this.scheduler = scheduler; this.scheduler = scheduler;
this.metadataFactory = metadataFactory; this.metadataFactory = metadataFactory;
this.packetEvents = packetEvents; this.packetEvents = packetEvents;
this.propertyRegistry = propertyRegistry;
} }
@Override @Override
@ -103,7 +106,7 @@ public class V1_8PacketFactory implements PacketFactory {
Component.empty(), Component.empty(), Component.empty(), Component.empty(), Component.empty(), Component.empty(),
WrapperPlayServerTeams.NameTagVisibility.NEVER, WrapperPlayServerTeams.NameTagVisibility.NEVER,
WrapperPlayServerTeams.CollisionRule.NEVER, WrapperPlayServerTeams.CollisionRule.NEVER,
properties.hasProperty(EntityPropertyImpl.GLOW) ? properties.getProperty(EntityPropertyImpl.GLOW) : NamedTextColor.WHITE, properties.hasProperty(propertyRegistry.getByName("glow")) ? properties.getProperty(propertyRegistry.getByName("glow", NamedTextColor.class)) : NamedTextColor.WHITE,
WrapperPlayServerTeams.OptionData.NONE WrapperPlayServerTeams.OptionData.NONE
))); )));
sendPacket(player, new WrapperPlayServerTeams("npc_team_" + entity.getEntityId(), WrapperPlayServerTeams.TeamMode.ADD_ENTITIES, (WrapperPlayServerTeams.ScoreBoardTeamInfo) null, sendPacket(player, new WrapperPlayServerTeams("npc_team_" + entity.getEntityId(), WrapperPlayServerTeams.TeamMode.ADD_ENTITIES, (WrapperPlayServerTeams.ScoreBoardTeamInfo) null,
@ -118,10 +121,10 @@ public class V1_8PacketFactory implements PacketFactory {
@Override @Override
public Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties) { public Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties) {
HashMap<Integer, EntityData> data = new HashMap<>(); HashMap<Integer, EntityData> data = new HashMap<>();
if (entity.getType() == EntityTypes.PLAYER) add(data, metadataFactory.skinLayers(properties.getProperty(EntityPropertyImpl.SKIN_LAYERS))); if (entity.getType() == EntityTypes.PLAYER) add(data, metadataFactory.skinLayers(properties.getProperty(propertyRegistry.getByName("skin_layers", Boolean.class))));
add(data, metadataFactory.effects(properties.getProperty(EntityPropertyImpl.FIRE), false, properties.getProperty(EntityPropertyImpl.INVISIBLE))); add(data, metadataFactory.effects(properties.getProperty(propertyRegistry.getByName("fire", Boolean.class)), false, properties.getProperty(propertyRegistry.getByName("fire", Boolean.class))));
add(data, metadataFactory.silent(properties.getProperty(EntityPropertyImpl.SILENT))); add(data, metadataFactory.silent(properties.getProperty(propertyRegistry.getByName("silent", Boolean.class))));
if (properties.hasProperty(EntityPropertyImpl.NAME)) addAll(data, metadataFactory.name(properties.getProperty(EntityPropertyImpl.NAME))); if (properties.hasProperty(propertyRegistry.getByName("name"))) addAll(data, metadataFactory.name(properties.getProperty(propertyRegistry.getByName("name", Component.class))));
return data; return data;
} }
@ -140,8 +143,8 @@ public class V1_8PacketFactory implements PacketFactory {
} }
protected CompletableFuture<UserProfile> skinned(Player player, PropertyHolder properties, UserProfile profile) { protected CompletableFuture<UserProfile> skinned(Player player, PropertyHolder properties, UserProfile profile) {
if (!properties.hasProperty(EntityPropertyImpl.SKIN)) return CompletableFuture.completedFuture(profile); if (!properties.hasProperty(propertyRegistry.getByName("skin"))) return CompletableFuture.completedFuture(profile);
BaseSkinDescriptor descriptor = (BaseSkinDescriptor) properties.getProperty(EntityPropertyImpl.SKIN); BaseSkinDescriptor descriptor = (BaseSkinDescriptor) properties.getProperty(propertyRegistry.getByName("skin", SkinDescriptor.class));
if (descriptor.supportsInstant(player)) { if (descriptor.supportsInstant(player)) {
descriptor.fetchInstant(player).apply(profile); descriptor.fetchInstant(player).apply(profile);
return CompletableFuture.completedFuture(profile); return CompletableFuture.completedFuture(profile);

@ -3,7 +3,7 @@ package lol.pyr.znpcsplus.packets;
import com.github.retrooper.packetevents.PacketEventsAPI; import com.github.retrooper.packetevents.PacketEventsAPI;
import com.github.retrooper.packetevents.protocol.entity.data.EntityData; import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
import lol.pyr.znpcsplus.api.entity.PropertyHolder; import lol.pyr.znpcsplus.api.entity.PropertyHolder;
import lol.pyr.znpcsplus.entity.EntityPropertyImpl; import lol.pyr.znpcsplus.entity.EntityPropertyRegistry;
import lol.pyr.znpcsplus.entity.PacketEntity; import lol.pyr.znpcsplus.entity.PacketEntity;
import lol.pyr.znpcsplus.metadata.MetadataFactory; import lol.pyr.znpcsplus.metadata.MetadataFactory;
import lol.pyr.znpcsplus.scheduling.TaskScheduler; import lol.pyr.znpcsplus.scheduling.TaskScheduler;
@ -13,14 +13,16 @@ import org.bukkit.plugin.Plugin;
import java.util.Map; import java.util.Map;
public class V1_9PacketFactory extends V1_8PacketFactory { public class V1_9PacketFactory extends V1_8PacketFactory {
public V1_9PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory, PacketEventsAPI<Plugin> packetEvents) { public V1_9PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory, PacketEventsAPI<Plugin> packetEvents, EntityPropertyRegistry propertyRegistry) {
super(scheduler, metadataFactory, packetEvents); super(scheduler, metadataFactory, packetEvents, propertyRegistry);
} }
@Override @Override
public Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties) { public Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties) {
Map<Integer, EntityData> data = super.generateMetadata(player, entity, properties); Map<Integer, EntityData> data = super.generateMetadata(player, entity, properties);
add(data, metadataFactory.effects(properties.getProperty(EntityPropertyImpl.FIRE), properties.hasProperty(EntityPropertyImpl.GLOW), properties.getProperty(EntityPropertyImpl.INVISIBLE))); add(data, metadataFactory.effects(properties.getProperty(propertyRegistry.getByName("fire", Boolean.class)),
properties.hasProperty(propertyRegistry.getByName("glow", Boolean.class)),
properties.getProperty(propertyRegistry.getByName("invisible", Boolean.class))));
return data; return data;
} }
} }

@ -5,18 +5,22 @@ import lol.pyr.director.adventure.parse.ParserType;
import lol.pyr.director.common.command.CommandExecutionException; import lol.pyr.director.common.command.CommandExecutionException;
import lol.pyr.director.common.message.Message; import lol.pyr.director.common.message.Message;
import lol.pyr.znpcsplus.entity.EntityPropertyImpl; import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
import lol.pyr.znpcsplus.entity.EntityPropertyRegistry;
import java.util.Deque; import java.util.Deque;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public class EntityPropertyParser extends ParserType<EntityPropertyImpl/*<?>*/> { public class EntityPropertyParser extends ParserType<EntityPropertyImpl/*<?>*/> {
public EntityPropertyParser(Message<CommandContext> message) { private final EntityPropertyRegistry propertyRegistry;
public EntityPropertyParser(Message<CommandContext> message, EntityPropertyRegistry propertyRegistry) {
super(message); super(message);
this.propertyRegistry = propertyRegistry;
} }
@Override @Override
public EntityPropertyImpl<?> parse(Deque<String> deque) throws CommandExecutionException { public EntityPropertyImpl<?> parse(Deque<String> deque) throws CommandExecutionException {
EntityPropertyImpl<?> property = EntityPropertyImpl.getByName(deque.pop()); EntityPropertyImpl<?> property = propertyRegistry.getByName(deque.pop());
if (property == null) throw new CommandExecutionException(); if (property == null) throw new CommandExecutionException();
return property; return property;
} }

@ -2,6 +2,7 @@ package lol.pyr.znpcsplus.storage;
import lol.pyr.znpcsplus.ZNpcsPlus; import lol.pyr.znpcsplus.ZNpcsPlus;
import lol.pyr.znpcsplus.config.ConfigManager; import lol.pyr.znpcsplus.config.ConfigManager;
import lol.pyr.znpcsplus.entity.EntityPropertyRegistry;
import lol.pyr.znpcsplus.interaction.ActionRegistry; import lol.pyr.znpcsplus.interaction.ActionRegistry;
import lol.pyr.znpcsplus.npc.NpcTypeRegistry; import lol.pyr.znpcsplus.npc.NpcTypeRegistry;
import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.packets.PacketFactory;
@ -12,10 +13,10 @@ import java.io.File;
public enum NpcStorageType { public enum NpcStorageType {
YAML { YAML {
@Override @Override
public NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, NpcTypeRegistry typeRegistry) { public NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, NpcTypeRegistry typeRegistry, EntityPropertyRegistry propertyRegistry) {
return new YamlStorage(packetFactory, configManager, actionRegistry, typeRegistry, new File(plugin.getDataFolder(), "data")); return new YamlStorage(packetFactory, configManager, actionRegistry, typeRegistry, propertyRegistry, new File(plugin.getDataFolder(), "data"));
} }
}; };
public abstract NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, NpcTypeRegistry typeRegistry); public abstract NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, NpcTypeRegistry typeRegistry, EntityPropertyRegistry propertyRegistry);
} }

@ -2,6 +2,7 @@ package lol.pyr.znpcsplus.storage.yaml;
import lol.pyr.znpcsplus.config.ConfigManager; import lol.pyr.znpcsplus.config.ConfigManager;
import lol.pyr.znpcsplus.entity.EntityPropertyImpl; import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
import lol.pyr.znpcsplus.entity.EntityPropertyRegistry;
import lol.pyr.znpcsplus.hologram.HologramLine; import lol.pyr.znpcsplus.hologram.HologramLine;
import lol.pyr.znpcsplus.interaction.ActionRegistry; import lol.pyr.znpcsplus.interaction.ActionRegistry;
import lol.pyr.znpcsplus.npc.NpcEntryImpl; import lol.pyr.znpcsplus.npc.NpcEntryImpl;
@ -24,13 +25,15 @@ public class YamlStorage implements NpcStorage {
private final ConfigManager configManager; private final ConfigManager configManager;
private final ActionRegistry actionRegistry; private final ActionRegistry actionRegistry;
private final NpcTypeRegistry typeRegistry; private final NpcTypeRegistry typeRegistry;
private final EntityPropertyRegistry propertyRegistry;
private final File folder; private final File folder;
public YamlStorage(PacketFactory packetFactory, ConfigManager configManager, ActionRegistry actionRegistry, NpcTypeRegistry typeRegistry, File folder) { public YamlStorage(PacketFactory packetFactory, ConfigManager configManager, ActionRegistry actionRegistry, NpcTypeRegistry typeRegistry, EntityPropertyRegistry propertyRegistry, File folder) {
this.packetFactory = packetFactory; this.packetFactory = packetFactory;
this.configManager = configManager; this.configManager = configManager;
this.actionRegistry = actionRegistry; this.actionRegistry = actionRegistry;
this.typeRegistry = typeRegistry; this.typeRegistry = typeRegistry;
this.propertyRegistry = propertyRegistry;
this.folder = folder; this.folder = folder;
if (!this.folder.exists()) this.folder.mkdirs(); if (!this.folder.exists()) this.folder.mkdirs();
} }
@ -49,7 +52,7 @@ public class YamlStorage implements NpcStorage {
ConfigurationSection properties = config.getConfigurationSection("properties"); ConfigurationSection properties = config.getConfigurationSection("properties");
if (properties != null) { if (properties != null) {
for (String key : properties.getKeys(false)) { for (String key : properties.getKeys(false)) {
EntityPropertyImpl<?> property = EntityPropertyImpl.getByName(key); EntityPropertyImpl<?> property = propertyRegistry.getByName(key);
npc.UNSAFE_setProperty(property, property.deserialize(properties.getString(key))); npc.UNSAFE_setProperty(property, property.deserialize(properties.getString(key)));
} }
} }