From 27877938bc452e46c1d43c70006455950c2a732b Mon Sep 17 00:00:00 2001 From: Chaoscaot Date: Fri, 12 Jun 2026 12:29:56 +0200 Subject: [PATCH] Add support for GameMode templates and YAML-based configuration handling in DevCommand. Signed-off-by: Chaoscaot --- CLI/build.gradle.kts | 1 + CLI/src/commands/dev/DevCommand.kt | 71 ++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/CLI/build.gradle.kts b/CLI/build.gradle.kts index f27d16b8..9629fc04 100644 --- a/CLI/build.gradle.kts +++ b/CLI/build.gradle.kts @@ -18,6 +18,7 @@ dependencies { implementation("com.github.ajalt.clikt:clikt:5.0.3") implementation("com.github.ajalt.mordant:mordant:3.0.2") implementation(libs.logback) + implementation("org.yaml:snakeyaml:2.2") implementation("org.mariadb.jdbc:mariadb-java-client:3.3.1") implementation(libs.exposedCore) diff --git a/CLI/src/commands/dev/DevCommand.kt b/CLI/src/commands/dev/DevCommand.kt index f0b14c53..0cc75728 100644 --- a/CLI/src/commands/dev/DevCommand.kt +++ b/CLI/src/commands/dev/DevCommand.kt @@ -14,9 +14,11 @@ import com.github.ajalt.clikt.parameters.types.file import com.github.ajalt.clikt.parameters.types.long import com.github.ajalt.clikt.parameters.types.path import com.sun.security.auth.module.UnixSystem +import org.yaml.snakeyaml.Yaml import java.io.File import kotlin.io.path.absolute import kotlin.io.path.absolutePathString +import kotlin.random.Random const val LOG4J_CONFIG = """ @@ -69,32 +71,42 @@ class DevCommand : CliktCommand("dev") { override fun run() { val args = mutableListOf() - val serverDirectory = File(workingDir, server) - val serverDir = - if (serverDirectory.exists() && serverDirectory.isDirectory) serverDirectory else File(workingDir, server) + var serverDir = resolveServerDirectory(server) if (isVelocity(server)) { runServer( args, jvmArgs, listOf( jar?.absolutePath - ?: File("/jar/Velocity.jar").absolutePath + ?: File("/jars/Velocity.jar").absolutePath ), serverDir ) } else { setLogConfig(args) val version = findVersion(server) ?: throw CliktError("Unknown Server Version") + val gameModeTemplate = if (serverDir.isDirectory) null else loadGameModeTemplate(server) + if (gameModeTemplate != null) { + serverDir = gameModeTemplate.serverDir + args += "-Dconfig=$server.yml" + } val worldFile = world?.absolute()?.toFile() - ?: File(serverDir, "devtempworld") - val jarFile = jar?.absolutePath + ?: File(workingDir, "devtempworld") + var jarFile = jar?.absolutePath ?: additionalVersions[server]?.let { supportedVersionJars[it] } ?: supportedVersionJars[version] ?: throw CliktError("Unknown Server Version") + if (gameModeTemplate != null) { + jarFile = if (gameModeTemplate.spigot) { + jarFile.replace("paper", "spigot") + } else { + jarFile.replace("spigot", "paper") + } + } if (!worldFile.exists()) { - val templateFile = File(serverDir, "Bauwelt") + val templateFile = gameModeTemplate?.worldTemplate ?: File(serverDir, "Bauwelt") if (!templateFile.exists()) { - throw CliktError("World Template not found!") + throw CliktError("Could not find world template: ${templateFile.absolutePath}") } templateFile.copyRecursively(worldFile) } @@ -123,6 +135,12 @@ class DevCommand : CliktCommand("dev") { } } + data class GameModeTemplate( + val serverDir: File, + val worldTemplate: File, + val spigot: Boolean + ) + val jvmDefaultParams = arrayOf( "-Xmx1G", "-Xgc:excessiveGCratio=80", @@ -165,6 +183,41 @@ class DevCommand : CliktCommand("dev") { fun isVelocity(server: String): Boolean = server.endsWith("Velocity") + fun resolveServerDirectory(server: String): File { + val localServer = File(workingDir, server) + if (localServer.isDirectory) { + return localServer + } + return File("/servers", server) + } + + fun loadGameModeTemplate(server: String): GameModeTemplate? { + val configFile = File("/configs/GameModes/$server.yml") + if (!configFile.exists()) { + throw CliktError("Server/GameMode not found") + } + + val document = configFile.reader().use { reader -> + Yaml().load>(reader) + } ?: throw CliktError("GameMode config is empty: ${configFile.absolutePath}") + val serverConfig = document["Server"] as? Map<*, *> + ?: throw CliktError("GameMode config is missing Server section: ${configFile.absolutePath}") + val folder = serverConfig["Folder"] as? String + ?: throw CliktError("GameMode config is missing Server.Folder: ${configFile.absolutePath}") + val maps = (serverConfig["Maps"] as? List<*>) + ?.filterIsInstance() + ?.takeIf { it.isNotEmpty() } + ?: throw CliktError("GameMode config is missing Server.Maps: ${configFile.absolutePath}") + + val serverDir = File("/servers", folder) + val worldTemplate = File(File(serverDir, "arenas"), maps[Random.nextInt(maps.size)]) + return GameModeTemplate( + serverDir = serverDir, + worldTemplate = worldTemplate, + spigot = serverConfig["Spigot"] == true + ) + } + fun setLogConfig(args: MutableList) { args += "-DlogPath=${workingDir.absolutePath}/logs" args += "-Dlog4j.configurationFile=${log4jConfig.absolutePath}" @@ -190,4 +243,4 @@ class DevCommand : CliktCommand("dev") { Runtime.getRuntime().addShutdownHook(Thread { if (process.isAlive) process.destroyForcibly() }) process.waitFor() } -} \ No newline at end of file +}