mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-19 15:09:25 +00:00
initial
- Auto migrator - Backup system
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
package org.dreeam.leaf.config;
|
||||
|
||||
import io.github.thatsmusic99.configurationmaster.api.ConfigFile;
|
||||
import io.github.thatsmusic99.configurationmaster.api.ConfigSection;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConfigMigrator {
|
||||
|
||||
private static final String BACKUP_PREFIX = "backup-migration-";
|
||||
|
||||
public void migrate() throws Exception {
|
||||
File oldConfigFile = new File(LeafConfig.I_CONFIG_FOLDER, LeafConfig.I_GLOBAL_CONFIG_FILE);
|
||||
if (!oldConfigFile.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure config/leaf directory exists
|
||||
LeafConfig.createDirectory(LeafConfig.I_LEAF_CONFIG_FOLDER);
|
||||
|
||||
// Load the old config
|
||||
ConfigFile oldConfig = ConfigFile.loadConfig(oldConfigFile);
|
||||
|
||||
// Create backup
|
||||
createBackup(oldConfigFile);
|
||||
|
||||
// Create separate config files for each category in config/leaf folder
|
||||
Map<EnumConfigCategory, ConfigFile> newConfigs = new HashMap<>();
|
||||
|
||||
for (EnumConfigCategory category : EnumConfigCategory.getCategoryValues()) {
|
||||
File newConfigFile = new File(LeafConfig.I_LEAF_CONFIG_FOLDER, category.getFileName());
|
||||
ConfigFile newConfig = ConfigFile.loadConfig(newConfigFile);
|
||||
newConfigs.put(category, newConfig);
|
||||
|
||||
// Set up basic structure
|
||||
newConfig.set("config-version", "3.0");
|
||||
newConfig.addComments("config-version", String.format("Leaf %s Config\nGitHub Repo: https://github.com/Winds-Studio/Leaf", category.name()));
|
||||
}
|
||||
|
||||
// Migrate data from old config to new configs
|
||||
migrateConfigData(oldConfig, newConfigs);
|
||||
|
||||
// Save all new config files
|
||||
for (ConfigFile newConfig : newConfigs.values()) {
|
||||
newConfig.save();
|
||||
}
|
||||
|
||||
LeafConfig.LOGGER.info("Config migration completed. Old config backed up.");
|
||||
LeafConfig.LOGGER.info("New config files created in config/leaf/ folder.");
|
||||
}
|
||||
|
||||
private void createBackup(File oldConfigFile) throws Exception {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd-HHmmss");
|
||||
String timestamp = dateFormat.format(new Date());
|
||||
String backupName = BACKUP_PREFIX + timestamp + "-" + oldConfigFile.getName();
|
||||
Path backupPath = oldConfigFile.toPath().resolveSibling(backupName);
|
||||
|
||||
Files.copy(oldConfigFile.toPath(), backupPath, StandardCopyOption.REPLACE_EXISTING);
|
||||
LeafConfig.LOGGER.info("Created backup: {}", backupName);
|
||||
}
|
||||
|
||||
private void migrateConfigData(ConfigFile oldConfig, Map<EnumConfigCategory, ConfigFile> newConfigs) {
|
||||
// Iterate through each category and migrate relevant sections
|
||||
for (EnumConfigCategory category : EnumConfigCategory.getCategoryValues()) {
|
||||
ConfigFile newConfig = newConfigs.get(category);
|
||||
String basePath = category.getBaseKeyName();
|
||||
|
||||
// Get the section from old config
|
||||
ConfigSection oldSection = oldConfig.getConfigSection(basePath);
|
||||
if (oldSection != null) {
|
||||
// Copy all values from the old section to the new config
|
||||
copySection(oldSection, newConfig, basePath);
|
||||
LeafConfig.LOGGER.debug("Migrated {} section to {}", basePath, category.getFileName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void copySection(ConfigSection source, ConfigFile target, String basePath) {
|
||||
// Get all keys from the source section (shallow keys only)
|
||||
for (String key : source.getKeys(false)) {
|
||||
String fullPath = basePath + "." + key;
|
||||
Object value = source.get(key);
|
||||
|
||||
if (value instanceof ConfigSection) {
|
||||
// Recursively copy subsections
|
||||
copySection((ConfigSection) value, target, fullPath);
|
||||
} else {
|
||||
// Copy the value
|
||||
target.set(fullPath, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,10 +15,32 @@ public abstract class ConfigModules extends LeafConfig {
|
||||
|
||||
private static final Set<ConfigModules> MODULES = new HashSet<>();
|
||||
|
||||
public LeafGlobalConfig config;
|
||||
public LeafCategoryConfig config;
|
||||
private EnumConfigCategory category;
|
||||
|
||||
public ConfigModules() {
|
||||
this.config = LeafConfig.config();
|
||||
// Determine category from the module's base path
|
||||
this.category = determineCategory();
|
||||
this.config = LeafConfig.config(this.category);
|
||||
}
|
||||
|
||||
// Abstract method that modules must implement to specify their base path
|
||||
public abstract String getBasePath();
|
||||
|
||||
// Determine category from base path
|
||||
private EnumConfigCategory determineCategory() {
|
||||
String basePath = getBasePath();
|
||||
for (EnumConfigCategory cat : EnumConfigCategory.getCategoryValues()) {
|
||||
if (basePath.startsWith(cat.getBaseKeyName())) {
|
||||
return cat;
|
||||
}
|
||||
}
|
||||
// Fallback to MISC if no category matches
|
||||
return EnumConfigCategory.MISC;
|
||||
}
|
||||
|
||||
public EnumConfigCategory getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public static void initModules() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
|
||||
@@ -38,7 +60,8 @@ public abstract class ConfigModules extends LeafConfig {
|
||||
}
|
||||
|
||||
if (!enabledExperimentalModules.isEmpty()) {
|
||||
LeafConfig.LOGGER.warn("You have following experimental module(s) enabled: {}, please proceed with caution!", enabledExperimentalModules.stream().map(f -> f.getDeclaringClass().getSimpleName() + "." + f.getName()).toList());
|
||||
LeafConfig.LOGGER.warn("You have following experimental module(s) enabled: {}, please proceed with caution!",
|
||||
enabledExperimentalModules.stream().map(f -> f.getDeclaringClass().getSimpleName() + "." + f.getName()).toList());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,11 +70,13 @@ public abstract class ConfigModules extends LeafConfig {
|
||||
module.onPostLoaded();
|
||||
}
|
||||
|
||||
// Save config to disk
|
||||
try {
|
||||
LeafConfig.config().saveConfig();
|
||||
} catch (Exception e) {
|
||||
LeafConfig.LOGGER.error("Failed to save config file!", e);
|
||||
// Save all config files to disk
|
||||
for (EnumConfigCategory category : EnumConfigCategory.getCategoryValues()) {
|
||||
try {
|
||||
LeafConfig.config(category).saveConfig();
|
||||
} catch (Exception e) {
|
||||
LeafConfig.LOGGER.error("Failed to save config file for category {}!", category.name(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.dreeam.leaf.config;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConfigStatus {
|
||||
|
||||
public static Map<String, Object> getStatus() {
|
||||
Map<String, Object> status = new HashMap<>();
|
||||
|
||||
File oldConfigFile = new File(LeafConfig.I_CONFIG_FOLDER, LeafConfig.I_GLOBAL_CONFIG_FILE);
|
||||
status.put("oldConfigExists", oldConfigFile.exists());
|
||||
status.put("oldConfigFile", LeafConfig.I_GLOBAL_CONFIG_FILE);
|
||||
|
||||
Map<String, Boolean> categoryFiles = new HashMap<>();
|
||||
for (EnumConfigCategory category : EnumConfigCategory.getCategoryValues()) {
|
||||
File categoryFile = new File(LeafConfig.I_CONFIG_FOLDER, category.getFileName());
|
||||
categoryFiles.put(category.getFileName(), categoryFile.exists());
|
||||
}
|
||||
status.put("categoryFiles", categoryFiles);
|
||||
|
||||
boolean needsMigration = oldConfigFile.exists() && !allCategoryFilesExist();
|
||||
status.put("needsMigration", needsMigration);
|
||||
status.put("multiFileSystemReady", allCategoryFilesExist());
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
private static boolean allCategoryFilesExist() {
|
||||
for (EnumConfigCategory category : EnumConfigCategory.getCategoryValues()) {
|
||||
File categoryFile = new File(LeafConfig.I_CONFIG_FOLDER, category.getFileName());
|
||||
if (!categoryFile.exists()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,40 @@
|
||||
package org.dreeam.leaf.config;
|
||||
|
||||
public enum EnumConfigCategory {
|
||||
ASYNC("async"),
|
||||
PERF("performance"),
|
||||
FIXES("fixes"),
|
||||
GAMEPLAY("gameplay-mechanisms"),
|
||||
NETWORK("network"),
|
||||
MISC("misc");
|
||||
ASYNC("async", "leaf-async.yml"),
|
||||
PERF("performance", "leaf-performance.yml"),
|
||||
FIXES("fixes", "leaf-fixes.yml"),
|
||||
GAMEPLAY("gameplay-mechanisms", "leaf-gameplay.yml"),
|
||||
NETWORK("network", "leaf-network.yml"),
|
||||
MISC("misc", "leaf-misc.yml");
|
||||
|
||||
private final String baseKeyName;
|
||||
private final String fileName;
|
||||
private static final EnumConfigCategory[] VALUES = EnumConfigCategory.values();
|
||||
|
||||
EnumConfigCategory(String baseKeyName) {
|
||||
EnumConfigCategory(String baseKeyName, String fileName) {
|
||||
this.baseKeyName = baseKeyName;
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
public String getBaseKeyName() {
|
||||
return this.baseKeyName;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return this.fileName;
|
||||
}
|
||||
|
||||
public static EnumConfigCategory[] getCategoryValues() {
|
||||
return VALUES;
|
||||
}
|
||||
|
||||
public static EnumConfigCategory fromBaseKeyName(String baseKeyName) {
|
||||
for (EnumConfigCategory category : VALUES) {
|
||||
if (category.baseKeyName.equals(baseKeyName)) {
|
||||
return category;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,211 @@
|
||||
package org.dreeam.leaf.config;
|
||||
|
||||
import io.github.thatsmusic99.configurationmaster.api.ConfigFile;
|
||||
import io.github.thatsmusic99.configurationmaster.api.ConfigSection;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class LeafCategoryConfig {
|
||||
|
||||
private static final String CURRENT_VERSION = "3.0";
|
||||
private static final String CURRENT_REGION = Locale.getDefault().getCountry().toUpperCase(Locale.ROOT);
|
||||
private static final boolean isCN = CURRENT_REGION.equals("CN");
|
||||
|
||||
private final EnumConfigCategory category;
|
||||
private ConfigFile configFile;
|
||||
|
||||
public LeafCategoryConfig(EnumConfigCategory category, boolean init) throws Exception {
|
||||
this.category = category;
|
||||
this.configFile = ConfigFile.loadConfig(new File(LeafConfig.I_LEAF_CONFIG_FOLDER, category.getFileName()));
|
||||
|
||||
// Add version and header comments
|
||||
configFile.set("config-version", CURRENT_VERSION);
|
||||
configFile.addComments("config-version", pickStringRegionBased(
|
||||
String.format("Leaf %s Config\nGitHub Repo: https://github.com/Winds-Studio/Leaf\nDiscord: https://discord.com/invite/gfgAwdSEuM",
|
||||
category.name()),
|
||||
String.format("Leaf %s Config\nGitHub Repo: https://github.com/Winds-Studio/Leaf\nQQ Group: 619278377",
|
||||
category.name())
|
||||
));
|
||||
|
||||
// Pre-structure the config
|
||||
structureConfig();
|
||||
}
|
||||
|
||||
protected void structureConfig() {
|
||||
createTitledSection(category.name(), category.getBaseKeyName());
|
||||
}
|
||||
|
||||
public void saveConfig() throws Exception {
|
||||
configFile.save();
|
||||
}
|
||||
|
||||
public EnumConfigCategory getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
// Config Utilities
|
||||
public void createTitledSection(String title, String path) {
|
||||
configFile.addSection(title);
|
||||
configFile.addDefault(path, null);
|
||||
}
|
||||
|
||||
public boolean getBoolean(String path, boolean def, String comment) {
|
||||
configFile.addDefault(path, def, comment);
|
||||
return configFile.getBoolean(path, def);
|
||||
}
|
||||
|
||||
public boolean getBoolean(String path, boolean def) {
|
||||
configFile.addDefault(path, def);
|
||||
return configFile.getBoolean(path, def);
|
||||
}
|
||||
|
||||
public String getString(String path, String def, String comment) {
|
||||
configFile.addDefault(path, def, comment);
|
||||
return configFile.getString(path, def);
|
||||
}
|
||||
|
||||
public String getString(String path, String def) {
|
||||
configFile.addDefault(path, def);
|
||||
return configFile.getString(path, def);
|
||||
}
|
||||
|
||||
public double getDouble(String path, double def, String comment) {
|
||||
configFile.addDefault(path, def, comment);
|
||||
return configFile.getDouble(path, def);
|
||||
}
|
||||
|
||||
public double getDouble(String path, double def) {
|
||||
configFile.addDefault(path, def);
|
||||
return configFile.getDouble(path, def);
|
||||
}
|
||||
|
||||
public int getInt(String path, int def, String comment) {
|
||||
configFile.addDefault(path, def, comment);
|
||||
return configFile.getInteger(path, def);
|
||||
}
|
||||
|
||||
public int getInt(String path, int def) {
|
||||
configFile.addDefault(path, def);
|
||||
return configFile.getInteger(path, def);
|
||||
}
|
||||
|
||||
public long getLong(String path, long def, String comment) {
|
||||
configFile.addDefault(path, def, comment);
|
||||
return configFile.getLong(path, def);
|
||||
}
|
||||
|
||||
public long getLong(String path, long def) {
|
||||
configFile.addDefault(path, def);
|
||||
return configFile.getLong(path, def);
|
||||
}
|
||||
|
||||
public List<String> getList(String path, List<String> def, String comment) {
|
||||
configFile.addDefault(path, def, comment);
|
||||
return configFile.getStringList(path);
|
||||
}
|
||||
|
||||
public List<String> getList(String path, List<String> def) {
|
||||
configFile.addDefault(path, def);
|
||||
return configFile.getStringList(path);
|
||||
}
|
||||
|
||||
public ConfigSection getConfigSection(String path, Map<String, Object> defaultKeyValue, String comment) {
|
||||
configFile.addDefault(path, null, comment);
|
||||
configFile.makeSectionLenient(path);
|
||||
defaultKeyValue.forEach((string, object) -> configFile.addExample(path + "." + string, object));
|
||||
return configFile.getConfigSection(path);
|
||||
}
|
||||
|
||||
public ConfigSection getConfigSection(String path, Map<String, Object> defaultKeyValue) {
|
||||
configFile.addDefault(path, null);
|
||||
configFile.makeSectionLenient(path);
|
||||
defaultKeyValue.forEach((string, object) -> configFile.addExample(path + "." + string, object));
|
||||
return configFile.getConfigSection(path);
|
||||
}
|
||||
|
||||
// Getter methods
|
||||
public Boolean getBoolean(String path) {
|
||||
String value = configFile.getString(path, null);
|
||||
return value == null ? null : Boolean.parseBoolean(value);
|
||||
}
|
||||
|
||||
public String getString(String path) {
|
||||
return configFile.getString(path, null);
|
||||
}
|
||||
|
||||
public Double getDouble(String path) {
|
||||
String value = configFile.getString(path, null);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Double.parseDouble(value);
|
||||
} catch (NumberFormatException e) {
|
||||
LeafConfig.LOGGER.warn("{} is not a valid number, skipped! Please check your configuration.", path, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Integer getInt(String path) {
|
||||
String value = configFile.getString(path, null);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Integer.parseInt(value);
|
||||
} catch (NumberFormatException e) {
|
||||
LeafConfig.LOGGER.warn("{} is not a valid number, skipped! Please check your configuration.", path, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Long getLong(String path) {
|
||||
String value = configFile.getString(path, null);
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Long.parseLong(value);
|
||||
} catch (NumberFormatException e) {
|
||||
LeafConfig.LOGGER.warn("{} is not a valid number, skipped! Please check your configuration.", path, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getList(String path) {
|
||||
return configFile.getList(path, null);
|
||||
}
|
||||
|
||||
public ConfigSection getConfigSection(String path) {
|
||||
configFile.addDefault(path, null);
|
||||
configFile.makeSectionLenient(path);
|
||||
return configFile.getConfigSection(path);
|
||||
}
|
||||
|
||||
public void addComment(String path, String comment) {
|
||||
configFile.addComment(path, comment);
|
||||
}
|
||||
|
||||
public void addCommentIfCN(String path, String comment) {
|
||||
if (isCN) {
|
||||
configFile.addComment(path, comment);
|
||||
}
|
||||
}
|
||||
|
||||
public void addCommentIfNonCN(String path, String comment) {
|
||||
if (!isCN) {
|
||||
configFile.addComment(path, comment);
|
||||
}
|
||||
}
|
||||
|
||||
public void addCommentRegionBased(String path, String en, String cn) {
|
||||
configFile.addComment(path, isCN ? cn : en);
|
||||
}
|
||||
|
||||
public String pickStringRegionBased(String en, String cn) {
|
||||
return isCN ? cn : en;
|
||||
}
|
||||
}
|
||||
@@ -26,13 +26,7 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
@@ -40,21 +34,18 @@ import java.util.jar.JarFile;
|
||||
/*
|
||||
* Yoinked from: https://github.com/xGinko/AnarchyExploitFixes/ & https://github.com/LuminolMC/Luminol
|
||||
* @author: @xGinko & @MrHua269
|
||||
*
|
||||
* Rewritten by @Taiyou
|
||||
*/
|
||||
public class LeafConfig {
|
||||
|
||||
public static final Logger LOGGER = LogManager.getLogger(LeafConfig.class.getSimpleName());
|
||||
protected static final File I_CONFIG_FOLDER = new File("config");
|
||||
protected static final File I_LEAF_CONFIG_FOLDER = new File(I_CONFIG_FOLDER, "leaf");
|
||||
protected static final String I_CONFIG_PKG = "org.dreeam.leaf.config.modules";
|
||||
protected static final String I_GLOBAL_CONFIG_FILE = "leaf-global.yml";
|
||||
protected static final String I_LEVEL_CONFIG_FILE = "leaf-world-defaults.yml"; // Leaf TODO - Per level config
|
||||
|
||||
private static LeafGlobalConfig leafGlobalConfig;
|
||||
|
||||
//private static int preMajorVer;
|
||||
private static int preMinorVer;
|
||||
//private static int currMajorVer;
|
||||
private static int currMinorVer;
|
||||
private static Map<EnumConfigCategory, LeafCategoryConfig> categoryConfigs = new HashMap<>();
|
||||
|
||||
/* Load & Reload */
|
||||
|
||||
@@ -84,6 +75,10 @@ public class LeafConfig {
|
||||
LOGGER.info("Loading config...");
|
||||
|
||||
purgeOutdated();
|
||||
|
||||
// Auto-migrate if old config exists
|
||||
autoMigrateIfNeeded();
|
||||
|
||||
loadConfig(true);
|
||||
|
||||
LOGGER.info("Successfully loaded config in {}ms.", (System.nanoTime() - begin) / 1_000_000);
|
||||
@@ -95,17 +90,58 @@ public class LeafConfig {
|
||||
/* Load Global Config */
|
||||
|
||||
private static void loadConfig(boolean init) throws Exception {
|
||||
// Create config folder
|
||||
createDirectory(I_CONFIG_FOLDER);
|
||||
// Create leaf config folder
|
||||
createDirectory(I_LEAF_CONFIG_FOLDER);
|
||||
|
||||
leafGlobalConfig = new LeafGlobalConfig(init);
|
||||
// Load all category configs
|
||||
categoryConfigs.clear();
|
||||
for (EnumConfigCategory category : EnumConfigCategory.getCategoryValues()) {
|
||||
categoryConfigs.put(category, new LeafCategoryConfig(category, init));
|
||||
}
|
||||
|
||||
// Load config modules
|
||||
ConfigModules.initModules();
|
||||
}
|
||||
|
||||
public static LeafGlobalConfig config() {
|
||||
return leafGlobalConfig;
|
||||
public static LeafCategoryConfig config(EnumConfigCategory category) {
|
||||
return categoryConfigs.get(category);
|
||||
}
|
||||
|
||||
// For backward compatibility - returns misc config
|
||||
@Deprecated
|
||||
public static LeafCategoryConfig config() {
|
||||
return categoryConfigs.get(EnumConfigCategory.MISC);
|
||||
}
|
||||
|
||||
/* Auto-migration logic */
|
||||
|
||||
private static void autoMigrateIfNeeded() {
|
||||
File oldConfigFile = new File(I_CONFIG_FOLDER, I_GLOBAL_CONFIG_FILE);
|
||||
if (!oldConfigFile.exists()) {
|
||||
return; // No old config to migrate
|
||||
}
|
||||
|
||||
// Check if any category files are missing
|
||||
boolean needsMigration = false;
|
||||
for (EnumConfigCategory category : EnumConfigCategory.getCategoryValues()) {
|
||||
File categoryFile = new File(I_LEAF_CONFIG_FOLDER, category.getFileName());
|
||||
if (!categoryFile.exists()) {
|
||||
needsMigration = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (needsMigration) {
|
||||
LOGGER.info("Detected old config file. Automatically migrating to multi-file system...");
|
||||
try {
|
||||
ConfigMigrator migrator = new ConfigMigrator();
|
||||
migrator.migrate();
|
||||
LOGGER.info("Migration completed successfully!");
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Auto-migration failed!", e);
|
||||
throw new RuntimeException("Failed to migrate config", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Create config folder */
|
||||
@@ -203,40 +239,42 @@ public class LeafConfig {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
public static void loadConfigVersion(String preVer, String currVer) {
|
||||
int currMinor;
|
||||
int preMinor;
|
||||
|
||||
// First time user
|
||||
if (preVer == null) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Register Spark profiler extra server configurations */
|
||||
|
||||
private static List<String> buildSparkExtraConfigs() {
|
||||
List<String> extraConfigs = new ArrayList<>(Arrays.asList(
|
||||
"config/leaf-global.yml",
|
||||
"config/gale-global.yml",
|
||||
"config/gale-world-defaults.yml"
|
||||
));
|
||||
public static void regSparkExtraConfig() {
|
||||
if (GlobalConfiguration.get().spark.enabled || Bukkit.getServer().getPluginManager().getPlugin("spark") != null) {
|
||||
List<String> extraConfigs = new ArrayList<>();
|
||||
|
||||
@Nullable String existing = System.getProperty("spark.serverconfigs.extra");
|
||||
if (existing != null) {
|
||||
extraConfigs.addAll(Arrays.asList(existing.split(",")));
|
||||
// Add all category config files from config/leaf folder (individual files)
|
||||
for (EnumConfigCategory category : EnumConfigCategory.getCategoryValues()) {
|
||||
extraConfigs.add("config/leaf/" + category.getFileName());
|
||||
}
|
||||
|
||||
// Add other configs
|
||||
extraConfigs.addAll(Arrays.asList(
|
||||
"config/gale-global.yml",
|
||||
"config/gale-world-defaults.yml"
|
||||
));
|
||||
|
||||
@Nullable String existing = System.getProperty("spark.serverconfigs.extra");
|
||||
if (existing != null) {
|
||||
extraConfigs.addAll(Arrays.asList(existing.split(",")));
|
||||
}
|
||||
|
||||
// Use same way in spark's BukkitServerConfigProvider#getNestedFiles to get all world configs
|
||||
// It may spam in the spark profiler, but it's ok, since spark uses YamlConfigParser.INSTANCE to
|
||||
// get configs defined in extra config flag instead of using SplitYamlConfigParser.INSTANCE
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
Path galeWorldFolder = world.getWorldFolder().toPath().resolve("gale-world.yml");
|
||||
extraConfigs.add(galeWorldFolder.toString().replace("\\", "/").replace("./", "")); // Gale world config
|
||||
}
|
||||
|
||||
String extraConfigsStr = String.join(",", extraConfigs);
|
||||
String hiddenPaths = String.join(",", buildSparkHiddenPaths());
|
||||
|
||||
System.setProperty("spark.serverconfigs.extra", extraConfigsStr);
|
||||
System.setProperty("spark.serverconfigs.hiddenpaths", hiddenPaths);
|
||||
}
|
||||
|
||||
// Use same way in spark's BukkitServerConfigProvider#getNestedFiles to get all world configs
|
||||
// It may spam in the spark profiler, but it's ok, since spark uses YamlConfigParser.INSTANCE to
|
||||
// get configs defined in extra config flag instead of using SplitYamlConfigParser.INSTANCE
|
||||
for (World world : Bukkit.getWorlds()) {
|
||||
Path galeWorldFolder = world.getWorldFolder().toPath().resolve("gale-world.yml");
|
||||
extraConfigs.add(galeWorldFolder.toString().replace("\\", "/").replace("./", "")); // Gale world config
|
||||
}
|
||||
|
||||
return extraConfigs;
|
||||
}
|
||||
|
||||
private static List<String> buildSparkHiddenPaths() {
|
||||
@@ -249,16 +287,6 @@ public class LeafConfig {
|
||||
return extraHidden;
|
||||
}
|
||||
|
||||
public static void regSparkExtraConfig() {
|
||||
if (GlobalConfiguration.get().spark.enabled || Bukkit.getServer().getPluginManager().getPlugin("spark") != null) {
|
||||
String extraConfigs = String.join(",", buildSparkExtraConfigs());
|
||||
String hiddenPaths = String.join(",", buildSparkHiddenPaths());
|
||||
|
||||
System.setProperty("spark.serverconfigs.extra", extraConfigs);
|
||||
System.setProperty("spark.serverconfigs.hiddenpaths", hiddenPaths);
|
||||
}
|
||||
}
|
||||
|
||||
/* Purge and backup old Leaf config & Pufferfish config */
|
||||
|
||||
private static void purgeOutdated() {
|
||||
@@ -295,7 +323,7 @@ public class LeafConfig {
|
||||
|
||||
if (foundLegacy) {
|
||||
LOGGER.warn("Found legacy Leaf config files, move to backup directory: {}", backupDir);
|
||||
LOGGER.warn("New Leaf config located at config/ folder, You need to transfer config to the new one manually and restart the server!");
|
||||
LOGGER.warn("New Leaf config located at config/leaf/ folder, You need to transfer config to the new one manually and restart the server!");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Failed to purge old configs.", e);
|
||||
|
||||
@@ -10,7 +10,7 @@ import java.util.Map;
|
||||
|
||||
public class LeafGlobalConfig {
|
||||
|
||||
private static final String CURRENT_VERSION = "3.0";
|
||||
private static final String CURRENT_VERSION = "4.0";
|
||||
private static final String CURRENT_REGION = Locale.getDefault().getCountry().toUpperCase(Locale.ROOT); // It will be in uppercase by default, just make sure
|
||||
private static final boolean isCN = CURRENT_REGION.equals("CN");
|
||||
|
||||
@@ -19,7 +19,6 @@ public class LeafGlobalConfig {
|
||||
public LeafGlobalConfig(boolean init) throws Exception {
|
||||
configFile = ConfigFile.loadConfig(new File(LeafConfig.I_CONFIG_FOLDER, LeafConfig.I_GLOBAL_CONFIG_FILE));
|
||||
|
||||
LeafConfig.loadConfigVersion(getString("config-version"), CURRENT_VERSION);
|
||||
configFile.set("config-version", CURRENT_VERSION);
|
||||
|
||||
configFile.addComments("config-version", pickStringRegionBased("""
|
||||
|
||||
Reference in New Issue
Block a user