diff --git a/src/main/java/org/mvplugins/multiverse/inventories/MultiverseInventories.java b/src/main/java/org/mvplugins/multiverse/inventories/MultiverseInventories.java index d7a298de..3b2c2f29 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/MultiverseInventories.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/MultiverseInventories.java @@ -10,6 +10,7 @@ import org.mvplugins.multiverse.core.inject.PluginServiceLocatorFactory; import org.mvplugins.multiverse.core.utils.StringFormatter; import org.mvplugins.multiverse.inventories.commands.InventoriesCommand; +import org.mvplugins.multiverse.inventories.config.InventoriesConfig; import org.mvplugins.multiverse.inventories.locale.Message; import org.mvplugins.multiverse.inventories.locale.Messager; import org.mvplugins.multiverse.inventories.locale.Messaging; @@ -49,6 +50,8 @@ public static MultiverseInventories getPlugin() { private PluginServiceLocator serviceLocator; + @Inject + private Provider configProvider; @Inject private Provider commandManager; @Inject @@ -62,7 +65,6 @@ public static MultiverseInventories getPlugin() { private ProfileContainerStore groupProfileContainerStore = null; private final ImportManager importManager = new ImportManager(this); - private InventoriesConfig config = null; private FlatFileProfileDataSource data = null; private InventoriesDupingPatch dupingPatch; @@ -251,7 +253,7 @@ private String logAndAddToPasteBinBuffer(String string) { * @return the Config object which contains settings for this plugin. */ public InventoriesConfig getMVIConfig() { - return this.config; + return this.configProvider.get(); } /** @@ -260,8 +262,7 @@ public InventoriesConfig getMVIConfig() { @Override public void reloadConfig() { try { - this.config = new InventoriesConfig(this, mvCoreConfig.get()); - this.worldGroupManager = new YamlWorldGroupManager(this, this.config.getConfig()); + this.worldGroupManager = new YamlWorldGroupManager(this, this.configProvider.get().getConfig()); this.worldProfileContainerStore = new WeakProfileContainerStore(this, ContainerType.WORLD); this.groupProfileContainerStore = new WeakProfileContainerStore(this, ContainerType.GROUP); @@ -363,3 +364,4 @@ public boolean isUsingSpawnChangeEvent() { return usingSpawnChangeEvent; } } + diff --git a/src/main/java/org/mvplugins/multiverse/inventories/YamlWorldGroupManager.java b/src/main/java/org/mvplugins/multiverse/inventories/YamlWorldGroupManager.java index 32ab98db..9ef34daa 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/YamlWorldGroupManager.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/YamlWorldGroupManager.java @@ -2,8 +2,8 @@ import com.dumptruckman.minecraft.util.Logging; import com.google.common.collect.Lists; +import org.mvplugins.multiverse.external.commentedconfiguration.CommentedConfiguration; import org.mvplugins.multiverse.inventories.share.Sharables; -import org.mvplugins.multiverse.inventories.util.CommentedYamlConfiguration; import org.mvplugins.multiverse.inventories.util.DeserializationException; import io.papermc.lib.PaperLib; import org.bukkit.Bukkit; @@ -24,12 +24,14 @@ final class YamlWorldGroupManager extends AbstractWorldGroupManager { - private final List groupSectionComments = Collections.unmodifiableList(new ArrayList() {{ - add("# To ADD, DELETE, and EDIT groups use the command /mvinv group."); - add("# No support will be given for those who manually edit these groups."); - }}); + private final String[] groupSectionComments = { + "# Multiverse-Inventories Groups", + "", + "# To ADD, DELETE, and EDIT groups use the command /mvinv group.", + "# No support will be given for those who manually edit these groups." + }; - private final CommentedYamlConfiguration groupsConfig; + private final CommentedConfiguration groupsConfig; YamlWorldGroupManager(final MultiverseInventories inventories, final Configuration config) throws IOException { super(inventories); @@ -44,19 +46,18 @@ final class YamlWorldGroupManager extends AbstractWorldGroupManager { migrateGroups = true; } // Load the configuration file into memory - boolean supportsCommentsNatively = PaperLib.getMinecraftVersion() > 17; - groupsConfig = new CommentedYamlConfiguration(groupsConfigFile, !groupsConfigFileExists || !supportsCommentsNatively); + groupsConfig = new CommentedConfiguration(groupsConfigFile.toPath()); + groupsConfig.load(); if (migrateGroups) { migrateGroups(config); } groupsConfig.addComment("groups", groupSectionComments); - if (groupsConfig.getConfig().get("groups") == null) { + if (groupsConfig.get("groups") == null) { this.getConfig().createSection("groups"); } - groupsConfig.getConfig().options().header("Multiverse-Inventories Groups"); // Saves the configuration from memory to file groupsConfig.save(); @@ -86,7 +87,7 @@ private void migrateGroups(final Configuration config) { } private FileConfiguration getConfig() { - return this.groupsConfig.getConfig(); + return this.groupsConfig; } private List getGroupsFromConfig() { diff --git a/src/main/java/org/mvplugins/multiverse/inventories/InventoriesConfig.java b/src/main/java/org/mvplugins/multiverse/inventories/config/InventoriesConfig.java similarity index 94% rename from src/main/java/org/mvplugins/multiverse/inventories/InventoriesConfig.java rename to src/main/java/org/mvplugins/multiverse/inventories/config/InventoriesConfig.java index ded9e252..8f56765c 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/InventoriesConfig.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/config/InventoriesConfig.java @@ -1,11 +1,14 @@ -package org.mvplugins.multiverse.inventories; +package org.mvplugins.multiverse.inventories.config; import com.dumptruckman.minecraft.util.Logging; import org.mvplugins.multiverse.core.config.MVCoreConfig; +import org.mvplugins.multiverse.external.commentedconfiguration.CommentedConfiguration; +import org.mvplugins.multiverse.external.jakarta.inject.Inject; +import org.mvplugins.multiverse.external.jvnet.hk2.annotations.Service; +import org.mvplugins.multiverse.inventories.MultiverseInventories; import org.mvplugins.multiverse.inventories.share.Sharable; import org.mvplugins.multiverse.inventories.share.Sharables; import org.mvplugins.multiverse.inventories.share.Shares; -import org.mvplugins.multiverse.inventories.util.CommentedYamlConfiguration; import io.papermc.lib.PaperLib; import org.bukkit.configuration.file.FileConfiguration; @@ -18,6 +21,7 @@ /** * Provides methods for interacting with the configuration of Multiverse-Inventories. */ +@Service public final class InventoriesConfig { /** @@ -107,10 +111,11 @@ private List getComments() { } } - private final CommentedYamlConfiguration config; + private final CommentedConfiguration config; private final MultiverseInventories plugin; private final MVCoreConfig mvCoreConfig; + @Inject InventoriesConfig(MultiverseInventories plugin, MVCoreConfig mvCoreConfig) throws IOException { this.plugin = plugin; this.mvCoreConfig = mvCoreConfig; @@ -128,13 +133,13 @@ private List getComments() { } // Load the configuration file into memory - boolean supportsCommentsNatively = PaperLib.getMinecraftVersion() > 17; - config = new CommentedYamlConfiguration(configFile, !configFileExists || !supportsCommentsNatively); + config = new CommentedConfiguration(configFile.toPath()); + config.load(); // Sets defaults config values this.setDefaults(); - config.getConfig().options().header("Multiverse-Inventories Settings"); + config.addComment("settings", "# Multiverse-Inventories Settings", ""); // Saves the configuration from memory to file config.save(); @@ -148,7 +153,7 @@ private List getComments() { */ private void setDefaults() { for (InventoriesConfig.Path path : InventoriesConfig.Path.values()) { - config.addComment(path.getPath(), path.getComments()); + config.addComment(path.getPath(), path.getComments().toArray(new String[0])); if (this.getConfig().get(path.getPath()) == null) { if (path.getDefault() != null) { Logging.fine("Config: Defaulting '" + path.getPath() + "' to " + path.getDefault()); @@ -173,8 +178,8 @@ private String getString(Path path) { return this.getConfig().getString(path.getPath(), (String) path.getDefault()); } - FileConfiguration getConfig() { - return this.config.getConfig(); + public FileConfiguration getConfig() { + return this.config; } /** @@ -218,7 +223,7 @@ public boolean isFirstRun() { * * @param firstRun What to set the flag to in the config. */ - void setFirstRun(boolean firstRun) { + public void setFirstRun(boolean firstRun) { this.getConfig().set(Path.FIRST_RUN.getPath(), firstRun); } diff --git a/src/main/java/org/mvplugins/multiverse/inventories/share/Sharable.java b/src/main/java/org/mvplugins/multiverse/inventories/share/Sharable.java index d3e77f4a..f0b9c5a3 100644 --- a/src/main/java/org/mvplugins/multiverse/inventories/share/Sharable.java +++ b/src/main/java/org/mvplugins/multiverse/inventories/share/Sharable.java @@ -1,6 +1,6 @@ package org.mvplugins.multiverse.inventories.share; -import org.mvplugins.multiverse.inventories.InventoriesConfig; +import org.mvplugins.multiverse.inventories.config.InventoriesConfig; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/org/mvplugins/multiverse/inventories/util/CommentedYamlConfiguration.java b/src/main/java/org/mvplugins/multiverse/inventories/util/CommentedYamlConfiguration.java deleted file mode 100644 index 78993d16..00000000 --- a/src/main/java/org/mvplugins/multiverse/inventories/util/CommentedYamlConfiguration.java +++ /dev/null @@ -1,278 +0,0 @@ -package org.mvplugins.multiverse.inventories.util; - -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.StringWriter; -import java.io.Writer; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * A Configuration wrapper class that allows for comments to be applied to the config paths. - */ -public final class CommentedYamlConfiguration { - - private final File file; - private final FileConfiguration config; - private final boolean doComments; - private final HashMap comments; - - private static final Pattern NEW_LINE_PATTERN = Pattern.compile("\r?\n"); - - public CommentedYamlConfiguration(File file, boolean doComments) { - this.file = file; - this.doComments = doComments; - this.comments = new HashMap(); - this.config = new YamlConfiguration(); - - try { - this.config.load(file); - } catch (Exception ignored) {} - } - - /** - * @return The underlying configuration object. - */ - public FileConfiguration getConfig() { - return this.config; - } - - /** - * Saves the file as per normal for YamlConfiguration and then parses the file and inserts - * comments where necessary. - * - * @return True if successful. - */ - public boolean save() { - // try to save the config file, return false on failure - try { - config.save(file); - } catch (Exception e) { - return false; - } - - // if we're not supposed to add comments, or there aren't any to add, we're done - if (!doComments || comments.isEmpty()) { - return true; - } - - // convert config file to String - String stringConfig = this.convertFileToString(file); - - // figure out where the header ends - int indexAfterHeader = 0; - Matcher newline = NEW_LINE_PATTERN.matcher(stringConfig); - - while (newline.find() && stringConfig.charAt(newline.end()) == '#') { - indexAfterHeader = newline.end(); - } - - // convert stringConfig to array, ignoring the header - String[] arrayConfig = stringConfig.substring(indexAfterHeader).split(newline.group()); - - // begin building the new config, starting with the header - StringBuilder newContents = new StringBuilder(); - newContents.append(stringConfig, 0, indexAfterHeader); - - // This holds the current path the lines are at in the config - StringBuilder currentPath = new StringBuilder(); - - // This flags if the line is a node or unknown text. - boolean node; - // The depth of the path. (number of words separated by periods - 1) - int depth = 0; - - // Loop through the config lines - for (final String line : arrayConfig) { - // If the line is a node (and not something like a list value) - if (line.contains(": ") || (line.length() > 1 && line.charAt(line.length() - 1) == ':')) { - // This is a node so flag it as one - node = true; - - // Grab the index of the end of the node name - int index; - index = line.indexOf(": "); - if (index < 0) { - index = line.length() - 1; - } - // If currentPath is empty, store the node name as the currentPath. (this is only on the first iteration, i think) - if (currentPath.toString().isEmpty()) { - currentPath = new StringBuilder(line.substring(0, index)); - } else { - // Calculate the whitespace preceding the node name - int whiteSpace = 0; - for (int n = 0; n < line.length(); n++) { - if (line.charAt(n) == ' ') { - whiteSpace++; - } else { - break; - } - } - - int whiteSpaceDividedByTwo = whiteSpace / 2; - // Find out if the current depth (whitespace * 2) is greater/lesser/equal to the previous depth - if (whiteSpaceDividedByTwo > depth) { - // Path is deeper. Add a dot and the node name - currentPath.append(".").append(line, whiteSpace, index); - depth++; - } else if (whiteSpaceDividedByTwo < depth) { - // Path is shallower, calculate current depth from whitespace (whitespace / 2) and subtract that many levels from the currentPath - for (int i = 0; i < depth - whiteSpaceDividedByTwo; i++) { - currentPath.replace(currentPath.lastIndexOf("."), currentPath.length(), ""); - } - // Grab the index of the final period - int lastIndex = currentPath.lastIndexOf("."); - if (lastIndex < 0) { - // if there isn't a final period, set the current path to nothing because we're at root - currentPath = new StringBuilder(); - } else { - // If there is a final period, replace everything after it with nothing - currentPath.replace(currentPath.lastIndexOf("."), currentPath.length(), "").append("."); - } - // Add the new node name to the path - currentPath.append(line, whiteSpace, index); - // Reset the depth - depth = whiteSpaceDividedByTwo; - } else { - // Path is same depth, replace the last path node name to the current node name - int lastIndex = currentPath.lastIndexOf("."); - if (lastIndex < 0) { - // if there isn't a final period, set the current path to nothing because we're at root - currentPath = new StringBuilder(); - } else { - // If there is a final period, replace everything after it with nothing - currentPath.replace(currentPath.lastIndexOf("."), currentPath.length(), "").append("."); - } - - currentPath.append(line, whiteSpace, index); - } - } - } else { - node = false; - } - - StringBuilder newLine = new StringBuilder(); - - if (node) { - // get the comment for the current node - String comment = comments.get(currentPath.toString()); - if (comment != null && !comment.isEmpty()) { - // if the previous line doesn't end in a colon - // and there's not already a newline character, - // add a newline before we add the comment - char previousChar = newContents.charAt(newContents.length() - 2); - if (previousChar != ':' && previousChar != '\n') { - newLine.append("\n"); - } - - // add the comment - newLine.append(comment).append("\n"); - } - } - - // add the config line - newLine.append(line).append("\n"); - - // Add the (modified) line to the total config String - newContents.append(newLine); - } - - // try to save the config file, returning whether it saved successfully - return this.stringToFile(newContents.toString(), file); - } - - /** - * Adds a comment just before the specified path. The comment can be multiple lines. An empty string will indicate - * a blank line. - * - * @param path Configuration path to add comment. - * @param commentLines Comments to add. One String per line. - */ - public void addComment(String path, List commentLines) { - StringBuilder commentString = new StringBuilder(); - StringBuilder leadingSpaces = new StringBuilder(); - for (int n = 0; n < path.length(); n++) { - if (path.charAt(n) == '.') { - leadingSpaces.append(" "); - } - } - for (String line : commentLines) { - if (commentString.length() > 0) { - commentString.append("\n"); - } - if (!line.isEmpty()) { - commentString.append(leadingSpaces).append(line); - } - } - comments.put(path, commentString.toString()); - } - - /** - * Pass a file and it will return it's contents as a string. - * - * @param file File to read. - * @return Contents of file. String will be empty in case of any errors. - */ - private String convertFileToString(File file) { - final int bufferSize = 1024; - if (file != null && file.exists() && file.canRead() && !file.isDirectory()) { - Writer writer = new StringWriter(); - char[] buffer = new char[bufferSize]; - - try (InputStream is = new FileInputStream(file)) { - int n; - Reader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); - while ((n = reader.read(buffer)) != -1) { - writer.write(buffer, 0, n); - } - } catch (IOException e) { - e.printStackTrace(); - } - return writer.toString(); - } else { - return ""; - } - } - - /** - * Writes the contents of a string to a file. - * - * @param source String to write. - * @param file File to write to. - * @return True on success. - */ - private boolean stringToFile(String source, File file) { - OutputStreamWriter out = null; - try { - out = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8); - out.write(source); - out.close(); - return true; - } catch (IOException e) { - e.printStackTrace(); - return false; - } finally { - if (out != null) { - try { - out.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - } -} - diff --git a/src/old-test/java/org/mvplugins/multiverse/inventories/TestCommentedYamlConfiguration.java b/src/old-test/java/org/mvplugins/multiverse/inventories/TestCommentedYamlConfiguration.java index 5a10dc48..600c8ab7 100644 --- a/src/old-test/java/org/mvplugins/multiverse/inventories/TestCommentedYamlConfiguration.java +++ b/src/old-test/java/org/mvplugins/multiverse/inventories/TestCommentedYamlConfiguration.java @@ -1,6 +1,5 @@ package org.mvplugins.multiverse.inventories; -import org.mvplugins.multiverse.inventories.util.CommentedYamlConfiguration; import org.junit.Test; import java.io.File;