From 48557c6af9ecc97fd7e64001eeadb07b5075e15c Mon Sep 17 00:00:00 2001 From: kuwacom Date: Wed, 11 Mar 2026 20:38:25 +0900 Subject: [PATCH] update: add world size config to dedicated server properties --- Minecraft.Server/ServerProperties.cpp | 131 ++++++++++++++++++++++ Minecraft.Server/ServerProperties.h | 6 + Minecraft.Server/Windows64/ServerMain.cpp | 29 +++++ 3 files changed, 166 insertions(+) diff --git a/Minecraft.Server/ServerProperties.cpp b/Minecraft.Server/ServerProperties.cpp index c93abc6ea..83233a25c 100644 --- a/Minecraft.Server/ServerProperties.cpp +++ b/Minecraft.Server/ServerProperties.cpp @@ -5,6 +5,7 @@ #include "ServerLogger.h" #include "Common\\StringUtils.h" #include "Common\\FileUtils.h" +#include "..\\Minecraft.World\\ChunkSource.h" #include #include @@ -61,6 +62,7 @@ static const ServerPropertyDefault kServerPropertyDefaults[] = { "level-name", "world" }, { "level-seed", "" }, { "level-type", "default" }, + { "world-size", "classic" }, { "log-level", "info" }, { "max-build-height", "256" }, { "max-players", "8" }, @@ -605,6 +607,128 @@ static std::string ReadNormalizedLevelTypeProperty( return normalized; } +static std::string WorldSizeToPropertyValue(int worldSize) +{ + switch (worldSize) + { + case e_worldSize_Small: + return "small"; + case e_worldSize_Medium: + return "medium"; + case e_worldSize_Large: + return "large"; + case e_worldSize_Classic: + default: + return "classic"; + } +} + +static int WorldSizeToXzChunks(int worldSize) +{ + switch (worldSize) + { + case e_worldSize_Small: + return LEVEL_WIDTH_SMALL; + case e_worldSize_Medium: + return LEVEL_WIDTH_MEDIUM; + case e_worldSize_Large: + return LEVEL_WIDTH_LARGE; + case e_worldSize_Classic: + default: + return LEVEL_WIDTH_CLASSIC; + } +} + +static int WorldSizeToHellScale(int worldSize) +{ + switch (worldSize) + { + case e_worldSize_Small: + return HELL_LEVEL_SCALE_SMALL; + case e_worldSize_Medium: + return HELL_LEVEL_SCALE_MEDIUM; + case e_worldSize_Large: + return HELL_LEVEL_SCALE_LARGE; + case e_worldSize_Classic: + default: + return HELL_LEVEL_SCALE_CLASSIC; + } +} + +static bool TryParseWorldSize(const std::string &lowered, int *outWorldSize) +{ + if (outWorldSize == NULL) + { + return false; + } + + if (lowered == "classic" || lowered == "54" || lowered == "1") + { + *outWorldSize = e_worldSize_Classic; + return true; + } + if (lowered == "small" || lowered == "64" || lowered == "2") + { + *outWorldSize = e_worldSize_Small; + return true; + } + if (lowered == "medium" || lowered == "192" || lowered == "3") + { + *outWorldSize = e_worldSize_Medium; + return true; + } + if (lowered == "large" || lowered == "320" || lowered == "4") + { + *outWorldSize = e_worldSize_Large; + return true; + } + + return false; +} + +static int ReadNormalizedWorldSizeProperty( + std::unordered_map *properties, + const char *key, + int defaultWorldSize, + int *outXzChunks, + int *outHellScale, + bool *shouldWrite) +{ + std::string raw = TrimAscii((*properties)[key]); + std::string lowered = ToLowerAscii(raw); + + int worldSize = defaultWorldSize; + if (!raw.empty()) + { + int parsedWorldSize = defaultWorldSize; + if (TryParseWorldSize(lowered, &parsedWorldSize)) + { + worldSize = parsedWorldSize; + } + } + + std::string normalized = WorldSizeToPropertyValue(worldSize); + if (raw != normalized) + { + (*properties)[key] = normalized; + if (shouldWrite != NULL) + { + *shouldWrite = true; + } + } + + if (outXzChunks != NULL) + { + *outXzChunks = WorldSizeToXzChunks(worldSize); + } + if (outHellScale != NULL) + { + *outHellScale = WorldSizeToHellScale(worldSize); + } + + return worldSize; +} + /** * **Load Effective Server Properties Config** * @@ -702,6 +826,13 @@ ServerPropertiesConfig LoadServerPropertiesConfig() config.difficulty = ReadNormalizedIntProperty(&merged, "difficulty", 1, 0, 3, &shouldWrite); config.gameMode = ReadNormalizedIntProperty(&merged, "gamemode", 0, 0, 1, &shouldWrite); + config.worldSize = ReadNormalizedWorldSizeProperty( + &merged, + "world-size", + e_worldSize_Classic, + &config.worldSizeChunks, + &config.worldHellScale, + &shouldWrite); config.levelType = ReadNormalizedLevelTypeProperty(&merged, "level-type", &config.levelTypeFlat, &shouldWrite); config.generateStructures = ReadNormalizedBoolProperty(&merged, "generate-structures", true, &shouldWrite); config.bonusChest = ReadNormalizedBoolProperty(&merged, "bonus-chest", false, &shouldWrite); diff --git a/Minecraft.Server/ServerProperties.h b/Minecraft.Server/ServerProperties.h index 50db845c7..28261b5cd 100644 --- a/Minecraft.Server/ServerProperties.h +++ b/Minecraft.Server/ServerProperties.h @@ -39,6 +39,12 @@ namespace ServerRuntime /** host options / game settings */ int difficulty; int gameMode; + /** `world-size` preset (`classic` / `small` / `medium` / `large`) */ + int worldSize; + /** Overworld chunk width derived from `world-size` */ + int worldSizeChunks; + /** Nether scale derived from `world-size` */ + int worldHellScale; bool levelTypeFlat; bool generateStructures; bool bonusChest; diff --git a/Minecraft.Server/Windows64/ServerMain.cpp b/Minecraft.Server/Windows64/ServerMain.cpp index 6b32fa1ec..92864ffcf 100644 --- a/Minecraft.Server/Windows64/ServerMain.cpp +++ b/Minecraft.Server/Windows64/ServerMain.cpp @@ -24,6 +24,7 @@ #include "../../Minecraft.World/AABB.h" #include "../../Minecraft.World/Vec3.h" #include "../../Minecraft.World/IntCache.h" +#include "../../Minecraft.World/ChunkSource.h" #include "../../Minecraft.World/TilePos.h" #include "../../Minecraft.World/compression.h" #include "../../Minecraft.World/OldChunkStorage.h" @@ -62,6 +63,9 @@ struct DedicatedServerConfig char bindIP[256]; char name[17]; int maxPlayers; + int worldSize; + int worldSizeChunks; + int worldHellScale; __int64 seed; ServerRuntime::EServerLogLevel logLevel; bool hasSeed; @@ -300,6 +304,9 @@ static void ApplyServerPropertiesToDedicatedConfig(const ServerPropertiesConfig serverProperties.serverName.empty() ? "DedicatedServer" : serverProperties.serverName.c_str(), _TRUNCATE); config->maxPlayers = serverProperties.maxPlayers; + config->worldSize = serverProperties.worldSize; + config->worldSizeChunks = serverProperties.worldSizeChunks; + config->worldHellScale = serverProperties.worldHellScale; config->logLevel = serverProperties.logLevel; config->hasSeed = serverProperties.hasSeed; config->seed = serverProperties.seed; @@ -346,6 +353,9 @@ int main(int argc, char **argv) strncpy_s(config.bindIP, sizeof(config.bindIP), "0.0.0.0", _TRUNCATE); strncpy_s(config.name, sizeof(config.name), "DedicatedServer", _TRUNCATE); config.maxPlayers = MINECRAFT_NET_MAX_PLAYERS; + config.worldSize = e_worldSize_Classic; + config.worldSizeChunks = LEVEL_WIDTH_CLASSIC; + config.worldHellScale = HELL_LEVEL_SCALE_CLASSIC; config.seed = 0; config.logLevel = ServerRuntime::eServerLogLevel_Info; config.hasSeed = false; @@ -398,6 +408,14 @@ int main(int argc, char **argv) accessShutdownGuard.Activate(); LogInfof("startup", "LAN advertise: %s", serverProperties.lanAdvertise ? "enabled" : "disabled"); LogInfof("startup", "Whitelist: %s", serverProperties.whiteListEnabled ? "enabled" : "disabled"); +#ifdef _LARGE_WORLDS + LogInfof( + "startup", + "World size preset: %d (xz=%d, hell-scale=%d)", + config.worldSize, + config.worldSizeChunks, + config.worldHellScale); +#endif LogStartupStep("registering hidden window class"); HINSTANCE hInstance = GetModuleHandle(NULL); @@ -509,6 +527,13 @@ int main(int argc, char **argv) app.SetGameHostOption(eGameHostOption_DoTileDrops, serverProperties.doTileDrops ? 1 : 0); app.SetGameHostOption(eGameHostOption_NaturalRegeneration, serverProperties.naturalRegeneration ? 1 : 0); app.SetGameHostOption(eGameHostOption_DoDaylightCycle, serverProperties.doDaylightCycle ? 1 : 0); +#ifdef _LARGE_WORLDS + app.SetGameHostOption(eGameHostOption_WorldSize, serverProperties.worldSize); + // Apply desired target size for loading existing worlds. + // Expansion happens only when target size is larger than current level size. + app.SetGameNewWorldSize(serverProperties.worldSizeChunks, true); + app.SetGameNewHellScale(serverProperties.worldHellScale); +#endif StorageManager.SetSaveDisabled(serverProperties.disableSaving); // Read world name and fixed save-id from server.properties @@ -549,6 +574,10 @@ int main(int argc, char **argv) { param->seed = config.seed; } +#ifdef _LARGE_WORLDS + param->xzSize = (unsigned int)config.worldSizeChunks; + param->hellScale = (unsigned char)config.worldHellScale; +#endif param->saveData = worldBootstrap.saveData; param->settings = app.GetGameHostOption(eGameHostOption_All); param->dedicatedNoLocalHostPlayer = true;