diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/HolographicDisplays.java b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/HolographicDisplays.java index 1f726a22..d359a6aa 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/HolographicDisplays.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/HolographicDisplays.java @@ -21,6 +21,7 @@ import me.filoghost.holographicdisplays.plugin.config.ConfigManager; import me.filoghost.holographicdisplays.plugin.config.HologramDatabase; import me.filoghost.holographicdisplays.plugin.config.Settings; import me.filoghost.holographicdisplays.plugin.config.upgrade.LegacyAnimationsUpgrade; +import me.filoghost.holographicdisplays.plugin.config.upgrade.LegacyDatabaseUpgrade; import me.filoghost.holographicdisplays.plugin.config.upgrade.LegacySymbolsUpgrade; import me.filoghost.holographicdisplays.plugin.hologram.api.APIHologramManager; import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologramManager; @@ -116,6 +117,11 @@ public class HolographicDisplays extends FCommonsPlugin { } catch (IOException e) { errorCollector.add(e, "couldn't automatically convert animation files to the new format"); } + try { + LegacyDatabaseUpgrade.run(configManager); + } catch (ConfigException | IOException e) { + errorCollector.add(e, "couldn't automatically convert database file to the new format"); + } // Load the configuration load(true, errorCollector); diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/config/HologramConfig.java b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/config/HologramConfig.java index 7ba42096..4a6b9785 100644 --- a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/config/HologramConfig.java +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/config/HologramConfig.java @@ -5,8 +5,8 @@ */ package me.filoghost.holographicdisplays.plugin.config; -import me.filoghost.fcommons.Strings; import me.filoghost.fcommons.config.ConfigSection; +import me.filoghost.fcommons.config.exception.ConfigValueException; import me.filoghost.holographicdisplays.plugin.hologram.base.BaseHologramPosition; import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologram; import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologramLine; @@ -14,25 +14,19 @@ import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologra import org.bukkit.Bukkit; 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 POSITION_NUMBER_FORMAT - = new DecimalFormat("0.000", DecimalFormatSymbols.getInstance(Locale.ROOT)); - private final String name; private final List serializedLines; - private final String serializedPosition; + private final ConfigSection positionConfigSection; public HologramConfig(String name, ConfigSection configSection) { this.name = name; this.serializedLines = configSection.getStringList("lines"); - this.serializedPosition = configSection.getString("location"); + this.positionConfigSection = configSection.getConfigSection("position"); } public HologramConfig(InternalHologram hologram) { @@ -42,25 +36,30 @@ public class HologramConfig { serializedLines.add(line.getSerializedConfigValue()); } - this.serializedPosition = serializePosition(hologram.getBasePosition()); + BaseHologramPosition position = hologram.getBasePosition(); + this.positionConfigSection = new ConfigSection(); + positionConfigSection.setString("world", position.getWorld().getName()); + positionConfigSection.setDouble("x", position.getX()); + positionConfigSection.setDouble("y", position.getY()); + positionConfigSection.setDouble("z", position.getZ()); } public ConfigSection toConfigSection() { ConfigSection configSection = new ConfigSection(); configSection.setStringList("lines", serializedLines); - configSection.setString("location", serializedPosition); + configSection.setConfigSection("position", positionConfigSection); return configSection; } - public InternalHologram createHologram(InternalHologramManager internalHologramManager) throws HologramLoadException { + public void createHologram(InternalHologramManager internalHologramManager) throws HologramLoadException { if (serializedLines == null || serializedLines.size() == 0) { throw new HologramLoadException("at least one line is required"); } - if (serializedPosition == null) { - throw new HologramLoadException("no location set"); + if (positionConfigSection == null) { + throw new HologramLoadException("no position set"); } - BaseHologramPosition position = deserializePosition(serializedPosition); + BaseHologramPosition position = parsePosition(); InternalHologram hologram = internalHologramManager.createHologram(position, name); List lines = new ArrayList<>(); @@ -74,41 +73,24 @@ public class HologramConfig { } hologram.setLines(lines); - return hologram; } - private String serializePosition(BaseHologramPosition position) { - return position.getWorld().getName() - + ", " + POSITION_NUMBER_FORMAT.format(position.getX()) - + ", " + POSITION_NUMBER_FORMAT.format(position.getY()) - + ", " + POSITION_NUMBER_FORMAT.format(position.getZ()); - } - - private BaseHologramPosition deserializePosition(String serializedPosition) throws HologramLoadException { - String[] parts = Strings.splitAndTrim(serializedPosition, ","); - - if (parts.length != 4) { - throw new HologramLoadException("hologram \"" + name + "\" has an invalid location format:" - + " it must be \"world, x, y, z\""); - } - + private BaseHologramPosition parsePosition() throws HologramLoadException { try { - String worldName = parts[0]; - double x = Double.parseDouble(parts[1]); - double y = Double.parseDouble(parts[2]); - double z = Double.parseDouble(parts[3]); + String worldName = positionConfigSection.getRequiredString("world"); + double x = positionConfigSection.getRequiredDouble("x"); + double y = positionConfigSection.getRequiredDouble("y"); + double z = positionConfigSection.getRequiredDouble("z"); World world = Bukkit.getWorld(worldName); if (world == null) { - throw new HologramLoadException("hologram \"" + name + "\"" - + " was in the world \"" + worldName + "\" but it wasn't loaded"); + throw new HologramLoadException("world \"" + worldName + "\" is not currently loaded"); } return new BaseHologramPosition(world, x, y, z); - } catch (NumberFormatException ex) { - throw new HologramLoadException("hologram \"" + name + "\"" - + " has an invalid location format: invalid number"); + } catch (ConfigValueException e) { + throw new HologramLoadException("invalid position attribute \"" + e.getConfigPath() + "\"", e); } } diff --git a/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/config/upgrade/LegacyDatabaseUpgrade.java b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/config/upgrade/LegacyDatabaseUpgrade.java new file mode 100644 index 00000000..a5d514f2 --- /dev/null +++ b/plugin/src/main/java/me/filoghost/holographicdisplays/plugin/config/upgrade/LegacyDatabaseUpgrade.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) filoghost and contributors + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ +package me.filoghost.holographicdisplays.plugin.config.upgrade; + +import me.filoghost.fcommons.Strings; +import me.filoghost.fcommons.config.ConfigLoader; +import me.filoghost.fcommons.config.ConfigSection; +import me.filoghost.fcommons.config.ConfigType; +import me.filoghost.fcommons.config.ConfigValue; +import me.filoghost.fcommons.config.FileConfig; +import me.filoghost.fcommons.config.exception.ConfigLoadException; +import me.filoghost.fcommons.config.exception.ConfigSaveException; +import me.filoghost.holographicdisplays.plugin.config.ConfigManager; + +import java.io.IOException; +import java.nio.file.Files; + +public class LegacyDatabaseUpgrade { + + public static void run(ConfigManager configManager) throws ConfigLoadException, ConfigSaveException, IOException { + ConfigLoader databaseConfigLoader = configManager.getConfigLoader("database.yml"); + + if (!databaseConfigLoader.fileExists()) { + return; // Database doesn't exist yet, nothing to convert + } + + FileConfig databaseConfig = databaseConfigLoader.load(); + boolean changed = false; + + for (ConfigSection hologramSection : databaseConfig.toMap(ConfigType.SECTION).values()) { + if (!hologramSection.contains("position")) { + String legacySerializedLocation = hologramSection.getString("location"); + if (legacySerializedLocation != null) { + hologramSection.remove("location"); + hologramSection.setConfigSection("position", convertLegacySerializedLocation(legacySerializedLocation)); + changed = true; + } + } + } + + if (changed) { + Files.copy(databaseConfigLoader.getFile(), LegacyUpgradeUtils.getBackupFile(databaseConfigLoader.getFile())); + databaseConfigLoader.save(databaseConfig); + } + } + + private static ConfigSection convertLegacySerializedLocation(String legacySerializedLocation) { + String[] legacyLocationParts = Strings.splitAndTrim(legacySerializedLocation, ","); + + ConfigSection positionSection = new ConfigSection(); + positionSection.setString("world", legacyLocationParts[0]); + if (legacyLocationParts.length > 1) { + positionSection.set("x", getDoubleOrString(legacyLocationParts[1])); + } + if (legacyLocationParts.length > 2) { + positionSection.set("y", getDoubleOrString(legacyLocationParts[2])); + } + if (legacyLocationParts.length > 3) { + positionSection.set("z", getDoubleOrString(legacyLocationParts[3])); + } + return positionSection; + } + + private static ConfigValue getDoubleOrString(String serializedDouble) { + try { + return ConfigValue.of(ConfigType.DOUBLE, Double.parseDouble(serializedDouble)); + } catch (NumberFormatException e) { + return ConfigValue.of(ConfigType.STRING, serializedDouble); + } + } + +}