upstream #1

Closed
bridge wants to merge 65 commits from feat/upstream into 2.X
12 changed files with 289 additions and 121 deletions
Showing only changes of commit c780c0ec78 - Show all commits

View file

@ -5,6 +5,7 @@ import lol.pyr.znpcsplus.api.interaction.ActionFactory;
import lol.pyr.znpcsplus.api.interaction.ActionRegistry; import lol.pyr.znpcsplus.api.interaction.ActionRegistry;
import lol.pyr.znpcsplus.api.npc.NpcRegistry; import lol.pyr.znpcsplus.api.npc.NpcRegistry;
import lol.pyr.znpcsplus.api.npc.NpcTypeRegistry; import lol.pyr.znpcsplus.api.npc.NpcTypeRegistry;
import lol.pyr.znpcsplus.api.serialization.NpcSerializerRegistry;
import lol.pyr.znpcsplus.api.skin.SkinDescriptorFactory; import lol.pyr.znpcsplus.api.skin.SkinDescriptorFactory;
/** /**
@ -46,4 +47,10 @@ public interface NpcApi {
* @return the skin descriptor factory * @return the skin descriptor factory
*/ */
SkinDescriptorFactory getSkinDescriptorFactory(); SkinDescriptorFactory getSkinDescriptorFactory();
/**
* Gets the npc serializer registry.
* @return the npc serializer registry
*/
NpcSerializerRegistry getNpcSerializerRegistry();
} }

View file

@ -64,4 +64,11 @@ public interface NpcRegistry {
* @param id The ID of the NPC entry * @param id The ID of the NPC entry
*/ */
void delete(String id); void delete(String id);
/**
* Register an NPC to this registry
* NpcEntry instances can be obtained through the NpcSerializer classes
* @param entry The npc to be registered
*/
void register(NpcEntry entry);
} }

View file

@ -0,0 +1,20 @@
package lol.pyr.znpcsplus.api.serialization;
import lol.pyr.znpcsplus.api.npc.NpcEntry;
public interface NpcSerializer<T> {
/**
* Serialize an npc into the type of this serializer
* @param entry The npc entry
* @return The serialized class
*/
T serialize(NpcEntry entry);
/**
* Deserialize an npc from a serialized class
* Note: This npc will not be registered, you need to also register it using the NpcRegistry#register(NpcEntry) method
* @param model The serialized class
* @return The deserialized NpcEntry
*/
NpcEntry deserialize(T model);
}

View file

@ -0,0 +1,19 @@
package lol.pyr.znpcsplus.api.serialization;
public interface NpcSerializerRegistry {
/**
* Get an NpcSerializer that serializes npcs into the provided class
* @param clazz The class to serialize into
* @return The npc serializer instance
* @param <T> The type of the class that the serializer serializes into
*/
<T> NpcSerializer<T> getSerializer(Class<T> clazz);
/**
* Register an NpcSerializer to be used by other plugins
* @param clazz The class that the serializer serializes into
* @param serializer The serializer itself
* @param <T> The type of the class that the serializer serializes into
*/
<T> void registerSerializer(Class<T> clazz, NpcSerializer<T> serializer);
}

View file

@ -38,6 +38,7 @@ import lol.pyr.znpcsplus.parsers.*;
import lol.pyr.znpcsplus.scheduling.FoliaScheduler; import lol.pyr.znpcsplus.scheduling.FoliaScheduler;
import lol.pyr.znpcsplus.scheduling.SpigotScheduler; import lol.pyr.znpcsplus.scheduling.SpigotScheduler;
import lol.pyr.znpcsplus.scheduling.TaskScheduler; import lol.pyr.znpcsplus.scheduling.TaskScheduler;
import lol.pyr.znpcsplus.serialization.NpcSerializerRegistryImpl;
import lol.pyr.znpcsplus.skin.cache.MojangSkinCache; import lol.pyr.znpcsplus.skin.cache.MojangSkinCache;
import lol.pyr.znpcsplus.skin.cache.SkinCacheCleanTask; import lol.pyr.znpcsplus.skin.cache.SkinCacheCleanTask;
import lol.pyr.znpcsplus.storage.NpcStorageType; import lol.pyr.znpcsplus.storage.NpcStorageType;
@ -135,8 +136,9 @@ public class ZNpcsPlus {
ActionRegistryImpl actionRegistry = new ActionRegistryImpl(); ActionRegistryImpl actionRegistry = new ActionRegistryImpl();
ActionFactoryImpl actionFactory = new ActionFactoryImpl(scheduler, adventure, textSerializer, bungeeConnector); ActionFactoryImpl actionFactory = new ActionFactoryImpl(scheduler, adventure, textSerializer, bungeeConnector);
NpcTypeRegistryImpl typeRegistry = new NpcTypeRegistryImpl(); NpcTypeRegistryImpl typeRegistry = new NpcTypeRegistryImpl();
NpcSerializerRegistryImpl serializerRegistry = new NpcSerializerRegistryImpl(packetFactory, configManager, actionRegistry, typeRegistry, propertyRegistry, textSerializer);
NpcRegistryImpl npcRegistry = new NpcRegistryImpl(configManager, this, packetFactory, actionRegistry, NpcRegistryImpl npcRegistry = new NpcRegistryImpl(configManager, this, packetFactory, actionRegistry,
scheduler, typeRegistry, propertyRegistry, textSerializer); scheduler, typeRegistry, propertyRegistry, serializerRegistry, textSerializer);
shutdownTasks.add(npcRegistry::unload); shutdownTasks.add(npcRegistry::unload);
UserManager userManager = new UserManager(); UserManager userManager = new UserManager();
@ -159,7 +161,7 @@ public class ZNpcsPlus {
pluginManager.registerEvents(new UserListener(userManager), bootstrap); pluginManager.registerEvents(new UserListener(userManager), bootstrap);
registerCommands(npcRegistry, skinCache, adventure, actionRegistry, registerCommands(npcRegistry, skinCache, adventure, actionRegistry,
typeRegistry, propertyRegistry, importerRegistry, configManager, packetFactory); typeRegistry, propertyRegistry, importerRegistry, configManager, packetFactory, serializerRegistry);
log(ChatColor.WHITE + " * Starting tasks..."); log(ChatColor.WHITE + " * Starting tasks...");
if (configManager.getConfig().checkForUpdates()) { if (configManager.getConfig().checkForUpdates()) {
@ -193,7 +195,7 @@ public class ZNpcsPlus {
} }
} }
NpcApiProvider.register(bootstrap, new ZNpcsPlusApi(npcRegistry, typeRegistry, propertyRegistry, actionRegistry, actionFactory, skinCache)); NpcApiProvider.register(bootstrap, new ZNpcsPlusApi(npcRegistry, typeRegistry, propertyRegistry, actionRegistry, actionFactory, skinCache, serializerRegistry));
log(ChatColor.WHITE + " * Loading complete! (" + (System.currentTimeMillis() - before) + "ms)"); log(ChatColor.WHITE + " * Loading complete! (" + (System.currentTimeMillis() - before) + "ms)");
log(""); log("");
@ -246,7 +248,7 @@ public class ZNpcsPlus {
private void registerCommands(NpcRegistryImpl npcRegistry, MojangSkinCache skinCache, BukkitAudiences adventure, private void registerCommands(NpcRegistryImpl npcRegistry, MojangSkinCache skinCache, BukkitAudiences adventure,
ActionRegistryImpl actionRegistry, NpcTypeRegistryImpl typeRegistry, ActionRegistryImpl actionRegistry, NpcTypeRegistryImpl typeRegistry,
EntityPropertyRegistryImpl propertyRegistry, DataImporterRegistry importerRegistry, EntityPropertyRegistryImpl propertyRegistry, DataImporterRegistry importerRegistry,
ConfigManager configManager, PacketFactory packetFactory) { ConfigManager configManager, PacketFactory packetFactory, NpcSerializerRegistryImpl serializerRegistry) {
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(bootstrap, adventure, incorrectUsageMessage); CommandManager manager = new CommandManager(bootstrap, adventure, incorrectUsageMessage);
@ -322,7 +324,7 @@ public class ZNpcsPlus {
.addSubcommand("save", new SaveAllCommand(npcRegistry)) .addSubcommand("save", new SaveAllCommand(npcRegistry))
.addSubcommand("reload", new LoadAllCommand(npcRegistry)) .addSubcommand("reload", new LoadAllCommand(npcRegistry))
.addSubcommand("import", new ImportCommand(npcRegistry, importerRegistry)) .addSubcommand("import", new ImportCommand(npcRegistry, importerRegistry))
.addSubcommand("migrate", new MigrateCommand(configManager, this, packetFactory, actionRegistry, typeRegistry, propertyRegistry, textSerializer, npcRegistry.getStorage(), configManager.getConfig().storageType(), npcRegistry))) .addSubcommand("migrate", new MigrateCommand(configManager, this, packetFactory, actionRegistry, typeRegistry, propertyRegistry, textSerializer, npcRegistry.getStorage(), configManager.getConfig().storageType(), npcRegistry, serializerRegistry)))
.addSubcommand("holo", new MultiCommand(bootstrap.loadHelpMessage("holo")) .addSubcommand("holo", new MultiCommand(bootstrap.loadHelpMessage("holo"))
.addSubcommand("add", new HoloAddCommand(npcRegistry)) .addSubcommand("add", new HoloAddCommand(npcRegistry))
.addSubcommand("additem", new HoloAddItemCommand(npcRegistry)) .addSubcommand("additem", new HoloAddItemCommand(npcRegistry))

View file

@ -12,6 +12,7 @@ import lol.pyr.znpcsplus.interaction.ActionFactoryImpl;
import lol.pyr.znpcsplus.interaction.ActionRegistryImpl; import lol.pyr.znpcsplus.interaction.ActionRegistryImpl;
import lol.pyr.znpcsplus.npc.NpcRegistryImpl; import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl; import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl;
import lol.pyr.znpcsplus.serialization.NpcSerializerRegistryImpl;
import lol.pyr.znpcsplus.skin.SkinDescriptorFactoryImpl; import lol.pyr.znpcsplus.skin.SkinDescriptorFactoryImpl;
import lol.pyr.znpcsplus.skin.cache.MojangSkinCache; import lol.pyr.znpcsplus.skin.cache.MojangSkinCache;
@ -22,14 +23,16 @@ public class ZNpcsPlusApi implements NpcApi {
private final ActionRegistryImpl actionRegistry; private final ActionRegistryImpl actionRegistry;
private final ActionFactoryImpl actionFactory; private final ActionFactoryImpl actionFactory;
private final SkinDescriptorFactoryImpl skinDescriptorFactory; private final SkinDescriptorFactoryImpl skinDescriptorFactory;
private final NpcSerializerRegistryImpl npcSerializerRegistry;
public ZNpcsPlusApi(NpcRegistryImpl npcRegistry, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, ActionRegistryImpl actionRegistry, ActionFactoryImpl actionFactory, MojangSkinCache skinCache) { public ZNpcsPlusApi(NpcRegistryImpl npcRegistry, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, ActionRegistryImpl actionRegistry, ActionFactoryImpl actionFactory, MojangSkinCache skinCache, NpcSerializerRegistryImpl npcSerializerRegistry) {
this.npcRegistry = npcRegistry; this.npcRegistry = npcRegistry;
this.typeRegistry = typeRegistry; this.typeRegistry = typeRegistry;
this.propertyRegistry = propertyRegistry; this.propertyRegistry = propertyRegistry;
this.actionRegistry = actionRegistry; this.actionRegistry = actionRegistry;
this.actionFactory = actionFactory; this.actionFactory = actionFactory;
this.skinDescriptorFactory = new SkinDescriptorFactoryImpl(skinCache); this.skinDescriptorFactory = new SkinDescriptorFactoryImpl(skinCache);
this.npcSerializerRegistry = npcSerializerRegistry;
} }
@Override @Override
@ -62,4 +65,9 @@ public class ZNpcsPlusApi implements NpcApi {
public SkinDescriptorFactory getSkinDescriptorFactory() { public SkinDescriptorFactory getSkinDescriptorFactory() {
return skinDescriptorFactory; return skinDescriptorFactory;
} }
@Override
public NpcSerializerRegistryImpl getNpcSerializerRegistry() {
return npcSerializerRegistry;
}
} }

View file

@ -11,6 +11,7 @@ import lol.pyr.znpcsplus.npc.NpcEntryImpl;
import lol.pyr.znpcsplus.npc.NpcRegistryImpl; import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl; import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl;
import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.packets.PacketFactory;
import lol.pyr.znpcsplus.serialization.NpcSerializerRegistryImpl;
import lol.pyr.znpcsplus.storage.NpcStorage; import lol.pyr.znpcsplus.storage.NpcStorage;
import lol.pyr.znpcsplus.storage.NpcStorageType; import lol.pyr.znpcsplus.storage.NpcStorageType;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -35,8 +36,9 @@ public class MigrateCommand implements CommandHandler {
private final NpcStorage currentStorage; private final NpcStorage currentStorage;
private final NpcStorageType currentStorageType; private final NpcStorageType currentStorageType;
private final NpcRegistryImpl npcRegistry; private final NpcRegistryImpl npcRegistry;
private final NpcSerializerRegistryImpl serializerRegistry;
public MigrateCommand(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistryImpl actionRegistry, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer, NpcStorage currentStorage, NpcStorageType currentStorageType, NpcRegistryImpl npcRegistry) { public MigrateCommand(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistryImpl actionRegistry, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer, NpcStorage currentStorage, NpcStorageType currentStorageType, NpcRegistryImpl npcRegistry, NpcSerializerRegistryImpl serializerRegistry) {
this.configManager = configManager; this.configManager = configManager;
this.plugin = plugin; this.plugin = plugin;
this.packetFactory = packetFactory; this.packetFactory = packetFactory;
@ -47,6 +49,7 @@ public class MigrateCommand implements CommandHandler {
this.currentStorage = currentStorage; this.currentStorage = currentStorage;
this.currentStorageType = currentStorageType; this.currentStorageType = currentStorageType;
this.npcRegistry = npcRegistry; this.npcRegistry = npcRegistry;
this.serializerRegistry = serializerRegistry;
} }
@Override @Override
@ -63,7 +66,7 @@ public class MigrateCommand implements CommandHandler {
if (currentStorageType == from) { if (currentStorageType == from) {
fromStorage = currentStorage; fromStorage = currentStorage;
} else { } else {
fromStorage = from.create(configManager, plugin, packetFactory, actionRegistry, typeRegistry, propertyRegistry, textSerializer); fromStorage = from.create(configManager, plugin, packetFactory, actionRegistry, typeRegistry, propertyRegistry, textSerializer, serializerRegistry);
if (fromStorage == null) { if (fromStorage == null) {
context.halt(Component.text("Failed to initialize the source storage. Please check the console for more information.", NamedTextColor.RED)); context.halt(Component.text("Failed to initialize the source storage. Please check the console for more information.", NamedTextColor.RED));
return; return;
@ -84,7 +87,7 @@ public class MigrateCommand implements CommandHandler {
if (currentStorageType == to) { if (currentStorageType == to) {
toStorage = currentStorage; toStorage = currentStorage;
} else { } else {
toStorage = to.create(configManager, plugin, packetFactory, actionRegistry, typeRegistry, propertyRegistry, textSerializer); toStorage = to.create(configManager, plugin, packetFactory, actionRegistry, typeRegistry, propertyRegistry, textSerializer, serializerRegistry);
if (toStorage == null) { if (toStorage == null) {
context.halt(Component.text("Failed to initialize the destination storage. Please check the console for more information.", NamedTextColor.RED)); context.halt(Component.text("Failed to initialize the destination storage. Please check the console for more information.", NamedTextColor.RED));
return; return;

View file

@ -14,6 +14,7 @@ import lol.pyr.znpcsplus.hologram.HologramText;
import lol.pyr.znpcsplus.interaction.ActionRegistryImpl; import lol.pyr.znpcsplus.interaction.ActionRegistryImpl;
import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.packets.PacketFactory;
import lol.pyr.znpcsplus.scheduling.TaskScheduler; import lol.pyr.znpcsplus.scheduling.TaskScheduler;
import lol.pyr.znpcsplus.serialization.NpcSerializerRegistryImpl;
import lol.pyr.znpcsplus.storage.NpcStorage; import lol.pyr.znpcsplus.storage.NpcStorage;
import lol.pyr.znpcsplus.storage.NpcStorageType; import lol.pyr.znpcsplus.storage.NpcStorageType;
import lol.pyr.znpcsplus.util.NpcLocation; import lol.pyr.znpcsplus.util.NpcLocation;
@ -35,13 +36,13 @@ public class NpcRegistryImpl implements NpcRegistry {
private final Map<String, NpcEntryImpl> npcIdLookupMap = new HashMap<>(); private final Map<String, NpcEntryImpl> npcIdLookupMap = new HashMap<>();
private final Map<UUID, NpcEntryImpl> npcUuidLookupMap = new HashMap<>(); private final Map<UUID, NpcEntryImpl> npcUuidLookupMap = new HashMap<>();
public NpcRegistryImpl(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistryImpl actionRegistry, TaskScheduler scheduler, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer) { public NpcRegistryImpl(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistryImpl actionRegistry, TaskScheduler scheduler, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, NpcSerializerRegistryImpl serializerRegistry, LegacyComponentSerializer textSerializer) {
this.textSerializer = textSerializer; this.textSerializer = textSerializer;
this.propertyRegistry = propertyRegistry; this.propertyRegistry = propertyRegistry;
storage = configManager.getConfig().storageType().create(configManager, plugin, packetFactory, actionRegistry, typeRegistry, propertyRegistry, textSerializer); storage = configManager.getConfig().storageType().create(configManager, plugin, packetFactory, actionRegistry, typeRegistry, propertyRegistry, textSerializer, serializerRegistry);
if (storage == null) { if (storage == null) {
Bukkit.getLogger().warning("Failed to initialize storage, falling back to YAML"); Bukkit.getLogger().warning("Failed to initialize storage, falling back to YAML");
storage = NpcStorageType.YAML.create(configManager, plugin, packetFactory, actionRegistry, typeRegistry, propertyRegistry, textSerializer); storage = NpcStorageType.YAML.create(configManager, plugin, packetFactory, actionRegistry, typeRegistry, propertyRegistry, textSerializer, serializerRegistry);
} }
this.packetFactory = packetFactory; this.packetFactory = packetFactory;
this.configManager = configManager; this.configManager = configManager;
@ -52,7 +53,13 @@ public class NpcRegistryImpl implements NpcRegistry {
} }
} }
@Override
public void register(NpcEntry entry) {
register((NpcEntryImpl) entry);
}
private void register(NpcEntryImpl entry) { private void register(NpcEntryImpl entry) {
if (entry == null) throw new NullPointerException();
unregister(npcIdLookupMap.put(entry.getId(), entry)); unregister(npcIdLookupMap.put(entry.getId(), entry));
unregister(npcUuidLookupMap.put(entry.getNpc().getUuid(), entry)); unregister(npcUuidLookupMap.put(entry.getNpc().getUuid(), entry));
npcList.add(entry); npcList.add(entry);

View file

@ -0,0 +1,33 @@
package lol.pyr.znpcsplus.serialization;
import lol.pyr.znpcsplus.api.serialization.NpcSerializer;
import lol.pyr.znpcsplus.api.serialization.NpcSerializerRegistry;
import lol.pyr.znpcsplus.config.ConfigManager;
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
import lol.pyr.znpcsplus.interaction.ActionRegistryImpl;
import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl;
import lol.pyr.znpcsplus.packets.PacketFactory;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.configuration.file.YamlConfiguration;
import java.util.HashMap;
import java.util.Map;
public class NpcSerializerRegistryImpl implements NpcSerializerRegistry {
private final Map<Class<?>, NpcSerializer<?>> serializerMap = new HashMap<>();
public NpcSerializerRegistryImpl(PacketFactory packetFactory, ConfigManager configManager, ActionRegistryImpl actionRegistry, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer) {
registerSerializer(YamlConfiguration.class, new YamlSerializer(packetFactory, configManager, actionRegistry, typeRegistry, propertyRegistry, textSerializer));
}
@SuppressWarnings("unchecked")
@Override
public <T> NpcSerializer<T> getSerializer(Class<T> clazz) {
return (NpcSerializer<T>) serializerMap.get(clazz);
}
@Override
public <T> void registerSerializer(Class<T> clazz, NpcSerializer<T> serializer) {
serializerMap.put(clazz, serializer);
}
}

View file

@ -0,0 +1,154 @@
package lol.pyr.znpcsplus.serialization;
import lol.pyr.znpcsplus.api.entity.EntityProperty;
import lol.pyr.znpcsplus.api.npc.NpcEntry;
import lol.pyr.znpcsplus.api.serialization.NpcSerializer;
import lol.pyr.znpcsplus.config.ConfigManager;
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
import lol.pyr.znpcsplus.entity.PropertySerializer;
import lol.pyr.znpcsplus.hologram.HologramImpl;
import lol.pyr.znpcsplus.interaction.ActionRegistryImpl;
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
import lol.pyr.znpcsplus.npc.NpcImpl;
import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl;
import lol.pyr.znpcsplus.packets.PacketFactory;
import lol.pyr.znpcsplus.util.NpcLocation;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
public class YamlSerializer implements NpcSerializer<YamlConfiguration> {
private final static Logger logger = Logger.getLogger("YamlSerializer");
private final PacketFactory packetFactory;
private final ConfigManager configManager;
private final ActionRegistryImpl actionRegistry;
private final NpcTypeRegistryImpl typeRegistry;
private final EntityPropertyRegistryImpl propertyRegistry;
private final LegacyComponentSerializer textSerializer;
public YamlSerializer(PacketFactory packetFactory, ConfigManager configManager, ActionRegistryImpl actionRegistry, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer) {
this.packetFactory = packetFactory;
this.configManager = configManager;
this.actionRegistry = actionRegistry;
this.typeRegistry = typeRegistry;
this.propertyRegistry = propertyRegistry;
this.textSerializer = textSerializer;
}
@Override
public YamlConfiguration serialize(NpcEntry entry) {
YamlConfiguration config = new YamlConfiguration();
config.set("id", entry.getId());
config.set("is-processed", entry.isProcessed());
config.set("allow-commands", entry.isAllowCommandModification());
config.set("save", entry.isSave());
NpcImpl npc = (NpcImpl) entry.getNpc();
config.set("enabled", npc.isEnabled());
config.set("uuid", npc.getUuid().toString());
config.set("world", npc.getWorldName());
config.set("location", serializeLocation(npc.getLocation()));
config.set("type", npc.getType().getName());
for (EntityProperty<?> property : npc.getAllProperties()) try {
PropertySerializer<?> serializer = propertyRegistry.getSerializer(((EntityPropertyImpl<?>) property).getType());
if (serializer == null) {
Bukkit.getLogger().log(Level.WARNING, "Unknown serializer for property '" + property.getName() + "' for npc '" + entry.getId() + "'. skipping ...");
continue;
}
config.set("properties." + property.getName(), serializer.UNSAFE_serialize(npc.getProperty(property)));
} catch (Exception exception) {
logger.severe("Failed to serialize property " + property.getName() + " for npc with id " + entry.getId());
exception.printStackTrace();
}
HologramImpl hologram = npc.getHologram();
if (hologram.getOffset() != 0.0) config.set("hologram.offset", hologram.getOffset());
if (hologram.getRefreshDelay() != -1) config.set("hologram.refresh-delay", hologram.getRefreshDelay());
List<String> lines = new ArrayList<>(npc.getHologram().getLines().size());
for (int i = 0; i < hologram.getLines().size(); i++) {
lines.add(hologram.getLine(i));
}
config.set("hologram.lines", lines);
config.set("actions", npc.getActions().stream()
.map(actionRegistry::serialize)
.filter(Objects::nonNull)
.collect(Collectors.toList()));
return config;
}
@Override
public NpcEntry deserialize(YamlConfiguration config) {
UUID uuid = config.contains("uuid") ? UUID.fromString(config.getString("uuid")) : UUID.randomUUID();
NpcImpl npc = new NpcImpl(uuid, propertyRegistry, configManager, packetFactory, textSerializer, config.getString("world"),
typeRegistry.getByName(config.getString("type")), deserializeLocation(config.getConfigurationSection("location")));
if (config.isBoolean("enabled")) npc.setEnabled(config.getBoolean("enabled"));
ConfigurationSection properties = config.getConfigurationSection("properties");
if (properties != null) {
for (String key : properties.getKeys(false)) {
EntityPropertyImpl<?> property = propertyRegistry.getByName(key);
if (property == null) {
Bukkit.getLogger().log(Level.WARNING, "Unknown property '" + key + "' for npc '" + config.getString("id") + "'. skipping ...");
continue;
}
PropertySerializer<?> serializer = propertyRegistry.getSerializer(property.getType());
if (serializer == null) {
Bukkit.getLogger().log(Level.WARNING, "Unknown serializer for property '" + key + "' for npc '" + config.getString("id") + "'. skipping ...");
continue;
}
Object value = serializer.deserialize(properties.getString(key));
if (value == null) {
Bukkit.getLogger().log(Level.WARNING, "Failed to deserialize property '" + key + "' for npc '" + config.getString("id") + "'. Resetting to default ...");
value = property.getDefaultValue();
}
npc.UNSAFE_setProperty(property, value);
}
}
HologramImpl hologram = npc.getHologram();
hologram.setOffset(config.getDouble("hologram.offset", 0.0));
hologram.setRefreshDelay(config.getLong("hologram.refresh-delay", -1));
for (String line : config.getStringList("hologram.lines")) hologram.addLine(line);
for (String s : config.getStringList("actions")) npc.addAction(actionRegistry.deserialize(s));
NpcEntryImpl entry = new NpcEntryImpl(config.getString("id"), npc);
entry.setProcessed(config.getBoolean("is-processed"));
entry.setAllowCommandModification(config.getBoolean("allow-commands"));
entry.setSave(config.getBoolean("save"));
return entry;
}
public NpcLocation deserializeLocation(ConfigurationSection section) {
return new NpcLocation(
section.getDouble("x"),
section.getDouble("y"),
section.getDouble("z"),
(float) section.getDouble("yaw"),
(float) section.getDouble("pitch")
);
}
public YamlConfiguration serializeLocation(NpcLocation location) {
YamlConfiguration config = new YamlConfiguration();
config.set("x", location.getX());
config.set("y", location.getY());
config.set("z", location.getZ());
config.set("yaw", location.getYaw());
config.set("pitch", location.getPitch());
return config;
}
}

View file

@ -6,6 +6,7 @@ import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
import lol.pyr.znpcsplus.interaction.ActionRegistryImpl; import lol.pyr.znpcsplus.interaction.ActionRegistryImpl;
import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl; import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl;
import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.packets.PacketFactory;
import lol.pyr.znpcsplus.serialization.NpcSerializerRegistryImpl;
import lol.pyr.znpcsplus.storage.mysql.MySQLStorage; import lol.pyr.znpcsplus.storage.mysql.MySQLStorage;
import lol.pyr.znpcsplus.storage.sqlite.SQLiteStorage; import lol.pyr.znpcsplus.storage.sqlite.SQLiteStorage;
import lol.pyr.znpcsplus.storage.yaml.YamlStorage; import lol.pyr.znpcsplus.storage.yaml.YamlStorage;
@ -16,13 +17,13 @@ import java.io.File;
public enum NpcStorageType { public enum NpcStorageType {
YAML { YAML {
@Override @Override
public NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistryImpl actionRegistry, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer) { public NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistryImpl actionRegistry, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer, NpcSerializerRegistryImpl serializerRegistry) {
return new YamlStorage(packetFactory, configManager, actionRegistry, typeRegistry, propertyRegistry, textSerializer, new File(plugin.getDataFolder(), "data")); return new YamlStorage(serializerRegistry, new File(plugin.getDataFolder(), "data"));
} }
}, },
SQLITE { SQLITE {
@Override @Override
public NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistryImpl actionRegistry, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer) { public NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistryImpl actionRegistry, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer, NpcSerializerRegistryImpl serializerRegistry) {
try { try {
return new SQLiteStorage(packetFactory, configManager, actionRegistry, typeRegistry, propertyRegistry, textSerializer, new File(plugin.getDataFolder(), "znpcsplus.sqlite")); return new SQLiteStorage(packetFactory, configManager, actionRegistry, typeRegistry, propertyRegistry, textSerializer, new File(plugin.getDataFolder(), "znpcsplus.sqlite"));
} catch (Exception e) { } catch (Exception e) {
@ -33,7 +34,7 @@ public enum NpcStorageType {
}, },
MYSQL { MYSQL {
@Override @Override
public NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistryImpl actionRegistry, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer) { public NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistryImpl actionRegistry, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer, NpcSerializerRegistryImpl serializerRegistry) {
try { try {
return new MySQLStorage(packetFactory, configManager, actionRegistry, typeRegistry, propertyRegistry, textSerializer); return new MySQLStorage(packetFactory, configManager, actionRegistry, typeRegistry, propertyRegistry, textSerializer);
} catch (Exception e) { } catch (Exception e) {
@ -43,5 +44,5 @@ public enum NpcStorageType {
} }
}; };
public abstract NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistryImpl actionRegistry, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer); public abstract NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistryImpl actionRegistry, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer, NpcSerializerRegistryImpl serializerRegistry);
} }

View file

@ -1,47 +1,28 @@
package lol.pyr.znpcsplus.storage.yaml; package lol.pyr.znpcsplus.storage.yaml;
import lol.pyr.znpcsplus.api.entity.EntityProperty; import lol.pyr.znpcsplus.api.serialization.NpcSerializer;
import lol.pyr.znpcsplus.config.ConfigManager;
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
import lol.pyr.znpcsplus.entity.PropertySerializer;
import lol.pyr.znpcsplus.hologram.HologramImpl;
import lol.pyr.znpcsplus.interaction.ActionRegistryImpl;
import lol.pyr.znpcsplus.npc.NpcEntryImpl; import lol.pyr.znpcsplus.npc.NpcEntryImpl;
import lol.pyr.znpcsplus.npc.NpcImpl; import lol.pyr.znpcsplus.serialization.NpcSerializerRegistryImpl;
import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl;
import lol.pyr.znpcsplus.packets.PacketFactory;
import lol.pyr.znpcsplus.storage.NpcStorage; import lol.pyr.znpcsplus.storage.NpcStorage;
import lol.pyr.znpcsplus.util.NpcLocation; import lol.pyr.znpcsplus.util.NpcLocation;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File; import java.io.File;
import java.util.*; import java.util.ArrayList;
import java.util.logging.Level; import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.stream.Collectors;
public class YamlStorage implements NpcStorage { public class YamlStorage implements NpcStorage {
private final static Logger logger = Logger.getLogger("YamlStorage"); private final static Logger logger = Logger.getLogger("YamlStorage");
private final PacketFactory packetFactory;
private final ConfigManager configManager;
private final ActionRegistryImpl actionRegistry;
private final NpcTypeRegistryImpl typeRegistry;
private final EntityPropertyRegistryImpl propertyRegistry;
private final LegacyComponentSerializer textSerializer;
private final File folder; private final File folder;
private final NpcSerializer<YamlConfiguration> yamlSerializer;
public YamlStorage(PacketFactory packetFactory, ConfigManager configManager, ActionRegistryImpl actionRegistry, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer, File folder) { public YamlStorage(NpcSerializerRegistryImpl serializerRegistry, File folder) {
this.packetFactory = packetFactory; this.yamlSerializer = serializerRegistry.getSerializer(YamlConfiguration.class);
this.configManager = configManager;
this.actionRegistry = actionRegistry;
this.typeRegistry = typeRegistry;
this.propertyRegistry = propertyRegistry;
this.textSerializer = textSerializer;
this.folder = folder; this.folder = folder;
if (!this.folder.exists()) this.folder.mkdirs(); if (!this.folder.exists()) this.folder.mkdirs();
} }
@ -53,45 +34,7 @@ public class YamlStorage implements NpcStorage {
List<NpcEntryImpl> npcs = new ArrayList<>(files.length); List<NpcEntryImpl> npcs = new ArrayList<>(files.length);
for (File file : files) if (file.isFile() && file.getName().toLowerCase().endsWith(".yml")) try { for (File file : files) if (file.isFile() && file.getName().toLowerCase().endsWith(".yml")) try {
YamlConfiguration config = YamlConfiguration.loadConfiguration(file); YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
UUID uuid = config.contains("uuid") ? UUID.fromString(config.getString("uuid")) : UUID.randomUUID(); npcs.add((NpcEntryImpl) yamlSerializer.deserialize(config));
NpcImpl npc = new NpcImpl(uuid, propertyRegistry, configManager, packetFactory, textSerializer, config.getString("world"),
typeRegistry.getByName(config.getString("type")), deserializeLocation(config.getConfigurationSection("location")));
if (config.isBoolean("enabled")) npc.setEnabled(config.getBoolean("enabled"));
ConfigurationSection properties = config.getConfigurationSection("properties");
if (properties != null) {
for (String key : properties.getKeys(false)) {
EntityPropertyImpl<?> property = propertyRegistry.getByName(key);
if (property == null) {
Bukkit.getLogger().log(Level.WARNING, "Unknown property '" + key + "' for npc '" + config.getString("id") + "'. skipping ...");
continue;
}
PropertySerializer<?> serializer = propertyRegistry.getSerializer(property.getType());
if (serializer == null) {
Bukkit.getLogger().log(Level.WARNING, "Unknown serializer for property '" + key + "' for npc '" + config.getString("id") + "'. skipping ...");
continue;
}
Object value = serializer.deserialize(properties.getString(key));
if (value == null) {
Bukkit.getLogger().log(Level.WARNING, "Failed to deserialize property '" + key + "' for npc '" + config.getString("id") + "'. Resetting to default ...");
value = property.getDefaultValue();
}
npc.UNSAFE_setProperty(property, value);
}
}
HologramImpl hologram = npc.getHologram();
hologram.setOffset(config.getDouble("hologram.offset", 0.0));
hologram.setRefreshDelay(config.getLong("hologram.refresh-delay", -1));
for (String line : config.getStringList("hologram.lines")) hologram.addLine(line);
for (String s : config.getStringList("actions")) npc.addAction(actionRegistry.deserialize(s));
NpcEntryImpl entry = new NpcEntryImpl(config.getString("id"), npc);
entry.setProcessed(config.getBoolean("is-processed"));
entry.setAllowCommandModification(config.getBoolean("allow-commands"));
entry.setSave(true);
npcs.add(entry);
} catch (Throwable t) { } catch (Throwable t) {
logger.severe("Failed to load npc file: " + file.getName()); logger.severe("Failed to load npc file: " + file.getName());
t.printStackTrace(); t.printStackTrace();
@ -102,43 +45,7 @@ public class YamlStorage implements NpcStorage {
@Override @Override
public void saveNpcs(Collection<NpcEntryImpl> npcs) { public void saveNpcs(Collection<NpcEntryImpl> npcs) {
for (NpcEntryImpl entry : npcs) try { for (NpcEntryImpl entry : npcs) try {
YamlConfiguration config = new YamlConfiguration(); YamlConfiguration config = yamlSerializer.serialize(entry);
config.set("id", entry.getId());
config.set("is-processed", entry.isProcessed());
config.set("allow-commands", entry.isAllowCommandModification());
NpcImpl npc = entry.getNpc();
config.set("enabled", npc.isEnabled());
config.set("uuid", npc.getUuid().toString());
config.set("world", npc.getWorldName());
config.set("location", serializeLocation(npc.getLocation()));
config.set("type", npc.getType().getName());
for (EntityProperty<?> property : npc.getAllProperties()) try {
PropertySerializer<?> serializer = propertyRegistry.getSerializer(((EntityPropertyImpl<?>) property).getType());
if (serializer == null) {
Bukkit.getLogger().log(Level.WARNING, "Unknown serializer for property '" + property.getName() + "' for npc '" + entry.getId() + "'. skipping ...");
continue;
}
config.set("properties." + property.getName(), serializer.UNSAFE_serialize(npc.getProperty(property)));
} catch (Exception exception) {
logger.severe("Failed to serialize property " + property.getName() + " for npc with id " + entry.getId());
exception.printStackTrace();
}
HologramImpl hologram = npc.getHologram();
if (hologram.getOffset() != 0.0) config.set("hologram.offset", hologram.getOffset());
if (hologram.getRefreshDelay() != -1) config.set("hologram.refresh-delay", hologram.getRefreshDelay());
List<String> lines = new ArrayList<>(npc.getHologram().getLines().size());
for (int i = 0; i < hologram.getLines().size(); i++) {
lines.add(hologram.getLine(i));
}
config.set("hologram.lines", lines);
config.set("actions", npc.getActions().stream()
.map(actionRegistry::serialize)
.filter(Objects::nonNull)
.collect(Collectors.toList()));
config.save(fileFor(entry)); config.save(fileFor(entry));
} catch (Exception exception) { } catch (Exception exception) {
logger.severe("Failed to save npc with id " + entry.getId()); logger.severe("Failed to save npc with id " + entry.getId());