From 5d05cec9c84f152c8bb7d6235953547f0253030c Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Mon, 14 Jun 2021 13:00:31 +0100 Subject: [PATCH 001/134] Initial standalone commit --- pom.xml | 5 ++ .../configurationmaster/CMConfigOption.java | 33 +++++++ .../configurationmaster/CMConfigSection.java | 90 +++++++++++++++++++ .../InternalConfigFile.java | 60 +++++++++++++ 4 files changed, 188 insertions(+) create mode 100644 src/main/java/io/github/thatsmusic99/configurationmaster/CMConfigOption.java create mode 100644 src/main/java/io/github/thatsmusic99/configurationmaster/CMConfigSection.java create mode 100644 src/main/java/io/github/thatsmusic99/configurationmaster/InternalConfigFile.java diff --git a/pom.xml b/pom.xml index 8c80932..0a7003a 100644 --- a/pom.xml +++ b/pom.xml @@ -45,5 +45,10 @@ 13.0 + + org.yaml + snakeyaml + 1.28 + \ No newline at end of file diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/CMConfigOption.java b/src/main/java/io/github/thatsmusic99/configurationmaster/CMConfigOption.java new file mode 100644 index 0000000..5bf50c4 --- /dev/null +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/CMConfigOption.java @@ -0,0 +1,33 @@ +package io.github.thatsmusic99.configurationmaster; + +import java.util.List; + +public class CMConfigOption { + + private String path; + private Object option; + private StringBuilder comment = new StringBuilder(); + private String section = ""; + + public CMConfigOption(String path, Object option) { + this.path = path; + this.option = option; + } + + public CMConfigOption(String path, Object option, String comment) { + + } + + public Object get() { + return option; + } + + public String getPath() { + return path; + } + + public void addComments(List str) { + + comment.insert().append("\n\n").append(str); + } +} diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/CMConfigSection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/CMConfigSection.java new file mode 100644 index 0000000..00e7f60 --- /dev/null +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/CMConfigSection.java @@ -0,0 +1,90 @@ +package io.github.thatsmusic99.configurationmaster; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class CMConfigSection extends CMConfigOption { + + protected LinkedHashMap defaults; + protected LinkedHashMap existingValues; + protected LinkedHashMap actualValues; + protected List pendingComments; + protected CMConfigSection parent; + + public CMConfigSection() { + super("", null); + if (this instanceof InternalConfigFile) { + this.pendingComments = new ArrayList<>(); + this.parent = null; + } else { + throw new IllegalStateException(""); + } + } + + public CMConfigSection(String path, CMConfigSection parent) { + super(path, null); + this.parent = parent; + } + + @Override + public Object get() { + return this; + } + + public void addDefault(String path, Object defaultOption) { + CMConfigSection section = getConfigSection(path); + CMConfigOption option = new CMConfigOption(path, defaultOption); + section.defaults.put(path, option); + section.actualValues.put(path, section.existingValues.getOrDefault(path, option)); + } + + public void addDefaults(CMConfigOption... options) { + for (CMConfigOption option : options) { + if (!pendingComments.isEmpty()) { + option.addComments(pendingComments); + pendingComments.clear(); + } + String path = option.getPath(); + CMConfigSection section = getConfigSection(path); + section.defaults.put(path, option); + section.actualValues.put(path, section.existingValues.getOrDefault(path, option)); + } + } + + public CMConfigSection createConfigSection(String path) { + String[] sections = path.split("\\."); + CMConfigSection toEdit = this; + for (int i = 1; i < sections.length; i++) { + Object option = toEdit.existingValues.get(sections[i]); + if (option == null) { + option = new CMConfigSection(toEdit); + + } + } + } + + public CMConfigSection getConfigSection(String path) { + String[] sections = path.split("\\."); + CMConfigSection toEdit = this; + for (int i = 1; i < sections.length; i++) { + Object option = toEdit.existingValues.get(sections[i]); + if (option == null) { + option = + } + } + } + + public Map convertToMap() { + LinkedHashMap map = new LinkedHashMap<>(); + for (String path : actualValues.keySet()) { + if (actualValues.get(path) instanceof CMConfigSection) { + map.put(path, ((CMConfigSection) actualValues.get(path)).convertToMap()); + } else { + map.put(path, actualValues.get(path).get()); + } + } + return map; + } +} diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/InternalConfigFile.java b/src/main/java/io/github/thatsmusic99/configurationmaster/InternalConfigFile.java new file mode 100644 index 0000000..53690ea --- /dev/null +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/InternalConfigFile.java @@ -0,0 +1,60 @@ +package io.github.thatsmusic99.configurationmaster; + +import org.bukkit.configuration.file.YamlConstructor; +import org.bukkit.configuration.file.YamlRepresenter; +import org.jetbrains.annotations.NotNull; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.LoaderOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.representer.Representer; + +import java.io.*; +import java.util.HashMap; + +public class InternalConfigFile extends CMConfigSection { + + private final Yaml yaml; + private final DumperOptions yamlOptions = new DumperOptions(); + private final LoaderOptions loaderOptions = new LoaderOptions(); + private final Representer yamlRepresenter = new YamlRepresenter(); + private final File file; + private boolean isNew; + + public InternalConfigFile(@NotNull File file) { + yaml = new Yaml(new YamlConstructor(), yamlRepresenter, yamlOptions, loaderOptions); + yamlOptions.setIndent(2); + yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + this.file = file; + load(); + } + + public void load() throws FileNotFoundException { + BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); + StringBuilder content = new StringBuilder(); + try { + String line = reader.readLine(); + while (line != null) { + content.append(line).append("\n"); + line = reader.readLine(); + } + } catch (IOException e) { + e.printStackTrace(); + } + loadFromString(content.toString()); + } + + public void loadFromString(String str) { + + } + + public void save() { + + } + + public String saveToString() { + String dump = this.yaml.dump(convertToMap()); + } + + +} From ace01ceedbe616646c21904cbee816158293519e Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Mon, 14 Jun 2021 13:02:07 +0100 Subject: [PATCH 002/134] Added tests --- pom.xml | 7 +++++++ .../configurationmaster/ConfigTests.java | 15 +++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 src/main/tests/io/github/thatsmusic99/configurationmaster/ConfigTests.java diff --git a/pom.xml b/pom.xml index 0a7003a..0054af4 100644 --- a/pom.xml +++ b/pom.xml @@ -50,5 +50,12 @@ snakeyaml 1.28 + + junit + junit + 4.13.1 + test + + \ No newline at end of file diff --git a/src/main/tests/io/github/thatsmusic99/configurationmaster/ConfigTests.java b/src/main/tests/io/github/thatsmusic99/configurationmaster/ConfigTests.java new file mode 100644 index 0000000..44aadf8 --- /dev/null +++ b/src/main/tests/io/github/thatsmusic99/configurationmaster/ConfigTests.java @@ -0,0 +1,15 @@ +package io.github.thatsmusic99.configurationmaster; + +import org.junit.Test; + +import java.io.File; + +public class ConfigTests { + + @Test + public void testConfig() { + File file = new File("test.yml"); + InternalConfigFile config = new InternalConfigFile(file); + + } +} From 865c386cdf0e0292e678ddb6e580bc59eca0402a Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Wed, 23 Jun 2021 17:45:57 +0100 Subject: [PATCH 003/134] Added interfaces --- .../api/ConfigSection.java | 27 ++++++ .../api/MemorySection.java | 85 +++++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java create mode 100644 src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java new file mode 100644 index 0000000..30a5e37 --- /dev/null +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java @@ -0,0 +1,27 @@ +package io.github.thatsmusic99.configurationmaster.api; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface ConfigSection { + + void addDefault(@NotNull String path, @Nullable Object value); + + void addDefault(@NotNull String path, @Nullable Object value, @NotNull String comment); + + void addDefault(@NotNull String path, @Nullable Object value, @NotNull String section, @NotNull String comment); + + void addComment(@NotNull String path, @NotNull String comment); + + void addComment(@NotNull String comment); + + void moveTo(@NotNull String oldPath, @NotNull String newPath); + + void moveTo(@NotNull String oldPath, @NotNull String newPath, @NotNull ConfigFile otherFile); + + void addSection(@NotNull String section); + + void addExample(@NotNull String path, @Nullable Object value); + + void addExample(@NotNull String path, @Nullable Object value, @Nullable String comment); +} diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java new file mode 100644 index 0000000..5bf5fc8 --- /dev/null +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java @@ -0,0 +1,85 @@ +package io.github.thatsmusic99.configurationmaster.api; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public interface MemorySection { + + default String getString(@NotNull String path) { + return getString(path, null); + } + + String getString(@NotNull String path, @Nullable String defaultValue); + + default int getInteger(@NotNull String path) { + return getInteger(path, 0); + } + + int getInteger(@NotNull String path, int defaultValue); + + default double getDouble(@NotNull String path) { + return getDouble(path, 0.0); + } + + double getDouble(@NotNull String path, double defaultValue); + + default Object get(@NotNull String path) { + return get(path, null); + } + + Object get(@NotNull String path, @Nullable Object defaultValue); + + default boolean getBoolean(@NotNull String path) { + return getBoolean(path, false); + } + + boolean getBoolean(@NotNull String path, boolean defaultValue); + + default long getLong(@NotNull String path) { + return getLong(path, 0); + } + + long getLong(@NotNull String path, long defaultValue); + + default short getShort(@NotNull String path) { + return getShort(path, (short) 0); + } + + short getShort(@NotNull String path, short defaultValue); + + default byte getByte(@NotNull String path) { + return getByte(path, (byte) 0); + } + + byte getByte(@NotNull String path, byte defaultValue); + + default float getFloat(@NotNull String path) { + return getFloat(path, 0f); + } + + float getFloat(@NotNull String path, float defaultValue); + + default ConfigSection getSection(@NotNull String path) { + return getSection(path, null); + } + + ConfigSection getSection(@NotNull String path, @Nullable ConfigSection defaultValue); + + @NotNull + default List getList(@NotNull String path) { + return getList(path, new ArrayList<>()); + } + + @NotNull + default List getStringList(@NotNull String path) { + return getList(path, new ArrayList<>()); + } + + List getList(@NotNull String path, @Nullable List defaultValue); + + void set(@NotNull String path, @Nullable Object object); + +} From 8e78ce3ea3576375cd339bb13f3c9b0c2f686a2f Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Fri, 2 Jul 2021 15:58:18 +0100 Subject: [PATCH 004/134] Bumped version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0054af4..0d2f887 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.thatsmusic99 ConfigurationMaster - v1.0.2 + v2.0.0-ALPHA-1 From 14132615d1c2c1028a35bc4925fa710b29256ad8 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 3 Jul 2021 10:18:38 +0100 Subject: [PATCH 005/134] Deprecated CMFile altogether --- .../io/github/thatsmusic99/configurationmaster/CMFile.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/CMFile.java b/src/main/java/io/github/thatsmusic99/configurationmaster/CMFile.java index d4e96bd..d0101af 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/CMFile.java +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/CMFile.java @@ -33,7 +33,9 @@ * conventions and to make it easier for others to use and understand. * * @author Holly (Thatsmusic99) + * @deprecated Please use the ConfigFile class instead. */ +@Deprecated public abstract class CMFile { // The actual configuration file. @@ -1124,9 +1126,9 @@ public boolean isNew() { * * @return The config file as a FileConfiguration object. */ - @Nullable + @Deprecated public FileConfiguration getConfig() { - return config; + return YamlConfiguration.loadConfiguration(configFile); } /** From aedaa77f2c1bb961120a607ebdd005fcea127d75 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 3 Jul 2021 10:19:11 +0100 Subject: [PATCH 006/134] Added ConfigSection implementation --- .../configurationmaster/CMConfigSection.java | 90 --------- .../api/ConfigSection.java | 4 +- .../impl/CMConfigSection.java | 178 ++++++++++++++++++ 3 files changed, 181 insertions(+), 91 deletions(-) delete mode 100644 src/main/java/io/github/thatsmusic99/configurationmaster/CMConfigSection.java create mode 100644 src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/CMConfigSection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/CMConfigSection.java deleted file mode 100644 index 00e7f60..0000000 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/CMConfigSection.java +++ /dev/null @@ -1,90 +0,0 @@ -package io.github.thatsmusic99.configurationmaster; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -public class CMConfigSection extends CMConfigOption { - - protected LinkedHashMap defaults; - protected LinkedHashMap existingValues; - protected LinkedHashMap actualValues; - protected List pendingComments; - protected CMConfigSection parent; - - public CMConfigSection() { - super("", null); - if (this instanceof InternalConfigFile) { - this.pendingComments = new ArrayList<>(); - this.parent = null; - } else { - throw new IllegalStateException(""); - } - } - - public CMConfigSection(String path, CMConfigSection parent) { - super(path, null); - this.parent = parent; - } - - @Override - public Object get() { - return this; - } - - public void addDefault(String path, Object defaultOption) { - CMConfigSection section = getConfigSection(path); - CMConfigOption option = new CMConfigOption(path, defaultOption); - section.defaults.put(path, option); - section.actualValues.put(path, section.existingValues.getOrDefault(path, option)); - } - - public void addDefaults(CMConfigOption... options) { - for (CMConfigOption option : options) { - if (!pendingComments.isEmpty()) { - option.addComments(pendingComments); - pendingComments.clear(); - } - String path = option.getPath(); - CMConfigSection section = getConfigSection(path); - section.defaults.put(path, option); - section.actualValues.put(path, section.existingValues.getOrDefault(path, option)); - } - } - - public CMConfigSection createConfigSection(String path) { - String[] sections = path.split("\\."); - CMConfigSection toEdit = this; - for (int i = 1; i < sections.length; i++) { - Object option = toEdit.existingValues.get(sections[i]); - if (option == null) { - option = new CMConfigSection(toEdit); - - } - } - } - - public CMConfigSection getConfigSection(String path) { - String[] sections = path.split("\\."); - CMConfigSection toEdit = this; - for (int i = 1; i < sections.length; i++) { - Object option = toEdit.existingValues.get(sections[i]); - if (option == null) { - option = - } - } - } - - public Map convertToMap() { - LinkedHashMap map = new LinkedHashMap<>(); - for (String path : actualValues.keySet()) { - if (actualValues.get(path) instanceof CMConfigSection) { - map.put(path, ((CMConfigSection) actualValues.get(path)).convertToMap()); - } else { - map.put(path, actualValues.get(path).get()); - } - } - return map; - } -} diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java index 30a5e37..bfcac2d 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java @@ -3,7 +3,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -public interface ConfigSection { +public interface ConfigSection extends MemorySection { void addDefault(@NotNull String path, @Nullable Object value); @@ -24,4 +24,6 @@ public interface ConfigSection { void addExample(@NotNull String path, @Nullable Object value); void addExample(@NotNull String path, @Nullable Object value, @Nullable String comment); + + ConfigSection createConfigSection(@NotNull String path); } diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java new file mode 100644 index 0000000..81016eb --- /dev/null +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -0,0 +1,178 @@ +package io.github.thatsmusic99.configurationmaster.impl; + +import com.google.common.collect.Lists; +import io.github.thatsmusic99.configurationmaster.api.ConfigSection; +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public class CMConfigSection extends CMMemorySection implements ConfigSection { + + public CMConfigSection() { + super(); + } + + public CMConfigSection(String path, ConfigFile file) { + super(path, file); + } + + public void addDefault(@NotNull String path, Object defaultOption) { + addDefault(path, defaultOption, null, null); + } + + public void addDefault(@NotNull String path, Object defaultOption, @NotNull String comment) { + addDefault(path, defaultOption, null, comment); + } + + public void addDefault(@NotNull String path, Object defaultOption, @Nullable String section, @Nullable String comment) { + CMMemorySection cmSection = getSectionInternal(path); + if (cmSection == null) cmSection = createSectionInternal(path); + String key = path.substring(path.lastIndexOf('.') + 1); + List comments = Lists.newArrayList(getParent().getPendingComments()); + if (getParent().getComments().containsKey(path)) { + comments.add(getParent().getComments().get(path)); + } + if (section != null) { + comments.add("CONFIG_SECTION: " + section); + } + if (comment != null) { + comments.add(comment); + } + getParent().getPendingComments().clear(); + if (comments.size() > 0) { + StringBuilder builder = new StringBuilder(); + builder.append(comments.get(0)); + for (int i = 1; i < comments.size(); i++) { + builder.append("\n\n").append(comments.get(i)); + } + getParent().getComments().put(path, builder.toString()); + } + cmSection.defaults.put(key, defaultOption); + cmSection.actualValues.put(key, cmSection.existingValues.getOrDefault(key, defaultOption)); + } + + public void addComment(@NotNull String comment) { + getParent().getPendingComments().add(comment); + } + + @Override + public void moveTo(@NotNull String oldPath, @NotNull String newPath) { + if (!contains(oldPath)) return; + CMMemorySection oldCmSection = getSectionInternal(oldPath); + if (oldCmSection == null) return; + CMMemorySection newCmSection = getSectionInternal(newPath); + if (newCmSection == null) newCmSection = createSectionInternal(newPath); + String oldKey = oldPath.substring(oldPath.lastIndexOf('.') + 1); + Object movingValue = oldCmSection.existingValues.get(oldKey); + String newKey = newPath.substring(newPath.lastIndexOf('.') + 1); + newCmSection.actualValues.put(newKey, movingValue); + } + + @Override + public void moveTo(@NotNull String oldPath, @NotNull String newPath, @NotNull ConfigFile otherFile) { + if (!contains(oldPath)) return; + CMMemorySection oldCmSection = getSectionInternal(oldPath); + if (oldCmSection == null) return; + CMMemorySection newCmSection = otherFile.getSectionInternal(newPath); + if (newCmSection == null) newCmSection = otherFile.createSectionInternal(newPath); + String oldKey = oldPath.substring(oldPath.lastIndexOf('.') + 1); + Object movingValue = oldCmSection.existingValues.get(oldKey); + String newKey = newPath.substring(newPath.lastIndexOf('.') + 1); + newCmSection.actualValues.put(newKey, movingValue); + } + + public void addComment(String path, @NotNull String comment) { + String key = path.substring(path.lastIndexOf('.') + 1); + if (getParent().getComments().containsKey(path)) { + String newComment = getParent().getComments().get(path) + "\n\n" + comment; + getParent().getComments().put(getPathWithKey(key), newComment); + } else { + getParent().getComments().put(getPathWithKey(key), comment); + } + } + + public void addExample(@NotNull String path, Object object) { + addExample(path, object, null); + } + + public void addExample(@NotNull String path, Object object, String comment) { + if (!getParent().isNew()) { + CMMemorySection section = getSectionInternal(path); + if (section != null) { + String key = path.substring(path.lastIndexOf('.') + 1); + if (!section.existingValues.containsKey(key)) return; + } + } + getParent().getExamples().add(path); + addDefault(path, object, null, comment); + } + + public void makeSectionLenient(String path) { + CMMemorySection section = getSectionInternal(path); + if (section == null) section = createSectionInternal(path); + String key = path.substring(path.lastIndexOf('.') + 1); + section.actualValues.put(key, section.existingValues.getOrDefault(key, createConfigSection(path))); + } + + public void addSection(@NotNull String section) { + getParent().getPendingComments().add("CONFIG_SECTION: " + section); + } + + protected CMConfigSection createSectionInternal(@NotNull String path) { + return createConfigSection(path.substring(0, path.lastIndexOf('.'))); + } + + public CMConfigSection createConfigSection(@NotNull String path) { + String[] sections = path.split("\\."); + CMConfigSection toEdit = this; + for (int i = 0; i < sections.length; i++) { + Object option = toEdit.actualValues.get(sections[i]); + if (option == null) { + option = new CMConfigSection( + toEdit.getPath().length() == 0 ? sections[i] : toEdit.getPath() + "." + sections[i], + toEdit.getParent()); + toEdit.actualValues.put(sections[i], option); + toEdit = (CMConfigSection) option; + } else if (option instanceof CMConfigSection) { + toEdit = (CMConfigSection) option; + } else { + return null; + } + } + return toEdit; + } + + public Map convertToMap() { + LinkedHashMap map = new LinkedHashMap<>(); + for (String path : actualValues.keySet()) { + if (actualValues.get(path) instanceof CMConfigSection) { + map.put(path, ((CMConfigSection) actualValues.get(path)).convertToMap()); + } else { + map.put(path, actualValues.get(path)); + } + } + return map; + } + + public void mapToCM(Map map) { + for (Object keyObj : map.keySet()) { + String key = keyObj.toString(); + Object value = map.get(keyObj); + if (value instanceof Map) { + CMConfigSection section = new CMConfigSection( + getPath().length() == 0 ? key : "." + key, getParent()); + section.mapToCM((Map) value); + existingValues.put(key, section); + } else { + existingValues.put(key, value); + } + } + } + + private String getPathWithKey(String key) { + if (getPath().isEmpty()) return key; + return getPath() + "." + key; + } +} From a666d4863a2fb30be31dfa5a6d0795230bb15d07 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 3 Jul 2021 10:23:37 +0100 Subject: [PATCH 007/134] Added MemorySection implementation --- .../api/MemorySection.java | 11 +- .../impl/CMMemorySection.java | 193 ++++++++++++++++++ 2 files changed, 201 insertions(+), 3 deletions(-) create mode 100644 src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java index 5bf5fc8..d6e6e94 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java @@ -62,11 +62,13 @@ default float getFloat(@NotNull String path) { float getFloat(@NotNull String path, float defaultValue); - default ConfigSection getSection(@NotNull String path) { - return getSection(path, null); + default ConfigSection getConfigSection(@NotNull String path) { + return getConfigSection(path, null); } - ConfigSection getSection(@NotNull String path, @Nullable ConfigSection defaultValue); + ConfigSection getConfigSection(@NotNull String path, @Nullable ConfigSection defaultValue); + + boolean contains(@NotNull String path); @NotNull default List getList(@NotNull String path) { @@ -82,4 +84,7 @@ default List getStringList(@NotNull String path) { void set(@NotNull String path, @Nullable Object object); + List getKeys(boolean deep); + + } diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java new file mode 100644 index 0000000..f068511 --- /dev/null +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -0,0 +1,193 @@ +package io.github.thatsmusic99.configurationmaster.impl; + +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import io.github.thatsmusic99.configurationmaster.api.ConfigSection; +import io.github.thatsmusic99.configurationmaster.api.MemorySection; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public class CMMemorySection implements MemorySection { + + protected LinkedHashMap defaults; + protected LinkedHashMap existingValues; + protected LinkedHashMap actualValues; + protected String path; + protected ConfigFile parent; + + CMMemorySection() { + if (this instanceof ConfigFile) { + this.path = ""; + init(); + } else { + throw new IllegalStateException("SHUT UP. SHUT UP"); + } + } + + CMMemorySection(String path, ConfigFile parent) { + this.path = path; + this.parent = parent; + init(); + } + + private void init() { + this.defaults = new LinkedHashMap<>(); + this.existingValues = new LinkedHashMap<>(); + this.actualValues = new LinkedHashMap<>(); + } + + @Override + public String getString(@NotNull String path, @Nullable String defaultValue) { + CMMemorySection section = getSectionInternal(path); + if (section == null) return defaultValue; + String key = path.substring(path.lastIndexOf('.') + 1); + Object result = section.actualValues.getOrDefault(key, defaultValue); + if (result == null) return null; + return String.valueOf(result); + } + + @Override + public int getInteger(@NotNull String path, int defaultValue) { + String result = getString(path); + try { + return result == null ? defaultValue : Integer.parseInt(result); + } catch (NumberFormatException ex) { + return defaultValue; + } + } + + @Override + public double getDouble(@NotNull String path, double defaultValue) { + String result = getString(path); + try { + return result == null ? defaultValue : Double.parseDouble(result); + } catch (NumberFormatException ex) { + return defaultValue; + } + } + + @Override + public Object get(@NotNull String path, @Nullable Object defaultValue) { + CMMemorySection section = getSectionInternal(path); + if (section == null) return defaultValue; + String key = path.substring(path.lastIndexOf('.') + 1); + return section.actualValues.getOrDefault(key, defaultValue); + } + + @Override + public boolean getBoolean(@NotNull String path, boolean defaultValue) { + String result = getString(path); + if (result == null) return defaultValue; + if (!(result.equalsIgnoreCase("false") || result.equalsIgnoreCase("true"))) return defaultValue; + return result.equalsIgnoreCase("true"); + } + + @Override + public long getLong(@NotNull String path, long defaultValue) { + String result = getString(path); + try { + return result == null ? defaultValue : Long.parseLong(result); + } catch (NumberFormatException ex) { + return defaultValue; + } + } + + @Override + public short getShort(@NotNull String path, short defaultValue) { + String result = getString(path); + try { + return result == null ? defaultValue : Short.parseShort(result); + } catch (NumberFormatException ex) { + return defaultValue; + } + } + + @Override + public byte getByte(@NotNull String path, byte defaultValue) { + String result = getString(path); + try { + return result == null ? defaultValue : Byte.parseByte(result); + } catch (NumberFormatException ex) { + return defaultValue; + } + } + + @Override + public float getFloat(@NotNull String path, float defaultValue) { + String result = getString(path); + try { + return result == null ? defaultValue : Float.parseFloat(result); + } catch (NumberFormatException ex) { + return defaultValue; + } + } + + @Override + public ConfigSection getConfigSection(@NotNull String path, @Nullable ConfigSection defaultValue) { + CMMemorySection section = getSectionInternal(path); + if (section == null) return defaultValue; + String key = path.substring(path.lastIndexOf('.') + 1); + Object value = section.actualValues.getOrDefault(key, defaultValue); + return value instanceof ConfigSection ? (ConfigSection) value : defaultValue; + } + + @Override + public boolean contains(@NotNull String path) { + CMMemorySection section = getSectionInternal(path); + if (section == null) return false; + String key = path.substring(path.lastIndexOf('.') + 1); + return section.actualValues.containsKey(key); + } + + @Override + public List getList(@NotNull String path, @Nullable List defaultValue) { + CMMemorySection section = getSectionInternal(path); + if (section == null) return defaultValue; + String key = path.substring(path.lastIndexOf('.') + 1); + Object value = section.actualValues.getOrDefault(key, defaultValue); + if (!(value instanceof List)) { + value = new ArrayList<>(Collections.singletonList(value)); + } + return (List) value; + } + + @Override + public void set(@NotNull String path, @Nullable Object object) { + CMMemorySection section = getSectionInternal(path); + if (section == null) section = getParent().createConfigSection(path); + String key = path.substring(path.lastIndexOf('.') + 1); + section.actualValues.put(key, object); + } + + @Nullable + protected CMMemorySection getSectionInternal(@NotNull String path) { + CMMemorySection section = this; + while (path.indexOf('.') != -1 && section != null) { + String key = path.substring(0, path.indexOf('.')); + path = path.substring(path.indexOf('.') + 1); + section = (CMMemorySection) section.getConfigSection(key); + } + return section; + } + + public List getKeys(boolean deep) { + List keys = new ArrayList<>(); + for (String path : actualValues.keySet()) { + if (deep && actualValues.get(path) instanceof CMConfigSection) { + keys.addAll(((CMConfigSection) actualValues.get(path)).getKeys(true)); + } else { + keys.add(path); + } + } + return keys; + } + + public String getPath() { + return path; + } + + protected ConfigFile getParent() { + return this instanceof ConfigFile ? (ConfigFile) this : parent; + } +} From 32934e1f7548cf993197f146bde67c71ccb22802 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 3 Jul 2021 10:23:49 +0100 Subject: [PATCH 008/134] Added CommentWriter --- .../api/CommentWriter.java | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java b/src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java new file mode 100644 index 0000000..866b5b9 --- /dev/null +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java @@ -0,0 +1,127 @@ +package io.github.thatsmusic99.configurationmaster.api; + +import java.util.ArrayList; +import java.util.List; + +public class CommentWriter { + + private final ConfigFile config; + // The currently written lines of the file. + private List currentLines; + + protected CommentWriter(ConfigFile config) { + this.config = config; + this.currentLines = new ArrayList<>(); + } + + /** + * Initiates the comment writing process. + */ + protected void writeComments(List currentLines) { + this.currentLines = currentLines; + // For each comment to be made... + for (String path : config.getComments().keySet()) { + // Get all the divisions made in the config + String[] divisions = path.split("\\."); + + writeComment(path, divisions, 0, 0); + } + + // However, if there's any comments left, write them in. + for (String str : config.getPendingComments()) { + if (str.isEmpty()) { + currentLines.add(""); + } else { + currentLines.add(""); + String[] rawComment = str.split("\n"); + for (String commentPart : rawComment) { + if (commentPart.isEmpty()) { + currentLines.add(""); + } else { + if (commentPart.startsWith("CONFIG_SECTION: ")) { + String section = commentPart.split(": ")[1]; + StringBuilder length = new StringBuilder(); + length.append("###"); + for (int j = 0; j < section.length(); j++) { + length.append("#"); + } + length.append("###"); + currentLines.add(length.toString()); + currentLines.add("# " + section + " #"); + currentLines.add(length.toString()); + } else { + currentLines.add("# " + commentPart); + } + } + } + } + } + } + + /** + * Method used to write a specified comment. + * + * @param path The path the comment must be written at. + * @param divisions The number of sections the part can be split up into. + * @param iteration How far we're down the pathway (in terms of different sections). + * @param startingLine The line we're starting from. + */ + private void writeComment(String path, String[] divisions, int iteration, int startingLine) { + StringBuilder indent = new StringBuilder(); + for (int j = 0; j < iteration; j++) { + indent.append(" "); + } + // Go through each line in the file + for (int i = startingLine; i < currentLines.size(); i++) { + String line = currentLines.get(i); + // If the line doesn't have an equal or larger indent, then the line could not be found. + if (!line.startsWith(indent.toString())) return; + // If it's already a comment, leave it be. + if (line.startsWith("#")) continue; + if (line.startsWith(indent + divisions[iteration] + ":") || + line.startsWith(indent + "'" + divisions[iteration] + "':")) { + iteration += 1; + if (iteration == divisions.length) { + int currentLine = i; + if (iteration == 1) { + currentLines.add(currentLine, ""); + currentLine++; + } + String comment = config.getComments().get(path); + if (comment == null) continue; + String[] rawComment = comment.split("\n"); + for (String commentPart : rawComment) { + if (commentPart.isEmpty()) { + currentLines.add(currentLine, ""); + } else { + if (commentPart.startsWith("CONFIG_SECTION: ")) { + String section = commentPart.split(": ")[1]; + StringBuilder length = new StringBuilder(); + length.append("###"); + for (int j = 0; j < section.length(); j++) { + length.append("#"); + } + length.append("###"); + currentLines.add(currentLine, length.toString()); + currentLines.add(currentLine, "# " + section + " #"); + currentLines.add(currentLine, length.toString()); + currentLine += 3; + continue; + } else { + currentLines.add(currentLine, indent + "# " + commentPart); + } + } + currentLine++; + } + break; + } else { + writeComment(path, divisions, iteration, i + 1); + } + } + } + } + + public List getLines() { + return currentLines; + } +} From de7d954b34204e791fca07fd20f8924ad4ef60fb Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 3 Jul 2021 10:24:24 +0100 Subject: [PATCH 009/134] Replaced ConfigTests with a test of AT's --- .../AdvancedTeleportTest.java | 302 ++++++++++++++++++ .../configurationmaster/ConfigTests.java | 15 - 2 files changed, 302 insertions(+), 15 deletions(-) create mode 100644 src/main/tests/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java delete mode 100644 src/main/tests/io/github/thatsmusic99/configurationmaster/ConfigTests.java diff --git a/src/main/tests/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java b/src/main/tests/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java new file mode 100644 index 0000000..c9b37cb --- /dev/null +++ b/src/main/tests/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java @@ -0,0 +1,302 @@ +package io.github.thatsmusic99.configurationmaster; + +import com.google.common.collect.Lists; +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.junit.Assert; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; + +public class AdvancedTeleportTest { + + @Test + public void initATConfig() throws IOException { + File file = new File("test-config.yml"); + if (file.exists()) { + file.delete(); + } + file.createNewFile(); + ConfigFile config = ConfigFile.loadConfig(file); + + config.addComment("Another comment at the very top for all you lads :)"); + config.addDefault("use-basic-teleport-features", true, "Features", "Whether basic teleportation features should be enabled or not." + + "\nThis includes /tpa, /tpahere, /tpblock, /tpunblock and /back." + + "\nThis does not disable the command for other plugins - if you want other plugins to use the provided commands, use Bukkit's commands.yml file." + + "\nPlease refer to https://bukkit.gamepedia.com/Commands.yml for this!"); + + config.addDefault("use-warps", true, "Whether warps should be enabled in the plugin."); + config.addDefault("use-spawn", true, "Whether the plugin should modify spawn/spawn properties."); + config.addDefault("use-randomtp", true, "Whether the plugin should allow random teleportation."); + config.addDefault("use-homes", true, "Whether homes should be enabled in the plugin."); + config.addDefault("disabled-commands", new ArrayList<>(), "The commands that AT should not register upon starting up.\n" + + "In other words, this gives up the command for other plugins to use.\n" + + "NOTE: If you are using Essentials with AT and want AT to give up its commands to Essentials, Essentials does NOT go down without a fight. Jesus Christ. You'll need to restart the server for anything to change."); + + config.addSection("Teleport Requesting"); + config.addDefault("request-lifetime", 60, "\u2770 How long tpa and tpahere requests last before expiring."); + config.addDefault("allow-multiple-requests", true, "Whether or not the plugin should enable the use of multiple requests.\n" + + "When enabled, user 1 may get TPA requests from user 2 and 3, but user 1 is prompted to select a specific request.\n" + + "When this is disabled and user 1 receives requests from user 2 and then 3, they will only have user 3's request to respond to."); + config.addDefault("notify-on-expire", true, "Let the player know when their request has timed out or been displaced by another user's request.\n" + + "Displacement only occurs when allow-multiple-requests is disabled."); + // addDefault("tpa-restrict-movement-on", "requester"); + // addDefault("tpahere-restrict-movement-on", "requester"); + + config.addDefault("warm-up-timer-duration", 3, "Warm-Up Timers", "The number of seconds it takes for the teleportation to take place following confirmation.\n" + + "(i.e. \"You will teleport in 3 seconds!\")\n" + + "This acts as the default option for the per-command warm-ups."); + config.addDefault("cancel-warm-up-on-rotation", true, "Whether or not teleportation should be cancelled if the player rotates or moves."); + config.addDefault("cancel-warm-up-on-movement", true, "Whether or not teleportation should be cancelled upon movement only."); + + config.addComment("per-command-warm-ups", "Command-specific warm-ups."); + config.addDefault("per-command-warm-ups.tpa", "default", "Warm-up timer for /tpa."); + config.addDefault("per-command-warm-ups.tpahere", "default", "Warm-up timer for /tpahere"); + config.addDefault("per-command-warm-ups.tpr", "default", "Warm-up timer for /tpr, or /rtp."); + config.addDefault("per-command-warm-ups.warp", "default", "Warm-up timer for /warp"); + config.addDefault("per-command-warm-ups.spawn", "default", "Warm-up timer for /spawn"); + config.addDefault("per-command-warm-ups.home", "default", "Warm-up timer for /home"); + config.addDefault("per-command-warm-ups.back", "default", "Warm-up timer for /back"); + + config.addDefault("cooldown-duration", 5, "Cooldowns", "How long before the user can use a command again.\n" + + "This stops users spamming commands repeatedly.\n" + + "This is also the default cooldown period for all commands."); + config.addDefault("add-cooldown-duration-to-warm-up", true, "Adds the warm-up duration to the cooldown duration.\n" + + "For example, if the cooldown duration was 5 seconds but the warm-up was 3, the cooldown becomes 8 seconds long."); + config.addDefault("apply-cooldown-to-all-commands", false, "Whether or not the cooldown of one command will stop a user from using all commands.\n" + + "For example, if a player used /tpa with a cooldown of 10 seconds but then used /tpahere with a cooldown of 5, the 10-second cooldown would still apply.\n" + + "On the other hand, if a player used /tpahere, the cooldown of 5 seconds would apply to /tpa and other commands."); + config.addDefault("apply-cooldown-after", "request", "When to apply the cooldown\n" + + "Options include:\n" + + "- request - Cooldown starts as soon as any teleport command is made and still applies even if no teleport takes place (i.e. cancelled by movement or not accepted).\n" + + "- accept - Cooldown starts only when the teleport request is accepted (with /tpyes) and still applies even if no teleport takes place (i.e. cancelled by movement).\n" + + "- teleport - Cooldown starts only when the teleport actually happens.\n" + + "Note:\n" + + "'request' and 'accept' behave the same for /rtp, /back, /spawn, /warp, and /home\n" + + "cooldown for /tpall always starts when the command is ran, regardless if any player accepts or teleports"); + + config.addComment("per-command-cooldowns", "Command-specific cooldowns."); + config.addDefault("per-command-cooldowns.tpa", "default", "Cooldown for /tpa."); + config.addDefault("per-command-cooldowns.tpahere", "default", "Cooldown for /tpahere"); + config.addDefault("per-command-cooldowns.tpr", "default", "Cooldown for /tpr, or /rtp."); + config.addDefault("per-command-cooldowns.warp", "default", "Cooldown for /warp"); + config.addDefault("per-command-cooldowns.spawn", "default", "Cooldown for /spawn"); + config.addDefault("per-command-cooldowns.home", "default", "Cooldown for /home"); + config.addDefault("per-command-cooldowns.back", "default", "Cooldown for /back"); + // addDefault("per-command-cooldowns.sethome", "default", "Cooldown for /sethome"); + // addDefault("per-command-cooldowns.setwarp", "default", "Cooldown for /setwarp"); + + config.addDefault("cost-amount", 100.0, "Teleportation Costs", "The amount it costs to teleport somewhere." + + "\nIf you want to use Vault Economy, use 100.0 to charge $100." + + "\nIf you want to use Minecraft EXP points, use 10EXP for 10 EXP Points." + + "\nIf you want to use Minecraft EXP levels, use 5LVL for 5 levels." + + "\nIf you want to use items, use the format MATERIAL:AMOUNT or MATERIAL:AMOUNT:BYTE." + + "\nFor example, on 1.13+, ORANGE_WOOL:3 for 3 orange wool, but on versions before 1.13, WOOL:3:1." + + "\nIf you're on a legacy version and unsure on what byte to use, see https://minecraftitemids.com/types" + + "\nTo use multiple methods of charging, use a ; - e.g. '100.0;10LVL' for $100 and 10 EXP levels." + + "\nTo disable, just put an empty string, i.e. ''"); + + config.addComment("per-command-cost", "Command-specific costs."); + config.addDefault("per-command-cost.tpa", "default", "Cost for /tpa."); + config.addDefault("per-command-cost.tpahere", "default", "Cost for /tpahere."); + config.addDefault("per-command-cost.tpr", "default", "Cost for /tpr, or /rtp."); + config.addDefault("per-command-cost.warp", "default", "Cost for /warp"); + config.addDefault("per-command-cost.spawn", "default", "Cost for /spawn"); + config.addDefault("per-command-cost.home", "default", "Cost for /home"); + config.addDefault("per-command-cost.back", "default", "Cost for /back"); + //addDefault("per-command-cost.sethome", "default", "Cost for /sethome"); + //addDefault("pet-command-cost.setwarp", "default", "Cost for /setwarp"); + + config.addSection("SQL Storage"); + + config.addDefault("use-mysql", false, "Whether the plugin should use SQL storage or not.\n" + + "By default, AT uses SQLite storage, which stores data in a .db file locally."); + config.addDefault("mysql-host", "127.0.0.1", "The MySQL host to connect to."); + config.addDefault("mysql-port", 3306, "The port to connect to."); + config.addDefault("mysql-database", "database", "The database to connect to."); + config.addDefault("mysql-username", "username", "The username to use when connecting."); + config.addDefault("mysql-password", "password", "The password to use when connecting."); + config.addDefault("mysql-table-prefix", "advancedtp", "The prefix of all AT tables. \n" + + "If you're on Bungee, you may want to add your server's name to the end."); + + config.addDefault("enable-distance-limitations", false, "Distance Limitations", + "Enables the distance limiter to stop players teleporting over a large distance.\n" + + "This is only applied when people are teleporting in the same world."); + config.addDefault("maximum-teleport-distance", 1000, "The maximum distance that a player can teleport.\n" + + "This is the default distance applied to all commands when specified."); + config.addDefault("monitor-all-teleports-distance", false, "Whether or not all teleportations - not just AT's - should be checked for distance."); + + config.addComment("per-command-distance-limitations", "Determines the distance limit for each command."); + config.addDefault("per-command-distance-limitations.tpa", "default", "Distance limit for /tpa"); + config.addDefault("per-command-distance-limitations.tpahere", "default", "Distance limit for /tpahere"); + config.addDefault("per-command-distance-limitations.tpr", "default", "Distance limit for /tpr"); + config.addDefault("per-command-distance-limitations.warp", "default", "Distance limit for /warp"); + config.addDefault("per-command-distance-limitations.spawn", "default", "Distance limit for /spawn"); + config.addDefault("per-command-distance-limitations.home", "default", "Distance limit for /home"); + config.addDefault("per-command-distance-limitations.back", "default", "Distance limit for /back"); + + config.addSection("Teleportation Limitations"); + + config.addComment("WARNING: A lot of the options below are considered advanced and use special syntax that is not often accepted in YAML.\n" + + "When using such options, wrap them in quotes: ''\n" + + "As an example, 'stop-teleportation-out:world,world_nether'"); + + config.addDefault("enable-teleport-limitations", false, + "Enables teleport limitations. This means cross-world or even world teleportation can be limited within specific worlds."); + config.addDefault("monitor-all-teleports-limitations", false, "Whether or not all teleportation - not just AT's - should be checked to see if teleportation is allowed."); + + config.addComment("world-rules", "The teleportation rules defined for each world.\n" + + "Rules include:\n" + + "- stop-teleportation-out - Stops players teleporting to another world when they are in this world.\n" + + "- stop-teleportation-within - Stops players teleporting within the world.\n" + + "- stop-teleportation-into - Stops players teleporting into this world.\n" + + "To combine multiple rules, use a ; - e.g. stop-teleportation-out;stop-teleportation-within\n" + + "For out and into rules, you can make it so that rules only initiate when in or going to a specific world using :, e.g. stop-teleportation-out:world stops players teleporting to \"world\" in the world they're currently in.\n" + + "To do the opposite (i.e. initiates the rule when users are not in the specified world), use !, e.g. stop-teleportation-into!world stops teleportation into a specific world if they are not in \"world\". If ! and : are used in the same rule, then : is given top priority." + + "To make this rule work with multiple worlds, use a comma (,), e.g. stop-teleportation-into:world,world_nether"); + + config.makeSectionLenient("world-rules"); + config.addDefault("world-rules.default", "stop-teleportation-within"); + config.addExample("world-rules.world", "default"); + config.addExample("world-rules.world_nether", "stop-teleportation-into!world", "Stops people teleporting into the Nether if they're not coming from \"world\""); + + config.addComment("command-rules", "The teleportation rules defined for each AT command.\n" + + "Rules include:\n" + + "- override - The command will override world rules and run regardless.\n" + + "- ignore - The command will refuse to run regardless of world rules.\n" + + "To combine multiple rules, use a ;.\n" + + "To make rules behave differently in different worlds, use : to initiate the rule in a specific world (e.g. override:world to make the command override \"world\"'s rules.)\n" + + "To initiate rules outside of a specific world, use ! (e.g. override!world to make the command override world rules everywhere but in world)\n" + + "To use multiple worlds, use a comma (,).\n" + + "By default, all commands will comply with the world rules. If no rules are specified, they will comply.\n" + + "All worlds specified will be considered the world in which the player is currently in. For worlds being teleported to, add > to the start of the world name.\n" + + "For example, ignore:world,>world_nether will not run if the player is in \"world\" or if the player is going into the Nether."); + config.addDefault("command-rules.tpa", ""); + config.addDefault("command-rules.tpahere", ""); + config.addDefault("command-rules.tpr", ""); + config.addDefault("command-rules.warp", ""); + config.addDefault("command-rules.spawn", ""); + config.addDefault("command-rules.home", ""); + config.addDefault("command-rules.back", ""); + + config.addDefault("maximum-x", 5000, "RandomTP", "The maximum X coordinate to go up to when selecting a random location."); + config.addDefault("maximum-z", 5000, "The maximum Z coordinate to go up to when selecting a random location."); + config.addDefault("minimum-x", -5000, "The minimum X coordinate to go down to when selecting a random location."); + config.addDefault("minimum-z", -5000, "The minimum Z coordinate to go down to when selecting a random location."); + config.addDefault("use-world-border", true, "When WorldBorder is installed, AT will check the border of each world instead rather than using the minimum and maximum coordinates."); + config.addDefault("use-rapid-response", true, "Use the new rapid response system for RTP.\n" + + "This means valid locations are prepared before a user chooses to use /tpr or interact with a sign, meaning they are ready for use and can instantly TP a player.\n" + + "This feature allows you to use the \"tpr\" death option in the death management section further down.\n" + + "IMPORTANT NOTE - this feature only works on the Paper server type and any of its forks. It is not considered safe to use on Spigot or Bukkit."); + config.addDefault("prepared-locations-limit", 3, "How many locations can be prepared per world when using AT's Rapid Response system.\n" + + "These are immediately prepared upon startup and when a world is loaded."); + config.addDefault("ignore-world-generators", new ArrayList<>(Arrays.asList( + "us.talabrek.ultimateskyblock.world.SkyBlockChunkGenerator", + "us.talabrek.ultimateskyblock.world.SkyBlockNetherChunkGenerator", + "world.bentobox.bskyblock.generators.ChunkGeneratorWorld", + "world.bentobox.acidisland.world.ChunkGeneratorWorld", + "world.bentobox.oneblock.generators.ChunkGeneratorWorld", + "com.wasteofplastic.askyblock.generators.ChunkGeneratorWorld", + "com.wasteofplastic.acidisland.generators.ChunkGeneratorWorld", + "b.a", + "com.chaseoes.voidworld.VoidWorld.VoidWorldGenerator", + "club.bastonbolado.voidgenerator.EmptyChunkGenerator")), "AT's Rapid Response system automatically loads locations for each world, but can be problematic on some worlds, mostly SkyBlock worlds.\n" + + "In response, this list acts as pro-active protection and ignores worlds generated using the following generators.\n" + + "This is provided as an option so you can have control over which worlds have locations load."); + config.addDefault("avoid-blocks", new ArrayList<>(Arrays.asList("WATER", "LAVA", "STATIONARY_WATER", "STATIONARY_LAVA")), + "Blocks that people must not be able to land in when using /tpr."); + config.addDefault("avoid-biomes", new ArrayList<>(Arrays.asList("OCEAN", "DEEP_OCEAN")), "Biomes that the plugin should avoid when searching for a location."); + config.addDefault("whitelist-worlds", false, "Whether or not /tpr should only be used in the worlds listed below."); + config.addDefault("redirect-to-whitelisted-worlds", true, "Whether or not players should be directed to a whitelisted world when using /tpr.\n" + + "When this option is disabled and the player tries to use /tpr in a non-whitelisted world, the command simply won't work."); + config.addDefault("allowed-worlds", new ArrayList<>(Arrays.asList("world", "world_nether")), "Worlds you can use /tpr in.\n" + + "If a player uses /tpr in a world that doesn't allow it, they will be teleported in the first world on the list instead.\n" + + "To make this feature effective, turn on \"whitelist-worlds\" above."); + + + config.addDefault("default-homes-limit", -1, "Homes", "The default maximum of homes people can have.\n" + + "This can be overridden by giving people permissions such as at.member.homes.10.\n" + + "To disable this, use -1 as provided by default."); + config.addDefault("add-bed-to-homes", true, "Whether or not the bed home should be added to /homes."); + config.addDefault("deny-homes-if-over-limit", false, "Whether or not players should be denied access to some of their homes if they exceed their homes limit.\n" + + "The homes denied access to will end up being their most recently set homes.\n" + + "For example, having homes A, B, C, D and E with a limit of 3 will deny access to D and E."); + config.addDefault("hide-homes-if-denied", false, "If homes should be hidden from /homes should they be denied access.\n" + + "If this is false, they will be greyed out in the /homes list."); + + config.addDefault("tpa-request-received", "none", "Notifications/Sounds", + "The sound played when a player receives a teleportation (tpa) request.\n" + + "For 1.16+, check https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Sound.html for a list of sounds you can use\n" + + "For 1.15 and below, check https://www.spigotmc.org/threads/sounds-spigot-1-7-1-14-4-sound-enums.340452/ for a list of sounds down to 1.7.\n" + + "(Friendly reminder that 1.7.x is not supported though!)\n" + + "Set to \"none\" if you want no sound playing."); + config.addDefault("tpa-request-sent", "none", "The sound played when a player sends a teleportation (tpa) request."); + config.addDefault("tpahere-request-received", "none", "The sound played when a player receives a teleportation (tpahere) request."); + config.addDefault("tpahere-request-sent", "none", "The sound played when a player sends a teleportation (tpahere) request."); + + config.addDefault("used-teleport-causes", new ArrayList<>(Arrays.asList("COMMAND", "PLUGIN", "SPECTATE")), "Back", + "The teleport causes that the plugin must listen to allow players to teleport back to the previous location.\n" + + "You can see a full list of these causes at https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/player/PlayerTeleportEvent.TeleportCause.html"); + config.addDefault("back-search-radius", 5, "The cubic radius to search for a safe block when using /back.\n" + + "If a player teleports from an unsafe location and uses /back to return to it, the plugin will search all blocks within this radius to see if it is a safe place for the player to be moved to.\n" + + "It is recommend to avoid setting this option too high as this can have a worst case execution time of O(n^3) (e.g. run 27 times, 64, 125, 216 and so on).\n" + + "To disable, either set to 0 or -1."); + + + config.addDefault("teleport-to-spawn-on-first-join", true, "Spawn Management", + "Whether the player should be teleported to the spawnpoint when they join for the first time."); + config.addDefault("teleport-to-spawn-on-every-join", false, + "Whether the player should be teleported to the spawnpoint every time they join."); + + config.addComment("death-management", "Determines how and where players teleport when they die.\n" + + "Options include:\n" + + "- spawn - Teleports the player to the spawnpoint of either the world or specified by the plugin.\n" + + "- bed - Teleports to the player's bed.\n" + + "- anchor - 1.16+ only, teleports to the player's respawn anchor. However, due to limitations with Spigot's API, it may or may not always work. (add Player#getRespawnAnchor pls)\n" + + "- warp:Warp Name - Teleports the player to a specified warp. For example, if you want to teleport to Hub, you'd type warp:Hub\n" + + "- tpr - Teleports the player to a random location. Can only be used when the rapid response system is enabled." + + "- {default} - Uses the default respawn option, which is spawn unless set differently.\n" + + "If you're using EssentialsX Spawn and want AT to take over respawn mechanics, set respawn-listener-priority in EssX's config.yml file to lowest."); + + config.makeSectionLenient("death-management"); + config.addDefault("death-management.default", "spawn"); + config.addExample("death-management.world", "{default}"); + config.addExample("death-management.special-world", "warp:Special"); + config.addExample("death-management.another-world", "bed"); + + config.addDefault("default-permissions", new ArrayList<>(Arrays.asList("at.member.*", "at.member.warp.*")), "Permissions", + "The default permissions given to users without OP.\n" + + "By default, Advanced Teleport allows users without OP to use all member features.\n" + + "This allows for permission management without a permissions plugin, especially if a user doesn't understand how such plugins work.\n" + + "However, if you have a permissions plugin and Vault installed, you cannot make admin permissions work by default."); + config.addDefault("allow-admin-permissions-as-default-perms", false, "Allows admin permissions to be allowed as default permissions by default.\n" + + "If you want to use admin permissions, it's often recommended to use a permissions plugin such as LuckPerms.\n" + + "Do not enable this if you are unsure of the risks this option proposes."); + + config.save(); + config.reload(); + + Assert.assertTrue(config.getBoolean("use-basic-teleport-features")); + Assert.assertTrue(config.getBoolean("use-warps")); + Assert.assertTrue(config.getBoolean("use-randomtp")); + Assert.assertTrue(config.getBoolean("use-homes")); + Assert.assertEquals(new ArrayList<>(), config.getStringList("disabled-commands")); + + Assert.assertEquals(60, config.getInteger("request-lifetime")); + Assert.assertTrue(config.getBoolean("allow-multiple-requests")); + Assert.assertTrue(config.getBoolean("notify-on-expire")); + + Assert.assertEquals(3, config.getInteger("warm-up-timer-duration")); + Assert.assertTrue(config.getBoolean("cancel-warm-up-on-rotation")); + Assert.assertTrue(config.getBoolean("cancel-warm-up-on-movement")); + + Assert.assertEquals("default", config.getString("per-command-warm-ups.tpa")); + + config.set("cooldown-duration", "60"); + Assert.assertEquals("60", config.getString("cooldown-duration")); + Assert.assertEquals(60, config.getInteger("cooldown-duration")); + Assert.assertEquals(Lists.newArrayList(), config.getList("disabled-commands")); + } +} diff --git a/src/main/tests/io/github/thatsmusic99/configurationmaster/ConfigTests.java b/src/main/tests/io/github/thatsmusic99/configurationmaster/ConfigTests.java deleted file mode 100644 index 44aadf8..0000000 --- a/src/main/tests/io/github/thatsmusic99/configurationmaster/ConfigTests.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.github.thatsmusic99.configurationmaster; - -import org.junit.Test; - -import java.io.File; - -public class ConfigTests { - - @Test - public void testConfig() { - File file = new File("test.yml"); - InternalConfigFile config = new InternalConfigFile(file); - - } -} From ef00ed61e96c2ad1c79a97a7abc24ca822d99838 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 3 Jul 2021 10:38:49 +0100 Subject: [PATCH 010/134] Renamed InternalConfigFile to ConfigFile --- .../InternalConfigFile.java | 60 ------- .../configurationmaster/api/ConfigFile.java | 158 ++++++++++++++++++ 2 files changed, 158 insertions(+), 60 deletions(-) delete mode 100644 src/main/java/io/github/thatsmusic99/configurationmaster/InternalConfigFile.java create mode 100644 src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/InternalConfigFile.java b/src/main/java/io/github/thatsmusic99/configurationmaster/InternalConfigFile.java deleted file mode 100644 index 53690ea..0000000 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/InternalConfigFile.java +++ /dev/null @@ -1,60 +0,0 @@ -package io.github.thatsmusic99.configurationmaster; - -import org.bukkit.configuration.file.YamlConstructor; -import org.bukkit.configuration.file.YamlRepresenter; -import org.jetbrains.annotations.NotNull; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.LoaderOptions; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.representer.Representer; - -import java.io.*; -import java.util.HashMap; - -public class InternalConfigFile extends CMConfigSection { - - private final Yaml yaml; - private final DumperOptions yamlOptions = new DumperOptions(); - private final LoaderOptions loaderOptions = new LoaderOptions(); - private final Representer yamlRepresenter = new YamlRepresenter(); - private final File file; - private boolean isNew; - - public InternalConfigFile(@NotNull File file) { - yaml = new Yaml(new YamlConstructor(), yamlRepresenter, yamlOptions, loaderOptions); - yamlOptions.setIndent(2); - yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - this.file = file; - load(); - } - - public void load() throws FileNotFoundException { - BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); - StringBuilder content = new StringBuilder(); - try { - String line = reader.readLine(); - while (line != null) { - content.append(line).append("\n"); - line = reader.readLine(); - } - } catch (IOException e) { - e.printStackTrace(); - } - loadFromString(content.toString()); - } - - public void loadFromString(String str) { - - } - - public void save() { - - } - - public String saveToString() { - String dump = this.yaml.dump(convertToMap()); - } - - -} diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java new file mode 100644 index 0000000..040a61f --- /dev/null +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -0,0 +1,158 @@ +package io.github.thatsmusic99.configurationmaster.api; + +import com.google.common.collect.Lists; +import io.github.thatsmusic99.configurationmaster.impl.CMConfigSection; +import org.bukkit.configuration.file.YamlConstructor; +import org.bukkit.configuration.file.YamlRepresenter; +import org.jetbrains.annotations.NotNull; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.LoaderOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.error.YAMLException; +import org.yaml.snakeyaml.representer.Representer; + +import java.io.*; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ConfigFile extends CMConfigSection { + + private final Yaml yaml; + private final DumperOptions yamlOptions = new DumperOptions(); + private final LoaderOptions loaderOptions = new LoaderOptions(); + private final Representer yamlRepresenter = new YamlRepresenter(); + private final File file; + private boolean isNew = false; + private CommentWriter writer; + protected List pendingComments; + protected HashMap comments; + protected List examples; + + /** + * Used to load a config file without safety precautions taken by the API. + * + * @param file The config file to be loaded. + */ + public ConfigFile(@NotNull File file) { + yaml = new Yaml(new YamlConstructor(), yamlRepresenter, yamlOptions, loaderOptions); + yamlOptions.setIndent(2); + yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + this.file = file; + writer = new CommentWriter(this); + pendingComments = new ArrayList<>(); + comments = new HashMap<>(); + examples = new ArrayList<>(); + loadWithExceptions(); + } + + public static ConfigFile loadConfig(File file) { + try { + return new ConfigFile(file); + } catch (YAMLException e) { + File tempFile = new File(file.getParentFile(), + file.getName().substring(0, file.getName().lastIndexOf(".")) + + "-errored-" + System.currentTimeMillis() + ".yml"); + + try { + if (!tempFile.exists()) { + tempFile.createNewFile(); + } + Files.copy(file.toPath(), tempFile.toPath()); + } catch (IOException ioException) { + ioException.printStackTrace(); + } + System.out.println("YAMLException caught - there is a syntax error in the config."); + e.printStackTrace(); + return new ConfigFile(tempFile); + } + } + + public void loadWithExceptions() { + BufferedReader reader; + try { + reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); + } catch (FileNotFoundException ex) { + try { + file.createNewFile(); + reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); + } catch (IOException e) { + e.printStackTrace(); + return; + } + } + + StringBuilder content = new StringBuilder(); + try { + String line = reader.readLine(); + while (line != null) { + content.append(line).append("\n"); + line = reader.readLine(); + } + } catch (IOException e) { + e.printStackTrace(); + } + if (content.length() == 0) isNew = true; + loadFromString(content.toString()); + } + + public void loadFromString(String str) { + Map map = this.yaml.load(str); + if (map != null) { + mapToCM(map); + } + } + + public void save() throws IOException { + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + try { + writer.write(saveToString()); + } finally { + writer.close(); + } + } + + public void reload() throws IOException { + actualValues.clear(); + existingValues.clear(); + loadWithExceptions(); + for (String defaultOption : defaults.keySet()) { + if (!examples.contains(defaultOption)) { + addDefault(defaultOption, defaults.get(defaultOption)); + } + } + save(); + } + + public boolean isNew() { + return isNew; + } + + public String saveToString() { + String dump = this.yaml.dump(convertToMap()); + if (dump.equals("{}")) { + dump = ""; + } + writer.writeComments(Lists.newArrayList(dump.split("\n"))); + StringBuilder result = new StringBuilder(); + for (String line : writer.getLines()) { + result.append(line).append("\n"); + } + return result.toString(); + } + + public HashMap getComments() { + return comments; + } + + public List getPendingComments() { + return pendingComments; + } + + public List getExamples() { + return examples; + } +} From 44d4706b542fa5646e385e9fd2519a17f717c475 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 3 Jul 2021 10:39:03 +0100 Subject: [PATCH 011/134] get rid of this, this sucks --- .../configurationmaster/CMConfigOption.java | 33 ------------------- 1 file changed, 33 deletions(-) delete mode 100644 src/main/java/io/github/thatsmusic99/configurationmaster/CMConfigOption.java diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/CMConfigOption.java b/src/main/java/io/github/thatsmusic99/configurationmaster/CMConfigOption.java deleted file mode 100644 index 5bf50c4..0000000 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/CMConfigOption.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.github.thatsmusic99.configurationmaster; - -import java.util.List; - -public class CMConfigOption { - - private String path; - private Object option; - private StringBuilder comment = new StringBuilder(); - private String section = ""; - - public CMConfigOption(String path, Object option) { - this.path = path; - this.option = option; - } - - public CMConfigOption(String path, Object option, String comment) { - - } - - public Object get() { - return option; - } - - public String getPath() { - return path; - } - - public void addComments(List str) { - - comment.insert().append("\n\n").append(str); - } -} From d327dbd980271264651c0035a18dc3a1d9b3195d Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 3 Jul 2021 17:19:21 +0100 Subject: [PATCH 012/134] Add any pending comments to the parent section rather than actual option --- .../configurationmaster/impl/CMConfigSection.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 81016eb..e806422 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -30,7 +30,12 @@ public void addDefault(@NotNull String path, Object defaultOption, @Nullable Str CMMemorySection cmSection = getSectionInternal(path); if (cmSection == null) cmSection = createSectionInternal(path); String key = path.substring(path.lastIndexOf('.') + 1); + // Move comments to parent option List comments = Lists.newArrayList(getParent().getPendingComments()); + String parentSection = path.substring(0, path.indexOf('.') == -1 ? path.length() : path.indexOf('.')); + addComments(parentSection, comments.toArray(new String[]{})); + comments.clear(); + // Then handle the comments for the actual option if (getParent().getComments().containsKey(path)) { comments.add(getParent().getComments().get(path)); } From f624b1d702f75c60f47835c49507d325c38e83d4 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 3 Jul 2021 17:20:04 +0100 Subject: [PATCH 013/134] Fixed addComment(String, String) only working for sections, not actual options --- .../configurationmaster/impl/CMConfigSection.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index e806422..61693e5 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -88,13 +88,12 @@ public void moveTo(@NotNull String oldPath, @NotNull String newPath, @NotNull Co newCmSection.actualValues.put(newKey, movingValue); } - public void addComment(String path, @NotNull String comment) { - String key = path.substring(path.lastIndexOf('.') + 1); + public void addComment(@NotNull String path, @NotNull String comment) { if (getParent().getComments().containsKey(path)) { String newComment = getParent().getComments().get(path) + "\n\n" + comment; - getParent().getComments().put(getPathWithKey(key), newComment); + getParent().getComments().put(path, newComment); } else { - getParent().getComments().put(getPathWithKey(key), comment); + getParent().getComments().put(path, comment); } } From 6767d0ab8502da975c2a07c48aa62f68ea08697b Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 3 Jul 2021 17:21:43 +0100 Subject: [PATCH 014/134] Added ConfigSection#addComments(String, String...) --- .../configurationmaster/api/ConfigSection.java | 2 ++ .../configurationmaster/impl/CMConfigSection.java | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java index bfcac2d..96ea4f8 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java @@ -15,6 +15,8 @@ public interface ConfigSection extends MemorySection { void addComment(@NotNull String comment); + void addComments(@NotNull String path, @NotNull String... comments); + void moveTo(@NotNull String oldPath, @NotNull String newPath); void moveTo(@NotNull String oldPath, @NotNull String newPath, @NotNull ConfigFile otherFile); diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 61693e5..756b575 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -97,6 +97,16 @@ public void addComment(@NotNull String path, @NotNull String comment) { } } + public void addComments(@NotNull String path, @NotNull String... comments) { + if (comments.length == 0) return; + StringBuilder builder = new StringBuilder(); + builder.append(comments[0]); + for (int i = 1; i < comments.length; i++) { + builder.append("\n\n").append(comments[i]); + } + addComment(path, builder.toString()); + } + public void addExample(@NotNull String path, Object object) { addExample(path, object, null); } From 1712bf941b409d558e815e0e5df4073f208b3fed Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 3 Jul 2021 17:22:22 +0100 Subject: [PATCH 015/134] Throw IllegalStateException when trying to make a section where an option exists --- .../thatsmusic99/configurationmaster/impl/CMConfigSection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 756b575..a9ae4a2 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -152,7 +152,7 @@ public CMConfigSection createConfigSection(@NotNull String path) { } else if (option instanceof CMConfigSection) { toEdit = (CMConfigSection) option; } else { - return null; + throw new IllegalStateException(path + " cannot be made into a configuration section due to already containing data!"); } } return toEdit; From e727a0ffb4a0ce2f25e6000e73f5bf1e64a70015 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 3 Jul 2021 17:23:48 +0100 Subject: [PATCH 016/134] Remove duplicating code in moveTo method --- .../configurationmaster/impl/CMConfigSection.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index a9ae4a2..482a6b6 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -64,15 +64,7 @@ public void addComment(@NotNull String comment) { @Override public void moveTo(@NotNull String oldPath, @NotNull String newPath) { - if (!contains(oldPath)) return; - CMMemorySection oldCmSection = getSectionInternal(oldPath); - if (oldCmSection == null) return; - CMMemorySection newCmSection = getSectionInternal(newPath); - if (newCmSection == null) newCmSection = createSectionInternal(newPath); - String oldKey = oldPath.substring(oldPath.lastIndexOf('.') + 1); - Object movingValue = oldCmSection.existingValues.get(oldKey); - String newKey = newPath.substring(newPath.lastIndexOf('.') + 1); - newCmSection.actualValues.put(newKey, movingValue); + moveTo(oldPath, newPath, getParent()); } @Override From c78812c6710be15f7657922ee29ee01feed877d7 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 3 Jul 2021 17:24:01 +0100 Subject: [PATCH 017/134] Add TODO for future release --- .../thatsmusic99/configurationmaster/impl/CMConfigSection.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 482a6b6..6d03334 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -39,6 +39,7 @@ public void addDefault(@NotNull String path, Object defaultOption, @Nullable Str if (getParent().getComments().containsKey(path)) { comments.add(getParent().getComments().get(path)); } + // TODO - should probably be done using objects if (section != null) { comments.add("CONFIG_SECTION: " + section); } From 36ff6530b58727e68576dd89e915b2053170d4a4 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 3 Jul 2021 17:29:43 +0100 Subject: [PATCH 018/134] oh yeah bump the version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0d2f887..45a0fee 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.github.thatsmusic99 ConfigurationMaster - v2.0.0-ALPHA-1 + v2.0.0-ALPHA-2 From f9b2d2e835223dbabc08fe3a9e6e379573eec61c Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 4 Jul 2021 14:33:30 +0100 Subject: [PATCH 019/134] Fixed ConfigFile#reload --- .../configurationmaster/api/ConfigFile.java | 22 +++++++++++++++---- .../impl/CMConfigSection.java | 10 +++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 040a61f..8060bee 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -30,6 +30,7 @@ public class ConfigFile extends CMConfigSection { protected List pendingComments; protected HashMap comments; protected List examples; + protected List lenientSections; /** * Used to load a config file without safety precautions taken by the API. @@ -46,6 +47,7 @@ public ConfigFile(@NotNull File file) { pendingComments = new ArrayList<>(); comments = new HashMap<>(); examples = new ArrayList<>(); + lenientSections = new ArrayList<>(); loadWithExceptions(); } @@ -116,14 +118,22 @@ public void save() throws IOException { } public void reload() throws IOException { - actualValues.clear(); + HashMap allDefaults = new LinkedHashMap<>(); + addDefaults(allDefaults); existingValues.clear(); + actualValues.clear(); loadWithExceptions(); - for (String defaultOption : defaults.keySet()) { - if (!examples.contains(defaultOption)) { - addDefault(defaultOption, defaults.get(defaultOption)); + + for (String path : allDefaults.keySet()) { + if (!examples.contains(path) || contains(path)) { + addDefault(path, allDefaults.get(path)); } } + + for (String section : lenientSections) { + makeSectionLenient(section); + } + save(); } @@ -155,4 +165,8 @@ public List getPendingComments() { public List getExamples() { return examples; } + + public List getLenientSections() { + return lenientSections; + } } diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 6d03334..1be9323 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -182,4 +182,14 @@ private String getPathWithKey(String key) { if (getPath().isEmpty()) return key; return getPath() + "." + key; } + + protected void addDefaults(HashMap map) { + for (String key : actualValues.keySet()) { + if (actualValues.get(key) instanceof CMConfigSection) { + ((CMConfigSection) actualValues.get(key)).addDefaults(map); + } else { + map.put(getPathWithKey(key), defaults.get(key)); + } + } + } } From 85d5a28d18f71968474978c18a301281094225db Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 4 Jul 2021 14:36:41 +0100 Subject: [PATCH 020/134] Fixed comments not always getting fetched and placed properly --- .../configurationmaster/impl/CMConfigSection.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 1be9323..ee0db94 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -27,6 +27,8 @@ public void addDefault(@NotNull String path, Object defaultOption, @NotNull Stri } public void addDefault(@NotNull String path, Object defaultOption, @Nullable String section, @Nullable String comment) { + // + String fullPath = getPathWithKey(path); CMMemorySection cmSection = getSectionInternal(path); if (cmSection == null) cmSection = createSectionInternal(path); String key = path.substring(path.lastIndexOf('.') + 1); @@ -36,8 +38,8 @@ public void addDefault(@NotNull String path, Object defaultOption, @Nullable Str addComments(parentSection, comments.toArray(new String[]{})); comments.clear(); // Then handle the comments for the actual option - if (getParent().getComments().containsKey(path)) { - comments.add(getParent().getComments().get(path)); + if (getParent().getComments().containsKey(fullPath)) { + comments.add(getParent().getComments().get(fullPath)); } // TODO - should probably be done using objects if (section != null) { @@ -53,7 +55,7 @@ public void addDefault(@NotNull String path, Object defaultOption, @Nullable Str for (int i = 1; i < comments.size(); i++) { builder.append("\n\n").append(comments.get(i)); } - getParent().getComments().put(path, builder.toString()); + getParent().getComments().put(fullPath, builder.toString()); } cmSection.defaults.put(key, defaultOption); cmSection.actualValues.put(key, cmSection.existingValues.getOrDefault(key, defaultOption)); From ac0e7aec99aa87b79f2302a9389809acf5e4b5bb Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 4 Jul 2021 14:37:41 +0100 Subject: [PATCH 021/134] Fixed option paths not being determined correctly --- .../configurationmaster/impl/CMConfigSection.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index ee0db94..744f378 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -86,9 +86,9 @@ public void moveTo(@NotNull String oldPath, @NotNull String newPath, @NotNull Co public void addComment(@NotNull String path, @NotNull String comment) { if (getParent().getComments().containsKey(path)) { String newComment = getParent().getComments().get(path) + "\n\n" + comment; - getParent().getComments().put(path, newComment); + getParent().getComments().put(getPathWithKey(path), newComment); } else { - getParent().getComments().put(path, comment); + getParent().getComments().put(getPathWithKey(path), comment); } } @@ -114,7 +114,7 @@ public void addExample(@NotNull String path, Object object, String comment) { if (!section.existingValues.containsKey(key)) return; } } - getParent().getExamples().add(path); + getParent().getExamples().add(getPathWithKey(path)); addDefault(path, object, null, comment); } @@ -170,9 +170,8 @@ public void mapToCM(Map map) { String key = keyObj.toString(); Object value = map.get(keyObj); if (value instanceof Map) { - CMConfigSection section = new CMConfigSection( - getPath().length() == 0 ? key : "." + key, getParent()); section.mapToCM((Map) value); + CMConfigSection section = new CMConfigSection(getPathWithKey(key), getParent()); existingValues.put(key, section); } else { existingValues.put(key, value); From 23148e8c86580897a1bc13646fba98a25281acf6 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 4 Jul 2021 14:39:58 +0100 Subject: [PATCH 022/134] Fixed ConfigSection#makeSectionLenient(String) not working properly --- .../configurationmaster/impl/CMConfigSection.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 744f378..ca227ee 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -119,10 +119,16 @@ public void addExample(@NotNull String path, Object object, String comment) { } public void makeSectionLenient(String path) { - CMMemorySection section = getSectionInternal(path); - if (section == null) section = createSectionInternal(path); - String key = path.substring(path.lastIndexOf('.') + 1); - section.actualValues.put(key, section.existingValues.getOrDefault(key, createConfigSection(path))); + CMConfigSection section = (CMConfigSection) getSectionInternal(path + ".haha"); + if (section == null) section = createSectionInternal(path + ".haha"); + for (String key : section.existingValues.keySet()) { + if (section.existingValues.get(key) instanceof CMConfigSection) { + section.makeSectionLenient(key); + } + section.actualValues.put(key, section.existingValues.get(key)); + } + if (getParent().getLenientSections().contains(getPathWithKey(path))) return; + getParent().getLenientSections().add(getPathWithKey(path)); } public void addSection(@NotNull String section) { From e07cd798ad3accbc497af9969351509ccc8d2b1d Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 4 Jul 2021 14:43:32 +0100 Subject: [PATCH 023/134] Generify the maps here --- .../thatsmusic99/configurationmaster/api/ConfigFile.java | 2 +- .../configurationmaster/impl/CMConfigSection.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 8060bee..58f95ed 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -102,7 +102,7 @@ public void loadWithExceptions() { } public void loadFromString(String str) { - Map map = this.yaml.load(str); + Map map = this.yaml.load(str); if (map != null) { mapToCM(map); } diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index ca227ee..70b2941 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -171,13 +171,13 @@ public Map convertToMap() { return map; } - public void mapToCM(Map map) { + public void mapToCM(Map map) { for (Object keyObj : map.keySet()) { String key = keyObj.toString(); Object value = map.get(keyObj); if (value instanceof Map) { - section.mapToCM((Map) value); CMConfigSection section = new CMConfigSection(getPathWithKey(key), getParent()); + section.mapToCM((Map) value); existingValues.put(key, section); } else { existingValues.put(key, value); From 20c69e68372ff151528a260608f6e532f42aa52f Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 4 Jul 2021 14:44:00 +0100 Subject: [PATCH 024/134] Remove the option if the value specified is null --- .../configurationmaster/impl/CMMemorySection.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index f068511..a3dad90 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -6,7 +6,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; public class CMMemorySection implements MemorySection { @@ -157,6 +160,10 @@ public void set(@NotNull String path, @Nullable Object object) { CMMemorySection section = getSectionInternal(path); if (section == null) section = getParent().createConfigSection(path); String key = path.substring(path.lastIndexOf('.') + 1); + if (object == null && section.actualValues.containsKey(key)) { + section.actualValues.remove(key); + return; + } section.actualValues.put(key, object); } From de63db359a043c33de4a5f9e187af2b8bad2aff1 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 4 Jul 2021 14:57:44 +0100 Subject: [PATCH 025/134] Moved API and Bukkit stuff into separate modules --- API/pom.xml | 30 ++++++++++ .../api/CommentWriter.java | 0 .../configurationmaster/api/ConfigFile.java | 15 ++--- .../api/ConfigSection.java | 0 .../api/MemorySection.java | 0 .../impl/CMConfigSection.java | 7 ++- .../impl/CMMemorySection.java | 9 ++- Bukkit/pom.xml | 58 +++++++++++++++++++ .../configurationmaster/CMFile.java | 8 ++- .../ConfigurationMaster.java | 0 {src => Bukkit/src}/main/resources/plugin.yml | 2 +- pom.xml | 20 ++----- 12 files changed, 117 insertions(+), 32 deletions(-) create mode 100644 API/pom.xml rename {src => API/src}/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java (100%) rename {src => API/src}/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java (93%) rename {src => API/src}/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java (100%) rename {src => API/src}/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java (100%) rename {src => API/src}/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java (98%) rename {src => API/src}/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java (93%) create mode 100644 Bukkit/pom.xml rename {src => Bukkit/src}/main/java/io/github/thatsmusic99/configurationmaster/CMFile.java (99%) rename {src => Bukkit/src}/main/java/io/github/thatsmusic99/configurationmaster/ConfigurationMaster.java (100%) rename {src => Bukkit/src}/main/resources/plugin.yml (85%) diff --git a/API/pom.xml b/API/pom.xml new file mode 100644 index 0000000..19cb2ea --- /dev/null +++ b/API/pom.xml @@ -0,0 +1,30 @@ + + + + ConfigurationMaster + com.github.thatsmusic99 + v2.0.0-ALPHA-2 + + 4.0.0 + + ConfigurationMaster-API + v2.0.0-ALPHA-2 + + + 8 + 8 + + + + + + org.yaml + snakeyaml + 1.28 + provided + + + + \ No newline at end of file diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java similarity index 100% rename from src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java rename to API/src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java similarity index 93% rename from src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java rename to API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 58f95ed..5f26308 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -13,10 +13,7 @@ import java.io.*; import java.nio.file.Files; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class ConfigFile extends CMConfigSection { @@ -89,10 +86,9 @@ public void loadWithExceptions() { StringBuilder content = new StringBuilder(); try { - String line = reader.readLine(); - while (line != null) { + String line; + while ((line = reader.readLine()) != null) { content.append(line).append("\n"); - line = reader.readLine(); } } catch (IOException e) { e.printStackTrace(); @@ -109,11 +105,8 @@ public void loadFromString(String str) { } public void save() throws IOException { - BufferedWriter writer = new BufferedWriter(new FileWriter(file)); - try { + try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) { writer.write(saveToString()); - } finally { - writer.close(); } } diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java similarity index 100% rename from src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java rename to API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java similarity index 100% rename from src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java rename to API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java similarity index 98% rename from src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java rename to API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 70b2941..c1db05c 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -1,12 +1,15 @@ package io.github.thatsmusic99.configurationmaster.impl; import com.google.common.collect.Lists; -import io.github.thatsmusic99.configurationmaster.api.ConfigSection; import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import io.github.thatsmusic99.configurationmaster.api.ConfigSection; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; public class CMConfigSection extends CMMemorySection implements ConfigSection { diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java similarity index 93% rename from src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java rename to API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index a3dad90..a768424 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -173,7 +173,14 @@ protected CMMemorySection getSectionInternal(@NotNull String path) { while (path.indexOf('.') != -1 && section != null) { String key = path.substring(0, path.indexOf('.')); path = path.substring(path.indexOf('.') + 1); - section = (CMMemorySection) section.getConfigSection(key); + CMMemorySection tempSection; + if (section.existingValues.get(key) instanceof CMConfigSection) { + tempSection = (CMMemorySection) section.getConfigSection(key, (CMConfigSection) section.existingValues.get(key)); + } else { + tempSection = (CMMemorySection) section.getConfigSection(key); + } + section.actualValues.putIfAbsent(key, tempSection); + section = tempSection; } return section; } diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml new file mode 100644 index 0000000..2b36e63 --- /dev/null +++ b/Bukkit/pom.xml @@ -0,0 +1,58 @@ + + + + ConfigurationMaster + com.github.thatsmusic99 + v2.0.0-ALPHA-2 + + 4.0.0 + + ConfigurationMaster-Bukkit + v2.0.0-ALPHA-2 + + + 8 + 8 + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.3.0-SNAPSHOT + + false + false + /tmp + + + + package + + shade + + + + + + + + + + com.github.thatsmusic99 + ConfigurationMaster-API + v2.0.0-ALPHA-2 + + + + org.spigotmc + spigot-api + 1.16.2-R0.1-SNAPSHOT + provided + + + + \ No newline at end of file diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/CMFile.java b/Bukkit/src/main/java/io/github/thatsmusic99/configurationmaster/CMFile.java similarity index 99% rename from src/main/java/io/github/thatsmusic99/configurationmaster/CMFile.java rename to Bukkit/src/main/java/io/github/thatsmusic99/configurationmaster/CMFile.java index d0101af..57a19fc 100644 --- a/src/main/java/io/github/thatsmusic99/configurationmaster/CMFile.java +++ b/Bukkit/src/main/java/io/github/thatsmusic99/configurationmaster/CMFile.java @@ -1,13 +1,15 @@ package io.github.thatsmusic99.configurationmaster; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.*; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; /** * CMFile is the specialised configuration file used by diff --git a/src/main/java/io/github/thatsmusic99/configurationmaster/ConfigurationMaster.java b/Bukkit/src/main/java/io/github/thatsmusic99/configurationmaster/ConfigurationMaster.java similarity index 100% rename from src/main/java/io/github/thatsmusic99/configurationmaster/ConfigurationMaster.java rename to Bukkit/src/main/java/io/github/thatsmusic99/configurationmaster/ConfigurationMaster.java diff --git a/src/main/resources/plugin.yml b/Bukkit/src/main/resources/plugin.yml similarity index 85% rename from src/main/resources/plugin.yml rename to Bukkit/src/main/resources/plugin.yml index 3228800..8f6f225 100644 --- a/src/main/resources/plugin.yml +++ b/Bukkit/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ main: io.github.thatsmusic99.configurationmaster.ConfigurationMaster name: ConfigurationMaster -version: 1.0.2 +version: 2.0.0-ALPHA-2 author: Thatsmusic99 api-version: 1.13 \ No newline at end of file diff --git a/pom.xml b/pom.xml index 45a0fee..f08624f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,6 +6,7 @@ com.github.thatsmusic99 ConfigurationMaster + pom v2.0.0-ALPHA-2 @@ -22,6 +23,10 @@ + + API + Bukkit + @@ -31,31 +36,18 @@ - - - org.spigotmc - spigot-api - 1.16.2-R0.1-SNAPSHOT - provided - - org.jetbrains annotations 13.0 + provided - - org.yaml - snakeyaml - 1.28 - junit junit 4.13.1 test - \ No newline at end of file From d95b4deb82983a2fcbc65bc791558e7e3dc8a537 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 4 Jul 2021 14:59:29 +0100 Subject: [PATCH 026/134] Added tests --- .../AdvancedTeleportTest.java | 6 +- .../CommandWhitelistTest.java | 65 +++++++++++++++++++ .../configurationmaster/HeadsPlusTest.java | 41 ++++++++++++ 3 files changed, 109 insertions(+), 3 deletions(-) rename {src/main/tests => API/src/test/java}/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java (99%) create mode 100644 API/src/test/java/io/github/thatsmusic99/configurationmaster/CommandWhitelistTest.java create mode 100644 API/src/test/java/io/github/thatsmusic99/configurationmaster/HeadsPlusTest.java diff --git a/src/main/tests/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java b/API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java similarity index 99% rename from src/main/tests/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java rename to API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java index c9b37cb..08018f1 100644 --- a/src/main/tests/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java +++ b/API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java @@ -15,10 +15,9 @@ public class AdvancedTeleportTest { @Test public void initATConfig() throws IOException { File file = new File("test-config.yml"); - if (file.exists()) { - file.delete(); + if (!file.exists()) { + file.createNewFile(); } - file.createNewFile(); ConfigFile config = ConfigFile.loadConfig(file); config.addComment("Another comment at the very top for all you lads :)"); @@ -276,6 +275,7 @@ public void initATConfig() throws IOException { "Do not enable this if you are unsure of the risks this option proposes."); config.save(); + System.out.println("Intermission"); config.reload(); Assert.assertTrue(config.getBoolean("use-basic-teleport-features")); diff --git a/API/src/test/java/io/github/thatsmusic99/configurationmaster/CommandWhitelistTest.java b/API/src/test/java/io/github/thatsmusic99/configurationmaster/CommandWhitelistTest.java new file mode 100644 index 0000000..11b6025 --- /dev/null +++ b/API/src/test/java/io/github/thatsmusic99/configurationmaster/CommandWhitelistTest.java @@ -0,0 +1,65 @@ +package io.github.thatsmusic99.configurationmaster; + +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +/** + * Sample configuration setup for CommandWhitelist by YouHaveTrouble + */ +public class CommandWhitelistTest { + + @Test + public void doCommandWhitelistTests() throws IOException { + ConfigFile config = ConfigFile.loadConfig(new File("command-whitelist.yml")); + + config.addDefault("messages.prefix", "CommandWhitelist > "); + config.addDefault("messages.command_denied", "No such command."); + config.addDefault("messages.subcommand_denied", "You cannot use this subcommand"); + config.addDefault("messages.no_permission", "You don't have permission to do this."); + config.addDefault("messages.no_such_subcommand", "No subcommand by that name."); + config.addDefault("messages.config_reloaded", "Configuration reloaded."); + config.addDefault("messages.added_to_whitelist", "Whitelisted command %s for permission %s"); + config.addDefault("messages.removed_from_whitelist", "Removed command %s from permission %s"); + config.addDefault("messages.group_doesnt_exist", "Group doesn't exist or error occured"); + + config.addComment("messages", "Messages use MiniMessage formatting (https://docs.adventure.kyori.net/minimessage.html#format)"); + + config.addDefault("use_protocollib", false, "Do not enable if you don't have issues with aliased commands.\nThis requires server restart to take effect."); + + config.makeSectionLenient("groups"); + List exampleCommands = new ArrayList<>(); + exampleCommands.add("example"); + List exampleSubCommands = new ArrayList<>(); + exampleSubCommands.add("example of"); + + config.addExample("groups.example.commands", exampleCommands, "This is the WHITELIST of commands that players will be able to see/use in the group \"example\""); + config.addExample("groups.example.subcommands", exampleSubCommands, "This is the BLACKLIST of subcommands that players will NOT be able to see/use in the group \"example\""); + config.addComment("groups.example", "All groups except from default require commandwhitelist.group. permission\ncommandwhitelist.group.example in this case\n If you wish to leave the list empty, put \"commands: []\" or \"subcommands: []\""); + + + List defaultCommands = new ArrayList<>(); + defaultCommands.add("help"); + defaultCommands.add("spawn"); + defaultCommands.add("bal"); + defaultCommands.add("balance"); + defaultCommands.add("baltop"); + defaultCommands.add("pay"); + defaultCommands.add("r"); + defaultCommands.add("msg"); + defaultCommands.add("tpa"); + defaultCommands.add("tpahere"); + defaultCommands.add("tpaccept"); + defaultCommands.add("tpdeny"); + defaultCommands.add("warp"); + List defaultSubcommands = new ArrayList<>(); + defaultSubcommands.add("help about"); + + + config.save(); + } +} diff --git a/API/src/test/java/io/github/thatsmusic99/configurationmaster/HeadsPlusTest.java b/API/src/test/java/io/github/thatsmusic99/configurationmaster/HeadsPlusTest.java new file mode 100644 index 0000000..b694b2e --- /dev/null +++ b/API/src/test/java/io/github/thatsmusic99/configurationmaster/HeadsPlusTest.java @@ -0,0 +1,41 @@ +package io.github.thatsmusic99.configurationmaster; + +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; + +public class HeadsPlusTest { + + @Test + public void animationsTest() { + ConfigFile animations = ConfigFile.loadConfig(new File("animations.yml")); + animations.addComment("This is the config where you can make head animations come to life.\n" + + "For technical reasons, these will only work in inventories and masks."); + + animations.makeSectionLenient("animations"); + + animations.addExample("animations.creeper.looping-mode", "loop-reverse", ""); + animations.addExample("animations.creeper.pausing-period", 4); + animations.addExample("animations.creeper.textures", new ArrayList<>(Arrays.asList( + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHBzOi8vaS5pbWd1ci5jb20vQXZ1Z29aeC5wbmcifX19", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHBzOi8vaS5pbWd1ci5jb20vSlFLeHYzNy5wbmcifX19", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHBzOi8vaS5pbWd1ci5jb20vRVRKalhYVS5wbmcifX19", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHBzOi8vaS5pbWd1ci5jb20vdVNGTlhway5wbmcifX19", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHBzOi8vaS5pbWd1ci5jb20vS0ZGTjJjVy5wbmcifX19", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHBzOi8vaS5pbWd1ci5jb20vUUVPUWxYcy5wbmcifX19", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHBzOi8vaS5pbWd1ci5jb20vUlQ5TEFkYS5wbmcifX19"))); + + animations.makeSectionLenient("testing-1.testing-2"); + animations.createConfigSection("testing-1.testing-2.testing-3"); + + try { + animations.save(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} From 8d40c80a7bc9f4a238fd321c5837e98da5410d8a Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 4 Jul 2021 14:59:48 +0100 Subject: [PATCH 027/134] Ignore all .yml files generated by tests --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5d19ae2..8a57975 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea/ target/ -ConfigurationMaster.iml \ No newline at end of file +ConfigurationMaster.iml +*.yml \ No newline at end of file From c181aec657e856902add36027f785dd0d28b2db4 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 4 Jul 2021 15:02:40 +0100 Subject: [PATCH 028/134] add a warning to own the libs --- .../io/github/thatsmusic99/configurationmaster/CMFile.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Bukkit/src/main/java/io/github/thatsmusic99/configurationmaster/CMFile.java b/Bukkit/src/main/java/io/github/thatsmusic99/configurationmaster/CMFile.java index 57a19fc..c3ef8cf 100644 --- a/Bukkit/src/main/java/io/github/thatsmusic99/configurationmaster/CMFile.java +++ b/Bukkit/src/main/java/io/github/thatsmusic99/configurationmaster/CMFile.java @@ -94,6 +94,9 @@ public CMFile(Plugin plugin, String name) { * @param name The name of the config file. */ public CMFile(Plugin plugin, File folder, String name) { + plugin.getLogger().severe("This plugin is using the CMFile class in ConfigurationMaster. " + + "This class is being removed in the next major release as it has been replaced by the standalone ConfigFile." + + "Please urge the developer to update their ConfigurationMaster code as soon as possible."); this.plugin = plugin; this.folder = folder; this.name = name; From ed3eaabecd958af1a2f2fcc6103e0c2a5829d3a6 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 4 Jul 2021 15:44:16 +0100 Subject: [PATCH 029/134] Fixed dependency/imports that come from Bukkit --- .../configurationmaster/api/ConfigFile.java | 10 ++++------ .../configurationmaster/impl/CMConfigSection.java | 8 ++------ .../configurationmaster/AdvancedTeleportTest.java | 3 +-- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 5f26308..fabc6ff 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -1,13 +1,11 @@ package io.github.thatsmusic99.configurationmaster.api; -import com.google.common.collect.Lists; import io.github.thatsmusic99.configurationmaster.impl.CMConfigSection; -import org.bukkit.configuration.file.YamlConstructor; -import org.bukkit.configuration.file.YamlRepresenter; import org.jetbrains.annotations.NotNull; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.SafeConstructor; import org.yaml.snakeyaml.error.YAMLException; import org.yaml.snakeyaml.representer.Representer; @@ -20,7 +18,7 @@ public class ConfigFile extends CMConfigSection { private final Yaml yaml; private final DumperOptions yamlOptions = new DumperOptions(); private final LoaderOptions loaderOptions = new LoaderOptions(); - private final Representer yamlRepresenter = new YamlRepresenter(); + private final Representer yamlRepresenter = new Representer(); private final File file; private boolean isNew = false; private CommentWriter writer; @@ -35,7 +33,7 @@ public class ConfigFile extends CMConfigSection { * @param file The config file to be loaded. */ public ConfigFile(@NotNull File file) { - yaml = new Yaml(new YamlConstructor(), yamlRepresenter, yamlOptions, loaderOptions); + yaml = new Yaml(new SafeConstructor(), yamlRepresenter, yamlOptions, loaderOptions); yamlOptions.setIndent(2); yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); @@ -139,7 +137,7 @@ public String saveToString() { if (dump.equals("{}")) { dump = ""; } - writer.writeComments(Lists.newArrayList(dump.split("\n"))); + writer.writeComments(new ArrayList<>(Arrays.asList(dump.split("\n")))); StringBuilder result = new StringBuilder(); for (String line : writer.getLines()) { result.append(line).append("\n"); diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index c1db05c..5eb1c84 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -1,15 +1,11 @@ package io.github.thatsmusic99.configurationmaster.impl; -import com.google.common.collect.Lists; import io.github.thatsmusic99.configurationmaster.api.ConfigFile; import io.github.thatsmusic99.configurationmaster.api.ConfigSection; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class CMConfigSection extends CMMemorySection implements ConfigSection { @@ -36,7 +32,7 @@ public void addDefault(@NotNull String path, Object defaultOption, @Nullable Str if (cmSection == null) cmSection = createSectionInternal(path); String key = path.substring(path.lastIndexOf('.') + 1); // Move comments to parent option - List comments = Lists.newArrayList(getParent().getPendingComments()); + List comments = new ArrayList<>(getParent().getPendingComments()); String parentSection = path.substring(0, path.indexOf('.') == -1 ? path.length() : path.indexOf('.')); addComments(parentSection, comments.toArray(new String[]{})); comments.clear(); diff --git a/API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java b/API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java index 08018f1..16283fc 100644 --- a/API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java +++ b/API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java @@ -1,6 +1,5 @@ package io.github.thatsmusic99.configurationmaster; -import com.google.common.collect.Lists; import io.github.thatsmusic99.configurationmaster.api.ConfigFile; import org.junit.Assert; import org.junit.Test; @@ -297,6 +296,6 @@ public void initATConfig() throws IOException { config.set("cooldown-duration", "60"); Assert.assertEquals("60", config.getString("cooldown-duration")); Assert.assertEquals(60, config.getInteger("cooldown-duration")); - Assert.assertEquals(Lists.newArrayList(), config.getList("disabled-commands")); + Assert.assertEquals(new ArrayList<>(), config.getList("disabled-commands")); } } From c4a2d0513281bfbffc88781bc260a97b63ab0b27 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Tue, 13 Jul 2021 21:38:10 +0100 Subject: [PATCH 030/134] Fixed null options being added --- .../configurationmaster/impl/CMMemorySection.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index a768424..84c871a 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -158,9 +158,12 @@ public List getList(@NotNull String path, @Nullable List defaultValue) @Override public void set(@NotNull String path, @Nullable Object object) { CMMemorySection section = getSectionInternal(path); - if (section == null) section = getParent().createConfigSection(path); + if (section == null) { + if (object == null) return; + section = getParent().createConfigSection(path); + } String key = path.substring(path.lastIndexOf('.') + 1); - if (object == null && section.actualValues.containsKey(key)) { + if (object == null) { section.actualValues.remove(key); return; } From 70a291b5afc73b4283db1c80308c25329a0ba36a Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Tue, 13 Jul 2021 21:39:00 +0100 Subject: [PATCH 031/134] Fixed NPE + problems when using getList on an array --- .../configurationmaster/impl/CMMemorySection.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index 84c871a..e7afc11 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -6,10 +6,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; +import java.util.*; public class CMMemorySection implements MemorySection { @@ -149,7 +146,10 @@ public List getList(@NotNull String path, @Nullable List defaultValue) if (section == null) return defaultValue; String key = path.substring(path.lastIndexOf('.') + 1); Object value = section.actualValues.getOrDefault(key, defaultValue); - if (!(value instanceof List)) { + if (value == null) return defaultValue; + if (value.getClass().isArray()) { + value = Arrays.asList((Object[]) value); + } else if (!(value instanceof List)) { value = new ArrayList<>(Collections.singletonList(value)); } return (List) value; From 03ff1a61a7596a3ebcd02479a9b28ab9384493d7 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Tue, 13 Jul 2021 21:39:13 +0100 Subject: [PATCH 032/134] Also prevent null sections being added --- .../thatsmusic99/configurationmaster/impl/CMMemorySection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index e7afc11..98d2f27 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -182,7 +182,7 @@ protected CMMemorySection getSectionInternal(@NotNull String path) { } else { tempSection = (CMMemorySection) section.getConfigSection(key); } - section.actualValues.putIfAbsent(key, tempSection); + if (tempSection != null) section.actualValues.putIfAbsent(key, tempSection); section = tempSection; } return section; From 41395edc56a27815c9a1ba94761bb3742bb2cf95 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Tue, 13 Jul 2021 22:28:03 +0100 Subject: [PATCH 033/134] Fixed moveTo not setting options to null --- .../thatsmusic99/configurationmaster/impl/CMConfigSection.java | 1 + 1 file changed, 1 insertion(+) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 5eb1c84..e1f15fe 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -80,6 +80,7 @@ public void moveTo(@NotNull String oldPath, @NotNull String newPath, @NotNull Co Object movingValue = oldCmSection.existingValues.get(oldKey); String newKey = newPath.substring(newPath.lastIndexOf('.') + 1); newCmSection.actualValues.put(newKey, movingValue); + oldCmSection.set(oldKey, null); } public void addComment(@NotNull String path, @NotNull String comment) { From 19b91b70655d2cfda31769375a1c0e3131c00806 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Tue, 13 Jul 2021 22:30:19 +0100 Subject: [PATCH 034/134] If the section is null, don't try to re-add a section --- .../configurationmaster/impl/CMConfigSection.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index e1f15fe..bd79b6f 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -109,10 +109,9 @@ public void addExample(@NotNull String path, Object object) { public void addExample(@NotNull String path, Object object, String comment) { if (!getParent().isNew()) { CMMemorySection section = getSectionInternal(path); - if (section != null) { - String key = path.substring(path.lastIndexOf('.') + 1); - if (!section.existingValues.containsKey(key)) return; - } + if (section == null) return; + String key = path.substring(path.lastIndexOf('.') + 1); + if (!section.existingValues.containsKey(key)) return; } getParent().getExamples().add(getPathWithKey(path)); addDefault(path, object, null, comment); From 1256afdf62a3997292ad6f31831f15f34be4b818 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Tue, 13 Jul 2021 22:31:20 +0100 Subject: [PATCH 035/134] Fixed ConfigFile#reload re-adding sections made via addExample --- .../thatsmusic99/configurationmaster/api/ConfigFile.java | 2 +- .../configurationmaster/impl/CMConfigSection.java | 3 --- .../configurationmaster/impl/CMMemorySection.java | 7 +++++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index fabc6ff..4a467dd 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -116,7 +116,7 @@ public void reload() throws IOException { loadWithExceptions(); for (String path : allDefaults.keySet()) { - if (!examples.contains(path) || contains(path)) { + if (!examples.contains(path) || containsExisting(path)) { addDefault(path, allDefaults.get(path)); } } diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index bd79b6f..53f3bf6 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -121,9 +121,6 @@ public void makeSectionLenient(String path) { CMConfigSection section = (CMConfigSection) getSectionInternal(path + ".haha"); if (section == null) section = createSectionInternal(path + ".haha"); for (String key : section.existingValues.keySet()) { - if (section.existingValues.get(key) instanceof CMConfigSection) { - section.makeSectionLenient(key); - } section.actualValues.put(key, section.existingValues.get(key)); } if (getParent().getLenientSections().contains(getPathWithKey(path))) return; diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index 98d2f27..caf2757 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -140,6 +140,13 @@ public boolean contains(@NotNull String path) { return section.actualValues.containsKey(key); } + protected boolean containsExisting(String path) { + CMMemorySection section = getSectionInternal(path); + if (section == null) return false; + String key = path.substring(path.lastIndexOf('.') + 1); + return section.existingValues.containsKey(key); + } + @Override public List getList(@NotNull String path, @Nullable List defaultValue) { CMMemorySection section = getSectionInternal(path); From bca2f543fd1ed02844fb43fb5b185f75380a9542 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Tue, 13 Jul 2021 22:32:54 +0100 Subject: [PATCH 036/134] Make ConfigFile#getExamples a hashset (better contains TO) --- .../thatsmusic99/configurationmaster/api/ConfigFile.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 4a467dd..3d8653a 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -24,7 +24,7 @@ public class ConfigFile extends CMConfigSection { private CommentWriter writer; protected List pendingComments; protected HashMap comments; - protected List examples; + protected HashSet examples; protected List lenientSections; /** @@ -41,7 +41,7 @@ public ConfigFile(@NotNull File file) { writer = new CommentWriter(this); pendingComments = new ArrayList<>(); comments = new HashMap<>(); - examples = new ArrayList<>(); + examples = new HashSet<>(); lenientSections = new ArrayList<>(); loadWithExceptions(); } @@ -153,7 +153,7 @@ public List getPendingComments() { return pendingComments; } - public List getExamples() { + public HashSet getExamples() { return examples; } From b231064b509f39d8033423d99465ccc026858977 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Tue, 13 Jul 2021 22:33:20 +0100 Subject: [PATCH 037/134] Make some methods private --- .../thatsmusic99/configurationmaster/api/ConfigFile.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 3d8653a..6100c78 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -68,7 +68,7 @@ public static ConfigFile loadConfig(File file) { } } - public void loadWithExceptions() { + private void loadWithExceptions() { BufferedReader reader; try { reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); @@ -95,7 +95,7 @@ public void loadWithExceptions() { loadFromString(content.toString()); } - public void loadFromString(String str) { + private void loadFromString(String str) { Map map = this.yaml.load(str); if (map != null) { mapToCM(map); @@ -132,7 +132,7 @@ public boolean isNew() { return isNew; } - public String saveToString() { + private String saveToString() { String dump = this.yaml.dump(convertToMap()); if (dump.equals("{}")) { dump = ""; From 61ef12835d1df5c828a07abbc83cdcdf0260b030 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Tue, 13 Jul 2021 22:35:05 +0100 Subject: [PATCH 038/134] Added some javadocs --- .../configurationmaster/api/ConfigFile.java | 32 +++++++++++++++++++ .../impl/CMConfigSection.java | 1 + 2 files changed, 33 insertions(+) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 6100c78..b9019ba 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -31,6 +31,8 @@ public class ConfigFile extends CMConfigSection { * Used to load a config file without safety precautions taken by the API. * * @param file The config file to be loaded. + * @see ConfigFile#loadConfig(File) + * @throws YAMLException if the file being loaded contains syntax errors. */ public ConfigFile(@NotNull File file) { yaml = new Yaml(new SafeConstructor(), yamlRepresenter, yamlOptions, loaderOptions); @@ -46,6 +48,14 @@ public ConfigFile(@NotNull File file) { loadWithExceptions(); } + /** + * Used to load a config file with safety precautions taken by the API.
+ * This safety precaution checks for syntax errors in the YAML file.
+ * If there is one, it is renamed and an empty file is loaded.
+ * + * @param file The file to be loaded. + * @return the ConfigFile instance of the file or backup file. + */ public static ConfigFile loadConfig(File file) { try { return new ConfigFile(file); @@ -102,12 +112,22 @@ private void loadFromString(String str) { } } + /** + * Saves all changes made to the config to the actual file. + * + * @throws IOException if something went wrong writing to the file. + */ public void save() throws IOException { try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) { writer.write(saveToString()); } } + /** + * Reloads the configuration and updates all values stored inside it.

+ * + * @throws IOException if something went wrong saving the file. + */ public void reload() throws IOException { HashMap allDefaults = new LinkedHashMap<>(); addDefaults(allDefaults); @@ -128,6 +148,13 @@ public void reload() throws IOException { save(); } + /** + * Returns whether the loaded file is brand new or not. + * + * This is determined by whether a new file was created or if the file itself is empty. + * + * @return true if the file is newly loaded, false if not. + */ public boolean isNew() { return isNew; } @@ -149,6 +176,11 @@ public HashMap getComments() { return comments; } + /** + * Get all comments that have yet to be added. These will be added when the next default/example is set. + * + * @return Comments waiting to be added. + */ public List getPendingComments() { return pendingComments; } diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 53f3bf6..1c9f6a0 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -128,6 +128,7 @@ public void makeSectionLenient(String path) { } public void addSection(@NotNull String section) { + // TODO - use objects getParent().getPendingComments().add("CONFIG_SECTION: " + section); } From 38de42ae9be70db5f33738efa180fcfdeeb16ced Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Tue, 13 Jul 2021 22:36:01 +0100 Subject: [PATCH 039/134] Bumped version --- API/pom.xml | 4 ++-- Bukkit/pom.xml | 4 ++-- Bukkit/src/main/resources/plugin.yml | 2 +- pom.xml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index 19cb2ea..d927dd8 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-ALPHA-2 + v2.0.0-ALPHA-4 4.0.0 ConfigurationMaster-API - v2.0.0-ALPHA-2 + v2.0.0-ALPHA-4 8 diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index 2b36e63..b6b1aae 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-ALPHA-2 + v2.0.0-ALPHA-4 4.0.0 ConfigurationMaster-Bukkit - v2.0.0-ALPHA-2 + v2.0.0-ALPHA-4 8 diff --git a/Bukkit/src/main/resources/plugin.yml b/Bukkit/src/main/resources/plugin.yml index 8f6f225..2edd944 100644 --- a/Bukkit/src/main/resources/plugin.yml +++ b/Bukkit/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ main: io.github.thatsmusic99.configurationmaster.ConfigurationMaster name: ConfigurationMaster -version: 2.0.0-ALPHA-2 +version: 2.0.0-ALPHA-4 author: Thatsmusic99 api-version: 1.13 \ No newline at end of file diff --git a/pom.xml b/pom.xml index f08624f..464d9fa 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.github.thatsmusic99 ConfigurationMaster pom - v2.0.0-ALPHA-2 + v2.0.0-ALPHA-4 From 331d7547162c2bd64b7b7e08511fe51da41f7939 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Tue, 13 Jul 2021 22:43:23 +0100 Subject: [PATCH 040/134] Fixed custom options added to lenient sections not saving if they were in sections --- .../configurationmaster/impl/CMConfigSection.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 1c9f6a0..2b34ae0 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -120,13 +120,20 @@ public void addExample(@NotNull String path, Object object, String comment) { public void makeSectionLenient(String path) { CMConfigSection section = (CMConfigSection) getSectionInternal(path + ".haha"); if (section == null) section = createSectionInternal(path + ".haha"); - for (String key : section.existingValues.keySet()) { - section.actualValues.put(key, section.existingValues.get(key)); - } + section.forceExistingIntoActual(); if (getParent().getLenientSections().contains(getPathWithKey(path))) return; getParent().getLenientSections().add(getPathWithKey(path)); } + private void forceExistingIntoActual() { + for (String key : existingValues.keySet()) { + if (existingValues.get(key) instanceof CMConfigSection) { + ((CMConfigSection) existingValues.get(key)).forceExistingIntoActual(); + } + actualValues.put(key, existingValues.get(key)); + } + } + public void addSection(@NotNull String section) { // TODO - use objects getParent().getPendingComments().add("CONFIG_SECTION: " + section); From ecadafe31511f0f9d0e54631d5e5be73d8f3b8df Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 17 Jul 2021 20:04:38 +0100 Subject: [PATCH 041/134] Force writing to file using the UTF-8 charset --- .../thatsmusic99/configurationmaster/api/ConfigFile.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index b9019ba..bd9a8d2 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -10,6 +10,7 @@ import org.yaml.snakeyaml.representer.Representer; import java.io.*; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.*; @@ -81,11 +82,11 @@ public static ConfigFile loadConfig(File file) { private void loadWithExceptions() { BufferedReader reader; try { - reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); + reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); } catch (FileNotFoundException ex) { try { file.createNewFile(); - reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); + reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); } catch (IOException e) { e.printStackTrace(); return; @@ -118,7 +119,7 @@ private void loadFromString(String str) { * @throws IOException if something went wrong writing to the file. */ public void save() throws IOException { - try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) { + try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) { writer.write(saveToString()); } } From 3266c827fb4a9dbdcbc7160c0def8545b153cc5f Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 17 Jul 2021 20:05:43 +0100 Subject: [PATCH 042/134] Fixed error in Bukkit pom --- Bukkit/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index b6b1aae..1f5c25f 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -44,7 +44,7 @@ com.github.thatsmusic99 ConfigurationMaster-API - v2.0.0-ALPHA-2 + v2.0.0-ALPHA-4 From f949276c3c801e571a593626c296391822cc49a8 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 18 Jul 2021 08:53:42 +0100 Subject: [PATCH 043/134] Add the override annotation where needed --- .../configurationmaster/impl/CMConfigSection.java | 7 +++++++ .../configurationmaster/impl/CMMemorySection.java | 1 + 2 files changed, 8 insertions(+) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 2b34ae0..f364932 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -60,6 +60,7 @@ public void addDefault(@NotNull String path, Object defaultOption, @Nullable Str cmSection.actualValues.put(key, cmSection.existingValues.getOrDefault(key, defaultOption)); } + @Override public void addComment(@NotNull String comment) { getParent().getPendingComments().add(comment); } @@ -83,6 +84,7 @@ public void moveTo(@NotNull String oldPath, @NotNull String newPath, @NotNull Co oldCmSection.set(oldKey, null); } + @Override public void addComment(@NotNull String path, @NotNull String comment) { if (getParent().getComments().containsKey(path)) { String newComment = getParent().getComments().get(path) + "\n\n" + comment; @@ -92,6 +94,7 @@ public void addComment(@NotNull String path, @NotNull String comment) { } } + @Override public void addComments(@NotNull String path, @NotNull String... comments) { if (comments.length == 0) return; StringBuilder builder = new StringBuilder(); @@ -102,10 +105,12 @@ public void addComments(@NotNull String path, @NotNull String... comments) { addComment(path, builder.toString()); } + @Override public void addExample(@NotNull String path, Object object) { addExample(path, object, null); } + @Override public void addExample(@NotNull String path, Object object, String comment) { if (!getParent().isNew()) { CMMemorySection section = getSectionInternal(path); @@ -134,6 +139,7 @@ private void forceExistingIntoActual() { } } + @Override public void addSection(@NotNull String section) { // TODO - use objects getParent().getPendingComments().add("CONFIG_SECTION: " + section); @@ -143,6 +149,7 @@ protected CMConfigSection createSectionInternal(@NotNull String path) { return createConfigSection(path.substring(0, path.lastIndexOf('.'))); } + @Override public CMConfigSection createConfigSection(@NotNull String path) { String[] sections = path.split("\\."); CMConfigSection toEdit = this; diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index caf2757..2a1bfe5 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -195,6 +195,7 @@ protected CMMemorySection getSectionInternal(@NotNull String path) { return section; } + @Override public List getKeys(boolean deep) { List keys = new ArrayList<>(); for (String path : actualValues.keySet()) { From 1fdfaf514a87c36e3e5a032aef70d0d2379f8159 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 18 Jul 2021 08:54:08 +0100 Subject: [PATCH 044/134] Add getPath as a method to the MemorySection interface --- .../thatsmusic99/configurationmaster/api/MemorySection.java | 2 ++ .../thatsmusic99/configurationmaster/impl/CMMemorySection.java | 1 + 2 files changed, 3 insertions(+) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java index d6e6e94..194cd70 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java @@ -86,5 +86,7 @@ default List getStringList(@NotNull String path) { List getKeys(boolean deep); + String getPath(); + } diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index 2a1bfe5..9f88744 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -208,6 +208,7 @@ public List getKeys(boolean deep) { return keys; } + @Override public String getPath() { return path; } From 853aeb96109f54cb989fdde665b40df6d55c42e6 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 18 Jul 2021 13:59:34 +0100 Subject: [PATCH 045/134] Added forceExample and createExampleSection --- .../api/ConfigSection.java | 6 +++++ .../impl/CMConfigSection.java | 24 ++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java index 96ea4f8..fc8309c 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java @@ -27,5 +27,11 @@ public interface ConfigSection extends MemorySection { void addExample(@NotNull String path, @Nullable Object value, @Nullable String comment); + void createExampleSection(@NotNull String path); + + void forceExample(@NotNull String path, @Nullable Object value); + + void forceExample(@NotNull String path, @Nullable Object value, @Nullable String comment); + ConfigSection createConfigSection(@NotNull String path); } diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index f364932..bf1d277 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -118,11 +118,33 @@ public void addExample(@NotNull String path, Object object, String comment) { String key = path.substring(path.lastIndexOf('.') + 1); if (!section.existingValues.containsKey(key)) return; } + forceExample(path, object, comment); + } + + @Override + public void createExampleSection(@NotNull String path) { + if (!getParent().isNew()) { + CMMemorySection section = (CMMemorySection) getConfigSection(path); + if (section == null) return; + String key = path.substring(path.lastIndexOf('.') + 1); + if (!section.existingValues.containsKey(key)) return; + } getParent().getExamples().add(getPathWithKey(path)); - addDefault(path, object, null, comment); + createConfigSection(path); } public void makeSectionLenient(String path) { + @Override + public void forceExample(@NotNull String path, @Nullable Object value) { + forceExample(path, value, null); + } + + @Override + public void forceExample(@NotNull String path, @Nullable Object value, @Nullable String comment) { + getParent().getExamples().add(getPathWithKey(path)); + addDefault(path, value, null, comment); + } + CMConfigSection section = (CMConfigSection) getSectionInternal(path + ".haha"); if (section == null) section = createSectionInternal(path + ".haha"); section.forceExistingIntoActual(); From 4bdc95d99189b66ff98489cf2770977b3e36df54 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 18 Jul 2021 14:53:15 +0100 Subject: [PATCH 046/134] Implemented the Title API with full documentation --- .../configurationmaster/api/ConfigFile.java | 11 +- .../configurationmaster/api/Title.java | 227 ++++++++++++++++++ 2 files changed, 237 insertions(+), 1 deletion(-) create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/api/Title.java diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index bd9a8d2..3dd84f0 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -23,6 +23,7 @@ public class ConfigFile extends CMConfigSection { private final File file; private boolean isNew = false; private CommentWriter writer; + private Title title = null; protected List pendingComments; protected HashMap comments; protected HashSet examples; @@ -170,7 +171,7 @@ private String saveToString() { for (String line : writer.getLines()) { result.append(line).append("\n"); } - return result.toString(); + return (title != null ? title + "\n" : "") + result; } public HashMap getComments() { @@ -193,4 +194,12 @@ public HashSet getExamples() { public List getLenientSections() { return lenientSections; } + + public Title getTitle() { + return title; + } + + public void setTitle(Title title) { + this.title = title; + } } diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/Title.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/Title.java new file mode 100644 index 0000000..4b40e63 --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/Title.java @@ -0,0 +1,227 @@ +package io.github.thatsmusic99.configurationmaster.api; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.StringJoiner; + +/** + * A subsection of the API which is used to make pretty + * titles easier to make and implement. + */ +public class Title { + + private final List parts; + private int width; + private boolean addPadding; + + /** + * The constructor used to initialise the title object. + */ + public Title() { + width = 75; + parts = new ArrayList<>(); + addPadding = true; + } + + /** + * Changes the character width of the title object. Default value is 75.

+ * + * This method cannot be used after using {@link Title#addLine(String)}, + * {@link Title#addLine(String, Pos)}, {@link Title#addSolidLine()} or + * {@link Title#addSolidLine(char)}. + * + * @param width The width to be set. + * @return the modified title object. + * @throws IllegalStateException when the width is adjusted after title parts have been added. + */ + public Title withWidth(int width) { + if (!parts.isEmpty()) + throw new IllegalStateException("Cannot adjust the title width after title content has been added!"); + this.width = width; + return this; + } + + /** + * Changes whether or not an extra # should be added at + * the end of each line. The API does this by default.

+ * + * This method cannot be used after using {@link Title#addLine(String)}, + * {@link Title#addLine(String, Pos)}, {@link Title#addSolidLine()} or + * {@link Title#addSolidLine(char)}. + * + * @param padding Whether or not to add padding (#). + * @return the modified title object. + * @throws IllegalStateException when the padding is adjusted after title parts have been added. + */ + public Title withPadding(boolean padding) { + if (!parts.isEmpty()) + throw new IllegalStateException("Cannot adjust padding status after title content has been added!"); + this.addPadding = padding; + return this; + } + + /** + * Adds a solid line of # characters that match the title width. + * + * @return The modified title object. + */ + public Title addSolidLine() { + return addSolidLine('#'); + } + + /** + * Adds a solid line of a specified character that matches the title width, + * but adjusted so padding can be included (or not). + * + * @param character The character to make a solid line of. + * @return The modified title object. + */ + public Title addSolidLine(char character) { + parts.add(new LineTitlePart(character)); + return this; + } + + /** + * Adds a text line oriented to the left. + * + * @param content The text to be added to the title. + * @return The modified title object. + * @throws NullPointerException if the content is null. + * @see #addLine(String, Pos) + */ + public Title addLine(@NotNull String content) { + return addLine(content, Pos.LEFT); + } + + /** + * Adds a text line oriented to the right. + * + * @param content The text to be added to the title. + * @param position The position it is oriented to. + * @return The modified title object. + * @throws NullPointerException if the content or position is null. + * @throws IllegalArgumentException if a word in the content is longer than what the title can accept (width - 4) + * @see #addLine(String) + */ + public Title addLine(@NotNull String content, @NotNull Pos position) { + // Null checks + Objects.requireNonNull(content, "Title content must not be null!"); + Objects.requireNonNull(position, "Position must not be null!"); + // If all the stuff added fits on one line, just dump it in. + if (content.length() < width - 3) { + parts.add(new TextTitlePart(content, position)); + return this; + } + // However, if it doesn't, shorten it down. + StringJoiner joiner = new StringJoiner(" "); + for (String word : content.split(" ")) { + // If the word itself is waaaay too long, throw an error. + if (word.length() > width - 4) { + throw new IllegalArgumentException(String.format("Word %s of size %s is too long to be fit into the title (%s)!", word, word.length(), width - 4)); + } + if ((joiner + " " + word).length() < width - 3) { + joiner.add(word); + continue; + } + parts.add(new TextTitlePart(joiner.toString(), position)); + joiner = new StringJoiner(" ").add(word); + } + if (joiner.length() == 0) return this; + parts.add(new TextTitlePart(joiner.toString(), position)); + return this; + } + + /** + * Converts the title to a string. + * + * @return the string representation of the title. + */ + public String toString() { + StringBuilder builder = new StringBuilder(); + for (TitlePart part : parts) { + if (builder.length() != 0) builder.append("\n"); + builder.append(part.toString()); + } + return builder.toString(); + } + + private String align(String content, Pos position) { + int remainder = width - 4 - content.length(); + switch (position) { + case LEFT: + return "# " + content + repeat(" ", remainder); + case RIGHT: + return "# " + repeat(" ", remainder) + content; + case CENTER: + return "# " + repeat(" ", remainder / 2) + content + repeat(" ", + remainder % 2 == 1 ? remainder / 2 + 1 : remainder / 2); + } + return content; + } + + /** + * Used to represent an alignment position in a title text part. + */ + public enum Pos { + LEFT, + CENTER, + RIGHT + } + + private class TextTitlePart extends TitlePart { + private final String content; + + public TextTitlePart(String content, Pos pos) { + super(pos); + this.content = content; + } + + @Override + public String toString() { + return align(content, position) + (addPadding ? " #" : ""); + } + } + + private class LineTitlePart extends TitlePart { + + private final char character; + + public LineTitlePart(char character) { + super(Pos.LEFT); + this.character = character; + } + + @Override + public String toString() { + if (character == '#') { + return repeat("#", width); + } else { + return "# " + repeat(String.valueOf(character), width - 4) + (addPadding ? " #" : ""); + } + } + } + + /** + * Used to represent a title part to be added. + */ + public abstract static class TitlePart { + protected Pos position; + + public TitlePart(Pos pos) { + this.position = pos; + } + + public abstract String toString(); + } + + private static String repeat(String str, int count) { + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < count; i++) { + builder.append(str); + } + return builder.toString(); + } +} From 78e874f84a914f390913f1c941afca160a5f439f Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 18 Jul 2021 15:13:07 +0100 Subject: [PATCH 047/134] Slight code cutdown --- .../configurationmaster/impl/CMMemorySection.java | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index 9f88744..7a23791 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -39,10 +39,7 @@ private void init() { @Override public String getString(@NotNull String path, @Nullable String defaultValue) { - CMMemorySection section = getSectionInternal(path); - if (section == null) return defaultValue; - String key = path.substring(path.lastIndexOf('.') + 1); - Object result = section.actualValues.getOrDefault(key, defaultValue); + Object result = get(path, defaultValue); if (result == null) return null; return String.valueOf(result); } @@ -125,10 +122,7 @@ public float getFloat(@NotNull String path, float defaultValue) { @Override public ConfigSection getConfigSection(@NotNull String path, @Nullable ConfigSection defaultValue) { - CMMemorySection section = getSectionInternal(path); - if (section == null) return defaultValue; - String key = path.substring(path.lastIndexOf('.') + 1); - Object value = section.actualValues.getOrDefault(key, defaultValue); + Object value = get(path, defaultValue); return value instanceof ConfigSection ? (ConfigSection) value : defaultValue; } @@ -149,10 +143,7 @@ protected boolean containsExisting(String path) { @Override public List getList(@NotNull String path, @Nullable List defaultValue) { - CMMemorySection section = getSectionInternal(path); - if (section == null) return defaultValue; - String key = path.substring(path.lastIndexOf('.') + 1); - Object value = section.actualValues.getOrDefault(key, defaultValue); + Object value = get(path, defaultValue); if (value == null) return defaultValue; if (value.getClass().isArray()) { value = Arrays.asList((Object[]) value); From de8c2269f97526c51632b692d27e7c0268902b3c Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 18 Jul 2021 15:18:33 +0100 Subject: [PATCH 048/134] Add internal method getKey --- .../configurationmaster/impl/CMConfigSection.java | 6 +++--- .../configurationmaster/impl/CMMemorySection.java | 12 ++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index bf1d277..94b3aaa 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -30,7 +30,7 @@ public void addDefault(@NotNull String path, Object defaultOption, @Nullable Str String fullPath = getPathWithKey(path); CMMemorySection cmSection = getSectionInternal(path); if (cmSection == null) cmSection = createSectionInternal(path); - String key = path.substring(path.lastIndexOf('.') + 1); + String key = getKey(path); // Move comments to parent option List comments = new ArrayList<>(getParent().getPendingComments()); String parentSection = path.substring(0, path.indexOf('.') == -1 ? path.length() : path.indexOf('.')); @@ -115,7 +115,7 @@ public void addExample(@NotNull String path, Object object, String comment) { if (!getParent().isNew()) { CMMemorySection section = getSectionInternal(path); if (section == null) return; - String key = path.substring(path.lastIndexOf('.') + 1); + String key = getKey(path); if (!section.existingValues.containsKey(key)) return; } forceExample(path, object, comment); @@ -126,7 +126,7 @@ public void createExampleSection(@NotNull String path) { if (!getParent().isNew()) { CMMemorySection section = (CMMemorySection) getConfigSection(path); if (section == null) return; - String key = path.substring(path.lastIndexOf('.') + 1); + String key = getKey(path); if (!section.existingValues.containsKey(key)) return; } getParent().getExamples().add(getPathWithKey(path)); diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index 7a23791..987efee 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -68,7 +68,7 @@ public double getDouble(@NotNull String path, double defaultValue) { public Object get(@NotNull String path, @Nullable Object defaultValue) { CMMemorySection section = getSectionInternal(path); if (section == null) return defaultValue; - String key = path.substring(path.lastIndexOf('.') + 1); + String key = getKey(path); return section.actualValues.getOrDefault(key, defaultValue); } @@ -130,14 +130,14 @@ public ConfigSection getConfigSection(@NotNull String path, @Nullable ConfigSect public boolean contains(@NotNull String path) { CMMemorySection section = getSectionInternal(path); if (section == null) return false; - String key = path.substring(path.lastIndexOf('.') + 1); + String key = getKey(path); return section.actualValues.containsKey(key); } protected boolean containsExisting(String path) { CMMemorySection section = getSectionInternal(path); if (section == null) return false; - String key = path.substring(path.lastIndexOf('.') + 1); + String key = getKey(path); return section.existingValues.containsKey(key); } @@ -160,7 +160,7 @@ public void set(@NotNull String path, @Nullable Object object) { if (object == null) return; section = getParent().createConfigSection(path); } - String key = path.substring(path.lastIndexOf('.') + 1); + String key = getKey(path); if (object == null) { section.actualValues.remove(key); return; @@ -207,4 +207,8 @@ public String getPath() { protected ConfigFile getParent() { return this instanceof ConfigFile ? (ConfigFile) this : parent; } + + protected String getKey(String path) { + return path.substring(path.lastIndexOf('.') + 1); + } } From f3fc9b13ab9b0c3478deef1b9131c0e74a94d55e Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 18 Jul 2021 15:34:20 +0100 Subject: [PATCH 049/134] Added makeSectionLenient to ConfigSection interface --- .../thatsmusic99/configurationmaster/api/ConfigSection.java | 2 ++ .../thatsmusic99/configurationmaster/impl/CMConfigSection.java | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java index fc8309c..0c4f99e 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java @@ -33,5 +33,7 @@ public interface ConfigSection extends MemorySection { void forceExample(@NotNull String path, @Nullable Object value, @Nullable String comment); + void makeSectionLenient(@NotNull String path); + ConfigSection createConfigSection(@NotNull String path); } diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 94b3aaa..a408d8a 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -133,7 +133,6 @@ public void createExampleSection(@NotNull String path) { createConfigSection(path); } - public void makeSectionLenient(String path) { @Override public void forceExample(@NotNull String path, @Nullable Object value) { forceExample(path, value, null); @@ -145,6 +144,8 @@ public void forceExample(@NotNull String path, @Nullable Object value, @Nullable addDefault(path, value, null, comment); } + @Override + public void makeSectionLenient(@NotNull String path) { CMConfigSection section = (CMConfigSection) getSectionInternal(path + ".haha"); if (section == null) section = createSectionInternal(path + ".haha"); section.forceExistingIntoActual(); From a4053f81b45f1168c4ea4e87105489317b352a84 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 18 Jul 2021 15:34:55 +0100 Subject: [PATCH 050/134] Tweaked annotations --- .../thatsmusic99/configurationmaster/api/ConfigSection.java | 4 ++-- .../configurationmaster/impl/CMConfigSection.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java index 0c4f99e..4db16e2 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java @@ -7,9 +7,9 @@ public interface ConfigSection extends MemorySection { void addDefault(@NotNull String path, @Nullable Object value); - void addDefault(@NotNull String path, @Nullable Object value, @NotNull String comment); + void addDefault(@NotNull String path, @Nullable Object value, @Nullable String comment); - void addDefault(@NotNull String path, @Nullable Object value, @NotNull String section, @NotNull String comment); + void addDefault(@NotNull String path, @Nullable Object value, @Nullable String section, @Nullable String comment); void addComment(@NotNull String path, @NotNull String comment); diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index a408d8a..195212e 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -17,15 +17,15 @@ public CMConfigSection(String path, ConfigFile file) { super(path, file); } - public void addDefault(@NotNull String path, Object defaultOption) { + public void addDefault(@NotNull String path, @Nullable Object defaultOption) { addDefault(path, defaultOption, null, null); } - public void addDefault(@NotNull String path, Object defaultOption, @NotNull String comment) { + public void addDefault(@NotNull String path, @Nullable Object defaultOption, @Nullable String comment) { addDefault(path, defaultOption, null, comment); } - public void addDefault(@NotNull String path, Object defaultOption, @Nullable String section, @Nullable String comment) { + public void addDefault(@NotNull String path, @Nullable Object defaultOption, @Nullable String section, @Nullable String comment) { // String fullPath = getPathWithKey(path); CMMemorySection cmSection = getSectionInternal(path); From 9aa7831e9cba20ca98c5a6bf7af5b90436f813fb Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 18 Jul 2021 15:36:36 +0100 Subject: [PATCH 051/134] Added null checks to the API implementations --- .../impl/CMConfigSection.java | 20 +++++++++++++++++++ .../impl/CMMemorySection.java | 1 + 2 files changed, 21 insertions(+) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 195212e..4b3c965 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -26,6 +26,7 @@ public void addDefault(@NotNull String path, @Nullable Object defaultOption, @Nu } public void addDefault(@NotNull String path, @Nullable Object defaultOption, @Nullable String section, @Nullable String comment) { + Objects.requireNonNull(path, "The path cannot be null!"); // String fullPath = getPathWithKey(path); CMMemorySection cmSection = getSectionInternal(path); @@ -72,6 +73,10 @@ public void moveTo(@NotNull String oldPath, @NotNull String newPath) { @Override public void moveTo(@NotNull String oldPath, @NotNull String newPath, @NotNull ConfigFile otherFile) { + Objects.requireNonNull(oldPath, "The old path cannot be null!"); + Objects.requireNonNull(newPath, "The new path cannot be null!"); + Objects.requireNonNull(otherFile, "The file being transferred to cannot be null!"); + if (!contains(oldPath)) return; CMMemorySection oldCmSection = getSectionInternal(oldPath); if (oldCmSection == null) return; @@ -86,6 +91,9 @@ public void moveTo(@NotNull String oldPath, @NotNull String newPath, @NotNull Co @Override public void addComment(@NotNull String path, @NotNull String comment) { + Objects.requireNonNull(path, "The path cannot be null!"); + Objects.requireNonNull(comment, "The comment cannot be null!"); + // If a specified path already has comments, add this one onto the existing comment, otherwise just add it if (getParent().getComments().containsKey(path)) { String newComment = getParent().getComments().get(path) + "\n\n" + comment; getParent().getComments().put(getPathWithKey(path), newComment); @@ -96,6 +104,9 @@ public void addComment(@NotNull String path, @NotNull String comment) { @Override public void addComments(@NotNull String path, @NotNull String... comments) { + Objects.requireNonNull(path, "The path cannot be null!"); + Objects.requireNonNull(comments, "The comments array cannot be null!"); + if (comments.length == 0) return; StringBuilder builder = new StringBuilder(); builder.append(comments[0]); @@ -112,6 +123,8 @@ public void addExample(@NotNull String path, Object object) { @Override public void addExample(@NotNull String path, Object object, String comment) { + Objects.requireNonNull(path, "The path cannot be null!"); + if (!getParent().isNew()) { CMMemorySection section = getSectionInternal(path); if (section == null) return; @@ -123,6 +136,8 @@ public void addExample(@NotNull String path, Object object, String comment) { @Override public void createExampleSection(@NotNull String path) { + Objects.requireNonNull(path, "The path cannot be null!"); + if (!getParent().isNew()) { CMMemorySection section = (CMMemorySection) getConfigSection(path); if (section == null) return; @@ -140,12 +155,16 @@ public void forceExample(@NotNull String path, @Nullable Object value) { @Override public void forceExample(@NotNull String path, @Nullable Object value, @Nullable String comment) { + Objects.requireNonNull(path, "The path cannot be null!"); getParent().getExamples().add(getPathWithKey(path)); addDefault(path, value, null, comment); } @Override public void makeSectionLenient(@NotNull String path) { + // TODO - allow null/empty path to signify making the whole ass file lenient + Objects.requireNonNull(path, "The path cannot be null!"); + // TODO - don't use internals here CMConfigSection section = (CMConfigSection) getSectionInternal(path + ".haha"); if (section == null) section = createSectionInternal(path + ".haha"); section.forceExistingIntoActual(); @@ -174,6 +193,7 @@ protected CMConfigSection createSectionInternal(@NotNull String path) { @Override public CMConfigSection createConfigSection(@NotNull String path) { + Objects.requireNonNull(path, "The path must not be null!"); String[] sections = path.split("\\."); CMConfigSection toEdit = this; for (int i = 0; i < sections.length; i++) { diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index 987efee..f756531 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -170,6 +170,7 @@ public void set(@NotNull String path, @Nullable Object object) { @Nullable protected CMMemorySection getSectionInternal(@NotNull String path) { + Objects.requireNonNull(path, "Path must not be null!"); CMMemorySection section = this; while (path.indexOf('.') != -1 && section != null) { String key = path.substring(0, path.indexOf('.')); From 2c52ca7f9c455da568fcd163c00ab49fac47e9e3 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 18 Jul 2021 15:37:38 +0100 Subject: [PATCH 052/134] Code cleanup/rearranging --- .../api/CommentWriter.java | 52 +++++++++---------- .../configurationmaster/api/ConfigFile.java | 2 +- .../impl/CMConfigSection.java | 12 ++--- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java index 866b5b9..cdc4805 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java @@ -3,7 +3,7 @@ import java.util.ArrayList; import java.util.List; -public class CommentWriter { +class CommentWriter { private final ConfigFile config; // The currently written lines of the file. @@ -21,38 +21,36 @@ protected void writeComments(List currentLines) { this.currentLines = currentLines; // For each comment to be made... for (String path : config.getComments().keySet()) { - // Get all the divisions made in the config - String[] divisions = path.split("\\."); - - writeComment(path, divisions, 0, 0); + // Write the comment at the specified path + writeComment(path, path.split("\\."), 0, 0); } // However, if there's any comments left, write them in. for (String str : config.getPendingComments()) { if (str.isEmpty()) { currentLines.add(""); - } else { - currentLines.add(""); - String[] rawComment = str.split("\n"); - for (String commentPart : rawComment) { - if (commentPart.isEmpty()) { - currentLines.add(""); - } else { - if (commentPart.startsWith("CONFIG_SECTION: ")) { - String section = commentPart.split(": ")[1]; - StringBuilder length = new StringBuilder(); - length.append("###"); - for (int j = 0; j < section.length(); j++) { - length.append("#"); - } - length.append("###"); - currentLines.add(length.toString()); - currentLines.add("# " + section + " #"); - currentLines.add(length.toString()); - } else { - currentLines.add("# " + commentPart); - } + continue; + } + currentLines.add(""); + String[] rawComment = str.split("\n"); + for (String commentPart : rawComment) { + if (commentPart.isEmpty()) { + currentLines.add(""); + continue; + } + if (commentPart.startsWith("CONFIG_SECTION: ")) { + String section = commentPart.split(": ")[1]; + StringBuilder length = new StringBuilder(); + length.append("###"); + for (int j = 0; j < section.length(); j++) { + length.append("#"); } + length.append("###"); + currentLines.add(length.toString()); + currentLines.add("# " + section + " #"); + currentLines.add(length.toString()); + } else { + currentLines.add("# " + commentPart); } } } @@ -121,7 +119,7 @@ private void writeComment(String path, String[] divisions, int iteration, int st } } - public List getLines() { + protected List getLines() { return currentLines; } } diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 3dd84f0..680061c 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -22,7 +22,7 @@ public class ConfigFile extends CMConfigSection { private final Representer yamlRepresenter = new Representer(); private final File file; private boolean isNew = false; - private CommentWriter writer; + private final CommentWriter writer; private Title title = null; protected List pendingComments; protected HashMap comments; diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 4b3c965..7c5d407 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -196,13 +196,13 @@ public CMConfigSection createConfigSection(@NotNull String path) { Objects.requireNonNull(path, "The path must not be null!"); String[] sections = path.split("\\."); CMConfigSection toEdit = this; - for (int i = 0; i < sections.length; i++) { - Object option = toEdit.actualValues.get(sections[i]); + for (String section : sections) { + Object option = toEdit.actualValues.get(section); if (option == null) { option = new CMConfigSection( - toEdit.getPath().length() == 0 ? sections[i] : toEdit.getPath() + "." + sections[i], + toEdit.getPath().length() == 0 ? section : toEdit.getPath() + "." + section, toEdit.getParent()); - toEdit.actualValues.put(sections[i], option); + toEdit.actualValues.put(section, option); toEdit = (CMConfigSection) option; } else if (option instanceof CMConfigSection) { toEdit = (CMConfigSection) option; @@ -213,7 +213,7 @@ public CMConfigSection createConfigSection(@NotNull String path) { return toEdit; } - public Map convertToMap() { + protected Map convertToMap() { LinkedHashMap map = new LinkedHashMap<>(); for (String path : actualValues.keySet()) { if (actualValues.get(path) instanceof CMConfigSection) { @@ -225,7 +225,7 @@ public Map convertToMap() { return map; } - public void mapToCM(Map map) { + protected void mapToCM(Map map) { for (Object keyObj : map.keySet()) { String key = keyObj.toString(); Object value = map.get(keyObj); From f12e6453f3e79c7ef3fd162f506a0960c37e1d1b Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 18 Jul 2021 15:37:59 +0100 Subject: [PATCH 053/134] Added some documentation --- .../configurationmaster/api/ConfigFile.java | 23 +++++++ .../api/ConfigSection.java | 11 ++++ .../api/MemorySection.java | 60 +++++++++++++++++++ 3 files changed, 94 insertions(+) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 680061c..6a02214 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -14,6 +14,29 @@ import java.nio.file.Files; import java.util.*; +/** + * Represents a specialised YAML file in ConfigurationMaster.

+ * + * It can be initialised using the following methods:
+ * + *
    + *
  1. {@link ConfigFile#loadConfig(File)} - this loads a file with safety precautions. + * If the file contains a syntax error, the API will print an error, + * rename the file temporarily and load a new empty file. + * + * It is recommended to use this if you want your users to + * not lose their progress on a config file if they make a + * single mistake. + *
  2. + * + *
  3. {@link io.github.thatsmusic99.configurationmaster.api.ConfigFile#ConfigFile(File)} + * - this loads a file without the safety precautions taken above. + * This is recommended if you want to handle YAMLExceptions.
  4. + * + *
  5. Simply extend the class. This will not take any safety precautions, similarly to using the constructor.
  6. + *
+ * + */ public class ConfigFile extends CMConfigSection { private final Yaml yaml; diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java index 4db16e2..1c37a54 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java @@ -5,6 +5,17 @@ public interface ConfigSection extends MemorySection { + /** + * Adds a default value to an option in the config file. + * + * If the option does not exist, it will be added with the provided default value. + * + * However, if the option does exist, it will only be adjusted to its correct position. The value inside does not change. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @param value The default value to be used if the option doesn't already exist. + */ void addDefault(@NotNull String path, @Nullable Object value); void addDefault(@NotNull String path, @Nullable Object value, @Nullable String comment); diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java index 194cd70..8e38247 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java @@ -8,24 +8,84 @@ public interface MemorySection { + /** + * Returns a string at a specified path. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @return The string stored at the path. If nothing is found, a value of null is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ + @Nullable default String getString(@NotNull String path) { return getString(path, null); } + /** + * Returns a string at a specified path. If it is not found, the default value is returned. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @param defaultValue The default value to be returned if nothing is found. + * @return The string stored at the path. If nothing is found, the default value is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ String getString(@NotNull String path, @Nullable String defaultValue); + /** + * Returns an integer at a specified path. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @return The integer stored at the path. If nothing is found, a value of 0 is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ default int getInteger(@NotNull String path) { return getInteger(path, 0); } + /** + * Returns an integer at a specified path. If it is not found, the default value is returned. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @param defaultValue The default value to be returned if nothing is found. + * @return The integer stored at the path. If nothing is found, the default value is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ int getInteger(@NotNull String path, int defaultValue); + /** + * Returns a double at a specified path. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @return The double stored at the path. If nothing is found, a value of 0.0 is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ default double getDouble(@NotNull String path) { return getDouble(path, 0.0); } + /** + * Returns a double at a specified path. If it is not found, the default value is returned. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @param defaultValue The default value to be returned if nothing is found. + * @return The double stored at the path. If nothing is found, the default value is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ double getDouble(@NotNull String path, double defaultValue); + /** + * Returns an object at a specified path. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @return The object stored at the path. If nothing is found, a null value is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ default Object get(@NotNull String path) { return get(path, null); } From 127c01911d695c2e2a7d74ed52f880b32463851b Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 18 Jul 2021 15:39:17 +0100 Subject: [PATCH 054/134] Bumped version to v2.0.0-BETA-1 --- API/pom.xml | 4 ++-- Bukkit/pom.xml | 4 ++-- Bukkit/src/main/resources/plugin.yml | 2 +- pom.xml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index d927dd8..9af54fe 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-ALPHA-4 + v2.0.0-BETA-1 4.0.0 ConfigurationMaster-API - v2.0.0-ALPHA-4 + v2.0.0-BETA-1 8 diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index 1f5c25f..21721cc 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-ALPHA-4 + v2.0.0-BETA-1 4.0.0 ConfigurationMaster-Bukkit - v2.0.0-ALPHA-4 + v2.0.0-BETA-1 8 diff --git a/Bukkit/src/main/resources/plugin.yml b/Bukkit/src/main/resources/plugin.yml index 2edd944..536d3d3 100644 --- a/Bukkit/src/main/resources/plugin.yml +++ b/Bukkit/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ main: io.github.thatsmusic99.configurationmaster.ConfigurationMaster name: ConfigurationMaster -version: 2.0.0-ALPHA-4 +version: 2.0.0-BETA-1 author: Thatsmusic99 api-version: 1.13 \ No newline at end of file diff --git a/pom.xml b/pom.xml index 464d9fa..a1e5cf7 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.github.thatsmusic99 ConfigurationMaster pom - v2.0.0-ALPHA-4 + v2.0.0-BETA-1 From 566f295894a4658b63eb4f361596c1a599406af2 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 18 Jul 2021 15:44:08 +0100 Subject: [PATCH 055/134] are you kidding me --- Bukkit/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index 21721cc..c840070 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -44,7 +44,7 @@ com.github.thatsmusic99 ConfigurationMaster-API - v2.0.0-ALPHA-4 + v2.0.0-BETA-1 From e34e865a79de59955cfe7a7cd59154373d3b04ef Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 18 Jul 2021 15:44:20 +0100 Subject: [PATCH 056/134] Extended AT tests for Title API --- .../configurationmaster/AdvancedTeleportTest.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java b/API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java index 16283fc..7769be0 100644 --- a/API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java +++ b/API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java @@ -1,6 +1,7 @@ package io.github.thatsmusic99.configurationmaster; import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import io.github.thatsmusic99.configurationmaster.api.Title; import org.junit.Assert; import org.junit.Test; @@ -18,6 +19,17 @@ public void initATConfig() throws IOException { file.createNewFile(); } ConfigFile config = ConfigFile.loadConfig(file); + config.setTitle(new Title().withWidth(100).addSolidLine() + .addLine("-<( AdvancedTeleport )>-", Title.Pos.CENTER) + .addLine("Made by Niestrat99 and Thatsmusic99", Title.Pos.CENTER) + .addLine("") + .addSolidLine('-') + .addLine("A rapidly growing teleportation plugin looking to break the boundaries of traditional teleport plugins.") + .addLine("") + .addLine("SpigotMC - https://www.spigotmc.org/resources/advanced-teleport.64139/") + .addLine("Wiki - https://github.com/Niestrat99/AT-Rewritten/wiki") + .addLine("Discord - https://discord.gg/mgWbbN4") + .addSolidLine()); config.addComment("Another comment at the very top for all you lads :)"); config.addDefault("use-basic-teleport-features", true, "Features", "Whether basic teleportation features should be enabled or not." + From b70d4a0e8d67c37fb5a112ffd4a0d4f49ce66537 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Mon, 9 Aug 2021 18:42:30 +0100 Subject: [PATCH 057/134] Fixed #moveTo and #moveToNew not working properly --- .../thatsmusic99/configurationmaster/impl/CMConfigSection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 7c5d407..6fc718c 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -77,7 +77,7 @@ public void moveTo(@NotNull String oldPath, @NotNull String newPath, @NotNull Co Objects.requireNonNull(newPath, "The new path cannot be null!"); Objects.requireNonNull(otherFile, "The file being transferred to cannot be null!"); - if (!contains(oldPath)) return; + if (!containsExisting(oldPath)) return; CMMemorySection oldCmSection = getSectionInternal(oldPath); if (oldCmSection == null) return; CMMemorySection newCmSection = otherFile.getSectionInternal(newPath); From d14ab7f94b913078056c5f790c1b3785f510079e Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Mon, 9 Aug 2021 18:44:18 +0100 Subject: [PATCH 058/134] Completed documentation for MemorySection --- .../api/MemorySection.java | 170 ++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java index 8e38247..a902637 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java @@ -6,6 +6,9 @@ import java.util.ArrayList; import java.util.List; +/** + * A MemorySection represents a section in the configuration that holds data. + */ public interface MemorySection { /** @@ -90,62 +93,229 @@ default Object get(@NotNull String path) { return get(path, null); } + /** + * Returns an object at a specified path. If it is not found, the default value is returned. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @param defaultValue The default value to be returned if nothing is found. + * @return The object stored at the path. If nothing is found, the default value is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ Object get(@NotNull String path, @Nullable Object defaultValue); + /** + * Returns a boolean at a specified path. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @return The boolean stored at the path. If nothing is found, false is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ default boolean getBoolean(@NotNull String path) { return getBoolean(path, false); } + /** + * Returns a boolean at a specified path. If it is not found, the default value is returned. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @param defaultValue The default value to be returned if nothing is found. + * @return The boolean stored at the path. If nothing is found, the default value is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ boolean getBoolean(@NotNull String path, boolean defaultValue); + /** + * Returns a long at a specified path. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @return The long stored at the path. If nothing is found, a value of 0 is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ default long getLong(@NotNull String path) { return getLong(path, 0); } + /** + * Returns a long at a specified path. If it is not found, the default value is returned. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @param defaultValue The default value to be returned if nothing is found. + * @return The long stored at the path. If nothing is found, the default value is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ long getLong(@NotNull String path, long defaultValue); + /** + * Returns a short at a specified path. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @return The short stored at the path. If nothing is found, a value of 0 is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ default short getShort(@NotNull String path) { return getShort(path, (short) 0); } + /** + * Returns a short at a specified path. If it is not found, the default value is returned. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @param defaultValue The default value to be returned if nothing is found. + * @return The short stored at the path. If nothing is found, the default value is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ short getShort(@NotNull String path, short defaultValue); + /** + * Returns a byte at a specified path. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @return The byte stored at the path. If nothing is found, a value of 0 is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ default byte getByte(@NotNull String path) { return getByte(path, (byte) 0); } + /** + * Returns a byte at a specified path. If it is not found, the default value is returned. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @param defaultValue The default value to be returned if nothing is found. + * @return The byte stored at the path. If nothing is found, the default value is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ byte getByte(@NotNull String path, byte defaultValue); + /** + * Returns a float at a specified path. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @return The float stored at the path. If nothing is found, a value of 0 is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ default float getFloat(@NotNull String path) { return getFloat(path, 0f); } + /** + * Returns a float at a specified path. If it is not found, the default value is returned. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @param defaultValue The default value to be returned if nothing is found. + * @return The float stored at the path. If nothing is found, the default value is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ float getFloat(@NotNull String path, float defaultValue); + /** + * Returns a configuration file at a specified path. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @return The configuration section stored at the path. If nothing is found, a null value is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ default ConfigSection getConfigSection(@NotNull String path) { return getConfigSection(path, null); } + /** + * Returns a configuration section at a specified path. If it is not found, the default value is returned. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @param defaultValue The default value to be returned if nothing is found. + * @return The configuration section stored at the path. If nothing is found, the default value is returned. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ ConfigSection getConfigSection(@NotNull String path, @Nullable ConfigSection defaultValue); + /** + * Returns whether or not the memory section contains a specific path. + * + * @param path The path to search for. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @return true if the memory section contains the path, false if not. + */ boolean contains(@NotNull String path); + /** + * Returns a list at a given path. If the provided path does not point to a list but a different data type, + * a new list is created containing that single element. If the path itself is not found, an empty list is created. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @param The list type you want returned. + * @return The list stored at the path. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ @NotNull default List getList(@NotNull String path) { return getList(path, new ArrayList<>()); } + /** + * Returns a string list at a given path. If the provided path does not point to a list but a different data type, + * a new list is created containing that single element. If the path itself is not found, an empty list is created. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @return The string list stored at the path. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ @NotNull default List getStringList(@NotNull String path) { return getList(path, new ArrayList<>()); } + /** + * Returns a list at a given path. If the provided path does not point to a list but a different data type, + * a new list is created containing that single element. If the path itself is not found, the default value is returned. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @param defaultValue The default value to be returned if nothing is found. + * @param The list type you want returned. + * @return The list stored at the path. + * @throws NullPointerException if the path is null (not if it wasn't found). + */ List getList(@NotNull String path, @Nullable List defaultValue); + /** + * Sets a value at a specified path. + * + * @param path The path of the option itself. + * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option + * @param object The object the option will be set to. + */ void set(@NotNull String path, @Nullable Object object); + /** + * Returns a list of option/config section keys stored within this memory section. + * + * @param deep true if options within configuration sections should be included, false if you just want to collect + * keys from this memory section only. + * @return A list of keys to the given paths. + */ List getKeys(boolean deep); + /** + * The path of this section. + * + * @return The full path - periods included - of this section. + */ String getPath(); From 85918444597e4b5a1a5fed7057fab36c4e870015 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Mon, 9 Aug 2021 18:44:33 +0100 Subject: [PATCH 059/134] Bumped version --- API/pom.xml | 4 ++-- Bukkit/pom.xml | 4 ++-- Bukkit/src/main/resources/plugin.yml | 2 +- pom.xml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index 9af54fe..cf00186 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-1 + v2.0.0-BETA-2 4.0.0 ConfigurationMaster-API - v2.0.0-BETA-1 + v2.0.0-BETA-2 8 diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index c840070..395c9af 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-1 + v2.0.0-BETA-2 4.0.0 ConfigurationMaster-Bukkit - v2.0.0-BETA-1 + v2.0.0-BETA-2 8 diff --git a/Bukkit/src/main/resources/plugin.yml b/Bukkit/src/main/resources/plugin.yml index 536d3d3..df5c9c7 100644 --- a/Bukkit/src/main/resources/plugin.yml +++ b/Bukkit/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ main: io.github.thatsmusic99.configurationmaster.ConfigurationMaster name: ConfigurationMaster -version: 2.0.0-BETA-1 +version: 2.0.0-BETA-2 author: Thatsmusic99 api-version: 1.13 \ No newline at end of file diff --git a/pom.xml b/pom.xml index a1e5cf7..5dd38a5 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.github.thatsmusic99 ConfigurationMaster pom - v2.0.0-BETA-1 + v2.0.0-BETA-2 From 1c3bd8ac50f8ca5d8014f41a461abbef3a39e918 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Mon, 9 Aug 2021 22:49:53 +0100 Subject: [PATCH 060/134] Fixed moveTo and reload regenerating stuff we don't want --- .../configurationmaster/impl/CMConfigSection.java | 2 +- .../configurationmaster/impl/CMMemorySection.java | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 6fc718c..efbcb83 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -78,7 +78,7 @@ public void moveTo(@NotNull String oldPath, @NotNull String newPath, @NotNull Co Objects.requireNonNull(otherFile, "The file being transferred to cannot be null!"); if (!containsExisting(oldPath)) return; - CMMemorySection oldCmSection = getSectionInternal(oldPath); + CMMemorySection oldCmSection = getSectionInternal(oldPath, false); if (oldCmSection == null) return; CMMemorySection newCmSection = otherFile.getSectionInternal(newPath); if (newCmSection == null) newCmSection = otherFile.createSectionInternal(newPath); diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index f756531..b71bcee 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -135,7 +135,7 @@ public boolean contains(@NotNull String path) { } protected boolean containsExisting(String path) { - CMMemorySection section = getSectionInternal(path); + CMMemorySection section = getSectionInternal(path, false); if (section == null) return false; String key = getKey(path); return section.existingValues.containsKey(key); @@ -170,6 +170,10 @@ public void set(@NotNull String path, @Nullable Object object) { @Nullable protected CMMemorySection getSectionInternal(@NotNull String path) { + return getSectionInternal(path, true); + } + + protected CMMemorySection getSectionInternal(@NotNull String path, boolean add) { Objects.requireNonNull(path, "Path must not be null!"); CMMemorySection section = this; while (path.indexOf('.') != -1 && section != null) { @@ -181,7 +185,7 @@ protected CMMemorySection getSectionInternal(@NotNull String path) { } else { tempSection = (CMMemorySection) section.getConfigSection(key); } - if (tempSection != null) section.actualValues.putIfAbsent(key, tempSection); + if (tempSection != null && add) section.actualValues.putIfAbsent(key, tempSection); section = tempSection; } return section; From bdd2a4ac0b05719eec96b4c825c56be02c5f9283 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Wed, 11 Aug 2021 17:44:12 +0100 Subject: [PATCH 061/134] gaaaah --- .../configurationmaster/impl/CMConfigSection.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index efbcb83..a78b03d 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -127,9 +127,15 @@ public void addExample(@NotNull String path, Object object, String comment) { if (!getParent().isNew()) { CMMemorySection section = getSectionInternal(path); - if (section == null) return; + if (section == null) { + getParent().getExamples().add(getPathWithKey(path)); + return; + } String key = getKey(path); - if (!section.existingValues.containsKey(key)) return; + if (!section.existingValues.containsKey(key)) { + getParent().getExamples().add(getPathWithKey(path)); + return; + } } forceExample(path, object, comment); } @@ -138,13 +144,13 @@ public void addExample(@NotNull String path, Object object, String comment) { public void createExampleSection(@NotNull String path) { Objects.requireNonNull(path, "The path cannot be null!"); + getParent().getExamples().add(getPathWithKey(path)); if (!getParent().isNew()) { CMMemorySection section = (CMMemorySection) getConfigSection(path); if (section == null) return; String key = getKey(path); if (!section.existingValues.containsKey(key)) return; } - getParent().getExamples().add(getPathWithKey(path)); createConfigSection(path); } @@ -173,6 +179,9 @@ public void makeSectionLenient(@NotNull String path) { } private void forceExistingIntoActual() { + if (!getParent().isNew()) { + actualValues.clear(); + } for (String key : existingValues.keySet()) { if (existingValues.get(key) instanceof CMConfigSection) { ((CMConfigSection) existingValues.get(key)).forceExistingIntoActual(); From 1864683998eebd25a0d5b451ffe1bc587a8190cc Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Wed, 11 Aug 2021 17:44:33 +0100 Subject: [PATCH 062/134] Close that damned file reader --- .../thatsmusic99/configurationmaster/api/ConfigFile.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 6a02214..7746edc 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -128,6 +128,11 @@ private void loadWithExceptions() { } if (content.length() == 0) isNew = true; loadFromString(content.toString()); + try { + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } } private void loadFromString(String str) { From b6af5206557d7584c8c5ef6d7de6a56624f89a00 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Wed, 11 Aug 2021 17:44:55 +0100 Subject: [PATCH 063/134] Re-add options where required --- .../thatsmusic99/configurationmaster/api/ConfigFile.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 7746edc..99cda04 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -111,6 +111,7 @@ private void loadWithExceptions() { try { file.createNewFile(); reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); + isNew = true; } catch (IOException e) { e.printStackTrace(); return; @@ -150,6 +151,7 @@ private void loadFromString(String str) { public void save() throws IOException { try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) { writer.write(saveToString()); + isNew = false; } } @@ -166,7 +168,7 @@ public void reload() throws IOException { loadWithExceptions(); for (String path : allDefaults.keySet()) { - if (!examples.contains(path) || containsExisting(path)) { + if (!examples.contains(path) || containsExisting(path) || isNew) { addDefault(path, allDefaults.get(path)); } } From ce8cf11167259ff7ee23e3b1f77a25854f4aebe7 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 4 Sep 2021 10:57:52 +0100 Subject: [PATCH 064/134] Make saveToString public --- .../github/thatsmusic99/configurationmaster/api/ConfigFile.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 99cda04..dae86a3 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -191,7 +191,7 @@ public boolean isNew() { return isNew; } - private String saveToString() { + public String saveToString() { String dump = this.yaml.dump(convertToMap()); if (dump.equals("{}")) { dump = ""; From c71b5652e1742d38fb715665d863bbb2951f9a86 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 4 Sep 2021 10:58:05 +0100 Subject: [PATCH 065/134] Add ConfigFile#getFile --- .../thatsmusic99/configurationmaster/api/ConfigFile.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index dae86a3..2d9ab6c 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -232,4 +232,8 @@ public Title getTitle() { public void setTitle(Title title) { this.title = title; } + + public File getFile() { + return file; + } } From aa15c0b9e92142ec9c68405fd6d1072726c3d877 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Thu, 14 Oct 2021 13:14:28 +0100 Subject: [PATCH 066/134] Fix the NPE nuke when someone sets a key to null --- .../thatsmusic99/configurationmaster/impl/CMConfigSection.java | 1 + 1 file changed, 1 insertion(+) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index a78b03d..8e4660d 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -236,6 +236,7 @@ protected Map convertToMap() { protected void mapToCM(Map map) { for (Object keyObj : map.keySet()) { + if (keyObj == null) keyObj = "null"; String key = keyObj.toString(); Object value = map.get(keyObj); if (value instanceof Map) { From 5f3afdde0249fe5fa66d7c4d0b66695e126da65c Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 21 Nov 2021 20:24:32 +0000 Subject: [PATCH 067/134] Fixed using set on a non-existent section doing something... uhh... stupid --- .../thatsmusic99/configurationmaster/impl/CMMemorySection.java | 2 +- Bukkit/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index b71bcee..f4c8fcc 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -158,7 +158,7 @@ public void set(@NotNull String path, @Nullable Object object) { CMMemorySection section = getSectionInternal(path); if (section == null) { if (object == null) return; - section = getParent().createConfigSection(path); + section = getParent().createSectionInternal(path); } String key = getKey(path); if (object == null) { diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index 395c9af..2f38b58 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -44,7 +44,7 @@ com.github.thatsmusic99 ConfigurationMaster-API - v2.0.0-BETA-1 + v2.0.0-BETA-2 From 52d3af44b6cddaa7ab3b6e349b8922d90ccaad80 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 21 Nov 2021 21:56:05 +0000 Subject: [PATCH 068/134] Semi-hotfix: add useExisting parameter to most getters --- .../api/MemorySection.java | 126 +++++++++++++++--- .../impl/CMMemorySection.java | 45 ++++--- 2 files changed, 128 insertions(+), 43 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java index a902637..26a7acf 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java @@ -21,7 +21,7 @@ public interface MemorySection { */ @Nullable default String getString(@NotNull String path) { - return getString(path, null); + return getString(path, null, false); } /** @@ -33,7 +33,15 @@ default String getString(@NotNull String path) { * @return The string stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - String getString(@NotNull String path, @Nullable String defaultValue); + default String getString(@NotNull String path, @Nullable String defaultValue) { + return getString(path, defaultValue, false); + } + + default String getString(@NotNull String path, boolean useExisting) { + return getString(path, null, useExisting); + } + + String getString(@NotNull String path, @Nullable String defaultValue, boolean useExisting); /** * Returns an integer at a specified path. @@ -44,7 +52,7 @@ default String getString(@NotNull String path) { * @throws NullPointerException if the path is null (not if it wasn't found). */ default int getInteger(@NotNull String path) { - return getInteger(path, 0); + return getInteger(path, 0, false); } /** @@ -56,7 +64,15 @@ default int getInteger(@NotNull String path) { * @return The integer stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - int getInteger(@NotNull String path, int defaultValue); + default int getInteger(@NotNull String path, int defaultValue) { + return getInteger(path, defaultValue, false); + } + + default int getInteger(@NotNull String path, boolean useExisting) { + return getInteger(path, 0, useExisting); + } + + int getInteger(@NotNull String path, int defaultValue, boolean useExisting); /** * Returns a double at a specified path. @@ -67,7 +83,7 @@ default int getInteger(@NotNull String path) { * @throws NullPointerException if the path is null (not if it wasn't found). */ default double getDouble(@NotNull String path) { - return getDouble(path, 0.0); + return getDouble(path, 0.0, false); } /** @@ -79,7 +95,15 @@ default double getDouble(@NotNull String path) { * @return The double stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - double getDouble(@NotNull String path, double defaultValue); + default double getDouble(@NotNull String path, double defaultValue) { + return getDouble(path, defaultValue, false); + } + + default double getDouble(@NotNull String path, boolean useExisting) { + return getDouble(path, 0, useExisting); + } + + double getDouble(@NotNull String path, double defaultValue, boolean useExisting); /** * Returns an object at a specified path. @@ -90,7 +114,7 @@ default double getDouble(@NotNull String path) { * @throws NullPointerException if the path is null (not if it wasn't found). */ default Object get(@NotNull String path) { - return get(path, null); + return get(path, null, false); } /** @@ -102,7 +126,15 @@ default Object get(@NotNull String path) { * @return The object stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - Object get(@NotNull String path, @Nullable Object defaultValue); + default Object get(@NotNull String path, @Nullable Object defaultValue) { + return get(path, defaultValue, false); + } + + default Object get(@NotNull String path, boolean useExisting) { + return get(path, null, useExisting); + } + + Object get(@NotNull String path, @Nullable Object defaultValue, boolean useExisting); /** * Returns a boolean at a specified path. @@ -125,7 +157,11 @@ default boolean getBoolean(@NotNull String path) { * @return The boolean stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - boolean getBoolean(@NotNull String path, boolean defaultValue); + default boolean getBoolean(@NotNull String path, boolean defaultValue) { + return getBoolean(path, defaultValue, false); + } + + boolean getBoolean(@NotNull String path, boolean defaultValue, boolean useExisting); /** * Returns a long at a specified path. @@ -136,7 +172,7 @@ default boolean getBoolean(@NotNull String path) { * @throws NullPointerException if the path is null (not if it wasn't found). */ default long getLong(@NotNull String path) { - return getLong(path, 0); + return getLong(path, 0, false); } /** @@ -148,7 +184,15 @@ default long getLong(@NotNull String path) { * @return The long stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - long getLong(@NotNull String path, long defaultValue); + default long getLong(@NotNull String path, long defaultValue) { + return getLong(path, defaultValue, false); + } + + default long getLong(@NotNull String path, boolean useExisting) { + return getLong(path, 0, useExisting); + } + + long getLong(@NotNull String path, long defaultValue, boolean useExisting); /** * Returns a short at a specified path. @@ -159,7 +203,7 @@ default long getLong(@NotNull String path) { * @throws NullPointerException if the path is null (not if it wasn't found). */ default short getShort(@NotNull String path) { - return getShort(path, (short) 0); + return getShort(path, (short) 0, false); } /** @@ -171,7 +215,15 @@ default short getShort(@NotNull String path) { * @return The short stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - short getShort(@NotNull String path, short defaultValue); + default short getShort(@NotNull String path, short defaultValue) { + return getShort(path, defaultValue, false); + } + + default short getShort(@NotNull String path, boolean useExisting) { + return getShort(path, (short) 0, useExisting); + } + + short getShort(@NotNull String path, short defaultValue, boolean useExisting); /** * Returns a byte at a specified path. @@ -182,7 +234,7 @@ default short getShort(@NotNull String path) { * @throws NullPointerException if the path is null (not if it wasn't found). */ default byte getByte(@NotNull String path) { - return getByte(path, (byte) 0); + return getByte(path, (byte) 0, false); } /** @@ -194,7 +246,15 @@ default byte getByte(@NotNull String path) { * @return The byte stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - byte getByte(@NotNull String path, byte defaultValue); + default byte getByte(@NotNull String path, byte defaultValue) { + return getByte(path, defaultValue, false); + } + + default byte getByte(@NotNull String path, boolean useExisting) { + return getByte(path, (byte) 0, useExisting); + } + + byte getByte(@NotNull String path, byte defaultValue, boolean useExisting); /** * Returns a float at a specified path. @@ -205,7 +265,7 @@ default byte getByte(@NotNull String path) { * @throws NullPointerException if the path is null (not if it wasn't found). */ default float getFloat(@NotNull String path) { - return getFloat(path, 0f); + return getFloat(path, 0f, false); } /** @@ -217,7 +277,15 @@ default float getFloat(@NotNull String path) { * @return The float stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - float getFloat(@NotNull String path, float defaultValue); + default float getFloat(@NotNull String path, float defaultValue) { + return getFloat(path, defaultValue, false); + } + + default float getFloat(@NotNull String path, boolean useExisting) { + return getFloat(path, 0.0f, useExisting); + } + + float getFloat(@NotNull String path, float defaultValue, boolean useExisting); /** * Returns a configuration file at a specified path. @@ -228,7 +296,7 @@ default float getFloat(@NotNull String path) { * @throws NullPointerException if the path is null (not if it wasn't found). */ default ConfigSection getConfigSection(@NotNull String path) { - return getConfigSection(path, null); + return getConfigSection(path, null, false); } /** @@ -240,7 +308,15 @@ default ConfigSection getConfigSection(@NotNull String path) { * @return The configuration section stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - ConfigSection getConfigSection(@NotNull String path, @Nullable ConfigSection defaultValue); + default ConfigSection getConfigSection(@NotNull String path, @Nullable ConfigSection defaultValue) { + return getConfigSection(path, defaultValue, false); + } + + default ConfigSection getConfigSection(@NotNull String path, boolean useExisting) { + return getConfigSection(path, null, useExisting); + } + + ConfigSection getConfigSection(@NotNull String path, @Nullable ConfigSection defaultValue, boolean useExisting); /** * Returns whether or not the memory section contains a specific path. @@ -277,7 +353,7 @@ default List getList(@NotNull String path) { */ @NotNull default List getStringList(@NotNull String path) { - return getList(path, new ArrayList<>()); + return getList(path, new ArrayList<>(), false); } /** @@ -291,7 +367,15 @@ default List getStringList(@NotNull String path) { * @return The list stored at the path. * @throws NullPointerException if the path is null (not if it wasn't found). */ - List getList(@NotNull String path, @Nullable List defaultValue); + default List getList(@NotNull String path, @Nullable List defaultValue) { + return getList(path, defaultValue, false); + } + + default List getList(@NotNull String path, boolean useExisting) { + return getList(path, new ArrayList<>(), useExisting); + } + + List getList(@NotNull String path, @Nullable List defaultValue, boolean useExisting); /** * Sets a value at a specified path. diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index f4c8fcc..a082208 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -38,15 +38,15 @@ private void init() { } @Override - public String getString(@NotNull String path, @Nullable String defaultValue) { - Object result = get(path, defaultValue); + public String getString(@NotNull String path, @Nullable String defaultValue, boolean useExisting) { + Object result = get(path, defaultValue, useExisting); if (result == null) return null; return String.valueOf(result); } @Override - public int getInteger(@NotNull String path, int defaultValue) { - String result = getString(path); + public int getInteger(@NotNull String path, int defaultValue, boolean useExisting) { + String result = getString(path, useExisting); try { return result == null ? defaultValue : Integer.parseInt(result); } catch (NumberFormatException ex) { @@ -55,8 +55,8 @@ public int getInteger(@NotNull String path, int defaultValue) { } @Override - public double getDouble(@NotNull String path, double defaultValue) { - String result = getString(path); + public double getDouble(@NotNull String path, double defaultValue, boolean useExisting) { + String result = getString(path, useExisting); try { return result == null ? defaultValue : Double.parseDouble(result); } catch (NumberFormatException ex) { @@ -65,24 +65,25 @@ public double getDouble(@NotNull String path, double defaultValue) { } @Override - public Object get(@NotNull String path, @Nullable Object defaultValue) { + public Object get(@NotNull String path, @Nullable Object defaultValue, boolean useExisting) { CMMemorySection section = getSectionInternal(path); if (section == null) return defaultValue; String key = getKey(path); - return section.actualValues.getOrDefault(key, defaultValue); + return useExisting ? section.existingValues.getOrDefault(key, defaultValue) + : section.actualValues.getOrDefault(key, defaultValue); } @Override - public boolean getBoolean(@NotNull String path, boolean defaultValue) { - String result = getString(path); + public boolean getBoolean(@NotNull String path, boolean defaultValue, boolean useExisting) { + String result = getString(path, useExisting); if (result == null) return defaultValue; if (!(result.equalsIgnoreCase("false") || result.equalsIgnoreCase("true"))) return defaultValue; return result.equalsIgnoreCase("true"); } @Override - public long getLong(@NotNull String path, long defaultValue) { - String result = getString(path); + public long getLong(@NotNull String path, long defaultValue, boolean useExisting) { + String result = getString(path, useExisting); try { return result == null ? defaultValue : Long.parseLong(result); } catch (NumberFormatException ex) { @@ -91,8 +92,8 @@ public long getLong(@NotNull String path, long defaultValue) { } @Override - public short getShort(@NotNull String path, short defaultValue) { - String result = getString(path); + public short getShort(@NotNull String path, short defaultValue, boolean useExisting) { + String result = getString(path, useExisting); try { return result == null ? defaultValue : Short.parseShort(result); } catch (NumberFormatException ex) { @@ -101,8 +102,8 @@ public short getShort(@NotNull String path, short defaultValue) { } @Override - public byte getByte(@NotNull String path, byte defaultValue) { - String result = getString(path); + public byte getByte(@NotNull String path, byte defaultValue, boolean useExisting) { + String result = getString(path, useExisting); try { return result == null ? defaultValue : Byte.parseByte(result); } catch (NumberFormatException ex) { @@ -111,8 +112,8 @@ public byte getByte(@NotNull String path, byte defaultValue) { } @Override - public float getFloat(@NotNull String path, float defaultValue) { - String result = getString(path); + public float getFloat(@NotNull String path, float defaultValue, boolean useExisting) { + String result = getString(path, useExisting); try { return result == null ? defaultValue : Float.parseFloat(result); } catch (NumberFormatException ex) { @@ -121,8 +122,8 @@ public float getFloat(@NotNull String path, float defaultValue) { } @Override - public ConfigSection getConfigSection(@NotNull String path, @Nullable ConfigSection defaultValue) { - Object value = get(path, defaultValue); + public ConfigSection getConfigSection(@NotNull String path, @Nullable ConfigSection defaultValue, boolean useExisting) { + Object value = get(path, defaultValue, useExisting); return value instanceof ConfigSection ? (ConfigSection) value : defaultValue; } @@ -142,8 +143,8 @@ protected boolean containsExisting(String path) { } @Override - public List getList(@NotNull String path, @Nullable List defaultValue) { - Object value = get(path, defaultValue); + public List getList(@NotNull String path, @Nullable List defaultValue, boolean useExisting) { + Object value = get(path, defaultValue, useExisting); if (value == null) return defaultValue; if (value.getClass().isArray()) { value = Arrays.asList((Object[]) value); From 2006b5f2aa192a1eb9898590b9710a51eb6f1712 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sun, 21 Nov 2021 22:11:42 +0000 Subject: [PATCH 069/134] Add the useExisting parameter to contains --- .../configurationmaster/api/MemorySection.java | 6 +++++- .../configurationmaster/impl/CMMemorySection.java | 11 ++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java index 26a7acf..128093f 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java @@ -325,7 +325,11 @@ default ConfigSection getConfigSection(@NotNull String path, boolean useExisting * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option * @return true if the memory section contains the path, false if not. */ - boolean contains(@NotNull String path); + default boolean contains(@NotNull String path) { + return contains(path, false); + } + + boolean contains(@NotNull String path, boolean useExisting); /** * Returns a list at a given path. If the provided path does not point to a list but a different data type, diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index a082208..9f9a8ed 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -128,18 +128,11 @@ public ConfigSection getConfigSection(@NotNull String path, @Nullable ConfigSect } @Override - public boolean contains(@NotNull String path) { + public boolean contains(@NotNull String path, boolean useExisting) { CMMemorySection section = getSectionInternal(path); if (section == null) return false; String key = getKey(path); - return section.actualValues.containsKey(key); - } - - protected boolean containsExisting(String path) { - CMMemorySection section = getSectionInternal(path, false); - if (section == null) return false; - String key = getKey(path); - return section.existingValues.containsKey(key); + return useExisting ? section.existingValues.containsKey(key) : section.actualValues.containsKey(key); } @Override From 34ef7beba37ac664b8526cf4fcabe3f3dbda7df4 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Tue, 23 Nov 2021 22:05:13 +0000 Subject: [PATCH 070/134] it has had to happen AGAIN --- .../configurationmaster/api/MemorySection.java | 6 +++++- .../configurationmaster/impl/CMConfigSection.java | 2 +- .../configurationmaster/impl/CMMemorySection.java | 9 +++++---- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java index 128093f..adf5647 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java @@ -397,7 +397,11 @@ default List getList(@NotNull String path, boolean useExisting) { * keys from this memory section only. * @return A list of keys to the given paths. */ - List getKeys(boolean deep); + default List getKeys(boolean deep) { + return getKeys(deep, false); + } + + List getKeys(boolean deep, boolean useExisting); /** * The path of this section. diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 8e4660d..c2d1e05 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -77,7 +77,7 @@ public void moveTo(@NotNull String oldPath, @NotNull String newPath, @NotNull Co Objects.requireNonNull(newPath, "The new path cannot be null!"); Objects.requireNonNull(otherFile, "The file being transferred to cannot be null!"); - if (!containsExisting(oldPath)) return; + if (!contains(oldPath, true)) return; CMMemorySection oldCmSection = getSectionInternal(oldPath, false); if (oldCmSection == null) return; CMMemorySection newCmSection = otherFile.getSectionInternal(newPath); diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index 9f9a8ed..e0431ea 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -186,11 +186,12 @@ protected CMMemorySection getSectionInternal(@NotNull String path, boolean add) } @Override - public List getKeys(boolean deep) { + public List getKeys(boolean deep, boolean useExisting) { List keys = new ArrayList<>(); - for (String path : actualValues.keySet()) { - if (deep && actualValues.get(path) instanceof CMConfigSection) { - keys.addAll(((CMConfigSection) actualValues.get(path)).getKeys(true)); + HashMap map = useExisting ? existingValues : actualValues; + for (String path : map.keySet()) { + if (deep && map.get(path) instanceof CMConfigSection) { + keys.addAll(((CMConfigSection) map.get(path)).getKeys(true)); } else { keys.add(path); } From 8e9536c08772759a134fc7fb533a20ffe049f191 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Tue, 23 Nov 2021 22:20:15 +0000 Subject: [PATCH 071/134] Stop adding sections that AREN'T NEEDED --- .../thatsmusic99/configurationmaster/impl/CMMemorySection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index e0431ea..96016fa 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -66,7 +66,7 @@ public double getDouble(@NotNull String path, double defaultValue, boolean useEx @Override public Object get(@NotNull String path, @Nullable Object defaultValue, boolean useExisting) { - CMMemorySection section = getSectionInternal(path); + CMMemorySection section = getSectionInternal(path, !useExisting); if (section == null) return defaultValue; String key = getKey(path); return useExisting ? section.existingValues.getOrDefault(key, defaultValue) From 7c6ce6f0eec3fc09ba93a82991db69f3d8b6b4f6 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Tue, 23 Nov 2021 22:33:56 +0000 Subject: [PATCH 072/134] lmao whoops i'm such a caprisun :nail_care: --- .../github/thatsmusic99/configurationmaster/api/ConfigFile.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 2d9ab6c..9acb103 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -168,7 +168,7 @@ public void reload() throws IOException { loadWithExceptions(); for (String path : allDefaults.keySet()) { - if (!examples.contains(path) || containsExisting(path) || isNew) { + if (!examples.contains(path) || contains(path, true) || isNew) { addDefault(path, allDefaults.get(path)); } } From 43013080a3c09fcd4d293db4d6a8d8d372e44d6d Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Mon, 29 Nov 2021 21:49:24 +0000 Subject: [PATCH 073/134] I will kill a THOUSAND children before i kill the economy --- API/pom.xml | 2 +- Bukkit/pom.xml | 2 +- Bukkit/src/main/resources/plugin.yml | 2 +- pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index cf00186..6cad140 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -10,7 +10,7 @@ 4.0.0 ConfigurationMaster-API - v2.0.0-BETA-2 + v2.0.0-BETA-3 8 diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index 2f38b58..113afd4 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,7 +5,7 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-2 + v2.0.0-BETA-3 4.0.0 diff --git a/Bukkit/src/main/resources/plugin.yml b/Bukkit/src/main/resources/plugin.yml index df5c9c7..bdd50bd 100644 --- a/Bukkit/src/main/resources/plugin.yml +++ b/Bukkit/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ main: io.github.thatsmusic99.configurationmaster.ConfigurationMaster name: ConfigurationMaster -version: 2.0.0-BETA-2 +version: 2.0.0-BETA-3 author: Thatsmusic99 api-version: 1.13 \ No newline at end of file diff --git a/pom.xml b/pom.xml index 5dd38a5..0aff0cf 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.github.thatsmusic99 ConfigurationMaster pom - v2.0.0-BETA-2 + v2.0.0-BETA-3 From b5b74e02b36803624264b0fbdf8fd30ca2b766ff Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Tue, 7 Dec 2021 15:55:43 +0000 Subject: [PATCH 074/134] Close the reader in all cases - constructor and loading now throws IOExceptions --- .../configurationmaster/api/ConfigFile.java | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 9acb103..330bac8 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -59,7 +59,7 @@ public class ConfigFile extends CMConfigSection { * @see ConfigFile#loadConfig(File) * @throws YAMLException if the file being loaded contains syntax errors. */ - public ConfigFile(@NotNull File file) { + public ConfigFile(@NotNull File file) throws IOException { yaml = new Yaml(new SafeConstructor(), yamlRepresenter, yamlOptions, loaderOptions); yamlOptions.setIndent(2); yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); @@ -81,7 +81,7 @@ public ConfigFile(@NotNull File file) { * @param file The file to be loaded. * @return the ConfigFile instance of the file or backup file. */ - public static ConfigFile loadConfig(File file) { + public static ConfigFile loadConfig(File file) throws IOException { try { return new ConfigFile(file); } catch (YAMLException e) { @@ -103,36 +103,31 @@ public static ConfigFile loadConfig(File file) { } } - private void loadWithExceptions() { - BufferedReader reader; + private void loadWithExceptions() throws IOException { + BufferedReader reader = null; try { - reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); - } catch (FileNotFoundException ex) { try { + debug("Loading the content of the file " + file.getName() + "..."); + reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); + } catch (FileNotFoundException ex) { + debug("Failed to find the file, creating a new one..."); file.createNewFile(); reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); isNew = true; - } catch (IOException e) { - e.printStackTrace(); - return; } - } - StringBuilder content = new StringBuilder(); - try { + StringBuilder content = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { content.append(line).append("\n"); } - } catch (IOException e) { - e.printStackTrace(); - } - if (content.length() == 0) isNew = true; - loadFromString(content.toString()); - try { - reader.close(); - } catch (IOException e) { - e.printStackTrace(); + if (content.length() == 0) { + debug(file.getName() + " is brand new."); + isNew = true; + } + loadFromString(content.toString()); + } finally { + if (reader != null) reader.close(); } } From 8ffa2a0c339917dba1e717a61b7b49a6e28e5fc6 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Thu, 9 Dec 2021 21:59:25 +0000 Subject: [PATCH 075/134] Nothing was seen --- .../thatsmusic99/configurationmaster/api/ConfigFile.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 330bac8..e9d475f 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -107,10 +107,8 @@ private void loadWithExceptions() throws IOException { BufferedReader reader = null; try { try { - debug("Loading the content of the file " + file.getName() + "..."); reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); } catch (FileNotFoundException ex) { - debug("Failed to find the file, creating a new one..."); file.createNewFile(); reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); isNew = true; @@ -122,7 +120,6 @@ private void loadWithExceptions() throws IOException { content.append(line).append("\n"); } if (content.length() == 0) { - debug(file.getName() + " is brand new."); isNew = true; } loadFromString(content.toString()); From eba029d85d5edf0d96f082c284ab79f56dc07877 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Thu, 9 Dec 2021 22:12:13 +0000 Subject: [PATCH 076/134] oh come on --- .../configurationmaster/HeadsPlusTest.java | 41 ------------------- 1 file changed, 41 deletions(-) delete mode 100644 API/src/test/java/io/github/thatsmusic99/configurationmaster/HeadsPlusTest.java diff --git a/API/src/test/java/io/github/thatsmusic99/configurationmaster/HeadsPlusTest.java b/API/src/test/java/io/github/thatsmusic99/configurationmaster/HeadsPlusTest.java deleted file mode 100644 index b694b2e..0000000 --- a/API/src/test/java/io/github/thatsmusic99/configurationmaster/HeadsPlusTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package io.github.thatsmusic99.configurationmaster; - -import io.github.thatsmusic99.configurationmaster.api.ConfigFile; -import org.junit.Test; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; - -public class HeadsPlusTest { - - @Test - public void animationsTest() { - ConfigFile animations = ConfigFile.loadConfig(new File("animations.yml")); - animations.addComment("This is the config where you can make head animations come to life.\n" + - "For technical reasons, these will only work in inventories and masks."); - - animations.makeSectionLenient("animations"); - - animations.addExample("animations.creeper.looping-mode", "loop-reverse", ""); - animations.addExample("animations.creeper.pausing-period", 4); - animations.addExample("animations.creeper.textures", new ArrayList<>(Arrays.asList( - "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHBzOi8vaS5pbWd1ci5jb20vQXZ1Z29aeC5wbmcifX19", - "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHBzOi8vaS5pbWd1ci5jb20vSlFLeHYzNy5wbmcifX19", - "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHBzOi8vaS5pbWd1ci5jb20vRVRKalhYVS5wbmcifX19", - "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHBzOi8vaS5pbWd1ci5jb20vdVNGTlhway5wbmcifX19", - "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHBzOi8vaS5pbWd1ci5jb20vS0ZGTjJjVy5wbmcifX19", - "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHBzOi8vaS5pbWd1ci5jb20vUUVPUWxYcy5wbmcifX19", - "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHBzOi8vaS5pbWd1ci5jb20vUlQ5TEFkYS5wbmcifX19"))); - - animations.makeSectionLenient("testing-1.testing-2"); - animations.createConfigSection("testing-1.testing-2.testing-3"); - - try { - animations.save(); - } catch (IOException e) { - e.printStackTrace(); - } - } -} From 4ccdb2e70cfb3631c7def82da2ef256ab04a7dab Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 1 Jan 2022 17:03:16 +0000 Subject: [PATCH 077/134] Loggers are the way forward! --- .../configurationmaster/api/ConfigFile.java | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index e9d475f..00ffd15 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -13,6 +13,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.*; +import java.util.logging.Logger; /** * Represents a specialised YAML file in ConfigurationMaster.

@@ -51,6 +52,8 @@ public class ConfigFile extends CMConfigSection { protected HashMap comments; protected HashSet examples; protected List lenientSections; + protected boolean verbose; + protected static Logger logger = new CMLogger(); /** * Used to load a config file without safety precautions taken by the API. @@ -73,6 +76,20 @@ public ConfigFile(@NotNull File file) throws IOException { loadWithExceptions(); } + /** + * Enables the debugging mode to track what is happening within the API. + * + * @return The ConfigFile object with debugging being enabled. + */ + public ConfigFile enableDebugging() { + this.verbose = true; + return this; + } + + public void debug(String message) { + if (verbose) logger.info(message); + } + /** * Used to load a config file with safety precautions taken by the API.
* This safety precaution checks for syntax errors in the YAML file.
@@ -97,7 +114,7 @@ public static ConfigFile loadConfig(File file) throws IOException { } catch (IOException ioException) { ioException.printStackTrace(); } - System.out.println("YAMLException caught - there is a syntax error in the config."); + logger.severe("YAMLException caught - there is a syntax error in the config."); e.printStackTrace(); return new ConfigFile(tempFile); } @@ -228,4 +245,12 @@ public void setTitle(Title title) { public File getFile() { return file; } + + private static class CMLogger extends Logger { + + // if you can't be 'em, join 'em + protected CMLogger() { + super("ConfigurationMaster", null); + } + } } From 3e463a328dde6362dffee5ceb03c20ce07892886 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 26 Mar 2022 18:26:35 +0000 Subject: [PATCH 078/134] Fix bad code, of course --- .../configurationmaster/api/ConfigFile.java | 6 +- .../api/MemorySection.java | 131 +++--------------- .../impl/CMMemorySection.java | 51 ++++--- Bukkit/ConfigurationMaster-Bukkit.iml | 12 ++ 4 files changed, 63 insertions(+), 137 deletions(-) create mode 100644 Bukkit/ConfigurationMaster-Bukkit.iml diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 00ffd15..a7555b3 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -159,8 +159,10 @@ private void loadFromString(String str) { */ public void save() throws IOException { try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) { - writer.write(saveToString()); + String saved = saveToString(); + writer.write(saved); isNew = false; + loadFromString(saved); } } @@ -177,7 +179,7 @@ public void reload() throws IOException { loadWithExceptions(); for (String path : allDefaults.keySet()) { - if (!examples.contains(path) || contains(path, true) || isNew) { + if (!examples.contains(path) || contains(path) || isNew) { addDefault(path, allDefaults.get(path)); } } diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java index adf5647..354d83b 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java @@ -21,7 +21,7 @@ public interface MemorySection { */ @Nullable default String getString(@NotNull String path) { - return getString(path, null, false); + return getString(path, null); } /** @@ -33,15 +33,7 @@ default String getString(@NotNull String path) { * @return The string stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - default String getString(@NotNull String path, @Nullable String defaultValue) { - return getString(path, defaultValue, false); - } - - default String getString(@NotNull String path, boolean useExisting) { - return getString(path, null, useExisting); - } - - String getString(@NotNull String path, @Nullable String defaultValue, boolean useExisting); + String getString(@NotNull String path, @Nullable String defaultValue); /** * Returns an integer at a specified path. @@ -52,7 +44,7 @@ default String getString(@NotNull String path, boolean useExisting) { * @throws NullPointerException if the path is null (not if it wasn't found). */ default int getInteger(@NotNull String path) { - return getInteger(path, 0, false); + return getInteger(path, 0); } /** @@ -64,15 +56,8 @@ default int getInteger(@NotNull String path) { * @return The integer stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - default int getInteger(@NotNull String path, int defaultValue) { - return getInteger(path, defaultValue, false); - } + int getInteger(@NotNull String path, int defaultValue); - default int getInteger(@NotNull String path, boolean useExisting) { - return getInteger(path, 0, useExisting); - } - - int getInteger(@NotNull String path, int defaultValue, boolean useExisting); /** * Returns a double at a specified path. @@ -83,7 +68,7 @@ default int getInteger(@NotNull String path, boolean useExisting) { * @throws NullPointerException if the path is null (not if it wasn't found). */ default double getDouble(@NotNull String path) { - return getDouble(path, 0.0, false); + return getDouble(path, 0.0); } /** @@ -95,15 +80,7 @@ default double getDouble(@NotNull String path) { * @return The double stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - default double getDouble(@NotNull String path, double defaultValue) { - return getDouble(path, defaultValue, false); - } - - default double getDouble(@NotNull String path, boolean useExisting) { - return getDouble(path, 0, useExisting); - } - - double getDouble(@NotNull String path, double defaultValue, boolean useExisting); + double getDouble(@NotNull String path, double defaultValue); /** * Returns an object at a specified path. @@ -114,7 +91,7 @@ default double getDouble(@NotNull String path, boolean useExisting) { * @throws NullPointerException if the path is null (not if it wasn't found). */ default Object get(@NotNull String path) { - return get(path, null, false); + return get(path, null); } /** @@ -126,15 +103,7 @@ default Object get(@NotNull String path) { * @return The object stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - default Object get(@NotNull String path, @Nullable Object defaultValue) { - return get(path, defaultValue, false); - } - - default Object get(@NotNull String path, boolean useExisting) { - return get(path, null, useExisting); - } - - Object get(@NotNull String path, @Nullable Object defaultValue, boolean useExisting); + Object get(@NotNull String path, @Nullable Object defaultValue); /** * Returns a boolean at a specified path. @@ -157,11 +126,7 @@ default boolean getBoolean(@NotNull String path) { * @return The boolean stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - default boolean getBoolean(@NotNull String path, boolean defaultValue) { - return getBoolean(path, defaultValue, false); - } - - boolean getBoolean(@NotNull String path, boolean defaultValue, boolean useExisting); + boolean getBoolean(@NotNull String path, boolean defaultValue); /** * Returns a long at a specified path. @@ -172,7 +137,7 @@ default boolean getBoolean(@NotNull String path, boolean defaultValue) { * @throws NullPointerException if the path is null (not if it wasn't found). */ default long getLong(@NotNull String path) { - return getLong(path, 0, false); + return getLong(path, 0); } /** @@ -184,15 +149,7 @@ default long getLong(@NotNull String path) { * @return The long stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - default long getLong(@NotNull String path, long defaultValue) { - return getLong(path, defaultValue, false); - } - - default long getLong(@NotNull String path, boolean useExisting) { - return getLong(path, 0, useExisting); - } - - long getLong(@NotNull String path, long defaultValue, boolean useExisting); + long getLong(@NotNull String path, long defaultValue); /** * Returns a short at a specified path. @@ -203,7 +160,7 @@ default long getLong(@NotNull String path, boolean useExisting) { * @throws NullPointerException if the path is null (not if it wasn't found). */ default short getShort(@NotNull String path) { - return getShort(path, (short) 0, false); + return getShort(path, (short) 0); } /** @@ -215,15 +172,7 @@ default short getShort(@NotNull String path) { * @return The short stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - default short getShort(@NotNull String path, short defaultValue) { - return getShort(path, defaultValue, false); - } - - default short getShort(@NotNull String path, boolean useExisting) { - return getShort(path, (short) 0, useExisting); - } - - short getShort(@NotNull String path, short defaultValue, boolean useExisting); + short getShort(@NotNull String path, short defaultValue); /** * Returns a byte at a specified path. @@ -234,7 +183,7 @@ default short getShort(@NotNull String path, boolean useExisting) { * @throws NullPointerException if the path is null (not if it wasn't found). */ default byte getByte(@NotNull String path) { - return getByte(path, (byte) 0, false); + return getByte(path, (byte) 0); } /** @@ -246,15 +195,7 @@ default byte getByte(@NotNull String path) { * @return The byte stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - default byte getByte(@NotNull String path, byte defaultValue) { - return getByte(path, defaultValue, false); - } - - default byte getByte(@NotNull String path, boolean useExisting) { - return getByte(path, (byte) 0, useExisting); - } - - byte getByte(@NotNull String path, byte defaultValue, boolean useExisting); + byte getByte(@NotNull String path, byte defaultValue); /** * Returns a float at a specified path. @@ -265,7 +206,7 @@ default byte getByte(@NotNull String path, boolean useExisting) { * @throws NullPointerException if the path is null (not if it wasn't found). */ default float getFloat(@NotNull String path) { - return getFloat(path, 0f, false); + return getFloat(path, 0f); } /** @@ -277,15 +218,7 @@ default float getFloat(@NotNull String path) { * @return The float stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - default float getFloat(@NotNull String path, float defaultValue) { - return getFloat(path, defaultValue, false); - } - - default float getFloat(@NotNull String path, boolean useExisting) { - return getFloat(path, 0.0f, useExisting); - } - - float getFloat(@NotNull String path, float defaultValue, boolean useExisting); + float getFloat(@NotNull String path, float defaultValue); /** * Returns a configuration file at a specified path. @@ -296,7 +229,7 @@ default float getFloat(@NotNull String path, boolean useExisting) { * @throws NullPointerException if the path is null (not if it wasn't found). */ default ConfigSection getConfigSection(@NotNull String path) { - return getConfigSection(path, null, false); + return getConfigSection(path, null); } /** @@ -308,15 +241,7 @@ default ConfigSection getConfigSection(@NotNull String path) { * @return The configuration section stored at the path. If nothing is found, the default value is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - default ConfigSection getConfigSection(@NotNull String path, @Nullable ConfigSection defaultValue) { - return getConfigSection(path, defaultValue, false); - } - - default ConfigSection getConfigSection(@NotNull String path, boolean useExisting) { - return getConfigSection(path, null, useExisting); - } - - ConfigSection getConfigSection(@NotNull String path, @Nullable ConfigSection defaultValue, boolean useExisting); + ConfigSection getConfigSection(@NotNull String path, @Nullable ConfigSection defaultValue); /** * Returns whether or not the memory section contains a specific path. @@ -325,11 +250,7 @@ default ConfigSection getConfigSection(@NotNull String path, boolean useExisting * To indicate for an option to be placed inside different sections, use a . delimiter, e.g. section.option * @return true if the memory section contains the path, false if not. */ - default boolean contains(@NotNull String path) { - return contains(path, false); - } - - boolean contains(@NotNull String path, boolean useExisting); + boolean contains(@NotNull String path); /** * Returns a list at a given path. If the provided path does not point to a list but a different data type, @@ -357,7 +278,7 @@ default List getList(@NotNull String path) { */ @NotNull default List getStringList(@NotNull String path) { - return getList(path, new ArrayList<>(), false); + return getList(path, new ArrayList<>()); } /** @@ -371,15 +292,7 @@ default List getStringList(@NotNull String path) { * @return The list stored at the path. * @throws NullPointerException if the path is null (not if it wasn't found). */ - default List getList(@NotNull String path, @Nullable List defaultValue) { - return getList(path, defaultValue, false); - } - - default List getList(@NotNull String path, boolean useExisting) { - return getList(path, new ArrayList<>(), useExisting); - } - - List getList(@NotNull String path, @Nullable List defaultValue, boolean useExisting); + List getList(@NotNull String path, @Nullable List defaultValue); /** * Sets a value at a specified path. diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index 96016fa..aeb961e 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -38,15 +38,15 @@ private void init() { } @Override - public String getString(@NotNull String path, @Nullable String defaultValue, boolean useExisting) { - Object result = get(path, defaultValue, useExisting); + public String getString(@NotNull String path, @Nullable String defaultValue) { + Object result = get(path, defaultValue); if (result == null) return null; return String.valueOf(result); } @Override - public int getInteger(@NotNull String path, int defaultValue, boolean useExisting) { - String result = getString(path, useExisting); + public int getInteger(@NotNull String path, int defaultValue) { + String result = getString(path); try { return result == null ? defaultValue : Integer.parseInt(result); } catch (NumberFormatException ex) { @@ -55,8 +55,8 @@ public int getInteger(@NotNull String path, int defaultValue, boolean useExistin } @Override - public double getDouble(@NotNull String path, double defaultValue, boolean useExisting) { - String result = getString(path, useExisting); + public double getDouble(@NotNull String path, double defaultValue) { + String result = getString(path); try { return result == null ? defaultValue : Double.parseDouble(result); } catch (NumberFormatException ex) { @@ -65,25 +65,24 @@ public double getDouble(@NotNull String path, double defaultValue, boolean useEx } @Override - public Object get(@NotNull String path, @Nullable Object defaultValue, boolean useExisting) { - CMMemorySection section = getSectionInternal(path, !useExisting); + public Object get(@NotNull String path, @Nullable Object defaultValue) { + CMMemorySection section = getSectionInternal(path, false); if (section == null) return defaultValue; String key = getKey(path); - return useExisting ? section.existingValues.getOrDefault(key, defaultValue) - : section.actualValues.getOrDefault(key, defaultValue); + return section.actualValues.getOrDefault(key, section.existingValues.getOrDefault(key, defaultValue)); } @Override - public boolean getBoolean(@NotNull String path, boolean defaultValue, boolean useExisting) { - String result = getString(path, useExisting); + public boolean getBoolean(@NotNull String path, boolean defaultValue) { + String result = getString(path); if (result == null) return defaultValue; if (!(result.equalsIgnoreCase("false") || result.equalsIgnoreCase("true"))) return defaultValue; return result.equalsIgnoreCase("true"); } @Override - public long getLong(@NotNull String path, long defaultValue, boolean useExisting) { - String result = getString(path, useExisting); + public long getLong(@NotNull String path, long defaultValue) { + String result = getString(path); try { return result == null ? defaultValue : Long.parseLong(result); } catch (NumberFormatException ex) { @@ -92,8 +91,8 @@ public long getLong(@NotNull String path, long defaultValue, boolean useExisting } @Override - public short getShort(@NotNull String path, short defaultValue, boolean useExisting) { - String result = getString(path, useExisting); + public short getShort(@NotNull String path, short defaultValue) { + String result = getString(path); try { return result == null ? defaultValue : Short.parseShort(result); } catch (NumberFormatException ex) { @@ -102,8 +101,8 @@ public short getShort(@NotNull String path, short defaultValue, boolean useExist } @Override - public byte getByte(@NotNull String path, byte defaultValue, boolean useExisting) { - String result = getString(path, useExisting); + public byte getByte(@NotNull String path, byte defaultValue) { + String result = getString(path); try { return result == null ? defaultValue : Byte.parseByte(result); } catch (NumberFormatException ex) { @@ -112,8 +111,8 @@ public byte getByte(@NotNull String path, byte defaultValue, boolean useExisting } @Override - public float getFloat(@NotNull String path, float defaultValue, boolean useExisting) { - String result = getString(path, useExisting); + public float getFloat(@NotNull String path, float defaultValue) { + String result = getString(path); try { return result == null ? defaultValue : Float.parseFloat(result); } catch (NumberFormatException ex) { @@ -122,22 +121,22 @@ public float getFloat(@NotNull String path, float defaultValue, boolean useExist } @Override - public ConfigSection getConfigSection(@NotNull String path, @Nullable ConfigSection defaultValue, boolean useExisting) { - Object value = get(path, defaultValue, useExisting); + public ConfigSection getConfigSection(@NotNull String path, @Nullable ConfigSection defaultValue) { + Object value = get(path, defaultValue); return value instanceof ConfigSection ? (ConfigSection) value : defaultValue; } @Override - public boolean contains(@NotNull String path, boolean useExisting) { + public boolean contains(@NotNull String path) { CMMemorySection section = getSectionInternal(path); if (section == null) return false; String key = getKey(path); - return useExisting ? section.existingValues.containsKey(key) : section.actualValues.containsKey(key); + return section.existingValues.containsKey(key) || section.actualValues.containsKey(key); } @Override - public List getList(@NotNull String path, @Nullable List defaultValue, boolean useExisting) { - Object value = get(path, defaultValue, useExisting); + public List getList(@NotNull String path, @Nullable List defaultValue) { + Object value = get(path, defaultValue); if (value == null) return defaultValue; if (value.getClass().isArray()) { value = Arrays.asList((Object[]) value); diff --git a/Bukkit/ConfigurationMaster-Bukkit.iml b/Bukkit/ConfigurationMaster-Bukkit.iml new file mode 100644 index 0000000..fa63d4b --- /dev/null +++ b/Bukkit/ConfigurationMaster-Bukkit.iml @@ -0,0 +1,12 @@ + + + + + + + SPIGOT + + + + + \ No newline at end of file From 6e871a40d750ab356e94f7bbefb43c22d81fe55f Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 26 Mar 2022 18:27:00 +0000 Subject: [PATCH 079/134] OH YEAH UH BUMP THIS PLS --- API/pom.xml | 2 +- .../thatsmusic99/configurationmaster/impl/CMConfigSection.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index 6cad140..262ee13 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -22,7 +22,7 @@ org.yaml snakeyaml - 1.28 + 1.30 provided diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index c2d1e05..f7837b3 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -77,7 +77,7 @@ public void moveTo(@NotNull String oldPath, @NotNull String newPath, @NotNull Co Objects.requireNonNull(newPath, "The new path cannot be null!"); Objects.requireNonNull(otherFile, "The file being transferred to cannot be null!"); - if (!contains(oldPath, true)) return; + if (!contains(oldPath)) return; CMMemorySection oldCmSection = getSectionInternal(oldPath, false); if (oldCmSection == null) return; CMMemorySection newCmSection = otherFile.getSectionInternal(newPath); From 85de53a2699819e4b04fe8a65b5645e9ffa555cb Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 26 Mar 2022 19:42:34 +0000 Subject: [PATCH 080/134] Fix contains adding sections when it, stupidly, shouldn't --- .../thatsmusic99/configurationmaster/impl/CMMemorySection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index aeb961e..f6e2ade 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -128,7 +128,7 @@ public ConfigSection getConfigSection(@NotNull String path, @Nullable ConfigSect @Override public boolean contains(@NotNull String path) { - CMMemorySection section = getSectionInternal(path); + CMMemorySection section = getSectionInternal(path, false); if (section == null) return false; String key = getKey(path); return section.existingValues.containsKey(key) || section.actualValues.containsKey(key); From 5f8d84989b3085e71a07921c6a2b1f90a72f991a Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 26 Mar 2022 19:59:13 +0000 Subject: [PATCH 081/134] Remove existing values after the config is saved --- .../github/thatsmusic99/configurationmaster/api/ConfigFile.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index a7555b3..8dd6d9e 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -162,7 +162,7 @@ public void save() throws IOException { String saved = saveToString(); writer.write(saved); isNew = false; - loadFromString(saved); + this.existingValues.clear(); } } From fecc591b61ee534a0eec6d2d8835ecf2d99481b6 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Tue, 29 Mar 2022 19:41:21 +0100 Subject: [PATCH 082/134] Get rid of loader options i hope you're happy 1.8 users --- .../thatsmusic99/configurationmaster/api/ConfigFile.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 8dd6d9e..434e41d 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -42,7 +42,6 @@ public class ConfigFile extends CMConfigSection { private final Yaml yaml; private final DumperOptions yamlOptions = new DumperOptions(); - private final LoaderOptions loaderOptions = new LoaderOptions(); private final Representer yamlRepresenter = new Representer(); private final File file; private boolean isNew = false; @@ -63,7 +62,7 @@ public class ConfigFile extends CMConfigSection { * @throws YAMLException if the file being loaded contains syntax errors. */ public ConfigFile(@NotNull File file) throws IOException { - yaml = new Yaml(new SafeConstructor(), yamlRepresenter, yamlOptions, loaderOptions); + yaml = new Yaml(new SafeConstructor(), yamlRepresenter, yamlOptions); yamlOptions.setIndent(2); yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); From 5de89f73f5e246232adf210094cb7ab42d688844 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sun, 19 Feb 2023 12:22:10 +0000 Subject: [PATCH 083/134] Get rid of loader options Added Option annotations --- .../annotations/Option.java | 18 ++++++++++++ .../AnnotatedConfigTest.java | 19 +++++++++++++ .../config/ExampleConfig.java | 28 +++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Option.java create mode 100644 API/src/test/java/io/github/thatsmusic99/configurationmaster/AnnotatedConfigTest.java create mode 100644 API/src/test/java/io/github/thatsmusic99/configurationmaster/config/ExampleConfig.java diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Option.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Option.java new file mode 100644 index 0000000..c903f16 --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Option.java @@ -0,0 +1,18 @@ +package io.github.thatsmusic99.configurationmaster.annotations; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Option { + + String path() default ""; + + String comment() default ""; + + String section() default ""; +} diff --git a/API/src/test/java/io/github/thatsmusic99/configurationmaster/AnnotatedConfigTest.java b/API/src/test/java/io/github/thatsmusic99/configurationmaster/AnnotatedConfigTest.java new file mode 100644 index 0000000..811f0d7 --- /dev/null +++ b/API/src/test/java/io/github/thatsmusic99/configurationmaster/AnnotatedConfigTest.java @@ -0,0 +1,19 @@ +package io.github.thatsmusic99.configurationmaster; + +import io.github.thatsmusic99.configurationmaster.config.ExampleConfig; +import org.junit.Test; + +import java.io.File; + +public class AnnotatedConfigTest { + + @Test + public void testAnnotatedConfig() throws Exception { + ExampleConfig config = new ExampleConfig(new File("test-config.yml")); + config.load(); + assert config.COMBAT_DURATION == 30; + + config.COMBAT_DURATION = 20; + config.save(); + } +} diff --git a/API/src/test/java/io/github/thatsmusic99/configurationmaster/config/ExampleConfig.java b/API/src/test/java/io/github/thatsmusic99/configurationmaster/config/ExampleConfig.java new file mode 100644 index 0000000..5e2215b --- /dev/null +++ b/API/src/test/java/io/github/thatsmusic99/configurationmaster/config/ExampleConfig.java @@ -0,0 +1,28 @@ +package io.github.thatsmusic99.configurationmaster.config; + +import io.github.thatsmusic99.configurationmaster.annotations.Option; +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.jetbrains.annotations.NotNull; +import org.yaml.snakeyaml.error.YAMLException; + +import java.io.File; +import java.io.IOException; + +public class ExampleConfig extends ConfigFile { + + @Option(comment = "How long a player is considered to be in combat for.", section = "Combat") + public int COMBAT_DURATION = 30; + @Option(comment = "How long the grace period lasts.") + public int GRACE_PERIOD = 30; + + /** + * Used to load a config file without safety precautions taken by the API. + * + * @param file The config file to be loaded. + * @throws YAMLException if the file being loaded contains syntax errors. + * @see ConfigFile#loadConfig(File) + */ + public ExampleConfig(@NotNull File file) throws IOException, IllegalAccessException { + super(file); + } +} From 475a1fc74cc514753f451aad7b3bae1b7054df30 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sun, 19 Feb 2023 13:38:44 +0000 Subject: [PATCH 084/134] Use comment and section objects --- .../api/CommentWriter.java | 116 ++++++++++++------ .../api/comments/Comment.java | 14 +++ .../api/comments/Section.java | 8 ++ .../impl/CMConfigSection.java | 59 ++++----- 4 files changed, 124 insertions(+), 73 deletions(-) create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/api/comments/Comment.java create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/api/comments/Section.java diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java index cdc4805..787dbbd 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java @@ -1,5 +1,8 @@ package io.github.thatsmusic99.configurationmaster.api; +import io.github.thatsmusic99.configurationmaster.api.comments.Comment; +import io.github.thatsmusic99.configurationmaster.api.comments.Section; + import java.util.ArrayList; import java.util.List; @@ -19,6 +22,7 @@ protected CommentWriter(ConfigFile config) { */ protected void writeComments(List currentLines) { this.currentLines = currentLines; + // For each comment to be made... for (String path : config.getComments().keySet()) { // Write the comment at the specified path @@ -26,7 +30,9 @@ protected void writeComments(List currentLines) { } // However, if there's any comments left, write them in. - for (String str : config.getPendingComments()) { + for (Comment comment : config.getPendingComments()) { + + String str = comment.getComment(); if (str.isEmpty()) { currentLines.add(""); continue; @@ -38,7 +44,9 @@ protected void writeComments(List currentLines) { currentLines.add(""); continue; } - if (commentPart.startsWith("CONFIG_SECTION: ")) { + + // If we have a comment section here, use that instead + if (comment instanceof Section) { String section = commentPart.split(": ")[1]; StringBuilder length = new StringBuilder(); length.append("###"); @@ -66,56 +74,86 @@ protected void writeComments(List currentLines) { */ private void writeComment(String path, String[] divisions, int iteration, int startingLine) { StringBuilder indent = new StringBuilder(); - for (int j = 0; j < iteration; j++) { - indent.append(" "); - } + for (int j = 0; j < iteration; j++) indent.append(" "); + // Go through each line in the file for (int i = startingLine; i < currentLines.size(); i++) { String line = currentLines.get(i); + // If the line doesn't have an equal or larger indent, then the line could not be found. if (!line.startsWith(indent.toString())) return; + // If it's already a comment, leave it be. if (line.startsWith("#")) continue; - if (line.startsWith(indent + divisions[iteration] + ":") || - line.startsWith(indent + "'" + divisions[iteration] + "':")) { - iteration += 1; - if (iteration == divisions.length) { - int currentLine = i; - if (iteration == 1) { - currentLines.add(currentLine, ""); + + // If it's not an option (e.g. option: or 'option':), continue + if (!(line.startsWith(indent + divisions[iteration] + ":") || + line.startsWith(indent + "'" + divisions[iteration] + "':"))) continue; + + // Increment the iteration + iteration += 1; + + // If the + if (iteration != divisions.length) { + writeComment(path, divisions, iteration, i + 1); + continue; + } + + // Get the current line we're on + int currentLine = i; + + // + List comments = config.getComments().get(path); + if (comments == null || comments.isEmpty()) continue; + + for (Comment comment : comments) { + + // Add an empty line before a single- + if (iteration == 1) { + currentLines.add(currentLine, ""); + currentLine++; + } + + if (comment == null || comment.getComment().isEmpty()) { + currentLines.add(currentLine, ""); + } else { + + String commentStr = comment.getComment(); + String[] commentParts = commentStr.split("\n"); + + if (comment instanceof Section) { + + // Get the maximum length + int max = 0; + for (String commentPart : commentParts) { + max = Math.max(commentPart.length(), max); + } + + // Build the + StringBuilder length = new StringBuilder(); + length.append("###"); + for (int j = 0; j < max; j++) { + length.append("#"); + } + length.append("###"); + currentLines.add(currentLine, length.toString()); currentLine++; - } - String comment = config.getComments().get(path); - if (comment == null) continue; - String[] rawComment = comment.split("\n"); - for (String commentPart : rawComment) { - if (commentPart.isEmpty()) { - currentLines.add(currentLine, ""); - } else { - if (commentPart.startsWith("CONFIG_SECTION: ")) { - String section = commentPart.split(": ")[1]; - StringBuilder length = new StringBuilder(); - length.append("###"); - for (int j = 0; j < section.length(); j++) { - length.append("#"); - } - length.append("###"); - currentLines.add(currentLine, length.toString()); - currentLines.add(currentLine, "# " + section + " #"); - currentLines.add(currentLine, length.toString()); - currentLine += 3; - continue; - } else { - currentLines.add(currentLine, indent + "# " + commentPart); - } + for (String commentPart : commentParts) { + currentLines.add(currentLine, "# " + commentPart + " #"); + currentLine++; } + currentLines.add(currentLine, length.toString()); + currentLine++; + continue; + } + + for (String commentPart : commentParts) { + currentLines.add(currentLine, indent + "# " + commentPart); currentLine++; } - break; - } else { - writeComment(path, divisions, iteration, i + 1); } } + break; } } diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/comments/Comment.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/comments/Comment.java new file mode 100644 index 0000000..f843b28 --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/comments/Comment.java @@ -0,0 +1,14 @@ +package io.github.thatsmusic99.configurationmaster.api.comments; + +public class Comment { + + private final String comment; + + public Comment(String comment) { + this.comment = comment; + } + + public String getComment() { + return comment; + } +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/comments/Section.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/comments/Section.java new file mode 100644 index 0000000..4037dfe --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/comments/Section.java @@ -0,0 +1,8 @@ +package io.github.thatsmusic99.configurationmaster.api.comments; + +public class Section extends Comment { + + public Section(String comment) { + super(comment); + } +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index f7837b3..3e21e0b 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -2,6 +2,8 @@ import io.github.thatsmusic99.configurationmaster.api.ConfigFile; import io.github.thatsmusic99.configurationmaster.api.ConfigSection; +import io.github.thatsmusic99.configurationmaster.api.comments.Comment; +import io.github.thatsmusic99.configurationmaster.api.comments.Section; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -33,37 +35,34 @@ public void addDefault(@NotNull String path, @Nullable Object defaultOption, @Nu if (cmSection == null) cmSection = createSectionInternal(path); String key = getKey(path); // Move comments to parent option - List comments = new ArrayList<>(getParent().getPendingComments()); - String parentSection = path.substring(0, path.indexOf('.') == -1 ? path.length() : path.indexOf('.')); - addComments(parentSection, comments.toArray(new String[]{})); + List comments = new ArrayList<>(getParent().getPendingComments()); + + for (Comment pendingComment : comments) addComment(path, pendingComment.getComment()); comments.clear(); + // Then handle the comments for the actual option - if (getParent().getComments().containsKey(fullPath)) { - comments.add(getParent().getComments().get(fullPath)); - } - // TODO - should probably be done using objects - if (section != null) { - comments.add("CONFIG_SECTION: " + section); - } - if (comment != null) { - comments.add(comment); - } + if (getParent().getComments().containsKey(fullPath)) comments.addAll(getParent().getComments().get(fullPath)); + + // Add the section + if (section != null) comments.add(new Section(section)); + + // Add the comment + if (comment != null) comments.add(new Comment(comment)); + + // Clear any pending comments getParent().getPendingComments().clear(); - if (comments.size() > 0) { - StringBuilder builder = new StringBuilder(); - builder.append(comments.get(0)); - for (int i = 1; i < comments.size(); i++) { - builder.append("\n\n").append(comments.get(i)); - } - getParent().getComments().put(fullPath, builder.toString()); - } + + // If there's comments to add, + if (comments.size() > 0) getParent().getComments().put(fullPath, comments); + + // Add the defaults cmSection.defaults.put(key, defaultOption); cmSection.actualValues.put(key, cmSection.existingValues.getOrDefault(key, defaultOption)); } @Override public void addComment(@NotNull String comment) { - getParent().getPendingComments().add(comment); + getParent().getPendingComments().add(new Comment(comment)); } @Override @@ -95,10 +94,9 @@ public void addComment(@NotNull String path, @NotNull String comment) { Objects.requireNonNull(comment, "The comment cannot be null!"); // If a specified path already has comments, add this one onto the existing comment, otherwise just add it if (getParent().getComments().containsKey(path)) { - String newComment = getParent().getComments().get(path) + "\n\n" + comment; - getParent().getComments().put(getPathWithKey(path), newComment); + getParent().getComments().get(path).add(new Comment(comment)); } else { - getParent().getComments().put(getPathWithKey(path), comment); + getParent().getComments().put(getPathWithKey(path), new ArrayList<>(Collections.singletonList(new Comment(comment)))); } } @@ -107,13 +105,7 @@ public void addComments(@NotNull String path, @NotNull String... comments) { Objects.requireNonNull(path, "The path cannot be null!"); Objects.requireNonNull(comments, "The comments array cannot be null!"); - if (comments.length == 0) return; - StringBuilder builder = new StringBuilder(); - builder.append(comments[0]); - for (int i = 1; i < comments.length; i++) { - builder.append("\n\n").append(comments[i]); - } - addComment(path, builder.toString()); + for (String comment : comments) addComment(path, comment); } @Override @@ -192,8 +184,7 @@ private void forceExistingIntoActual() { @Override public void addSection(@NotNull String section) { - // TODO - use objects - getParent().getPendingComments().add("CONFIG_SECTION: " + section); + getParent().getPendingComments().add(new Section(section)); } protected CMConfigSection createSectionInternal(@NotNull String path) { From fd3cbdfd0b9dc18917c776e100952075fd1857a9 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sun, 19 Feb 2023 13:39:13 +0000 Subject: [PATCH 085/134] Implement Map --- .../api/MemorySection.java | 6 ++-- .../impl/CMConfigSection.java | 34 +++++++++++-------- .../impl/CMMemorySection.java | 15 ++++---- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java index 354d83b..1e05a97 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java @@ -5,11 +5,12 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * A MemorySection represents a section in the configuration that holds data. */ -public interface MemorySection { +public interface MemorySection extends Map { /** * Returns a string at a specified path. @@ -19,8 +20,7 @@ public interface MemorySection { * @return The string stored at the path. If nothing is found, a value of null is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - @Nullable - default String getString(@NotNull String path) { + default @Nullable String getString(@NotNull String path) { return getString(path, null); } diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 3e21e0b..785743d 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -28,12 +28,18 @@ public void addDefault(@NotNull String path, @Nullable Object defaultOption, @Nu } public void addDefault(@NotNull String path, @Nullable Object defaultOption, @Nullable String section, @Nullable String comment) { + + // Null checks Objects.requireNonNull(path, "The path cannot be null!"); - // + + // Get the full path of the key in question String fullPath = getPathWithKey(path); + + // Get the section to be created - if it's null, create it CMMemorySection cmSection = getSectionInternal(path); if (cmSection == null) cmSection = createSectionInternal(path); String key = getKey(path); + // Move comments to parent option List comments = new ArrayList<>(getParent().getPendingComments()); @@ -57,7 +63,7 @@ public void addDefault(@NotNull String path, @Nullable Object defaultOption, @Nu // Add the defaults cmSection.defaults.put(key, defaultOption); - cmSection.actualValues.put(key, cmSection.existingValues.getOrDefault(key, defaultOption)); + cmSection.put(key, cmSection.existingValues.getOrDefault(key, defaultOption)); } @Override @@ -84,7 +90,7 @@ public void moveTo(@NotNull String oldPath, @NotNull String newPath, @NotNull Co String oldKey = oldPath.substring(oldPath.lastIndexOf('.') + 1); Object movingValue = oldCmSection.existingValues.get(oldKey); String newKey = newPath.substring(newPath.lastIndexOf('.') + 1); - newCmSection.actualValues.put(newKey, movingValue); + newCmSection.put(newKey, movingValue); oldCmSection.set(oldKey, null); } @@ -172,13 +178,13 @@ public void makeSectionLenient(@NotNull String path) { private void forceExistingIntoActual() { if (!getParent().isNew()) { - actualValues.clear(); + clear(); } for (String key : existingValues.keySet()) { if (existingValues.get(key) instanceof CMConfigSection) { ((CMConfigSection) existingValues.get(key)).forceExistingIntoActual(); } - actualValues.put(key, existingValues.get(key)); + put(key, existingValues.get(key)); } } @@ -197,12 +203,12 @@ public CMConfigSection createConfigSection(@NotNull String path) { String[] sections = path.split("\\."); CMConfigSection toEdit = this; for (String section : sections) { - Object option = toEdit.actualValues.get(section); + Object option = toEdit.get(section); if (option == null) { option = new CMConfigSection( toEdit.getPath().length() == 0 ? section : toEdit.getPath() + "." + section, toEdit.getParent()); - toEdit.actualValues.put(section, option); + toEdit.put(section, option); toEdit = (CMConfigSection) option; } else if (option instanceof CMConfigSection) { toEdit = (CMConfigSection) option; @@ -215,11 +221,11 @@ public CMConfigSection createConfigSection(@NotNull String path) { protected Map convertToMap() { LinkedHashMap map = new LinkedHashMap<>(); - for (String path : actualValues.keySet()) { - if (actualValues.get(path) instanceof CMConfigSection) { - map.put(path, ((CMConfigSection) actualValues.get(path)).convertToMap()); + for (String path : keySet()) { + if (get(path) instanceof CMConfigSection) { + map.put(path, ((CMConfigSection) get(path)).convertToMap()); } else { - map.put(path, actualValues.get(path)); + map.put(path, get(path)); } } return map; @@ -246,9 +252,9 @@ private String getPathWithKey(String key) { } protected void addDefaults(HashMap map) { - for (String key : actualValues.keySet()) { - if (actualValues.get(key) instanceof CMConfigSection) { - ((CMConfigSection) actualValues.get(key)).addDefaults(map); + for (String key : keySet()) { + if (get(key) instanceof CMConfigSection) { + ((CMConfigSection) get(key)).addDefaults(map); } else { map.put(getPathWithKey(key), defaults.get(key)); } diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index f6e2ade..2411382 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -8,7 +8,7 @@ import java.util.*; -public class CMMemorySection implements MemorySection { +public class CMMemorySection extends LinkedHashMap implements MemorySection { protected LinkedHashMap defaults; protected LinkedHashMap existingValues; @@ -34,7 +34,6 @@ public class CMMemorySection implements MemorySection { private void init() { this.defaults = new LinkedHashMap<>(); this.existingValues = new LinkedHashMap<>(); - this.actualValues = new LinkedHashMap<>(); } @Override @@ -69,7 +68,7 @@ public Object get(@NotNull String path, @Nullable Object defaultValue) { CMMemorySection section = getSectionInternal(path, false); if (section == null) return defaultValue; String key = getKey(path); - return section.actualValues.getOrDefault(key, section.existingValues.getOrDefault(key, defaultValue)); + return section.getOrDefault(key, section.existingValues.getOrDefault(key, defaultValue)); } @Override @@ -131,7 +130,7 @@ public boolean contains(@NotNull String path) { CMMemorySection section = getSectionInternal(path, false); if (section == null) return false; String key = getKey(path); - return section.existingValues.containsKey(key) || section.actualValues.containsKey(key); + return section.existingValues.containsKey(key) || section.containsKey(key); } @Override @@ -155,10 +154,10 @@ public void set(@NotNull String path, @Nullable Object object) { } String key = getKey(path); if (object == null) { - section.actualValues.remove(key); + section.remove(key); return; } - section.actualValues.put(key, object); + section.put(key, object); } @Nullable @@ -178,7 +177,7 @@ protected CMMemorySection getSectionInternal(@NotNull String path, boolean add) } else { tempSection = (CMMemorySection) section.getConfigSection(key); } - if (tempSection != null && add) section.actualValues.putIfAbsent(key, tempSection); + if (tempSection != null && add) section.putIfAbsent(key, tempSection); section = tempSection; } return section; @@ -187,7 +186,7 @@ protected CMMemorySection getSectionInternal(@NotNull String path, boolean add) @Override public List getKeys(boolean deep, boolean useExisting) { List keys = new ArrayList<>(); - HashMap map = useExisting ? existingValues : actualValues; + HashMap map = useExisting ? existingValues : this; for (String path : map.keySet()) { if (deep && map.get(path) instanceof CMConfigSection) { keys.addAll(((CMConfigSection) map.get(path)).getKeys(true)); From 44271d84816b63262ced82d4210c5f645655c6d9 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sun, 19 Feb 2023 13:39:28 +0000 Subject: [PATCH 086/134] so many changes in this file omg --- .../configurationmaster/api/ConfigFile.java | 303 ++++++++++++------ 1 file changed, 213 insertions(+), 90 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 434e41d..acadd50 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -1,18 +1,22 @@ package io.github.thatsmusic99.configurationmaster.api; +import io.github.thatsmusic99.configurationmaster.annotations.Option; +import io.github.thatsmusic99.configurationmaster.api.comments.Comment; import io.github.thatsmusic99.configurationmaster.impl.CMConfigSection; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.SafeConstructor; import org.yaml.snakeyaml.error.YAMLException; import org.yaml.snakeyaml.representer.Representer; import java.io.*; +import java.lang.reflect.Field; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.*; +import java.util.function.Function; import java.util.logging.Logger; /** @@ -23,7 +27,7 @@ *
    *
  1. {@link ConfigFile#loadConfig(File)} - this loads a file with safety precautions. * If the file contains a syntax error, the API will print an error, - * rename the file temporarily and load a new empty file. + * rename the file temporarily and load a new empty file.
    * * It is recommended to use this if you want your users to * not lose their progress on a config file if they make a @@ -40,53 +44,52 @@ */ public class ConfigFile extends CMConfigSection { - private final Yaml yaml; - private final DumperOptions yamlOptions = new DumperOptions(); - private final Representer yamlRepresenter = new Representer(); - private final File file; - private boolean isNew = false; - private final CommentWriter writer; - private Title title = null; - protected List pendingComments; - protected HashMap comments; - protected HashSet examples; - protected List lenientSections; + @NotNull private final Yaml yaml; + @NotNull protected final DumperOptions yamlOptions = new DumperOptions(); + @NotNull protected final Representer yamlRepresenter = new Representer(); + @NotNull private final File file; + @NotNull private final CommentWriter writer; + @NotNull protected List pendingComments; + @NotNull protected HashMap> comments; + @NotNull protected HashSet examples; + @NotNull protected List lenientSections; + @NotNull protected Function optionNameTranslator; + @Nullable private Title title; + private boolean isNew; protected boolean verbose; protected static Logger logger = new CMLogger(); /** - * Used to load a config file without safety precautions taken by the API. + * Used to initialise a config file without safety precautions taken by the API. * * @param file The config file to be loaded. * @see ConfigFile#loadConfig(File) * @throws YAMLException if the file being loaded contains syntax errors. */ - public ConfigFile(@NotNull File file) throws IOException { + public ConfigFile(@NotNull File file) throws IOException, IllegalAccessException { + this(file, name -> name.replaceAll("_", "-").toLowerCase()); + } + + public ConfigFile(@NotNull File file, @NotNull Function optionNameTranslator) throws IOException, IllegalAccessException { + + // Load the YAML configuration yaml = new Yaml(new SafeConstructor(), yamlRepresenter, yamlOptions); yamlOptions.setIndent(2); yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + + // Set up the file itself this.file = file; + this.optionNameTranslator = optionNameTranslator; + this.isNew = false; + this.title = null; + + // Set up internal variables writer = new CommentWriter(this); pendingComments = new ArrayList<>(); comments = new HashMap<>(); examples = new HashSet<>(); lenientSections = new ArrayList<>(); - loadWithExceptions(); - } - - /** - * Enables the debugging mode to track what is happening within the API. - * - * @return The ConfigFile object with debugging being enabled. - */ - public ConfigFile enableDebugging() { - this.verbose = true; - return this; - } - - public void debug(String message) { - if (verbose) logger.info(message); } /** @@ -97,58 +100,92 @@ public void debug(String message) { * @param file The file to be loaded. * @return the ConfigFile instance of the file or backup file. */ - public static ConfigFile loadConfig(File file) throws IOException { + public static ConfigFile loadConfig(File file) throws Exception { + ConfigFile configFile = new ConfigFile(file); + configFile.load(); + return configFile; + } + + public void load() throws Exception { + + // If the file doesn't already exist, create it + if (!file.exists()) { + if (!file.createNewFile()) { + throw new IOException("Failed to create " + file.getName() + "!"); + } + + // It's a new file + isNew = true; + } + + // Read the file content + String content = readFileContent(); + + // Load any options from the content + loadFromString(content); + + // Load the default options + addDefaults(); + + // Move everything to the new options + moveToNew(); + + // Then save! + save(); + + // Carry out any extra operations post-save + postSave(); + } + + protected void loadFromString(String content) throws IOException { try { - return new ConfigFile(file); - } catch (YAMLException e) { + + // Load everything + Map map = this.yaml.load(content); + if (map != null) { + mapToCM(map); + } + + } catch (YAMLException exception) { + File tempFile = new File(file.getParentFile(), file.getName().substring(0, file.getName().lastIndexOf(".")) + "-errored-" + System.currentTimeMillis() + ".yml"); - try { - if (!tempFile.exists()) { - tempFile.createNewFile(); - } - Files.copy(file.toPath(), tempFile.toPath()); - } catch (IOException ioException) { - ioException.printStackTrace(); - } + Files.copy(file.toPath(), tempFile.toPath()); + logger.severe("YAMLException caught - there is a syntax error in the config."); - e.printStackTrace(); - return new ConfigFile(tempFile); + exception.printStackTrace(); } } - private void loadWithExceptions() throws IOException { - BufferedReader reader = null; - try { - try { - reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); - } catch (FileNotFoundException ex) { - file.createNewFile(); - reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); - isNew = true; - } + /** + * Used to load options + */ + public void addDefaults() throws Exception { - StringBuilder content = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - content.append(line).append("\n"); - } - if (content.length() == 0) { - isNew = true; - } - loadFromString(content.toString()); - } finally { - if (reader != null) reader.close(); - } + handleAnnotations((field, option) -> { + + // Also get the field value and treat it as the default option + final Object defaultOpt = field.get(this); + + // Get the option metadata + final String name = option.path().isEmpty() ? optionNameTranslator.apply(field.getName()) : option.path(); + final String comment = option.comment().isEmpty() ? null : option.comment(); + final String section = option.section().isEmpty() ? null : option.section(); + + // Add the default + addDefault(name, defaultOpt, section, comment); + + // Set the result + field.set(this, get(name)); + }); } - private void loadFromString(String str) { - Map map = this.yaml.load(str); - if (map != null) { - mapToCM(map); - } + public void moveToNew() { + } + + public void postSave() { } /** @@ -156,8 +193,8 @@ private void loadFromString(String str) { * * @throws IOException if something went wrong writing to the file. */ - public void save() throws IOException { - try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) { + public void save() throws Exception { + try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(file.toPath()), StandardCharsets.UTF_8))) { String saved = saveToString(); writer.write(saved); isNew = false; @@ -165,18 +202,48 @@ public void save() throws IOException { } } + protected String readFileContent() throws IOException { + + StringBuilder content = new StringBuilder(); + + // Load the reader + try (BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(file.toPath()), StandardCharsets.UTF_8))) { + + String line; + while ((line = reader.readLine()) != null) { + content.append(line).append("\n"); + } + if (content.length() == 0) { + isNew = true; + } + } + + return content.toString(); + } + /** * Reloads the configuration and updates all values stored inside it.

    * * @throws IOException if something went wrong saving the file. */ - public void reload() throws IOException { + public void reload() throws Exception { + debug("Reloading the configuration file " + file.getName() + "..."); + + // Reset the defaults HashMap allDefaults = new LinkedHashMap<>(); addDefaults(allDefaults); + + // Reset internal values existingValues.clear(); - actualValues.clear(); - loadWithExceptions(); + clear(); + + // Reset content + String content = readFileContent(); + loadFromString(content); + addDefaults(); + moveToNew(); + // for (String path : allDefaults.keySet()) { if (!examples.contains(path) || contains(path) || isNew) { addDefault(path, allDefaults.get(path)); @@ -188,10 +255,11 @@ public void reload() throws IOException { } save(); + postSave(); } /** - * Returns whether the loaded file is brand new or not. + * Returns whether the loaded file is brand new or not.
    * * This is determined by whether a new file was created or if the file itself is empty. * @@ -201,20 +269,56 @@ public boolean isNew() { return isNew; } - public String saveToString() { - String dump = this.yaml.dump(convertToMap()); - if (dump.equals("{}")) { - dump = ""; + public void updateAnnotations() throws Exception { + + handleAnnotations((field, option) -> { + + // Also get the field value and treat it as the default option + final Object value = field.get(this); + + // Get the option metadata + final String name = option.path().isEmpty() ? optionNameTranslator.apply(field.getName()) : option.path(); + + // Update the values + set(name, value); + }); + } + + private void handleAnnotations(OptionConsumer consumer) throws Exception { + // Before doing anything else, check the fields + Field[] fields = getClass().getFields(); + for (Field field : fields) { + + // Check if a field has the option annotation, add it + if (!field.isAnnotationPresent(Option.class)) continue; + final Option option = field.getAnnotation(Option.class); + + // + consumer.accept(field, option); } + } + + public String saveToString() throws Exception { + + // Update the annotations + updateAnnotations(); + + // Convert the map + String dump = this.yaml.dump(convertToMap()); + if (dump.equals("{}")) dump = ""; + + // Write the comments writer.writeComments(new ArrayList<>(Arrays.asList(dump.split("\n")))); + + // Write to the lines StringBuilder result = new StringBuilder(); - for (String line : writer.getLines()) { - result.append(line).append("\n"); - } + writer.getLines().forEach(line -> result.append(line).append("\n")); + + // Write the title and result return (title != null ? title + "\n" : "") + result; } - public HashMap getComments() { + public @NotNull HashMap> getComments() { return comments; } @@ -223,30 +327,44 @@ public HashMap getComments() { * * @return Comments waiting to be added. */ - public List getPendingComments() { + public @NotNull List getPendingComments() { return pendingComments; } - public HashSet getExamples() { + public @NotNull HashSet getExamples() { return examples; } - public List getLenientSections() { + public @NotNull List getLenientSections() { return lenientSections; } - public Title getTitle() { + public @Nullable Title getTitle() { return title; } - public void setTitle(Title title) { + public void setTitle(@Nullable Title title) { this.title = title; } - public File getFile() { + public @NotNull File getFile() { return file; } + /** + * Enables the debugging mode to track what is happening within the API. + * + * @return The ConfigFile object with debugging being enabled. + */ + public ConfigFile enableDebugging() { + this.verbose = true; + return this; + } + + public void debug(String message) { + if (verbose) logger.info(message); + } + private static class CMLogger extends Logger { // if you can't be 'em, join 'em @@ -254,4 +372,9 @@ protected CMLogger() { super("ConfigurationMaster", null); } } + + private interface OptionConsumer { + + void accept(T t, R r) throws Exception; + } } From 42fb32c696376fc2c847bed17e378dea9fb763e9 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sun, 19 Feb 2023 13:39:42 +0000 Subject: [PATCH 087/134] bump version --- API/pom.xml | 4 ++-- Bukkit/pom.xml | 8 ++++---- pom.xml | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index 262ee13..d58173c 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-2 + v2.0.0-BETA-4 4.0.0 ConfigurationMaster-API - v2.0.0-BETA-3 + v2.0.0-BETA-4 8 diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index 113afd4..2beed1b 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-3 + v2.0.0-BETA-4 4.0.0 ConfigurationMaster-Bukkit - v2.0.0-BETA-2 + v2.0.0-BETA-4 8 @@ -22,7 +22,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.3.0-SNAPSHOT + 3.3.0 false false @@ -44,7 +44,7 @@ com.github.thatsmusic99 ConfigurationMaster-API - v2.0.0-BETA-2 + v2.0.0-BETA-4 diff --git a/pom.xml b/pom.xml index 0aff0cf..80ebe88 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.github.thatsmusic99 ConfigurationMaster pom - v2.0.0-BETA-3 + v2.0.0-BETA-4 From 379a172b9a966deaa6fb43793d9d2734d64f6a02 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sun, 19 Feb 2023 13:41:15 +0000 Subject: [PATCH 088/134] modify tests --- .../thatsmusic99/configurationmaster/AdvancedTeleportTest.java | 2 +- .../thatsmusic99/configurationmaster/CommandWhitelistTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java b/API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java index 7769be0..f5eafcb 100644 --- a/API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java +++ b/API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java @@ -13,7 +13,7 @@ public class AdvancedTeleportTest { @Test - public void initATConfig() throws IOException { + public void initATConfig() throws Exception { File file = new File("test-config.yml"); if (!file.exists()) { file.createNewFile(); diff --git a/API/src/test/java/io/github/thatsmusic99/configurationmaster/CommandWhitelistTest.java b/API/src/test/java/io/github/thatsmusic99/configurationmaster/CommandWhitelistTest.java index 11b6025..bc1c012 100644 --- a/API/src/test/java/io/github/thatsmusic99/configurationmaster/CommandWhitelistTest.java +++ b/API/src/test/java/io/github/thatsmusic99/configurationmaster/CommandWhitelistTest.java @@ -14,7 +14,7 @@ public class CommandWhitelistTest { @Test - public void doCommandWhitelistTests() throws IOException { + public void doCommandWhitelistTests() throws Exception { ConfigFile config = ConfigFile.loadConfig(new File("command-whitelist.yml")); config.addDefault("messages.prefix", "CommandWhitelist > "); From 3a9ff7c2f6a59757d07c2d5796a5faf3eb7dc0e3 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Tue, 21 Feb 2023 12:11:38 +0000 Subject: [PATCH 089/134] feat: add option handlers --- .../annotations/Option.java | 6 +++++ .../annotations/OptionHandler.java | 27 +++++++++++++++++++ .../handlers/BooleanOptionHandler.java | 12 +++++++++ .../handlers/DefaultOptionHandler.java | 25 +++++++++++++++++ .../handlers/FloatOptionHandler.java | 12 +++++++++ .../handlers/IntegerOptionHandler.java | 12 +++++++++ .../handlers/LongOptionHandler.java | 12 +++++++++ .../handlers/StringOptionHandler.java | 12 +++++++++ .../configurationmaster/api/ConfigFile.java | 14 ++++++++-- 9 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/OptionHandler.java create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/BooleanOptionHandler.java create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/DefaultOptionHandler.java create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/FloatOptionHandler.java create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/IntegerOptionHandler.java create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/LongOptionHandler.java create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/StringOptionHandler.java diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Option.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Option.java index c903f16..edd4092 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Option.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Option.java @@ -1,6 +1,8 @@ package io.github.thatsmusic99.configurationmaster.annotations; +import io.github.thatsmusic99.configurationmaster.annotations.handlers.DefaultOptionHandler; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -15,4 +17,8 @@ String comment() default ""; String section() default ""; + + boolean lenient() default false; + + Class optionHandler() default DefaultOptionHandler.class; } diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/OptionHandler.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/OptionHandler.java new file mode 100644 index 0000000..cbf2c13 --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/OptionHandler.java @@ -0,0 +1,27 @@ +package io.github.thatsmusic99.configurationmaster.annotations; + +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface OptionHandler { + + Object get( + @NotNull ConfigFile file, + @NotNull String name + ); + + void set( + @NotNull ConfigFile file, + @NotNull String name, + @NotNull Object value + ); + + void addDefault( + @NotNull ConfigFile file, + @NotNull String name, + @NotNull Object value, + @Nullable String section, + @Nullable String comment + ); +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/BooleanOptionHandler.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/BooleanOptionHandler.java new file mode 100644 index 0000000..6d4374b --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/BooleanOptionHandler.java @@ -0,0 +1,12 @@ +package io.github.thatsmusic99.configurationmaster.annotations.handlers; + +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.jetbrains.annotations.NotNull; + +public class BooleanOptionHandler extends DefaultOptionHandler { + + @Override + public Object get(@NotNull ConfigFile file, @NotNull String name) { + return file.getBoolean(name); + } +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/DefaultOptionHandler.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/DefaultOptionHandler.java new file mode 100644 index 0000000..4e5b36c --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/DefaultOptionHandler.java @@ -0,0 +1,25 @@ +package io.github.thatsmusic99.configurationmaster.annotations.handlers; + +import io.github.thatsmusic99.configurationmaster.annotations.OptionHandler; +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class DefaultOptionHandler implements OptionHandler { + + + @Override + public Object get(@NotNull ConfigFile file, @NotNull String name) { + return file.get(name); + } + + @Override + public void set(@NotNull ConfigFile file, @NotNull String name, @NotNull Object value) { + file.set(name, value); + } + + @Override + public void addDefault(@NotNull ConfigFile file, @NotNull String name, @NotNull Object value, @Nullable String section, @Nullable String comment) { + file.addDefault(name, value, section, comment); + } +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/FloatOptionHandler.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/FloatOptionHandler.java new file mode 100644 index 0000000..132d372 --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/FloatOptionHandler.java @@ -0,0 +1,12 @@ +package io.github.thatsmusic99.configurationmaster.annotations.handlers; + +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.jetbrains.annotations.NotNull; + +public class FloatOptionHandler extends DefaultOptionHandler { + + @Override + public Object get(@NotNull ConfigFile file, @NotNull String name) { + return file.getFloat(name); + } +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/IntegerOptionHandler.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/IntegerOptionHandler.java new file mode 100644 index 0000000..d2a6b7a --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/IntegerOptionHandler.java @@ -0,0 +1,12 @@ +package io.github.thatsmusic99.configurationmaster.annotations.handlers; + +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.jetbrains.annotations.NotNull; + +public class IntegerOptionHandler extends DefaultOptionHandler { + + @Override + public Object get(@NotNull ConfigFile file, @NotNull String name) { + return file.getInteger(name); + } +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/LongOptionHandler.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/LongOptionHandler.java new file mode 100644 index 0000000..8e1d165 --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/LongOptionHandler.java @@ -0,0 +1,12 @@ +package io.github.thatsmusic99.configurationmaster.annotations.handlers; + +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.jetbrains.annotations.NotNull; + +public class LongOptionHandler extends DefaultOptionHandler { + + @Override + public Object get(@NotNull ConfigFile file, @NotNull String name) { + return file.getLong(name); + } +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/StringOptionHandler.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/StringOptionHandler.java new file mode 100644 index 0000000..a904736 --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/StringOptionHandler.java @@ -0,0 +1,12 @@ +package io.github.thatsmusic99.configurationmaster.annotations.handlers; + +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.jetbrains.annotations.NotNull; + +public class StringOptionHandler extends DefaultOptionHandler { + + @Override + public Object get(@NotNull ConfigFile file, @NotNull String name) { + return file.getString(name); + } +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index acadd50..afbcdc3 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -1,6 +1,7 @@ package io.github.thatsmusic99.configurationmaster.api; import io.github.thatsmusic99.configurationmaster.annotations.Option; +import io.github.thatsmusic99.configurationmaster.annotations.OptionHandler; import io.github.thatsmusic99.configurationmaster.api.comments.Comment; import io.github.thatsmusic99.configurationmaster.impl.CMConfigSection; import org.jetbrains.annotations.NotNull; @@ -173,12 +174,21 @@ public void addDefaults() throws Exception { final String name = option.path().isEmpty() ? optionNameTranslator.apply(field.getName()) : option.path(); final String comment = option.comment().isEmpty() ? null : option.comment(); final String section = option.section().isEmpty() ? null : option.section(); + final boolean lenient = option.lenient(); + final Class optionHandlerClass = option.optionHandler(); + OptionHandler handler = optionHandlerClass.getConstructor().newInstance(); + + // If it's a lenient field, then make it lenient + if (lenient) { + if (comment != null) addComment(name, comment); + makeSectionLenient(name); + } // Add the default - addDefault(name, defaultOpt, section, comment); + handler.addDefault(this, name, defaultOpt, section, comment); // Set the result - field.set(this, get(name)); + field.set(this, handler.get(this, name)); }); } From 8331868feb894148389ccd3c90f96cd0f90a5eb9 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Thu, 23 Feb 2023 16:41:09 +0000 Subject: [PATCH 090/134] dev: bump version --- API/pom.xml | 4 ++-- Bukkit/pom.xml | 4 ++-- pom.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index d58173c..fbce171 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-4 + v2.0.0-BETA-5 4.0.0 ConfigurationMaster-API - v2.0.0-BETA-4 + v2.0.0-BETA-5 8 diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index 2beed1b..e8158ac 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-4 + v2.0.0-BETA-5 4.0.0 ConfigurationMaster-Bukkit - v2.0.0-BETA-4 + v2.0.0-BETA-5 8 diff --git a/pom.xml b/pom.xml index 80ebe88..fc5df68 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.github.thatsmusic99 ConfigurationMaster pom - v2.0.0-BETA-4 + v2.0.0-BETA-5 From 2cf34aab0620e0a10f244ec5e677420e2587cc1a Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Thu, 23 Feb 2023 16:41:23 +0000 Subject: [PATCH 091/134] fix: comments being re-added --- .../configurationmaster/api/ConfigFile.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index afbcdc3..04b4073 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -245,14 +245,9 @@ public void reload() throws Exception { // Reset internal values existingValues.clear(); + comments.clear(); clear(); - // Reset content - String content = readFileContent(); - loadFromString(content); - addDefaults(); - moveToNew(); - // for (String path : allDefaults.keySet()) { if (!examples.contains(path) || contains(path) || isNew) { @@ -264,8 +259,8 @@ public void reload() throws Exception { makeSectionLenient(section); } - save(); - postSave(); + // Try loading + load(); } /** From d47bba0eb75165a8d752c1959d7a4409dbc222e5 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Wed, 7 Jun 2023 17:58:29 +0100 Subject: [PATCH 092/134] fix: SnakeYAML being outdated --- API/pom.xml | 2 +- .../thatsmusic99/configurationmaster/api/ConfigFile.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index fbce171..4e8f9c7 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -22,7 +22,7 @@ org.yaml snakeyaml - 1.30 + 2.0 provided diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 04b4073..cbfecfa 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -7,6 +7,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.SafeConstructor; import org.yaml.snakeyaml.error.YAMLException; @@ -47,7 +48,7 @@ public class ConfigFile extends CMConfigSection { @NotNull private final Yaml yaml; @NotNull protected final DumperOptions yamlOptions = new DumperOptions(); - @NotNull protected final Representer yamlRepresenter = new Representer(); + @NotNull protected final Representer yamlRepresenter = new Representer(yamlOptions); @NotNull private final File file; @NotNull private final CommentWriter writer; @NotNull protected List pendingComments; @@ -74,7 +75,7 @@ public ConfigFile(@NotNull File file) throws IOException, IllegalAccessException public ConfigFile(@NotNull File file, @NotNull Function optionNameTranslator) throws IOException, IllegalAccessException { // Load the YAML configuration - yaml = new Yaml(new SafeConstructor(), yamlRepresenter, yamlOptions); + yaml = new Yaml(new SafeConstructor(new LoaderOptions()), yamlRepresenter, yamlOptions); yamlOptions.setIndent(2); yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); From 0a74f805deca6b916d40f3e18b6647dd37b1f116 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Wed, 7 Jun 2023 17:58:57 +0100 Subject: [PATCH 093/134] chore(version): bump --- API/pom.xml | 4 ++-- Bukkit/pom.xml | 6 +++--- pom.xml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index 4e8f9c7..8065bda 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-5 + v2.0.0-BETA-6 4.0.0 ConfigurationMaster-API - v2.0.0-BETA-5 + v2.0.0-BETA-6 8 diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index e8158ac..afae3db 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-5 + v2.0.0-BETA-6 4.0.0 ConfigurationMaster-Bukkit - v2.0.0-BETA-5 + v2.0.0-BETA-6 8 @@ -44,7 +44,7 @@ com.github.thatsmusic99 ConfigurationMaster-API - v2.0.0-BETA-4 + v2.0.0-BETA-6 diff --git a/pom.xml b/pom.xml index fc5df68..4639ba1 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.github.thatsmusic99 ConfigurationMaster pom - v2.0.0-BETA-5 + v2.0.0-BETA-6 From 10950b5c59d7545ca08cee70731689164d8d7091 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Sat, 26 Mar 2022 19:59:13 +0000 Subject: [PATCH 094/134] Remove existing values after the config is saved --- API/pom.xml | 4 ++-- .../thatsmusic99/configurationmaster/api/ConfigFile.java | 6 +++--- Bukkit/pom.xml | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index 262ee13..5e2fb74 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -5,7 +5,7 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-2 + v2.0.0-BETA-3 4.0.0 @@ -22,7 +22,7 @@ org.yaml snakeyaml - 1.30 + 2.0 provided diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index a7555b3..ae07274 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -43,7 +43,7 @@ public class ConfigFile extends CMConfigSection { private final Yaml yaml; private final DumperOptions yamlOptions = new DumperOptions(); private final LoaderOptions loaderOptions = new LoaderOptions(); - private final Representer yamlRepresenter = new Representer(); + private final Representer yamlRepresenter = new Representer(new DumperOptions()); private final File file; private boolean isNew = false; private final CommentWriter writer; @@ -63,7 +63,7 @@ public class ConfigFile extends CMConfigSection { * @throws YAMLException if the file being loaded contains syntax errors. */ public ConfigFile(@NotNull File file) throws IOException { - yaml = new Yaml(new SafeConstructor(), yamlRepresenter, yamlOptions, loaderOptions); + yaml = new Yaml(new SafeConstructor(new LoaderOptions()), yamlRepresenter, yamlOptions, loaderOptions); yamlOptions.setIndent(2); yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); @@ -162,7 +162,7 @@ public void save() throws IOException { String saved = saveToString(); writer.write(saved); isNew = false; - loadFromString(saved); + this.existingValues.clear(); } } diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index 113afd4..c1ae5dc 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -10,7 +10,7 @@ 4.0.0 ConfigurationMaster-Bukkit - v2.0.0-BETA-2 + v2.0.0-BETA-3 8 @@ -22,7 +22,7 @@ org.apache.maven.plugins maven-shade-plugin - 3.3.0-SNAPSHOT + 3.3.0 false false @@ -44,7 +44,7 @@ com.github.thatsmusic99 ConfigurationMaster-API - v2.0.0-BETA-2 + v2.0.0-BETA-3 From a331e3060589d5222257cf0d6be4ea2b097717c7 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+Thatsmusic99@users.noreply.github.com> Date: Tue, 29 Mar 2022 19:41:21 +0100 Subject: [PATCH 095/134] Get rid of loader options i hope you're happy 1.8 users --- .../github/thatsmusic99/configurationmaster/api/ConfigFile.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index ae07274..c2da13d 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -63,7 +63,7 @@ public class ConfigFile extends CMConfigSection { * @throws YAMLException if the file being loaded contains syntax errors. */ public ConfigFile(@NotNull File file) throws IOException { - yaml = new Yaml(new SafeConstructor(new LoaderOptions()), yamlRepresenter, yamlOptions, loaderOptions); + yaml = new Yaml(new SafeConstructor(new LoaderOptions()), yamlRepresenter, yamlOptions); yamlOptions.setIndent(2); yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); From cee793f5b9a39f6eeb88294b0b7796a9e1ca62e0 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sun, 19 Feb 2023 12:22:10 +0000 Subject: [PATCH 096/134] Get rid of loader options Added Option annotations --- .../annotations/Option.java | 18 ++++++++++++ .../AnnotatedConfigTest.java | 19 +++++++++++++ .../config/ExampleConfig.java | 28 +++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Option.java create mode 100644 API/src/test/java/io/github/thatsmusic99/configurationmaster/AnnotatedConfigTest.java create mode 100644 API/src/test/java/io/github/thatsmusic99/configurationmaster/config/ExampleConfig.java diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Option.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Option.java new file mode 100644 index 0000000..c903f16 --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Option.java @@ -0,0 +1,18 @@ +package io.github.thatsmusic99.configurationmaster.annotations; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Option { + + String path() default ""; + + String comment() default ""; + + String section() default ""; +} diff --git a/API/src/test/java/io/github/thatsmusic99/configurationmaster/AnnotatedConfigTest.java b/API/src/test/java/io/github/thatsmusic99/configurationmaster/AnnotatedConfigTest.java new file mode 100644 index 0000000..811f0d7 --- /dev/null +++ b/API/src/test/java/io/github/thatsmusic99/configurationmaster/AnnotatedConfigTest.java @@ -0,0 +1,19 @@ +package io.github.thatsmusic99.configurationmaster; + +import io.github.thatsmusic99.configurationmaster.config.ExampleConfig; +import org.junit.Test; + +import java.io.File; + +public class AnnotatedConfigTest { + + @Test + public void testAnnotatedConfig() throws Exception { + ExampleConfig config = new ExampleConfig(new File("test-config.yml")); + config.load(); + assert config.COMBAT_DURATION == 30; + + config.COMBAT_DURATION = 20; + config.save(); + } +} diff --git a/API/src/test/java/io/github/thatsmusic99/configurationmaster/config/ExampleConfig.java b/API/src/test/java/io/github/thatsmusic99/configurationmaster/config/ExampleConfig.java new file mode 100644 index 0000000..5e2215b --- /dev/null +++ b/API/src/test/java/io/github/thatsmusic99/configurationmaster/config/ExampleConfig.java @@ -0,0 +1,28 @@ +package io.github.thatsmusic99.configurationmaster.config; + +import io.github.thatsmusic99.configurationmaster.annotations.Option; +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.jetbrains.annotations.NotNull; +import org.yaml.snakeyaml.error.YAMLException; + +import java.io.File; +import java.io.IOException; + +public class ExampleConfig extends ConfigFile { + + @Option(comment = "How long a player is considered to be in combat for.", section = "Combat") + public int COMBAT_DURATION = 30; + @Option(comment = "How long the grace period lasts.") + public int GRACE_PERIOD = 30; + + /** + * Used to load a config file without safety precautions taken by the API. + * + * @param file The config file to be loaded. + * @throws YAMLException if the file being loaded contains syntax errors. + * @see ConfigFile#loadConfig(File) + */ + public ExampleConfig(@NotNull File file) throws IOException, IllegalAccessException { + super(file); + } +} From 25519c1f3dc801f81cda503754c7588601379230 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sun, 19 Feb 2023 13:38:44 +0000 Subject: [PATCH 097/134] Use comment and section objects --- .../api/CommentWriter.java | 116 ++++++++++++------ .../api/comments/Comment.java | 14 +++ .../api/comments/Section.java | 8 ++ .../impl/CMConfigSection.java | 59 ++++----- 4 files changed, 124 insertions(+), 73 deletions(-) create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/api/comments/Comment.java create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/api/comments/Section.java diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java index cdc4805..787dbbd 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/CommentWriter.java @@ -1,5 +1,8 @@ package io.github.thatsmusic99.configurationmaster.api; +import io.github.thatsmusic99.configurationmaster.api.comments.Comment; +import io.github.thatsmusic99.configurationmaster.api.comments.Section; + import java.util.ArrayList; import java.util.List; @@ -19,6 +22,7 @@ protected CommentWriter(ConfigFile config) { */ protected void writeComments(List currentLines) { this.currentLines = currentLines; + // For each comment to be made... for (String path : config.getComments().keySet()) { // Write the comment at the specified path @@ -26,7 +30,9 @@ protected void writeComments(List currentLines) { } // However, if there's any comments left, write them in. - for (String str : config.getPendingComments()) { + for (Comment comment : config.getPendingComments()) { + + String str = comment.getComment(); if (str.isEmpty()) { currentLines.add(""); continue; @@ -38,7 +44,9 @@ protected void writeComments(List currentLines) { currentLines.add(""); continue; } - if (commentPart.startsWith("CONFIG_SECTION: ")) { + + // If we have a comment section here, use that instead + if (comment instanceof Section) { String section = commentPart.split(": ")[1]; StringBuilder length = new StringBuilder(); length.append("###"); @@ -66,56 +74,86 @@ protected void writeComments(List currentLines) { */ private void writeComment(String path, String[] divisions, int iteration, int startingLine) { StringBuilder indent = new StringBuilder(); - for (int j = 0; j < iteration; j++) { - indent.append(" "); - } + for (int j = 0; j < iteration; j++) indent.append(" "); + // Go through each line in the file for (int i = startingLine; i < currentLines.size(); i++) { String line = currentLines.get(i); + // If the line doesn't have an equal or larger indent, then the line could not be found. if (!line.startsWith(indent.toString())) return; + // If it's already a comment, leave it be. if (line.startsWith("#")) continue; - if (line.startsWith(indent + divisions[iteration] + ":") || - line.startsWith(indent + "'" + divisions[iteration] + "':")) { - iteration += 1; - if (iteration == divisions.length) { - int currentLine = i; - if (iteration == 1) { - currentLines.add(currentLine, ""); + + // If it's not an option (e.g. option: or 'option':), continue + if (!(line.startsWith(indent + divisions[iteration] + ":") || + line.startsWith(indent + "'" + divisions[iteration] + "':"))) continue; + + // Increment the iteration + iteration += 1; + + // If the + if (iteration != divisions.length) { + writeComment(path, divisions, iteration, i + 1); + continue; + } + + // Get the current line we're on + int currentLine = i; + + // + List comments = config.getComments().get(path); + if (comments == null || comments.isEmpty()) continue; + + for (Comment comment : comments) { + + // Add an empty line before a single- + if (iteration == 1) { + currentLines.add(currentLine, ""); + currentLine++; + } + + if (comment == null || comment.getComment().isEmpty()) { + currentLines.add(currentLine, ""); + } else { + + String commentStr = comment.getComment(); + String[] commentParts = commentStr.split("\n"); + + if (comment instanceof Section) { + + // Get the maximum length + int max = 0; + for (String commentPart : commentParts) { + max = Math.max(commentPart.length(), max); + } + + // Build the + StringBuilder length = new StringBuilder(); + length.append("###"); + for (int j = 0; j < max; j++) { + length.append("#"); + } + length.append("###"); + currentLines.add(currentLine, length.toString()); currentLine++; - } - String comment = config.getComments().get(path); - if (comment == null) continue; - String[] rawComment = comment.split("\n"); - for (String commentPart : rawComment) { - if (commentPart.isEmpty()) { - currentLines.add(currentLine, ""); - } else { - if (commentPart.startsWith("CONFIG_SECTION: ")) { - String section = commentPart.split(": ")[1]; - StringBuilder length = new StringBuilder(); - length.append("###"); - for (int j = 0; j < section.length(); j++) { - length.append("#"); - } - length.append("###"); - currentLines.add(currentLine, length.toString()); - currentLines.add(currentLine, "# " + section + " #"); - currentLines.add(currentLine, length.toString()); - currentLine += 3; - continue; - } else { - currentLines.add(currentLine, indent + "# " + commentPart); - } + for (String commentPart : commentParts) { + currentLines.add(currentLine, "# " + commentPart + " #"); + currentLine++; } + currentLines.add(currentLine, length.toString()); + currentLine++; + continue; + } + + for (String commentPart : commentParts) { + currentLines.add(currentLine, indent + "# " + commentPart); currentLine++; } - break; - } else { - writeComment(path, divisions, iteration, i + 1); } } + break; } } diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/comments/Comment.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/comments/Comment.java new file mode 100644 index 0000000..f843b28 --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/comments/Comment.java @@ -0,0 +1,14 @@ +package io.github.thatsmusic99.configurationmaster.api.comments; + +public class Comment { + + private final String comment; + + public Comment(String comment) { + this.comment = comment; + } + + public String getComment() { + return comment; + } +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/comments/Section.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/comments/Section.java new file mode 100644 index 0000000..4037dfe --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/comments/Section.java @@ -0,0 +1,8 @@ +package io.github.thatsmusic99.configurationmaster.api.comments; + +public class Section extends Comment { + + public Section(String comment) { + super(comment); + } +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index f7837b3..3e21e0b 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -2,6 +2,8 @@ import io.github.thatsmusic99.configurationmaster.api.ConfigFile; import io.github.thatsmusic99.configurationmaster.api.ConfigSection; +import io.github.thatsmusic99.configurationmaster.api.comments.Comment; +import io.github.thatsmusic99.configurationmaster.api.comments.Section; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -33,37 +35,34 @@ public void addDefault(@NotNull String path, @Nullable Object defaultOption, @Nu if (cmSection == null) cmSection = createSectionInternal(path); String key = getKey(path); // Move comments to parent option - List comments = new ArrayList<>(getParent().getPendingComments()); - String parentSection = path.substring(0, path.indexOf('.') == -1 ? path.length() : path.indexOf('.')); - addComments(parentSection, comments.toArray(new String[]{})); + List comments = new ArrayList<>(getParent().getPendingComments()); + + for (Comment pendingComment : comments) addComment(path, pendingComment.getComment()); comments.clear(); + // Then handle the comments for the actual option - if (getParent().getComments().containsKey(fullPath)) { - comments.add(getParent().getComments().get(fullPath)); - } - // TODO - should probably be done using objects - if (section != null) { - comments.add("CONFIG_SECTION: " + section); - } - if (comment != null) { - comments.add(comment); - } + if (getParent().getComments().containsKey(fullPath)) comments.addAll(getParent().getComments().get(fullPath)); + + // Add the section + if (section != null) comments.add(new Section(section)); + + // Add the comment + if (comment != null) comments.add(new Comment(comment)); + + // Clear any pending comments getParent().getPendingComments().clear(); - if (comments.size() > 0) { - StringBuilder builder = new StringBuilder(); - builder.append(comments.get(0)); - for (int i = 1; i < comments.size(); i++) { - builder.append("\n\n").append(comments.get(i)); - } - getParent().getComments().put(fullPath, builder.toString()); - } + + // If there's comments to add, + if (comments.size() > 0) getParent().getComments().put(fullPath, comments); + + // Add the defaults cmSection.defaults.put(key, defaultOption); cmSection.actualValues.put(key, cmSection.existingValues.getOrDefault(key, defaultOption)); } @Override public void addComment(@NotNull String comment) { - getParent().getPendingComments().add(comment); + getParent().getPendingComments().add(new Comment(comment)); } @Override @@ -95,10 +94,9 @@ public void addComment(@NotNull String path, @NotNull String comment) { Objects.requireNonNull(comment, "The comment cannot be null!"); // If a specified path already has comments, add this one onto the existing comment, otherwise just add it if (getParent().getComments().containsKey(path)) { - String newComment = getParent().getComments().get(path) + "\n\n" + comment; - getParent().getComments().put(getPathWithKey(path), newComment); + getParent().getComments().get(path).add(new Comment(comment)); } else { - getParent().getComments().put(getPathWithKey(path), comment); + getParent().getComments().put(getPathWithKey(path), new ArrayList<>(Collections.singletonList(new Comment(comment)))); } } @@ -107,13 +105,7 @@ public void addComments(@NotNull String path, @NotNull String... comments) { Objects.requireNonNull(path, "The path cannot be null!"); Objects.requireNonNull(comments, "The comments array cannot be null!"); - if (comments.length == 0) return; - StringBuilder builder = new StringBuilder(); - builder.append(comments[0]); - for (int i = 1; i < comments.length; i++) { - builder.append("\n\n").append(comments[i]); - } - addComment(path, builder.toString()); + for (String comment : comments) addComment(path, comment); } @Override @@ -192,8 +184,7 @@ private void forceExistingIntoActual() { @Override public void addSection(@NotNull String section) { - // TODO - use objects - getParent().getPendingComments().add("CONFIG_SECTION: " + section); + getParent().getPendingComments().add(new Section(section)); } protected CMConfigSection createSectionInternal(@NotNull String path) { From 2e0faa662aa13993c87c5d179390c733187a5d1d Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sun, 19 Feb 2023 13:39:13 +0000 Subject: [PATCH 098/134] Implement Map --- .../api/MemorySection.java | 6 ++-- .../impl/CMConfigSection.java | 34 +++++++++++-------- .../impl/CMMemorySection.java | 15 ++++---- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java index 354d83b..1e05a97 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/MemorySection.java @@ -5,11 +5,12 @@ import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * A MemorySection represents a section in the configuration that holds data. */ -public interface MemorySection { +public interface MemorySection extends Map { /** * Returns a string at a specified path. @@ -19,8 +20,7 @@ public interface MemorySection { * @return The string stored at the path. If nothing is found, a value of null is returned. * @throws NullPointerException if the path is null (not if it wasn't found). */ - @Nullable - default String getString(@NotNull String path) { + default @Nullable String getString(@NotNull String path) { return getString(path, null); } diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 3e21e0b..785743d 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -28,12 +28,18 @@ public void addDefault(@NotNull String path, @Nullable Object defaultOption, @Nu } public void addDefault(@NotNull String path, @Nullable Object defaultOption, @Nullable String section, @Nullable String comment) { + + // Null checks Objects.requireNonNull(path, "The path cannot be null!"); - // + + // Get the full path of the key in question String fullPath = getPathWithKey(path); + + // Get the section to be created - if it's null, create it CMMemorySection cmSection = getSectionInternal(path); if (cmSection == null) cmSection = createSectionInternal(path); String key = getKey(path); + // Move comments to parent option List comments = new ArrayList<>(getParent().getPendingComments()); @@ -57,7 +63,7 @@ public void addDefault(@NotNull String path, @Nullable Object defaultOption, @Nu // Add the defaults cmSection.defaults.put(key, defaultOption); - cmSection.actualValues.put(key, cmSection.existingValues.getOrDefault(key, defaultOption)); + cmSection.put(key, cmSection.existingValues.getOrDefault(key, defaultOption)); } @Override @@ -84,7 +90,7 @@ public void moveTo(@NotNull String oldPath, @NotNull String newPath, @NotNull Co String oldKey = oldPath.substring(oldPath.lastIndexOf('.') + 1); Object movingValue = oldCmSection.existingValues.get(oldKey); String newKey = newPath.substring(newPath.lastIndexOf('.') + 1); - newCmSection.actualValues.put(newKey, movingValue); + newCmSection.put(newKey, movingValue); oldCmSection.set(oldKey, null); } @@ -172,13 +178,13 @@ public void makeSectionLenient(@NotNull String path) { private void forceExistingIntoActual() { if (!getParent().isNew()) { - actualValues.clear(); + clear(); } for (String key : existingValues.keySet()) { if (existingValues.get(key) instanceof CMConfigSection) { ((CMConfigSection) existingValues.get(key)).forceExistingIntoActual(); } - actualValues.put(key, existingValues.get(key)); + put(key, existingValues.get(key)); } } @@ -197,12 +203,12 @@ public CMConfigSection createConfigSection(@NotNull String path) { String[] sections = path.split("\\."); CMConfigSection toEdit = this; for (String section : sections) { - Object option = toEdit.actualValues.get(section); + Object option = toEdit.get(section); if (option == null) { option = new CMConfigSection( toEdit.getPath().length() == 0 ? section : toEdit.getPath() + "." + section, toEdit.getParent()); - toEdit.actualValues.put(section, option); + toEdit.put(section, option); toEdit = (CMConfigSection) option; } else if (option instanceof CMConfigSection) { toEdit = (CMConfigSection) option; @@ -215,11 +221,11 @@ public CMConfigSection createConfigSection(@NotNull String path) { protected Map convertToMap() { LinkedHashMap map = new LinkedHashMap<>(); - for (String path : actualValues.keySet()) { - if (actualValues.get(path) instanceof CMConfigSection) { - map.put(path, ((CMConfigSection) actualValues.get(path)).convertToMap()); + for (String path : keySet()) { + if (get(path) instanceof CMConfigSection) { + map.put(path, ((CMConfigSection) get(path)).convertToMap()); } else { - map.put(path, actualValues.get(path)); + map.put(path, get(path)); } } return map; @@ -246,9 +252,9 @@ private String getPathWithKey(String key) { } protected void addDefaults(HashMap map) { - for (String key : actualValues.keySet()) { - if (actualValues.get(key) instanceof CMConfigSection) { - ((CMConfigSection) actualValues.get(key)).addDefaults(map); + for (String key : keySet()) { + if (get(key) instanceof CMConfigSection) { + ((CMConfigSection) get(key)).addDefaults(map); } else { map.put(getPathWithKey(key), defaults.get(key)); } diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java index f6e2ade..2411382 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMMemorySection.java @@ -8,7 +8,7 @@ import java.util.*; -public class CMMemorySection implements MemorySection { +public class CMMemorySection extends LinkedHashMap implements MemorySection { protected LinkedHashMap defaults; protected LinkedHashMap existingValues; @@ -34,7 +34,6 @@ public class CMMemorySection implements MemorySection { private void init() { this.defaults = new LinkedHashMap<>(); this.existingValues = new LinkedHashMap<>(); - this.actualValues = new LinkedHashMap<>(); } @Override @@ -69,7 +68,7 @@ public Object get(@NotNull String path, @Nullable Object defaultValue) { CMMemorySection section = getSectionInternal(path, false); if (section == null) return defaultValue; String key = getKey(path); - return section.actualValues.getOrDefault(key, section.existingValues.getOrDefault(key, defaultValue)); + return section.getOrDefault(key, section.existingValues.getOrDefault(key, defaultValue)); } @Override @@ -131,7 +130,7 @@ public boolean contains(@NotNull String path) { CMMemorySection section = getSectionInternal(path, false); if (section == null) return false; String key = getKey(path); - return section.existingValues.containsKey(key) || section.actualValues.containsKey(key); + return section.existingValues.containsKey(key) || section.containsKey(key); } @Override @@ -155,10 +154,10 @@ public void set(@NotNull String path, @Nullable Object object) { } String key = getKey(path); if (object == null) { - section.actualValues.remove(key); + section.remove(key); return; } - section.actualValues.put(key, object); + section.put(key, object); } @Nullable @@ -178,7 +177,7 @@ protected CMMemorySection getSectionInternal(@NotNull String path, boolean add) } else { tempSection = (CMMemorySection) section.getConfigSection(key); } - if (tempSection != null && add) section.actualValues.putIfAbsent(key, tempSection); + if (tempSection != null && add) section.putIfAbsent(key, tempSection); section = tempSection; } return section; @@ -187,7 +186,7 @@ protected CMMemorySection getSectionInternal(@NotNull String path, boolean add) @Override public List getKeys(boolean deep, boolean useExisting) { List keys = new ArrayList<>(); - HashMap map = useExisting ? existingValues : actualValues; + HashMap map = useExisting ? existingValues : this; for (String path : map.keySet()) { if (deep && map.get(path) instanceof CMConfigSection) { keys.addAll(((CMConfigSection) map.get(path)).getKeys(true)); From ceb9ff1a8652e8786ff6549b18f862b7a74b0730 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sun, 19 Feb 2023 13:39:28 +0000 Subject: [PATCH 099/134] so many changes in this file omg --- .../configurationmaster/api/ConfigFile.java | 303 ++++++++++++------ 1 file changed, 213 insertions(+), 90 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index c2da13d..424a99a 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -1,7 +1,10 @@ package io.github.thatsmusic99.configurationmaster.api; +import io.github.thatsmusic99.configurationmaster.annotations.Option; +import io.github.thatsmusic99.configurationmaster.api.comments.Comment; import io.github.thatsmusic99.configurationmaster.impl.CMConfigSection; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.LoaderOptions; import org.yaml.snakeyaml.Yaml; @@ -10,9 +13,11 @@ import org.yaml.snakeyaml.representer.Representer; import java.io.*; +import java.lang.reflect.Field; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.*; +import java.util.function.Function; import java.util.logging.Logger; /** @@ -23,7 +28,7 @@ *
      *
    1. {@link ConfigFile#loadConfig(File)} - this loads a file with safety precautions. * If the file contains a syntax error, the API will print an error, - * rename the file temporarily and load a new empty file. + * rename the file temporarily and load a new empty file.
      * * It is recommended to use this if you want your users to * not lose their progress on a config file if they make a @@ -40,54 +45,52 @@ */ public class ConfigFile extends CMConfigSection { - private final Yaml yaml; - private final DumperOptions yamlOptions = new DumperOptions(); - private final LoaderOptions loaderOptions = new LoaderOptions(); - private final Representer yamlRepresenter = new Representer(new DumperOptions()); - private final File file; - private boolean isNew = false; - private final CommentWriter writer; - private Title title = null; - protected List pendingComments; - protected HashMap comments; - protected HashSet examples; - protected List lenientSections; + @NotNull private final Yaml yaml; + @NotNull protected final DumperOptions yamlOptions = new DumperOptions(); + @NotNull protected final Representer yamlRepresenter = new Representer(yamlOptions); + @NotNull private final File file; + @NotNull private final CommentWriter writer; + @NotNull protected List pendingComments; + @NotNull protected HashMap> comments; + @NotNull protected HashSet examples; + @NotNull protected List lenientSections; + @NotNull protected Function optionNameTranslator; + @Nullable private Title title; + private boolean isNew; protected boolean verbose; protected static Logger logger = new CMLogger(); /** - * Used to load a config file without safety precautions taken by the API. + * Used to initialise a config file without safety precautions taken by the API. * * @param file The config file to be loaded. * @see ConfigFile#loadConfig(File) * @throws YAMLException if the file being loaded contains syntax errors. */ - public ConfigFile(@NotNull File file) throws IOException { + public ConfigFile(@NotNull File file) throws IOException, IllegalAccessException { + this(file, name -> name.replaceAll("_", "-").toLowerCase()); + } + + public ConfigFile(@NotNull File file, @NotNull Function optionNameTranslator) throws IOException, IllegalAccessException { + + // Load the YAML configuration yaml = new Yaml(new SafeConstructor(new LoaderOptions()), yamlRepresenter, yamlOptions); yamlOptions.setIndent(2); yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + + // Set up the file itself this.file = file; + this.optionNameTranslator = optionNameTranslator; + this.isNew = false; + this.title = null; + + // Set up internal variables writer = new CommentWriter(this); pendingComments = new ArrayList<>(); comments = new HashMap<>(); examples = new HashSet<>(); lenientSections = new ArrayList<>(); - loadWithExceptions(); - } - - /** - * Enables the debugging mode to track what is happening within the API. - * - * @return The ConfigFile object with debugging being enabled. - */ - public ConfigFile enableDebugging() { - this.verbose = true; - return this; - } - - public void debug(String message) { - if (verbose) logger.info(message); } /** @@ -98,58 +101,92 @@ public void debug(String message) { * @param file The file to be loaded. * @return the ConfigFile instance of the file or backup file. */ - public static ConfigFile loadConfig(File file) throws IOException { + public static ConfigFile loadConfig(File file) throws Exception { + ConfigFile configFile = new ConfigFile(file); + configFile.load(); + return configFile; + } + + public void load() throws Exception { + + // If the file doesn't already exist, create it + if (!file.exists()) { + if (!file.createNewFile()) { + throw new IOException("Failed to create " + file.getName() + "!"); + } + + // It's a new file + isNew = true; + } + + // Read the file content + String content = readFileContent(); + + // Load any options from the content + loadFromString(content); + + // Load the default options + addDefaults(); + + // Move everything to the new options + moveToNew(); + + // Then save! + save(); + + // Carry out any extra operations post-save + postSave(); + } + + protected void loadFromString(String content) throws IOException { try { - return new ConfigFile(file); - } catch (YAMLException e) { + + // Load everything + Map map = this.yaml.load(content); + if (map != null) { + mapToCM(map); + } + + } catch (YAMLException exception) { + File tempFile = new File(file.getParentFile(), file.getName().substring(0, file.getName().lastIndexOf(".")) + "-errored-" + System.currentTimeMillis() + ".yml"); - try { - if (!tempFile.exists()) { - tempFile.createNewFile(); - } - Files.copy(file.toPath(), tempFile.toPath()); - } catch (IOException ioException) { - ioException.printStackTrace(); - } + Files.copy(file.toPath(), tempFile.toPath()); + logger.severe("YAMLException caught - there is a syntax error in the config."); - e.printStackTrace(); - return new ConfigFile(tempFile); + exception.printStackTrace(); } } - private void loadWithExceptions() throws IOException { - BufferedReader reader = null; - try { - try { - reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); - } catch (FileNotFoundException ex) { - file.createNewFile(); - reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)); - isNew = true; - } + /** + * Used to load options + */ + public void addDefaults() throws Exception { - StringBuilder content = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - content.append(line).append("\n"); - } - if (content.length() == 0) { - isNew = true; - } - loadFromString(content.toString()); - } finally { - if (reader != null) reader.close(); - } + handleAnnotations((field, option) -> { + + // Also get the field value and treat it as the default option + final Object defaultOpt = field.get(this); + + // Get the option metadata + final String name = option.path().isEmpty() ? optionNameTranslator.apply(field.getName()) : option.path(); + final String comment = option.comment().isEmpty() ? null : option.comment(); + final String section = option.section().isEmpty() ? null : option.section(); + + // Add the default + addDefault(name, defaultOpt, section, comment); + + // Set the result + field.set(this, get(name)); + }); } - private void loadFromString(String str) { - Map map = this.yaml.load(str); - if (map != null) { - mapToCM(map); - } + public void moveToNew() { + } + + public void postSave() { } /** @@ -157,8 +194,8 @@ private void loadFromString(String str) { * * @throws IOException if something went wrong writing to the file. */ - public void save() throws IOException { - try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) { + public void save() throws Exception { + try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(file.toPath()), StandardCharsets.UTF_8))) { String saved = saveToString(); writer.write(saved); isNew = false; @@ -166,18 +203,48 @@ public void save() throws IOException { } } + protected String readFileContent() throws IOException { + + StringBuilder content = new StringBuilder(); + + // Load the reader + try (BufferedReader reader = new BufferedReader(new InputStreamReader(Files.newInputStream(file.toPath()), StandardCharsets.UTF_8))) { + + String line; + while ((line = reader.readLine()) != null) { + content.append(line).append("\n"); + } + if (content.length() == 0) { + isNew = true; + } + } + + return content.toString(); + } + /** * Reloads the configuration and updates all values stored inside it.

      * * @throws IOException if something went wrong saving the file. */ - public void reload() throws IOException { + public void reload() throws Exception { + debug("Reloading the configuration file " + file.getName() + "..."); + + // Reset the defaults HashMap allDefaults = new LinkedHashMap<>(); addDefaults(allDefaults); + + // Reset internal values existingValues.clear(); - actualValues.clear(); - loadWithExceptions(); + clear(); + + // Reset content + String content = readFileContent(); + loadFromString(content); + addDefaults(); + moveToNew(); + // for (String path : allDefaults.keySet()) { if (!examples.contains(path) || contains(path) || isNew) { addDefault(path, allDefaults.get(path)); @@ -189,10 +256,11 @@ public void reload() throws IOException { } save(); + postSave(); } /** - * Returns whether the loaded file is brand new or not. + * Returns whether the loaded file is brand new or not.
      * * This is determined by whether a new file was created or if the file itself is empty. * @@ -202,20 +270,56 @@ public boolean isNew() { return isNew; } - public String saveToString() { - String dump = this.yaml.dump(convertToMap()); - if (dump.equals("{}")) { - dump = ""; + public void updateAnnotations() throws Exception { + + handleAnnotations((field, option) -> { + + // Also get the field value and treat it as the default option + final Object value = field.get(this); + + // Get the option metadata + final String name = option.path().isEmpty() ? optionNameTranslator.apply(field.getName()) : option.path(); + + // Update the values + set(name, value); + }); + } + + private void handleAnnotations(OptionConsumer consumer) throws Exception { + // Before doing anything else, check the fields + Field[] fields = getClass().getFields(); + for (Field field : fields) { + + // Check if a field has the option annotation, add it + if (!field.isAnnotationPresent(Option.class)) continue; + final Option option = field.getAnnotation(Option.class); + + // + consumer.accept(field, option); } + } + + public String saveToString() throws Exception { + + // Update the annotations + updateAnnotations(); + + // Convert the map + String dump = this.yaml.dump(convertToMap()); + if (dump.equals("{}")) dump = ""; + + // Write the comments writer.writeComments(new ArrayList<>(Arrays.asList(dump.split("\n")))); + + // Write to the lines StringBuilder result = new StringBuilder(); - for (String line : writer.getLines()) { - result.append(line).append("\n"); - } + writer.getLines().forEach(line -> result.append(line).append("\n")); + + // Write the title and result return (title != null ? title + "\n" : "") + result; } - public HashMap getComments() { + public @NotNull HashMap> getComments() { return comments; } @@ -224,30 +328,44 @@ public HashMap getComments() { * * @return Comments waiting to be added. */ - public List getPendingComments() { + public @NotNull List getPendingComments() { return pendingComments; } - public HashSet getExamples() { + public @NotNull HashSet getExamples() { return examples; } - public List getLenientSections() { + public @NotNull List getLenientSections() { return lenientSections; } - public Title getTitle() { + public @Nullable Title getTitle() { return title; } - public void setTitle(Title title) { + public void setTitle(@Nullable Title title) { this.title = title; } - public File getFile() { + public @NotNull File getFile() { return file; } + /** + * Enables the debugging mode to track what is happening within the API. + * + * @return The ConfigFile object with debugging being enabled. + */ + public ConfigFile enableDebugging() { + this.verbose = true; + return this; + } + + public void debug(String message) { + if (verbose) logger.info(message); + } + private static class CMLogger extends Logger { // if you can't be 'em, join 'em @@ -255,4 +373,9 @@ protected CMLogger() { super("ConfigurationMaster", null); } } + + private interface OptionConsumer { + + void accept(T t, R r) throws Exception; + } } From dbce0d51af8be0860805ebb26f611ab38c0d261b Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sun, 19 Feb 2023 13:39:42 +0000 Subject: [PATCH 100/134] bump version --- API/pom.xml | 4 ++-- Bukkit/pom.xml | 6 +++--- pom.xml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index 5e2fb74..7c92525 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-3 + v2.0.0-BETA-4 4.0.0 ConfigurationMaster-API - v2.0.0-BETA-3 + v2.0.0-BETA-4 8 diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index c1ae5dc..2beed1b 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-3 + v2.0.0-BETA-4 4.0.0 ConfigurationMaster-Bukkit - v2.0.0-BETA-3 + v2.0.0-BETA-4 8 @@ -44,7 +44,7 @@ com.github.thatsmusic99 ConfigurationMaster-API - v2.0.0-BETA-3 + v2.0.0-BETA-4 diff --git a/pom.xml b/pom.xml index 0aff0cf..80ebe88 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.github.thatsmusic99 ConfigurationMaster pom - v2.0.0-BETA-3 + v2.0.0-BETA-4 From e4ba8b535e7454b5c103e60d735b6833951b68eb Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sun, 19 Feb 2023 13:41:15 +0000 Subject: [PATCH 101/134] modify tests --- .../thatsmusic99/configurationmaster/AdvancedTeleportTest.java | 2 +- .../thatsmusic99/configurationmaster/CommandWhitelistTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java b/API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java index 7769be0..f5eafcb 100644 --- a/API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java +++ b/API/src/test/java/io/github/thatsmusic99/configurationmaster/AdvancedTeleportTest.java @@ -13,7 +13,7 @@ public class AdvancedTeleportTest { @Test - public void initATConfig() throws IOException { + public void initATConfig() throws Exception { File file = new File("test-config.yml"); if (!file.exists()) { file.createNewFile(); diff --git a/API/src/test/java/io/github/thatsmusic99/configurationmaster/CommandWhitelistTest.java b/API/src/test/java/io/github/thatsmusic99/configurationmaster/CommandWhitelistTest.java index 11b6025..bc1c012 100644 --- a/API/src/test/java/io/github/thatsmusic99/configurationmaster/CommandWhitelistTest.java +++ b/API/src/test/java/io/github/thatsmusic99/configurationmaster/CommandWhitelistTest.java @@ -14,7 +14,7 @@ public class CommandWhitelistTest { @Test - public void doCommandWhitelistTests() throws IOException { + public void doCommandWhitelistTests() throws Exception { ConfigFile config = ConfigFile.loadConfig(new File("command-whitelist.yml")); config.addDefault("messages.prefix", "CommandWhitelist > "); From e327adf60d00e9b0450ea7a58ab06c2c11f38dc4 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Tue, 21 Feb 2023 12:11:38 +0000 Subject: [PATCH 102/134] feat: add option handlers --- .../annotations/Option.java | 6 +++++ .../annotations/OptionHandler.java | 27 +++++++++++++++++++ .../handlers/BooleanOptionHandler.java | 12 +++++++++ .../handlers/DefaultOptionHandler.java | 25 +++++++++++++++++ .../handlers/FloatOptionHandler.java | 12 +++++++++ .../handlers/IntegerOptionHandler.java | 12 +++++++++ .../handlers/LongOptionHandler.java | 12 +++++++++ .../handlers/StringOptionHandler.java | 12 +++++++++ .../configurationmaster/api/ConfigFile.java | 14 ++++++++-- 9 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/OptionHandler.java create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/BooleanOptionHandler.java create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/DefaultOptionHandler.java create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/FloatOptionHandler.java create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/IntegerOptionHandler.java create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/LongOptionHandler.java create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/StringOptionHandler.java diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Option.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Option.java index c903f16..edd4092 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Option.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Option.java @@ -1,6 +1,8 @@ package io.github.thatsmusic99.configurationmaster.annotations; +import io.github.thatsmusic99.configurationmaster.annotations.handlers.DefaultOptionHandler; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -15,4 +17,8 @@ String comment() default ""; String section() default ""; + + boolean lenient() default false; + + Class optionHandler() default DefaultOptionHandler.class; } diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/OptionHandler.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/OptionHandler.java new file mode 100644 index 0000000..cbf2c13 --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/OptionHandler.java @@ -0,0 +1,27 @@ +package io.github.thatsmusic99.configurationmaster.annotations; + +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public interface OptionHandler { + + Object get( + @NotNull ConfigFile file, + @NotNull String name + ); + + void set( + @NotNull ConfigFile file, + @NotNull String name, + @NotNull Object value + ); + + void addDefault( + @NotNull ConfigFile file, + @NotNull String name, + @NotNull Object value, + @Nullable String section, + @Nullable String comment + ); +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/BooleanOptionHandler.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/BooleanOptionHandler.java new file mode 100644 index 0000000..6d4374b --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/BooleanOptionHandler.java @@ -0,0 +1,12 @@ +package io.github.thatsmusic99.configurationmaster.annotations.handlers; + +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.jetbrains.annotations.NotNull; + +public class BooleanOptionHandler extends DefaultOptionHandler { + + @Override + public Object get(@NotNull ConfigFile file, @NotNull String name) { + return file.getBoolean(name); + } +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/DefaultOptionHandler.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/DefaultOptionHandler.java new file mode 100644 index 0000000..4e5b36c --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/DefaultOptionHandler.java @@ -0,0 +1,25 @@ +package io.github.thatsmusic99.configurationmaster.annotations.handlers; + +import io.github.thatsmusic99.configurationmaster.annotations.OptionHandler; +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class DefaultOptionHandler implements OptionHandler { + + + @Override + public Object get(@NotNull ConfigFile file, @NotNull String name) { + return file.get(name); + } + + @Override + public void set(@NotNull ConfigFile file, @NotNull String name, @NotNull Object value) { + file.set(name, value); + } + + @Override + public void addDefault(@NotNull ConfigFile file, @NotNull String name, @NotNull Object value, @Nullable String section, @Nullable String comment) { + file.addDefault(name, value, section, comment); + } +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/FloatOptionHandler.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/FloatOptionHandler.java new file mode 100644 index 0000000..132d372 --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/FloatOptionHandler.java @@ -0,0 +1,12 @@ +package io.github.thatsmusic99.configurationmaster.annotations.handlers; + +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.jetbrains.annotations.NotNull; + +public class FloatOptionHandler extends DefaultOptionHandler { + + @Override + public Object get(@NotNull ConfigFile file, @NotNull String name) { + return file.getFloat(name); + } +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/IntegerOptionHandler.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/IntegerOptionHandler.java new file mode 100644 index 0000000..d2a6b7a --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/IntegerOptionHandler.java @@ -0,0 +1,12 @@ +package io.github.thatsmusic99.configurationmaster.annotations.handlers; + +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.jetbrains.annotations.NotNull; + +public class IntegerOptionHandler extends DefaultOptionHandler { + + @Override + public Object get(@NotNull ConfigFile file, @NotNull String name) { + return file.getInteger(name); + } +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/LongOptionHandler.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/LongOptionHandler.java new file mode 100644 index 0000000..8e1d165 --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/LongOptionHandler.java @@ -0,0 +1,12 @@ +package io.github.thatsmusic99.configurationmaster.annotations.handlers; + +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.jetbrains.annotations.NotNull; + +public class LongOptionHandler extends DefaultOptionHandler { + + @Override + public Object get(@NotNull ConfigFile file, @NotNull String name) { + return file.getLong(name); + } +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/StringOptionHandler.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/StringOptionHandler.java new file mode 100644 index 0000000..a904736 --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/handlers/StringOptionHandler.java @@ -0,0 +1,12 @@ +package io.github.thatsmusic99.configurationmaster.annotations.handlers; + +import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import org.jetbrains.annotations.NotNull; + +public class StringOptionHandler extends DefaultOptionHandler { + + @Override + public Object get(@NotNull ConfigFile file, @NotNull String name) { + return file.getString(name); + } +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 424a99a..a294af1 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -1,6 +1,7 @@ package io.github.thatsmusic99.configurationmaster.api; import io.github.thatsmusic99.configurationmaster.annotations.Option; +import io.github.thatsmusic99.configurationmaster.annotations.OptionHandler; import io.github.thatsmusic99.configurationmaster.api.comments.Comment; import io.github.thatsmusic99.configurationmaster.impl.CMConfigSection; import org.jetbrains.annotations.NotNull; @@ -174,12 +175,21 @@ public void addDefaults() throws Exception { final String name = option.path().isEmpty() ? optionNameTranslator.apply(field.getName()) : option.path(); final String comment = option.comment().isEmpty() ? null : option.comment(); final String section = option.section().isEmpty() ? null : option.section(); + final boolean lenient = option.lenient(); + final Class optionHandlerClass = option.optionHandler(); + OptionHandler handler = optionHandlerClass.getConstructor().newInstance(); + + // If it's a lenient field, then make it lenient + if (lenient) { + if (comment != null) addComment(name, comment); + makeSectionLenient(name); + } // Add the default - addDefault(name, defaultOpt, section, comment); + handler.addDefault(this, name, defaultOpt, section, comment); // Set the result - field.set(this, get(name)); + field.set(this, handler.get(this, name)); }); } From 2161b9f334c456796d31255f09d98c733c463038 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Thu, 23 Feb 2023 16:41:09 +0000 Subject: [PATCH 103/134] dev: bump version --- API/pom.xml | 4 ++-- Bukkit/pom.xml | 4 ++-- pom.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index 7c92525..4e8f9c7 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-4 + v2.0.0-BETA-5 4.0.0 ConfigurationMaster-API - v2.0.0-BETA-4 + v2.0.0-BETA-5 8 diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index 2beed1b..e8158ac 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-4 + v2.0.0-BETA-5 4.0.0 ConfigurationMaster-Bukkit - v2.0.0-BETA-4 + v2.0.0-BETA-5 8 diff --git a/pom.xml b/pom.xml index 80ebe88..fc5df68 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.github.thatsmusic99 ConfigurationMaster pom - v2.0.0-BETA-4 + v2.0.0-BETA-5 From 04489fb701df2afa3c9d573fa19dcf947076fe00 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Thu, 23 Feb 2023 16:41:23 +0000 Subject: [PATCH 104/134] fix: comments being re-added --- .../configurationmaster/api/ConfigFile.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index a294af1..cbfecfa 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -246,14 +246,9 @@ public void reload() throws Exception { // Reset internal values existingValues.clear(); + comments.clear(); clear(); - // Reset content - String content = readFileContent(); - loadFromString(content); - addDefaults(); - moveToNew(); - // for (String path : allDefaults.keySet()) { if (!examples.contains(path) || contains(path) || isNew) { @@ -265,8 +260,8 @@ public void reload() throws Exception { makeSectionLenient(section); } - save(); - postSave(); + // Try loading + load(); } /** From 29bf0507dc316bd11d090fe0bfa30c013ee70625 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Wed, 7 Jun 2023 17:58:57 +0100 Subject: [PATCH 105/134] chore(version): bump --- API/pom.xml | 4 ++-- Bukkit/pom.xml | 6 +++--- pom.xml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index 4e8f9c7..8065bda 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-5 + v2.0.0-BETA-6 4.0.0 ConfigurationMaster-API - v2.0.0-BETA-5 + v2.0.0-BETA-6 8 diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index e8158ac..afae3db 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-5 + v2.0.0-BETA-6 4.0.0 ConfigurationMaster-Bukkit - v2.0.0-BETA-5 + v2.0.0-BETA-6 8 @@ -44,7 +44,7 @@ com.github.thatsmusic99 ConfigurationMaster-API - v2.0.0-BETA-4 + v2.0.0-BETA-6 diff --git a/pom.xml b/pom.xml index fc5df68..4639ba1 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.github.thatsmusic99 ConfigurationMaster pom - v2.0.0-BETA-5 + v2.0.0-BETA-6 From c515fcbdcc24d21b97b56a58cae41491f6b6dbb1 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Thu, 8 Jun 2023 15:18:16 +0100 Subject: [PATCH 106/134] feat: add example annotations --- .../configurationmaster/annotations/Example.java | 13 +++++++++++++ .../configurationmaster/annotations/Examples.java | 12 ++++++++++++ .../configurationmaster/api/ConfigFile.java | 6 ++++++ .../configurationmaster/config/ExampleConfig.java | 7 +++++++ 4 files changed, 38 insertions(+) create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Example.java create mode 100644 API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Examples.java diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Example.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Example.java new file mode 100644 index 0000000..485743d --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Example.java @@ -0,0 +1,13 @@ +package io.github.thatsmusic99.configurationmaster.annotations; + +import java.lang.annotation.*; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Repeatable(Examples.class) +public @interface Example { + + String key(); + + String value(); +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Examples.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Examples.java new file mode 100644 index 0000000..c923a8c --- /dev/null +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/annotations/Examples.java @@ -0,0 +1,12 @@ +package io.github.thatsmusic99.configurationmaster.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Examples { + Example[] value(); +} diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index cbfecfa..03f48e0 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -1,5 +1,6 @@ package io.github.thatsmusic99.configurationmaster.api; +import io.github.thatsmusic99.configurationmaster.annotations.Example; import io.github.thatsmusic99.configurationmaster.annotations.Option; import io.github.thatsmusic99.configurationmaster.annotations.OptionHandler; import io.github.thatsmusic99.configurationmaster.api.comments.Comment; @@ -179,6 +180,11 @@ public void addDefaults() throws Exception { final Class optionHandlerClass = option.optionHandler(); OptionHandler handler = optionHandlerClass.getConstructor().newInstance(); + // If there's examples to add, add them + for (Example example : field.getAnnotationsByType(Example.class)) { + addExample(name + "." + example.key(), example.value()); + } + // If it's a lenient field, then make it lenient if (lenient) { if (comment != null) addComment(name, comment); diff --git a/API/src/test/java/io/github/thatsmusic99/configurationmaster/config/ExampleConfig.java b/API/src/test/java/io/github/thatsmusic99/configurationmaster/config/ExampleConfig.java index 5e2215b..0db457a 100644 --- a/API/src/test/java/io/github/thatsmusic99/configurationmaster/config/ExampleConfig.java +++ b/API/src/test/java/io/github/thatsmusic99/configurationmaster/config/ExampleConfig.java @@ -1,7 +1,9 @@ package io.github.thatsmusic99.configurationmaster.config; +import io.github.thatsmusic99.configurationmaster.annotations.Example; import io.github.thatsmusic99.configurationmaster.annotations.Option; import io.github.thatsmusic99.configurationmaster.api.ConfigFile; +import io.github.thatsmusic99.configurationmaster.api.ConfigSection; import org.jetbrains.annotations.NotNull; import org.yaml.snakeyaml.error.YAMLException; @@ -12,6 +14,11 @@ public class ExampleConfig extends ConfigFile { @Option(comment = "How long a player is considered to be in combat for.", section = "Combat") public int COMBAT_DURATION = 30; + + @Option(comment = "Players who should not be in combat and why.", lenient = true) + @Example(key = "Thatsmusic99", value = "Git gud") + @Example(key = "Niestrat99", value = "Too handsome") + public ConfigSection DENIED_PLAYERS; @Option(comment = "How long the grace period lasts.") public int GRACE_PERIOD = 30; From 0f5fb2addb9cccb08f7aa0dce524a9aef332d88d Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Fri, 9 Jun 2023 16:42:20 +0100 Subject: [PATCH 107/134] fix: reloading duplicating comments --- .../configurationmaster/api/ConfigFile.java | 8 +++++ .../impl/CMConfigSection.java | 33 +++++++++++-------- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 03f48e0..5387453 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -60,6 +60,7 @@ public class ConfigFile extends CMConfigSection { @Nullable private Title title; private boolean isNew; protected boolean verbose; + protected boolean reloading; protected static Logger logger = new CMLogger(); /** @@ -85,6 +86,7 @@ public ConfigFile(@NotNull File file, @NotNull Function optionNa this.file = file; this.optionNameTranslator = optionNameTranslator; this.isNew = false; + this.reloading = false; this.title = null; // Set up internal variables @@ -245,6 +247,7 @@ protected String readFileContent() throws IOException { */ public void reload() throws Exception { debug("Reloading the configuration file " + file.getName() + "..."); + reloading = true; // Reset the defaults HashMap allDefaults = new LinkedHashMap<>(); @@ -268,6 +271,7 @@ public void reload() throws Exception { // Try loading load(); + reloading = false; } /** @@ -281,6 +285,10 @@ public boolean isNew() { return isNew; } + public boolean isReloading() { + return reloading; + } + public void updateAnnotations() throws Exception { handleAnnotations((field, option) -> { diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 785743d..414c19c 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -40,26 +40,29 @@ public void addDefault(@NotNull String path, @Nullable Object defaultOption, @Nu if (cmSection == null) cmSection = createSectionInternal(path); String key = getKey(path); - // Move comments to parent option - List comments = new ArrayList<>(getParent().getPendingComments()); + if (!getParent().isReloading()) { - for (Comment pendingComment : comments) addComment(path, pendingComment.getComment()); - comments.clear(); + // Move comments to parent option + List comments = new ArrayList<>(getParent().getPendingComments()); - // Then handle the comments for the actual option - if (getParent().getComments().containsKey(fullPath)) comments.addAll(getParent().getComments().get(fullPath)); + for (Comment pendingComment : comments) addComment(path, pendingComment.getComment()); + comments.clear(); - // Add the section - if (section != null) comments.add(new Section(section)); + // Then handle the comments for the actual option + if (getParent().getComments().containsKey(fullPath)) comments.addAll(getParent().getComments().get(fullPath)); - // Add the comment - if (comment != null) comments.add(new Comment(comment)); + // Add the section + if (section != null) comments.add(new Section(section)); - // Clear any pending comments - getParent().getPendingComments().clear(); + // Add the comment + if (comment != null) comments.add(new Comment(comment)); - // If there's comments to add, - if (comments.size() > 0) getParent().getComments().put(fullPath, comments); + // Clear any pending comments + getParent().getPendingComments().clear(); + + // If there's comments to add, + if (comments.size() > 0) getParent().getComments().put(fullPath, comments); + } // Add the defaults cmSection.defaults.put(key, defaultOption); @@ -98,6 +101,7 @@ public void moveTo(@NotNull String oldPath, @NotNull String newPath, @NotNull Co public void addComment(@NotNull String path, @NotNull String comment) { Objects.requireNonNull(path, "The path cannot be null!"); Objects.requireNonNull(comment, "The comment cannot be null!"); + if (getParent().isReloading()) return; // If a specified path already has comments, add this one onto the existing comment, otherwise just add it if (getParent().getComments().containsKey(path)) { getParent().getComments().get(path).add(new Comment(comment)); @@ -190,6 +194,7 @@ private void forceExistingIntoActual() { @Override public void addSection(@NotNull String section) { + if (getParent().isReloading()) return; getParent().getPendingComments().add(new Section(section)); } From a35c4c3d687c851aa845b2b1c5138fd14d33056c Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Fri, 9 Jun 2023 16:43:17 +0100 Subject: [PATCH 108/134] fix: this too --- .../thatsmusic99/configurationmaster/impl/CMConfigSection.java | 1 + 1 file changed, 1 insertion(+) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 414c19c..6e8b589 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -71,6 +71,7 @@ public void addDefault(@NotNull String path, @Nullable Object defaultOption, @Nu @Override public void addComment(@NotNull String comment) { + if (getParent().isReloading()) return; getParent().getPendingComments().add(new Comment(comment)); } From d297950b668b6c6c4139b7a9174e554843a2a93b Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Fri, 9 Jun 2023 16:46:12 +0100 Subject: [PATCH 109/134] fix: several API issues such as self-deleting sections and examples --- .../configurationmaster/api/ConfigFile.java | 82 ++++++++++++++++--- .../impl/CMConfigSection.java | 77 ++++++++++++----- 2 files changed, 126 insertions(+), 33 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 5387453..493f688 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -3,6 +3,7 @@ import io.github.thatsmusic99.configurationmaster.annotations.Example; import io.github.thatsmusic99.configurationmaster.annotations.Option; import io.github.thatsmusic99.configurationmaster.annotations.OptionHandler; +import io.github.thatsmusic99.configurationmaster.annotations.handlers.*; import io.github.thatsmusic99.configurationmaster.api.comments.Comment; import io.github.thatsmusic99.configurationmaster.impl.CMConfigSection; import org.jetbrains.annotations.NotNull; @@ -16,6 +17,7 @@ import java.io.*; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.*; @@ -47,9 +49,8 @@ */ public class ConfigFile extends CMConfigSection { + @NotNull private static final HashMap, Class> REGISTERED_HANDLERS = new HashMap<>(); @NotNull private final Yaml yaml; - @NotNull protected final DumperOptions yamlOptions = new DumperOptions(); - @NotNull protected final Representer yamlRepresenter = new Representer(yamlOptions); @NotNull private final File file; @NotNull private final CommentWriter writer; @NotNull protected List pendingComments; @@ -63,6 +64,18 @@ public class ConfigFile extends CMConfigSection { protected boolean reloading; protected static Logger logger = new CMLogger(); + static { + REGISTERED_HANDLERS.put(boolean.class, BooleanOptionHandler.class); + REGISTERED_HANDLERS.put(Boolean.class, BooleanOptionHandler.class); + REGISTERED_HANDLERS.put(float.class, FloatOptionHandler.class); + REGISTERED_HANDLERS.put(Float.class, FloatOptionHandler.class); + REGISTERED_HANDLERS.put(int.class, IntegerOptionHandler.class); + REGISTERED_HANDLERS.put(Integer.class, IntegerOptionHandler.class); + REGISTERED_HANDLERS.put(long.class, LongOptionHandler.class); + REGISTERED_HANDLERS.put(Long.class, LongOptionHandler.class); + REGISTERED_HANDLERS.put(String.class, StringOptionHandler.class); + } + /** * Used to initialise a config file without safety precautions taken by the API. * @@ -77,10 +90,7 @@ public ConfigFile(@NotNull File file) throws IOException, IllegalAccessException public ConfigFile(@NotNull File file, @NotNull Function optionNameTranslator) throws IOException, IllegalAccessException { // Load the YAML configuration - yaml = new Yaml(new SafeConstructor(new LoaderOptions()), yamlRepresenter, yamlOptions); - yamlOptions.setIndent(2); - yamlOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - yamlRepresenter.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + yaml = getYaml(); // Set up the file itself this.file = file; @@ -129,6 +139,11 @@ public void load() throws Exception { // Load any options from the content loadFromString(content); + // Dump in lenient sections, if there are any + for (String section : lenientSections) { + makeSectionLenient(section); + } + // Load the default options addDefaults(); @@ -179,7 +194,10 @@ public void addDefaults() throws Exception { final String comment = option.comment().isEmpty() ? null : option.comment(); final String section = option.section().isEmpty() ? null : option.section(); final boolean lenient = option.lenient(); - final Class optionHandlerClass = option.optionHandler(); + Class optionHandlerClass = option.optionHandler(); + if (optionHandlerClass == DefaultOptionHandler.class) { + optionHandlerClass = REGISTERED_HANDLERS.getOrDefault(field.getType(), DefaultOptionHandler.class); + } OptionHandler handler = optionHandlerClass.getConstructor().newInstance(); // If there's examples to add, add them @@ -194,7 +212,7 @@ public void addDefaults() throws Exception { } // Add the default - handler.addDefault(this, name, defaultOpt, section, comment); + if (defaultOpt != null) handler.addDefault(this, name, defaultOpt, section, comment); // Set the result field.set(this, handler.get(this, name)); @@ -255,20 +273,20 @@ public void reload() throws Exception { // Reset internal values existingValues.clear(); - comments.clear(); clear(); // for (String path : allDefaults.keySet()) { + + // Make sure it's not in a lenient section + String parentPath = getParentPath(path); + if (lenientSections.contains(parentPath)) continue; + if (!examples.contains(path) || contains(path) || isNew) { addDefault(path, allDefaults.get(path)); } } - for (String section : lenientSections) { - makeSectionLenient(section); - } - // Try loading load(); reloading = false; @@ -385,6 +403,44 @@ public void debug(String message) { if (verbose) logger.info(message); } + private Yaml getYaml() { + + // Initialise dump options + DumperOptions options = new DumperOptions(); + options.setIndent(2); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + + // Initialise representer + Representer representerClone; + try { + representerClone = new Representer(options); + } catch (NoSuchMethodError ex) { + try { + representerClone = Representer.class.getConstructor().newInstance(); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | + NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + representerClone.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + + // Initialise YAML + Yaml yaml; + try { + yaml = new Yaml(new SafeConstructor(new LoaderOptions()), representerClone, options, new LoaderOptions()); + } catch (Exception | NoSuchMethodError | NoClassDefFoundError ex) { + // YOLO + try { + yaml = new Yaml(SafeConstructor.class.getConstructor().newInstance(), representerClone, options); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | + NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + return yaml; + } + private static class CMLogger extends Logger { // if you can't be 'em, join 'em diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 6e8b589..7f085fc 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -125,22 +125,33 @@ public void addExample(@NotNull String path, Object object) { } @Override - public void addExample(@NotNull String path, Object object, String comment) { + public void addExample(@NotNull String path, Object object, @Nullable String comment) { Objects.requireNonNull(path, "The path cannot be null!"); - if (!getParent().isNew()) { - CMMemorySection section = getSectionInternal(path); - if (section == null) { - getParent().getExamples().add(getPathWithKey(path)); - return; - } - String key = getKey(path); - if (!section.existingValues.containsKey(key)) { - getParent().getExamples().add(getPathWithKey(path)); + // See if the base section exists - if not, force it + CMMemorySection section = getSectionInternal(path); + if (section == null) { + forceExample(path, object, comment); + return; + } + + CMMemorySection parentSection = getSectionInternal(section.path); + if (parentSection != null && !parentSection.existingValues.containsKey(parentSection.getKey(section.path))) { + forceExample(path, object, comment); + return; + } + + // If the section is lenient, then force the value into existing values + /* int finalIndex = path.lastIndexOf('.'); + if (finalIndex != -1) { + String parentPath = path.substring(0, finalIndex); + if (getParent().getLenientSections().contains(parentPath)) { + section.put(getKey(path), object); return; } - } - forceExample(path, object, comment); + } */ + + getParent().getExamples().add(getPathWithKey(path)); } @Override @@ -148,13 +159,9 @@ public void createExampleSection(@NotNull String path) { Objects.requireNonNull(path, "The path cannot be null!"); getParent().getExamples().add(getPathWithKey(path)); - if (!getParent().isNew()) { - CMMemorySection section = (CMMemorySection) getConfigSection(path); - if (section == null) return; - String key = getKey(path); - if (!section.existingValues.containsKey(key)) return; - } - createConfigSection(path); + // See if the base section exists - if not, force it + CMMemorySection section = getSectionInternal(path); + if (section == null) createConfigSection(path); } @Override @@ -179,11 +186,33 @@ public void makeSectionLenient(@NotNull String path) { section.forceExistingIntoActual(); if (getParent().getLenientSections().contains(getPathWithKey(path))) return; getParent().getLenientSections().add(getPathWithKey(path)); + + // Add it as a default option to the parent section + CMConfigSection parent = (CMConfigSection) getSectionInternal(path); + String key = getKey(path); + if (parent != null) parent.defaults.put(key, new CMConfigSection(parent.getPathWithKey(key), getParent())); + + // Check for any pending comments + if (getParent().isReloading()) return; + String fullPath = getPathWithKey(path); + List comments = new ArrayList<>(getParent().getPendingComments()); + + for (Comment pendingComment : comments) addComment(path, pendingComment.getComment()); + comments.clear(); + + // Then handle the comments for the actual option + if (getParent().getComments().containsKey(fullPath)) comments.addAll(getParent().getComments().get(fullPath)); + + // Clear any pending comments + getParent().getPendingComments().clear(); + + // If there's comments to add, + if (comments.size() > 0) getParent().getComments().put(fullPath, comments); } private void forceExistingIntoActual() { if (!getParent().isNew()) { - clear(); + // clear(); } for (String key : existingValues.keySet()) { if (existingValues.get(key) instanceof CMConfigSection) { @@ -252,6 +281,14 @@ protected void mapToCM(Map map) { } } + protected String getParentPath(String path) { + int finalIndex = path.lastIndexOf('.'); + if (finalIndex != -1) { + return path.substring(0, finalIndex); + } + return null; + } + private String getPathWithKey(String key) { if (getPath().isEmpty()) return key; return getPath() + "." + key; From 7267d2faa667ce4b5ca43ceeee225160682a34a8 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Fri, 9 Jun 2023 17:36:02 +0100 Subject: [PATCH 110/134] fix: non-extended file handling overriding config content --- .../configurationmaster/api/ConfigFile.java | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 493f688..ccfb1a5 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -117,7 +117,7 @@ public ConfigFile(@NotNull File file, @NotNull Function optionNa */ public static ConfigFile loadConfig(File file) throws Exception { ConfigFile configFile = new ConfigFile(file); - configFile.load(); + configFile.loadContent(); return configFile; } @@ -134,15 +134,7 @@ public void load() throws Exception { } // Read the file content - String content = readFileContent(); - - // Load any options from the content - loadFromString(content); - - // Dump in lenient sections, if there are any - for (String section : lenientSections) { - makeSectionLenient(section); - } + loadContent(); // Load the default options addDefaults(); @@ -219,6 +211,10 @@ public void addDefaults() throws Exception { }); } + public void loadContent() throws IOException { + loadFromString(readFileContent()); + } + public void moveToNew() { } @@ -275,7 +271,10 @@ public void reload() throws Exception { existingValues.clear(); clear(); - // + // Load file content + loadContent(); + + // Add defaults for (String path : allDefaults.keySet()) { // Make sure it's not in a lenient section @@ -286,9 +285,17 @@ public void reload() throws Exception { addDefault(path, allDefaults.get(path)); } } + addDefaults(); + + // Dump in lenient sections, if there are any + for (String section : lenientSections) { + makeSectionLenient(section); + } + + moveToNew(); + save(); + postSave(); - // Try loading - load(); reloading = false; } From 6bfaab857044e3da7615501cd37e6ab015d01040 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Fri, 9 Jun 2023 17:36:15 +0100 Subject: [PATCH 111/134] chore(version): bump --- API/pom.xml | 4 ++-- Bukkit/pom.xml | 4 ++-- pom.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index 8065bda..15f09ed 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-6 + v2.0.0-BETA-7 4.0.0 ConfigurationMaster-API - v2.0.0-BETA-6 + v2.0.0-BETA-7 8 diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index afae3db..7029289 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-6 + v2.0.0-BETA-7 4.0.0 ConfigurationMaster-Bukkit - v2.0.0-BETA-6 + v2.0.0-BETA-7 8 diff --git a/pom.xml b/pom.xml index 4639ba1..abbf3ed 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.github.thatsmusic99 ConfigurationMaster pom - v2.0.0-BETA-6 + v2.0.0-BETA-7 From c7dd28e068a67cd55359cbd2dde8f601ca15e83a Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sat, 17 Jun 2023 18:55:19 +0100 Subject: [PATCH 112/134] fix: error when deleting files and reloading --- .../configurationmaster/api/ConfigFile.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index ccfb1a5..d399468 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -267,6 +267,16 @@ public void reload() throws Exception { HashMap allDefaults = new LinkedHashMap<>(); addDefaults(allDefaults); + // If the file doesn't already exist, create it + if (!file.exists()) { + if (!file.createNewFile()) { + throw new IOException("Failed to create " + file.getName() + "!"); + } + + // It's a new file + isNew = true; + } + // Reset internal values existingValues.clear(); clear(); From 19ba091f1a35636fe094b53f36712380cf94328c Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sat, 17 Jun 2023 18:55:37 +0100 Subject: [PATCH 113/134] fix: put lenient sections in the right place --- .../configurationmaster/api/ConfigFile.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index d399468..02dbc46 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -289,7 +289,10 @@ public void reload() throws Exception { // Make sure it's not in a lenient section String parentPath = getParentPath(path); - if (lenientSections.contains(parentPath)) continue; + if (lenientSections.contains(parentPath)) { + makeSectionLenient(parentPath); + continue; + } if (!examples.contains(path) || contains(path) || isNew) { addDefault(path, allDefaults.get(path)); @@ -297,11 +300,6 @@ public void reload() throws Exception { } addDefaults(); - // Dump in lenient sections, if there are any - for (String section : lenientSections) { - makeSectionLenient(section); - } - moveToNew(); save(); postSave(); From 47056d8a912ac04699ceacc23510207921972554 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sat, 17 Jun 2023 18:56:07 +0100 Subject: [PATCH 114/134] fix: don't bring back old sections after a reload --- .../thatsmusic99/configurationmaster/impl/CMConfigSection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 7f085fc..7b7dc6d 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -212,7 +212,7 @@ public void makeSectionLenient(@NotNull String path) { private void forceExistingIntoActual() { if (!getParent().isNew()) { - // clear(); + clear(); } for (String key : existingValues.keySet()) { if (existingValues.get(key) instanceof CMConfigSection) { From 054a6fd11499a7ae6dccfa0c71bb5079a49a2cea Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sat, 17 Jun 2023 18:57:09 +0100 Subject: [PATCH 115/134] chore(version): bump --- API/pom.xml | 4 ++-- Bukkit/pom.xml | 4 ++-- pom.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index 15f09ed..7d427b0 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-7 + v2.0.0-BETA-8 4.0.0 ConfigurationMaster-API - v2.0.0-BETA-7 + v2.0.0-BETA-8 8 diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index 7029289..a48a8f6 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-7 + v2.0.0-BETA-8 4.0.0 ConfigurationMaster-Bukkit - v2.0.0-BETA-7 + v2.0.0-BETA-8 8 diff --git a/pom.xml b/pom.xml index abbf3ed..421b046 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.github.thatsmusic99 ConfigurationMaster pom - v2.0.0-BETA-7 + v2.0.0-BETA-8 From 0f1aa4a487dbd4ed7769123e5222d7e171be0694 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sat, 17 Jun 2023 19:02:49 +0100 Subject: [PATCH 116/134] fix: create a new file when using loadConfig --- .../configurationmaster/api/ConfigFile.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 02dbc46..ebf07a7 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -117,6 +117,7 @@ public ConfigFile(@NotNull File file, @NotNull Function optionNa */ public static ConfigFile loadConfig(File file) throws Exception { ConfigFile configFile = new ConfigFile(file); + configFile.createFile(); configFile.loadContent(); return configFile; } @@ -124,14 +125,7 @@ public static ConfigFile loadConfig(File file) throws Exception { public void load() throws Exception { // If the file doesn't already exist, create it - if (!file.exists()) { - if (!file.createNewFile()) { - throw new IOException("Failed to create " + file.getName() + "!"); - } - - // It's a new file - isNew = true; - } + createFile(); // Read the file content loadContent(); @@ -267,15 +261,8 @@ public void reload() throws Exception { HashMap allDefaults = new LinkedHashMap<>(); addDefaults(allDefaults); - // If the file doesn't already exist, create it - if (!file.exists()) { - if (!file.createNewFile()) { - throw new IOException("Failed to create " + file.getName() + "!"); - } - - // It's a new file - isNew = true; - } + // Create the file + createFile(); // Reset internal values existingValues.clear(); @@ -322,6 +309,19 @@ public boolean isReloading() { return reloading; } + protected void createFile() throws IOException { + + // If the file doesn't already exist, create it + if (!file.exists()) { + if (!file.createNewFile()) { + throw new IOException("Failed to create " + file.getName() + "!"); + } + + // It's a new file + isNew = true; + } + } + public void updateAnnotations() throws Exception { handleAnnotations((field, option) -> { From 5b04db0f56fff67a4fc3fc7d9d5be0630d4ae3a5 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Wed, 28 Jun 2023 11:07:29 +0100 Subject: [PATCH 117/134] fix: examples being forced when the parent section does not exist, but the parent of the parent section is lenient --- .../impl/CMConfigSection.java | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index 7b7dc6d..c346fce 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -128,28 +128,22 @@ public void addExample(@NotNull String path, Object object) { public void addExample(@NotNull String path, Object object, @Nullable String comment) { Objects.requireNonNull(path, "The path cannot be null!"); - // See if the base section exists - if not, force it - CMMemorySection section = getSectionInternal(path); - if (section == null) { - forceExample(path, object, comment); - return; - } - - CMMemorySection parentSection = getSectionInternal(section.path); - if (parentSection != null && !parentSection.existingValues.containsKey(parentSection.getKey(section.path))) { - forceExample(path, object, comment); - return; - } + // Check if any of the sections are lenient + String[] sections = path.split("\\."); + List visited = new ArrayList<>(); + for (String section : sections) { + visited.add(section); + String parentPath = String.join(".", visited); - // If the section is lenient, then force the value into existing values - /* int finalIndex = path.lastIndexOf('.'); - if (finalIndex != -1) { - String parentPath = path.substring(0, finalIndex); + // If it's lenient, check if it exists if (getParent().getLenientSections().contains(parentPath)) { - section.put(getKey(path), object); - return; + CMConfigSection parentSection = (CMConfigSection) getSectionInternal(parentPath, false); + if (parentSection == null || parentSection.existingValues.get(section) == null) { + forceExample(path, object, comment); + return; + } } - } */ + } getParent().getExamples().add(getPathWithKey(path)); } @@ -302,5 +296,10 @@ protected void addDefaults(HashMap map) { map.put(getPathWithKey(key), defaults.get(key)); } } + + // If the section is empty but lenient, keep it + if (getParent().getLenientSections().contains(getPath()) && keySet().size() == 0) { + map.put(getPath(), this); + } } } From d9e72148bc1e086924e2e6eb5823512ccd085d34 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Wed, 28 Jun 2023 11:08:56 +0100 Subject: [PATCH 118/134] chore(version): bump to v2.0.0-BETA-9 --- API/pom.xml | 4 ++-- Bukkit/pom.xml | 6 +++--- pom.xml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index 7d427b0..cb6dacb 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-8 + v2.0.0-BETA-9 4.0.0 ConfigurationMaster-API - v2.0.0-BETA-8 + v2.0.0-BETA-9 8 diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index a48a8f6..ca14e31 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-8 + v2.0.0-BETA-9 4.0.0 ConfigurationMaster-Bukkit - v2.0.0-BETA-8 + v2.0.0-BETA-9 8 @@ -44,7 +44,7 @@ com.github.thatsmusic99 ConfigurationMaster-API - v2.0.0-BETA-6 + v2.0.0-BETA-9 diff --git a/pom.xml b/pom.xml index 421b046..5652c0a 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.github.thatsmusic99 ConfigurationMaster pom - v2.0.0-BETA-8 + v2.0.0-BETA-9 From 3c12d1a5c86d44438dffb2967936b943fb02f6e0 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Sun, 2 Jul 2023 22:38:39 +0100 Subject: [PATCH 119/134] fix: sections not being marked as, well, sections --- .../api/ConfigSection.java | 2 ++ .../impl/CMConfigSection.java | 22 ++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java index 1c37a54..6b356c6 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigSection.java @@ -34,6 +34,8 @@ public interface ConfigSection extends MemorySection { void addSection(@NotNull String section); + void addSection(@NotNull String path, @NotNull String section); + void addExample(@NotNull String path, @Nullable Object value); void addExample(@NotNull String path, @Nullable Object value, @Nullable String comment); diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index c346fce..d82544b 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -45,7 +45,13 @@ public void addDefault(@NotNull String path, @Nullable Object defaultOption, @Nu // Move comments to parent option List comments = new ArrayList<>(getParent().getPendingComments()); - for (Comment pendingComment : comments) addComment(path, pendingComment.getComment()); + for (Comment pendingComment : comments) { + if (pendingComment instanceof Section) { + addSection(path, pendingComment.getComment()); + } else { + addComment(path, pendingComment.getComment()); + } + } comments.clear(); // Then handle the comments for the actual option @@ -222,6 +228,20 @@ public void addSection(@NotNull String section) { getParent().getPendingComments().add(new Section(section)); } + @Override + public void addSection(@NotNull String path, @NotNull String section) { + Objects.requireNonNull(path, "The path cannot be null!"); + Objects.requireNonNull(section, "The section cannot be null!"); + + if (getParent().isReloading()) return; + // If a specified path already has comments, add this one onto the existing comment, otherwise just add it + if (getParent().getComments().containsKey(path)) { + getParent().getComments().get(path).add(new Section(section)); + } else { + getParent().getComments().put(getPathWithKey(path), new ArrayList<>(Collections.singletonList(new Section(section)))); + } + } + protected CMConfigSection createSectionInternal(@NotNull String path) { return createConfigSection(path.substring(0, path.lastIndexOf('.'))); } From 75e5f74f43f06a8e2ce242f5f58a88a4b2a5c557 Mon Sep 17 00:00:00 2001 From: Holly P <25277367+Thatsmusic99@users.noreply.github.com> Date: Wed, 2 Aug 2023 19:51:10 +0100 Subject: [PATCH 120/134] Update API pom --- API/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/API/pom.xml b/API/pom.xml index cb6dacb..ea7e5b7 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -10,7 +10,7 @@ 4.0.0 ConfigurationMaster-API - v2.0.0-BETA-9 + v2.0.0-BETA-10 8 From 5b9a37f75fc376b6e419e6de28aed4e29a96b10b Mon Sep 17 00:00:00 2001 From: Holly P <25277367+Thatsmusic99@users.noreply.github.com> Date: Wed, 2 Aug 2023 19:51:32 +0100 Subject: [PATCH 121/134] Update it here too --- API/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/API/pom.xml b/API/pom.xml index ea7e5b7..b3a9568 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -5,7 +5,7 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-9 + v2.0.0-BETA-10 4.0.0 From cec628e72dac80b75da393b12a67d63ee4b0c3cd Mon Sep 17 00:00:00 2001 From: Holly P <25277367+Thatsmusic99@users.noreply.github.com> Date: Wed, 2 Aug 2023 19:51:55 +0100 Subject: [PATCH 122/134] And this too --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5652c0a..872ed2c 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.github.thatsmusic99 ConfigurationMaster pom - v2.0.0-BETA-9 + v2.0.0-BETA-10 From 5e3d9c723da6e8f9cbe6cc80509febd3e817659a Mon Sep 17 00:00:00 2001 From: Holly P <25277367+Thatsmusic99@users.noreply.github.com> Date: Wed, 2 Aug 2023 19:52:23 +0100 Subject: [PATCH 123/134] And this too --- Bukkit/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index ca14e31..28c6344 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-9 + v2.0.0-BETA-10/version> 4.0.0 ConfigurationMaster-Bukkit - v2.0.0-BETA-9 + v2.0.0-BETA-10 8 From 5211f45bbb1334cb21eeff766b12e8e3c4d5014e Mon Sep 17 00:00:00 2001 From: Holly P <25277367+Thatsmusic99@users.noreply.github.com> Date: Wed, 2 Aug 2023 19:58:42 +0100 Subject: [PATCH 124/134] On this fine day I thank SnakeYAML and Spigot for being so wonderful to work with nah actually fuck this --- .../thatsmusic99/configurationmaster/api/ConfigFile.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index ebf07a7..2617b38 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -442,7 +442,9 @@ private Yaml getYaml() { // Initialise YAML Yaml yaml; try { - yaml = new Yaml(new SafeConstructor(new LoaderOptions()), representerClone, options, new LoaderOptions()); + LoaderOptions loader = new LoaderOptions(); + loader.setCodePointLimit(1024 * 1024 * 100); + yaml = new Yaml(new SafeConstructor(loader), representerClone, options, new LoaderOptions()); } catch (Exception | NoSuchMethodError | NoClassDefFoundError ex) { // YOLO try { From cfa23defc11e4234385dec69be6e6e0bc0eedb8e Mon Sep 17 00:00:00 2001 From: Holly P <25277367+Thatsmusic99@users.noreply.github.com> Date: Wed, 2 Aug 2023 20:07:01 +0100 Subject: [PATCH 125/134] =?UTF-8?q?I=E2=80=99m=20editing=20on=20mobile=20h?= =?UTF-8?q?ave=20mercy=20for=20the=20love=20of=20god?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bukkit/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index 28c6344..7d22ecd 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,7 +5,7 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-10/version> + v2.0.0-BETA-10 4.0.0 From c4a1b91f6c8d2ef8d46e8a2339af9d2b81a86408 Mon Sep 17 00:00:00 2001 From: Holly P <25277367+Thatsmusic99@users.noreply.github.com> Date: Thu, 3 Aug 2023 15:50:50 +0100 Subject: [PATCH 126/134] fix: LoaderOptions in the wrong spot --- .../github/thatsmusic99/configurationmaster/api/ConfigFile.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 2617b38..295370b 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -444,7 +444,7 @@ private Yaml getYaml() { try { LoaderOptions loader = new LoaderOptions(); loader.setCodePointLimit(1024 * 1024 * 100); - yaml = new Yaml(new SafeConstructor(loader), representerClone, options, new LoaderOptions()); + yaml = new Yaml(new SafeConstructor(loader), representerClone, options, loader); } catch (Exception | NoSuchMethodError | NoClassDefFoundError ex) { // YOLO try { From 0d6c52fb8c3baa7604e182ebb3bbd350cc605e73 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Fri, 11 Aug 2023 18:10:50 +0100 Subject: [PATCH 127/134] feat: add permitted classes for tag inspection --- .../thatsmusic99/configurationmaster/api/ConfigFile.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index 295370b..d2364b3 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -58,6 +58,7 @@ public class ConfigFile extends CMConfigSection { @NotNull protected HashSet examples; @NotNull protected List lenientSections; @NotNull protected Function optionNameTranslator; + @NotNull protected List permittedClasses; @Nullable private Title title; private boolean isNew; protected boolean verbose; @@ -105,6 +106,7 @@ public ConfigFile(@NotNull File file, @NotNull Function optionNa comments = new HashMap<>(); examples = new HashSet<>(); lenientSections = new ArrayList<>(); + permittedClasses = new ArrayList<>(); } /** @@ -124,6 +126,9 @@ public static ConfigFile loadConfig(File file) throws Exception { public void load() throws Exception { + // Before we do anything + preFileCreation(); + // If the file doesn't already exist, create it createFile(); @@ -143,6 +148,9 @@ public void load() throws Exception { postSave(); } + public void preFileCreation() { + } + protected void loadFromString(String content) throws IOException { try { @@ -444,6 +452,7 @@ private Yaml getYaml() { try { LoaderOptions loader = new LoaderOptions(); loader.setCodePointLimit(1024 * 1024 * 100); + loader.setTagInspector(tag -> this.permittedClasses.contains(tag.getClassName())); yaml = new Yaml(new SafeConstructor(loader), representerClone, options, loader); } catch (Exception | NoSuchMethodError | NoClassDefFoundError ex) { // YOLO From 1c79b689da4983def8c88c99c7849f544abe461e Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Fri, 11 Aug 2023 18:11:50 +0100 Subject: [PATCH 128/134] chore(version): bump to v2.0.0-rc.1 --- API/pom.xml | 4 ++-- Bukkit/pom.xml | 6 +++--- pom.xml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index b3a9568..26cfab7 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-10 + v2.0.0-rc.1 4.0.0 ConfigurationMaster-API - v2.0.0-BETA-10 + v2.0.0-rc.1 8 diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index 7d22ecd..4ff2d50 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-BETA-10 + v2.0.0-rc.1 4.0.0 ConfigurationMaster-Bukkit - v2.0.0-BETA-10 + v2.0.0-rc.1 8 @@ -44,7 +44,7 @@ com.github.thatsmusic99 ConfigurationMaster-API - v2.0.0-BETA-9 + v2.0.0-rc.1 diff --git a/pom.xml b/pom.xml index 872ed2c..854ff29 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.github.thatsmusic99 ConfigurationMaster pom - v2.0.0-BETA-10 + v2.0.0-rc.1 From 816f328b7454b238e90b88bbca07e3f010abf55c Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Wed, 3 Jan 2024 23:17:33 +0000 Subject: [PATCH 129/134] fix: pending comments (and sections) being handled incorrectly --- .../impl/CMConfigSection.java | 47 +++++++++++++------ 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java index d82544b..e4da352 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/impl/CMConfigSection.java @@ -42,17 +42,9 @@ public void addDefault(@NotNull String path, @Nullable Object defaultOption, @Nu if (!getParent().isReloading()) { - // Move comments to parent option - List comments = new ArrayList<>(getParent().getPendingComments()); - - for (Comment pendingComment : comments) { - if (pendingComment instanceof Section) { - addSection(path, pendingComment.getComment()); - } else { - addComment(path, pendingComment.getComment()); - } - } - comments.clear(); + addPendingCommentsToPath(path); + + final List comments = new ArrayList<>(); // Then handle the comments for the actual option if (getParent().getComments().containsKey(fullPath)) comments.addAll(getParent().getComments().get(fullPath)); @@ -106,9 +98,15 @@ public void moveTo(@NotNull String oldPath, @NotNull String newPath, @NotNull Co @Override public void addComment(@NotNull String path, @NotNull String comment) { + addComment(path, comment, true); + } + + private void addComment(final @NotNull String path, final @NotNull String comment, final boolean addPending) { Objects.requireNonNull(path, "The path cannot be null!"); Objects.requireNonNull(comment, "The comment cannot be null!"); if (getParent().isReloading()) return; + if (addPending) addPendingCommentsToPath(path); + // If a specified path already has comments, add this one onto the existing comment, otherwise just add it if (getParent().getComments().containsKey(path)) { getParent().getComments().get(path).add(new Comment(comment)); @@ -195,10 +193,10 @@ public void makeSectionLenient(@NotNull String path) { // Check for any pending comments if (getParent().isReloading()) return; String fullPath = getPathWithKey(path); - List comments = new ArrayList<>(getParent().getPendingComments()); - for (Comment pendingComment : comments) addComment(path, pendingComment.getComment()); - comments.clear(); + addPendingCommentsToPath(path); + + final List comments = new ArrayList<>(); // Then handle the comments for the actual option if (getParent().getComments().containsKey(fullPath)) comments.addAll(getParent().getComments().get(fullPath)); @@ -230,10 +228,15 @@ public void addSection(@NotNull String section) { @Override public void addSection(@NotNull String path, @NotNull String section) { + addSection(path, section, true); + } + + private void addSection(final @NotNull String path, final @NotNull String section, final boolean addPending) { Objects.requireNonNull(path, "The path cannot be null!"); Objects.requireNonNull(section, "The section cannot be null!"); if (getParent().isReloading()) return; + if (addPending) addPendingCommentsToPath(path); // If a specified path already has comments, add this one onto the existing comment, otherwise just add it if (getParent().getComments().containsKey(path)) { getParent().getComments().get(path).add(new Section(section)); @@ -322,4 +325,20 @@ protected void addDefaults(HashMap map) { map.put(getPath(), this); } } + + private void addPendingCommentsToPath(final @NotNull String path) { + + // Get the root path for pending commands + final int index = path.indexOf('.'); + final String root = path.substring(0, index == -1 ? path.length() : index); + + for (Comment pendingComment : getParent().getPendingComments()) { + if (pendingComment instanceof Section) { + addSection(root, pendingComment.getComment(), false); + } else { + addComment(root, pendingComment.getComment(), false); + } + } + getParent().getPendingComments().clear(); + } } From bb69324cc5f7ab2464318993714b8b1a4c313546 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Wed, 3 Jan 2024 23:19:42 +0000 Subject: [PATCH 130/134] chore(version): bump to v2.0.0-rc.2 --- API/pom.xml | 4 ++-- Bukkit/pom.xml | 6 +++--- pom.xml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index 26cfab7..72e6d9f 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-rc.1 + v2.0.0-rc.2 4.0.0 ConfigurationMaster-API - v2.0.0-rc.1 + v2.0.0-rc.2 8 diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index 4ff2d50..12844f9 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-rc.1 + v2.0.0-rc.2 4.0.0 ConfigurationMaster-Bukkit - v2.0.0-rc.1 + v2.0.0-rc.2 8 @@ -44,7 +44,7 @@ com.github.thatsmusic99 ConfigurationMaster-API - v2.0.0-rc.1 + v2.0.0-rc.2 diff --git a/pom.xml b/pom.xml index 854ff29..412f590 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.github.thatsmusic99 ConfigurationMaster pom - v2.0.0-rc.1 + v2.0.0-rc.2 From 51bcbe2b986864758cb034e594d57645ee20b9e5 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Wed, 3 Jan 2024 23:20:41 +0000 Subject: [PATCH 131/134] chore(deps): bump annotations to 24.0.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 412f590..336003e 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,7 @@ org.jetbrains annotations - 13.0 + 24.0.1 provided From e34c38e4695542bebba46f247a39d8f5c5e30e13 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Wed, 3 Jan 2024 23:21:08 +0000 Subject: [PATCH 132/134] chore(deps): bump junit to 4.13.2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 336003e..2dfb849 100644 --- a/pom.xml +++ b/pom.xml @@ -46,7 +46,7 @@ junit junit - 4.13.1 + 4.13.2 test From d3e3294822866f7a05ffe1e898b13c6ba45e09df Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Mon, 23 Dec 2024 21:06:10 +0000 Subject: [PATCH 133/134] feat: add ability to check options before being processed by the config --- .../thatsmusic99/configurationmaster/api/ConfigFile.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java index d2364b3..ffa017e 100644 --- a/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java +++ b/API/src/main/java/io/github/thatsmusic99/configurationmaster/api/ConfigFile.java @@ -180,6 +180,8 @@ public void addDefaults() throws Exception { handleAnnotations((field, option) -> { + if (!canProcessOption(field, option)) return; + // Also get the field value and treat it as the default option final Object defaultOpt = field.get(this); @@ -213,6 +215,10 @@ public void addDefaults() throws Exception { }); } + public boolean canProcessOption(final @NotNull Field field, final @NotNull Option option) { + return true; + } + public void loadContent() throws IOException { loadFromString(readFileContent()); } From 4070ca923a3c972d5ff0855be60392b686141929 Mon Sep 17 00:00:00 2001 From: Thatsmusic99 <25277367+thatsmusic99@users.noreply.github.com> Date: Mon, 23 Dec 2024 21:06:54 +0000 Subject: [PATCH 134/134] chore(version): bump to v2.0.0-rc.3 --- API/pom.xml | 4 ++-- Bukkit/pom.xml | 4 ++-- pom.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/API/pom.xml b/API/pom.xml index 72e6d9f..67594b8 100644 --- a/API/pom.xml +++ b/API/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-rc.2 + v2.0.0-rc.3 4.0.0 ConfigurationMaster-API - v2.0.0-rc.2 + v2.0.0-rc.3 8 diff --git a/Bukkit/pom.xml b/Bukkit/pom.xml index 12844f9..b6ae390 100644 --- a/Bukkit/pom.xml +++ b/Bukkit/pom.xml @@ -5,12 +5,12 @@ ConfigurationMaster com.github.thatsmusic99 - v2.0.0-rc.2 + v2.0.0-rc.3 4.0.0 ConfigurationMaster-Bukkit - v2.0.0-rc.2 + v2.0.0-rc.3 8 diff --git a/pom.xml b/pom.xml index 2dfb849..ef18c5a 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ com.github.thatsmusic99 ConfigurationMaster pom - v2.0.0-rc.2 + v2.0.0-rc.3