diff --git a/divinemc-api/paper-patches/features/0002-Configuration.patch b/divinemc-api/paper-patches/features/0002-Configuration.patch deleted file mode 100644 index c0c586c..0000000 --- a/divinemc-api/paper-patches/features/0002-Configuration.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> -Date: Fri, 21 Feb 2025 23:00:22 +0300 -Subject: [PATCH] Configuration - - -diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java -index 78637a4f9650c1dd7ccc94bbfeb1fac048aa7f69..225c13225837c2748843cece816e2ad70da4b056 100644 ---- a/src/main/java/org/bukkit/Server.java -+++ b/src/main/java/org/bukkit/Server.java -@@ -2346,6 +2346,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi - } - // Purpur end - -+ // DivineMC start - Configuration -+ @NotNull -+ public org.bukkit.configuration.file.YamlConfiguration getDivineConfig() { -+ throw new UnsupportedOperationException("Not supported yet"); -+ } -+ // DivineMC end - Configuration -+ - /** - * Sends the component to the player - * diff --git a/divinemc-api/paper-patches/features/0003-Delete-Timings.patch b/divinemc-api/paper-patches/features/0002-Delete-Timings.patch similarity index 100% rename from divinemc-api/paper-patches/features/0003-Delete-Timings.patch rename to divinemc-api/paper-patches/features/0002-Delete-Timings.patch diff --git a/divinemc-api/paper-patches/features/0004-Disable-reload-command-by-default.patch b/divinemc-api/paper-patches/features/0003-Disable-reload-command-by-default.patch similarity index 100% rename from divinemc-api/paper-patches/features/0004-Disable-reload-command-by-default.patch rename to divinemc-api/paper-patches/features/0003-Disable-reload-command-by-default.patch diff --git a/divinemc-server/build.gradle.kts.patch b/divinemc-server/build.gradle.kts.patch index d27dd65..d810c4c 100644 --- a/divinemc-server/build.gradle.kts.patch +++ b/divinemc-server/build.gradle.kts.patch @@ -57,11 +57,17 @@ implementation("ca.spottedleaf:concurrentutil:0.0.3") implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+ implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21 -@@ -176,6 +_,8 @@ +@@ -176,6 +_,14 @@ implementation("org.mozilla:rhino-engine:1.7.14") // Purpur implementation("dev.omega24:upnp4j:1.0") // Purpur -+ implementation("net.objecthunter:exp4j:0.4.8") // DivineMC ++ // DivineMC start - Add DivineMC required dependencies ++ implementation("org.yaml:snakeyaml:1.33") ++ implementation ("me.carleslc.Simple-YAML:Simple-Yaml:1.8.4") { ++ exclude(group="org.yaml", module="snakeyaml") ++ } ++ implementation("net.objecthunter:exp4j:0.4.8") ++ // DivineMC end - Add DivineMC required dependencies + runtimeOnly("org.apache.maven:maven-resolver-provider:3.9.6") runtimeOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18") diff --git a/divinemc-server/paper-patches/features/0002-Configuration.patch b/divinemc-server/paper-patches/features/0002-Configuration.patch index f3d36e0..d6c11c2 100644 --- a/divinemc-server/paper-patches/features/0002-Configuration.patch +++ b/divinemc-server/paper-patches/features/0002-Configuration.patch @@ -5,18 +5,24 @@ Subject: [PATCH] Configuration diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 6a08a42acdb2ee24b5e403b15fb825f3cb49c968..c3c6e23b4da16025d0f6472290183732f5eb9880 100644 +index 6a08a42acdb2ee24b5e403b15fb825f3cb49c968..f4f2473aa844bb245156e391df9f1997bf2013f5 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1103,6 +1103,7 @@ public final class CraftServer implements Server { +@@ -1103,6 +1103,13 @@ public final class CraftServer implements Server { org.spigotmc.SpigotConfig.init((File) this.console.options.valueOf("spigot-settings")); // Spigot this.console.paperConfigurations.reloadConfigs(this.console); org.purpurmc.purpur.PurpurConfig.init((File) console.options.valueOf("purpur-settings")); // Purpur - Purpur config files -+ org.bxteam.divinemc.DivineConfig.init((File) console.options.valueOf("divinemc-settings")); // DivineMC - Configuration ++ // DivineMC start - Configuration ++ try { ++ org.bxteam.divinemc.DivineConfig.init((File) console.options.valueOf("divinemc-settings")); ++ } catch (IOException e) { ++ this.logger.log(Level.WARNING, "Failed to load DivineMC configuration, " + e.getMessage()); ++ } ++ // DivineMC end - Configuration for (ServerLevel world : this.console.getAllLevels()) { // world.serverLevelData.setDifficulty(config.difficulty); // Paper - per level difficulty world.setSpawnSettings(world.serverLevelData.getDifficulty() != Difficulty.PEACEFUL && config.spawnMonsters); // Paper - per level difficulty (from MinecraftServer#setDifficulty(ServerLevel, Difficulty, boolean)) -@@ -1119,6 +1120,7 @@ public final class CraftServer implements Server { +@@ -1119,6 +1126,7 @@ public final class CraftServer implements Server { } world.spigotConfig.init(); // Spigot world.purpurConfig.init(); // Purpur - Purpur config files @@ -24,22 +30,8 @@ index 6a08a42acdb2ee24b5e403b15fb825f3cb49c968..c3c6e23b4da16025d0f6472290183732 } Plugin[] pluginClone = pluginManager.getPlugins().clone(); // Paper -@@ -3134,6 +3136,13 @@ public final class CraftServer implements Server { - } - // Purpur end - Purpur config files - -+ // DivineMC start - Configuration -+ @Override -+ public YamlConfiguration getDivineConfig() { -+ return org.bxteam.divinemc.DivineConfig.config; -+ } -+ // DivineMC end - Configuration -+ - @Override - public void restart() { - org.spigotmc.RestartCommand.restart(); diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 2e1b7f613de8876095ef39bb0341a3f9520c8d5d..5eb36ddf8eea7a84299a91f28a031e2b750975ce 100644 +index bab0d25e82f85c7b9524ae42e0bb41e6233d71cf..f367efa0afae9792f87a842dfe7ba098a3ce7f2d 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -183,6 +183,15 @@ public class Main { diff --git a/divinemc-server/paper-patches/features/0004-Implement-Secure-Seed.patch b/divinemc-server/paper-patches/features/0004-Implement-Secure-Seed.patch index 1f343f3..2caabea 100644 --- a/divinemc-server/paper-patches/features/0004-Implement-Secure-Seed.patch +++ b/divinemc-server/paper-patches/features/0004-Implement-Secure-Seed.patch @@ -25,10 +25,10 @@ index de8b9048c8395c05b8688bc9d984b8ad680f15b3..98bd60111797225f3be5e2a19e25d654 @Override diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 652acceb96843e8242a0989518dec5c65fbcf953..be2859b2bb31bdf342c1e8fb14ccac8b6d215439 100644 +index f5072cf579af02bde4d2f822f4e4b7973f0b7a83..cdd2fa08a813c8cec11472e378a19ce0ab3157c8 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -@@ -1402,7 +1402,11 @@ public final class CraftServer implements Server { +@@ -1408,7 +1408,11 @@ public final class CraftServer implements Server { registryAccess = levelDataAndDimensions.dimensions().dimensionsRegistryAccess(); } else { LevelSettings levelSettings; diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java b/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java index ed6fe4a..fffcb3d 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/DivineConfig.java @@ -1,81 +1,83 @@ package org.bxteam.divinemc; -import com.google.common.base.Throwables; -import com.google.common.collect.ImmutableMap; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.bukkit.Bukkit; -import org.bukkit.command.Command; import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.configuration.MemoryConfiguration; import org.bxteam.divinemc.server.chunk.ChunkSystemAlgorithms; import org.jetbrains.annotations.Nullable; -import org.jspecify.annotations.NullMarked; +import org.simpleyaml.configuration.comments.CommentType; +import org.simpleyaml.configuration.file.YamlFile; +import org.simpleyaml.exceptions.InvalidConfigurationException; + import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.List; -import java.util.Map; import java.util.logging.Level; @SuppressWarnings("unused") -@NullMarked -public final class DivineConfig { // TODO: Remake config system - private DivineConfig() { - throw new IllegalStateException("Utility class"); - } +public class DivineConfig { + private static final String HEADER = """ + This is the main configuration file for DivineMC. + If you need help with the configuration or have any questions related to DivineMC, + join us in our Discord server. - private static final String HEADER = "This is the main configuration file for DivineMC.\n" - + "If you need help with the configuration or have any questions related to DivineMC,\n" - + "join us in our Discord server.\n" - + "\n" - + "Discord: https://discord.gg/p7cxhw7E2M \n" - + "Docs: https://bxteam.org/docs/divinemc \n" - + "New builds: https://github.com/BX-Team/DivineMC/releases/latest"; + Discord: https://discord.gg/p7cxhw7E2M + Docs: https://bxteam.org/docs/divinemc + New builds: https://github.com/BX-Team/DivineMC/releases/latest"""; + + public static final Logger LOGGER = LogManager.getLogger(DivineConfig.class.getSimpleName()); private static File configFile; - public static YamlConfiguration config; + public static final YamlFile config = new YamlFile(); + private static int updates = 0; - private static Map commands; + private static ConfigurationSection convertToBukkit(org.simpleyaml.configuration.ConfigurationSection section) { + ConfigurationSection newSection = new MemoryConfiguration(); + for (String key : section.getKeys(false)) { + if (section.isConfigurationSection(key)) { + newSection.set(key, convertToBukkit(section.getConfigurationSection(key))); + } else { + newSection.set(key, section.get(key)); + } + } + return newSection; + } - public static int version; - static boolean verbose; + public static ConfigurationSection getConfigCopy() { + return convertToBukkit(config); + } - public static void init(File configFile) { + public static int getUpdates() { + return updates; + } + + public static void init(File configFile) throws IOException { DivineConfig.configFile = configFile; - config = new YamlConfiguration(); - try { - config.load(configFile); - } catch (IOException ignored) { - } catch (InvalidConfigurationException ex) { - Bukkit.getLogger().log(Level.SEVERE, "Could not load divinemc.yml, please correct your syntax errors", ex); - throw Throwables.propagate(ex); - } + if (configFile.exists()) { + try { + config.load(configFile); + } catch (InvalidConfigurationException e) { + throw new IOException(e); + } + } + + getString("config.version", "5"); + getBoolean("config.verbose", false); config.options().header(HEADER); config.options().copyDefaults(true); - verbose = getBoolean(config, "verbose", false); - version = getInt(config, "config-version", 5); - set(config, "config-version", 5); + readConfig(configFile, config, DivineConfig.class, null); + } - readConfig(DivineConfig.class, null); - } - - public static void log(String s) { - if (verbose) { - log(Level.INFO, s); - } - } - - public static void log(Level level, String s) { - Bukkit.getLogger().log(level, s); - } - - static void readConfig(Class clazz, @Nullable Object instance) { + public static void readConfig(Class clazz, @Nullable Object instance) { readConfig(configFile, config, clazz, instance); } - public static void readConfig(File configFile, YamlConfiguration config, Class clazz, @Nullable Object instance) { + private static void readConfig(File configFile, YamlFile config, Class clazz, @Nullable Object instance) { for (Method method : clazz.getDeclaredMethods()) { if (!Modifier.isPrivate(method.getModifiers())) continue; if (method.getParameterTypes().length != 0) continue; @@ -85,7 +87,7 @@ public final class DivineConfig { // TODO: Remake config system method.setAccessible(true); method.invoke(instance); } catch (InvocationTargetException ex) { - throw Throwables.propagate(ex.getCause()); + throw new RuntimeException(ex.getCause()); } catch (Exception ex) { Bukkit.getLogger().log(Level.SEVERE, "Error invoking " + method, ex); } @@ -98,91 +100,78 @@ public final class DivineConfig { // TODO: Remake config system } } - private static void set(YamlConfiguration config, String path, Object val, String... comments) { - config.addDefault(path, val); - config.set(path, val); - if (comments.length > 0) { - config.setComments(path, List.of(comments)); - } + private static void setComment(String key, String... comment) { + if (config.contains(key)) { + config.setComment(key, String.join("\n", comment), CommentType.BLOCK); + } + } + + private static void ensureDefault(String key, Object defaultValue, String... comment) { + if (!config.contains(key)) { + config.set(key, defaultValue); + if (comment.length > 0) config.setComment(key, String.join("\n", comment), CommentType.BLOCK); + } + } + + private static boolean getBoolean(String key, boolean defaultValue, String... comment) { + return getBoolean(key, null, defaultValue, comment); + } + + private static boolean getBoolean(String key, @Nullable String oldKey, boolean defaultValue, String... comment) { + ensureDefault(key, defaultValue, comment); + return config.getBoolean(key, defaultValue); + } + + private static int getInt(String key, int defaultValue, String... comment) { + return getInt(key, null, defaultValue, comment); + } + + private static int getInt(String key, @Nullable String oldKey, int defaultValue, String... comment) { + ensureDefault(key, defaultValue, comment); + return config.getInt(key, defaultValue); + } + + private static double getDouble(String key, double defaultValue, String... comment) { + return getDouble(key, null, defaultValue, comment); + } + + private static double getDouble(String key, @Nullable String oldKey, double defaultValue, String... comment) { + ensureDefault(key, defaultValue, comment); + return config.getDouble(key, defaultValue); + } + + private static long getLong(String key, long defaultValue, String... comment) { + return getLong(key, null, defaultValue, comment); } - private static String getString(YamlConfiguration config, String path, String def, String... comments) { - config.addDefault(path, def); - if (comments.length > 0) { - config.setComments(path, List.of(comments)); - } - return config.getString(path, config.getString(path)); + private static long getLong(String key, @Nullable String oldKey, long defaultValue, String... comment) { + ensureDefault(key, defaultValue, comment); + return config.getLong(key, defaultValue); } - private static boolean getBoolean(YamlConfiguration config, String path, boolean def, String... comments) { - config.addDefault(path, def); - if (comments.length > 0) { - config.setComments(path, List.of(comments)); - } - return config.getBoolean(path, config.getBoolean(path)); - } + private static String getString(String key, String defaultValue, String... comment) { + return getOldString(key, null, defaultValue, comment); + } - private static double getDouble(YamlConfiguration config, String path, double def, String... comments) { - config.addDefault(path, def); - if (comments.length > 0) { - config.setComments(path, List.of(comments)); - } - return config.getDouble(path, config.getDouble(path)); - } + private static String getOldString(String key, @Nullable String oldKey, String defaultValue, String... comment) { + ensureDefault(key, defaultValue, comment); + return config.getString(key, defaultValue); + } - private static int getInt(YamlConfiguration config, String path, int def, String... comments) { - config.addDefault(path, def); - if (comments.length > 0) { - config.setComments(path, List.of(comments)); - } - return config.getInt(path, config.getInt(path)); - } + private static List getStringList(String key, List defaultValue, String... comment) { + return getStringList(key, null, defaultValue, comment); + } - private static long getLong(YamlConfiguration config, String path, long def, String... comments) { - config.addDefault(path, def); - if (comments.length > 0) { - config.setComments(path, List.of(comments)); - } - return config.getLong(path, config.getLong(path)); - } - - private static List getList(YamlConfiguration config, String path, List def, String... comments) { - config.addDefault(path, def); - if (comments.length > 0) { - config.setComments(path, List.of(comments)); - } - return (List) config.getList(path, def); - } - - static Map getMap(YamlConfiguration config, String path, Map def, String... comments) { - if (def != null && config.getConfigurationSection(path) == null) { - config.addDefault(path, def); - return def; - } - if (comments.length > 0) { - config.setComments(path, List.of(comments)); - } - return toMap(config.getConfigurationSection(path)); - } - - private static Map toMap(ConfigurationSection section) { - ImmutableMap.Builder builder = ImmutableMap.builder(); - if (section != null) { - for (String key : section.getKeys(false)) { - Object obj = section.get(key); - if (obj != null) { - builder.put(key, obj instanceof ConfigurationSection val ? toMap(val) : obj); - } - } - } - return builder.build(); - } + private static List getStringList(String key, @Nullable String oldKey, List defaultValue, String... comment) { + ensureDefault(key, defaultValue, comment); + return config.getStringList(key); + } public static int parallelThreadCount = 4; public static boolean logContainerCreationStacktraces = false; private static void parallelWorldTicking() { - parallelThreadCount = getInt(config, "settings.parallel-world-ticking.thread-count", parallelThreadCount); - logContainerCreationStacktraces = getBoolean(config, "settings.parallel-world-ticking.log-container-creation-stacktraces", logContainerCreationStacktraces); + parallelThreadCount = getInt("settings.parallel-world-ticking.thread-count", parallelThreadCount); + logContainerCreationStacktraces = getBoolean("settings.parallel-world-ticking.log-container-creation-stacktraces", logContainerCreationStacktraces); } public static boolean nativeAccelerationEnabled = true; @@ -197,38 +186,37 @@ public final class DivineConfig { // TODO: Remake config system public static boolean enableDensityFunctionCompiler = false; public static boolean enableStructureLayoutOptimizer = true; public static boolean deduplicateShuffledTemplatePoolElementList = false; - private static void chunkGeneration() { - nativeAccelerationEnabled = getBoolean(config, "settings.chunk-generation.native-acceleration-enabled", nativeAccelerationEnabled); + nativeAccelerationEnabled = getBoolean("settings.chunk-generation.native-acceleration-enabled", nativeAccelerationEnabled); - allowAVX512 = getBoolean(config, "settings.chunk-generation.allow-avx512", allowAVX512, + allowAVX512 = getBoolean("settings.chunk-generation.allow-avx512", allowAVX512, "Enables AVX512 support for natives-math optimizations"); - isaTargetLevelOverride = getInt(config, "settings.chunk-generation.isa-target-level-override", isaTargetLevelOverride, + isaTargetLevelOverride = getInt("settings.chunk-generation.isa-target-level-override", isaTargetLevelOverride, "Overrides the ISA target located by the native loader, which allows forcing AVX512 (must be a value between 6-9 for AVX512 support).", "Value must be between 1-9, and -1 to disable override"); if (isaTargetLevelOverride < -1 || isaTargetLevelOverride > 9) { - log(Level.WARNING, "Invalid ISA target level override: " + isaTargetLevelOverride + ", resetting to -1"); + LOGGER.warn("Invalid ISA target level override: " + isaTargetLevelOverride + ", resetting to -1"); isaTargetLevelOverride = -1; } - chunkDataCacheSoftLimit = getLong(config, "settings.chunk-generation.chunk-data-cache-soft-limit", chunkDataCacheSoftLimit); - chunkDataCacheLimit = getLong(config, "settings.chunk-generation.chunk-data-cache-limit", chunkDataCacheLimit); - maxViewDistance = getInt(config, "settings.chunk-generation.max-view-distance", maxViewDistance, + chunkDataCacheSoftLimit = getLong("settings.chunk-generation.chunk-data-cache-soft-limit", chunkDataCacheSoftLimit); + chunkDataCacheLimit = getLong("settings.chunk-generation.chunk-data-cache-limit", chunkDataCacheLimit); + maxViewDistance = getInt("settings.chunk-generation.max-view-distance", maxViewDistance, "Changes the maximum view distance for the server, allowing clients to have render distances higher than 32"); - chunkWorkerAlgorithm = ChunkSystemAlgorithms.valueOf(getString(config, "settings.chunk-generation.chunk-worker-algorithm", chunkWorkerAlgorithm.name(), + chunkWorkerAlgorithm = ChunkSystemAlgorithms.valueOf(getString("settings.chunk-generation.chunk-worker-algorithm", chunkWorkerAlgorithm.name(), "Modifies what algorithm the chunk system will use to define thread counts. values: MOONRISE, C2ME, C2ME_AGGRESSIVE")); - threadPoolPriority = getInt(config, "settings.chunk-generation.thread-pool-priority", threadPoolPriority, + threadPoolPriority = getInt("settings.chunk-generation.thread-pool-priority", threadPoolPriority, "Sets the priority of the thread pool used for chunk generation"); - enableSecureSeed = getBoolean(config, "settings.misc.enable-secure-seed", enableSecureSeed, + enableSecureSeed = getBoolean("settings.misc.enable-secure-seed", enableSecureSeed, "This feature is based on Secure Seed mod by Earthcomputer.", "", "Terrain and biome generation remains the same, but all the ores and structures are generated with 1024-bit seed, instead of the usual 64-bit seed.", "This seed is almost impossible to crack, and there are no weird links between structures."); - enableDensityFunctionCompiler = getBoolean(config, "settings.chunk-generation.experimental.enable-density-function-compiler", enableDensityFunctionCompiler, + enableDensityFunctionCompiler = getBoolean("settings.chunk-generation.experimental.enable-density-function-compiler", enableDensityFunctionCompiler, "Whether to use density function compiler to accelerate world generation", "", "Density function: https://minecraft.wiki/w/Density_function", @@ -241,9 +229,9 @@ public final class DivineConfig { // TODO: Remake config system "Please test if this optimization actually benefits your server, as", "it can sometimes slow down chunk performance than speed it up."); - enableStructureLayoutOptimizer = getBoolean(config, "settings.chunk-generation.experimental.enable-structure-layout-optimizer", enableStructureLayoutOptimizer, + enableStructureLayoutOptimizer = getBoolean("settings.chunk-generation.experimental.enable-structure-layout-optimizer", enableStructureLayoutOptimizer, "Enables a port of the mod StructureLayoutOptimizer, which optimizes general Jigsaw structure generation"); - deduplicateShuffledTemplatePoolElementList = getBoolean(config, "settings.chunk-generation.experimental.deduplicate-shuffled-template-pool-element-list", deduplicateShuffledTemplatePoolElementList, + deduplicateShuffledTemplatePoolElementList = getBoolean("settings.chunk-generation.experimental.deduplicate-shuffled-template-pool-element-list", deduplicateShuffledTemplatePoolElementList, "Whether to use an alternative strategy to make structure layouts generate slightly even faster than", "the default optimization this mod has for template pool weights. This alternative strategy works by", "changing the list of pieces that structures collect from the template pool to not have duplicate entries.", @@ -258,26 +246,24 @@ public final class DivineConfig { // TODO: Remake config system public static boolean ignoreMovedTooQuicklyWhenLagging = true; public static boolean alwaysAllowWeirdMovement = true; public static boolean updateSuppressionCrashFix = true; - private static void miscSettings() { - skipUselessSecondaryPoiSensor = getBoolean(config, "settings.misc.skip-useless-secondary-poi-sensor", skipUselessSecondaryPoiSensor); - clumpOrbs = getBoolean(config, "settings.misc.clump-orbs", clumpOrbs, + skipUselessSecondaryPoiSensor = getBoolean("settings.misc.skip-useless-secondary-poi-sensor", skipUselessSecondaryPoiSensor); + clumpOrbs = getBoolean("settings.misc.clump-orbs", clumpOrbs, "Clumps experience orbs together to reduce entity count"); - ignoreMovedTooQuicklyWhenLagging = getBoolean(config, "settings.misc.ignore-moved-too-quickly-when-lagging", ignoreMovedTooQuicklyWhenLagging, + ignoreMovedTooQuicklyWhenLagging = getBoolean("settings.misc.ignore-moved-too-quickly-when-lagging", ignoreMovedTooQuicklyWhenLagging, "Improves general gameplay experience of the player when the server is lagging, as they won't get lagged back (message 'moved too quickly')"); - alwaysAllowWeirdMovement = getBoolean(config, "settings.misc.always-allow-weird-movement", alwaysAllowWeirdMovement, + alwaysAllowWeirdMovement = getBoolean("settings.misc.always-allow-weird-movement", alwaysAllowWeirdMovement, "Means ignoring messages like 'moved too quickly' and 'moved wrongly'"); - updateSuppressionCrashFix = getBoolean(config, "settings.misc.update-suppression-crash-fix", updateSuppressionCrashFix); + updateSuppressionCrashFix = getBoolean("settings.misc.update-suppression-crash-fix", updateSuppressionCrashFix); } public static boolean enableFasterTntOptimization = true; public static boolean explosionNoBlockDamage = false; public static double tntRandomRange = -1; - private static void tntOptimization() { - enableFasterTntOptimization = getBoolean(config, "settings.tnt-optimization.enable-faster-tnt-optimization", enableFasterTntOptimization); - explosionNoBlockDamage = getBoolean(config, "settings.tnt-optimization.explosion-no-block-damage", explosionNoBlockDamage); - tntRandomRange = getDouble(config, "settings.tnt-optimization.tnt-random-range", tntRandomRange); + enableFasterTntOptimization = getBoolean("settings.tnt-optimization.enable-faster-tnt-optimization", enableFasterTntOptimization); + explosionNoBlockDamage = getBoolean("settings.tnt-optimization.explosion-no-block-damage", explosionNoBlockDamage); + tntRandomRange = getDouble("settings.tnt-optimization.tnt-random-range", tntRandomRange); } public static boolean lagCompensationEnabled = true; @@ -290,18 +276,17 @@ public final class DivineConfig { // TODO: Remake config system public static boolean portalAcceleration = true; public static boolean timeAcceleration = true; public static boolean randomTickSpeedAcceleration = true; - private static void lagCompensation() { - lagCompensationEnabled = getBoolean(config, "settings.lag-compensation.enabled", lagCompensationEnabled, "Improves the player experience when TPS is low"); - blockEntityAcceleration = getBoolean(config, "settings.lag-compensation.block-entity-acceleration", blockEntityAcceleration); - blockBreakingAcceleration = getBoolean(config, "settings.lag-compensation.block-breaking-acceleration", blockBreakingAcceleration); - eatingAcceleration = getBoolean(config, "settings.lag-compensation.eating-acceleration", eatingAcceleration); - potionEffectAcceleration = getBoolean(config, "settings.lag-compensation.potion-effect-acceleration", potionEffectAcceleration); - fluidAcceleration = getBoolean(config, "settings.lag-compensation.fluid-acceleration", fluidAcceleration); - pickupAcceleration = getBoolean(config, "settings.lag-compensation.pickup-acceleration", pickupAcceleration); - portalAcceleration = getBoolean(config, "settings.lag-compensation.portal-acceleration", portalAcceleration); - timeAcceleration = getBoolean(config, "settings.lag-compensation.time-acceleration", timeAcceleration); - randomTickSpeedAcceleration = getBoolean(config, "settings.lag-compensation.random-tick-speed-acceleration", randomTickSpeedAcceleration); + lagCompensationEnabled = getBoolean("settings.lag-compensation.enabled", lagCompensationEnabled, "Improves the player experience when TPS is low"); + blockEntityAcceleration = getBoolean("settings.lag-compensation.block-entity-acceleration", blockEntityAcceleration); + blockBreakingAcceleration = getBoolean("settings.lag-compensation.block-breaking-acceleration", blockBreakingAcceleration); + eatingAcceleration = getBoolean("settings.lag-compensation.eating-acceleration", eatingAcceleration); + potionEffectAcceleration = getBoolean("settings.lag-compensation.potion-effect-acceleration", potionEffectAcceleration); + fluidAcceleration = getBoolean("settings.lag-compensation.fluid-acceleration", fluidAcceleration); + pickupAcceleration = getBoolean("settings.lag-compensation.pickup-acceleration", pickupAcceleration); + portalAcceleration = getBoolean("settings.lag-compensation.portal-acceleration", portalAcceleration); + timeAcceleration = getBoolean("settings.lag-compensation.time-acceleration", timeAcceleration); + randomTickSpeedAcceleration = getBoolean("settings.lag-compensation.random-tick-speed-acceleration", randomTickSpeedAcceleration); } public static boolean noChatReportsEnabled = false; @@ -310,29 +295,27 @@ public final class DivineConfig { // TODO: Remake config system public static boolean noChatReportsDebugLog = false; public static boolean noChatReportsDemandOnClient = false; public static String noChatReportsDisconnectDemandOnClientMessage = "You do not have No Chat Reports, and this server is configured to require it on client!"; - private static void noChatReports() { - noChatReportsEnabled = getBoolean(config, "settings.no-chat-reports.enabled", noChatReportsEnabled, + noChatReportsEnabled = getBoolean("settings.no-chat-reports.enabled", noChatReportsEnabled, "Enables or disables the No Chat Reports feature"); - noChatReportsAddQueryData = getBoolean(config, "settings.no-chat-reports.add-query-data", noChatReportsAddQueryData, + noChatReportsAddQueryData = getBoolean("settings.no-chat-reports.add-query-data", noChatReportsAddQueryData, "Should server include extra query data to help clients know that your server is secure"); - noChatReportsConvertToGameMessage = getBoolean(config, "settings.no-chat-reports.convert-to-game-message", noChatReportsConvertToGameMessage, + noChatReportsConvertToGameMessage = getBoolean("settings.no-chat-reports.convert-to-game-message", noChatReportsConvertToGameMessage, "Should the server convert all player messages to system messages"); - noChatReportsDebugLog = getBoolean(config, "settings.no-chat-reports.debug-log", noChatReportsDebugLog); - noChatReportsDemandOnClient = getBoolean(config, "settings.no-chat-reports.demand-on-client", noChatReportsDemandOnClient, + noChatReportsDebugLog = getBoolean("settings.no-chat-reports.debug-log", noChatReportsDebugLog); + noChatReportsDemandOnClient = getBoolean("settings.no-chat-reports.demand-on-client", noChatReportsDemandOnClient, "Should the server require No Chat Reports on the client side"); - noChatReportsDisconnectDemandOnClientMessage = getString(config, "settings.no-chat-reports.disconnect-demand-on-client-message", noChatReportsDisconnectDemandOnClientMessage, + noChatReportsDisconnectDemandOnClientMessage = getString("settings.no-chat-reports.disconnect-demand-on-client-message", noChatReportsDisconnectDemandOnClientMessage, "Message to send to the client when they are disconnected for not having No Chat Reports"); } public static boolean asyncPathfinding = true; public static int asyncPathfindingMaxThreads = 2; public static int asyncPathfindingKeepalive = 60; - private static void asyncPathfinding() { - asyncPathfinding = getBoolean(config, "settings.async-pathfinding.enable", asyncPathfinding); - asyncPathfindingMaxThreads = getInt(config, "settings.async-pathfinding.max-threads", asyncPathfindingMaxThreads); - asyncPathfindingKeepalive = getInt(config, "settings.async-pathfinding.keepalive", asyncPathfindingKeepalive); + asyncPathfinding = getBoolean("settings.async-pathfinding.enable", asyncPathfinding); + asyncPathfindingMaxThreads = getInt("settings.async-pathfinding.max-threads", asyncPathfindingMaxThreads); + asyncPathfindingKeepalive = getInt("settings.async-pathfinding.keepalive", asyncPathfindingKeepalive); if (asyncPathfindingMaxThreads < 0) { asyncPathfindingMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() + asyncPathfindingMaxThreads, 1); @@ -351,12 +334,11 @@ public final class DivineConfig { // TODO: Remake config system public static boolean multithreadedCompatModeEnabled = false; public static int asyncEntityTrackerMaxThreads = 1; public static int asyncEntityTrackerKeepalive = 60; - private static void multithreadedTracker() { - multithreadedEnabled = getBoolean(config, "settings.multithreaded-tracker.enable", multithreadedEnabled); - multithreadedCompatModeEnabled = getBoolean(config, "settings.multithreaded-tracker.compat-mode", multithreadedCompatModeEnabled); - asyncEntityTrackerMaxThreads = getInt(config, "settings.multithreaded-tracker.max-threads", asyncEntityTrackerMaxThreads); - asyncEntityTrackerKeepalive = getInt(config, "settings.multithreaded-tracker.keepalive", asyncEntityTrackerKeepalive); + multithreadedEnabled = getBoolean("settings.multithreaded-tracker.enable", multithreadedEnabled); + multithreadedCompatModeEnabled = getBoolean("settings.multithreaded-tracker.compat-mode", multithreadedCompatModeEnabled); + asyncEntityTrackerMaxThreads = getInt("settings.multithreaded-tracker.max-threads", asyncEntityTrackerMaxThreads); + asyncEntityTrackerKeepalive = getInt("settings.multithreaded-tracker.keepalive", asyncEntityTrackerKeepalive); if (asyncEntityTrackerMaxThreads < 0) { asyncEntityTrackerMaxThreads = Math.max(Runtime.getRuntime().availableProcessors() + asyncEntityTrackerMaxThreads, 1); diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/DivineWorldConfig.java b/divinemc-server/src/main/java/org/bxteam/divinemc/DivineWorldConfig.java index fc4b847..5f1f59e 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/DivineWorldConfig.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/DivineWorldConfig.java @@ -1,19 +1,14 @@ package org.bxteam.divinemc; import org.bukkit.World; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.YamlConfiguration; -import org.jspecify.annotations.NullMarked; +import org.simpleyaml.configuration.file.YamlFile; import java.util.List; import java.util.Map; -import static org.bxteam.divinemc.DivineConfig.log; - @SuppressWarnings("unused") -@NullMarked -public final class DivineWorldConfig { - private final YamlConfiguration config; +public class DivineWorldConfig { + private final YamlFile config; private final String worldName; private final World.Environment environment; @@ -25,52 +20,46 @@ public final class DivineWorldConfig { } public void init() { - log("-------- World Settings For [" + worldName + "] --------"); DivineConfig.readConfig(DivineWorldConfig.class, this); } private void set(String path, Object val) { - this.config.addDefault("world-settings.default." + path, val); - this.config.set("world-settings.default." + path, val); - if (this.config.get("world-settings." + worldName + "." + path) != null) { - this.config.addDefault("world-settings." + worldName + "." + path, val); - this.config.set("world-settings." + worldName + "." + path, val); + this.config.addDefault("settings.world-settings.default." + path, val); + this.config.set("settings.world-settings.default." + path, val); + if (this.config.get("settings.world-settings." + worldName + "." + path) != null) { + this.config.addDefault("settings.world-settings." + worldName + "." + path, val); + this.config.set("settings.world-settings." + worldName + "." + path, val); } } - private ConfigurationSection getConfigurationSection(String path) { - ConfigurationSection section = this.config.getConfigurationSection("world-settings." + worldName + "." + path); - return section != null ? section : this.config.getConfigurationSection("world-settings.default." + path); - } - private String getString(String path, String def) { - this.config.addDefault("world-settings.default." + path, def); - return this.config.getString("world-settings." + worldName + "." + path, this.config.getString("world-settings.default." + path)); + this.config.addDefault("settings.world-settings.default." + path, def); + return this.config.getString("settings.world-settings." + worldName + "." + path, this.config.getString("settings.world-settings.default." + path)); } private boolean getBoolean(String path, boolean def) { - this.config.addDefault("world-settings.default." + path, def); - return this.config.getBoolean("world-settings." + worldName + "." + path, this.config.getBoolean("world-settings.default." + path)); + this.config.addDefault("settings.world.default." + path, def); + return this.config.getBoolean("settings.world-settings." + worldName + "." + path, this.config.getBoolean("settings.world-settings.default." + path)); } private double getDouble(String path, double def) { - this.config.addDefault("world-settings.default." + path, def); - return this.config.getDouble("world-settings." + worldName + "." + path, this.config.getDouble("world-settings.default." + path)); + this.config.addDefault("settings.world-settings.default." + path, def); + return this.config.getDouble("settings.world-settings." + worldName + "." + path, this.config.getDouble("settings.world-settings.default." + path)); } private int getInt(String path, int def) { - this.config.addDefault("world-settings.default." + path, def); - return this.config.getInt("world-settings." + worldName + "." + path, this.config.getInt("world-settings.default." + path)); + this.config.addDefault("settings.world-settings.default." + path, def); + return this.config.getInt("settings.world-settings." + worldName + "." + path, this.config.getInt("settings.world-settings.default." + path)); } private List getList(String path, T def) { - this.config.addDefault("world-settings.default." + path, def); - return this.config.getList("world-settings." + worldName + "." + path, this.config.getList("world-settings.default." + path)); + this.config.addDefault("settings.world-settings.default." + path, def); + return this.config.getList("settings.world-settings." + worldName + "." + path, this.config.getList("settings.world-settings.default." + path)); } private Map getMap(String path, Map def) { - final Map fallback = this.getMap("world-settings.default." + path, def); - final Map value = this.getMap("world-settings." + worldName + "." + path, null); + final Map fallback = this.getMap("settings.world-settings.default." + path, def); + final Map value = this.getMap("settings.world-settings." + worldName + "." + path, null); return value.isEmpty() ? fallback : value; } diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/command/subcommands/ReloadCommand.java b/divinemc-server/src/main/java/org/bxteam/divinemc/command/subcommands/ReloadCommand.java index 9efae38..f4bc27b 100644 --- a/divinemc-server/src/main/java/org/bxteam/divinemc/command/subcommands/ReloadCommand.java +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/command/subcommands/ReloadCommand.java @@ -11,6 +11,7 @@ import org.bxteam.divinemc.command.DivineSubCommandPermission; import org.bxteam.divinemc.DivineConfig; import java.io.File; +import java.io.IOException; import static net.kyori.adventure.text.Component.text; import static net.kyori.adventure.text.format.NamedTextColor.GREEN; @@ -35,12 +36,18 @@ public final class ReloadCommand extends DivineSubCommandPermission { Command.broadcastCommandMessage(sender, text("If you encounter any issues please use the /stop command to restart your server.", RED)); MinecraftServer server = ((CraftServer) sender.getServer()).getServer(); - DivineConfig.init((File) server.options.valueOf("divinemc-settings")); - for (ServerLevel level : server.getAllLevels()) { - level.divineConfig.init(); - level.resetBreedingCooldowns(); - } - server.server.reloadCount++; + + try { + DivineConfig.init((File) server.options.valueOf("divinemc-settings")); + } catch (IOException e) { + MinecraftServer.LOGGER.error("Failed to reload DivineMC config", e); + } + + for (ServerLevel level : server.getAllLevels()) { + level.divineConfig.init(); + level.resetBreedingCooldowns(); + } + server.server.reloadCount++; Command.broadcastCommandMessage(sender, text("DivineMC config reload complete.", GREEN)); }