diff --git a/divinemc-server/paper-patches/features/0002-Configuration.patch b/divinemc-server/paper-patches/features/0002-Configuration.patch index f99c7eb..1c85f1f 100644 --- a/divinemc-server/paper-patches/features/0002-Configuration.patch +++ b/divinemc-server/paper-patches/features/0002-Configuration.patch @@ -4,8 +4,21 @@ Date: Mon, 27 Jan 2025 20:53:24 +0300 Subject: [PATCH] Configuration +diff --git a/src/main/java/io/papermc/paper/SparksFly.java b/src/main/java/io/papermc/paper/SparksFly.java +index 62e2d5704c348955bc8284dc2d54c933b7bcdd06..341f13e57896f03058ea3ec68e69b7cb946ce3fc 100644 +--- a/src/main/java/io/papermc/paper/SparksFly.java ++++ b/src/main/java/io/papermc/paper/SparksFly.java +@@ -42,7 +42,7 @@ public final class SparksFly { + this.mainThreadTaskQueue = new ConcurrentLinkedQueue<>(); + this.logger = Logger.getLogger(ID); + this.logger.log(Level.INFO, "This server bundles the spark profiler. For more information please visit https://docs.papermc.io/paper/profiling"); +- this.spark = PaperSparkModule.create(Compatibility.VERSION_1_0, server, this.logger, new PaperScheduler() { ++ this.spark = org.bxteam.divinemc.spark.DivineSparkPlugin.create(Compatibility.VERSION_1_0, server, this.logger, new PaperScheduler() { // DivineMC - use own spark module + @Override + public void executeAsync(final Runnable runnable) { + MCUtil.scheduleAsyncTask(this.catching(runnable, "asynchronous")); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 6a08a42acdb2ee24b5e403b15fb825f3cb49c968..e51fd95bad5038ec7c1b85babf29799d443f9b8b 100644 +index f87062cdaf4e02e51904f275913907c0269f4d41..037ca6ea2edb3c4ff9bf9f7856360cd2c19b7628 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -1103,6 +1103,13 @@ public final class CraftServer implements Server { diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/spark/DivineServerConfigProvider.java b/divinemc-server/src/main/java/org/bxteam/divinemc/spark/DivineServerConfigProvider.java new file mode 100644 index 0000000..12c1985 --- /dev/null +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/spark/DivineServerConfigProvider.java @@ -0,0 +1,137 @@ +package org.bxteam.divinemc.spark; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializer; +import me.lucko.spark.paper.common.platform.serverconfig.ConfigParser; +import me.lucko.spark.paper.common.platform.serverconfig.ExcludedConfigFilter; +import me.lucko.spark.paper.common.platform.serverconfig.PropertiesConfigParser; +import me.lucko.spark.paper.common.platform.serverconfig.ServerConfigProvider; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.configuration.MemorySection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; +import org.jspecify.annotations.Nullable; +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; + +public class DivineServerConfigProvider extends ServerConfigProvider { + private static final Map FILES; + private static final Collection HIDDEN_PATHS; + + public DivineServerConfigProvider() { + super(FILES, HIDDEN_PATHS); + } + + private static class YamlConfigParser implements ConfigParser { + public static final YamlConfigParser INSTANCE = new YamlConfigParser(); + protected static final Gson GSON = new GsonBuilder() + .registerTypeAdapter(MemorySection.class, (JsonSerializer) (obj, type, ctx) -> ctx.serialize(obj.getValues(false))) + .create(); + + @Override + public JsonElement load(String file, ExcludedConfigFilter filter) throws IOException { + Map values = this.parse(Paths.get(file)); + if (values == null) { + return null; + } + + return filter.apply(GSON.toJsonTree(values)); + } + + @Override + public Map parse(BufferedReader reader) { + YamlConfiguration config = YamlConfiguration.loadConfiguration(reader); + return config.getValues(false); + } + } + + private static class SplitYamlConfigParser extends YamlConfigParser { + public static final SplitYamlConfigParser INSTANCE = new SplitYamlConfigParser(); + + @Override + @Nullable + public JsonElement load(@NotNull String group, ExcludedConfigFilter filter) throws IOException { + String prefix = group.replace("/", ""); + + Path configDir = Paths.get("config"); + if (!Files.exists(configDir)) { + return null; + } + + JsonObject root = new JsonObject(); + + for (Map.Entry entry : getNestedFiles(configDir, prefix).entrySet()) { + String fileName = entry.getKey(); + Path path = entry.getValue(); + + Map values = this.parse(path); + if (values == null) { + continue; + } + + root.add(fileName, filter.apply(GSON.toJsonTree(values))); + } + + return root; + } + + @NotNull + private static Map getNestedFiles(@NotNull Path configDir, String prefix) { + Map files = new LinkedHashMap<>(); + files.put("global.yml", configDir.resolve(prefix + "-global.yml")); + files.put("world-defaults.yml", configDir.resolve(prefix + "-world-defaults.yml")); + for (World world : Bukkit.getWorlds()) { + files.put(world.getName() + ".yml", world.getWorldFolder().toPath().resolve(prefix + "-world.yml")); + } + return files; + } + } + + static { + ImmutableMap.Builder files = ImmutableMap.builder() + .put("server.properties", PropertiesConfigParser.INSTANCE) + .put("bukkit.yml", YamlConfigParser.INSTANCE) + .put("spigot.yml", YamlConfigParser.INSTANCE) + .put("paper.yml", YamlConfigParser.INSTANCE) + .put("paper/", SplitYamlConfigParser.INSTANCE) + .put("pufferfish.yml", YamlConfigParser.INSTANCE) + .put("purpur.yml", YamlConfigParser.INSTANCE) + .put("divinemc.yml", YamlConfigParser.INSTANCE); + + for (String config : getSystemPropertyList("spark.serverconfigs.extra")) { + files.put(config, YamlConfigParser.INSTANCE); + } + + ImmutableSet.Builder hiddenPaths = ImmutableSet.builder() + .add("database") + .add("settings.bungeecord-addresses") + .add("settings.velocity-support.secret") + .add("proxies.velocity.secret") + .add("server-ip") + .add("motd") + .add("resource-pack") + .add("rconpassword") + .add("rconip") + .add("level-seed") + .add("world-settings.*.feature-seeds") + .add("world-settings.*.seed-*") + .add("feature-seeds") + .add("seed-*") + .addAll(getSystemPropertyList("spark.serverconfigs.hiddenpaths")); + + FILES = files.build(); + HIDDEN_PATHS = hiddenPaths.build(); + } +} diff --git a/divinemc-server/src/main/java/org/bxteam/divinemc/spark/DivineSparkPlugin.java b/divinemc-server/src/main/java/org/bxteam/divinemc/spark/DivineSparkPlugin.java new file mode 100644 index 0000000..52665a6 --- /dev/null +++ b/divinemc-server/src/main/java/org/bxteam/divinemc/spark/DivineSparkPlugin.java @@ -0,0 +1,27 @@ +package org.bxteam.divinemc.spark; + +import me.lucko.spark.paper.PaperSparkPlugin; +import me.lucko.spark.paper.api.Compatibility; +import me.lucko.spark.paper.api.PaperClassLookup; +import me.lucko.spark.paper.api.PaperScheduler; +import me.lucko.spark.paper.common.platform.serverconfig.ServerConfigProvider; +import org.bukkit.Server; +import org.jetbrains.annotations.NotNull; + +import java.util.logging.Logger; + +public class DivineSparkPlugin extends PaperSparkPlugin { + @NotNull + public static DivineSparkPlugin create(Compatibility ignoredCompatibility, Server server, Logger logger, PaperScheduler scheduler, PaperClassLookup classLookup) { + return new DivineSparkPlugin(server, logger, scheduler, classLookup); + } + + public DivineSparkPlugin(Server server, Logger logger, PaperScheduler scheduler, PaperClassLookup classLookup) { + super(server, logger, scheduler, classLookup); + } + + @Override + public ServerConfigProvider createServerConfigProvider() { + return new DivineServerConfigProvider(); + } +}