From 8e6cbb61afd7140049fbcf1df004a1694ab0bd64 Mon Sep 17 00:00:00 2001 From: Pyrbu Date: Sun, 18 Jun 2023 19:33:47 +0200 Subject: [PATCH] Add import command & improve importing --- .../java/lol/pyr/znpcsplus/ZNpcsPlus.java | 17 ++++-- .../commands/storage/ImportCommand.java | 54 +++++++++++++++++++ .../conversion/DataImporterRegistry.java | 42 +++++++++++++++ .../conversion/DataImporterType.java | 19 ------- .../{ZNpcsLoader.java => ZNpcImporter.java} | 33 +++++++----- .../conversion/znpcs/model/ZNpcsModel.java | 6 +-- .../pyr/znpcsplus/npc/NpcRegistryImpl.java | 12 ++++- .../main/resources/help-messages/storage.txt | 1 + 8 files changed, 142 insertions(+), 42 deletions(-) create mode 100644 plugin/src/main/java/lol/pyr/znpcsplus/commands/storage/ImportCommand.java create mode 100644 plugin/src/main/java/lol/pyr/znpcsplus/conversion/DataImporterRegistry.java delete mode 100644 plugin/src/main/java/lol/pyr/znpcsplus/conversion/DataImporterType.java rename plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/{ZNpcsLoader.java => ZNpcImporter.java} (83%) diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java index 86b42e0..c3293c0 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/ZNpcsPlus.java @@ -20,9 +20,11 @@ import lol.pyr.znpcsplus.commands.action.ActionDeleteCommand; import lol.pyr.znpcsplus.commands.action.ActionEditCommand; import lol.pyr.znpcsplus.commands.action.ActionListCommand; import lol.pyr.znpcsplus.commands.hologram.*; +import lol.pyr.znpcsplus.commands.storage.ImportCommand; import lol.pyr.znpcsplus.commands.storage.LoadAllCommand; import lol.pyr.znpcsplus.commands.storage.SaveAllCommand; import lol.pyr.znpcsplus.config.ConfigManager; +import lol.pyr.znpcsplus.conversion.DataImporterRegistry; import lol.pyr.znpcsplus.entity.EntityPropertyImpl; import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl; import lol.pyr.znpcsplus.interaction.ActionRegistry; @@ -112,8 +114,11 @@ public class ZNpcsPlus extends JavaPlugin { BungeeConnector bungeeConnector = new BungeeConnector(this); ActionRegistry actionRegistry = new ActionRegistry(); NpcTypeRegistryImpl typeRegistry = new NpcTypeRegistryImpl(); - NpcRegistryImpl npcRegistry = new NpcRegistryImpl(configManager, this, packetFactory, actionRegistry, scheduler, typeRegistry, propertyRegistry, textSerializer); + NpcRegistryImpl npcRegistry = new NpcRegistryImpl(configManager, this, packetFactory, actionRegistry, + scheduler, typeRegistry, propertyRegistry, textSerializer); UserManager userManager = new UserManager(); + DataImporterRegistry importerRegistry = new DataImporterRegistry(configManager, adventure, bungeeConnector, + scheduler, packetFactory, textSerializer, typeRegistry, getDataFolder().getParentFile()); log(ChatColor.WHITE + " * Registerring components..."); typeRegistry.registerDefault(packetEvents, propertyRegistry); @@ -123,7 +128,7 @@ public class ZNpcsPlus extends JavaPlugin { pluginManager.registerEvents(new UserListener(userManager), this); getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); - registerCommands(npcRegistry, skinCache, adventure, actionRegistry, typeRegistry, propertyRegistry); + registerCommands(npcRegistry, skinCache, adventure, actionRegistry, typeRegistry, propertyRegistry, importerRegistry); log(ChatColor.WHITE + " * Starting tasks..."); if (configManager.getConfig().checkForUpdates()) { @@ -209,7 +214,10 @@ public class ZNpcsPlus extends JavaPlugin { } - private void registerCommands(NpcRegistryImpl npcRegistry, SkinCache skinCache, BukkitAudiences adventure, ActionRegistry actionRegistry, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry) { + private void registerCommands(NpcRegistryImpl npcRegistry, SkinCache skinCache, BukkitAudiences adventure, + ActionRegistry actionRegistry, NpcTypeRegistryImpl typeRegistry, + EntityPropertyRegistryImpl propertyRegistry, DataImporterRegistry importerRegistry) { + Message incorrectUsageMessage = context -> context.send(Component.text("Incorrect usage: /" + context.getUsage(), NamedTextColor.RED)); CommandManager manager = new CommandManager(this, adventure, incorrectUsageMessage); @@ -234,7 +242,8 @@ public class ZNpcsPlus extends JavaPlugin { .addSubcommand("type", new TypeCommand(npcRegistry, typeRegistry)) .addSubcommand("storage", new MultiCommand(loadHelpMessage("storage")) .addSubcommand("save", new SaveAllCommand(npcRegistry)) - .addSubcommand("reload", new LoadAllCommand(npcRegistry))) + .addSubcommand("reload", new LoadAllCommand(npcRegistry)) + .addSubcommand("import", new ImportCommand(npcRegistry, importerRegistry))) .addSubcommand("holo", new MultiCommand(loadHelpMessage("holo")) .addSubcommand("add", new HoloAddCommand(npcRegistry, textSerializer)) .addSubcommand("delete", new HoloDeleteCommand(npcRegistry)) diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/commands/storage/ImportCommand.java b/plugin/src/main/java/lol/pyr/znpcsplus/commands/storage/ImportCommand.java new file mode 100644 index 0000000..0a810e9 --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/commands/storage/ImportCommand.java @@ -0,0 +1,54 @@ +package lol.pyr.znpcsplus.commands.storage; + +import lol.pyr.director.adventure.command.CommandContext; +import lol.pyr.director.adventure.command.CommandHandler; +import lol.pyr.director.common.command.CommandExecutionException; +import lol.pyr.znpcsplus.conversion.DataImporter; +import lol.pyr.znpcsplus.conversion.DataImporterRegistry; +import lol.pyr.znpcsplus.npc.NpcRegistryImpl; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +public class ImportCommand implements CommandHandler { + private final NpcRegistryImpl npcRegistry; + private final DataImporterRegistry importerRegistry; + + public ImportCommand(NpcRegistryImpl npcRegistry, DataImporterRegistry importerRegistry) { + this.npcRegistry = npcRegistry; + this.importerRegistry = importerRegistry; + } + + @SuppressWarnings("ConstantConditions") + @Override + public void run(CommandContext context) throws CommandExecutionException { + context.setUsage(context.getLabel() + " storage import "); + String id = context.popString().toUpperCase(); + DataImporter importer = importerRegistry.getImporter(id); + if (importer == null) context.halt(Component.text("Importer not found! Possible importers: " + + String.join(", ", importerRegistry.getIds()), NamedTextColor.RED)); + + CompletableFuture.runAsync(() -> { + if (!importer.isValid()) { + context.send(Component.text("There is no data to import from this importer!", NamedTextColor.RED)); + return; + } + try { + npcRegistry.registerAll(importer.importData()); + context.send(Component.text("All NPCs from " + id + " have been loaded.", NamedTextColor.GREEN)); + } catch (Exception exception) { + context.send(Component.text("Importing failed! Please check the console for more details.", NamedTextColor.RED)); + exception.printStackTrace(); + } + }); + } + + @Override + public List suggest(CommandContext context) throws CommandExecutionException { + if (context.argSize() == 1) return context.suggestCollection(importerRegistry.getIds()); + return Collections.emptyList(); + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/DataImporterRegistry.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/DataImporterRegistry.java new file mode 100644 index 0000000..f8f083a --- /dev/null +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/DataImporterRegistry.java @@ -0,0 +1,42 @@ +package lol.pyr.znpcsplus.conversion; + +import lol.pyr.znpcsplus.config.ConfigManager; +import lol.pyr.znpcsplus.conversion.znpcs.ZNpcImporter; +import lol.pyr.znpcsplus.npc.NpcTypeRegistryImpl; +import lol.pyr.znpcsplus.packets.PacketFactory; +import lol.pyr.znpcsplus.scheduling.TaskScheduler; +import lol.pyr.znpcsplus.util.BungeeConnector; +import lol.pyr.znpcsplus.util.LazyLoader; +import net.kyori.adventure.platform.bukkit.BukkitAudiences; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; + +import java.io.File; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public class DataImporterRegistry { + private final Map> importers = new HashMap<>(); + + public DataImporterRegistry(ConfigManager configManager, BukkitAudiences adventure, BungeeConnector bungeeConnector, + TaskScheduler taskScheduler, PacketFactory packetFactory, LegacyComponentSerializer textSerializer, + NpcTypeRegistryImpl typeRegistry, File pluginsFolder) { + + register("znpcs", LazyLoader.of(() -> new ZNpcImporter(configManager, adventure, bungeeConnector, taskScheduler, + packetFactory, textSerializer, typeRegistry, new File(pluginsFolder, "ServersNPC/data.json")))); + } + + private void register(String id, LazyLoader loader) { + importers.put(id.toUpperCase(), loader); + } + + public DataImporter getImporter(String id) { + id = id.toUpperCase(); + return importers.containsKey(id) ? importers.get(id).get() : null; + } + + public Collection getIds() { + return Collections.unmodifiableSet(importers.keySet()); + } +} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/DataImporterType.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/DataImporterType.java deleted file mode 100644 index 6fb081e..0000000 --- a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/DataImporterType.java +++ /dev/null @@ -1,19 +0,0 @@ -package lol.pyr.znpcsplus.conversion; - -import lol.pyr.znpcsplus.util.LazyLoader; - -public enum DataImporterType { - ZNPCS(() -> null), // TODO - LEGACY_ZNPCS_PLUS(() -> null), // TODO - CITIZENS(() -> null); // TODO - - private final LazyLoader importerLoader; - - DataImporterType(LazyLoader.ObjectProvider provider) { - this.importerLoader = LazyLoader.of(provider); - } - - DataImporter getImporter() { - return importerLoader.get(); - } -} diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/ZNpcsLoader.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/ZNpcImporter.java similarity index 83% rename from plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/ZNpcsLoader.java rename to plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/ZNpcImporter.java index 99510ce..47df599 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/ZNpcsLoader.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/ZNpcImporter.java @@ -1,7 +1,9 @@ package lol.pyr.znpcsplus.conversion.znpcs; import com.google.gson.Gson; -import com.google.gson.stream.JsonReader; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; import lol.pyr.znpcsplus.api.interaction.InteractionType; import lol.pyr.znpcsplus.config.ConfigManager; import lol.pyr.znpcsplus.conversion.DataImporter; @@ -25,14 +27,15 @@ import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; import java.io.IOException; +import java.nio.file.Files; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -public class ZNpcsLoader implements DataImporter { +public class ZNpcImporter implements DataImporter { private final ConfigManager configManager; private final BukkitAudiences adventure; private final BungeeConnector bungeeConnector; @@ -40,11 +43,13 @@ public class ZNpcsLoader implements DataImporter { private final PacketFactory packetFactory; private final LegacyComponentSerializer textSerializer; private final NpcTypeRegistryImpl typeRegistry; - private final File folder; private final File dataFile; private final Gson gson; - public ZNpcsLoader(ConfigManager configManager, BukkitAudiences adventure, BungeeConnector bungeeConnector, TaskScheduler taskScheduler, PacketFactory packetFactory, LegacyComponentSerializer textSerializer, NpcTypeRegistryImpl typeRegistry, File pluginsFolder) { + public ZNpcImporter(ConfigManager configManager, BukkitAudiences adventure, BungeeConnector bungeeConnector, + TaskScheduler taskScheduler, PacketFactory packetFactory, LegacyComponentSerializer textSerializer, + NpcTypeRegistryImpl typeRegistry, File dataFile) { + this.configManager = configManager; this.adventure = adventure; this.bungeeConnector = bungeeConnector; @@ -52,18 +57,20 @@ public class ZNpcsLoader implements DataImporter { this.packetFactory = packetFactory; this.textSerializer = textSerializer; this.typeRegistry = typeRegistry; - folder = new File(pluginsFolder, "ServersNPC"); - dataFile = new File(folder, "data.json"); - gson = new Gson(); + this.dataFile = dataFile; + gson = new GsonBuilder() + .create(); } @Override public Collection importData() { ZNpcsModel[] models; - try (FileReader fileReader = new FileReader(dataFile)) { - models = gson.fromJson(new JsonReader(fileReader), ZNpcsModel[].class); + try (BufferedReader fileReader = Files.newBufferedReader(dataFile.toPath())) { + JsonElement element = JsonParser.parseReader(fileReader); + models = gson.fromJson(element, ZNpcsModel[].class); } catch (IOException e) { - throw new RuntimeException(e); + e.printStackTrace(); + return Collections.emptyList(); } if (models == null) return Collections.emptyList(); ArrayList entries = new ArrayList<>(); @@ -89,7 +96,7 @@ public class ZNpcsLoader implements DataImporter { } for (ZNpcsAction action : model.getClickActions()) { - InteractionType t = adaptClickType(action.getActionType()); + InteractionType t = adaptClickType(action.getClickType()); npc.addAction(adaptAction(action.getActionType(), t, action.getAction(), action.getDelay())); } @@ -102,7 +109,7 @@ public class ZNpcsLoader implements DataImporter { @Override public boolean isValid() { - return folder.isDirectory() && dataFile.isFile(); + return dataFile.isFile(); } private InteractionType adaptClickType(String clickType) { diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/model/ZNpcsModel.java b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/model/ZNpcsModel.java index dddb09a..69198d6 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/model/ZNpcsModel.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/conversion/znpcs/model/ZNpcsModel.java @@ -1,7 +1,5 @@ package lol.pyr.znpcsplus.conversion.znpcs.model; -import org.bukkit.inventory.ItemStack; - import java.util.List; import java.util.Map; @@ -15,7 +13,7 @@ public class ZNpcsModel { private String npcType; private List hologramLines; private List clickActions; - private Map npcEquip; + private Map npcEquip; private Map customizationMap; public int getId() { @@ -54,7 +52,7 @@ public class ZNpcsModel { return clickActions; } - public Map getNpcEquip() { + public Map getNpcEquip() { return npcEquip; } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcRegistryImpl.java b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcRegistryImpl.java index e164616..2527d4a 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcRegistryImpl.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/npc/NpcRegistryImpl.java @@ -25,6 +25,8 @@ public class NpcRegistryImpl implements NpcRegistry { private final ConfigManager configManager; private final LegacyComponentSerializer textSerializer; + private final Map npcMap = new HashMap<>(); + public NpcRegistryImpl(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, TaskScheduler scheduler, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer) { this.textSerializer = textSerializer; storage = configManager.getConfig().storageType().create(configManager, plugin, packetFactory, actionRegistry, typeRegistry, propertyRegistry, textSerializer); @@ -37,7 +39,15 @@ public class NpcRegistryImpl implements NpcRegistry { } } + public void registerAll(Collection entries) { + for (NpcEntryImpl entry : entries) { + NpcEntryImpl old = npcMap.put(entry.getId(), entry); + if (old != null) old.getNpc().delete(); + } + } + public void reload() { + for (NpcEntryImpl entry : npcMap.values()) entry.getNpc().delete(); npcMap.clear(); for (NpcEntryImpl entry : storage.loadNpcs()) npcMap.put(entry.getId(), entry); } @@ -46,8 +56,6 @@ public class NpcRegistryImpl implements NpcRegistry { storage.saveNpcs(npcMap.values().stream().filter(NpcEntryImpl::isSave).collect(Collectors.toList())); } - private final Map npcMap = new HashMap<>(); - public NpcEntryImpl get(String id) { return npcMap.get(id.toLowerCase()); } diff --git a/plugin/src/main/resources/help-messages/storage.txt b/plugin/src/main/resources/help-messages/storage.txt index a88f672..6cbe3f5 100644 --- a/plugin/src/main/resources/help-messages/storage.txt +++ b/plugin/src/main/resources/help-messages/storage.txt @@ -4,4 +4,5 @@ * /npc storage save * /npc storage reload + * /npc storage import