Configuration refactoring, convert symbols.yml to custom-placeholders.yml

This commit is contained in:
filoghost 2021-02-19 21:37:56 +01:00
parent 40e1967d20
commit acd83a6fe6
40 changed files with 845 additions and 687 deletions

View File

@ -6,6 +6,7 @@
package me.filoghost.holographicdisplays; package me.filoghost.holographicdisplays;
import me.filoghost.fcommons.BaseJavaPlugin; import me.filoghost.fcommons.BaseJavaPlugin;
import me.filoghost.fcommons.config.exception.ConfigException;
import me.filoghost.fcommons.logging.Log; import me.filoghost.fcommons.logging.Log;
import me.filoghost.fcommons.reflection.ReflectUtils; import me.filoghost.fcommons.reflection.ReflectUtils;
import me.filoghost.holographicdisplays.api.internal.BackendAPI; 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.ProtocolLibHook;
import me.filoghost.holographicdisplays.bridge.protocollib.current.ProtocolLibHookImpl; import me.filoghost.holographicdisplays.bridge.protocollib.current.ProtocolLibHookImpl;
import me.filoghost.holographicdisplays.commands.HologramCommandManager; import me.filoghost.holographicdisplays.commands.HologramCommandManager;
import me.filoghost.holographicdisplays.disk.ConfigManager;
import me.filoghost.holographicdisplays.disk.Configuration; import me.filoghost.holographicdisplays.disk.Configuration;
import me.filoghost.holographicdisplays.disk.HologramDatabase; import me.filoghost.holographicdisplays.disk.upgrade.LegacySymbolsUpgrader;
import me.filoghost.holographicdisplays.disk.UnicodeSymbols;
import me.filoghost.holographicdisplays.listener.MainListener; import me.filoghost.holographicdisplays.listener.MainListener;
import me.filoghost.holographicdisplays.nms.interfaces.NMSManager; import me.filoghost.holographicdisplays.nms.interfaces.NMSManager;
import me.filoghost.holographicdisplays.object.DefaultBackendAPI; import me.filoghost.holographicdisplays.object.DefaultBackendAPI;
@ -71,12 +72,20 @@ public class HolographicDisplays extends BaseJavaPlugin {
System.setProperty("HolographicDisplaysLoaded", "true"); System.setProperty("HolographicDisplaysLoaded", "true");
instance = this; instance = this;
dataFolderPath = getDataFolder().toPath(); 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. // Load placeholders.yml.
UnicodeSymbols.load(this); configManager.reloadCustomPlaceholders();
// Load the configuration. // Load the configuration.
Configuration.load(this); configManager.reloadMainConfig();
if (Configuration.updateNotification) { if (Configuration.updateNotification) {
UpdateChecker.run(this, 75097, (String newVersion) -> { UpdateChecker.run(this, 75097, (String newVersion) -> {
@ -119,7 +128,7 @@ public class HolographicDisplays extends BaseJavaPlugin {
} }
// Initialize other static classes. // Initialize other static classes.
HologramDatabase.loadYamlFile(this); configManager.reloadHologramDatabase();
BungeeServerTracker.restartTask(Configuration.bungeeRefreshSeconds); BungeeServerTracker.restartTask(Configuration.bungeeRefreshSeconds);
// Start repeating tasks. // Start repeating tasks.
@ -132,7 +141,7 @@ public class HolographicDisplays extends BaseJavaPlugin {
"This can be caused by edits to plugin.yml or other plugins."); "This can be caused by edits to plugin.yml or other plugins.");
} }
commandManager = new HologramCommandManager(); commandManager = new HologramCommandManager(configManager);
commandManager.register(this); commandManager.register(this);
mainListener = new MainListener(nmsManager); mainListener = new MainListener(nmsManager);
@ -143,7 +152,8 @@ public class HolographicDisplays extends BaseJavaPlugin {
new MetricsLite(this, pluginID); new MetricsLite(this, pluginID);
// Holograms are loaded later, when the worlds are ready. // 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. // Enable the API.
BackendAPI.setImplementation(new DefaultBackendAPI()); BackendAPI.setImplementation(new DefaultBackendAPI());

View File

@ -17,7 +17,6 @@ import java.io.IOException;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
public class BungeeServerTracker { public class BungeeServerTracker {
@ -146,12 +145,12 @@ public class BungeeServerTracker {
if (Configuration.pingerEnable) { if (Configuration.pingerEnable) {
Bukkit.getScheduler().runTaskAsynchronously(HolographicDisplays.getInstance(), () -> { Bukkit.getScheduler().runTaskAsynchronously(HolographicDisplays.getInstance(), () -> {
for (Entry<String, ServerAddress> entry : Configuration.pingerServers.entrySet()) { for (ServerAddress serverAddress : Configuration.pingerServers) {
BungeeServerInfo serverInfo = getOrCreateServerInfo(entry.getKey()); BungeeServerInfo serverInfo = getOrCreateServerInfo(serverAddress.getName());
boolean displayOffline = false; boolean displayOffline = false;
try { try {
PingResponse data = ServerPinger.fetchData(entry.getValue(), Configuration.pingerTimeout); PingResponse data = ServerPinger.fetchData(serverAddress, Configuration.pingerTimeout);
if (data.isOnline()) { if (data.isOnline()) {
serverInfo.setOnline(true); serverInfo.setOnline(true);
@ -164,13 +163,13 @@ public class BungeeServerTracker {
} catch (SocketTimeoutException e) { } catch (SocketTimeoutException e) {
displayOffline = true; displayOffline = true;
} catch (UnknownHostException e) { } 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; displayOffline = true;
} catch (IOException e) { } catch (IOException e) {
displayOffline = true; displayOffline = true;
} catch (Throwable t) { } catch (Throwable t) {
displayOffline = true; 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) { if (displayOffline) {

View File

@ -31,6 +31,7 @@ import me.filoghost.holographicdisplays.commands.subs.RemovelineCommand;
import me.filoghost.holographicdisplays.commands.subs.SetlineCommand; import me.filoghost.holographicdisplays.commands.subs.SetlineCommand;
import me.filoghost.holographicdisplays.commands.subs.TeleportCommand; import me.filoghost.holographicdisplays.commands.subs.TeleportCommand;
import me.filoghost.holographicdisplays.common.Utils; import me.filoghost.holographicdisplays.common.Utils;
import me.filoghost.holographicdisplays.disk.ConfigManager;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -47,28 +48,28 @@ public class HologramCommandManager extends SubCommandManager {
private final HelpCommand helpCommand; private final HelpCommand helpCommand;
public HologramCommandManager() { public HologramCommandManager(ConfigManager configManager) {
setName("holograms"); setName("holograms");
subCommands = new ArrayList<>(); subCommands = new ArrayList<>();
subCommandsByClass = new HashMap<>(); subCommandsByClass = new HashMap<>();
registerSubCommand(new AddlineCommand()); registerSubCommand(new AddlineCommand(configManager));
registerSubCommand(new CreateCommand()); registerSubCommand(new CreateCommand(configManager));
registerSubCommand(new DeleteCommand()); registerSubCommand(new DeleteCommand(configManager));
registerSubCommand(new EditCommand()); registerSubCommand(new EditCommand());
registerSubCommand(new ListCommand()); registerSubCommand(new ListCommand());
registerSubCommand(new NearCommand()); registerSubCommand(new NearCommand());
registerSubCommand(new TeleportCommand()); registerSubCommand(new TeleportCommand());
registerSubCommand(new MovehereCommand()); registerSubCommand(new MovehereCommand(configManager));
registerSubCommand(new AlignCommand()); registerSubCommand(new AlignCommand(configManager));
registerSubCommand(new CopyCommand()); registerSubCommand(new CopyCommand(configManager));
registerSubCommand(new ReloadCommand()); registerSubCommand(new ReloadCommand(configManager));
registerSubCommand(new RemovelineCommand()); registerSubCommand(new RemovelineCommand(configManager));
registerSubCommand(new SetlineCommand()); registerSubCommand(new SetlineCommand(configManager));
registerSubCommand(new InsertlineCommand()); registerSubCommand(new InsertlineCommand(configManager));
registerSubCommand(new ReadtextCommand()); registerSubCommand(new ReadtextCommand(configManager));
registerSubCommand(new ReadimageCommand()); registerSubCommand(new ReadimageCommand(configManager));
registerSubCommand(new InfoCommand()); registerSubCommand(new InfoCommand());
registerSubCommand(new DebugCommand()); registerSubCommand(new DebugCommand());

View File

@ -10,7 +10,7 @@ import me.filoghost.fcommons.command.validation.CommandValidate;
import me.filoghost.holographicdisplays.HolographicDisplays; import me.filoghost.holographicdisplays.HolographicDisplays;
import me.filoghost.holographicdisplays.common.Utils; import me.filoghost.holographicdisplays.common.Utils;
import me.filoghost.holographicdisplays.disk.HologramLineParser; 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.NamedHologram;
import me.filoghost.holographicdisplays.object.NamedHologramManager; import me.filoghost.holographicdisplays.object.NamedHologramManager;
import me.filoghost.holographicdisplays.object.line.CraftHologramLine; 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 { public static CraftHologramLine parseHologramLine(NamedHologram hologram, String serializedLine, boolean validateMaterial) throws CommandException {
try { try {
return HologramLineParser.parseLine(hologram, serializedLine, validateMaterial); return HologramLineParser.parseLine(hologram, serializedLine, validateMaterial);
} catch (HologramLineParseException e) { } catch (HologramLoadException e) {
throw new CommandException(Utils.formatExceptionMessage(e)); throw new CommandException(Utils.formatExceptionMessage(e));
} }
} }

View File

@ -10,7 +10,7 @@ import me.filoghost.fcommons.command.validation.CommandException;
import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.Colors;
import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.HologramCommandValidate;
import me.filoghost.holographicdisplays.common.Utils; 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.event.NamedHologramEditedEvent;
import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.NamedHologram;
import me.filoghost.holographicdisplays.object.line.CraftHologramLine; import me.filoghost.holographicdisplays.object.line.CraftHologramLine;
@ -19,11 +19,15 @@ import org.bukkit.command.CommandSender;
public class AddlineCommand extends LineEditingCommand { public class AddlineCommand extends LineEditingCommand {
public AddlineCommand() { private final ConfigManager configManager;
public AddlineCommand(ConfigManager configManager) {
super("addline"); super("addline");
setMinArgs(2); setMinArgs(2);
setUsageArgs("<hologram> <text>"); setUsageArgs("<hologram> <text>");
setDescription("Adds a line to an existing hologram."); setDescription("Adds a line to an existing hologram.");
this.configManager = configManager;
} }
@Override @Override
@ -35,8 +39,8 @@ public class AddlineCommand extends LineEditingCommand {
hologram.getLinesUnsafe().add(line); hologram.getLinesUnsafe().add(line);
hologram.refreshAll(); hologram.refreshAll();
HologramDatabase.saveHologram(hologram); configManager.getHologramDatabase().addOrUpdate(hologram);
HologramDatabase.trySaveToDisk(); configManager.saveHologramDatabase();
Bukkit.getPluginManager().callEvent(new NamedHologramEditedEvent(hologram)); Bukkit.getPluginManager().callEvent(new NamedHologramEditedEvent(hologram));
sender.sendMessage(Colors.PRIMARY + "Line added!"); sender.sendMessage(Colors.PRIMARY + "Line added!");

View File

@ -11,18 +11,22 @@ import me.filoghost.fcommons.command.validation.CommandValidate;
import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.Colors;
import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.HologramCommandValidate;
import me.filoghost.holographicdisplays.commands.HologramSubCommand; 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.NamedHologram;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
public class AlignCommand extends HologramSubCommand { public class AlignCommand extends HologramSubCommand {
public AlignCommand() { private final ConfigManager configManager;
public AlignCommand(ConfigManager configManager) {
super("align"); super("align");
setMinArgs(3); setMinArgs(3);
setUsageArgs("<X | Y | Z | XZ> <hologram> <referenceHologram>"); setUsageArgs("<X | Y | Z | XZ> <hologram> <referenceHologram>");
setDescription("Aligns the first hologram to the second, in the specified axis."); setDescription("Aligns the first hologram to the second, in the specified axis.");
this.configManager = configManager;
} }
@Override @Override
@ -52,8 +56,8 @@ public class AlignCommand extends HologramSubCommand {
hologram.despawnEntities(); hologram.despawnEntities();
hologram.refreshAll(); hologram.refreshAll();
HologramDatabase.saveHologram(hologram); configManager.getHologramDatabase().addOrUpdate(hologram);
HologramDatabase.trySaveToDisk(); configManager.saveHologramDatabase();
sender.sendMessage(Colors.PRIMARY + "Hologram \"" + hologram.getName() + "\" aligned to the hologram \"" + referenceHologram.getName() + "\" on the " + axis.toUpperCase() + " axis."); sender.sendMessage(Colors.PRIMARY + "Hologram \"" + hologram.getName() + "\" aligned to the hologram \"" + referenceHologram.getName() + "\" on the " + axis.toUpperCase() + " axis.");
} }

View File

@ -10,18 +10,22 @@ import me.filoghost.fcommons.command.validation.CommandException;
import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.Colors;
import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.HologramCommandValidate;
import me.filoghost.holographicdisplays.commands.HologramSubCommand; 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.NamedHologram;
import me.filoghost.holographicdisplays.object.line.CraftHologramLine; import me.filoghost.holographicdisplays.object.line.CraftHologramLine;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
public class CopyCommand extends HologramSubCommand { public class CopyCommand extends HologramSubCommand {
public CopyCommand() { private final ConfigManager configManager;
public CopyCommand(ConfigManager configManager) {
super("copy"); super("copy");
setMinArgs(2); setMinArgs(2);
setUsageArgs("<fromHologram> <toHologram>"); setUsageArgs("<fromHologram> <toHologram>");
setDescription("Copies the contents of a hologram into another one."); setDescription("Copies the contents of a hologram into another one.");
this.configManager = configManager;
} }
@Override @Override
@ -31,14 +35,14 @@ public class CopyCommand extends HologramSubCommand {
toHologram.clearLines(); toHologram.clearLines();
for (CraftHologramLine line : fromHologram.getLinesUnsafe()) { 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.getLinesUnsafe().add(clonedLine);
} }
toHologram.refreshAll(); toHologram.refreshAll();
HologramDatabase.saveHologram(toHologram); configManager.getHologramDatabase().addOrUpdate(toHologram);
HologramDatabase.trySaveToDisk(); configManager.saveHologramDatabase();
sender.sendMessage(Colors.PRIMARY + "Hologram \"" + fromHologram.getName() + "\" copied into hologram \"" + toHologram.getName() + "\"!"); sender.sendMessage(Colors.PRIMARY + "Hologram \"" + fromHologram.getName() + "\" copied into hologram \"" + toHologram.getName() + "\"!");
} }

View File

@ -12,7 +12,7 @@ import me.filoghost.holographicdisplays.Colors;
import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.HologramCommandValidate;
import me.filoghost.holographicdisplays.commands.HologramSubCommand; import me.filoghost.holographicdisplays.commands.HologramSubCommand;
import me.filoghost.holographicdisplays.common.Utils; 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.NamedHologram;
import me.filoghost.holographicdisplays.object.NamedHologramManager; import me.filoghost.holographicdisplays.object.NamedHologramManager;
import me.filoghost.holographicdisplays.object.line.CraftHologramLine; import me.filoghost.holographicdisplays.object.line.CraftHologramLine;
@ -23,7 +23,9 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
public class CreateCommand extends HologramSubCommand { public class CreateCommand extends HologramSubCommand {
public CreateCommand() { private final ConfigManager configManager;
public CreateCommand(ConfigManager configManager) {
super("create"); super("create");
setMinArgs(1); setMinArgs(1);
setUsageArgs("<hologramName> [text]"); setUsageArgs("<hologramName> [text]");
@ -31,6 +33,8 @@ public class CreateCommand extends HologramSubCommand {
"Creates a new hologram with the given name, that must", "Creates a new hologram with the given name, that must",
"be alphanumeric. The name will be used as reference to", "be alphanumeric. The name will be used as reference to",
"that hologram for editing commands."); "that hologram for editing commands.");
this.configManager = configManager;
} }
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@ -68,8 +72,8 @@ public class CreateCommand extends HologramSubCommand {
NamedHologramManager.addHologram(hologram); NamedHologramManager.addHologram(hologram);
hologram.refreshAll(); hologram.refreshAll();
HologramDatabase.saveHologram(hologram); configManager.getHologramDatabase().addOrUpdate(hologram);
HologramDatabase.trySaveToDisk(); configManager.saveHologramDatabase();
Location look = player.getLocation(); Location look = player.getLocation();
look.setPitch(90); look.setPitch(90);
player.teleport(look, TeleportCause.PLUGIN); player.teleport(look, TeleportCause.PLUGIN);

View File

@ -10,18 +10,22 @@ import me.filoghost.fcommons.command.validation.CommandException;
import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.Colors;
import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.HologramCommandValidate;
import me.filoghost.holographicdisplays.commands.HologramSubCommand; 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.NamedHologram;
import me.filoghost.holographicdisplays.object.NamedHologramManager; import me.filoghost.holographicdisplays.object.NamedHologramManager;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
public class DeleteCommand extends HologramSubCommand { public class DeleteCommand extends HologramSubCommand {
public DeleteCommand() { private final ConfigManager configManager;
public DeleteCommand(ConfigManager configManager) {
super("delete", "remove"); super("delete", "remove");
setMinArgs(1); setMinArgs(1);
setUsageArgs("<hologram>"); setUsageArgs("<hologram>");
setDescription("Deletes a hologram. Cannot be undone."); setDescription("Deletes a hologram. Cannot be undone.");
this.configManager = configManager;
} }
@Override @Override
@ -30,9 +34,10 @@ public class DeleteCommand extends HologramSubCommand {
hologram.delete(); hologram.delete();
NamedHologramManager.removeHologram(hologram); NamedHologramManager.removeHologram(hologram);
HologramDatabase.deleteHologram(hologram.getName());
HologramDatabase.trySaveToDisk(); configManager.getHologramDatabase().removeHologram(hologram);
configManager.saveHologramDatabase();
sender.sendMessage(Colors.PRIMARY + "You deleted the hologram '" + hologram.getName() + "'."); sender.sendMessage(Colors.PRIMARY + "You deleted the hologram '" + hologram.getName() + "'.");
} }

View File

@ -10,7 +10,6 @@ import me.filoghost.fcommons.command.validation.CommandException;
import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.Colors;
import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.HologramCommandValidate;
import me.filoghost.holographicdisplays.commands.Messages; import me.filoghost.holographicdisplays.commands.Messages;
import me.filoghost.holographicdisplays.disk.HologramDatabase;
import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.NamedHologram;
import me.filoghost.holographicdisplays.object.line.CraftHologramLine; import me.filoghost.holographicdisplays.object.line.CraftHologramLine;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -33,7 +32,7 @@ public class InfoCommand extends LineEditingCommand {
int index = 0; int index = 0;
for (CraftHologramLine line : hologram.getLinesUnsafe()) { 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); EditCommand.sendQuickEditCommands(context, hologram);
} }

View File

@ -12,7 +12,7 @@ import me.filoghost.holographicdisplays.Colors;
import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.HologramCommandValidate;
import me.filoghost.holographicdisplays.commands.Messages; import me.filoghost.holographicdisplays.commands.Messages;
import me.filoghost.holographicdisplays.common.Utils; 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.event.NamedHologramEditedEvent;
import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.NamedHologram;
import me.filoghost.holographicdisplays.object.line.CraftHologramLine; import me.filoghost.holographicdisplays.object.line.CraftHologramLine;
@ -21,7 +21,9 @@ import org.bukkit.command.CommandSender;
public class InsertlineCommand extends LineEditingCommand { public class InsertlineCommand extends LineEditingCommand {
public InsertlineCommand() { private final ConfigManager configManager;
public InsertlineCommand(ConfigManager configManager) {
super("insertline"); super("insertline");
setMinArgs(3); setMinArgs(3);
setUsageArgs("<hologram> <lineNumber> <text>"); setUsageArgs("<hologram> <lineNumber> <text>");
@ -29,6 +31,8 @@ public class InsertlineCommand extends LineEditingCommand {
"Inserts a line after the specified index.", "Inserts a line after the specified index.",
"If the index is 0, the line will be put before", "If the index is 0, the line will be put before",
"the first line of the hologram."); "the first line of the hologram.");
this.configManager = configManager;
} }
@Override @Override
@ -45,8 +49,8 @@ public class InsertlineCommand extends LineEditingCommand {
hologram.getLinesUnsafe().add(insertAfter, line); hologram.getLinesUnsafe().add(insertAfter, line);
hologram.refreshAll(); hologram.refreshAll();
HologramDatabase.saveHologram(hologram); configManager.getHologramDatabase().addOrUpdate(hologram);
HologramDatabase.trySaveToDisk(); configManager.saveHologramDatabase();
Bukkit.getPluginManager().callEvent(new NamedHologramEditedEvent(hologram)); Bukkit.getPluginManager().callEvent(new NamedHologramEditedEvent(hologram));

View File

@ -11,7 +11,7 @@ import me.filoghost.fcommons.command.validation.CommandValidate;
import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.Colors;
import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.HologramCommandValidate;
import me.filoghost.holographicdisplays.commands.HologramSubCommand; 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.NamedHologram;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -20,12 +20,15 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
public class MovehereCommand extends HologramSubCommand { public class MovehereCommand extends HologramSubCommand {
private final ConfigManager configManager;
public MovehereCommand() { public MovehereCommand(ConfigManager configManager) {
super("movehere"); super("movehere");
setMinArgs(1); setMinArgs(1);
setUsageArgs("<hologram>"); setUsageArgs("<hologram>");
setDescription("Moves a hologram to your location."); setDescription("Moves a hologram to your location.");
this.configManager = configManager;
} }
@Override @Override
@ -37,8 +40,8 @@ public class MovehereCommand extends HologramSubCommand {
hologram.despawnEntities(); hologram.despawnEntities();
hologram.refreshAll(); hologram.refreshAll();
HologramDatabase.saveHologram(hologram); configManager.getHologramDatabase().addOrUpdate(hologram);
HologramDatabase.trySaveToDisk(); configManager.saveHologramDatabase();
Location to = player.getLocation(); Location to = player.getLocation();
to.setPitch(90); to.setPitch(90);
player.teleport(to, TeleportCause.PLUGIN); player.teleport(to, TeleportCause.PLUGIN);

View File

@ -12,12 +12,12 @@ import me.filoghost.fcommons.command.validation.CommandValidate;
import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.Colors;
import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.HologramCommandValidate;
import me.filoghost.holographicdisplays.commands.Messages; 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.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.ImageReader;
import me.filoghost.holographicdisplays.image.ImageTooWideException; 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.NamedHologram;
import me.filoghost.holographicdisplays.object.line.CraftTextLine; import me.filoghost.holographicdisplays.object.line.CraftTextLine;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -35,10 +35,14 @@ import java.util.List;
public class ReadimageCommand extends LineEditingCommand { public class ReadimageCommand extends LineEditingCommand {
public ReadimageCommand() { private final ConfigManager configManager;
public ReadimageCommand(ConfigManager configManager) {
super("readimage", "image"); super("readimage", "image");
setMinArgs(3); setMinArgs(3);
setUsageArgs("<hologram> <imageWithExtension> <width>"); setUsageArgs("<hologram> <imageWithExtension> <width>");
this.configManager = configManager;
} }
@Override @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."); 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); configManager.getHologramDatabase().addOrUpdate(hologram);
HologramDatabase.trySaveToDisk(); configManager.saveHologramDatabase();
if (append) { if (append) {
sender.sendMessage(Colors.PRIMARY + "The image was appended int the end of the hologram!"); sender.sendMessage(Colors.PRIMARY + "The image was appended int the end of the hologram!");

View File

@ -11,9 +11,9 @@ import me.filoghost.fcommons.command.validation.CommandException;
import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.Colors;
import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.HologramCommandValidate;
import me.filoghost.holographicdisplays.commands.Messages; import me.filoghost.holographicdisplays.commands.Messages;
import me.filoghost.holographicdisplays.disk.HologramDatabase; import me.filoghost.holographicdisplays.disk.ConfigManager;
import me.filoghost.holographicdisplays.disk.HologramLineParseException;
import me.filoghost.holographicdisplays.disk.HologramLineParser; import me.filoghost.holographicdisplays.disk.HologramLineParser;
import me.filoghost.holographicdisplays.disk.HologramLoadException;
import me.filoghost.holographicdisplays.event.NamedHologramEditedEvent; import me.filoghost.holographicdisplays.event.NamedHologramEditedEvent;
import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.NamedHologram;
import me.filoghost.holographicdisplays.object.line.CraftHologramLine; import me.filoghost.holographicdisplays.object.line.CraftHologramLine;
@ -31,10 +31,14 @@ import java.util.List;
public class ReadtextCommand extends LineEditingCommand { public class ReadtextCommand extends LineEditingCommand {
public ReadtextCommand() { private final ConfigManager configManager;
public ReadtextCommand(ConfigManager configManager) {
super("readtext", "readlines"); super("readtext", "readlines");
setMinArgs(2); setMinArgs(2);
setUsageArgs("<hologram> <fileWithExtension>"); setUsageArgs("<hologram> <fileWithExtension>");
this.configManager = configManager;
} }
@Override @Override
@ -71,7 +75,7 @@ public class ReadtextCommand extends LineEditingCommand {
try { try {
CraftHologramLine line = HologramLineParser.parseLine(hologram, serializedLines.get(i), true); CraftHologramLine line = HologramLineParser.parseLine(hologram, serializedLines.get(i), true);
linesToAdd.add(line); linesToAdd.add(line);
} catch (HologramLineParseException e) { } catch (HologramLoadException e) {
throw new CommandException("Error at line " + (i + 1) + ": " + e.getMessage()); throw new CommandException("Error at line " + (i + 1) + ": " + e.getMessage());
} }
} }
@ -80,8 +84,8 @@ public class ReadtextCommand extends LineEditingCommand {
hologram.getLinesUnsafe().addAll(linesToAdd); hologram.getLinesUnsafe().addAll(linesToAdd);
hologram.refreshAll(); hologram.refreshAll();
HologramDatabase.saveHologram(hologram); configManager.getHologramDatabase().addOrUpdate(hologram);
HologramDatabase.trySaveToDisk(); configManager.saveHologramDatabase();
if (isImageExtension(FileUtils.getExtension(fileName))) { 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."); Messages.sendWarning(sender, "The read file has an image's extension. If it is an image, you should use /" + context.getRootLabel() + " readimage.");

View File

@ -13,10 +13,10 @@ import me.filoghost.holographicdisplays.bridge.bungeecord.BungeeServerTracker;
import me.filoghost.holographicdisplays.commands.HologramSubCommand; import me.filoghost.holographicdisplays.commands.HologramSubCommand;
import me.filoghost.holographicdisplays.commands.Messages; import me.filoghost.holographicdisplays.commands.Messages;
import me.filoghost.holographicdisplays.common.Utils; import me.filoghost.holographicdisplays.common.Utils;
import me.filoghost.holographicdisplays.disk.ConfigManager;
import me.filoghost.holographicdisplays.disk.Configuration; 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.HologramLoadException;
import me.filoghost.holographicdisplays.disk.UnicodeSymbols;
import me.filoghost.holographicdisplays.event.HolographicDisplaysReloadEvent; import me.filoghost.holographicdisplays.event.HolographicDisplaysReloadEvent;
import me.filoghost.holographicdisplays.object.CraftHologram; import me.filoghost.holographicdisplays.object.CraftHologram;
import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.NamedHologram;
@ -26,26 +26,28 @@ import me.filoghost.holographicdisplays.placeholder.PlaceholdersManager;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.util.Set;
public class ReloadCommand extends HologramSubCommand { public class ReloadCommand extends HologramSubCommand {
public ReloadCommand() { private final ConfigManager configManager;
public ReloadCommand(ConfigManager configManager) {
super("reload"); super("reload");
setDescription("Reloads the holograms from the database."); setDescription("Reloads the holograms from the database.");
this.configManager = configManager;
} }
@Override @Override
public void execute(CommandSender sender, String[] args, SubCommandContext context) { public void execute(CommandSender sender, String[] args, SubCommandContext context) {
long startMillis = System.currentTimeMillis(); long startMillis = System.currentTimeMillis();
UnicodeSymbols.load(HolographicDisplays.getInstance()); configManager.reloadCustomPlaceholders();
Configuration.load(HolographicDisplays.getInstance()); configManager.reloadMainConfig();
BungeeServerTracker.resetTrackedServers(); BungeeServerTracker.resetTrackedServers();
BungeeServerTracker.restartTask(Configuration.bungeeRefreshSeconds); BungeeServerTracker.restartTask(Configuration.bungeeRefreshSeconds);
HologramDatabase.loadYamlFile(HolographicDisplays.getInstance()); configManager.reloadHologramDatabase();
try { try {
AnimationsRegister.loadAnimations(HolographicDisplays.getInstance()); AnimationsRegister.loadAnimations(HolographicDisplays.getInstance());
} catch (Exception e) { } catch (Exception e) {
@ -55,17 +57,14 @@ public class ReloadCommand extends HologramSubCommand {
PlaceholdersManager.untrackAll(); PlaceholdersManager.untrackAll();
NamedHologramManager.clearAll(); NamedHologramManager.clearAll();
Set<String> savedHolograms = HologramDatabase.getHolograms(); for (HologramConfig hologramConfig : configManager.getHologramDatabase().getHolograms()) {
if (savedHolograms != null && savedHolograms.size() > 0) {
for (String singleSavedHologram : savedHolograms) {
try { try {
NamedHologram singleHologramEntity = HologramDatabase.loadHologram(singleSavedHologram); NamedHologram hologram = hologramConfig.createHologram();
NamedHologramManager.addHologram(singleHologramEntity); NamedHologramManager.addHologram(hologram);
} catch (HologramLoadException e) { } catch (HologramLoadException e) {
Messages.sendWarning(sender, Utils.formatExceptionMessage(e)); Messages.sendWarning(sender, Utils.formatExceptionMessage(e));
} }
} }
}
for (CraftHologram hologram : NamedHologramManager.getHolograms()) { for (CraftHologram hologram : NamedHologramManager.getHolograms()) {
hologram.refreshAll(); hologram.refreshAll();

View File

@ -10,7 +10,7 @@ import me.filoghost.fcommons.command.validation.CommandException;
import me.filoghost.fcommons.command.validation.CommandValidate; import me.filoghost.fcommons.command.validation.CommandValidate;
import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.Colors;
import me.filoghost.holographicdisplays.commands.HologramCommandValidate; 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.event.NamedHologramEditedEvent;
import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.NamedHologram;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
@ -18,11 +18,15 @@ import org.bukkit.command.CommandSender;
public class RemovelineCommand extends LineEditingCommand { public class RemovelineCommand extends LineEditingCommand {
public RemovelineCommand() { private final ConfigManager configManager;
public RemovelineCommand(ConfigManager configManager) {
super("removeline"); super("removeline");
setMinArgs(2); setMinArgs(2);
setUsageArgs("<hologram> <lineNumber>"); setUsageArgs("<hologram> <lineNumber>");
setDescription("Removes a line from a hologram."); setDescription("Removes a line from a hologram.");
this.configManager = configManager;
} }
@Override @Override
@ -39,8 +43,8 @@ public class RemovelineCommand extends LineEditingCommand {
hologram.removeLine(index); hologram.removeLine(index);
hologram.refreshAll(); hologram.refreshAll();
HologramDatabase.saveHologram(hologram); configManager.getHologramDatabase().addOrUpdate(hologram);
HologramDatabase.trySaveToDisk(); configManager.saveHologramDatabase();
Bukkit.getPluginManager().callEvent(new NamedHologramEditedEvent(hologram)); Bukkit.getPluginManager().callEvent(new NamedHologramEditedEvent(hologram));
sender.sendMessage(Colors.PRIMARY + "Line " + lineNumber + " removed!"); sender.sendMessage(Colors.PRIMARY + "Line " + lineNumber + " removed!");

View File

@ -11,7 +11,7 @@ import me.filoghost.fcommons.command.validation.CommandValidate;
import me.filoghost.holographicdisplays.Colors; import me.filoghost.holographicdisplays.Colors;
import me.filoghost.holographicdisplays.commands.HologramCommandValidate; import me.filoghost.holographicdisplays.commands.HologramCommandValidate;
import me.filoghost.holographicdisplays.common.Utils; 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.event.NamedHologramEditedEvent;
import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.NamedHologram;
import me.filoghost.holographicdisplays.object.line.CraftHologramLine; import me.filoghost.holographicdisplays.object.line.CraftHologramLine;
@ -20,11 +20,15 @@ import org.bukkit.command.CommandSender;
public class SetlineCommand extends LineEditingCommand { public class SetlineCommand extends LineEditingCommand {
public SetlineCommand() { private final ConfigManager configManager;
public SetlineCommand(ConfigManager configManager) {
super("setline"); super("setline");
setMinArgs(3); setMinArgs(3);
setUsageArgs("<hologram> <lineNumber> <newText>"); setUsageArgs("<hologram> <lineNumber> <newText>");
setDescription("Changes a line of a hologram."); setDescription("Changes a line of a hologram.");
this.configManager = configManager;
} }
@Override @Override
@ -42,8 +46,8 @@ public class SetlineCommand extends LineEditingCommand {
hologram.getLinesUnsafe().set(index, line); hologram.getLinesUnsafe().set(index, line);
hologram.refreshAll(); hologram.refreshAll();
HologramDatabase.saveHologram(hologram); configManager.getHologramDatabase().addOrUpdate(hologram);
HologramDatabase.trySaveToDisk(); configManager.saveHologramDatabase();
Bukkit.getPluginManager().callEvent(new NamedHologramEditedEvent(hologram)); Bukkit.getPluginManager().callEvent(new NamedHologramEditedEvent(hologram));
sender.sendMessage(Colors.PRIMARY + "Line " + lineNumber + " changed!"); sender.sendMessage(Colors.PRIMARY + "Line " + lineNumber + " changed!");

View File

@ -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<MainConfigModel> 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);
}
}

View File

@ -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;
}
}

View File

@ -11,213 +11,154 @@
*/ */
package me.filoghost.holographicdisplays.disk; package me.filoghost.holographicdisplays.disk;
import me.filoghost.fcommons.Strings;
import me.filoghost.fcommons.logging.Log; import me.filoghost.fcommons.logging.Log;
import me.filoghost.holographicdisplays.common.DebugLogger; import me.filoghost.holographicdisplays.common.DebugLogger;
import org.bukkit.ChatColor; 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.DateTimeException;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.Arrays; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; 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 class Configuration {
public static double spaceBetweenLines; public static double spaceBetweenLines;
public static boolean quickEditCommands; public static boolean quickEditCommands;
public static DateTimeFormatter timeFormat;
public static boolean updateNotification;
public static String imageSymbol; public static String imageSymbol;
public static String transparencySymbol; public static String transparencySymbol;
public static boolean updateNotification;
public static ChatColor transparencyColor; public static ChatColor transparencyColor;
public static DateTimeFormatter timeFormat;
public static int bungeeRefreshSeconds; public static int bungeeRefreshSeconds;
public static boolean useRedisBungee; public static boolean useRedisBungee;
public static boolean pingerEnable; public static boolean pingerEnable;
public static int pingerTimeout; public static int pingerTimeout;
public static String pingerOfflineMotd; public static String pingerOfflineMotd;
public static String pingerStatusOnline; public static String pingerStatusOnline;
public static String pingerStatusOffline; public static String pingerStatusOffline;
public static boolean pingerTrimMotd; public static boolean pingerTrimMotd;
public static Map<String, ServerAddress> pingerServers; public static List<ServerAddress> pingerServers;
public static void load(MainConfigModel config) {
spaceBetweenLines = config.spaceBetweenLines;
quickEditCommands = config.quickEditCommands;
timeFormat = parseTimeFormatter(config.timeFormat, config.timeZone);
updateNotification = config.updateNotification;
public static void load(Plugin plugin) { imageSymbol = StringConverter.toReadableFormat(config.imageSymbol);
File configFile = new File(plugin.getDataFolder(), "config.yml"); transparencySymbol = StringConverter.toReadableFormat(config.transparencySymbol);
if (!configFile.exists()) { transparencyColor = parseTransparencyColor(config.transparencyColor);
plugin.getDataFolder().mkdirs();
plugin.saveResource("config.yml", true);
}
YamlConfiguration config = new YamlConfiguration(); bungeeRefreshSeconds = parseBungeeRefreshInterval(config.bungeeRefreshSeconds);
try { useRedisBungee = config.useRedisBungee;
config.load(configFile); pingerEnable = config.pingerEnable;
} catch (InvalidConfigurationException e) { pingerTimeout = parsePingerTimeout(config.pingerTimeout);
e.printStackTrace(); pingerOfflineMotd = StringConverter.toReadableFormat(config.pingerOfflineMotd);
Log.warning("The configuration is not a valid YAML file! Please check it with a tool like http://yaml-online-parser.appspot.com/"); pingerStatusOnline = StringConverter.toReadableFormat(config.pingerStatusOnline);
return; pingerStatusOffline = StringConverter.toReadableFormat(config.pingerStatusOffline);
} catch (IOException e) { pingerTrimMotd = config.pingerTrimMotd;
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;
}
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<String> 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<>();
pingerServers = new ArrayList<>();
if (pingerEnable) { if (pingerEnable) {
for (String singleServer : config.getStringList(ConfigNode.BUNGEE_PINGER_SERVERS.getPath())) { for (String singleServer : config.pingerServers) {
String[] nameAndAddress = singleServer.split(":", 2); ServerAddress serverAddress = parseServerAddress(singleServer);
if (nameAndAddress.length < 2) { if (serverAddress != null) {
Log.warning("The server info \"" + singleServer + "\" is not valid. There should be a name and an address, separated by a colon."); pingerServers.add(serverAddress);
continue;
} }
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())); DebugLogger.setDebugEnabled(config.debug);
}
String tempColor = config.getString(ConfigNode.TRANSPARENCY_COLOR.getPath()).replace('&', ChatColor.COLOR_CHAR); private static DateTimeFormatter parseTimeFormatter(String pattern, String timeZone) {
boolean foundColor = false; DateTimeFormatter timeFormat;
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.");
}
try { try {
timeFormat = DateTimeFormatter.ofPattern(config.getString(ConfigNode.TIME_FORMAT.getPath())); timeFormat = DateTimeFormatter.ofPattern(pattern);
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
timeFormat = DateTimeFormatter.ofPattern("H:mm"); timeFormat = DateTimeFormatter.ofPattern("H:mm");
Log.warning("Time format not valid in the configuration, using the default."); Log.warning("Time format not valid in the configuration, using the default.");
} }
try { try {
timeFormat = timeFormat.withZone(ZoneId.of(config.getString(ConfigNode.TIME_ZONE.getPath()))); timeFormat = timeFormat.withZone(ZoneId.of(timeZone));
} catch (DateTimeException e) { } catch (DateTimeException e) {
Log.warning("Time zone not valid in the configuration, using the default."); Log.warning("Time zone not valid in the configuration, using the default.");
} }
if (bungeeRefreshSeconds < 1) { return timeFormat;
Log.warning("The minimum interval for pinging BungeeCord's servers is 1 second. It has been automatically set.");
bungeeRefreshSeconds = 1;
} }
if (bungeeRefreshSeconds > 60) { private static ChatColor parseTransparencyColor(String transparencyColor) {
transparencyColor = transparencyColor.replace('&', ChatColor.COLOR_CHAR);
for (ChatColor chatColor : ChatColor.values()) {
if (chatColor.toString().equals(transparencyColor)) {
return chatColor;
}
}
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."); 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);
}
} }

View File

@ -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<StaticPlaceholder> 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;
}
}

View File

@ -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<String> 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;
}
}

View File

@ -5,108 +5,64 @@
*/ */
package me.filoghost.holographicdisplays.disk; 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.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.util.Collection;
import java.io.IOException; import java.util.LinkedHashMap;
import java.util.ArrayList; import java.util.Map.Entry;
import java.util.List;
import java.util.Set;
public class HologramDatabase { public class HologramDatabase {
private static File file; private final LinkedHashMap<String, HologramConfig> hologramConfigs;
private static FileConfiguration config;
public static void loadYamlFile(Plugin plugin) { public HologramDatabase() {
file = new File(plugin.getDataFolder(), "database.yml"); this.hologramConfigs = new LinkedHashMap<>();
if (!file.exists()) {
plugin.getDataFolder().mkdirs();
plugin.saveResource("database.yml", true);
} }
config = YamlConfiguration.loadConfiguration(file); public void reloadFromConfig(Config config) {
hologramConfigs.clear();
for (String hologramName : config.getKeys()) {
ConfigSection hologramSection = config.getConfigSection(hologramName);
if (hologramSection == null) {
continue;
} }
public static NamedHologram loadHologram(String name) throws HologramNotFoundException, LocationFormatException, LocationWorldNotLoadedException, HologramLineParseException { HologramConfig hologramConfig = new HologramConfig(hologramName, hologramSection);
ConfigurationSection configSection = config.getConfigurationSection(name); hologramConfigs.put(hologramConfig.getName(), hologramConfig);
if (configSection == null) {
throw new HologramNotFoundException("hologram \"" + name + "\" not found, skipping it");
}
List<String> 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());
} }
} }
return hologram; public Config saveToConfig() {
Config config = new Config();
for (Entry<String, HologramConfig> entry : hologramConfigs.entrySet()) {
config.setConfigSection(entry.getKey(), entry.getValue().toConfigSection());
} }
public static String serializeHologramLine(CraftHologramLine line) { config.setHeader(
return line.getSerializedConfigValue(); "",
"Please do NOT edit this file manually if possible.",
""
);
return config;
} }
public static void deleteHologram(String name) { public Collection<HologramConfig> getHolograms() {
config.set(name, null); return hologramConfigs.values();
} }
public static void saveHologram(NamedHologram hologram) { public void addOrUpdate(NamedHologram hologram) {
List<String> serializedLines = new ArrayList<>(); HologramConfig hologramConfig = new HologramConfig(hologram);
for (CraftHologramLine line : hologram.getLinesUnsafe()) {
serializedLines.add(serializeHologramLine(line)); hologramConfigs.put(hologram.getName(), hologramConfig);
} }
ConfigurationSection hologramSection = getOrCreateSection(hologram.getName()); public void removeHologram(NamedHologram hologram) {
hologramSection.set("location", LocationSerializer.locationToString(hologram.getLocation())); hologramConfigs.remove(hologram.getName());
hologramSection.set("lines", serializedLines);
} }
public static Set<String> 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);
}
}
} }

View File

@ -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);
}
}

View File

@ -19,12 +19,13 @@ import org.bukkit.inventory.ItemStack;
public class HologramLineParser { public class HologramLineParser {
private static final String ICON_PREFIX = "icon:";
public static CraftHologramLine parseLine(NamedHologram hologram, String serializedLine, boolean checkMaterialValidity) throws HologramLineParseException { public static CraftHologramLine parseLine(NamedHologram hologram, String serializedLine, boolean checkMaterialValidity) throws HologramLoadException {
CraftHologramLine hologramLine; CraftHologramLine hologramLine;
if (serializedLine.toLowerCase().startsWith("icon:")) { if (serializedLine.toLowerCase().startsWith(ICON_PREFIX)) {
String serializedIcon = serializedLine.substring("icon:".length()); String serializedIcon = serializedLine.substring(ICON_PREFIX.length());
ItemStack icon = parseItemStack(serializedIcon, checkMaterialValidity); ItemStack icon = parseItemStack(serializedIcon, checkMaterialValidity);
hologramLine = new CraftItemLine(hologram, icon); hologramLine = new CraftItemLine(hologram, icon);
@ -42,7 +43,7 @@ public class HologramLineParser {
@SuppressWarnings("deprecation") @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(); serializedItem = serializedItem.trim();
// Parse json // Parse json
@ -69,7 +70,7 @@ public class HologramLineParser {
try { try {
dataValue = (short) Integer.parseInt(materialAndDataValue[1]); dataValue = (short) Integer.parseInt(materialAndDataValue[1]);
} catch (NumberFormatException e) { } 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]; materialName = materialAndDataValue[0];
} else { } else {
@ -79,7 +80,7 @@ public class HologramLineParser {
Material material = MaterialsHelper.matchMaterial(materialName); Material material = MaterialsHelper.matchMaterial(materialName);
if (material == null) { if (material == null) {
if (checkMaterialValidity) { if (checkMaterialValidity) {
throw new HologramLineParseException("\"" + materialName + "\" is not a valid material"); throw new HologramLoadException("\"" + materialName + "\" is not a valid material");
} }
material = Material.BEDROCK; material = Material.BEDROCK;
} }
@ -92,9 +93,9 @@ public class HologramLineParser {
MojangsonParser.parse(nbtString); MojangsonParser.parse(nbtString);
Bukkit.getUnsafe().modifyItemStack(itemStack, nbtString); Bukkit.getUnsafe().modifyItemStack(itemStack, nbtString);
} catch (MojangsonParseException e) { } catch (MojangsonParseException e) {
throw new HologramLineParseException("invalid NBT data, " + e.getMessage()); throw new HologramLoadException("invalid NBT data, " + e.getMessage());
} catch (Throwable t) { } catch (Throwable t) {
throw new HologramLineParseException("unexpected exception while parsing NBT data", t); throw new HologramLoadException("unexpected exception while parsing NBT data", t);
} }
} }

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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()));
}
}

View File

@ -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);
}
}

View File

@ -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<String> 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<String> getHeader() {
return Arrays.asList(
"",
"Plugin page: https://dev.bukkit.org/projects/holographic-displays",
"",
"Created by filoghost.",
""
);
}
@Override
public boolean beforeSave(Config rawConfig) {
List<String> 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;
}
}

View File

@ -7,14 +7,20 @@ package me.filoghost.holographicdisplays.disk;
public class ServerAddress { public class ServerAddress {
private String name;
private String ip; private String ip;
private int port; private int port;
public ServerAddress(String ip, int port) { public ServerAddress(String name, String ip, int port) {
this.name = name;
this.ip = ip; this.ip = ip;
this.port = port; this.port = port;
} }
public String getName() {
return name;
}
public String getAddress() { public String getAddress() {
return ip; return ip;
} }
@ -25,7 +31,7 @@ public class ServerAddress {
@Override @Override
public String toString() { public String toString() {
return ip + ":" + port; return name + " (" + ip + ":" + port + ")";
} }
} }

View File

@ -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;
}
}

View File

@ -20,7 +20,7 @@ public class StringConverter {
return null; return null;
} }
input = UnicodeSymbols.placeholdersToSymbols(input); input = CustomPlaceholders.replaceStaticPlaceholders(input);
input = Colors.addColors(input); input = Colors.addColors(input);
return input; return input;
} }

View File

@ -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<String, String> 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<String> 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<String, String> 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;
}
}

View File

@ -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<String> 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;
}
}

View File

@ -7,32 +7,35 @@ package me.filoghost.holographicdisplays.task;
import me.filoghost.fcommons.logging.Log; import me.filoghost.fcommons.logging.Log;
import me.filoghost.holographicdisplays.common.Utils; 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.disk.HologramLoadException;
import me.filoghost.holographicdisplays.object.NamedHologram; import me.filoghost.holographicdisplays.object.NamedHologram;
import me.filoghost.holographicdisplays.object.NamedHologramManager; import me.filoghost.holographicdisplays.object.NamedHologramManager;
import java.util.Set; import java.util.Collection;
public class StartupLoadHologramsTask implements Runnable { public class StartupLoadHologramsTask implements Runnable {
private Collection<HologramConfig> hologramConfigsToLoad;
public StartupLoadHologramsTask(Collection<HologramConfig> hologramConfigsToLoad) {
this.hologramConfigsToLoad = hologramConfigsToLoad;
}
@Override @Override
public void run() { public void run() {
Set<String> savedHologramsNames = HologramDatabase.getHolograms(); for (HologramConfig hologramConfig : hologramConfigsToLoad) {
if (savedHologramsNames != null) {
for (String hologramName : savedHologramsNames) {
try { try {
NamedHologram namedHologram = HologramDatabase.loadHologram(hologramName); NamedHologram hologram = hologramConfig.createHologram();
NamedHologramManager.addHologram(namedHologram); NamedHologramManager.addHologram(hologram);
namedHologram.refreshAll(); hologram.refreshAll();
} catch (HologramLoadException e) { } catch (HologramLoadException e) {
Log.warning(Utils.formatExceptionMessage(e)); Log.warning(Utils.formatExceptionMessage(e));
} catch (Exception e) { } catch (Exception e) {
Log.warning("Unexpected exception while loading the hologram \"" + hologramName + "\"." Log.warning("Unexpected exception while loading the hologram \"" + hologramConfig.getName() + "\"."
+ " Please contact the developer.", e); + " Please contact the developer.", e);
} }
} }
} }
}
} }

View File

@ -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

View File

@ -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 '

View File

@ -1,3 +0,0 @@
#.
#. Please do NOT edit this file manually.
#.

View File

@ -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