From 9460ffe32c902858ec414b9339df59c236037b1a Mon Sep 17 00:00:00 2001 From: Ben Willenbring Date: Sun, 9 May 2021 18:47:57 +0200 Subject: [PATCH] feat: add option to load a specific world for aa runs --- README.md | 22 +++++++++++++++------- example/speedrun.json | 3 ++- src/adapter/serverProperties.ts | 23 ++++++++++++----------- src/model/configuration.ts | 1 + src/server.ts | 16 ++++++++++------ 5 files changed, 40 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 10f649e..1c9c115 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,14 @@ # Minecraft Speedrun Server -This project provides a better startup for a speedrun server as it automatically: +This project provides a better startup for a speedrun server as it can automatically: -- Deletes the world folder after stopping the server -- Restarts the server -- Turns off auto-save to prevent the lag every 5 minutes -- Moves datapacks to the world folder **(optional)** -- Sets the seed from a list of seeds sequentially **(optional)** +- Delete the world folder after stopping the server +- Rename the world folder after stopping the server to persist previously played worlds +- Restart the server +- Turn off auto-save to prevent the lag every 5 minutes +- Move datapacks to the world folder +- Set the seed from a list of seeds sequentially +- Load a specific world for All Advancement runs ## Prerequisites @@ -36,7 +38,8 @@ _Note: Enabling flight will prevent random disconnects when traveling too fast v "DATA_PACK": false, // set to true, if datapacks should be copied into the world "SEEDS": ["-9223372036854775808", "9223372036854775807"], // List of set seeds that are played one by one, set [] to disable this option "AUTO_SAVE": false, // Turn off to prevent 5 minute lag, default false - "KEEP_WORLDS": false // Turn on if worlds should be renamed instead of deleted, default false + "KEEP_WORLDS": false, // Turn on if worlds should be renamed instead of deleted, default false + "LOAD_WORLD": "world_2021-05-21_15-31-24" // Set world folder name that should be loaded on server start, leave empty ("") to disable } ``` @@ -49,3 +52,8 @@ minecraft server and put the unzipped datapacks inside and enable it in the `spe Add seeds to the `SEEDS` list, if you want to restart the world with set seeds. On each restart, the first seed of the list will be loaded and removed from the list. This is really helpful, if you want to do some speedrun battles with a pool of set seeds. + +### All Advancements + +Set `AUTO_SAVE` and `KEEP_WORLDS` to `true` while resetting for a good seed. Once a playable seed is found, +set `LOAD_WORLD` to the world folder name of that world to prevent future resets. diff --git a/example/speedrun.json b/example/speedrun.json index cb6239d..6491139 100644 --- a/example/speedrun.json +++ b/example/speedrun.json @@ -6,5 +6,6 @@ "DATA_PACK": false, "SEEDS": ["-9223372036854775808", "9223372036854775807"], "AUTO_SAVE": false, - "KEEP_WORLDS": false + "KEEP_WORLDS": false, + "LOAD_WORLD": "world_2021-05-21_15-31-24" } diff --git a/src/adapter/serverProperties.ts b/src/adapter/serverProperties.ts index 89f1b5b..7667221 100644 --- a/src/adapter/serverProperties.ts +++ b/src/adapter/serverProperties.ts @@ -16,20 +16,22 @@ export async function initSeed(seeds: string[], configuration: Configuration) { } } +export async function setWorld(world: string) { + console.log(`Setting world ${world} ...`) + const serverProperties = await promises.readFile(FILE_NAME, "utf-8") + await setProperty(serverProperties, "level-name", world) +} + async function setSeed(seed) { console.log(`Setting seed ${seed} ...`) const serverProperties = await promises.readFile(FILE_NAME, "utf-8") - const updated = getUpdatedServerProperties(serverProperties, seed) - - await promises.writeFile(FILE_NAME, updated, "utf-8") + await setProperty(serverProperties, "level-seed", seed) } async function resetSeed() { console.log("Resetting seed ...") const serverProperties = await promises.readFile(FILE_NAME, "utf-8") - const updated = getUpdatedServerProperties(serverProperties) - - await promises.writeFile(FILE_NAME, updated, "utf-8") + await setProperty(serverProperties, "level-seed") } async function seedExists() { @@ -41,10 +43,9 @@ async function seedExists() { return end - start > 1 } -function getUpdatedServerProperties(serverProperties: string, seed: string = "") { - const key = "level-seed=" - const start = serverProperties.indexOf(key) + key.length +async function setProperty(serverProperties: string, key: string, value: string = "") { + const start = serverProperties.indexOf(key) + key.length + 1 const end = serverProperties.indexOf("\n", start) - - return serverProperties.substring(0, start) + seed + serverProperties.substring(end) + const updated = serverProperties.substring(0, start) + value + serverProperties.substring(end) + await promises.writeFile(FILE_NAME, updated, "utf-8") } diff --git a/src/model/configuration.ts b/src/model/configuration.ts index 23f0da2..6a945ea 100644 --- a/src/model/configuration.ts +++ b/src/model/configuration.ts @@ -7,4 +7,5 @@ export interface Configuration { SEEDS: string[] AUTO_SAVE: boolean KEEP_WORLDS: boolean + LOAD_WORLD: string } diff --git a/src/server.ts b/src/server.ts index 909514b..e8d958d 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,21 +1,25 @@ import { ChildProcess, spawn } from "child_process" import shell from "shelljs" import { parseConfiguration } from "./adapter/configuration" -import { initSeed } from "./adapter/serverProperties" +import { initSeed, setWorld } from "./adapter/serverProperties" import { deleteWorldFolder, renameWorldFolder } from "./adapter/world" async function startServer() { setupErrorListeners() const configuration = await parseConfiguration() - const { MIN_RAM, MAX_RAM, OP, WHITELIST, DATA_PACK, SEEDS, AUTO_SAVE, KEEP_WORLDS } = configuration + const { MIN_RAM, MAX_RAM, OP, WHITELIST, DATA_PACK, SEEDS, AUTO_SAVE, KEEP_WORLDS, LOAD_WORLD } = configuration - if (KEEP_WORLDS) { - renameWorldFolder() + if (LOAD_WORLD) { + await setWorld(LOAD_WORLD) } else { - deleteWorldFolder() + if (KEEP_WORLDS) { + renameWorldFolder() + } else { + deleteWorldFolder() + } + await initSeed(SEEDS, configuration) } - await initSeed(SEEDS, configuration) const server = spawn("java", [`-Xms${MIN_RAM}G`, `-Xmx${MAX_RAM}G`, "-jar", "server.jar", "nogui"]) redirectStdio(server)