The raw configuration
+ */ + public FileConfiguration getConfiguration() { + return this.configuration; + } + + @Override + public void reloadConfig() { + super.reloadConfig(); + this.configuration = new StargateYamlConfiguration(); + try { + configuration.load(configFile); + } catch (IOException | InvalidConfigurationException e) { + Stargate.logSevere(e.getMessage()); + } + } + @Override public void onDisable() { PortalHandler.closeAllPortals(); @@ -340,11 +365,17 @@ public class Stargate extends JavaPlugin { @Override public void onEnable() { + configFile = new File(this.getDataFolder(), "config.yml"); PluginDescriptionFile pluginDescriptionFile = this.getDescription(); pluginManager = getServer().getPluginManager(); - FileConfiguration newConfig = this.getConfig(); + configuration = new StargateYamlConfiguration(); + try { + configuration.load(configFile); + } catch (IOException | InvalidConfigurationException e) { + Stargate.logSevere(e.getMessage()); + } this.saveDefaultConfig(); - newConfig.options().copyDefaults(true); + configuration.options().copyDefaults(true); logger = Logger.getLogger("Minecraft"); Server server = getServer(); diff --git a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java index 6374518..2ae0691 100644 --- a/src/main/java/net/knarcraft/stargate/command/CommandConfig.java +++ b/src/main/java/net/knarcraft/stargate/command/CommandConfig.java @@ -66,7 +66,7 @@ public class CommandConfig implements CommandExecutor { * @param valueThe new value of the config option
*/ private void updateConfigValue(ConfigOption selectedOption, CommandSender commandSender, String value) { - FileConfiguration configuration = Stargate.getInstance().getConfig(); + FileConfiguration configuration = Stargate.getInstance().getConfiguration(); //Validate any sign colors if (ConfigTag.COLOR.isTagged(selectedOption)) { @@ -162,7 +162,7 @@ public class CommandConfig implements CommandExecutor { * @param argumentsThe arguments for the new config option
*/ private void updateListConfigValue(ConfigOption selectedOption, CommandSender commandSender, String[] arguments) { - FileConfiguration configuration = Stargate.getInstance().getConfig(); + FileConfiguration configuration = Stargate.getInstance().getConfiguration(); if (selectedOption == ConfigOption.PER_SIGN_COLORS) { if (arguments.length < 4) { diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index 99b0096..ea8598d 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -361,7 +361,7 @@ public final class StargateConfig { */ public void loadConfig() { Stargate.getInstance().reloadConfig(); - FileConfiguration newConfig = Stargate.getInstance().getConfig(); + FileConfiguration newConfig = Stargate.getInstance().getConfiguration(); boolean isMigrating = false; if (newConfig.getString("lang") != null || newConfig.getString("economy.freeGatesGreen") != null || diff --git a/src/main/java/net/knarcraft/stargate/config/StargateYamlConfiguration.java b/src/main/java/net/knarcraft/stargate/config/StargateYamlConfiguration.java new file mode 100644 index 0000000..2b5f751 --- /dev/null +++ b/src/main/java/net/knarcraft/stargate/config/StargateYamlConfiguration.java @@ -0,0 +1,155 @@ +package net.knarcraft.stargate.config; + +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * A YAML configuration which keeps all comments + * + * @author Thorin + */ +public class StargateYamlConfiguration extends YamlConfiguration { + + static public final String END_OF_COMMENT = "_endOfComment_"; + static public final String START_OF_COMMENT = "comment_"; + + @Override + public @NotNull String saveToString() { + return this.convertYAMLMappingsToComments(super.saveToString()); + } + + @Override + public void loadFromString(@NotNull String contents) throws InvalidConfigurationException { + super.loadFromString(this.convertCommentsToYAMLMappings(contents)); + } + + /** + * Reads a file with comments, and recreates them into yaml mappings + * + *A mapping follows this format: comment_{CommentNumber}: "The comment" + * This needs to be done as comments otherwise get removed using + * the {@link FileConfiguration#save(File)} method. The config + * needs to be saved if a config value has changed.
+ */ + private String convertCommentsToYAMLMappings(String configString) { + StringBuilder yamlBuilder = new StringBuilder(); + ListThe string builder to add the generated YAML to
+ * @param commentLinesThe lines of the comment to convert into YAML
+ * @param commentIdThe unique id of the comment
+ * @param indentationThe indentation to add to every line
+ */ + private void generateCommentYAML(StringBuilder yamlBuilder, ListThe internal YAML structure is converted to a string with the same format as a standard configuration file. + * The internal structure has comments in the format: START_OF_COMMENT + id + multi-line YAML string + + * END_OF_COMMENT.
+ * + * @param yamlStringA string using the YAML format
+ * @returnThe corresponding comment string
+ */ + private String convertYAMLMappingsToComments(String yamlString) { + StringBuilder finalText = new StringBuilder(); + boolean isReadingCommentBlock = false; + int commentIndentation = 0; + for (String line : yamlString.split("\n")) { + String possibleComment = line.trim(); + + if (isReadingCommentBlock && line.contains(END_OF_COMMENT)) { + //Skip the line signifying the end of a comment + isReadingCommentBlock = false; + } else if (possibleComment.startsWith(START_OF_COMMENT)) { + //Skip the comment start line, and start comment parsing + isReadingCommentBlock = true; + //Get the indentation to use for the comment block + commentIndentation = getIndentation(line); + //Add an empty line before every comment block + finalText.append("\n"); + } else if (line.isEmpty() && !isReadingCommentBlock) { + //Output the empty line as-is, as it's not part of a comment + finalText.append("\n"); + } else if (isReadingCommentBlock) { + //Output the comment with correct indentation + finalText.append(addIndentation(commentIndentation)).append("# ").append(possibleComment).append("\n"); + } else { + //Output the configuration key + finalText.append(line).append("\n"); + } + } + return finalText.toString().trim(); + } + + /** + * Gets a string containing the given indentation + * + * @param indentationSpacesThe number spaces to use for indentation
+ * @returnA string containing the number of spaces specified
+ */ + private String addIndentation(int indentationSpaces) { + return " ".repeat(Math.max(0, indentationSpaces)); + } + + + /** + * Gets the indentation (number of spaces) of the given line + * + * @param lineThe line to get indentation of
+ * @returnThe number of spaces in the line's indentation
+ */ + private int getIndentation(String line) { + int spacesFound = 0; + for (char aCharacter : line.toCharArray()) { + if (aCharacter == ' ') { + spacesFound++; + } else { + break; + } + } + return spacesFound; + } + +} diff --git a/src/main/resources/config-migrations.txt b/src/main/resources/config-migrations.txt index b898212..43893cd 100644 --- a/src/main/resources/config-migrations.txt +++ b/src/main/resources/config-migrations.txt @@ -1,5 +1,5 @@ lang=language -defaultNetwork=defaultGateNetwork +defaultNetwork=gates.defaultGateNetwork use-mysql= ignoreEntrance= enableEconomy=economy.useEconomy @@ -17,7 +17,7 @@ sortLists=gates.cosmetic.sortNetworkDestinations protectEntrance=gates.integrity.protectEntrance enableBungee=gates.functionality.enableBungee verifyPortals=gates.integrity.verifyPortals -signColor=gates.cosmetic.signColor +signColor=gates.cosmetic.mainSignColor gates.cosmetic.signColor=gates.cosmetic.mainSignColor debug=debugging.debug permdebug=debugging.permissionDebug