|
@@ -7,53 +7,112 @@ import org.jetbrains.annotations.NotNull;
|
|
|
|
|
|
import java.io.*;
|
|
|
import java.util.HashSet;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.nio.file.Path;
|
|
|
import java.util.List;
|
|
|
import java.util.Set;
|
|
|
|
|
|
public abstract class BukkitConfig {
|
|
|
- public static final String CONFIG_PATCH_PREFIX = "ConfigPatchVersion:";
|
|
|
- public static final String CURRENT_CONFIG_PATCH_VER = "ConfigPatchVersion: 2";
|
|
|
- public static final char COMMENT_PREFIX = '#';
|
|
|
+ boolean copyDefaults = true;
|
|
|
protected final String fileName;
|
|
|
protected final File configFile;
|
|
|
+ protected YamlConfiguration defaultYamlConfig;
|
|
|
protected YamlConfiguration config;
|
|
|
- protected @NotNull
|
|
|
- final File dataFolder;
|
|
|
+ protected @NotNull final File dataFolder;
|
|
|
|
|
|
public BukkitConfig(@NotNull String fileName, @NotNull File dataFolder) {
|
|
|
mcMMO.p.getLogger().info("[config] Initializing config: " + fileName);
|
|
|
this.fileName = fileName;
|
|
|
this.dataFolder = dataFolder;
|
|
|
configFile = new File(dataFolder, fileName);
|
|
|
- // purgeComments(true);
|
|
|
+ this.defaultYamlConfig = copyDefaultConfig();
|
|
|
+ this.config = initConfig();
|
|
|
+ updateFile();
|
|
|
+ mcMMO.p.getLogger().info("[config] Config initialized: " + fileName);
|
|
|
+ }
|
|
|
+
|
|
|
+ public BukkitConfig(@NotNull String fileName, @NotNull File dataFolder, boolean copyDefaults) {
|
|
|
+ mcMMO.p.getLogger().info("[config] Initializing config: " + fileName);
|
|
|
+ this.copyDefaults = copyDefaults;
|
|
|
+ this.fileName = fileName;
|
|
|
+ this.dataFolder = dataFolder;
|
|
|
+ configFile = new File(dataFolder, fileName);
|
|
|
+ this.defaultYamlConfig = copyDefaultConfig();
|
|
|
this.config = initConfig();
|
|
|
- initDefaults();
|
|
|
updateFile();
|
|
|
mcMMO.p.getLogger().info("[config] Config initialized: " + fileName);
|
|
|
}
|
|
|
|
|
|
- @Deprecated
|
|
|
public BukkitConfig(@NotNull String fileName) {
|
|
|
this(fileName, mcMMO.p.getDataFolder());
|
|
|
}
|
|
|
-
|
|
|
- /**
|
|
|
- * Initialize default values for the config
|
|
|
- */
|
|
|
- public void initDefaults() {}
|
|
|
+ public BukkitConfig(@NotNull String fileName, boolean copyDefaults) {
|
|
|
+ this(fileName, mcMMO.p.getDataFolder(), copyDefaults);
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* Update the file on the disk by copying out any new and missing defaults
|
|
|
*/
|
|
|
public void updateFile() {
|
|
|
try {
|
|
|
+ if(copyDefaults) {
|
|
|
+ copyMissingDefaultsFromResource();
|
|
|
+ }
|
|
|
config.save(configFile);
|
|
|
} catch (IOException e) {
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private YamlConfiguration initConfig() {
|
|
|
+ /**
|
|
|
+ * Copies missing keys and values from the internal resource config within the JAR
|
|
|
+ */
|
|
|
+ private void copyMissingDefaultsFromResource() {
|
|
|
+ boolean updated = false;
|
|
|
+ for (String key : defaultYamlConfig.getKeys(true)) {
|
|
|
+ if (!config.contains(key)) {
|
|
|
+ config.set(key, defaultYamlConfig.get(key));
|
|
|
+ updated = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (updated) {
|
|
|
+ updateFile();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Copies the config from the JAR to defaults/<fileName>
|
|
|
+ */
|
|
|
+ YamlConfiguration copyDefaultConfig() {
|
|
|
+ mcMMO.p.getLogger().info("[config] Copying default config to disk: " + fileName + " to defaults/" + fileName);
|
|
|
+ try(InputStream inputStream = mcMMO.p.getResource(fileName)) {
|
|
|
+ if(inputStream == null) {
|
|
|
+ mcMMO.p.getLogger().severe("[config] Unable to copy default config: " + fileName);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ //Save default file into defaults/<fileName>
|
|
|
+ File defaultsFolder = new File(dataFolder, "defaults");
|
|
|
+ if (!defaultsFolder.exists()) {
|
|
|
+ defaultsFolder.mkdir();
|
|
|
+ }
|
|
|
+ File defaultFile = new File(defaultsFolder, fileName);
|
|
|
+ Path path = defaultFile.toPath();
|
|
|
+ Files.copy(inputStream, path, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
|
|
|
+
|
|
|
+ // Load file into YAML config
|
|
|
+ YamlConfiguration defaultYamlConfig = new YamlConfiguration();
|
|
|
+ defaultYamlConfig.load(defaultFile);
|
|
|
+ return defaultYamlConfig;
|
|
|
+ } catch (IOException | InvalidConfigurationException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ YamlConfiguration initConfig() {
|
|
|
if (!configFile.exists()) {
|
|
|
mcMMO.p.getLogger().info("[config] User config file not found, copying a default config to disk: " + fileName);
|
|
|
mcMMO.p.saveResource(fileName, false);
|
|
@@ -106,8 +165,8 @@ public abstract class BukkitConfig {
|
|
|
}
|
|
|
|
|
|
public void backup() {
|
|
|
- mcMMO.p.getLogger().severe("You are using an old version of the " + fileName + " file.");
|
|
|
- mcMMO.p.getLogger().severe("Your old file has been renamed to " + fileName + ".old and has been replaced by an updated version.");
|
|
|
+ mcMMO.p.getLogger().info("You are using an old version of the " + fileName + " file.");
|
|
|
+ mcMMO.p.getLogger().info("Your old file has been renamed to " + fileName + ".old and has been replaced by an updated version.");
|
|
|
|
|
|
configFile.renameTo(new File(configFile.getPath() + ".old"));
|
|
|
|
|
@@ -123,98 +182,4 @@ public abstract class BukkitConfig {
|
|
|
public File getFile() {
|
|
|
return configFile;
|
|
|
}
|
|
|
-
|
|
|
-// /**
|
|
|
-// * Somewhere between December 2021-January 2022 Spigot updated their
|
|
|
-// * SnakeYAML dependency/API and due to our own crappy legacy code
|
|
|
-// * this introduced a very problematic bug where comments got duplicated
|
|
|
-// * <p>
|
|
|
-// * This method hotfixes the problem by just deleting any existing comments
|
|
|
-// * it's ugly, but it gets the job done
|
|
|
-// *
|
|
|
-// * @param silentFail when true mcMMO will report errors during the patch process or debug information
|
|
|
-// * the option to have it fail silently is because mcMMO wants to check files before they are parsed as a file with a zillion comments will fail to even load
|
|
|
-// */
|
|
|
-// private void purgeComments(boolean silentFail) {
|
|
|
-// if(!configFile.exists())
|
|
|
-// return;
|
|
|
-//
|
|
|
-// int dupedLines = 0, lineCount = 0, lineCountAfter = 0;
|
|
|
-// try (FileReader fileReader = new FileReader(configFile);
|
|
|
-// BufferedReader bufferedReader = new BufferedReader(fileReader)) {
|
|
|
-// StringBuilder stringBuilder = new StringBuilder();
|
|
|
-// String line;
|
|
|
-// Set<String> seenBefore = new HashSet<>();
|
|
|
-//
|
|
|
-// stringBuilder.append(CURRENT_CONFIG_PATCH_VER).append(System.lineSeparator());
|
|
|
-// boolean noPatchNeeded = false;
|
|
|
-//
|
|
|
-// // While not at the end of the file
|
|
|
-// while ((line = bufferedReader.readLine()) != null) {
|
|
|
-// lineCount++;
|
|
|
-//
|
|
|
-// if(line.startsWith(CURRENT_CONFIG_PATCH_VER)) {
|
|
|
-// noPatchNeeded = true;
|
|
|
-// break;
|
|
|
-// }
|
|
|
-//
|
|
|
-// //Older version, don't append this line
|
|
|
-// if(line.startsWith(CONFIG_PATCH_PREFIX))
|
|
|
-// continue;
|
|
|
-//
|
|
|
-// if (isFirstCharAsciiCharacter(line, COMMENT_PREFIX)) {
|
|
|
-// if(seenBefore.contains(line))
|
|
|
-// dupedLines++;
|
|
|
-// else
|
|
|
-// seenBefore.add(line);
|
|
|
-//
|
|
|
-// continue; //Delete the line by not appending it
|
|
|
-// }
|
|
|
-//
|
|
|
-// stringBuilder
|
|
|
-// .append(line) //Convert existing files into two-spaced format
|
|
|
-// .append(System.lineSeparator());
|
|
|
-// lineCountAfter++;
|
|
|
-// }
|
|
|
-//
|
|
|
-// if(noPatchNeeded)
|
|
|
-// return;
|
|
|
-//
|
|
|
-// if(lineCount == 0 && !silentFail) {
|
|
|
-// mcMMO.p.getLogger().info("[config patcher] Config line count: " + lineCount);
|
|
|
-// throw new InvalidConfigurationException("[config patcher] Patching of config file resulted in an empty file, this will not be saved. Contact the mcMMO devs!");
|
|
|
-// }
|
|
|
-//
|
|
|
-// if(dupedLines > 0 && !silentFail) {
|
|
|
-// mcMMO.p.getLogger().info("[config patcher] Found "+dupedLines+" duplicate comments in config file: " + configFile.getName());
|
|
|
-// mcMMO.p.getLogger().info("[config patcher] Purging the duplicate comments... (Nothing is broken, this is just info used for debugging)");
|
|
|
-// mcMMO.p.getLogger().info("[config patcher] Line count before: "+lineCount);
|
|
|
-// mcMMO.p.getLogger().info("[config patcher] Line count after: "+lineCountAfter);
|
|
|
-// }
|
|
|
-//
|
|
|
-// // Write out the *patched* file
|
|
|
-// // AKA the file without any comments
|
|
|
-// try (FileWriter fileWriter = new FileWriter(configFile)) {
|
|
|
-// fileWriter.write(stringBuilder.toString());
|
|
|
-// }
|
|
|
-// } catch (IOException | InvalidConfigurationException ex) {
|
|
|
-// mcMMO.p.getLogger().severe("Failed to patch config file: " + configFile.getName());
|
|
|
-// ex.printStackTrace();
|
|
|
-// }
|
|
|
-// }
|
|
|
-
|
|
|
- private boolean isFirstCharAsciiCharacter(String line, char character) {
|
|
|
- if(line == null || line.isEmpty()) {
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- for(Character c : line.toCharArray()) {
|
|
|
- if(c.equals(' '))
|
|
|
- continue;
|
|
|
-
|
|
|
- return c.equals(character);
|
|
|
- }
|
|
|
-
|
|
|
- return false;
|
|
|
- }
|
|
|
}
|