Add import command & improve importing

This commit is contained in:
Pyrbu 2023-06-18 19:33:47 +02:00
parent 1f7ddb5b7c
commit 8e6cbb61af
8 changed files with 142 additions and 42 deletions

@ -20,9 +20,11 @@ import lol.pyr.znpcsplus.commands.action.ActionDeleteCommand;
import lol.pyr.znpcsplus.commands.action.ActionEditCommand; import lol.pyr.znpcsplus.commands.action.ActionEditCommand;
import lol.pyr.znpcsplus.commands.action.ActionListCommand; import lol.pyr.znpcsplus.commands.action.ActionListCommand;
import lol.pyr.znpcsplus.commands.hologram.*; 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.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.conversion.DataImporterRegistry;
import lol.pyr.znpcsplus.entity.EntityPropertyImpl; import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl; import lol.pyr.znpcsplus.entity.EntityPropertyRegistryImpl;
import lol.pyr.znpcsplus.interaction.ActionRegistry; import lol.pyr.znpcsplus.interaction.ActionRegistry;
@ -112,8 +114,11 @@ public class ZNpcsPlus extends JavaPlugin {
BungeeConnector bungeeConnector = new BungeeConnector(this); BungeeConnector bungeeConnector = new BungeeConnector(this);
ActionRegistry actionRegistry = new ActionRegistry(); ActionRegistry actionRegistry = new ActionRegistry();
NpcTypeRegistryImpl typeRegistry = new NpcTypeRegistryImpl(); 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(); UserManager userManager = new UserManager();
DataImporterRegistry importerRegistry = new DataImporterRegistry(configManager, adventure, bungeeConnector,
scheduler, packetFactory, textSerializer, typeRegistry, getDataFolder().getParentFile());
log(ChatColor.WHITE + " * Registerring components..."); log(ChatColor.WHITE + " * Registerring components...");
typeRegistry.registerDefault(packetEvents, propertyRegistry); typeRegistry.registerDefault(packetEvents, propertyRegistry);
@ -123,7 +128,7 @@ public class ZNpcsPlus extends JavaPlugin {
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, propertyRegistry); registerCommands(npcRegistry, skinCache, adventure, actionRegistry, typeRegistry, propertyRegistry, importerRegistry);
log(ChatColor.WHITE + " * Starting tasks..."); log(ChatColor.WHITE + " * Starting tasks...");
if (configManager.getConfig().checkForUpdates()) { 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<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);
@ -234,7 +242,8 @@ public class ZNpcsPlus extends JavaPlugin {
.addSubcommand("type", new TypeCommand(npcRegistry, typeRegistry)) .addSubcommand("type", new TypeCommand(npcRegistry, typeRegistry))
.addSubcommand("storage", new MultiCommand(loadHelpMessage("storage")) .addSubcommand("storage", new MultiCommand(loadHelpMessage("storage"))
.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("holo", new MultiCommand(loadHelpMessage("holo")) .addSubcommand("holo", new MultiCommand(loadHelpMessage("holo"))
.addSubcommand("add", new HoloAddCommand(npcRegistry, textSerializer)) .addSubcommand("add", new HoloAddCommand(npcRegistry, textSerializer))
.addSubcommand("delete", new HoloDeleteCommand(npcRegistry)) .addSubcommand("delete", new HoloDeleteCommand(npcRegistry))

@ -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 <importer>");
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<String> suggest(CommandContext context) throws CommandExecutionException {
if (context.argSize() == 1) return context.suggestCollection(importerRegistry.getIds());
return Collections.emptyList();
}
}

@ -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<String, LazyLoader<DataImporter>> 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<DataImporter> 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<String> getIds() {
return Collections.unmodifiableSet(importers.keySet());
}
}

@ -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<DataImporter> importerLoader;
DataImporterType(LazyLoader.ObjectProvider<DataImporter> provider) {
this.importerLoader = LazyLoader.of(provider);
}
DataImporter getImporter() {
return importerLoader.get();
}
}

@ -1,7 +1,9 @@
package lol.pyr.znpcsplus.conversion.znpcs; package lol.pyr.znpcsplus.conversion.znpcs;
import com.google.gson.Gson; 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.api.interaction.InteractionType;
import lol.pyr.znpcsplus.config.ConfigManager; import lol.pyr.znpcsplus.config.ConfigManager;
import lol.pyr.znpcsplus.conversion.DataImporter; 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.Component;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
public class ZNpcsLoader implements DataImporter { public class ZNpcImporter implements DataImporter {
private final ConfigManager configManager; private final ConfigManager configManager;
private final BukkitAudiences adventure; private final BukkitAudiences adventure;
private final BungeeConnector bungeeConnector; private final BungeeConnector bungeeConnector;
@ -40,11 +43,13 @@ public class ZNpcsLoader implements DataImporter {
private final PacketFactory packetFactory; private final PacketFactory packetFactory;
private final LegacyComponentSerializer textSerializer; private final LegacyComponentSerializer textSerializer;
private final NpcTypeRegistryImpl typeRegistry; private final NpcTypeRegistryImpl typeRegistry;
private final File folder;
private final File dataFile; private final File dataFile;
private final Gson gson; 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.configManager = configManager;
this.adventure = adventure; this.adventure = adventure;
this.bungeeConnector = bungeeConnector; this.bungeeConnector = bungeeConnector;
@ -52,18 +57,20 @@ public class ZNpcsLoader implements DataImporter {
this.packetFactory = packetFactory; this.packetFactory = packetFactory;
this.textSerializer = textSerializer; this.textSerializer = textSerializer;
this.typeRegistry = typeRegistry; this.typeRegistry = typeRegistry;
folder = new File(pluginsFolder, "ServersNPC"); this.dataFile = dataFile;
dataFile = new File(folder, "data.json"); gson = new GsonBuilder()
gson = new Gson(); .create();
} }
@Override @Override
public Collection<NpcEntryImpl> importData() { public Collection<NpcEntryImpl> importData() {
ZNpcsModel[] models; ZNpcsModel[] models;
try (FileReader fileReader = new FileReader(dataFile)) { try (BufferedReader fileReader = Files.newBufferedReader(dataFile.toPath())) {
models = gson.fromJson(new JsonReader(fileReader), ZNpcsModel[].class); JsonElement element = JsonParser.parseReader(fileReader);
models = gson.fromJson(element, ZNpcsModel[].class);
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(e); e.printStackTrace();
return Collections.emptyList();
} }
if (models == null) return Collections.emptyList(); if (models == null) return Collections.emptyList();
ArrayList<NpcEntryImpl> entries = new ArrayList<>(); ArrayList<NpcEntryImpl> entries = new ArrayList<>();
@ -89,7 +96,7 @@ public class ZNpcsLoader implements DataImporter {
} }
for (ZNpcsAction action : model.getClickActions()) { 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())); npc.addAction(adaptAction(action.getActionType(), t, action.getAction(), action.getDelay()));
} }
@ -102,7 +109,7 @@ public class ZNpcsLoader implements DataImporter {
@Override @Override
public boolean isValid() { public boolean isValid() {
return folder.isDirectory() && dataFile.isFile(); return dataFile.isFile();
} }
private InteractionType adaptClickType(String clickType) { private InteractionType adaptClickType(String clickType) {

@ -1,7 +1,5 @@
package lol.pyr.znpcsplus.conversion.znpcs.model; package lol.pyr.znpcsplus.conversion.znpcs.model;
import org.bukkit.inventory.ItemStack;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -15,7 +13,7 @@ public class ZNpcsModel {
private String npcType; private String npcType;
private List<String> hologramLines; private List<String> hologramLines;
private List<ZNpcsAction> clickActions; private List<ZNpcsAction> clickActions;
private Map<String, ItemStack> npcEquip; private Map<String, String> npcEquip;
private Map<String, String[]> customizationMap; private Map<String, String[]> customizationMap;
public int getId() { public int getId() {
@ -54,7 +52,7 @@ public class ZNpcsModel {
return clickActions; return clickActions;
} }
public Map<String, ItemStack> getNpcEquip() { public Map<String, String> getNpcEquip() {
return npcEquip; return npcEquip;
} }

@ -25,6 +25,8 @@ public class NpcRegistryImpl implements NpcRegistry {
private final ConfigManager configManager; private final ConfigManager configManager;
private final LegacyComponentSerializer textSerializer; private final LegacyComponentSerializer textSerializer;
private final Map<String, NpcEntryImpl> npcMap = new HashMap<>();
public NpcRegistryImpl(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, TaskScheduler scheduler, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer) { public NpcRegistryImpl(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry, TaskScheduler scheduler, NpcTypeRegistryImpl typeRegistry, EntityPropertyRegistryImpl propertyRegistry, LegacyComponentSerializer textSerializer) {
this.textSerializer = textSerializer; this.textSerializer = textSerializer;
storage = configManager.getConfig().storageType().create(configManager, plugin, packetFactory, actionRegistry, typeRegistry, propertyRegistry, 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<NpcEntryImpl> entries) {
for (NpcEntryImpl entry : entries) {
NpcEntryImpl old = npcMap.put(entry.getId(), entry);
if (old != null) old.getNpc().delete();
}
}
public void reload() { public void reload() {
for (NpcEntryImpl entry : npcMap.values()) entry.getNpc().delete();
npcMap.clear(); npcMap.clear();
for (NpcEntryImpl entry : storage.loadNpcs()) npcMap.put(entry.getId(), entry); 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())); storage.saveNpcs(npcMap.values().stream().filter(NpcEntryImpl::isSave).collect(Collectors.toList()));
} }
private final Map<String, NpcEntryImpl> npcMap = new HashMap<>();
public NpcEntryImpl get(String id) { public NpcEntryImpl get(String id) {
return npcMap.get(id.toLowerCase()); return npcMap.get(id.toLowerCase());
} }

@ -4,4 +4,5 @@
<gold>* <yellow>/npc storage save <gold>* <yellow>/npc storage save
<gold>* <yellow>/npc storage reload <gold>* <yellow>/npc storage reload
<gold>* <yellow>/npc storage import <importer>