Update database format and add automatic converter

This commit is contained in:
filoghost 2021-08-06 19:13:18 +02:00
parent 15f88dacb3
commit 4dc46456a3
3 changed files with 103 additions and 40 deletions

View File

@ -21,6 +21,7 @@ import me.filoghost.holographicdisplays.plugin.config.ConfigManager;
import me.filoghost.holographicdisplays.plugin.config.HologramDatabase; import me.filoghost.holographicdisplays.plugin.config.HologramDatabase;
import me.filoghost.holographicdisplays.plugin.config.Settings; import me.filoghost.holographicdisplays.plugin.config.Settings;
import me.filoghost.holographicdisplays.plugin.config.upgrade.LegacyAnimationsUpgrade; 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.config.upgrade.LegacySymbolsUpgrade;
import me.filoghost.holographicdisplays.plugin.hologram.api.APIHologramManager; import me.filoghost.holographicdisplays.plugin.hologram.api.APIHologramManager;
import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologramManager; import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologramManager;
@ -116,6 +117,11 @@ public class HolographicDisplays extends FCommonsPlugin {
} catch (IOException e) { } catch (IOException e) {
errorCollector.add(e, "couldn't automatically convert animation files to the new format"); 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 the configuration
load(true, errorCollector); load(true, errorCollector);

View File

@ -5,8 +5,8 @@
*/ */
package me.filoghost.holographicdisplays.plugin.config; package me.filoghost.holographicdisplays.plugin.config;
import me.filoghost.fcommons.Strings;
import me.filoghost.fcommons.config.ConfigSection; 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.base.BaseHologramPosition;
import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologram; import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologram;
import me.filoghost.holographicdisplays.plugin.hologram.internal.InternalHologramLine; 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.Bukkit;
import org.bukkit.World; import org.bukkit.World;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale;
public class HologramConfig { public class HologramConfig {
private static final DecimalFormat POSITION_NUMBER_FORMAT
= new DecimalFormat("0.000", DecimalFormatSymbols.getInstance(Locale.ROOT));
private final String name; private final String name;
private final List<String> serializedLines; private final List<String> serializedLines;
private final String serializedPosition; private final ConfigSection positionConfigSection;
public HologramConfig(String name, ConfigSection configSection) { public HologramConfig(String name, ConfigSection configSection) {
this.name = name; this.name = name;
this.serializedLines = configSection.getStringList("lines"); this.serializedLines = configSection.getStringList("lines");
this.serializedPosition = configSection.getString("location"); this.positionConfigSection = configSection.getConfigSection("position");
} }
public HologramConfig(InternalHologram hologram) { public HologramConfig(InternalHologram hologram) {
@ -42,25 +36,30 @@ public class HologramConfig {
serializedLines.add(line.getSerializedConfigValue()); 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() { public ConfigSection toConfigSection() {
ConfigSection configSection = new ConfigSection(); ConfigSection configSection = new ConfigSection();
configSection.setStringList("lines", serializedLines); configSection.setStringList("lines", serializedLines);
configSection.setString("location", serializedPosition); configSection.setConfigSection("position", positionConfigSection);
return configSection; return configSection;
} }
public InternalHologram createHologram(InternalHologramManager internalHologramManager) throws HologramLoadException { public void createHologram(InternalHologramManager internalHologramManager) throws HologramLoadException {
if (serializedLines == null || serializedLines.size() == 0) { if (serializedLines == null || serializedLines.size() == 0) {
throw new HologramLoadException("at least one line is required"); throw new HologramLoadException("at least one line is required");
} }
if (serializedPosition == null) { if (positionConfigSection == null) {
throw new HologramLoadException("no location set"); throw new HologramLoadException("no position set");
} }
BaseHologramPosition position = deserializePosition(serializedPosition); BaseHologramPosition position = parsePosition();
InternalHologram hologram = internalHologramManager.createHologram(position, name); InternalHologram hologram = internalHologramManager.createHologram(position, name);
List<InternalHologramLine> lines = new ArrayList<>(); List<InternalHologramLine> lines = new ArrayList<>();
@ -74,41 +73,24 @@ public class HologramConfig {
} }
hologram.setLines(lines); hologram.setLines(lines);
return hologram;
} }
private String serializePosition(BaseHologramPosition position) { private BaseHologramPosition parsePosition() throws HologramLoadException {
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\"");
}
try { try {
String worldName = parts[0]; String worldName = positionConfigSection.getRequiredString("world");
double x = Double.parseDouble(parts[1]); double x = positionConfigSection.getRequiredDouble("x");
double y = Double.parseDouble(parts[2]); double y = positionConfigSection.getRequiredDouble("y");
double z = Double.parseDouble(parts[3]); double z = positionConfigSection.getRequiredDouble("z");
World world = Bukkit.getWorld(worldName); World world = Bukkit.getWorld(worldName);
if (world == null) { if (world == null) {
throw new HologramLoadException("hologram \"" + name + "\"" throw new HologramLoadException("world \"" + worldName + "\" is not currently loaded");
+ " was in the world \"" + worldName + "\" but it wasn't loaded");
} }
return new BaseHologramPosition(world, x, y, z); return new BaseHologramPosition(world, x, y, z);
} catch (NumberFormatException ex) { } catch (ConfigValueException e) {
throw new HologramLoadException("hologram \"" + name + "\"" throw new HologramLoadException("invalid position attribute \"" + e.getConfigPath() + "\"", e);
+ " has an invalid location format: invalid number");
} }
} }

View File

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