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.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);

View File

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

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