From acd83a6fe660718db942104fa77e1c9a1b909adc Mon Sep 17 00:00:00 2001 From: filoghost Date: Fri, 19 Feb 2021 21:37:56 +0100 Subject: [PATCH] Configuration refactoring, convert symbols.yml to custom-placeholders.yml --- .../HolographicDisplays.java | 28 +- .../bungeecord/BungeeServerTracker.java | 11 +- .../commands/HologramCommandManager.java | 27 +- .../commands/HologramCommandValidate.java | 4 +- .../commands/subs/AddlineCommand.java | 14 +- .../commands/subs/AlignCommand.java | 12 +- .../commands/subs/CopyCommand.java | 16 +- .../commands/subs/CreateCommand.java | 12 +- .../commands/subs/DeleteCommand.java | 13 +- .../commands/subs/InfoCommand.java | 3 +- .../commands/subs/InsertlineCommand.java | 12 +- .../commands/subs/MovehereCommand.java | 11 +- .../commands/subs/ReadimageCommand.java | 16 +- .../commands/subs/ReadtextCommand.java | 16 +- .../commands/subs/ReloadCommand.java | 33 ++- .../commands/subs/RemovelineCommand.java | 12 +- .../commands/subs/SetlineCommand.java | 12 +- .../disk/ConfigManager.java | 97 +++++++ .../holographicdisplays/disk/ConfigNode.java | 47 --- .../disk/Configuration.java | 269 +++++++----------- .../disk/CustomPlaceholders.java | 55 ++++ .../disk/HologramConfig.java | 117 ++++++++ .../disk/HologramDatabase.java | 138 +++------ .../disk/HologramLineParseException.java | 18 -- .../disk/HologramLineParser.java | 21 +- .../disk/HologramNotFoundException.java | 14 - .../disk/LocationFormatException.java | 14 - .../disk/LocationSerializer.java | 56 ---- .../disk/LocationWorldNotLoadedException.java | 14 - .../disk/MainConfigModel.java | 106 +++++++ .../disk/ServerAddress.java | 12 +- .../disk/StaticPlaceholder.java | 26 ++ .../disk/StringConverter.java | 2 +- .../disk/UnicodeSymbols.java | 103 ------- .../disk/upgrade/LegacySymbolsUpgrader.java | 87 ++++++ .../task/StartupLoadHologramsTask.java | 33 ++- plugin/src/main/resources/config.yml | 20 -- .../main/resources/custom-placeholders.yml | 14 + plugin/src/main/resources/database.yml | 3 - plugin/src/main/resources/symbols.yml | 14 - 40 files changed, 845 insertions(+), 687 deletions(-) create mode 100644 plugin/src/main/java/me/filoghost/holographicdisplays/disk/ConfigManager.java delete mode 100644 plugin/src/main/java/me/filoghost/holographicdisplays/disk/ConfigNode.java create mode 100644 plugin/src/main/java/me/filoghost/holographicdisplays/disk/CustomPlaceholders.java create mode 100644 plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramConfig.java delete mode 100644 plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramLineParseException.java delete mode 100644 plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramNotFoundException.java delete mode 100644 plugin/src/main/java/me/filoghost/holographicdisplays/disk/LocationFormatException.java delete mode 100644 plugin/src/main/java/me/filoghost/holographicdisplays/disk/LocationSerializer.java delete mode 100644 plugin/src/main/java/me/filoghost/holographicdisplays/disk/LocationWorldNotLoadedException.java create mode 100644 plugin/src/main/java/me/filoghost/holographicdisplays/disk/MainConfigModel.java create mode 100644 plugin/src/main/java/me/filoghost/holographicdisplays/disk/StaticPlaceholder.java delete mode 100644 plugin/src/main/java/me/filoghost/holographicdisplays/disk/UnicodeSymbols.java create mode 100644 plugin/src/main/java/me/filoghost/holographicdisplays/disk/upgrade/LegacySymbolsUpgrader.java delete mode 100644 plugin/src/main/resources/config.yml create mode 100644 plugin/src/main/resources/custom-placeholders.yml delete mode 100644 plugin/src/main/resources/database.yml delete mode 100644 plugin/src/main/resources/symbols.yml diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/HolographicDisplays.java b/plugin/src/main/java/me/filoghost/holographicdisplays/HolographicDisplays.java index 2b6f54a1..0a27474e 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/HolographicDisplays.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/HolographicDisplays.java @@ -6,6 +6,7 @@ package me.filoghost.holographicdisplays; import me.filoghost.fcommons.BaseJavaPlugin; +import me.filoghost.fcommons.config.exception.ConfigException; import me.filoghost.fcommons.logging.Log; import me.filoghost.fcommons.reflection.ReflectUtils; import me.filoghost.holographicdisplays.api.internal.BackendAPI; @@ -13,9 +14,9 @@ import me.filoghost.holographicdisplays.bridge.bungeecord.BungeeServerTracker; import me.filoghost.holographicdisplays.bridge.protocollib.ProtocolLibHook; import me.filoghost.holographicdisplays.bridge.protocollib.current.ProtocolLibHookImpl; import me.filoghost.holographicdisplays.commands.HologramCommandManager; +import me.filoghost.holographicdisplays.disk.ConfigManager; import me.filoghost.holographicdisplays.disk.Configuration; -import me.filoghost.holographicdisplays.disk.HologramDatabase; -import me.filoghost.holographicdisplays.disk.UnicodeSymbols; +import me.filoghost.holographicdisplays.disk.upgrade.LegacySymbolsUpgrader; import me.filoghost.holographicdisplays.listener.MainListener; import me.filoghost.holographicdisplays.nms.interfaces.NMSManager; import me.filoghost.holographicdisplays.object.DefaultBackendAPI; @@ -55,7 +56,7 @@ public class HolographicDisplays extends BaseJavaPlugin { // The new version found by the updater, null if there is no new version. private static String newVersion; - + // Not null if ProtocolLib is installed and successfully loaded. private static ProtocolLibHook protocolLibHook; @@ -71,12 +72,20 @@ public class HolographicDisplays extends BaseJavaPlugin { System.setProperty("HolographicDisplaysLoaded", "true"); instance = this; dataFolderPath = getDataFolder().toPath(); - + ConfigManager configManager = new ConfigManager(dataFolderPath); + + // Run only once at startup, before anything else. + try { + LegacySymbolsUpgrader.run(configManager); + } catch (ConfigException e) { + Log.warning("Couldn't convert symbols file", e); + } + // Load placeholders.yml. - UnicodeSymbols.load(this); + configManager.reloadCustomPlaceholders(); // Load the configuration. - Configuration.load(this); + configManager.reloadMainConfig(); if (Configuration.updateNotification) { UpdateChecker.run(this, 75097, (String newVersion) -> { @@ -119,7 +128,7 @@ public class HolographicDisplays extends BaseJavaPlugin { } // Initialize other static classes. - HologramDatabase.loadYamlFile(this); + configManager.reloadHologramDatabase(); BungeeServerTracker.restartTask(Configuration.bungeeRefreshSeconds); // Start repeating tasks. @@ -132,7 +141,7 @@ public class HolographicDisplays extends BaseJavaPlugin { "This can be caused by edits to plugin.yml or other plugins."); } - commandManager = new HologramCommandManager(); + commandManager = new HologramCommandManager(configManager); commandManager.register(this); mainListener = new MainListener(nmsManager); @@ -143,7 +152,8 @@ public class HolographicDisplays extends BaseJavaPlugin { new MetricsLite(this, pluginID); // Holograms are loaded later, when the worlds are ready. - Bukkit.getScheduler().runTask(this, new StartupLoadHologramsTask()); + Bukkit.getScheduler().runTask(this, + new StartupLoadHologramsTask(configManager.getHologramDatabase().getHolograms())); // Enable the API. BackendAPI.setImplementation(new DefaultBackendAPI()); diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/bridge/bungeecord/BungeeServerTracker.java b/plugin/src/main/java/me/filoghost/holographicdisplays/bridge/bungeecord/BungeeServerTracker.java index dedc4348..75bbeae2 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/bridge/bungeecord/BungeeServerTracker.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/bridge/bungeecord/BungeeServerTracker.java @@ -17,7 +17,6 @@ import java.io.IOException; import java.net.SocketTimeoutException; import java.net.UnknownHostException; import java.util.Map; -import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; public class BungeeServerTracker { @@ -146,12 +145,12 @@ public class BungeeServerTracker { if (Configuration.pingerEnable) { Bukkit.getScheduler().runTaskAsynchronously(HolographicDisplays.getInstance(), () -> { - for (Entry entry : Configuration.pingerServers.entrySet()) { - BungeeServerInfo serverInfo = getOrCreateServerInfo(entry.getKey()); + for (ServerAddress serverAddress : Configuration.pingerServers) { + BungeeServerInfo serverInfo = getOrCreateServerInfo(serverAddress.getName()); boolean displayOffline = false; try { - PingResponse data = ServerPinger.fetchData(entry.getValue(), Configuration.pingerTimeout); + PingResponse data = ServerPinger.fetchData(serverAddress, Configuration.pingerTimeout); if (data.isOnline()) { serverInfo.setOnline(true); @@ -164,13 +163,13 @@ public class BungeeServerTracker { } catch (SocketTimeoutException e) { displayOffline = true; } catch (UnknownHostException e) { - Log.warning("Couldn't fetch data from " + entry.getKey() + "(" + entry.getValue().toString() + "): unknown host address."); + Log.warning("Couldn't fetch data from " + serverAddress + ": unknown host address."); displayOffline = true; } catch (IOException e) { displayOffline = true; } catch (Throwable t) { displayOffline = true; - Log.warning("Couldn't fetch data from " + entry.getKey() + "(" + entry.getValue().toString() + ")", t); + Log.warning("Couldn't fetch data from " + serverAddress, t); } if (displayOffline) { diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/HologramCommandManager.java b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/HologramCommandManager.java index dd542357..32c794a1 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/HologramCommandManager.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/HologramCommandManager.java @@ -31,6 +31,7 @@ import me.filoghost.holographicdisplays.commands.subs.RemovelineCommand; import me.filoghost.holographicdisplays.commands.subs.SetlineCommand; import me.filoghost.holographicdisplays.commands.subs.TeleportCommand; import me.filoghost.holographicdisplays.common.Utils; +import me.filoghost.holographicdisplays.disk.ConfigManager; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; @@ -47,28 +48,28 @@ public class HologramCommandManager extends SubCommandManager { private final HelpCommand helpCommand; - public HologramCommandManager() { + public HologramCommandManager(ConfigManager configManager) { setName("holograms"); subCommands = new ArrayList<>(); subCommandsByClass = new HashMap<>(); - registerSubCommand(new AddlineCommand()); - registerSubCommand(new CreateCommand()); - registerSubCommand(new DeleteCommand()); + registerSubCommand(new AddlineCommand(configManager)); + registerSubCommand(new CreateCommand(configManager)); + registerSubCommand(new DeleteCommand(configManager)); registerSubCommand(new EditCommand()); registerSubCommand(new ListCommand()); registerSubCommand(new NearCommand()); registerSubCommand(new TeleportCommand()); - registerSubCommand(new MovehereCommand()); - registerSubCommand(new AlignCommand()); - registerSubCommand(new CopyCommand()); - registerSubCommand(new ReloadCommand()); + registerSubCommand(new MovehereCommand(configManager)); + registerSubCommand(new AlignCommand(configManager)); + registerSubCommand(new CopyCommand(configManager)); + registerSubCommand(new ReloadCommand(configManager)); - registerSubCommand(new RemovelineCommand()); - registerSubCommand(new SetlineCommand()); - registerSubCommand(new InsertlineCommand()); - registerSubCommand(new ReadtextCommand()); - registerSubCommand(new ReadimageCommand()); + registerSubCommand(new RemovelineCommand(configManager)); + registerSubCommand(new SetlineCommand(configManager)); + registerSubCommand(new InsertlineCommand(configManager)); + registerSubCommand(new ReadtextCommand(configManager)); + registerSubCommand(new ReadimageCommand(configManager)); registerSubCommand(new InfoCommand()); registerSubCommand(new DebugCommand()); diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/HologramCommandValidate.java b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/HologramCommandValidate.java index 13d4bb8d..25208c9f 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/HologramCommandValidate.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/HologramCommandValidate.java @@ -10,7 +10,7 @@ import me.filoghost.fcommons.command.validation.CommandValidate; import me.filoghost.holographicdisplays.HolographicDisplays; import me.filoghost.holographicdisplays.common.Utils; import me.filoghost.holographicdisplays.disk.HologramLineParser; -import me.filoghost.holographicdisplays.disk.HologramLineParseException; +import me.filoghost.holographicdisplays.disk.HologramLoadException; import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.NamedHologramManager; import me.filoghost.holographicdisplays.object.line.CraftHologramLine; @@ -24,7 +24,7 @@ public class HologramCommandValidate { public static CraftHologramLine parseHologramLine(NamedHologram hologram, String serializedLine, boolean validateMaterial) throws CommandException { try { return HologramLineParser.parseLine(hologram, serializedLine, validateMaterial); - } catch (HologramLineParseException e) { + } catch (HologramLoadException e) { throw new CommandException(Utils.formatExceptionMessage(e)); } } diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/AddlineCommand.java b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/AddlineCommand.java index 95db5a58..8e11ee55 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/AddlineCommand.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/AddlineCommand.java @@ -10,7 +10,7 @@ import me.filoghost.fcommons.command.validation.CommandException; import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.common.Utils; -import me.filoghost.holographicdisplays.disk.HologramDatabase; +import me.filoghost.holographicdisplays.disk.ConfigManager; import me.filoghost.holographicdisplays.event.NamedHologramEditedEvent; import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.line.CraftHologramLine; @@ -19,11 +19,15 @@ import org.bukkit.command.CommandSender; public class AddlineCommand extends LineEditingCommand { - public AddlineCommand() { + private final ConfigManager configManager; + + public AddlineCommand(ConfigManager configManager) { super("addline"); setMinArgs(2); setUsageArgs(" "); setDescription("Adds a line to an existing hologram."); + + this.configManager = configManager; } @Override @@ -34,9 +38,9 @@ public class AddlineCommand extends LineEditingCommand { CraftHologramLine line = HologramCommandValidate.parseHologramLine(hologram, serializedLine, true); hologram.getLinesUnsafe().add(line); hologram.refreshAll(); - - HologramDatabase.saveHologram(hologram); - HologramDatabase.trySaveToDisk(); + + configManager.getHologramDatabase().addOrUpdate(hologram); + configManager.saveHologramDatabase(); Bukkit.getPluginManager().callEvent(new NamedHologramEditedEvent(hologram)); sender.sendMessage(Colors.PRIMARY + "Line added!"); diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/AlignCommand.java b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/AlignCommand.java index 55ed1623..52e96a8c 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/AlignCommand.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/AlignCommand.java @@ -11,18 +11,22 @@ import me.filoghost.fcommons.command.validation.CommandValidate; import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.HologramSubCommand; -import me.filoghost.holographicdisplays.disk.HologramDatabase; +import me.filoghost.holographicdisplays.disk.ConfigManager; import me.filoghost.holographicdisplays.object.NamedHologram; import org.bukkit.Location; import org.bukkit.command.CommandSender; public class AlignCommand extends HologramSubCommand { - public AlignCommand() { + private final ConfigManager configManager; + + public AlignCommand(ConfigManager configManager) { super("align"); setMinArgs(3); setUsageArgs(" "); setDescription("Aligns the first hologram to the second, in the specified axis."); + + this.configManager = configManager; } @Override @@ -52,8 +56,8 @@ public class AlignCommand extends HologramSubCommand { hologram.despawnEntities(); hologram.refreshAll(); - HologramDatabase.saveHologram(hologram); - HologramDatabase.trySaveToDisk(); + configManager.getHologramDatabase().addOrUpdate(hologram); + configManager.saveHologramDatabase(); sender.sendMessage(Colors.PRIMARY + "Hologram \"" + hologram.getName() + "\" aligned to the hologram \"" + referenceHologram.getName() + "\" on the " + axis.toUpperCase() + " axis."); } diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/CopyCommand.java b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/CopyCommand.java index 1bebcf03..8f6a9a90 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/CopyCommand.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/CopyCommand.java @@ -10,18 +10,22 @@ import me.filoghost.fcommons.command.validation.CommandException; import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.HologramSubCommand; -import me.filoghost.holographicdisplays.disk.HologramDatabase; +import me.filoghost.holographicdisplays.disk.ConfigManager; import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.line.CraftHologramLine; import org.bukkit.command.CommandSender; public class CopyCommand extends HologramSubCommand { + + private final ConfigManager configManager; - public CopyCommand() { + public CopyCommand(ConfigManager configManager) { super("copy"); setMinArgs(2); setUsageArgs(" "); setDescription("Copies the contents of a hologram into another one."); + + this.configManager = configManager; } @Override @@ -31,14 +35,14 @@ public class CopyCommand extends HologramSubCommand { toHologram.clearLines(); for (CraftHologramLine line : fromHologram.getLinesUnsafe()) { - CraftHologramLine clonedLine = HologramCommandValidate.parseHologramLine(toHologram, HologramDatabase.serializeHologramLine(line), false); + CraftHologramLine clonedLine = HologramCommandValidate.parseHologramLine(toHologram, line.getSerializedConfigValue(), false); toHologram.getLinesUnsafe().add(clonedLine); } toHologram.refreshAll(); - - HologramDatabase.saveHologram(toHologram); - HologramDatabase.trySaveToDisk(); + + configManager.getHologramDatabase().addOrUpdate(toHologram); + configManager.saveHologramDatabase(); sender.sendMessage(Colors.PRIMARY + "Hologram \"" + fromHologram.getName() + "\" copied into hologram \"" + toHologram.getName() + "\"!"); } diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/CreateCommand.java b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/CreateCommand.java index b6bef42e..90f33cef 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/CreateCommand.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/CreateCommand.java @@ -12,7 +12,7 @@ import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.HologramSubCommand; import me.filoghost.holographicdisplays.common.Utils; -import me.filoghost.holographicdisplays.disk.HologramDatabase; +import me.filoghost.holographicdisplays.disk.ConfigManager; import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.NamedHologramManager; import me.filoghost.holographicdisplays.object.line.CraftHologramLine; @@ -22,8 +22,10 @@ import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; public class CreateCommand extends HologramSubCommand { + + private final ConfigManager configManager; - public CreateCommand() { + public CreateCommand(ConfigManager configManager) { super("create"); setMinArgs(1); setUsageArgs(" [text]"); @@ -31,6 +33,8 @@ public class CreateCommand extends HologramSubCommand { "Creates a new hologram with the given name, that must", "be alphanumeric. The name will be used as reference to", "that hologram for editing commands."); + + this.configManager = configManager; } @SuppressWarnings("deprecation") @@ -68,8 +72,8 @@ public class CreateCommand extends HologramSubCommand { NamedHologramManager.addHologram(hologram); hologram.refreshAll(); - HologramDatabase.saveHologram(hologram); - HologramDatabase.trySaveToDisk(); + configManager.getHologramDatabase().addOrUpdate(hologram); + configManager.saveHologramDatabase(); Location look = player.getLocation(); look.setPitch(90); player.teleport(look, TeleportCause.PLUGIN); diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/DeleteCommand.java b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/DeleteCommand.java index 98fd430d..dd33af55 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/DeleteCommand.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/DeleteCommand.java @@ -10,18 +10,22 @@ import me.filoghost.fcommons.command.validation.CommandException; import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.HologramSubCommand; -import me.filoghost.holographicdisplays.disk.HologramDatabase; +import me.filoghost.holographicdisplays.disk.ConfigManager; import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.NamedHologramManager; import org.bukkit.command.CommandSender; public class DeleteCommand extends HologramSubCommand { - public DeleteCommand() { + private final ConfigManager configManager; + + public DeleteCommand(ConfigManager configManager) { super("delete", "remove"); setMinArgs(1); setUsageArgs(""); setDescription("Deletes a hologram. Cannot be undone."); + + this.configManager = configManager; } @Override @@ -30,9 +34,10 @@ public class DeleteCommand extends HologramSubCommand { hologram.delete(); NamedHologramManager.removeHologram(hologram); - HologramDatabase.deleteHologram(hologram.getName()); + + configManager.getHologramDatabase().removeHologram(hologram); + configManager.saveHologramDatabase(); - HologramDatabase.trySaveToDisk(); sender.sendMessage(Colors.PRIMARY + "You deleted the hologram '" + hologram.getName() + "'."); } diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/InfoCommand.java b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/InfoCommand.java index e621e16e..4aa2eab5 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/InfoCommand.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/InfoCommand.java @@ -10,7 +10,6 @@ import me.filoghost.fcommons.command.validation.CommandException; import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.Messages; -import me.filoghost.holographicdisplays.disk.HologramDatabase; import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.line.CraftHologramLine; import org.bukkit.command.CommandSender; @@ -33,7 +32,7 @@ public class InfoCommand extends LineEditingCommand { int index = 0; for (CraftHologramLine line : hologram.getLinesUnsafe()) { - sender.sendMessage(Colors.SECONDARY + Colors.BOLD + (++index) + Colors.SECONDARY_SHADOW + ". " + Colors.SECONDARY + HologramDatabase.serializeHologramLine(line)); + sender.sendMessage(Colors.SECONDARY + Colors.BOLD + (++index) + Colors.SECONDARY_SHADOW + ". " + Colors.SECONDARY + line.getSerializedConfigValue()); } EditCommand.sendQuickEditCommands(context, hologram); } diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/InsertlineCommand.java b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/InsertlineCommand.java index bcdaac9b..c198549a 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/InsertlineCommand.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/InsertlineCommand.java @@ -12,7 +12,7 @@ import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.Messages; import me.filoghost.holographicdisplays.common.Utils; -import me.filoghost.holographicdisplays.disk.HologramDatabase; +import me.filoghost.holographicdisplays.disk.ConfigManager; import me.filoghost.holographicdisplays.event.NamedHologramEditedEvent; import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.line.CraftHologramLine; @@ -20,8 +20,10 @@ import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; public class InsertlineCommand extends LineEditingCommand { + + private final ConfigManager configManager; - public InsertlineCommand() { + public InsertlineCommand(ConfigManager configManager) { super("insertline"); setMinArgs(3); setUsageArgs(" "); @@ -29,6 +31,8 @@ public class InsertlineCommand extends LineEditingCommand { "Inserts a line after the specified index.", "If the index is 0, the line will be put before", "the first line of the hologram."); + + this.configManager = configManager; } @Override @@ -45,8 +49,8 @@ public class InsertlineCommand extends LineEditingCommand { hologram.getLinesUnsafe().add(insertAfter, line); hologram.refreshAll(); - HologramDatabase.saveHologram(hologram); - HologramDatabase.trySaveToDisk(); + configManager.getHologramDatabase().addOrUpdate(hologram); + configManager.saveHologramDatabase(); Bukkit.getPluginManager().callEvent(new NamedHologramEditedEvent(hologram)); diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/MovehereCommand.java b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/MovehereCommand.java index 9a3f5e9d..15f5852a 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/MovehereCommand.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/MovehereCommand.java @@ -11,7 +11,7 @@ import me.filoghost.fcommons.command.validation.CommandValidate; import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.HologramSubCommand; -import me.filoghost.holographicdisplays.disk.HologramDatabase; +import me.filoghost.holographicdisplays.disk.ConfigManager; import me.filoghost.holographicdisplays.object.NamedHologram; import org.bukkit.Location; import org.bukkit.command.CommandSender; @@ -20,12 +20,15 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; public class MovehereCommand extends HologramSubCommand { + private final ConfigManager configManager; - public MovehereCommand() { + public MovehereCommand(ConfigManager configManager) { super("movehere"); setMinArgs(1); setUsageArgs(""); setDescription("Moves a hologram to your location."); + + this.configManager = configManager; } @Override @@ -37,8 +40,8 @@ public class MovehereCommand extends HologramSubCommand { hologram.despawnEntities(); hologram.refreshAll(); - HologramDatabase.saveHologram(hologram); - HologramDatabase.trySaveToDisk(); + configManager.getHologramDatabase().addOrUpdate(hologram); + configManager.saveHologramDatabase(); Location to = player.getLocation(); to.setPitch(90); player.teleport(to, TeleportCause.PLUGIN); diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/ReadimageCommand.java b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/ReadimageCommand.java index 5a8be068..cc371651 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/ReadimageCommand.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/ReadimageCommand.java @@ -12,12 +12,12 @@ import me.filoghost.fcommons.command.validation.CommandValidate; import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.Messages; -import me.filoghost.holographicdisplays.disk.HologramDatabase; +import me.filoghost.holographicdisplays.disk.ConfigManager; import me.filoghost.holographicdisplays.event.NamedHologramEditedEvent; +import me.filoghost.holographicdisplays.image.ImageMessage; +import me.filoghost.holographicdisplays.image.ImageReadException; import me.filoghost.holographicdisplays.image.ImageReader; import me.filoghost.holographicdisplays.image.ImageTooWideException; -import me.filoghost.holographicdisplays.image.ImageReadException; -import me.filoghost.holographicdisplays.image.ImageMessage; import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.line.CraftTextLine; import org.bukkit.Bukkit; @@ -34,11 +34,15 @@ import java.util.Arrays; import java.util.List; public class ReadimageCommand extends LineEditingCommand { + + private final ConfigManager configManager; - public ReadimageCommand() { + public ReadimageCommand(ConfigManager configManager) { super("readimage", "image"); setMinArgs(3); setUsageArgs(" "); + + this.configManager = configManager; } @Override @@ -120,8 +124,8 @@ public class ReadimageCommand extends LineEditingCommand { Messages.sendTip(sender, "The image has a very low height. You can increase it by increasing the width, it will scale automatically."); } - HologramDatabase.saveHologram(hologram); - HologramDatabase.trySaveToDisk(); + configManager.getHologramDatabase().addOrUpdate(hologram); + configManager.saveHologramDatabase(); if (append) { sender.sendMessage(Colors.PRIMARY + "The image was appended int the end of the hologram!"); diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/ReadtextCommand.java b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/ReadtextCommand.java index c0c8ec10..beae3078 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/ReadtextCommand.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/ReadtextCommand.java @@ -11,9 +11,9 @@ import me.filoghost.fcommons.command.validation.CommandException; import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.Messages; -import me.filoghost.holographicdisplays.disk.HologramDatabase; -import me.filoghost.holographicdisplays.disk.HologramLineParseException; +import me.filoghost.holographicdisplays.disk.ConfigManager; import me.filoghost.holographicdisplays.disk.HologramLineParser; +import me.filoghost.holographicdisplays.disk.HologramLoadException; import me.filoghost.holographicdisplays.event.NamedHologramEditedEvent; import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.line.CraftHologramLine; @@ -31,10 +31,14 @@ import java.util.List; public class ReadtextCommand extends LineEditingCommand { - public ReadtextCommand() { + private final ConfigManager configManager; + + public ReadtextCommand(ConfigManager configManager) { super("readtext", "readlines"); setMinArgs(2); setUsageArgs(" "); + + this.configManager = configManager; } @Override @@ -71,7 +75,7 @@ public class ReadtextCommand extends LineEditingCommand { try { CraftHologramLine line = HologramLineParser.parseLine(hologram, serializedLines.get(i), true); linesToAdd.add(line); - } catch (HologramLineParseException e) { + } catch (HologramLoadException e) { throw new CommandException("Error at line " + (i + 1) + ": " + e.getMessage()); } } @@ -80,8 +84,8 @@ public class ReadtextCommand extends LineEditingCommand { hologram.getLinesUnsafe().addAll(linesToAdd); hologram.refreshAll(); - HologramDatabase.saveHologram(hologram); - HologramDatabase.trySaveToDisk(); + configManager.getHologramDatabase().addOrUpdate(hologram); + configManager.saveHologramDatabase(); if (isImageExtension(FileUtils.getExtension(fileName))) { Messages.sendWarning(sender, "The read file has an image's extension. If it is an image, you should use /" + context.getRootLabel() + " readimage."); diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/ReloadCommand.java b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/ReloadCommand.java index 0bfefd2b..2e71a596 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/ReloadCommand.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/ReloadCommand.java @@ -13,10 +13,10 @@ import me.filoghost.holographicdisplays.bridge.bungeecord.BungeeServerTracker; import me.filoghost.holographicdisplays.commands.HologramSubCommand; import me.filoghost.holographicdisplays.commands.Messages; import me.filoghost.holographicdisplays.common.Utils; +import me.filoghost.holographicdisplays.disk.ConfigManager; import me.filoghost.holographicdisplays.disk.Configuration; -import me.filoghost.holographicdisplays.disk.HologramDatabase; +import me.filoghost.holographicdisplays.disk.HologramConfig; import me.filoghost.holographicdisplays.disk.HologramLoadException; -import me.filoghost.holographicdisplays.disk.UnicodeSymbols; import me.filoghost.holographicdisplays.event.HolographicDisplaysReloadEvent; import me.filoghost.holographicdisplays.object.CraftHologram; import me.filoghost.holographicdisplays.object.NamedHologram; @@ -26,26 +26,28 @@ import me.filoghost.holographicdisplays.placeholder.PlaceholdersManager; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; -import java.util.Set; - public class ReloadCommand extends HologramSubCommand { - public ReloadCommand() { + private final ConfigManager configManager; + + public ReloadCommand(ConfigManager configManager) { super("reload"); setDescription("Reloads the holograms from the database."); + + this.configManager = configManager; } @Override public void execute(CommandSender sender, String[] args, SubCommandContext context) { long startMillis = System.currentTimeMillis(); - UnicodeSymbols.load(HolographicDisplays.getInstance()); - Configuration.load(HolographicDisplays.getInstance()); + configManager.reloadCustomPlaceholders(); + configManager.reloadMainConfig(); BungeeServerTracker.resetTrackedServers(); BungeeServerTracker.restartTask(Configuration.bungeeRefreshSeconds); - HologramDatabase.loadYamlFile(HolographicDisplays.getInstance()); + configManager.reloadHologramDatabase(); try { AnimationsRegister.loadAnimations(HolographicDisplays.getInstance()); } catch (Exception e) { @@ -55,15 +57,12 @@ public class ReloadCommand extends HologramSubCommand { PlaceholdersManager.untrackAll(); NamedHologramManager.clearAll(); - Set savedHolograms = HologramDatabase.getHolograms(); - if (savedHolograms != null && savedHolograms.size() > 0) { - for (String singleSavedHologram : savedHolograms) { - try { - NamedHologram singleHologramEntity = HologramDatabase.loadHologram(singleSavedHologram); - NamedHologramManager.addHologram(singleHologramEntity); - } catch (HologramLoadException e) { - Messages.sendWarning(sender, Utils.formatExceptionMessage(e)); - } + for (HologramConfig hologramConfig : configManager.getHologramDatabase().getHolograms()) { + try { + NamedHologram hologram = hologramConfig.createHologram(); + NamedHologramManager.addHologram(hologram); + } catch (HologramLoadException e) { + Messages.sendWarning(sender, Utils.formatExceptionMessage(e)); } } diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/RemovelineCommand.java b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/RemovelineCommand.java index 6f0672f9..0be8ce1b 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/RemovelineCommand.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/RemovelineCommand.java @@ -10,7 +10,7 @@ import me.filoghost.fcommons.command.validation.CommandException; import me.filoghost.fcommons.command.validation.CommandValidate; import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.commands.HologramCommandValidate; -import me.filoghost.holographicdisplays.disk.HologramDatabase; +import me.filoghost.holographicdisplays.disk.ConfigManager; import me.filoghost.holographicdisplays.event.NamedHologramEditedEvent; import me.filoghost.holographicdisplays.object.NamedHologram; import org.bukkit.Bukkit; @@ -18,11 +18,15 @@ import org.bukkit.command.CommandSender; public class RemovelineCommand extends LineEditingCommand { - public RemovelineCommand() { + private final ConfigManager configManager; + + public RemovelineCommand(ConfigManager configManager) { super("removeline"); setMinArgs(2); setUsageArgs(" "); setDescription("Removes a line from a hologram."); + + this.configManager = configManager; } @Override @@ -39,8 +43,8 @@ public class RemovelineCommand extends LineEditingCommand { hologram.removeLine(index); hologram.refreshAll(); - HologramDatabase.saveHologram(hologram); - HologramDatabase.trySaveToDisk(); + configManager.getHologramDatabase().addOrUpdate(hologram); + configManager.saveHologramDatabase(); Bukkit.getPluginManager().callEvent(new NamedHologramEditedEvent(hologram)); sender.sendMessage(Colors.PRIMARY + "Line " + lineNumber + " removed!"); diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/SetlineCommand.java b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/SetlineCommand.java index b0ab3c2b..21c712fd 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/SetlineCommand.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/commands/subs/SetlineCommand.java @@ -11,7 +11,7 @@ import me.filoghost.fcommons.command.validation.CommandValidate; import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.common.Utils; -import me.filoghost.holographicdisplays.disk.HologramDatabase; +import me.filoghost.holographicdisplays.disk.ConfigManager; import me.filoghost.holographicdisplays.event.NamedHologramEditedEvent; import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.line.CraftHologramLine; @@ -20,11 +20,15 @@ import org.bukkit.command.CommandSender; public class SetlineCommand extends LineEditingCommand { - public SetlineCommand() { + private final ConfigManager configManager; + + public SetlineCommand(ConfigManager configManager) { super("setline"); setMinArgs(3); setUsageArgs(" "); setDescription("Changes a line of a hologram."); + + this.configManager = configManager; } @Override @@ -42,8 +46,8 @@ public class SetlineCommand extends LineEditingCommand { hologram.getLinesUnsafe().set(index, line); hologram.refreshAll(); - HologramDatabase.saveHologram(hologram); - HologramDatabase.trySaveToDisk(); + configManager.getHologramDatabase().addOrUpdate(hologram); + configManager.saveHologramDatabase(); Bukkit.getPluginManager().callEvent(new NamedHologramEditedEvent(hologram)); sender.sendMessage(Colors.PRIMARY + "Line " + lineNumber + " changed!"); diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/ConfigManager.java b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/ConfigManager.java new file mode 100644 index 00000000..e839bdba --- /dev/null +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/ConfigManager.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) filoghost and contributors + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ +package me.filoghost.holographicdisplays.disk; + +import me.filoghost.fcommons.config.BaseConfigManager; +import me.filoghost.fcommons.config.Config; +import me.filoghost.fcommons.config.ConfigErrors; +import me.filoghost.fcommons.config.ConfigLoader; +import me.filoghost.fcommons.config.FileConfig; +import me.filoghost.fcommons.config.exception.ConfigException; +import me.filoghost.fcommons.config.mapped.MappedConfigLoader; +import me.filoghost.fcommons.logging.Log; + +import java.nio.file.Path; + +public class ConfigManager extends BaseConfigManager { + + private final MappedConfigLoader mainConfigLoader; + private final ConfigLoader databaseConfigLoader; + private final ConfigLoader placeholdersConfigLoader; + private final HologramDatabase hologramDatabase; + + public ConfigManager(Path rootDataFolder) { + super(rootDataFolder); + this.mainConfigLoader = getMappedConfigLoader("config.yml", MainConfigModel.class); + this.databaseConfigLoader = getConfigLoader("database.yml"); + this.placeholdersConfigLoader = getConfigLoader("custom-placeholders.yml"); + this.hologramDatabase = new HologramDatabase(); + } + + public void reloadMainConfig() { + MainConfigModel mainConfig; + + try { + mainConfig = mainConfigLoader.init(); + } catch (ConfigException e) { + logConfigInitException(mainConfigLoader.getFile(), e); + mainConfig = new MainConfigModel(); // Fallback: use default values + } + + Configuration.load(mainConfig); + } + + public void reloadHologramDatabase() { + Config databaseConfig; + + try { + databaseConfig = databaseConfigLoader.init(); + } catch (ConfigException e) { + logConfigInitException(databaseConfigLoader.getFile(), e); + databaseConfig = new Config(); // Fallback: empty config + } + + hologramDatabase.reloadFromConfig(databaseConfig); + } + + public void saveHologramDatabase() { + try { + databaseConfigLoader.save(hologramDatabase.saveToConfig()); + } catch (ConfigException e) { + logConfigSaveException(databaseConfigLoader.getFile(), e); + } + } + + public HologramDatabase getHologramDatabase() { + return hologramDatabase; + } + + public void reloadCustomPlaceholders() { + FileConfig placeholdersConfig; + + try { + placeholdersConfig = placeholdersConfigLoader.init(); + } catch (ConfigException e) { + logConfigInitException(placeholdersConfigLoader.getFile(), e); + placeholdersConfig = new FileConfig(placeholdersConfigLoader.getFile()); // Fallback: empty config + } + + CustomPlaceholders.load(placeholdersConfig); + } + + private void logConfigInitException(Path file, ConfigException e) { + Log.severe("error while initializing config file \"" + formatPath(file) + "\"", e); + } + + private void logConfigSaveException(Path file, ConfigException e) { + Log.severe("error while saving config file \"" + formatPath(file) + "\"", e); + } + + private String formatPath(Path path) { + return ConfigErrors.formatPath(getRootDataFolder(), path); + } + +} diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/ConfigNode.java b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/ConfigNode.java deleted file mode 100644 index d255e7b0..00000000 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/ConfigNode.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) filoghost and contributors - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ -package me.filoghost.holographicdisplays.disk; - -import java.util.Arrays; - -public enum ConfigNode { - - SPACE_BETWEEN_LINES("space-between-lines", 0.02), - QUICK_EDIT_COMMANDS("quick-edit-commands", true), - IMAGES_SYMBOL("images.symbol", "[x]"), - TRANSPARENCY_SPACE("images.transparency.space", " [|] "), - TRANSPARENCY_COLOR("images.transparency.color", "&7"), - UPDATE_NOTIFICATION("update-notification", true), - BUNGEE_REFRESH_SECONDS("bungee.refresh-seconds", 3), - BUNGEE_USE_REDIS_BUNGEE("bungee.use-RedisBungee", false), - BUNGEE_USE_FULL_PINGER("bungee.pinger.enable", false), - BUNGEE_PINGER_TIMEOUT("bungee.pinger.timeout", 500), - BUNGEE_PINGER_OFFLINE_MOTD("bungee.pinger.offline-motd", "&cOffline, couldn't get the MOTD."), - BUNGEE_PINGER_ONLINE_FORMAT("bungee.pinger.status.online", "&aOnline"), - BUNGEE_PINGER_OFFLINE_FORMAT("bungee.pinger.status.offline", "&cOffline"), - BUNGEE_PINGER_TRIM_MOTD("bungee.pinger.motd-remove-leading-trailing-spaces", true), - BUNGEE_PINGER_SERVERS("bungee.pinger.servers", Arrays.asList("hub: 127.0.0.1:25565", "survival: 127.0.0.1:25566", "minigames: 127.0.0.1:25567")), - TIME_FORMAT("time.format", "H:mm"), - TIME_ZONE("time.zone", "GMT+1"), - DEBUG("debug", false); - - private final String path; - private final Object value; - - ConfigNode(String path, Object defaultValue) { - this.path = path; - value = defaultValue; - } - - public String getPath() { - return path; - } - - public Object getDefaultValue() { - return value; - } - -} diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/Configuration.java b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/Configuration.java index afa0607f..fce35f71 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/Configuration.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/Configuration.java @@ -11,213 +11,154 @@ */ package me.filoghost.holographicdisplays.disk; +import me.filoghost.fcommons.Strings; import me.filoghost.fcommons.logging.Log; import me.filoghost.holographicdisplays.common.DebugLogger; import org.bukkit.ChatColor; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.plugin.Plugin; -import java.io.File; -import java.io.IOException; import java.time.DateTimeException; import java.time.ZoneId; import java.time.format.DateTimeFormatter; -import java.util.Arrays; -import java.util.HashMap; +import java.util.ArrayList; import java.util.List; -import java.util.Map; -/** - * Just a bunch of static variables to hold the settings. - * Useful for fast access. - */ public class Configuration { public static double spaceBetweenLines; public static boolean quickEditCommands; + public static DateTimeFormatter timeFormat; + public static boolean updateNotification; + public static String imageSymbol; public static String transparencySymbol; - public static boolean updateNotification; public static ChatColor transparencyColor; - - public static DateTimeFormatter timeFormat; - + public static int bungeeRefreshSeconds; public static boolean useRedisBungee; - public static boolean pingerEnable; public static int pingerTimeout; public static String pingerOfflineMotd; public static String pingerStatusOnline; public static String pingerStatusOffline; public static boolean pingerTrimMotd; - public static Map pingerServers; - + public static List pingerServers; - public static void load(Plugin plugin) { - File configFile = new File(plugin.getDataFolder(), "config.yml"); - if (!configFile.exists()) { - plugin.getDataFolder().mkdirs(); - plugin.saveResource("config.yml", true); - } + public static void load(MainConfigModel config) { + spaceBetweenLines = config.spaceBetweenLines; + quickEditCommands = config.quickEditCommands; + timeFormat = parseTimeFormatter(config.timeFormat, config.timeZone); + updateNotification = config.updateNotification; - YamlConfiguration config = new YamlConfiguration(); - try { - config.load(configFile); - } catch (InvalidConfigurationException e) { - e.printStackTrace(); - Log.warning("The configuration is not a valid YAML file! Please check it with a tool like http://yaml-online-parser.appspot.com/"); - return; - } catch (IOException e) { - e.printStackTrace(); - Log.warning("I/O error while reading the configuration. Was the file in use?"); - return; - } catch (Exception e) { - e.printStackTrace(); - Log.warning("Unhandled exception while reading the configuration!"); - return; - } + imageSymbol = StringConverter.toReadableFormat(config.imageSymbol); + transparencySymbol = StringConverter.toReadableFormat(config.transparencySymbol); + transparencyColor = parseTransparencyColor(config.transparencyColor); - boolean needsSave = false; - - for (ConfigNode node : ConfigNode.values()) { - if (!config.isSet(node.getPath())) { - needsSave = true; - config.set(node.getPath(), node.getDefaultValue()); - } - } - - // Check the old values. - List nodesToRemove = Arrays.asList( - "vertical-spacing", - "time-format", - "bungee-refresh-seconds", - "using-RedisBungee", - "bungee-online-format", - "bungee-offline-format", - "precise-hologram-movement" - ); - - for (String oldNode : nodesToRemove) { - if (config.isSet(oldNode)) { - config.set(oldNode, null); - needsSave = true; - } - } - - - - if (needsSave) { - config.options().header(String.join("\n", - ".", - ". Read the tutorial at: http://dev.bukkit.org/bukkit-plugins/holographic-displays/", - ".", - ". Plugin created by filoghost.", - ".")); - config.options().copyHeader(true); - try { - config.save(configFile); - } catch (IOException e) { - e.printStackTrace(); - Log.warning("I/O error while saving the configuration. Was the file in use?"); - } - } - - spaceBetweenLines = config.getDouble(ConfigNode.SPACE_BETWEEN_LINES.getPath()); - quickEditCommands = config.getBoolean(ConfigNode.QUICK_EDIT_COMMANDS.getPath()); - - updateNotification = config.getBoolean(ConfigNode.UPDATE_NOTIFICATION.getPath()); - - imageSymbol = StringConverter.toReadableFormat(config.getString(ConfigNode.IMAGES_SYMBOL.getPath())); - transparencySymbol = StringConverter.toReadableFormat(config.getString(ConfigNode.TRANSPARENCY_SPACE.getPath())); - bungeeRefreshSeconds = config.getInt(ConfigNode.BUNGEE_REFRESH_SECONDS.getPath()); - useRedisBungee = config.getBoolean(ConfigNode.BUNGEE_USE_REDIS_BUNGEE.getPath()); - - pingerEnable = config.getBoolean(ConfigNode.BUNGEE_USE_FULL_PINGER.getPath()); - pingerTimeout = config.getInt(ConfigNode.BUNGEE_PINGER_TIMEOUT.getPath()); - pingerTrimMotd = config.getBoolean(ConfigNode.BUNGEE_PINGER_TRIM_MOTD.getPath()); - - pingerOfflineMotd = StringConverter.toReadableFormat(config.getString(ConfigNode.BUNGEE_PINGER_OFFLINE_MOTD.getPath())); - pingerStatusOnline = StringConverter.toReadableFormat(config.getString(ConfigNode.BUNGEE_PINGER_ONLINE_FORMAT.getPath())); - pingerStatusOffline = StringConverter.toReadableFormat(config.getString(ConfigNode.BUNGEE_PINGER_OFFLINE_FORMAT.getPath())); - - if (pingerTimeout <= 0) { - pingerTimeout = 100; - } else if (pingerTimeout >= 10000) { - pingerTimeout = 10000; - } - - pingerServers = new HashMap<>(); + bungeeRefreshSeconds = parseBungeeRefreshInterval(config.bungeeRefreshSeconds); + useRedisBungee = config.useRedisBungee; + pingerEnable = config.pingerEnable; + pingerTimeout = parsePingerTimeout(config.pingerTimeout); + pingerOfflineMotd = StringConverter.toReadableFormat(config.pingerOfflineMotd); + pingerStatusOnline = StringConverter.toReadableFormat(config.pingerStatusOnline); + pingerStatusOffline = StringConverter.toReadableFormat(config.pingerStatusOffline); + pingerTrimMotd = config.pingerTrimMotd; + pingerServers = new ArrayList<>(); if (pingerEnable) { - for (String singleServer : config.getStringList(ConfigNode.BUNGEE_PINGER_SERVERS.getPath())) { - String[] nameAndAddress = singleServer.split(":", 2); - if (nameAndAddress.length < 2) { - Log.warning("The server info \"" + singleServer + "\" is not valid. There should be a name and an address, separated by a colon."); - continue; + for (String singleServer : config.pingerServers) { + ServerAddress serverAddress = parseServerAddress(singleServer); + if (serverAddress != null) { + pingerServers.add(serverAddress); } - - String name = nameAndAddress[0].trim(); - String address = nameAndAddress[1].replace(" ", ""); - - String ip; - int port; - - if (address.contains(":")) { - String[] ipAndPort = address.split(":", 2); - ip = ipAndPort[0]; - try { - port = Integer.parseInt(ipAndPort[1]); - } catch (NumberFormatException e) { - Log.warning("Invalid port number in the server info \"" + singleServer + "\"."); - continue; - } - } else { - ip = address; - port = 25565; // The default Minecraft port. - } - - pingerServers.put(name, new ServerAddress(ip, port)); } } - - DebugLogger.setDebugEnabled(config.getBoolean(ConfigNode.DEBUG.getPath())); - - String tempColor = config.getString(ConfigNode.TRANSPARENCY_COLOR.getPath()).replace('&', ChatColor.COLOR_CHAR); - boolean foundColor = false; - for (ChatColor chatColor : ChatColor.values()) { - if (chatColor.toString().equals(tempColor)) { - Configuration.transparencyColor = chatColor; - foundColor = true; - } - } - if (!foundColor) { - Configuration.transparencyColor = ChatColor.GRAY; - Log.warning("You didn't set a valid chat color for transparency in the configuration, light gray (&7) will be used."); - } - + + DebugLogger.setDebugEnabled(config.debug); + } + + private static DateTimeFormatter parseTimeFormatter(String pattern, String timeZone) { + DateTimeFormatter timeFormat; + try { - timeFormat = DateTimeFormatter.ofPattern(config.getString(ConfigNode.TIME_FORMAT.getPath())); + timeFormat = DateTimeFormatter.ofPattern(pattern); } catch (IllegalArgumentException ex) { timeFormat = DateTimeFormatter.ofPattern("H:mm"); Log.warning("Time format not valid in the configuration, using the default."); } - + try { - timeFormat = timeFormat.withZone(ZoneId.of(config.getString(ConfigNode.TIME_ZONE.getPath()))); + timeFormat = timeFormat.withZone(ZoneId.of(timeZone)); } catch (DateTimeException e) { Log.warning("Time zone not valid in the configuration, using the default."); } - - if (bungeeRefreshSeconds < 1) { - Log.warning("The minimum interval for pinging BungeeCord's servers is 1 second. It has been automatically set."); - bungeeRefreshSeconds = 1; + + return timeFormat; + } + + private static ChatColor parseTransparencyColor(String transparencyColor) { + transparencyColor = transparencyColor.replace('&', ChatColor.COLOR_CHAR); + + for (ChatColor chatColor : ChatColor.values()) { + if (chatColor.toString().equals(transparencyColor)) { + return chatColor; + } } - - if (bungeeRefreshSeconds > 60) { + + Log.warning("You didn't set a valid chat color for transparency in the configuration, light gray (&7) will be used."); + return ChatColor.GRAY; + } + + private static int parseBungeeRefreshInterval(int interval) { + if (interval < 1) { + Log.warning("The minimum interval for pinging BungeeCord's servers is 1 second. It has been automatically set."); + return 1; + } else if (interval > 60) { Log.warning("The maximum interval for pinging BungeeCord's servers is 60 seconds. It has been automatically set."); - bungeeRefreshSeconds = 60; + return 60; + } else { + return interval; } } + + private static int parsePingerTimeout(int timeout) { + if (timeout < 100) { + Log.warning("The minimum timeout for pinging BungeeCord's servers is 100 milliseconds. It has been automatically set."); + return 100; + } else if (timeout > 10000) { + Log.warning("The maximum timeout for pinging BungeeCord's servers is 10000 milliseconds. It has been automatically set."); + return 10000; + } else { + return timeout; + } + } + + private static ServerAddress parseServerAddress(String singleServer) { + String[] nameAndAddress = Strings.splitAndTrim(singleServer, ":", 2); + if (nameAndAddress.length < 2) { + Log.warning("The server info \"" + singleServer + "\" is not valid. There should be a name and an address, separated by a colon."); + return null; + } + + String name = nameAndAddress[0]; + String address = nameAndAddress[1]; + + String ip; + int port; + + if (address.contains(":")) { + String[] ipAndPort = Strings.splitAndTrim(address, ":", 2); + ip = ipAndPort[0]; + try { + port = Integer.parseInt(ipAndPort[1]); + } catch (NumberFormatException e) { + Log.warning("Invalid port number in the server info \"" + singleServer + "\"."); + return null; + } + } else { + ip = address; + port = 25565; // The default Minecraft port. + } + + return new ServerAddress(name, ip, port); + } + } diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/CustomPlaceholders.java b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/CustomPlaceholders.java new file mode 100644 index 00000000..0af66201 --- /dev/null +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/CustomPlaceholders.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) filoghost and contributors + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ +package me.filoghost.holographicdisplays.disk; + +import me.filoghost.fcommons.Colors; +import me.filoghost.fcommons.config.ConfigSection; +import me.filoghost.fcommons.config.FileConfig; +import me.filoghost.fcommons.logging.Log; + +import java.util.ArrayList; +import java.util.List; + +public class CustomPlaceholders { + + private static final List placeholders = new ArrayList<>(); + + public static void load(FileConfig config) { + placeholders.clear(); + + ConfigSection placeholdersSection = config.getConfigSection("placeholders"); + if (placeholdersSection == null) { + return; + } + + for (String placeholder : placeholdersSection.getKeys()) { + String replacement = Colors.addColors(placeholdersSection.getString(placeholder)); + if (replacement == null) { + return; + } + + if (placeholder.length() == 0) { + Log.warning("Error in \"" + config.getSourceFile() + "\": placeholder cannot be empty (skipped)."); + continue; + } + + if (placeholder.length() > 100) { + Log.warning("Error in \"" + config.getSourceFile() + "\": placeholder cannot be longer than 100 character (" + placeholder + ")."); + continue; + } + + placeholders.add(new StaticPlaceholder(placeholder, replacement)); + } + } + + public static String replaceStaticPlaceholders(String text) { + for (StaticPlaceholder staticPlaceholder : placeholders) { + text = text.replace(staticPlaceholder.getIdentifier(), staticPlaceholder.getReplacement()); + } + return text; + } + +} diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramConfig.java b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramConfig.java new file mode 100644 index 00000000..a0c20efa --- /dev/null +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramConfig.java @@ -0,0 +1,117 @@ +/* + * Copyright (C) filoghost and contributors + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ +package me.filoghost.holographicdisplays.disk; + +import me.filoghost.fcommons.Strings; +import me.filoghost.fcommons.config.ConfigSection; +import me.filoghost.holographicdisplays.object.NamedHologram; +import me.filoghost.holographicdisplays.object.line.CraftHologramLine; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +public class HologramConfig { + + private static final DecimalFormat LOCATION_NUMBER_FORMAT + = new DecimalFormat("0.000", DecimalFormatSymbols.getInstance(Locale.ROOT)); + + private final String name; + private final List serializedLines; + private final String serializedLocation; + + public HologramConfig(String name, ConfigSection configSection) { + this.name = name; + this.serializedLines = configSection.getStringList("lines"); + this.serializedLocation = configSection.getString("location"); + } + + public HologramConfig(NamedHologram hologram) { + this.name = hologram.getName(); + this.serializedLines = new ArrayList<>(); + for (CraftHologramLine line : hologram.getLinesUnsafe()) { + serializedLines.add(line.getSerializedConfigValue()); + } + + this.serializedLocation = serializeLocation(hologram.getLocation()); + } + + public ConfigSection toConfigSection() { + ConfigSection configSection = new ConfigSection(); + configSection.setStringList("lines", serializedLines); + configSection.setString("location", serializedLocation); + return configSection; + } + + public NamedHologram createHologram() throws HologramLoadException { + if (serializedLines == null || serializedLines.size() == 0) { + throw new HologramLoadException("hologram \"" + name + "\" was found, but it contained no lines"); + } + if (serializedLocation == null) { + throw new HologramLoadException("hologram \"" + name + "\" doesn't have a location set"); + } + + Location location = deserializeLocation(serializedLocation); + NamedHologram hologram = new NamedHologram(location, name); + + for (String serializedLine : serializedLines) { + try { + CraftHologramLine line = HologramLineParser.parseLine(hologram, serializedLine, false); + hologram.getLinesUnsafe().add(line); + } catch (HologramLoadException e) { + // Rethrow with more details + throw new HologramLoadException("hologram \"" + hologram.getName() + "\" has an invalid line: " + e.getMessage(), e); + } + } + + return hologram; + } + + private String serializeLocation(Location loc) { + return loc.getWorld().getName() + + ", " + LOCATION_NUMBER_FORMAT.format(loc.getX()) + + ", " + LOCATION_NUMBER_FORMAT.format(loc.getY()) + + ", " + LOCATION_NUMBER_FORMAT.format(loc.getZ()); + } + + private Location deserializeLocation(String serializedLocation) throws HologramLoadException { + String[] parts = Strings.splitAndTrim(serializedLocation, ","); + + if (parts.length != 4) { + throw new HologramLoadException("hologram \"" + name + "\" has an invalid location format:" + + " it must be \"world, x, y, z\""); + } + + try { + String worldName = parts[0]; + double x = Double.parseDouble(parts[1]); + double y = Double.parseDouble(parts[2]); + double z = Double.parseDouble(parts[3]); + + World world = Bukkit.getWorld(worldName); + if (world == null) { + throw new HologramLoadException("hologram \"" + name + "\"" + + " was in the world \"" + worldName + "\" but it wasn't loaded"); + } + + return new Location(world, x, y, z); + + } catch (NumberFormatException ex) { + throw new HologramLoadException("hologram \"" + name + "\"" + + " has an invalid location format: invalid number"); + } + } + + public String getName() { + return name; + } + +} diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramDatabase.java b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramDatabase.java index 0bdf66e5..438c9f2d 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramDatabase.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramDatabase.java @@ -5,108 +5,64 @@ */ package me.filoghost.holographicdisplays.disk; -import me.filoghost.fcommons.logging.Log; +import me.filoghost.fcommons.config.Config; +import me.filoghost.fcommons.config.ConfigSection; import me.filoghost.holographicdisplays.object.NamedHologram; -import me.filoghost.holographicdisplays.object.line.CraftHologramLine; -import org.bukkit.Location; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.plugin.Plugin; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map.Entry; public class HologramDatabase { - - private static File file; - private static FileConfiguration config; - - public static void loadYamlFile(Plugin plugin) { - file = new File(plugin.getDataFolder(), "database.yml"); - - if (!file.exists()) { - plugin.getDataFolder().mkdirs(); - plugin.saveResource("database.yml", true); - } - - config = YamlConfiguration.loadConfiguration(file); - } - - public static NamedHologram loadHologram(String name) throws HologramNotFoundException, LocationFormatException, LocationWorldNotLoadedException, HologramLineParseException { - ConfigurationSection configSection = config.getConfigurationSection(name); - - if (configSection == null) { - throw new HologramNotFoundException("hologram \"" + name + "\" not found, skipping it"); - } - - List lines = configSection.getStringList("lines"); - String locationString = configSection.getString("location"); - - if (lines == null || locationString == null || lines.size() == 0) { - throw new HologramNotFoundException("hologram \"" + name + "\" was found, but it contained no lines"); - } - - Location loc = LocationSerializer.locationFromString(name, locationString); - - NamedHologram hologram = new NamedHologram(loc, name); - for (String line : lines) { - try { - hologram.getLinesUnsafe().add(HologramLineParser.parseLine(hologram, line, false)); - } catch (HologramLineParseException e) { - throw new HologramLineParseException("hologram \"" + hologram.getName() + "\" has an invalid line: " + e.getMessage(), e.getCause()); + private final LinkedHashMap hologramConfigs; + + public HologramDatabase() { + this.hologramConfigs = new LinkedHashMap<>(); + } + + public void reloadFromConfig(Config config) { + hologramConfigs.clear(); + + for (String hologramName : config.getKeys()) { + ConfigSection hologramSection = config.getConfigSection(hologramName); + if (hologramSection == null) { + continue; } + + HologramConfig hologramConfig = new HologramConfig(hologramName, hologramSection); + hologramConfigs.put(hologramConfig.getName(), hologramConfig); } + } + + public Config saveToConfig() { + Config config = new Config(); + + for (Entry entry : hologramConfigs.entrySet()) { + config.setConfigSection(entry.getKey(), entry.getValue().toConfigSection()); + } + + config.setHeader( + "", + "Please do NOT edit this file manually if possible.", + "" + ); - return hologram; + return config; + } + + public Collection getHolograms() { + return hologramConfigs.values(); } - public static String serializeHologramLine(CraftHologramLine line) { - return line.getSerializedConfigValue(); - } - - public static void deleteHologram(String name) { - config.set(name, null); - } - - public static void saveHologram(NamedHologram hologram) { - List serializedLines = new ArrayList<>(); - for (CraftHologramLine line : hologram.getLinesUnsafe()) { - serializedLines.add(serializeHologramLine(line)); - } + public void addOrUpdate(NamedHologram hologram) { + HologramConfig hologramConfig = new HologramConfig(hologram); - ConfigurationSection hologramSection = getOrCreateSection(hologram.getName()); - hologramSection.set("location", LocationSerializer.locationToString(hologram.getLocation())); - hologramSection.set("lines", serializedLines); + hologramConfigs.put(hologram.getName(), hologramConfig); } - - public static Set getHolograms() { - return config.getKeys(false); - } - - private static ConfigurationSection getOrCreateSection(String name) { - if (config.isConfigurationSection(name)) { - return config.getConfigurationSection(name); - } else { - return config.createSection(name); - } - } - - public static void saveToDisk() throws IOException { - if (config != null && file != null) { - config.save(file); - } - } - - public static void trySaveToDisk() { - try { - saveToDisk(); - } catch (IOException ex) { - Log.severe("Unable to save database.yml to disk!", ex); - } + + public void removeHologram(NamedHologram hologram) { + hologramConfigs.remove(hologram.getName()); } + } diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramLineParseException.java b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramLineParseException.java deleted file mode 100644 index 864a273b..00000000 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramLineParseException.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (C) filoghost and contributors - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ -package me.filoghost.holographicdisplays.disk; - -public class HologramLineParseException extends HologramLoadException { - - public HologramLineParseException(String message) { - super(message); - } - - public HologramLineParseException(String message, Throwable cause) { - super(message, cause); - } - -} diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramLineParser.java b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramLineParser.java index 777c97ef..40bdeada 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramLineParser.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramLineParser.java @@ -18,13 +18,14 @@ import org.bukkit.Material; import org.bukkit.inventory.ItemStack; public class HologramLineParser { - - - public static CraftHologramLine parseLine(NamedHologram hologram, String serializedLine, boolean checkMaterialValidity) throws HologramLineParseException { + + private static final String ICON_PREFIX = "icon:"; + + public static CraftHologramLine parseLine(NamedHologram hologram, String serializedLine, boolean checkMaterialValidity) throws HologramLoadException { CraftHologramLine hologramLine; - if (serializedLine.toLowerCase().startsWith("icon:")) { - String serializedIcon = serializedLine.substring("icon:".length()); + if (serializedLine.toLowerCase().startsWith(ICON_PREFIX)) { + String serializedIcon = serializedLine.substring(ICON_PREFIX.length()); ItemStack icon = parseItemStack(serializedIcon, checkMaterialValidity); hologramLine = new CraftItemLine(hologram, icon); @@ -42,7 +43,7 @@ public class HologramLineParser { @SuppressWarnings("deprecation") - private static ItemStack parseItemStack(String serializedItem, boolean checkMaterialValidity) throws HologramLineParseException { + private static ItemStack parseItemStack(String serializedItem, boolean checkMaterialValidity) throws HologramLoadException { serializedItem = serializedItem.trim(); // Parse json @@ -69,7 +70,7 @@ public class HologramLineParser { try { dataValue = (short) Integer.parseInt(materialAndDataValue[1]); } catch (NumberFormatException e) { - throw new HologramLineParseException("data value \"" + materialAndDataValue[1] + "\" is not a valid number"); + throw new HologramLoadException("data value \"" + materialAndDataValue[1] + "\" is not a valid number"); } materialName = materialAndDataValue[0]; } else { @@ -79,7 +80,7 @@ public class HologramLineParser { Material material = MaterialsHelper.matchMaterial(materialName); if (material == null) { if (checkMaterialValidity) { - throw new HologramLineParseException("\"" + materialName + "\" is not a valid material"); + throw new HologramLoadException("\"" + materialName + "\" is not a valid material"); } material = Material.BEDROCK; } @@ -92,9 +93,9 @@ public class HologramLineParser { MojangsonParser.parse(nbtString); Bukkit.getUnsafe().modifyItemStack(itemStack, nbtString); } catch (MojangsonParseException e) { - throw new HologramLineParseException("invalid NBT data, " + e.getMessage()); + throw new HologramLoadException("invalid NBT data, " + e.getMessage()); } catch (Throwable t) { - throw new HologramLineParseException("unexpected exception while parsing NBT data", t); + throw new HologramLoadException("unexpected exception while parsing NBT data", t); } } diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramNotFoundException.java b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramNotFoundException.java deleted file mode 100644 index b54a04d3..00000000 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/HologramNotFoundException.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) filoghost and contributors - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ -package me.filoghost.holographicdisplays.disk; - -public class HologramNotFoundException extends HologramLoadException { - - public HologramNotFoundException(String message) { - super(message); - } - -} diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/LocationFormatException.java b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/LocationFormatException.java deleted file mode 100644 index 072d3714..00000000 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/LocationFormatException.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) filoghost and contributors - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ -package me.filoghost.holographicdisplays.disk; - -public class LocationFormatException extends HologramLoadException { - - public LocationFormatException(String message) { - super(message); - } - -} diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/LocationSerializer.java b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/LocationSerializer.java deleted file mode 100644 index 2c9ba861..00000000 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/LocationSerializer.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) filoghost and contributors - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ -package me.filoghost.holographicdisplays.disk; - -import me.filoghost.fcommons.Strings; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.World; - -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.util.Locale; - -public class LocationSerializer { - - private static DecimalFormat numberFormat = new DecimalFormat("0.000", DecimalFormatSymbols.getInstance(Locale.ROOT)); - - public static Location locationFromString(String hologramName, String serializedLocation) throws LocationWorldNotLoadedException, LocationFormatException { - if (serializedLocation == null) { - throw new LocationFormatException("hologram \"" + hologramName + "\" doesn't have a location set"); - } - - String[] parts = Strings.splitAndTrim(serializedLocation, ","); - - if (parts.length != 4) { - throw new LocationFormatException("hologram \"" + hologramName + "\" has an invalid location format:" - + " it must be \"world, x, y, z\""); - } - - try { - String worldName = parts[0]; - double x = Double.parseDouble(parts[1]); - double y = Double.parseDouble(parts[2]); - double z = Double.parseDouble(parts[3]); - - World world = Bukkit.getWorld(worldName); - if (world == null) { - throw new LocationWorldNotLoadedException("hologram \"" + hologramName + "\"" - + " was in the world \"" + worldName + "\" but it wasn't loaded"); - } - - return new Location(world, x, y, z); - - } catch (NumberFormatException ex) { - throw new LocationFormatException("hologram \"" + hologramName + "\"" - + " has an invalid location format: invalid number"); - } - } - - public static String locationToString(Location loc) { - return (loc.getWorld().getName() + ", " + numberFormat.format(loc.getX()) + ", " + numberFormat.format(loc.getY()) + ", " + numberFormat.format(loc.getZ())); - } -} diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/LocationWorldNotLoadedException.java b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/LocationWorldNotLoadedException.java deleted file mode 100644 index c6877d72..00000000 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/LocationWorldNotLoadedException.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (C) filoghost and contributors - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ -package me.filoghost.holographicdisplays.disk; - -public class LocationWorldNotLoadedException extends HologramLoadException { - - public LocationWorldNotLoadedException(String message) { - super(message); - } - -} diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/MainConfigModel.java b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/MainConfigModel.java new file mode 100644 index 00000000..307b110e --- /dev/null +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/MainConfigModel.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) filoghost and contributors + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ +package me.filoghost.holographicdisplays.disk; + +import me.filoghost.fcommons.config.Config; +import me.filoghost.fcommons.config.mapped.ConfigPath; +import me.filoghost.fcommons.config.mapped.MappedConfig; + +import java.util.Arrays; +import java.util.List; + +public class MainConfigModel implements MappedConfig { + + @ConfigPath("space-between-lines") + double spaceBetweenLines = 0.02; + + @ConfigPath("quick-edit-commands") + boolean quickEditCommands = true; + + @ConfigPath("images.symbol") + String imageSymbol = "[x]"; + + @ConfigPath("images.transparency.space") + String transparencySymbol = " [|] "; + + @ConfigPath("images.transparency.color") + String transparencyColor = "&7"; + + @ConfigPath("bungee.refresh-seconds") + int bungeeRefreshSeconds = 3; + + @ConfigPath("bungee.use-RedisBungee") + boolean useRedisBungee = false; + + @ConfigPath("bungee.pinger.enable") + boolean pingerEnable = false; + + @ConfigPath("bungee.pinger.timeout") + int pingerTimeout = 500; + + @ConfigPath("bungee.pinger.offline-motd") + String pingerOfflineMotd = "&cOffline, couldn't get the MOTD"; + + @ConfigPath("bungee.pinger.status.online") + String pingerStatusOnline = "&aOnline"; + + @ConfigPath("bungee.pinger.status.offline") + String pingerStatusOffline = "&cOffline"; + + @ConfigPath("bungee.pinger.motd-remove-leading-trailing-spaces") + boolean pingerTrimMotd = true; + + @ConfigPath("bungee.pinger.servers") + List pingerServers = Arrays.asList("hub: 127.0.0.1:25565", "games: 127.0.0.1:25566"); + + @ConfigPath("time.format") + String timeFormat = "H:mm"; + + @ConfigPath("time.zone") + String timeZone = "GMT+1"; + + @ConfigPath("update-notification") + boolean updateNotification = true; + + @ConfigPath("debug") + boolean debug = false; + + @Override + public List getHeader() { + return Arrays.asList( + "", + "Plugin page: https://dev.bukkit.org/projects/holographic-displays", + "", + "Created by filoghost.", + "" + ); + } + + @Override + public boolean beforeSave(Config rawConfig) { + List pathsToRemove = Arrays.asList( + "vertical-spacing", + "time-format", + "bungee-refresh-seconds", + "using-RedisBungee", + "bungee-online-format", + "bungee-offline-format", + "precise-hologram-movement" + ); + + boolean modified = false; + + for (String path : pathsToRemove) { + if (rawConfig.get(path) != null) { + rawConfig.remove(path); + modified = true; + } + } + + return modified; + } + +} diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/ServerAddress.java b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/ServerAddress.java index 77248359..b8282f31 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/ServerAddress.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/ServerAddress.java @@ -7,14 +7,20 @@ package me.filoghost.holographicdisplays.disk; public class ServerAddress { + private String name; private String ip; private int port; - public ServerAddress(String ip, int port) { + public ServerAddress(String name, String ip, int port) { + this.name = name; this.ip = ip; this.port = port; } + public String getName() { + return name; + } + public String getAddress() { return ip; } @@ -22,10 +28,10 @@ public class ServerAddress { public int getPort() { return port; } - + @Override public String toString() { - return ip + ":" + port; + return name + " (" + ip + ":" + port + ")"; } } diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/StaticPlaceholder.java b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/StaticPlaceholder.java new file mode 100644 index 00000000..79545bb5 --- /dev/null +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/StaticPlaceholder.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) filoghost and contributors + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ +package me.filoghost.holographicdisplays.disk; + +public class StaticPlaceholder { + + private final String identifier; + private final String replacement; + + public StaticPlaceholder(String identifier, String replacement) { + this.identifier = identifier; + this.replacement = replacement; + } + + public String getIdentifier() { + return identifier; + } + + public String getReplacement() { + return replacement; + } + +} diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/StringConverter.java b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/StringConverter.java index 25e13ec7..e822aa3a 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/StringConverter.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/StringConverter.java @@ -20,7 +20,7 @@ public class StringConverter { return null; } - input = UnicodeSymbols.placeholdersToSymbols(input); + input = CustomPlaceholders.replaceStaticPlaceholders(input); input = Colors.addColors(input); return input; } diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/UnicodeSymbols.java b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/UnicodeSymbols.java deleted file mode 100644 index cabfdd51..00000000 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/UnicodeSymbols.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) filoghost and contributors - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -/* - * Copyright (C) filoghost and contributors - * - * SPDX-License-Identifier: GPL-3.0-or-later - */ -package me.filoghost.holographicdisplays.disk; - -import me.filoghost.fcommons.logging.Log; -import me.filoghost.holographicdisplays.HolographicDisplays; -import org.apache.commons.lang.StringEscapeUtils; -import org.bukkit.plugin.Plugin; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -public class UnicodeSymbols { - - private static Map placeholders = new HashMap<>(); - - public static void load(Plugin plugin) { - placeholders.clear(); - - Path file = HolographicDisplays.getDataFolderPath().resolve("symbols.yml"); - - if (!Files.isRegularFile(file)) { - plugin.saveResource("symbols.yml", true); - } - - List lines; - try { - lines = Files.readAllLines(file); - } catch (IOException e) { - Log.warning("I/O error while reading symbols.yml. Was the file in use?", e); - return; - } catch (Exception e) { - Log.warning("Unhandled exception while reading symbols.yml!", e); - return; - } - - for (String line : lines) { - - // Comment or empty line. - if (line.length() == 0 || line.startsWith("#")) { - continue; - } - - if (!line.contains(":")) { - Log.warning("Unable to parse a line(" + line + ") from symbols.yml: it must contain ':' to separate the placeholder and the replacement."); - continue; - } - - int indexOf = line.indexOf(':'); - String placeholder = unquote(line.substring(0, indexOf).trim()); - String replacement = StringEscapeUtils.unescapeJava(unquote(line.substring(indexOf + 1).trim())); - - if (placeholder.isEmpty() || replacement.isEmpty()) { - Log.warning("Unable to parse a line(" + line + ") from symbols.yml: the placeholder and the replacement must have both at least 1 character."); - continue; - } - - if (placeholder.length() > 30) { - Log.warning("Unable to parse a line(" + line + ") from symbols.yml: the placeholder cannot be longer than 30 characters."); - continue; - } - - placeholders.put(placeholder, replacement); - } - } - - - protected static String placeholdersToSymbols(String input) { - for (Entry entry : placeholders.entrySet()) { - input = input.replace(entry.getKey(), entry.getValue()); - } - return input; - } - - - private static String unquote(String input) { - if (input.length() < 2) { - // Cannot be quoted. - return input; - } - if (input.startsWith("'") && input.endsWith("'")) { - return input.substring(1, input.length() - 1); - } else if (input.startsWith("\"") && input.endsWith("\"")) { - return input.substring(1, input.length() - 1); - } - - return input; - } -} diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/disk/upgrade/LegacySymbolsUpgrader.java b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/upgrade/LegacySymbolsUpgrader.java new file mode 100644 index 00000000..37ce629d --- /dev/null +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/disk/upgrade/LegacySymbolsUpgrader.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) filoghost and contributors + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ +package me.filoghost.holographicdisplays.disk.upgrade; + +import me.filoghost.fcommons.Strings; +import me.filoghost.fcommons.config.Config; +import me.filoghost.fcommons.config.ConfigErrors; +import me.filoghost.fcommons.config.ConfigLoader; +import me.filoghost.fcommons.config.exception.ConfigLoadException; +import me.filoghost.fcommons.config.exception.ConfigSaveException; +import me.filoghost.fcommons.logging.Log; +import me.filoghost.holographicdisplays.disk.ConfigManager; +import org.apache.commons.lang.StringEscapeUtils; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +public class LegacySymbolsUpgrader { + + public static void run(ConfigManager configManager) throws ConfigLoadException, ConfigSaveException { + Path oldFile = configManager.getRootDataFolder().resolve("symbols.yml"); + ConfigLoader newConfigLoader = configManager.getConfigLoader("custom-placeholders.yml"); + Path newFile = newConfigLoader.getFile(); + + if (!Files.isRegularFile(oldFile)) { + return; // Old file doesn't exist, ignore upgrade + } + + if (Files.isRegularFile(newFile)) { + return; // Already created, do not override + } + + Config newConfig = new Config(); + List lines; + try { + lines = Files.readAllLines(oldFile); + } catch (IOException e) { + throw new ConfigLoadException(ConfigErrors.readIOException, e); + } + + for (String line : lines) { + // Comment or empty line + if (line.isEmpty() || line.startsWith("#")) { + continue; + } + + // Ignore bad line + if (!line.contains(":")) { + Log.warning("Couldn't convert invalid line in " + oldFile.getFileName() + ": " + line); + continue; + } + + String[] parts = Strings.splitAndTrim(line, ":", 2); + String placeholder = unquote(parts[0]); + String replacement = StringEscapeUtils.unescapeJava(unquote(parts[1])); + + newConfig.setString("placeholders." + placeholder, replacement); + } + + try { + Files.move(oldFile, oldFile.resolveSibling("symbols.yml.backup")); + } catch (IOException e) { + Log.warning("Couldn't rename " + oldFile.getFileName(), e); + } + newConfigLoader.save(newConfig); + } + + private static String unquote(String input) { + if (input.length() < 2) { + // Too short, cannot be a quoted string + return input; + } + if (input.startsWith("'") && input.endsWith("'")) { + return input.substring(1, input.length() - 1); + } else if (input.startsWith("\"") && input.endsWith("\"")) { + return input.substring(1, input.length() - 1); + } + + return input; + } + +} diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/task/StartupLoadHologramsTask.java b/plugin/src/main/java/me/filoghost/holographicdisplays/task/StartupLoadHologramsTask.java index 503cb8f6..55e6328d 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/task/StartupLoadHologramsTask.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/task/StartupLoadHologramsTask.java @@ -7,30 +7,33 @@ package me.filoghost.holographicdisplays.task; import me.filoghost.fcommons.logging.Log; import me.filoghost.holographicdisplays.common.Utils; -import me.filoghost.holographicdisplays.disk.HologramDatabase; +import me.filoghost.holographicdisplays.disk.HologramConfig; import me.filoghost.holographicdisplays.disk.HologramLoadException; import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.NamedHologramManager; -import java.util.Set; +import java.util.Collection; public class StartupLoadHologramsTask implements Runnable { + private Collection hologramConfigsToLoad; + + public StartupLoadHologramsTask(Collection hologramConfigsToLoad) { + this.hologramConfigsToLoad = hologramConfigsToLoad; + } + @Override public void run() { - Set savedHologramsNames = HologramDatabase.getHolograms(); - if (savedHologramsNames != null) { - for (String hologramName : savedHologramsNames) { - try { - NamedHologram namedHologram = HologramDatabase.loadHologram(hologramName); - NamedHologramManager.addHologram(namedHologram); - namedHologram.refreshAll(); - } catch (HologramLoadException e) { - Log.warning(Utils.formatExceptionMessage(e)); - } catch (Exception e) { - Log.warning("Unexpected exception while loading the hologram \"" + hologramName + "\"." - + " Please contact the developer.", e); - } + for (HologramConfig hologramConfig : hologramConfigsToLoad) { + try { + NamedHologram hologram = hologramConfig.createHologram(); + NamedHologramManager.addHologram(hologram); + hologram.refreshAll(); + } catch (HologramLoadException e) { + Log.warning(Utils.formatExceptionMessage(e)); + } catch (Exception e) { + Log.warning("Unexpected exception while loading the hologram \"" + hologramConfig.getName() + "\"." + + " Please contact the developer.", e); } } } diff --git a/plugin/src/main/resources/config.yml b/plugin/src/main/resources/config.yml deleted file mode 100644 index 3f0adef6..00000000 --- a/plugin/src/main/resources/config.yml +++ /dev/null @@ -1,20 +0,0 @@ -#. -#. Read the tutorial at: http://dev.bukkit.org/bukkit-plugins/holographic-displays/ -#. -#. Plugin created by filoghost. -#. -space-between-lines: 0.02 -quick-edit-commands: true -images: - symbol: '[x]' - transparency: - space: ' [|] ' - color: '&7' -bungee: - refresh-seconds: 3 - use-RedisBungee: false -time: - format: H:mm - zone: GMT+1 -update-notification: true -debug: false \ No newline at end of file diff --git a/plugin/src/main/resources/custom-placeholders.yml b/plugin/src/main/resources/custom-placeholders.yml new file mode 100644 index 00000000..bda1bcad --- /dev/null +++ b/plugin/src/main/resources/custom-placeholders.yml @@ -0,0 +1,14 @@ +# +# This is the configuration file for custom placeholders. +# Dynamic placeholders are {online}, {max_players}... +# +# You can use these to avoid repeating text multiple times, +# and edit it from a single location. +# +# Another use would be for defining colors, symbols, or text decorations. +# +placeholders: + '{custom_placeholder}': 'This is a custom placeholder.' + '{primary_color}': '&b' + '{secondary_color}': '&7' + '{separator}': '&8&m ' diff --git a/plugin/src/main/resources/database.yml b/plugin/src/main/resources/database.yml deleted file mode 100644 index a115210e..00000000 --- a/plugin/src/main/resources/database.yml +++ /dev/null @@ -1,3 +0,0 @@ -#. -#. Please do NOT edit this file manually. -#. \ No newline at end of file diff --git a/plugin/src/main/resources/symbols.yml b/plugin/src/main/resources/symbols.yml deleted file mode 100644 index d54ca8c1..00000000 --- a/plugin/src/main/resources/symbols.yml +++ /dev/null @@ -1,14 +0,0 @@ -# -# This is the configuration file for static placeholders. -# Dynamic placeholders are {online}, {max_players}, ... -# Static placeholders are symbols. -# -# List of unicode symbols: http://www.fileformat.info/info/unicode/index.htm -# -[x]: \u2588 -[/]: \u258C -[.]: \u2591 -[..]: \u2592 -[...]: \u2593 -[p]: \u2022 -[|]: \u23B9 \ No newline at end of file