From 80372ff02ff4ad66efc1d2526b285b9ab8b9692d Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Fri, 17 Oct 2025 13:01:58 -0500 Subject: [PATCH 01/50] Add files via upload --- renown.kvp | 4 +- renownconfig.json | 1406 +++++++++++++++++++++++++++--------- renownengine.ini | 65 ++ renowngame.ini | 77 +- renowngameusersettings.ini | 2 + renownmetaconfig.json | 50 +- renownupdates.json | 133 ++-- 7 files changed, 1335 insertions(+), 402 deletions(-) create mode 100644 renownengine.ini create mode 100644 renowngameusersettings.ini diff --git a/renown.kvp b/renown.kvp index 9ec34646f..eb4b30410 100644 --- a/renown.kvp +++ b/renown.kvp @@ -11,7 +11,7 @@ Meta.ConfigManifest=renownconfig.json Meta.MetaConfigManifest=renownmetaconfig.json Meta.ConfigRoot=renown.kvp Meta.MinAMPVersion=2.6.2.8 -Meta.SpecificDockerImage=cubecoders/ampbase:debian +Meta.SpecificDockerImage= Meta.DockerRequired=False Meta.DockerBaseReadOnly=False Meta.ContainerPolicy=Supported @@ -24,7 +24,7 @@ Meta.NoCommercialUsage=False Meta.ConfigVersion=2 Meta.ReleaseNotes= Meta.BreakingReleaseNotes= -Meta.AppConfigId=3a94e6c8-e0f9-4008-afc8-903c7e372bad +Meta.AppConfigId=3a94e6c8-e0f9-4008-afc8-903c7e37da2b Meta.ImportableExtensions=[".ini"] Meta.AppIsMultiIPAware=False App.DisplayName=Renown diff --git a/renownconfig.json b/renownconfig.json index d3992a084..63ecbf0eb 100644 --- a/renownconfig.json +++ b/renownconfig.json @@ -1,325 +1,1085 @@ [ - { - "DisplayName": "Enable RCON", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "", - "Keywords": "", - "FieldName": "EnableRCON", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.EnableRCON", - "Hidden": true, - "DefaultValue": "True", - "ExcludeFromImport": true, - "EnumValues": {} - }, - { - "DisplayName": "RCON Password", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "", - "Keywords": "", - "FieldName": "$RemoteAdminPassword", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONPassword", - "Hidden": true, - "ExcludeFromImport": true, - "EnumValues": {} - }, - { - "DisplayName": "RCON Port", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "", - "Keywords": "", - "FieldName": "$RCONPort", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONPort", - "Hidden": true, - "ExcludeFromImport": true, - "EnumValues": {} - }, - { - "DisplayName": "Server Name", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the name of the server that is displayed in the server browser", - "Keywords": "server,name,ServerName", - "FieldName": "ServerName", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.ServerName", - "DefaultValue": "AMP Powered Renown Server", - "Placeholder": "AMP Powered Renown Server", - "EnumValues": {} - }, - { - "DisplayName": "Server Region", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the region tag for the server as shown in the server browser. The official tags appear in the dropdown. If 'Custom' is selected, Custom Server Region must also be set", - "Keywords": "region", - "FieldName": "Region", - "InputType": "enum", - "ParamFieldName": "Region", - "DefaultValue": "US Central", - "EnumValues": { - "US East": "US East", - "US West": "US West", - "US Central": "US Central", - "Europe": "Europe", - "South America": "South America", - "Asia": "Asia", - "Oceania": "Oceania", - "{{CustomRegion}}": "--Custom--" - } - }, - { - "DisplayName": "Custom Server Region", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets a custom region tag for the server, if 'Custom' is selected under Server Region", - "Keywords": "custom,region", - "FieldName": "CustomRegion", - "InputType": "text", - "ParamFieldName": "CustomRegion", - "DefaultValue": "", - "Placeholder": "Modded", - "EnumValues": {} - }, - { - "DisplayName": "Make Server Private", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "If set, the server will not be listed in the server browser and can only be joined via direct connect", - "Keywords": "private,session,PrivateSession", - "FieldName": "PrivateSession", - "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.PrivateSession", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Server MOTD", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the message of the day (MOTD) shown to players when they join", - "Keywords": "motd,message,day", - "FieldName": "MOTD", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MOTD", - "DefaultValue": "Welome to my server!", - "EnumValues": {} - }, - { - "DisplayName": "Server Password", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the password required to join the server. Empty = no password", - "Keywords": "server,password,ServerPassword", - "FieldName": "ServerPassword", - "InputType": "password", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.ServerPassword", - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Admin Password", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the password for server admins in-game", - "Keywords": "admin,password,AdminPassword", - "FieldName": "AdminPassword", - "InputType": "password", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.AdminPassword", - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Player Limit", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the maximum number of players allowed on the server at one time", - "Keywords": "max,players,MaxPlayers", - "FieldName": "$MaxUsers", - "InputType": "number", - "MinValue": "1", - "MaxValue": "100", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxPlayers", - "DefaultValue": "40", - "Placeholder": "40", - "Suffix": "players", - "EnumValues": {} - }, - { - "DisplayName": "Player Limit", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "", - "Keywords": "", - "FieldName": "$MaxUsers", - "InputType": "number", - "ParamFieldName": "/Script/Engine.GameSession.MaxPlayers", - "Hidden": true, - "EnumValues": {} - }, - { - "DisplayName": "Map Rotation", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Map rotations can be set in Game.ini. Format: MapRotation=RSurv-AlgaraIsle_p. One map entry per line", - "Keywords": "map,rotation,MapRotation", - "FieldName": "MapRotation", - "InputType": "hidden", - "ParamFieldName": "MapRotation", - "EnumValues": {} - }, - { - "DisplayName": "Game Save Name", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the name of the game save", - "Keywords": "game,save,name,GameSaveName", - "FieldName": "GameSaveName", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.GameSaveName", - "DefaultValue": "Save 1", - "Placeholder": "Save 1", - "Required": true, - "EnumValues": {} - }, - { - "DisplayName": "Maximum Ping", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the maximum ping allowed for players to join the server. 0 = no limit", - "Keywords": "max,ping,MaxPing", - "FieldName": "MaxPing", - "InputType": "number", - "MinValue": "0", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxPing", - "DefaultValue": "180", - "Placeholder": "180", - "EnumValues": {} - }, - { - "DisplayName": "RCON Chat Messages Limit", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the limit for RCON chat messages", - "Keywords": "rcon,chat,messages,limit", - "FieldName": "RCONChatMessagesLimit", - "InputType": "number", - "MinValue": "0", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONChatMessagesLimit", - "DefaultValue": "30", - "Placeholder": "30", - "EnumValues": {} - }, - { - "DisplayName": "Network Maximum Tick Rate", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the maximum tick rate for the server's network driver", - "Keywords": "net,server,tick,rate,NetServerMaxTickRate", - "FieldName": "NetServerMaxTickRate", - "InputType": "number", - "MinValue": "1", - "ParamFieldName": "ini:Engine:[Script/SteamSockets.SteamSocketsNetDriver]:NetServerMaxTickRate", - "IncludeInCommandLine": true, - "SkipIfEmpty": true, - "DefaultValue": "30", - "Placeholder": "30", - "EnumValues": {} - }, - { - "DisplayName": "Resource Gain Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Sets the multiplier for resource gain, which determines how much players gather from resources", - "Keywords": "resource,gain,multiplier,ResourceGainMultiplier", - "FieldName": "ResourceGainMultiplier", - "InputType": "number", - "MinValue": "0", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.ResourceGainMultiplier", - "DefaultValue": "1", - "Placeholder": "1", - "EnumValues": {} - }, - { - "DisplayName": "Gold Coin Gain Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Sets the multiplier for gold coin gain, which determines how much gold players earn", - "Keywords": "gold,coin,gain,multiplier,GoldCoinGainMultiplier", - "FieldName": "GoldCoinGainMultiplier", - "InputType": "number", - "MinValue": "0", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GoldCoinGainMultiplier", - "DefaultValue": "1", - "Placeholder": "1", - "EnumValues": {} - }, - { - "DisplayName": "Global Crafting Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Sets the multiplier for crafting speed globally", - "Keywords": "crafting,multiplier,global,CraftingSpeedMultiplier", - "FieldName": "GlobalCraftingMultiplier", - "InputType": "number", - "MinValue": "0", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalCraftingMultiplier", - "DefaultValue": "1", - "Placeholder": "1", - "EnumValues": {} - }, - { - "DisplayName": "Global Smelting Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Sets the multiplier for smelting speed globally", - "Keywords": "smelting,multiplier,global,GlobalSmeltingMultiplier", - "FieldName": "GlobalSmeltingMultiplier", - "InputType": "number", - "MinValue": "0", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalSmeltingMultiplier", - "DefaultValue": "1", - "Placeholder": "1", - "EnumValues": {} - }, - { - "DisplayName": "Enable First Person Only", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "If set, the server will enforce first-person-only gameplay", - "Keywords": "first,person,only,Server.FirstPersonOnly", - "FieldName": "Server.FirstPersonOnly", - "InputType": "checkbox", - "ParamFieldName": "ini:Engine:[SystemSettings]:Server.FirstPersonOnly", - "IncludeInCommandLine": true, - "SkipIfEmpty": true, - "DefaultValue": "0", - "EnumValues": { - "False": "0", - "True": "1" - } - }, - { - "DisplayName": "Server Release Version", - "Category": "Updates", - "Subcategory": "Steam Downloads:download", - "Description": "Sets the server release version to install. Update the server after changing this setting", - "Keywords": "server,version,public,beta", - "FieldName": "ServerVersion", - "InputType": "enum", - "ParamFieldName": "ServerVersion", - "DefaultValue": "public", - "EnumValues": { - "public": "Public (default)", - "beta": "Beta" - } + { + "DisplayName": "Enable RCON", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "", + "Keywords": "", + "FieldName": "EnableRCON", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.EnableRCON", + "Hidden": true, + "DefaultValue": "True", + "ExcludeFromImport": true, + "EnumValues": {} + }, + { + "DisplayName": "RCON Password", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "", + "Keywords": "", + "FieldName": "$RemoteAdminPassword", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONPassword", + "Hidden": true, + "ExcludeFromImport": true, + "EnumValues": {} + }, + { + "DisplayName": "RCON Port", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "", + "Keywords": "", + "FieldName": "$RCONPort", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONPort", + "Hidden": true, + "ExcludeFromImport": true, + "EnumValues": {} + }, + { + "DisplayName": "Server Name", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the name of the server that is displayed in the server browser", + "Keywords": "server,name,ServerName", + "FieldName": "ServerName", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.ServerName", + "DefaultValue": "AMP Powered Renown Server", + "Placeholder": "AMP Powered Renown Server", + "EnumValues": {} + }, + { + "DisplayName": "Server Region", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the region tag for the server as shown in the server browser. The official tags appear in the dropdown. If 'Custom' is selected, Custom Server Region must also be set", + "Keywords": "region", + "FieldName": "Region", + "InputType": "enum", + "ParamFieldName": "Region", + "DefaultValue": "US Central", + "EnumValues": { + "US East": "US East", + "US West": "US West", + "US Central": "US Central", + "Europe": "Europe", + "South America": "South America", + "Asia": "Asia", + "Oceania": "Oceania", + "{{CustomRegion}}": "--Custom--" } -] \ No newline at end of file + }, + { + "DisplayName": "Custom Server Region", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets a custom region tag for the server, if 'Custom' is selected under Server Region", + "Keywords": "custom,region", + "FieldName": "CustomRegion", + "InputType": "text", + "ParamFieldName": "CustomRegion", + "DefaultValue": "", + "Placeholder": "Modded", + "EnumValues": {} + }, + { + "DisplayName": "Make Server Private", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "If set, the server will not be listed in the server browser and can only be joined via direct connect", + "Keywords": "private,session,PrivateSession", + "FieldName": "PrivateSession", + "InputType": "checkbox", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.PrivateSession", + "DefaultValue": "False", + "EnumValues": { "False": "False", "True": "True" } + }, + { + "DisplayName": "Server MOTD", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the message of the day (MOTD) shown to players when they join", + "Keywords": "motd,message,day", + "FieldName": "MOTD", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MOTD", + "DefaultValue": "NSLOCTEXT(\"[2CF2D1E04F419B14490A65BF06750767]\", \"F67B0BE94A3C4A2665B05284056D0757\", \"Welcome to Renown, in order to play on this server you must accept the following Rules.\\r\\n\\r\\n1. **Respect and Courtesy**: Treat fellow players and staff with respect. Harassment, hate speech, or any form of discrimination will not be tolerated.\\r\\n\\r\\n2. **Cheating and Exploits**: Any use of cheats, hacks, exploits, or any unfair advantage is strictly prohibited. Players found violating this rule will face severe consequences, including permanent bans.\\r\\n\\r\\n3. **Language and Content**: Keep chat and in-game communication appropriate for all ages. Avoid using offensive language, explicit content, or engaging in discussions that may make others uncomfortable.\\r\\n\\r\\n4. **No Spamming or Advertising**: Do not spam chat with repetitive messages or advertise external services or products without permission from server staff.\\r\\n\\r\\n5. **Bug Reporting**: If you encounter any bugs or issues, report them to server staff or file a bug report promptly. Exploiting or abusing bugs for personal gain is not allowed.\\r\\n\\r\\n6. **Impersonation**: Do not impersonate server staff or other players. This includes using similar names or pretending to have authority you do not possess.\\r\\n\\r\\n7. **Final Authority**: Server staff have the final say in all matters concerning rule enforcement and disciplinary actions. Respect their decisions and cooperate with them at all times.\\r\\n\\r\\nRemember, these rules are in place to ensure a fair, enjoyable, and respectful gaming environment for all players. Violating these rules may result in warnings, temporary suspensions, or permanent bans, depending on the severity of the offense. Enjoy your time on the server and have fun gaming!\")", + "EnumValues": {} + }, + { + "DisplayName": "Server Password", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the password required to join the server. Empty = no password", + "Keywords": "server,password,ServerPassword", + "FieldName": "ServerPassword", + "InputType": "password", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.ServerPassword", + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Admin Password", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the password for server admins in-game", + "Keywords": "admin,password,AdminPassword", + "FieldName": "AdminPassword", + "InputType": "password", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.AdminPassword", + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Player Limit", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the maximum number of players allowed on the server at one time", + "Keywords": "max,players,MaxPlayers", + "FieldName": "$MaxUsers", + "InputType": "number", + "MinValue": "1", + "MaxValue": "1000", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxPlayers", + "DefaultValue": "40", + "Placeholder": "40", + "Suffix": "players", + "EnumValues": {} + }, + { + "DisplayName": "Player Limit", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "", + "Keywords": "", + "FieldName": "$MaxUsers", + "InputType": "number", + "ParamFieldName": "/Script/Engine.GameSession.MaxPlayers", + "Hidden": true, + "EnumValues": {} + }, + { + "DisplayName": "Map Rotation (Game.ini)", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Map rotations can be set in Game.ini. Format: MapRotation=RSurv-AlgaraIsle_p. One map entry per line", + "Keywords": "map,rotation,MapRotation", + "FieldName": "MapRotation", + "InputType": "hidden", + "ParamFieldName": "MapRotation", + "EnumValues": {} + }, + { + "DisplayName": "Game Save Name", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the name of the game save", + "Keywords": "game,save,name,GameSaveName", + "FieldName": "GameSaveName", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.GameSaveName", + "DefaultValue": "Save 1", + "Placeholder": "Save 1", + "Required": true, + "EnumValues": {} + }, + { + "DisplayName": "Maximum Ping (Game.ini)", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the maximum ping allowed for players to join the server. 0 = no limit", + "Keywords": "max,ping,MaxPing", + "FieldName": "MaxPing", + "InputType": "number", + "MinValue": "0", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxPing", + "DefaultValue": "180", + "Placeholder": "180", + "EnumValues": {} + }, + { + "DisplayName": "RCON Chat Messages Limit", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the limit for RCON chat messages", + "Keywords": "rcon,chat,messages,limit", + "FieldName": "RCONChatMessagesLimit", + "InputType": "number", + "MinValue": "0", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONChatMessagesLimit", + "DefaultValue": "30", + "Placeholder": "30", + "EnumValues": {} + }, + { + "DisplayName": "Network Maximum Tick Rate (SteamSockets)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Sets the maximum tick rate for the server's SteamSockets network driver", + "Keywords": "net,server,tick,rate,NetServerMaxTickRate", + "FieldName": "NetServerMaxTickRate", + "InputType": "number", + "MinValue": "1", + "ParamFieldName": "ini:Engine:[Script/SteamSockets.SteamSocketsNetDriver]:NetServerMaxTickRate", + "IncludeInCommandLine": true, + "SkipIfEmpty": true, + "DefaultValue": "30", + "Placeholder": "30", + "EnumValues": {} + }, + { + "DisplayName": "Resource Gain Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Sets the multiplier for resource gain, which determines how much players gather from resources", + "Keywords": "resource,gain,multiplier,ResourceGainMultiplier", + "FieldName": "ResourceGainMultiplier", + "InputType": "number", + "MinValue": "0", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.ResourceGainMultiplier", + "DefaultValue": "1", + "Placeholder": "1", + "EnumValues": {} + }, + { + "DisplayName": "Gold Coin Gain Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Sets the multiplier for gold coin gain, which determines how much gold players earn", + "Keywords": "gold,coin,gain,multiplier,GoldCoinGainMultiplier", + "FieldName": "GoldCoinGainMultiplier", + "InputType": "number", + "MinValue": "0", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GoldCoinGainMultiplier", + "DefaultValue": "1", + "Placeholder": "1", + "EnumValues": {} + }, + { + "DisplayName": "Global Crafting Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Sets the multiplier for crafting speed globally", + "Keywords": "crafting,multiplier,global,CraftingSpeedMultiplier", + "FieldName": "GlobalCraftingMultiplier", + "InputType": "number", + "MinValue": "0", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalCraftingMultiplier", + "DefaultValue": "1", + "Placeholder": "1", + "EnumValues": {} + }, + { + "DisplayName": "Global Smelting Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Sets the multiplier for smelting speed globally", + "Keywords": "smelting,multiplier,global,GlobalSmeltingMultiplier", + "FieldName": "GlobalSmeltingMultiplier", + "InputType": "number", + "MinValue": "0", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalSmeltingMultiplier", + "DefaultValue": "1", + "Placeholder": "1", + "EnumValues": {} + }, + { + "DisplayName": "Enable First Person Only", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "If set, the server will enforce first-person-only gameplay", + "Keywords": "first,person,only,Server.FirstPersonOnly", + "FieldName": "Server.FirstPersonOnly", + "InputType": "checkbox", + "ParamFieldName": "ini:Engine:[SystemSettings]:Server.FirstPersonOnly", + "IncludeInCommandLine": true, + "SkipIfEmpty": true, + "DefaultValue": "0", + "EnumValues": { "False": "0", "True": "1" } + }, + + // ===== Added: Remaining Game.ini keys (GameInstance) ===== + { + "DisplayName": "RCON Server Max Uptime (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "If set, server will reboot after this uptime when commanded via RCON", + "Keywords": "RCON,uptime,reboot", + "FieldName": "RCON_ServerMaxUptime", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCON_ServerMaxUptime", + "DefaultValue": "1800", + "EnumValues": {} + }, + { + "DisplayName": "Max Server Uptime (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Hard cap on server uptime before auto-restart", + "Keywords": "max,uptime,restart", + "FieldName": "MaxServerUptime", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxServerUptime", + "DefaultValue": "28800", + "EnumValues": {} + }, + { + "DisplayName": "Public Listing", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Show this server in the public server browser", + "Keywords": "public,listing", + "FieldName": "Public", + "InputType": "checkbox", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.Public", + "DefaultValue": "True", + "EnumValues": { "False": "False", "True": "True" } + }, + { + "DisplayName": "LAN Mode", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Run the server in LAN mode (not internet listed)", + "Keywords": "LAN,bLAN", + "FieldName": "bLAN", + "InputType": "checkbox", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.bLAN", + "DefaultValue": "False", + "EnumValues": { "False": "False", "True": "True" } + }, + { + "DisplayName": "Anti-Cheat Enabled", + "Category": "Renown:stadia_controller", + "Subcategory": "Security:shield:4", + "Description": "Enable built-in anti-cheat", + "Keywords": "anticheat,bAntiCheat", + "FieldName": "bAntiCheat", + "InputType": "checkbox", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.bAntiCheat", + "DefaultValue": "False", + "EnumValues": { "False": "False", "True": "True" } + }, + { + "DisplayName": "Game Description", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Short description shown in server details (optional)", + "Keywords": "description,GameDescription", + "FieldName": "GameDescription", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.GameDescription", + "DefaultValue": "Renown", + "EnumValues": {} + }, + { + "DisplayName": "Admin Whitelist (comma-separated SteamIDs)", + "Category": "Renown:stadia_controller", + "Subcategory": "Security:shield:4", + "Description": "Admins that can use in-game admin controls", + "Keywords": "admin,whitelist", + "FieldName": "AdminWhitelist", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.AdminWhitelist", + "DefaultValue": "", + "Placeholder": "7656119...,7656119...", + "EnumValues": {} + }, + { + "DisplayName": "Use First Map", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "If true, load the first map from rotation on boot", + "Keywords": "UseFirstMap", + "FieldName": "UseFirstMap", + "InputType": "checkbox", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.UseFirstMap", + "DefaultValue": "True", + "EnumValues": { "False": "False", "True": "True" } + }, + { + "DisplayName": "Ban List Path / IDs", + "Category": "Renown:stadia_controller", + "Subcategory": "Security:shield:4", + "Description": "Ban list (file path or comma-separated IDs)", + "Keywords": "ban,BanList", + "FieldName": "BanList", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.BanList", + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Debug RCON Logs", + "Category": "Renown:stadia_controller", + "Subcategory": "Security:shield:4", + "Description": "Verbose RCON logging", + "Keywords": "debug,DebugRCON", + "FieldName": "DebugRCON", + "InputType": "checkbox", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.DebugRCON", + "DefaultValue": "False", + "EnumValues": { "False": "False", "True": "True" } + }, + + // ===== Added: Game.ini (Base GameMode) ===== + { + "DisplayName": "Match Time Limit (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Time limit for match-based modes", + "Keywords": "TimeLimit", + "FieldName": "TimeLimit", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.TimeLimit", + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Auto Balance Teams", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Automatically balance teams in team modes", + "Keywords": "AutoBalance", + "FieldName": "AutoBalance", + "InputType": "checkbox", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.AutoBalance", + "DefaultValue": "0", + "EnumValues": { "False": "0", "True": "1" } + }, + { + "DisplayName": "Maintenance Rate X", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Maintenance rate vector (X component)", + "Keywords": "MaintenanceRate,X", + "FieldName": "MaintenanceRateX", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.MaintenanceRate.X", + "DefaultValue": "0.5", + "EnumValues": {} + }, + { + "DisplayName": "Maintenance Rate Y", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Maintenance rate vector (Y component)", + "Keywords": "MaintenanceRate,Y", + "FieldName": "MaintenanceRateY", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.MaintenanceRate.Y", + "DefaultValue": "1.0", + "EnumValues": {} + }, + { + "DisplayName": "Global Resource Respawn Time Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Multiplier for resource respawn timers", + "Keywords": "GlobalResourceRespawnTimeMultiplier", + "FieldName": "GlobalResourceRespawnTimeMultiplier", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.GlobalResourceRespawnTimeMultiplier", + "DefaultValue": "1", + "EnumValues": {} + }, + { + "DisplayName": "Global Maintenance Cost Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Multiplier for structure upkeep costs", + "Keywords": "GlobalMaintenanceCostMultiplier", + "FieldName": "GlobalMaintenanceCostMultiplier", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.GlobalMaintenanceCostMultiplier", + "DefaultValue": "1", + "EnumValues": {} + }, + { + "DisplayName": "Global Decay Damage Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Multiplier for decay damage to structures", + "Keywords": "GlobalDecayDamageMultiplier", + "FieldName": "GlobalDecayDamageMultiplier", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.GlobalDecayDamageMultiplier", + "DefaultValue": "1", + "EnumValues": {} + }, + { + "DisplayName": "Kick Idle Players", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Automatically kick idle players", + "Keywords": "KickIdlePlayers", + "FieldName": "KickIdlePlayers", + "InputType": "checkbox", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.KickIdlePlayers", + "DefaultValue": "True", + "EnumValues": { "False": "False", "True": "True" } + }, + { + "DisplayName": "Idle Timeout (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Time before idle player is kicked", + "Keywords": "IdleTimeOutTime", + "FieldName": "IdleTimeOutTime", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.IdleTimeOutTime", + "DefaultValue": "300", + "EnumValues": {} + }, + { + "DisplayName": "Max Players Per Banner (clan)", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Limit of players per banner/clan (0 = unlimited)", + "Keywords": "MaxPlayersPerBanner", + "FieldName": "MaxPlayersPerBanner", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.MaxPlayersPerBanner", + "DefaultValue": "0", + "EnumValues": {} + }, + + // ===== Added: Game.ini (Survival GameMode) ===== + { + "DisplayName": "Auto Reboot Interval (min)", + "Category": "Renown:stadia_controller", + "Subcategory": "Maintenance:refresh-cw:5", + "Description": "Periodically reboot the server to keep performance healthy", + "Keywords": "ServerRebootTimeMinutes", + "FieldName": "ServerRebootTimeMinutes", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.ServerRebootTimeMinutes", + "DefaultValue": "120", + "EnumValues": {} + }, + + // ===== Added: Developer/Server Queue (Game.ini) ===== + { + "DisplayName": "Enable Server Queue", + "Category": "Renown:stadia_controller", + "Subcategory": "Queue:users:6", + "Description": "Enable join queue when server is full or starting", + "Keywords": "queue,bEnableServerQueue", + "FieldName": "bEnableServerQueue", + "InputType": "checkbox", + "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:bEnableServerQueue", + "DefaultValue": "True", + "EnumValues": { "False": "False", "True": "True" } + }, + { + "DisplayName": "Run On LAN (Queue)", + "Category": "Renown:stadia_controller", + "Subcategory": "Queue:users:6", + "Description": "Run queue in LAN mode", + "Keywords": "bRunOnLan", + "FieldName": "bRunOnLan", + "InputType": "checkbox", + "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:bRunOnLan", + "DefaultValue": "False", + "EnumValues": { "False": "False", "True": "True" } + }, + { + "DisplayName": "Client & Server Same Machine", + "Category": "Renown:stadia_controller", + "Subcategory": "Queue:users:6", + "Description": "Optimizations if client and server run on same machine", + "Keywords": "bIsServerClientRunningOnSameMachine", + "FieldName": "bIsServerClientRunningOnSameMachine", + "InputType": "checkbox", + "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:bIsServerClientRunningOnSameMachine", + "DefaultValue": "False", + "EnumValues": { "False": "False", "True": "True" } + }, + { + "DisplayName": "Reconnection Grace (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Queue:users:6", + "Description": "How long a disconnecting player can rejoin without losing spot", + "Keywords": "ReconnectionGracePeriodSeconds", + "FieldName": "ReconnectionGracePeriodSeconds", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:ReconnectionGracePeriodSeconds", + "DefaultValue": "90", + "EnumValues": {} + }, + { + "DisplayName": "Max Join Duration (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Queue:users:6", + "Description": "Time window to complete a join from queue", + "Keywords": "ServerQueueMaxJoinDuration", + "FieldName": "ServerQueueMaxJoinDuration", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:ServerQueueMaxJoinDuration", + "DefaultValue": "300", + "EnumValues": {} + }, + { + "DisplayName": "Purge Pending Connections (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Queue:users:6", + "Description": "Purge half-open connections after this time", + "Keywords": "PurgePendingPlayerConnections", + "FieldName": "PurgePendingPlayerConnections", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:PurgePendingPlayerConnections", + "DefaultValue": "60", + "EnumValues": {} + }, + { + "DisplayName": "Player Slots To Consume", + "Category": "Renown:stadia_controller", + "Subcategory": "Queue:users:6", + "Description": "Reserved slots consumed by queue/internal services", + "Keywords": "PlayerSlotsToConsume", + "FieldName": "PlayerSlotsToConsume", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:PlayerSlotsToConsume", + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Max Client Reconnect Attempts", + "Category": "Renown:stadia_controller", + "Subcategory": "Queue:users:6", + "Description": "How many reconnect tries are allowed", + "Keywords": "MaxClientReconnectAttempts", + "FieldName": "MaxClientReconnectAttempts", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:MaxClientReconnectAttempts", + "DefaultValue": "0", + "EnumValues": {} + }, + + // ===== Party/Lobby/Session (Game.ini) ===== + { + "DisplayName": "Default Max Party Size", + "Category": "Renown:stadia_controller", + "Subcategory": "Social:users:7", + "Description": "Max party size in lobby", + "Keywords": "party,DefaultMaxPartySize", + "FieldName": "DefaultMaxPartySize", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Party.Party]:DefaultMaxPartySize", + "DefaultValue": "5", + "EnumValues": {} + }, + { + "DisplayName": "Wait For Players Time Remaining (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Social:users:7", + "Description": "Time the lobby waits before starting", + "Keywords": "Lobby,WaitForPlayersTimeRemaining", + "FieldName": "WaitForPlayersTimeRemaining", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Lobby.LobbyBeaconState]:WaitForPlayersTimeRemaining", + "DefaultValue": "20.0", + "EnumValues": {} + }, + { + "DisplayName": "Max Spectators", + "Category": "Renown:stadia_controller", + "Subcategory": "Social:users:7", + "Description": "Number of spectator slots", + "Keywords": "spectators,MaxSpectators", + "FieldName": "MaxSpectators", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Engine.GameSession]:MaxSpectators", + "DefaultValue": "2", + "EnumValues": {} + }, + { + "DisplayName": "Requires Push-To-Talk", + "Category": "Renown:stadia_controller", + "Subcategory": "Social:users:7", + "Description": "Require PTT for in-game voice", + "Keywords": "voice,bRequiresPushToTalk", + "FieldName": "bRequiresPushToTalk", + "InputType": "checkbox", + "ParamFieldName": "ini:Game:[Script/Engine.GameSession]:bRequiresPushToTalk", + "DefaultValue": "True", + "EnumValues": { "False": "False", "True": "True" } + }, + + // ===== Networking (Game.ini) ===== + { + "DisplayName": "Total Net Bandwidth (Game.ini)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Server total outgoing bandwidth budget (bytes/sec)", + "Keywords": "bandwidth,TotalNetBandwidth", + "FieldName": "TotalNetBandwidth_Game", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Engine.GameNetworkManager]:TotalNetBandwidth", + "DefaultValue": "4000000", + "EnumValues": {} + }, + { + "DisplayName": "Max Dynamic Bandwidth (Game.ini)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Max per-connection bandwidth cap", + "Keywords": "bandwidth,MaxDynamicBandwidth", + "FieldName": "MaxDynamicBandwidth_Game", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Engine.GameNetworkManager]:MaxDynamicBandwidth", + "DefaultValue": "100000", + "EnumValues": {} + }, + { + "DisplayName": "Min Dynamic Bandwidth (Game.ini)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Min per-connection bandwidth floor", + "Keywords": "bandwidth,MinDynamicBandwidth", + "FieldName": "MinDynamicBandwidth_Game", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Engine.GameNetworkManager]:MinDynamicBandwidth", + "DefaultValue": "40000", + "EnumValues": {} + }, + + // ===== Engine.ini (general) ===== + { + "DisplayName": "Max Ping (Engine.ini override)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Engine.ini override for maximum ping filter", + "Keywords": "MaxPing,override", + "FieldName": "MaxPing_Engine", + "InputType": "number", + "ParamFieldName": "ini:Engine:[/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C]:MaxPing", + "DefaultValue": "500", + "EnumValues": {} + }, + { + "DisplayName": "Smooth Frame Rate", + "Category": "Renown:stadia_controller", + "Subcategory": "Performance:activity:8", + "Description": "Enable UE frame smoothing on the server", + "Keywords": "bSmoothFrameRate", + "FieldName": "bSmoothFrameRate", + "InputType": "checkbox", + "ParamFieldName": "ini:Engine:[Script/Engine.GameEngine]:bSmoothFrameRate", + "DefaultValue": "True", + "EnumValues": { "False": "False", "True": "True" } + }, + { + "DisplayName": "Total Net Bandwidth (Engine.ini)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Engine-level total outgoing bandwidth budget (bytes/sec)", + "Keywords": "bandwidth,TotalNetBandwidth", + "FieldName": "TotalNetBandwidth_Engine", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/Engine.GameNetworkManager]:TotalNetBandwidth", + "DefaultValue": "500000", + "EnumValues": {} + }, + { + "DisplayName": "Max Dynamic Bandwidth (Engine.ini)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Engine-level per-connection bandwidth cap", + "Keywords": "bandwidth,MaxDynamicBandwidth", + "FieldName": "MaxDynamicBandwidth_Engine", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/Engine.GameNetworkManager]:MaxDynamicBandwidth", + "DefaultValue": "80000", + "EnumValues": {} + }, + { + "DisplayName": "Min Dynamic Bandwidth (Engine.ini)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Engine-level per-connection bandwidth floor", + "Keywords": "bandwidth,MinDynamicBandwidth", + "FieldName": "MinDynamicBandwidth_Engine", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/Engine.GameNetworkManager]:MinDynamicBandwidth", + "DefaultValue": "20000", + "EnumValues": {} + }, + { + "DisplayName": "IP Driver: Allow Peer Connections", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Allow peer-to-peer client connections", + "Keywords": "IpNetDriver,AllowPeerConnections", + "FieldName": "AllowPeerConnections", + "InputType": "checkbox", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:AllowPeerConnections", + "DefaultValue": "False", + "EnumValues": { "False": "False", "True": "True" } + }, + { + "DisplayName": "IP Driver: Connection Timeout (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Timeout for network connections", + "Keywords": "IpNetDriver,ConnectionTimeout", + "FieldName": "ConnectionTimeout", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:ConnectionTimeout", + "DefaultValue": "60.0", + "EnumValues": {} + }, + { + "DisplayName": "IP Driver: Initial Connect Timeout (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Initial connection timeout", + "Keywords": "IpNetDriver,InitialConnectTimeout", + "FieldName": "InitialConnectTimeout", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:InitialConnectTimeout", + "DefaultValue": "60.0", + "EnumValues": {} + }, + { + "DisplayName": "IP Driver: Max Client Rate", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Max client rate (bytes/sec)", + "Keywords": "IpNetDriver,MaxClientRate", + "FieldName": "MaxClientRate", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:MaxClientRate", + "DefaultValue": "100000", + "EnumValues": {} + }, + { + "DisplayName": "IP Driver: Max Internet Client Rate", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Max internet client rate (bytes/sec)", + "Keywords": "IpNetDriver,MaxInternetClientRate", + "FieldName": "MaxInternetClientRate", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:MaxInternetClientRate", + "DefaultValue": "100000", + "EnumValues": {} + }, + { + "DisplayName": "IP Driver: Relevant Timeout (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Relevancy timeout", + "Keywords": "IpNetDriver,RelevantTimeout", + "FieldName": "RelevantTimeout", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:RelevantTimeout", + "DefaultValue": "5.0", + "EnumValues": {} + }, + { + "DisplayName": "IP Driver: Spawn Priority Seconds", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Spawn priority seconds", + "Keywords": "IpNetDriver,SpawnPrioritySeconds", + "FieldName": "SpawnPrioritySeconds", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:SpawnPrioritySeconds", + "DefaultValue": "1.0", + "EnumValues": {} + }, + { + "DisplayName": "IP Driver: Server Travel Pause (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Pause during seamless travel", + "Keywords": "IpNetDriver,ServerTravelPause", + "FieldName": "ServerTravelPause", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:ServerTravelPause", + "DefaultValue": "4.0", + "EnumValues": {} + }, + { + "DisplayName": "IP Driver: Net Server Max Tick Rate", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Tick rate for IpNetDriver", + "Keywords": "IpNetDriver,NetServerMaxTickRate", + "FieldName": "IpNetDriver_NetServerMaxTickRate", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:NetServerMaxTickRate", + "DefaultValue": "30", + "EnumValues": {} + }, + { + "DisplayName": "IP Driver: Max Net Tick Rate", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Overall max network tick rate", + "Keywords": "IpNetDriver,MaxNetTickRate", + "FieldName": "MaxNetTickRate", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:MaxNetTickRate", + "DefaultValue": "120", + "EnumValues": {} + }, + + // ===== DDoS Detection ===== + { + "DisplayName": "DDoS Detection Enabled", + "Category": "Renown:stadia_controller", + "Subcategory": "Security:shield:4", + "Description": "Enable UE DDoS detection", + "Keywords": "DDoS,bDDoSDetection", + "FieldName": "bDDoSDetection", + "InputType": "checkbox", + "ParamFieldName": "ini:Engine:[DDoSDetection]:bDDoSDetection", + "DefaultValue": "False", + "EnumValues": { "False": "False", "True": "True" } + }, + { + "DisplayName": "DDoS Analytics Enabled", + "Category": "Renown:stadia_controller", + "Subcategory": "Security:shield:4", + "Description": "Enable DDoS analytics", + "Keywords": "DDoS,bDDoSAnalytics", + "FieldName": "bDDoSAnalytics", + "InputType": "checkbox", + "ParamFieldName": "ini:Engine:[DDoSDetection]:bDDoSAnalytics", + "DefaultValue": "False", + "EnumValues": { "False": "False", "True": "True" } + }, + { + "DisplayName": "DDoS Log Spam Limit", + "Category": "Renown:stadia_controller", + "Subcategory": "Security:shield:4", + "Description": "Limit for DDoS log spam", + "Keywords": "DDoS,Log", + "FieldName": "DDoSLogSpamLimit", + "InputType": "number", + "ParamFieldName": "ini:Engine:[DDoSDetection]:DDoSLogSpamLimit", + "DefaultValue": "64", + "EnumValues": {} + }, + { + "DisplayName": "Hitch Time Quota (ms)", + "Category": "Renown:stadia_controller", + "Subcategory": "Performance:activity:8", + "Description": "Hitch detection time quota", + "Keywords": "HitchTimeQuotaMS", + "FieldName": "HitchTimeQuotaMS", + "InputType": "number", + "ParamFieldName": "ini:Engine:[DDoSDetection]:HitchTimeQuotaMS", + "DefaultValue": "500", + "EnumValues": {} + }, + { + "DisplayName": "Hitch Frame Tolerance", + "Category": "Renown:stadia_controller", + "Subcategory": "Performance:activity:8", + "Description": "Hitch detection frame tolerance", + "Keywords": "HitchFrameTolerance", + "FieldName": "HitchFrameTolerance", + "InputType": "number", + "ParamFieldName": "ini:Engine:[DDoSDetection]:HitchFrameTolerance", + "DefaultValue": "3", + "EnumValues": {} + }, + + // ===== Logging & Housekeeping ===== + { + "DisplayName": "Purge Logs After (days)", + "Category": "Renown:stadia_controller", + "Subcategory": "Maintenance:refresh-cw:5", + "Description": "Delete logs older than this many days", + "Keywords": "logs,PurgeLogsDays", + "FieldName": "PurgeLogsDays", + "InputType": "number", + "ParamFieldName": "ini:Engine:[LogFiles]:PurgeLogsDays", + "DefaultValue": "5", + "EnumValues": {} + }, + { + "DisplayName": "Max Log Files On Disk", + "Category": "Renown:stadia_controller", + "Subcategory": "Maintenance:refresh-cw:5", + "Description": "Limit number of rotated log files", + "Keywords": "logs,MaxLogFilesOnDisk", + "FieldName": "MaxLogFilesOnDisk", + "InputType": "number", + "ParamFieldName": "ini:Engine:[LogFiles]:MaxLogFilesOnDisk", + "DefaultValue": "10", + "EnumValues": {} + }, + { + "DisplayName": "Log Times", + "Category": "Renown:stadia_controller", + "Subcategory": "Maintenance:refresh-cw:5", + "Description": "Include timestamps in logs", + "Keywords": "logs,LogTimes", + "FieldName": "LogTimes", + "InputType": "checkbox", + "ParamFieldName": "ini:Engine:[LogFiles]:LogTimes", + "DefaultValue": "True", + "EnumValues": { "False": "False", "True": "True" } + }, + { + "DisplayName": "Core.Log Advanced (raw block)", + "Category": "Renown:stadia_controller", + "Subcategory": "Maintenance:refresh-cw:5", + "Description": "Optional advanced Core.Log overrides; paste lines like 'Online=all off' each on new line", + "Keywords": "Core.Log,advanced", + "FieldName": "CoreLogRaw", + "InputType": "textarea", + "ParamFieldName": "ini:Engine:[Core.Log]:__raw__", + "DefaultValue": "Online=all off\nOnlineSession=log\nOnlineGame=log\nSteamCore=all off\nAssetLog=all off\nLogRedpointEOS=all off\nLogRedpointEOSIdentity=all off\nLogRedpointEOSSocket=all off\nLogRedpointEOSSocketLifecycle=all off\nLogRedpointEOSSessionListening=all off\nLogRedpointEOSNetworkTrace=all off\nLogRedpointEOSNetworkAuth=all off\nLogRedpointEOSStat=all off\nLogRedpointEOSAntiCheat=all off\nLogRedpointEOSFriends=all off\nLogRedpointEOSFileTransfer=all off\nLogRedpointEOSVoiceChat=all off\nLogBeacon=log\nLogServerQueue=log", + "EnumValues": {} + }, + + // ===== Internationalization (GameUserSettings.ini) ===== + { + "DisplayName": "Server Language Culture", + "Category": "Renown:stadia_controller", + "Subcategory": "Localization:languages:9", + "Description": "Set server culture/language (eg. en, es-MX)", + "Keywords": "language,culture,Internationalization", + "FieldName": "Culture", + "InputType": "text", + "ParamFieldName": "ini:GameUserSettings:[Internationalization]:Culture", + "DefaultValue": "en", + "EnumValues": {} + }, + + // ===== Voice ===== + { + "DisplayName": "EOS Voice Chat Enabled", + "Category": "Renown:stadia_controller", + "Subcategory": "Voice:mic:10", + "Description": "Enable Epic Online Services voice chat", + "Keywords": "voice,EOS,bEnabled", + "FieldName": "EOSVoiceChatEnabled", + "InputType": "checkbox", + "ParamFieldName": "ini:Engine:[EOSVoiceChat]:bEnabled", + "DefaultValue": "True", + "EnumValues": { "False": "False", "True": "True" } + }, + + // ===== Updates ===== + { + "DisplayName": "Server Release Version", + "Category": "Updates", + "Subcategory": "Steam Downloads:download", + "Description": "Sets the server release version to install. Update the server after changing this setting", + "Keywords": "server,version,public,beta", + "FieldName": "ServerVersion", + "InputType": "enum", + "ParamFieldName": "ServerVersion", + "DefaultValue": "public", + "EnumValues": { "public": "Public (default)", "beta": "Beta" } + } +] diff --git a/renownengine.ini b/renownengine.ini new file mode 100644 index 000000000..81997fdba --- /dev/null +++ b/renownengine.ini @@ -0,0 +1,65 @@ +[/Script/SteamSockets.SteamSocketsNetDriver] +NetServerMaxTickRate=30 + +[SystemSettings] +Server.FirstPersonOnly=0 +RollingSavesLimit=250 + +[/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C] +MaxPing=500 + +[/Script/Engine.GameEngine] +bSmoothFrameRate=True + +[/Script/Engine.GameNetworkManager] +TotalNetBandwidth=500000 +MaxDynamicBandwidth=80000 +MinDynamicBandwidth=20000 + +[/Script/OnlineSubsystemUtils.IpNetDriver] +AllowPeerConnections=False +ConnectionTimeout=60.0 +InitialConnectTimeout=60.0 +MaxClientRate=100000 +MaxInternetClientRate=100000 +RelevantTimeout=5.0 +SpawnPrioritySeconds=1.0 +ServerTravelPause=4.0 +NetServerMaxTickRate=30 +MaxNetTickRate=120 + +[DDoSDetection] +bDDoSDetection=false +bDDoSAnalytics=false +DDoSLogSpamLimit=64 +HitchTimeQuotaMS=500 +HitchFrameTolerance=3 + +[LogFiles] +PurgeLogsDays=5 +MaxLogFilesOnDisk=10 +LogTimes=True + +[Core.Log] +Online=all off +OnlineSession=log +OnlineGame=log +SteamCore=all off +AssetLog=all off +LogRedpointEOS=all off +LogRedpointEOSIdentity=all off +LogRedpointEOSSocket=all off +LogRedpointEOSSocketLifecycle=all off +LogRedpointEOSSessionListening=all off +LogRedpointEOSNetworkTrace=all off +LogRedpointEOSNetworkAuth=all off +LogRedpointEOSStat=all off +LogRedpointEOSAntiCheat=all off +LogRedpointEOSFriends=all off +LogRedpointEOSFileTransfer=all off +LogRedpointEOSVoiceChat=all off +LogBeacon=log +LogServerQueue=log + +[EOSVoiceChat] +bEnabled=True diff --git a/renowngame.ini b/renowngame.ini index 46795c155..cfcdda35a 100644 --- a/renowngame.ini +++ b/renowngame.ini @@ -1,24 +1,75 @@ [/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C] -ServerName=AMP Powered Renown Server -MaxPlayers=40 +EnableRCON=True +RCONPort=25575 +RCONChatMessagesLimit=50 +RCONPassword= +RCON_ServerMaxUptime=1800 ServerPassword= +ServerName= +MaxPlayers=40 +bLAN=False +bAntiCheat=False +GameSaveName=Save 1 +GameDescription=Renown AdminPassword= +AdminWhitelist= +UseFirstMap=True +Public=True MapRotation=RSurv-AlgaraIsle_p +BanList= PrivateSession=False -GameSaveName=Save 1 -MaxPing=180 -EnableRCON=True -RCONPort=25575 -RCONChatMessagesLimit=30 -RCONPassword= -MOTD=Welome to my server! +MaxPing=195 +MOTD="NSLOCTEXT("[2CF2D1E04F419B14490A65BF06750767]", "F67B0BE94A3C4A2665B05284056D0757", "Welcome to Renown, in order to play on this server you must accept the following Rules.\r\n\r\n1. **Respect and Courtesy**: Treat fellow players and staff with respect. Harassment, hate speech, or any form of discrimination will not be tolerated.\r\n\r\n2. **Cheating and Exploits**: Any use of cheats, hacks, exploits, or any unfair advantage is strictly prohibited. Players found violating this rule will face severe consequences, including permanent bans.\r\n\r\n3. **Language and Content**: Keep chat and in-game communication appropriate for all ages. Avoid using offensive language, explicit content, or engaging in discussions that may make others uncomfortable.\r\n\r\n4. **No Spamming or Advertising**: Do not spam chat with repetitive messages or advertise external services or products without permission from server staff.\r\n\r\n5. **Bug Reporting**: If you encounter any bugs or issues, report them to server staff or file a bug report promptly. Exploiting or abusing bugs for personal gain is not allowed.\r\n\r\n6. **Impersonation**: Do not impersonate server staff or other players. This includes using similar names or pretending to have authority you do not possess.\r\n\r\n7. **Final Authority**: Server staff have the final say in all matters concerning rule enforcement and disciplinary actions. Respect their decisions and cooperate with them at all times.\r\n\r\nRemember, these rules are in place to ensure a fair, enjoyable, and respectful gaming environment for all players. Violating these rules may result in warnings, temporary suspensions, or permanent bans, depending on the severity of the offense. Enjoy your time on the server and have fun gaming!")" Region= +MaxServerUptime=28800 +DebugRCON=True -[/Script/Engine.GameSession] -MaxPlayers=40 - -[/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C] +[/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C] +TimeLimit=0 +AutoBalance=0 +MaintenanceRate=(X=0.500000,Y=1.000000) ResourceGainMultiplier=1 GoldCoinGainMultiplier=1 GlobalCraftingMultiplier=1 GlobalSmeltingMultiplier=1 +GlobalResourceRespawnTimeMultiplier=1 +GlobalMaintenanceCostMultiplier=1 +GlobalDecayDamageMultiplier=1 +KickIdlePlayers=True +IdleTimeOutTime=300 +MaxPlayersPerBanner=0 + +[/Game/Core/Blueprints/GameModes/Renown_FFA_GameMode.Renown_FFA_GameMode_C] +[/Game/Core/Blueprints/GameModes/Renown_TDM_GameMode.Renown_TDM_GameMode_C] +[/Game/Core/Blueprints/GameModes/Renown_LTS_GameMode.Renown_LTS_GameMode_C] +[/Game/Core/Blueprints/GameModes/Renown_Raid_GameMode.Renown_Raid_GameMode_C] +[/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C] +ServerRebootTimeMinutes=120 +[/Game/Core/Blueprints/GameModes/Renown_Horde_GameMode.Renown_Horde_GameMode_C] +[/Game/Core/Blueprints/GameModes/Renown_Duels_GameMode.Renown_Duels_GameMode_C] + +[/Script/Renown_Combat.RenownDeveloperSettings] +bEnableServerQueue=True +bRunOnLan=False +bIsServerClientRunningOnSameMachine=False +ReconnectionGracePeriodSeconds=90 +ServerQueueMaxJoinDuration=300 +PurgePendingPlayerConnections=60 +PlayerSlotsToConsume=0 +MaxClientReconnectAttempts=0 + +[/Script/Party.Party] +DefaultMaxPartySize=5 + +[/Script/Lobby.LobbyBeaconState] +WaitForPlayersTimeRemaining=20.0 + +[/Script/Engine.GameSession] +MaxSpectators=2 +bRequiresPushToTalk=true + + +[/Script/Engine.GameNetworkManager] +TotalNetBandwidth=4000000 +MaxDynamicBandwidth=100000 +MinDynamicBandwidth=40000 diff --git a/renowngameusersettings.ini b/renowngameusersettings.ini new file mode 100644 index 000000000..e2dd90415 --- /dev/null +++ b/renowngameusersettings.ini @@ -0,0 +1,2 @@ +[Internationalization] +Culture=en diff --git a/renownmetaconfig.json b/renownmetaconfig.json index f02299463..90367eef8 100644 --- a/renownmetaconfig.json +++ b/renownmetaconfig.json @@ -1,14 +1,38 @@ [ - { - "ConfigFile": "Renown_Combat/Saved/Config/LinuxServer/Game.ini", - "ConfigType": "ini", - "AutoMap": true, - "Importable": true - }, - { - "ConfigFile": "Renown_Combat/Saved/Config/WindowsServer/Game.ini", - "ConfigType": "ini", - "AutoMap": true, - "Importable": true - } -] \ No newline at end of file + { + "ConfigFile": "Renown_Combat/Saved/Config/LinuxServer/Game.ini", + "ConfigType": "ini", + "AutoMap": true, + "Importable": true + }, + { + "ConfigFile": "Renown_Combat/Saved/Config/WindowsServer/Game.ini", + "ConfigType": "ini", + "AutoMap": true, + "Importable": true + }, + { + "ConfigFile": "Renown_Combat/Saved/Config/LinuxServer/Engine.ini", + "ConfigType": "ini", + "AutoMap": true, + "Importable": true + }, + { + "ConfigFile": "Renown_Combat/Saved/Config/WindowsServer/Engine.ini", + "ConfigType": "ini", + "AutoMap": true, + "Importable": true + }, + { + "ConfigFile": "Renown_Combat/Saved/Config/LinuxServer/GameUserSettings.ini", + "ConfigType": "ini", + "AutoMap": true, + "Importable": true + }, + { + "ConfigFile": "Renown_Combat/Saved/Config/WindowsServer/GameUserSettings.ini", + "ConfigType": "ini", + "AutoMap": true, + "Importable": true + } +] diff --git a/renownupdates.json b/renownupdates.json index 3a7f24970..bb932904c 100644 --- a/renownupdates.json +++ b/renownupdates.json @@ -1,52 +1,83 @@ [ - { - "UpdateStageName": "SteamCMD Download", - "UpdateSourcePlatform": "All", - "UpdateSource": "SteamCMD", - "UpdateSourceData": "1512690", - "UpdateSourceArgs": "1488310", - "UpdateSourceVersion": "{{ServerVersion}}", - "SkipOnFailure": false - }, - { - "UpdateStageName": "SteamCMD Component Download", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "SteamCMD", - "UpdateSourceData": "1007", - "UpdateSourceArgs": "1488310", - "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Binaries/Win64", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Create Config Directory", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Create Config Directory", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Game.ini Download", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/CubeCoders/AMPTemplates/main/renowngame.ini", - "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", - "UpdateSourceArgs": "Game.ini", - "OverwriteExistingFiles": false - }, - { - "UpdateStageName": "Game.ini Download", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/CubeCoders/AMPTemplates/main/renowngame.ini", - "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", - "UpdateSourceArgs": "Game.ini", - "OverwriteExistingFiles": false - } -] \ No newline at end of file + { + "UpdateStageName": "SteamCMD Download", + "UpdateSourcePlatform": "All", + "UpdateSource": "SteamCMD", + "UpdateSourceData": "1512690", + "UpdateSourceArgs": "1488310", + "UpdateSourceVersion": "{{ServerVersion}}", + "SkipOnFailure": false + }, + { + "UpdateStageName": "SteamCMD Component Download", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "SteamCMD", + "UpdateSourceData": "1007", + "UpdateSourceArgs": "1488310", + "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Binaries/Win64", + "SkipOnFailure": false + }, + + { "UpdateStageName": "Create Config Directory (Linux)", "UpdateSourcePlatform": "Linux", "UpdateSource": "CreateDirectory", "UpdateSourceArgs": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", "SkipOnFailure": false }, + { "UpdateStageName": "Create Config Directory (Windows)", "UpdateSourcePlatform": "Windows", "UpdateSource": "CreateDirectory", "UpdateSourceArgs": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", "SkipOnFailure": false }, + + // ===== Game.ini from your fork (source filename → destination Game.ini) + { + "UpdateStageName": "Game.ini Download (Linux)", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "FetchURL", + "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renowngame.ini", + "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", + "UpdateSourceArgs": "Game.ini", + "OverwriteExistingFiles": false + }, + { + "UpdateStageName": "Game.ini Download (Windows)", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "FetchURL", + "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renowngame.ini", + "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", + "UpdateSourceArgs": "Game.ini", + "OverwriteExistingFiles": false + }, + + // ===== Engine.ini from your fork (renownengine.ini → Engine.ini) + { + "UpdateStageName": "Engine.ini Download (Linux)", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "FetchURL", + "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renownengine.ini", + "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", + "UpdateSourceArgs": "Engine.ini", + "OverwriteExistingFiles": false + }, + { + "UpdateStageName": "Engine.ini Download (Windows)", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "FetchURL", + "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renownengine.ini", + "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", + "UpdateSourceArgs": "Engine.ini", + "OverwriteExistingFiles": false + }, + + // ===== GameUserSettings.ini from your fork (renowngameusersettings.ini → GameUserSettings.ini) + { + "UpdateStageName": "GameUserSettings.ini Download (Linux)", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "FetchURL", + "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renowngameusersettings.ini", + "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", + "UpdateSourceArgs": "GameUserSettings.ini", + "OverwriteExistingFiles": false + }, + { + "UpdateStageName": "GameUserSettings.ini Download (Windows)", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "FetchURL", + "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renowngameusersettings.ini", + "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", + "UpdateSourceArgs": "GameUserSettings.ini", + "OverwriteExistingFiles": false + } +] From 2285720b6ee0955d9c5908578697e7d182e258fc Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Thu, 26 Mar 2026 16:26:33 -0500 Subject: [PATCH 02/50] renowngame.ini --- renowngame.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/renowngame.ini b/renowngame.ini index cfcdda35a..77e53af34 100644 --- a/renowngame.ini +++ b/renowngame.ini @@ -45,6 +45,8 @@ MaxPlayersPerBanner=0 [/Game/Core/Blueprints/GameModes/Renown_Raid_GameMode.Renown_Raid_GameMode_C] [/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C] ServerRebootTimeMinutes=120 +RaidWindowTimes=(X=16,Y=0) +OfflineRaidProtectionMultiplier=.99 [/Game/Core/Blueprints/GameModes/Renown_Horde_GameMode.Renown_Horde_GameMode_C] [/Game/Core/Blueprints/GameModes/Renown_Duels_GameMode.Renown_Duels_GameMode_C] From 5984a06a101af746af6ad943809a521d7fa6ed21 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Thu, 26 Mar 2026 16:38:01 -0500 Subject: [PATCH 03/50] renownconfig.json --- renownconfig.json | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/renownconfig.json b/renownconfig.json index 63ecbf0eb..addf03b7c 100644 --- a/renownconfig.json +++ b/renownconfig.json @@ -560,6 +560,45 @@ "DefaultValue": "120", "EnumValues": {} }, +{ + "DisplayName": "Raid Window Start Hour", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Hour of the day (0-23) when raiding becomes allowed", + "Keywords": "raid,window,start", + "FieldName": "RaidWindowStart", + "InputType": "number", + "MinValue": "0", + "MaxValue": "23", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.RaidWindowTimes.X", + "DefaultValue": "16" +}, +{ + "DisplayName": "Raid Window End Hour", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Hour of the day (0-23) when raiding stops. If less than start, wraps past midnight.", + "Keywords": "raid,window,end", + "FieldName": "RaidWindowEnd", + "InputType": "number", + "MinValue": "0", + "MaxValue": "23", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.RaidWindowTimes.Y", + "DefaultValue": "0" +}, +{ + "DisplayName": "Offline Raid Protection Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Damage multiplier applied when the defending player is offline (0 = no damage, 1 = full damage)", + "Keywords": "offline,raid,protection", + "FieldName": "OfflineRaidProtectionMultiplier", + "InputType": "number", + "MinValue": "0", + "MaxValue": "1", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.OfflineRaidProtectionMultiplier", + "DefaultValue": "0.99" +}, // ===== Added: Developer/Server Queue (Game.ini) ===== { From 09a4889b0653e0149089d502a5d92f9d9605458b Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Thu, 26 Mar 2026 19:24:33 -0500 Subject: [PATCH 04/50] renownconfig.json --- renownconfig.json | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/renownconfig.json b/renownconfig.json index addf03b7c..56421bcd7 100644 --- a/renownconfig.json +++ b/renownconfig.json @@ -561,30 +561,17 @@ "EnumValues": {} }, { - "DisplayName": "Raid Window Start Hour", + "DisplayName": "Raid Window Times", "Category": "Renown:stadia_controller", "Subcategory": "Gameplay:joystick:2", - "Description": "Hour of the day (0-23) when raiding becomes allowed", - "Keywords": "raid,window,start", - "FieldName": "RaidWindowStart", - "InputType": "number", - "MinValue": "0", - "MaxValue": "23", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.RaidWindowTimes.X", - "DefaultValue": "16" -}, -{ - "DisplayName": "Raid Window End Hour", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Hour of the day (0-23) when raiding stops. If less than start, wraps past midnight.", - "Keywords": "raid,window,end", - "FieldName": "RaidWindowEnd", - "InputType": "number", - "MinValue": "0", - "MaxValue": "23", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.RaidWindowTimes.Y", - "DefaultValue": "0" + "Description": "Raid window in tuple format. X = start hour, Y = end hour, using 24-hour time. Example: (X=16,Y=0) means 4 PM to midnight. If Y is less than X, the window wraps past midnight.", + "Keywords": "raid,window,times,RaidWindowTimes", + "FieldName": "RaidWindowTimes", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.RaidWindowTimes", + "DefaultValue": "(X=16,Y=0)", + "Placeholder": "(X=16,Y=0)", + "EnumValues": {} }, { "DisplayName": "Offline Raid Protection Multiplier", From 907532f9d76fcb907c41b6ef5e351b55f23c92a2 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Thu, 26 Mar 2026 19:52:01 -0500 Subject: [PATCH 05/50] renowngame.ini --- renowngame.ini | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/renowngame.ini b/renowngame.ini index 77e53af34..96730d97d 100644 --- a/renowngame.ini +++ b/renowngame.ini @@ -24,7 +24,7 @@ Region= MaxServerUptime=28800 DebugRCON=True -[/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C] +[/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C] TimeLimit=0 AutoBalance=0 MaintenanceRate=(X=0.500000,Y=1.000000) @@ -38,12 +38,6 @@ GlobalDecayDamageMultiplier=1 KickIdlePlayers=True IdleTimeOutTime=300 MaxPlayersPerBanner=0 - -[/Game/Core/Blueprints/GameModes/Renown_FFA_GameMode.Renown_FFA_GameMode_C] -[/Game/Core/Blueprints/GameModes/Renown_TDM_GameMode.Renown_TDM_GameMode_C] -[/Game/Core/Blueprints/GameModes/Renown_LTS_GameMode.Renown_LTS_GameMode_C] -[/Game/Core/Blueprints/GameModes/Renown_Raid_GameMode.Renown_Raid_GameMode_C] -[/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C] ServerRebootTimeMinutes=120 RaidWindowTimes=(X=16,Y=0) OfflineRaidProtectionMultiplier=.99 From 62e034c556d59e865c4c7af217253ef7b53a86fa Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Thu, 26 Mar 2026 20:05:13 -0500 Subject: [PATCH 06/50] renownconfig.json --- renownconfig.json | 265 ++++++++++++++++++++++++++-------------------- 1 file changed, 151 insertions(+), 114 deletions(-) diff --git a/renownconfig.json b/renownconfig.json index 56421bcd7..4a57543c2 100644 --- a/renownconfig.json +++ b/renownconfig.json @@ -24,7 +24,8 @@ "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONPassword", "Hidden": true, "ExcludeFromImport": true, - "EnumValues": {} + "EnumValues": {}, + "DefaultValue": "" }, { "DisplayName": "RCON Port", @@ -37,7 +38,8 @@ "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONPort", "Hidden": true, "ExcludeFromImport": true, - "EnumValues": {} + "EnumValues": {}, + "DefaultValue": "25575" }, { "DisplayName": "Server Name", @@ -48,7 +50,7 @@ "FieldName": "ServerName", "InputType": "text", "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.ServerName", - "DefaultValue": "AMP Powered Renown Server", + "DefaultValue": "", "Placeholder": "AMP Powered Renown Server", "EnumValues": {} }, @@ -61,8 +63,9 @@ "FieldName": "Region", "InputType": "enum", "ParamFieldName": "Region", - "DefaultValue": "US Central", + "DefaultValue": "", "EnumValues": { + "": "--None--", "US East": "US East", "US West": "US West", "US Central": "US Central", @@ -96,7 +99,10 @@ "InputType": "checkbox", "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.PrivateSession", "DefaultValue": "False", - "EnumValues": { "False": "False", "True": "True" } + "EnumValues": { + "False": "False", + "True": "True" + } }, { "DisplayName": "Server MOTD", @@ -171,7 +177,8 @@ "FieldName": "MapRotation", "InputType": "hidden", "ParamFieldName": "MapRotation", - "EnumValues": {} + "EnumValues": {}, + "DefaultValue": "RSurv-AlgaraIsle_p" }, { "DisplayName": "Game Save Name", @@ -197,8 +204,8 @@ "InputType": "number", "MinValue": "0", "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxPing", - "DefaultValue": "180", - "Placeholder": "180", + "DefaultValue": "195", + "Placeholder": "195", "EnumValues": {} }, { @@ -211,8 +218,8 @@ "InputType": "number", "MinValue": "0", "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONChatMessagesLimit", - "DefaultValue": "30", - "Placeholder": "30", + "DefaultValue": "50", + "Placeholder": "50", "EnumValues": {} }, { @@ -299,10 +306,11 @@ "IncludeInCommandLine": true, "SkipIfEmpty": true, "DefaultValue": "0", - "EnumValues": { "False": "0", "True": "1" } + "EnumValues": { + "False": "0", + "True": "1" + } }, - - // ===== Added: Remaining Game.ini keys (GameInstance) ===== { "DisplayName": "RCON Server Max Uptime (sec)", "Category": "Renown:stadia_controller", @@ -337,7 +345,10 @@ "InputType": "checkbox", "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.Public", "DefaultValue": "True", - "EnumValues": { "False": "False", "True": "True" } + "EnumValues": { + "False": "False", + "True": "True" + } }, { "DisplayName": "LAN Mode", @@ -349,7 +360,10 @@ "InputType": "checkbox", "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.bLAN", "DefaultValue": "False", - "EnumValues": { "False": "False", "True": "True" } + "EnumValues": { + "False": "False", + "True": "True" + } }, { "DisplayName": "Anti-Cheat Enabled", @@ -361,7 +375,10 @@ "InputType": "checkbox", "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.bAntiCheat", "DefaultValue": "False", - "EnumValues": { "False": "False", "True": "True" } + "EnumValues": { + "False": "False", + "True": "True" + } }, { "DisplayName": "Game Description", @@ -398,7 +415,10 @@ "InputType": "checkbox", "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.UseFirstMap", "DefaultValue": "True", - "EnumValues": { "False": "False", "True": "True" } + "EnumValues": { + "False": "False", + "True": "True" + } }, { "DisplayName": "Ban List Path / IDs", @@ -421,11 +441,12 @@ "FieldName": "DebugRCON", "InputType": "checkbox", "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.DebugRCON", - "DefaultValue": "False", - "EnumValues": { "False": "False", "True": "True" } + "DefaultValue": "True", + "EnumValues": { + "False": "False", + "True": "True" + } }, - - // ===== Added: Game.ini (Base GameMode) ===== { "DisplayName": "Match Time Limit (sec)", "Category": "Renown:stadia_controller", @@ -434,9 +455,10 @@ "Keywords": "TimeLimit", "FieldName": "TimeLimit", "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.TimeLimit", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.TimeLimit", "DefaultValue": "0", - "EnumValues": {} + "EnumValues": {}, + "Placeholder": "0" }, { "DisplayName": "Auto Balance Teams", @@ -446,32 +468,24 @@ "Keywords": "AutoBalance", "FieldName": "AutoBalance", "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.AutoBalance", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.AutoBalance", "DefaultValue": "0", - "EnumValues": { "False": "0", "True": "1" } - }, - { - "DisplayName": "Maintenance Rate X", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Maintenance rate vector (X component)", - "Keywords": "MaintenanceRate,X", - "FieldName": "MaintenanceRateX", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.MaintenanceRate.X", - "DefaultValue": "0.5", - "EnumValues": {} + "EnumValues": { + "False": "0", + "True": "1" + } }, { - "DisplayName": "Maintenance Rate Y", + "DisplayName": "Maintenance Rate", "Category": "Renown:stadia_controller", "Subcategory": "Gameplay:joystick:2", - "Description": "Maintenance rate vector (Y component)", - "Keywords": "MaintenanceRate,Y", - "FieldName": "MaintenanceRateY", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.MaintenanceRate.Y", - "DefaultValue": "1.0", + "Description": "Tuple format for maintenance scaling. Example: (X=0.500000,Y=1.000000)", + "Keywords": "MaintenanceRate", + "FieldName": "MaintenanceRate", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.MaintenanceRate", + "DefaultValue": "(X=0.500000,Y=1.000000)", + "Placeholder": "(X=0.500000,Y=1.000000)", "EnumValues": {} }, { @@ -482,9 +496,10 @@ "Keywords": "GlobalResourceRespawnTimeMultiplier", "FieldName": "GlobalResourceRespawnTimeMultiplier", "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.GlobalResourceRespawnTimeMultiplier", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalResourceRespawnTimeMultiplier", "DefaultValue": "1", - "EnumValues": {} + "EnumValues": {}, + "Placeholder": "1" }, { "DisplayName": "Global Maintenance Cost Multiplier", @@ -494,9 +509,10 @@ "Keywords": "GlobalMaintenanceCostMultiplier", "FieldName": "GlobalMaintenanceCostMultiplier", "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.GlobalMaintenanceCostMultiplier", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalMaintenanceCostMultiplier", "DefaultValue": "1", - "EnumValues": {} + "EnumValues": {}, + "Placeholder": "1" }, { "DisplayName": "Global Decay Damage Multiplier", @@ -506,9 +522,10 @@ "Keywords": "GlobalDecayDamageMultiplier", "FieldName": "GlobalDecayDamageMultiplier", "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.GlobalDecayDamageMultiplier", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalDecayDamageMultiplier", "DefaultValue": "1", - "EnumValues": {} + "EnumValues": {}, + "Placeholder": "1" }, { "DisplayName": "Kick Idle Players", @@ -518,9 +535,12 @@ "Keywords": "KickIdlePlayers", "FieldName": "KickIdlePlayers", "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.KickIdlePlayers", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.KickIdlePlayers", "DefaultValue": "True", - "EnumValues": { "False": "False", "True": "True" } + "EnumValues": { + "False": "False", + "True": "True" + } }, { "DisplayName": "Idle Timeout (sec)", @@ -530,9 +550,10 @@ "Keywords": "IdleTimeOutTime", "FieldName": "IdleTimeOutTime", "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.IdleTimeOutTime", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.IdleTimeOutTime", "DefaultValue": "300", - "EnumValues": {} + "EnumValues": {}, + "Placeholder": "300" }, { "DisplayName": "Max Players Per Banner (clan)", @@ -542,12 +563,11 @@ "Keywords": "MaxPlayersPerBanner", "FieldName": "MaxPlayersPerBanner", "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Base_GameMode.Renown_Base_GameMode_C.MaxPlayersPerBanner", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.MaxPlayersPerBanner", "DefaultValue": "0", - "EnumValues": {} + "EnumValues": {}, + "Placeholder": "0" }, - - // ===== Added: Game.ini (Survival GameMode) ===== { "DisplayName": "Auto Reboot Interval (min)", "Category": "Renown:stadia_controller", @@ -558,36 +578,36 @@ "InputType": "number", "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.ServerRebootTimeMinutes", "DefaultValue": "120", + "EnumValues": {}, + "Placeholder": "120" + }, + { + "DisplayName": "Raid Window Times", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Raid window in tuple format. X = start hour, Y = end hour, using 24-hour time. Example: (X=16,Y=0) means 4 PM to midnight. If Y is less than X, the window wraps past midnight.", + "Keywords": "raid,window,times,RaidWindowTimes", + "FieldName": "RaidWindowTimes", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.RaidWindowTimes", + "DefaultValue": "(X=16,Y=0)", + "Placeholder": "(X=16,Y=0)", "EnumValues": {} }, -{ - "DisplayName": "Raid Window Times", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Raid window in tuple format. X = start hour, Y = end hour, using 24-hour time. Example: (X=16,Y=0) means 4 PM to midnight. If Y is less than X, the window wraps past midnight.", - "Keywords": "raid,window,times,RaidWindowTimes", - "FieldName": "RaidWindowTimes", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.RaidWindowTimes", - "DefaultValue": "(X=16,Y=0)", - "Placeholder": "(X=16,Y=0)", - "EnumValues": {} -}, -{ - "DisplayName": "Offline Raid Protection Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Damage multiplier applied when the defending player is offline (0 = no damage, 1 = full damage)", - "Keywords": "offline,raid,protection", - "FieldName": "OfflineRaidProtectionMultiplier", - "InputType": "number", - "MinValue": "0", - "MaxValue": "1", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.OfflineRaidProtectionMultiplier", - "DefaultValue": "0.99" -}, - - // ===== Added: Developer/Server Queue (Game.ini) ===== + { + "DisplayName": "Offline Raid Protection Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Multiplier applied to raid damage when the defending player is offline. 1 = full damage (no protection), 0 = no damage (full protection).", + "Keywords": "offline,raid,protection", + "FieldName": "OfflineRaidProtectionMultiplier", + "InputType": "number", + "MinValue": "0", + "MaxValue": "1", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.OfflineRaidProtectionMultiplier", + "DefaultValue": ".99", + "Placeholder": ".99" + }, { "DisplayName": "Enable Server Queue", "Category": "Renown:stadia_controller", @@ -598,7 +618,10 @@ "InputType": "checkbox", "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:bEnableServerQueue", "DefaultValue": "True", - "EnumValues": { "False": "False", "True": "True" } + "EnumValues": { + "False": "False", + "True": "True" + } }, { "DisplayName": "Run On LAN (Queue)", @@ -610,7 +633,10 @@ "InputType": "checkbox", "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:bRunOnLan", "DefaultValue": "False", - "EnumValues": { "False": "False", "True": "True" } + "EnumValues": { + "False": "False", + "True": "True" + } }, { "DisplayName": "Client & Server Same Machine", @@ -622,7 +648,10 @@ "InputType": "checkbox", "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:bIsServerClientRunningOnSameMachine", "DefaultValue": "False", - "EnumValues": { "False": "False", "True": "True" } + "EnumValues": { + "False": "False", + "True": "True" + } }, { "DisplayName": "Reconnection Grace (sec)", @@ -684,8 +713,6 @@ "DefaultValue": "0", "EnumValues": {} }, - - // ===== Party/Lobby/Session (Game.ini) ===== { "DisplayName": "Default Max Party Size", "Category": "Renown:stadia_controller", @@ -731,11 +758,12 @@ "FieldName": "bRequiresPushToTalk", "InputType": "checkbox", "ParamFieldName": "ini:Game:[Script/Engine.GameSession]:bRequiresPushToTalk", - "DefaultValue": "True", - "EnumValues": { "False": "False", "True": "True" } + "DefaultValue": "true", + "EnumValues": { + "False": "False", + "True": "True" + } }, - - // ===== Networking (Game.ini) ===== { "DisplayName": "Total Net Bandwidth (Game.ini)", "Category": "Renown:stadia_controller", @@ -772,8 +800,6 @@ "DefaultValue": "40000", "EnumValues": {} }, - - // ===== Engine.ini (general) ===== { "DisplayName": "Max Ping (Engine.ini override)", "Category": "Renown:stadia_controller", @@ -796,7 +822,10 @@ "InputType": "checkbox", "ParamFieldName": "ini:Engine:[Script/Engine.GameEngine]:bSmoothFrameRate", "DefaultValue": "True", - "EnumValues": { "False": "False", "True": "True" } + "EnumValues": { + "False": "False", + "True": "True" + } }, { "DisplayName": "Total Net Bandwidth (Engine.ini)", @@ -844,7 +873,10 @@ "InputType": "checkbox", "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:AllowPeerConnections", "DefaultValue": "False", - "EnumValues": { "False": "False", "True": "True" } + "EnumValues": { + "False": "False", + "True": "True" + } }, { "DisplayName": "IP Driver: Connection Timeout (sec)", @@ -954,8 +986,6 @@ "DefaultValue": "120", "EnumValues": {} }, - - // ===== DDoS Detection ===== { "DisplayName": "DDoS Detection Enabled", "Category": "Renown:stadia_controller", @@ -966,7 +996,10 @@ "InputType": "checkbox", "ParamFieldName": "ini:Engine:[DDoSDetection]:bDDoSDetection", "DefaultValue": "False", - "EnumValues": { "False": "False", "True": "True" } + "EnumValues": { + "False": "False", + "True": "True" + } }, { "DisplayName": "DDoS Analytics Enabled", @@ -978,7 +1011,10 @@ "InputType": "checkbox", "ParamFieldName": "ini:Engine:[DDoSDetection]:bDDoSAnalytics", "DefaultValue": "False", - "EnumValues": { "False": "False", "True": "True" } + "EnumValues": { + "False": "False", + "True": "True" + } }, { "DisplayName": "DDoS Log Spam Limit", @@ -1016,8 +1052,6 @@ "DefaultValue": "3", "EnumValues": {} }, - - // ===== Logging & Housekeeping ===== { "DisplayName": "Purge Logs After (days)", "Category": "Renown:stadia_controller", @@ -1052,7 +1086,10 @@ "InputType": "checkbox", "ParamFieldName": "ini:Engine:[LogFiles]:LogTimes", "DefaultValue": "True", - "EnumValues": { "False": "False", "True": "True" } + "EnumValues": { + "False": "False", + "True": "True" + } }, { "DisplayName": "Core.Log Advanced (raw block)", @@ -1066,8 +1103,6 @@ "DefaultValue": "Online=all off\nOnlineSession=log\nOnlineGame=log\nSteamCore=all off\nAssetLog=all off\nLogRedpointEOS=all off\nLogRedpointEOSIdentity=all off\nLogRedpointEOSSocket=all off\nLogRedpointEOSSocketLifecycle=all off\nLogRedpointEOSSessionListening=all off\nLogRedpointEOSNetworkTrace=all off\nLogRedpointEOSNetworkAuth=all off\nLogRedpointEOSStat=all off\nLogRedpointEOSAntiCheat=all off\nLogRedpointEOSFriends=all off\nLogRedpointEOSFileTransfer=all off\nLogRedpointEOSVoiceChat=all off\nLogBeacon=log\nLogServerQueue=log", "EnumValues": {} }, - - // ===== Internationalization (GameUserSettings.ini) ===== { "DisplayName": "Server Language Culture", "Category": "Renown:stadia_controller", @@ -1080,8 +1115,6 @@ "DefaultValue": "en", "EnumValues": {} }, - - // ===== Voice ===== { "DisplayName": "EOS Voice Chat Enabled", "Category": "Renown:stadia_controller", @@ -1092,10 +1125,11 @@ "InputType": "checkbox", "ParamFieldName": "ini:Engine:[EOSVoiceChat]:bEnabled", "DefaultValue": "True", - "EnumValues": { "False": "False", "True": "True" } + "EnumValues": { + "False": "False", + "True": "True" + } }, - - // ===== Updates ===== { "DisplayName": "Server Release Version", "Category": "Updates", @@ -1106,6 +1140,9 @@ "InputType": "enum", "ParamFieldName": "ServerVersion", "DefaultValue": "public", - "EnumValues": { "public": "Public (default)", "beta": "Beta" } + "EnumValues": { + "public": "Public (default)", + "beta": "Beta" + } } ] From 32390c9c3ef4e243eb9f9bf1e63b298ea8ada131 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Thu, 26 Mar 2026 20:12:34 -0500 Subject: [PATCH 07/50] renownconfig.json --- renownconfig.json | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/renownconfig.json b/renownconfig.json index 4a57543c2..3ea4c6a08 100644 --- a/renownconfig.json +++ b/renownconfig.json @@ -594,20 +594,21 @@ "Placeholder": "(X=16,Y=0)", "EnumValues": {} }, - { - "DisplayName": "Offline Raid Protection Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Multiplier applied to raid damage when the defending player is offline. 1 = full damage (no protection), 0 = no damage (full protection).", - "Keywords": "offline,raid,protection", - "FieldName": "OfflineRaidProtectionMultiplier", - "InputType": "number", - "MinValue": "0", - "MaxValue": "1", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.OfflineRaidProtectionMultiplier", - "DefaultValue": ".99", - "Placeholder": ".99" - }, +{ + "DisplayName": "Offline Raid Protection", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Damage reduction applied when the defending player is offline. 1.0 = 100% damage reduction (no damage), 0.0 = no protection (full damage). Recommended: 0.99 for near-complete protection.", + "Keywords": "offline,raid,protection", + "FieldName": "OfflineRaidProtectionMultiplier", + "InputType": "number", + "MinValue": "0", + "MaxValue": ".99", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.OfflineRaidProtectionMultiplier", + "DefaultValue": "0.99", + "Placeholder": "0.99", + "EnumValues": {} +}, { "DisplayName": "Enable Server Queue", "Category": "Renown:stadia_controller", From 048a98dac1fab4246a9678b3c5165c4cb32e0c0f Mon Sep 17 00:00:00 2001 From: IceOfWraith <96364530+IceOfWraith@users.noreply.github.com> Date: Mon, 3 Aug 2026 23:12:08 -0500 Subject: [PATCH 08/50] Revert kvp changes and JSON spacing --- renown.kvp | 4 +- renownconfig.json | 2292 ++++++++++++++++++++++----------------------- 2 files changed, 1148 insertions(+), 1148 deletions(-) diff --git a/renown.kvp b/renown.kvp index eb4b30410..9ec34646f 100644 --- a/renown.kvp +++ b/renown.kvp @@ -11,7 +11,7 @@ Meta.ConfigManifest=renownconfig.json Meta.MetaConfigManifest=renownmetaconfig.json Meta.ConfigRoot=renown.kvp Meta.MinAMPVersion=2.6.2.8 -Meta.SpecificDockerImage= +Meta.SpecificDockerImage=cubecoders/ampbase:debian Meta.DockerRequired=False Meta.DockerBaseReadOnly=False Meta.ContainerPolicy=Supported @@ -24,7 +24,7 @@ Meta.NoCommercialUsage=False Meta.ConfigVersion=2 Meta.ReleaseNotes= Meta.BreakingReleaseNotes= -Meta.AppConfigId=3a94e6c8-e0f9-4008-afc8-903c7e37da2b +Meta.AppConfigId=3a94e6c8-e0f9-4008-afc8-903c7e372bad Meta.ImportableExtensions=[".ini"] Meta.AppIsMultiIPAware=False App.DisplayName=Renown diff --git a/renownconfig.json b/renownconfig.json index 3ea4c6a08..48e4fc8a0 100644 --- a/renownconfig.json +++ b/renownconfig.json @@ -1,1149 +1,1149 @@ [ - { - "DisplayName": "Enable RCON", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "", - "Keywords": "", - "FieldName": "EnableRCON", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.EnableRCON", - "Hidden": true, - "DefaultValue": "True", - "ExcludeFromImport": true, - "EnumValues": {} - }, - { - "DisplayName": "RCON Password", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "", - "Keywords": "", - "FieldName": "$RemoteAdminPassword", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONPassword", - "Hidden": true, - "ExcludeFromImport": true, - "EnumValues": {}, - "DefaultValue": "" - }, - { - "DisplayName": "RCON Port", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "", - "Keywords": "", - "FieldName": "$RCONPort", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONPort", - "Hidden": true, - "ExcludeFromImport": true, - "EnumValues": {}, - "DefaultValue": "25575" - }, - { - "DisplayName": "Server Name", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the name of the server that is displayed in the server browser", - "Keywords": "server,name,ServerName", - "FieldName": "ServerName", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.ServerName", - "DefaultValue": "", - "Placeholder": "AMP Powered Renown Server", - "EnumValues": {} - }, - { - "DisplayName": "Server Region", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the region tag for the server as shown in the server browser. The official tags appear in the dropdown. If 'Custom' is selected, Custom Server Region must also be set", - "Keywords": "region", - "FieldName": "Region", - "InputType": "enum", - "ParamFieldName": "Region", - "DefaultValue": "", - "EnumValues": { - "": "--None--", - "US East": "US East", - "US West": "US West", - "US Central": "US Central", - "Europe": "Europe", - "South America": "South America", - "Asia": "Asia", - "Oceania": "Oceania", - "{{CustomRegion}}": "--Custom--" + { + "DisplayName": "Enable RCON", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "", + "Keywords": "", + "FieldName": "EnableRCON", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.EnableRCON", + "Hidden": true, + "DefaultValue": "True", + "ExcludeFromImport": true, + "EnumValues": {} + }, + { + "DisplayName": "RCON Password", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "", + "Keywords": "", + "FieldName": "$RemoteAdminPassword", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONPassword", + "Hidden": true, + "ExcludeFromImport": true, + "EnumValues": {}, + "DefaultValue": "" + }, + { + "DisplayName": "RCON Port", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "", + "Keywords": "", + "FieldName": "$RCONPort", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONPort", + "Hidden": true, + "ExcludeFromImport": true, + "EnumValues": {}, + "DefaultValue": "25575" + }, + { + "DisplayName": "Server Name", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the name of the server that is displayed in the server browser", + "Keywords": "server,name,ServerName", + "FieldName": "ServerName", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.ServerName", + "DefaultValue": "", + "Placeholder": "AMP Powered Renown Server", + "EnumValues": {} + }, + { + "DisplayName": "Server Region", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the region tag for the server as shown in the server browser. The official tags appear in the dropdown. If 'Custom' is selected, Custom Server Region must also be set", + "Keywords": "region", + "FieldName": "Region", + "InputType": "enum", + "ParamFieldName": "Region", + "DefaultValue": "", + "EnumValues": { + "": "--None--", + "US East": "US East", + "US West": "US West", + "US Central": "US Central", + "Europe": "Europe", + "South America": "South America", + "Asia": "Asia", + "Oceania": "Oceania", + "{{CustomRegion}}": "--Custom--" + } + }, + { + "DisplayName": "Custom Server Region", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets a custom region tag for the server, if 'Custom' is selected under Server Region", + "Keywords": "custom,region", + "FieldName": "CustomRegion", + "InputType": "text", + "ParamFieldName": "CustomRegion", + "DefaultValue": "", + "Placeholder": "Modded", + "EnumValues": {} + }, + { + "DisplayName": "Make Server Private", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "If set, the server will not be listed in the server browser and can only be joined via direct connect", + "Keywords": "private,session,PrivateSession", + "FieldName": "PrivateSession", + "InputType": "checkbox", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.PrivateSession", + "DefaultValue": "False", + "EnumValues": { + "False": "False", + "True": "True" + } + }, + { + "DisplayName": "Server MOTD", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the message of the day (MOTD) shown to players when they join", + "Keywords": "motd,message,day", + "FieldName": "MOTD", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MOTD", + "DefaultValue": "NSLOCTEXT(\"[2CF2D1E04F419B14490A65BF06750767]\", \"F67B0BE94A3C4A2665B05284056D0757\", \"Welcome to Renown, in order to play on this server you must accept the following Rules.\\r\\n\\r\\n1. **Respect and Courtesy**: Treat fellow players and staff with respect. Harassment, hate speech, or any form of discrimination will not be tolerated.\\r\\n\\r\\n2. **Cheating and Exploits**: Any use of cheats, hacks, exploits, or any unfair advantage is strictly prohibited. Players found violating this rule will face severe consequences, including permanent bans.\\r\\n\\r\\n3. **Language and Content**: Keep chat and in-game communication appropriate for all ages. Avoid using offensive language, explicit content, or engaging in discussions that may make others uncomfortable.\\r\\n\\r\\n4. **No Spamming or Advertising**: Do not spam chat with repetitive messages or advertise external services or products without permission from server staff.\\r\\n\\r\\n5. **Bug Reporting**: If you encounter any bugs or issues, report them to server staff or file a bug report promptly. Exploiting or abusing bugs for personal gain is not allowed.\\r\\n\\r\\n6. **Impersonation**: Do not impersonate server staff or other players. This includes using similar names or pretending to have authority you do not possess.\\r\\n\\r\\n7. **Final Authority**: Server staff have the final say in all matters concerning rule enforcement and disciplinary actions. Respect their decisions and cooperate with them at all times.\\r\\n\\r\\nRemember, these rules are in place to ensure a fair, enjoyable, and respectful gaming environment for all players. Violating these rules may result in warnings, temporary suspensions, or permanent bans, depending on the severity of the offense. Enjoy your time on the server and have fun gaming!\")", + "EnumValues": {} + }, + { + "DisplayName": "Server Password", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the password required to join the server. Empty = no password", + "Keywords": "server,password,ServerPassword", + "FieldName": "ServerPassword", + "InputType": "password", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.ServerPassword", + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Admin Password", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the password for server admins in-game", + "Keywords": "admin,password,AdminPassword", + "FieldName": "AdminPassword", + "InputType": "password", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.AdminPassword", + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Player Limit", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the maximum number of players allowed on the server at one time", + "Keywords": "max,players,MaxPlayers", + "FieldName": "$MaxUsers", + "InputType": "number", + "MinValue": "1", + "MaxValue": "1000", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxPlayers", + "DefaultValue": "40", + "Placeholder": "40", + "Suffix": "players", + "EnumValues": {} + }, + { + "DisplayName": "Player Limit", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "", + "Keywords": "", + "FieldName": "$MaxUsers", + "InputType": "number", + "ParamFieldName": "/Script/Engine.GameSession.MaxPlayers", + "Hidden": true, + "EnumValues": {} + }, + { + "DisplayName": "Map Rotation (Game.ini)", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Map rotations can be set in Game.ini. Format: MapRotation=RSurv-AlgaraIsle_p. One map entry per line", + "Keywords": "map,rotation,MapRotation", + "FieldName": "MapRotation", + "InputType": "hidden", + "ParamFieldName": "MapRotation", + "EnumValues": {}, + "DefaultValue": "RSurv-AlgaraIsle_p" + }, + { + "DisplayName": "Game Save Name", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the name of the game save", + "Keywords": "game,save,name,GameSaveName", + "FieldName": "GameSaveName", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.GameSaveName", + "DefaultValue": "Save 1", + "Placeholder": "Save 1", + "Required": true, + "EnumValues": {} + }, + { + "DisplayName": "Maximum Ping (Game.ini)", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the maximum ping allowed for players to join the server. 0 = no limit", + "Keywords": "max,ping,MaxPing", + "FieldName": "MaxPing", + "InputType": "number", + "MinValue": "0", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxPing", + "DefaultValue": "195", + "Placeholder": "195", + "EnumValues": {} + }, + { + "DisplayName": "RCON Chat Messages Limit", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the limit for RCON chat messages", + "Keywords": "rcon,chat,messages,limit", + "FieldName": "RCONChatMessagesLimit", + "InputType": "number", + "MinValue": "0", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONChatMessagesLimit", + "DefaultValue": "50", + "Placeholder": "50", + "EnumValues": {} + }, + { + "DisplayName": "Network Maximum Tick Rate (SteamSockets)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Sets the maximum tick rate for the server's SteamSockets network driver", + "Keywords": "net,server,tick,rate,NetServerMaxTickRate", + "FieldName": "NetServerMaxTickRate", + "InputType": "number", + "MinValue": "1", + "ParamFieldName": "ini:Engine:[Script/SteamSockets.SteamSocketsNetDriver]:NetServerMaxTickRate", + "IncludeInCommandLine": true, + "SkipIfEmpty": true, + "DefaultValue": "30", + "Placeholder": "30", + "EnumValues": {} + }, + { + "DisplayName": "Resource Gain Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Sets the multiplier for resource gain, which determines how much players gather from resources", + "Keywords": "resource,gain,multiplier,ResourceGainMultiplier", + "FieldName": "ResourceGainMultiplier", + "InputType": "number", + "MinValue": "0", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.ResourceGainMultiplier", + "DefaultValue": "1", + "Placeholder": "1", + "EnumValues": {} + }, + { + "DisplayName": "Gold Coin Gain Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Sets the multiplier for gold coin gain, which determines how much gold players earn", + "Keywords": "gold,coin,gain,multiplier,GoldCoinGainMultiplier", + "FieldName": "GoldCoinGainMultiplier", + "InputType": "number", + "MinValue": "0", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GoldCoinGainMultiplier", + "DefaultValue": "1", + "Placeholder": "1", + "EnumValues": {} + }, + { + "DisplayName": "Global Crafting Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Sets the multiplier for crafting speed globally", + "Keywords": "crafting,multiplier,global,CraftingSpeedMultiplier", + "FieldName": "GlobalCraftingMultiplier", + "InputType": "number", + "MinValue": "0", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalCraftingMultiplier", + "DefaultValue": "1", + "Placeholder": "1", + "EnumValues": {} + }, + { + "DisplayName": "Global Smelting Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Sets the multiplier for smelting speed globally", + "Keywords": "smelting,multiplier,global,GlobalSmeltingMultiplier", + "FieldName": "GlobalSmeltingMultiplier", + "InputType": "number", + "MinValue": "0", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalSmeltingMultiplier", + "DefaultValue": "1", + "Placeholder": "1", + "EnumValues": {} + }, + { + "DisplayName": "Enable First Person Only", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "If set, the server will enforce first-person-only gameplay", + "Keywords": "first,person,only,Server.FirstPersonOnly", + "FieldName": "Server.FirstPersonOnly", + "InputType": "checkbox", + "ParamFieldName": "ini:Engine:[SystemSettings]:Server.FirstPersonOnly", + "IncludeInCommandLine": true, + "SkipIfEmpty": true, + "DefaultValue": "0", + "EnumValues": { + "False": "0", + "True": "1" + } + }, + { + "DisplayName": "RCON Server Max Uptime (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "If set, server will reboot after this uptime when commanded via RCON", + "Keywords": "RCON,uptime,reboot", + "FieldName": "RCON_ServerMaxUptime", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCON_ServerMaxUptime", + "DefaultValue": "1800", + "EnumValues": {} + }, + { + "DisplayName": "Max Server Uptime (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Hard cap on server uptime before auto-restart", + "Keywords": "max,uptime,restart", + "FieldName": "MaxServerUptime", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxServerUptime", + "DefaultValue": "28800", + "EnumValues": {} + }, + { + "DisplayName": "Public Listing", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Show this server in the public server browser", + "Keywords": "public,listing", + "FieldName": "Public", + "InputType": "checkbox", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.Public", + "DefaultValue": "True", + "EnumValues": { + "False": "False", + "True": "True" + } + }, + { + "DisplayName": "LAN Mode", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Run the server in LAN mode (not internet listed)", + "Keywords": "LAN,bLAN", + "FieldName": "bLAN", + "InputType": "checkbox", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.bLAN", + "DefaultValue": "False", + "EnumValues": { + "False": "False", + "True": "True" + } + }, + { + "DisplayName": "Anti-Cheat Enabled", + "Category": "Renown:stadia_controller", + "Subcategory": "Security:shield:4", + "Description": "Enable built-in anti-cheat", + "Keywords": "anticheat,bAntiCheat", + "FieldName": "bAntiCheat", + "InputType": "checkbox", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.bAntiCheat", + "DefaultValue": "False", + "EnumValues": { + "False": "False", + "True": "True" + } + }, + { + "DisplayName": "Game Description", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Short description shown in server details (optional)", + "Keywords": "description,GameDescription", + "FieldName": "GameDescription", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.GameDescription", + "DefaultValue": "Renown", + "EnumValues": {} + }, + { + "DisplayName": "Admin Whitelist (comma-separated SteamIDs)", + "Category": "Renown:stadia_controller", + "Subcategory": "Security:shield:4", + "Description": "Admins that can use in-game admin controls", + "Keywords": "admin,whitelist", + "FieldName": "AdminWhitelist", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.AdminWhitelist", + "DefaultValue": "", + "Placeholder": "7656119...,7656119...", + "EnumValues": {} + }, + { + "DisplayName": "Use First Map", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "If true, load the first map from rotation on boot", + "Keywords": "UseFirstMap", + "FieldName": "UseFirstMap", + "InputType": "checkbox", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.UseFirstMap", + "DefaultValue": "True", + "EnumValues": { + "False": "False", + "True": "True" + } + }, + { + "DisplayName": "Ban List Path / IDs", + "Category": "Renown:stadia_controller", + "Subcategory": "Security:shield:4", + "Description": "Ban list (file path or comma-separated IDs)", + "Keywords": "ban,BanList", + "FieldName": "BanList", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.BanList", + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Debug RCON Logs", + "Category": "Renown:stadia_controller", + "Subcategory": "Security:shield:4", + "Description": "Verbose RCON logging", + "Keywords": "debug,DebugRCON", + "FieldName": "DebugRCON", + "InputType": "checkbox", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.DebugRCON", + "DefaultValue": "True", + "EnumValues": { + "False": "False", + "True": "True" + } + }, + { + "DisplayName": "Match Time Limit (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Time limit for match-based modes", + "Keywords": "TimeLimit", + "FieldName": "TimeLimit", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.TimeLimit", + "DefaultValue": "0", + "EnumValues": {}, + "Placeholder": "0" + }, + { + "DisplayName": "Auto Balance Teams", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Automatically balance teams in team modes", + "Keywords": "AutoBalance", + "FieldName": "AutoBalance", + "InputType": "checkbox", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.AutoBalance", + "DefaultValue": "0", + "EnumValues": { + "False": "0", + "True": "1" + } + }, + { + "DisplayName": "Maintenance Rate", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Tuple format for maintenance scaling. Example: (X=0.500000,Y=1.000000)", + "Keywords": "MaintenanceRate", + "FieldName": "MaintenanceRate", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.MaintenanceRate", + "DefaultValue": "(X=0.500000,Y=1.000000)", + "Placeholder": "(X=0.500000,Y=1.000000)", + "EnumValues": {} + }, + { + "DisplayName": "Global Resource Respawn Time Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Multiplier for resource respawn timers", + "Keywords": "GlobalResourceRespawnTimeMultiplier", + "FieldName": "GlobalResourceRespawnTimeMultiplier", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalResourceRespawnTimeMultiplier", + "DefaultValue": "1", + "EnumValues": {}, + "Placeholder": "1" + }, + { + "DisplayName": "Global Maintenance Cost Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Multiplier for structure upkeep costs", + "Keywords": "GlobalMaintenanceCostMultiplier", + "FieldName": "GlobalMaintenanceCostMultiplier", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalMaintenanceCostMultiplier", + "DefaultValue": "1", + "EnumValues": {}, + "Placeholder": "1" + }, + { + "DisplayName": "Global Decay Damage Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Multiplier for decay damage to structures", + "Keywords": "GlobalDecayDamageMultiplier", + "FieldName": "GlobalDecayDamageMultiplier", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalDecayDamageMultiplier", + "DefaultValue": "1", + "EnumValues": {}, + "Placeholder": "1" + }, + { + "DisplayName": "Kick Idle Players", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Automatically kick idle players", + "Keywords": "KickIdlePlayers", + "FieldName": "KickIdlePlayers", + "InputType": "checkbox", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.KickIdlePlayers", + "DefaultValue": "True", + "EnumValues": { + "False": "False", + "True": "True" + } + }, + { + "DisplayName": "Idle Timeout (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Time before idle player is kicked", + "Keywords": "IdleTimeOutTime", + "FieldName": "IdleTimeOutTime", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.IdleTimeOutTime", + "DefaultValue": "300", + "EnumValues": {}, + "Placeholder": "300" + }, + { + "DisplayName": "Max Players Per Banner (clan)", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Limit of players per banner/clan (0 = unlimited)", + "Keywords": "MaxPlayersPerBanner", + "FieldName": "MaxPlayersPerBanner", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.MaxPlayersPerBanner", + "DefaultValue": "0", + "EnumValues": {}, + "Placeholder": "0" + }, + { + "DisplayName": "Auto Reboot Interval (min)", + "Category": "Renown:stadia_controller", + "Subcategory": "Maintenance:refresh-cw:5", + "Description": "Periodically reboot the server to keep performance healthy", + "Keywords": "ServerRebootTimeMinutes", + "FieldName": "ServerRebootTimeMinutes", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.ServerRebootTimeMinutes", + "DefaultValue": "120", + "EnumValues": {}, + "Placeholder": "120" + }, + { + "DisplayName": "Raid Window Times", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Raid window in tuple format. X = start hour, Y = end hour, using 24-hour time. Example: (X=16,Y=0) means 4 PM to midnight. If Y is less than X, the window wraps past midnight.", + "Keywords": "raid,window,times,RaidWindowTimes", + "FieldName": "RaidWindowTimes", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.RaidWindowTimes", + "DefaultValue": "(X=16,Y=0)", + "Placeholder": "(X=16,Y=0)", + "EnumValues": {} + }, + { + "DisplayName": "Offline Raid Protection", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Damage reduction applied when the defending player is offline. 1.0 = 100% damage reduction (no damage), 0.0 = no protection (full damage). Recommended: 0.99 for near-complete protection.", + "Keywords": "offline,raid,protection", + "FieldName": "OfflineRaidProtectionMultiplier", + "InputType": "number", + "MinValue": "0", + "MaxValue": ".99", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.OfflineRaidProtectionMultiplier", + "DefaultValue": "0.99", + "Placeholder": "0.99", + "EnumValues": {} + }, + { + "DisplayName": "Enable Server Queue", + "Category": "Renown:stadia_controller", + "Subcategory": "Queue:users:6", + "Description": "Enable join queue when server is full or starting", + "Keywords": "queue,bEnableServerQueue", + "FieldName": "bEnableServerQueue", + "InputType": "checkbox", + "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:bEnableServerQueue", + "DefaultValue": "True", + "EnumValues": { + "False": "False", + "True": "True" + } + }, + { + "DisplayName": "Run On LAN (Queue)", + "Category": "Renown:stadia_controller", + "Subcategory": "Queue:users:6", + "Description": "Run queue in LAN mode", + "Keywords": "bRunOnLan", + "FieldName": "bRunOnLan", + "InputType": "checkbox", + "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:bRunOnLan", + "DefaultValue": "False", + "EnumValues": { + "False": "False", + "True": "True" + } + }, + { + "DisplayName": "Client & Server Same Machine", + "Category": "Renown:stadia_controller", + "Subcategory": "Queue:users:6", + "Description": "Optimizations if client and server run on same machine", + "Keywords": "bIsServerClientRunningOnSameMachine", + "FieldName": "bIsServerClientRunningOnSameMachine", + "InputType": "checkbox", + "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:bIsServerClientRunningOnSameMachine", + "DefaultValue": "False", + "EnumValues": { + "False": "False", + "True": "True" + } + }, + { + "DisplayName": "Reconnection Grace (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Queue:users:6", + "Description": "How long a disconnecting player can rejoin without losing spot", + "Keywords": "ReconnectionGracePeriodSeconds", + "FieldName": "ReconnectionGracePeriodSeconds", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:ReconnectionGracePeriodSeconds", + "DefaultValue": "90", + "EnumValues": {} + }, + { + "DisplayName": "Max Join Duration (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Queue:users:6", + "Description": "Time window to complete a join from queue", + "Keywords": "ServerQueueMaxJoinDuration", + "FieldName": "ServerQueueMaxJoinDuration", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:ServerQueueMaxJoinDuration", + "DefaultValue": "300", + "EnumValues": {} + }, + { + "DisplayName": "Purge Pending Connections (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Queue:users:6", + "Description": "Purge half-open connections after this time", + "Keywords": "PurgePendingPlayerConnections", + "FieldName": "PurgePendingPlayerConnections", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:PurgePendingPlayerConnections", + "DefaultValue": "60", + "EnumValues": {} + }, + { + "DisplayName": "Player Slots To Consume", + "Category": "Renown:stadia_controller", + "Subcategory": "Queue:users:6", + "Description": "Reserved slots consumed by queue/internal services", + "Keywords": "PlayerSlotsToConsume", + "FieldName": "PlayerSlotsToConsume", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:PlayerSlotsToConsume", + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Max Client Reconnect Attempts", + "Category": "Renown:stadia_controller", + "Subcategory": "Queue:users:6", + "Description": "How many reconnect tries are allowed", + "Keywords": "MaxClientReconnectAttempts", + "FieldName": "MaxClientReconnectAttempts", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:MaxClientReconnectAttempts", + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Default Max Party Size", + "Category": "Renown:stadia_controller", + "Subcategory": "Social:users:7", + "Description": "Max party size in lobby", + "Keywords": "party,DefaultMaxPartySize", + "FieldName": "DefaultMaxPartySize", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Party.Party]:DefaultMaxPartySize", + "DefaultValue": "5", + "EnumValues": {} + }, + { + "DisplayName": "Wait For Players Time Remaining (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Social:users:7", + "Description": "Time the lobby waits before starting", + "Keywords": "Lobby,WaitForPlayersTimeRemaining", + "FieldName": "WaitForPlayersTimeRemaining", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Lobby.LobbyBeaconState]:WaitForPlayersTimeRemaining", + "DefaultValue": "20.0", + "EnumValues": {} + }, + { + "DisplayName": "Max Spectators", + "Category": "Renown:stadia_controller", + "Subcategory": "Social:users:7", + "Description": "Number of spectator slots", + "Keywords": "spectators,MaxSpectators", + "FieldName": "MaxSpectators", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Engine.GameSession]:MaxSpectators", + "DefaultValue": "2", + "EnumValues": {} + }, + { + "DisplayName": "Requires Push-To-Talk", + "Category": "Renown:stadia_controller", + "Subcategory": "Social:users:7", + "Description": "Require PTT for in-game voice", + "Keywords": "voice,bRequiresPushToTalk", + "FieldName": "bRequiresPushToTalk", + "InputType": "checkbox", + "ParamFieldName": "ini:Game:[Script/Engine.GameSession]:bRequiresPushToTalk", + "DefaultValue": "true", + "EnumValues": { + "False": "False", + "True": "True" + } + }, + { + "DisplayName": "Total Net Bandwidth (Game.ini)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Server total outgoing bandwidth budget (bytes/sec)", + "Keywords": "bandwidth,TotalNetBandwidth", + "FieldName": "TotalNetBandwidth_Game", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Engine.GameNetworkManager]:TotalNetBandwidth", + "DefaultValue": "4000000", + "EnumValues": {} + }, + { + "DisplayName": "Max Dynamic Bandwidth (Game.ini)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Max per-connection bandwidth cap", + "Keywords": "bandwidth,MaxDynamicBandwidth", + "FieldName": "MaxDynamicBandwidth_Game", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Engine.GameNetworkManager]:MaxDynamicBandwidth", + "DefaultValue": "100000", + "EnumValues": {} + }, + { + "DisplayName": "Min Dynamic Bandwidth (Game.ini)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Min per-connection bandwidth floor", + "Keywords": "bandwidth,MinDynamicBandwidth", + "FieldName": "MinDynamicBandwidth_Game", + "InputType": "number", + "ParamFieldName": "ini:Game:[Script/Engine.GameNetworkManager]:MinDynamicBandwidth", + "DefaultValue": "40000", + "EnumValues": {} + }, + { + "DisplayName": "Max Ping (Engine.ini override)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Engine.ini override for maximum ping filter", + "Keywords": "MaxPing,override", + "FieldName": "MaxPing_Engine", + "InputType": "number", + "ParamFieldName": "ini:Engine:[/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C]:MaxPing", + "DefaultValue": "500", + "EnumValues": {} + }, + { + "DisplayName": "Smooth Frame Rate", + "Category": "Renown:stadia_controller", + "Subcategory": "Performance:activity:8", + "Description": "Enable UE frame smoothing on the server", + "Keywords": "bSmoothFrameRate", + "FieldName": "bSmoothFrameRate", + "InputType": "checkbox", + "ParamFieldName": "ini:Engine:[Script/Engine.GameEngine]:bSmoothFrameRate", + "DefaultValue": "True", + "EnumValues": { + "False": "False", + "True": "True" + } + }, + { + "DisplayName": "Total Net Bandwidth (Engine.ini)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Engine-level total outgoing bandwidth budget (bytes/sec)", + "Keywords": "bandwidth,TotalNetBandwidth", + "FieldName": "TotalNetBandwidth_Engine", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/Engine.GameNetworkManager]:TotalNetBandwidth", + "DefaultValue": "500000", + "EnumValues": {} + }, + { + "DisplayName": "Max Dynamic Bandwidth (Engine.ini)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Engine-level per-connection bandwidth cap", + "Keywords": "bandwidth,MaxDynamicBandwidth", + "FieldName": "MaxDynamicBandwidth_Engine", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/Engine.GameNetworkManager]:MaxDynamicBandwidth", + "DefaultValue": "80000", + "EnumValues": {} + }, + { + "DisplayName": "Min Dynamic Bandwidth (Engine.ini)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Engine-level per-connection bandwidth floor", + "Keywords": "bandwidth,MinDynamicBandwidth", + "FieldName": "MinDynamicBandwidth_Engine", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/Engine.GameNetworkManager]:MinDynamicBandwidth", + "DefaultValue": "20000", + "EnumValues": {} + }, + { + "DisplayName": "IP Driver: Allow Peer Connections", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Allow peer-to-peer client connections", + "Keywords": "IpNetDriver,AllowPeerConnections", + "FieldName": "AllowPeerConnections", + "InputType": "checkbox", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:AllowPeerConnections", + "DefaultValue": "False", + "EnumValues": { + "False": "False", + "True": "True" + } + }, + { + "DisplayName": "IP Driver: Connection Timeout (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Timeout for network connections", + "Keywords": "IpNetDriver,ConnectionTimeout", + "FieldName": "ConnectionTimeout", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:ConnectionTimeout", + "DefaultValue": "60.0", + "EnumValues": {} + }, + { + "DisplayName": "IP Driver: Initial Connect Timeout (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Initial connection timeout", + "Keywords": "IpNetDriver,InitialConnectTimeout", + "FieldName": "InitialConnectTimeout", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:InitialConnectTimeout", + "DefaultValue": "60.0", + "EnumValues": {} + }, + { + "DisplayName": "IP Driver: Max Client Rate", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Max client rate (bytes/sec)", + "Keywords": "IpNetDriver,MaxClientRate", + "FieldName": "MaxClientRate", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:MaxClientRate", + "DefaultValue": "100000", + "EnumValues": {} + }, + { + "DisplayName": "IP Driver: Max Internet Client Rate", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Max internet client rate (bytes/sec)", + "Keywords": "IpNetDriver,MaxInternetClientRate", + "FieldName": "MaxInternetClientRate", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:MaxInternetClientRate", + "DefaultValue": "100000", + "EnumValues": {} + }, + { + "DisplayName": "IP Driver: Relevant Timeout (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Relevancy timeout", + "Keywords": "IpNetDriver,RelevantTimeout", + "FieldName": "RelevantTimeout", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:RelevantTimeout", + "DefaultValue": "5.0", + "EnumValues": {} + }, + { + "DisplayName": "IP Driver: Spawn Priority Seconds", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Spawn priority seconds", + "Keywords": "IpNetDriver,SpawnPrioritySeconds", + "FieldName": "SpawnPrioritySeconds", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:SpawnPrioritySeconds", + "DefaultValue": "1.0", + "EnumValues": {} + }, + { + "DisplayName": "IP Driver: Server Travel Pause (sec)", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Pause during seamless travel", + "Keywords": "IpNetDriver,ServerTravelPause", + "FieldName": "ServerTravelPause", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:ServerTravelPause", + "DefaultValue": "4.0", + "EnumValues": {} + }, + { + "DisplayName": "IP Driver: Net Server Max Tick Rate", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Tick rate for IpNetDriver", + "Keywords": "IpNetDriver,NetServerMaxTickRate", + "FieldName": "IpNetDriver_NetServerMaxTickRate", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:NetServerMaxTickRate", + "DefaultValue": "30", + "EnumValues": {} + }, + { + "DisplayName": "IP Driver: Max Net Tick Rate", + "Category": "Renown:stadia_controller", + "Subcategory": "Networking:globe-2:3", + "Description": "Overall max network tick rate", + "Keywords": "IpNetDriver,MaxNetTickRate", + "FieldName": "MaxNetTickRate", + "InputType": "number", + "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:MaxNetTickRate", + "DefaultValue": "120", + "EnumValues": {} + }, + { + "DisplayName": "DDoS Detection Enabled", + "Category": "Renown:stadia_controller", + "Subcategory": "Security:shield:4", + "Description": "Enable UE DDoS detection", + "Keywords": "DDoS,bDDoSDetection", + "FieldName": "bDDoSDetection", + "InputType": "checkbox", + "ParamFieldName": "ini:Engine:[DDoSDetection]:bDDoSDetection", + "DefaultValue": "False", + "EnumValues": { + "False": "False", + "True": "True" + } + }, + { + "DisplayName": "DDoS Analytics Enabled", + "Category": "Renown:stadia_controller", + "Subcategory": "Security:shield:4", + "Description": "Enable DDoS analytics", + "Keywords": "DDoS,bDDoSAnalytics", + "FieldName": "bDDoSAnalytics", + "InputType": "checkbox", + "ParamFieldName": "ini:Engine:[DDoSDetection]:bDDoSAnalytics", + "DefaultValue": "False", + "EnumValues": { + "False": "False", + "True": "True" + } + }, + { + "DisplayName": "DDoS Log Spam Limit", + "Category": "Renown:stadia_controller", + "Subcategory": "Security:shield:4", + "Description": "Limit for DDoS log spam", + "Keywords": "DDoS,Log", + "FieldName": "DDoSLogSpamLimit", + "InputType": "number", + "ParamFieldName": "ini:Engine:[DDoSDetection]:DDoSLogSpamLimit", + "DefaultValue": "64", + "EnumValues": {} + }, + { + "DisplayName": "Hitch Time Quota (ms)", + "Category": "Renown:stadia_controller", + "Subcategory": "Performance:activity:8", + "Description": "Hitch detection time quota", + "Keywords": "HitchTimeQuotaMS", + "FieldName": "HitchTimeQuotaMS", + "InputType": "number", + "ParamFieldName": "ini:Engine:[DDoSDetection]:HitchTimeQuotaMS", + "DefaultValue": "500", + "EnumValues": {} + }, + { + "DisplayName": "Hitch Frame Tolerance", + "Category": "Renown:stadia_controller", + "Subcategory": "Performance:activity:8", + "Description": "Hitch detection frame tolerance", + "Keywords": "HitchFrameTolerance", + "FieldName": "HitchFrameTolerance", + "InputType": "number", + "ParamFieldName": "ini:Engine:[DDoSDetection]:HitchFrameTolerance", + "DefaultValue": "3", + "EnumValues": {} + }, + { + "DisplayName": "Purge Logs After (days)", + "Category": "Renown:stadia_controller", + "Subcategory": "Maintenance:refresh-cw:5", + "Description": "Delete logs older than this many days", + "Keywords": "logs,PurgeLogsDays", + "FieldName": "PurgeLogsDays", + "InputType": "number", + "ParamFieldName": "ini:Engine:[LogFiles]:PurgeLogsDays", + "DefaultValue": "5", + "EnumValues": {} + }, + { + "DisplayName": "Max Log Files On Disk", + "Category": "Renown:stadia_controller", + "Subcategory": "Maintenance:refresh-cw:5", + "Description": "Limit number of rotated log files", + "Keywords": "logs,MaxLogFilesOnDisk", + "FieldName": "MaxLogFilesOnDisk", + "InputType": "number", + "ParamFieldName": "ini:Engine:[LogFiles]:MaxLogFilesOnDisk", + "DefaultValue": "10", + "EnumValues": {} + }, + { + "DisplayName": "Log Times", + "Category": "Renown:stadia_controller", + "Subcategory": "Maintenance:refresh-cw:5", + "Description": "Include timestamps in logs", + "Keywords": "logs,LogTimes", + "FieldName": "LogTimes", + "InputType": "checkbox", + "ParamFieldName": "ini:Engine:[LogFiles]:LogTimes", + "DefaultValue": "True", + "EnumValues": { + "False": "False", + "True": "True" + } + }, + { + "DisplayName": "Core.Log Advanced (raw block)", + "Category": "Renown:stadia_controller", + "Subcategory": "Maintenance:refresh-cw:5", + "Description": "Optional advanced Core.Log overrides; paste lines like 'Online=all off' each on new line", + "Keywords": "Core.Log,advanced", + "FieldName": "CoreLogRaw", + "InputType": "textarea", + "ParamFieldName": "ini:Engine:[Core.Log]:__raw__", + "DefaultValue": "Online=all off\nOnlineSession=log\nOnlineGame=log\nSteamCore=all off\nAssetLog=all off\nLogRedpointEOS=all off\nLogRedpointEOSIdentity=all off\nLogRedpointEOSSocket=all off\nLogRedpointEOSSocketLifecycle=all off\nLogRedpointEOSSessionListening=all off\nLogRedpointEOSNetworkTrace=all off\nLogRedpointEOSNetworkAuth=all off\nLogRedpointEOSStat=all off\nLogRedpointEOSAntiCheat=all off\nLogRedpointEOSFriends=all off\nLogRedpointEOSFileTransfer=all off\nLogRedpointEOSVoiceChat=all off\nLogBeacon=log\nLogServerQueue=log", + "EnumValues": {} + }, + { + "DisplayName": "Server Language Culture", + "Category": "Renown:stadia_controller", + "Subcategory": "Localization:languages:9", + "Description": "Set server culture/language (eg. en, es-MX)", + "Keywords": "language,culture,Internationalization", + "FieldName": "Culture", + "InputType": "text", + "ParamFieldName": "ini:GameUserSettings:[Internationalization]:Culture", + "DefaultValue": "en", + "EnumValues": {} + }, + { + "DisplayName": "EOS Voice Chat Enabled", + "Category": "Renown:stadia_controller", + "Subcategory": "Voice:mic:10", + "Description": "Enable Epic Online Services voice chat", + "Keywords": "voice,EOS,bEnabled", + "FieldName": "EOSVoiceChatEnabled", + "InputType": "checkbox", + "ParamFieldName": "ini:Engine:[EOSVoiceChat]:bEnabled", + "DefaultValue": "True", + "EnumValues": { + "False": "False", + "True": "True" + } + }, + { + "DisplayName": "Server Release Version", + "Category": "Updates", + "Subcategory": "Steam Downloads:download", + "Description": "Sets the server release version to install. Update the server after changing this setting", + "Keywords": "server,version,public,beta", + "FieldName": "ServerVersion", + "InputType": "enum", + "ParamFieldName": "ServerVersion", + "DefaultValue": "public", + "EnumValues": { + "public": "Public (default)", + "beta": "Beta" + } } - }, - { - "DisplayName": "Custom Server Region", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets a custom region tag for the server, if 'Custom' is selected under Server Region", - "Keywords": "custom,region", - "FieldName": "CustomRegion", - "InputType": "text", - "ParamFieldName": "CustomRegion", - "DefaultValue": "", - "Placeholder": "Modded", - "EnumValues": {} - }, - { - "DisplayName": "Make Server Private", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "If set, the server will not be listed in the server browser and can only be joined via direct connect", - "Keywords": "private,session,PrivateSession", - "FieldName": "PrivateSession", - "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.PrivateSession", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Server MOTD", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the message of the day (MOTD) shown to players when they join", - "Keywords": "motd,message,day", - "FieldName": "MOTD", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MOTD", - "DefaultValue": "NSLOCTEXT(\"[2CF2D1E04F419B14490A65BF06750767]\", \"F67B0BE94A3C4A2665B05284056D0757\", \"Welcome to Renown, in order to play on this server you must accept the following Rules.\\r\\n\\r\\n1. **Respect and Courtesy**: Treat fellow players and staff with respect. Harassment, hate speech, or any form of discrimination will not be tolerated.\\r\\n\\r\\n2. **Cheating and Exploits**: Any use of cheats, hacks, exploits, or any unfair advantage is strictly prohibited. Players found violating this rule will face severe consequences, including permanent bans.\\r\\n\\r\\n3. **Language and Content**: Keep chat and in-game communication appropriate for all ages. Avoid using offensive language, explicit content, or engaging in discussions that may make others uncomfortable.\\r\\n\\r\\n4. **No Spamming or Advertising**: Do not spam chat with repetitive messages or advertise external services or products without permission from server staff.\\r\\n\\r\\n5. **Bug Reporting**: If you encounter any bugs or issues, report them to server staff or file a bug report promptly. Exploiting or abusing bugs for personal gain is not allowed.\\r\\n\\r\\n6. **Impersonation**: Do not impersonate server staff or other players. This includes using similar names or pretending to have authority you do not possess.\\r\\n\\r\\n7. **Final Authority**: Server staff have the final say in all matters concerning rule enforcement and disciplinary actions. Respect their decisions and cooperate with them at all times.\\r\\n\\r\\nRemember, these rules are in place to ensure a fair, enjoyable, and respectful gaming environment for all players. Violating these rules may result in warnings, temporary suspensions, or permanent bans, depending on the severity of the offense. Enjoy your time on the server and have fun gaming!\")", - "EnumValues": {} - }, - { - "DisplayName": "Server Password", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the password required to join the server. Empty = no password", - "Keywords": "server,password,ServerPassword", - "FieldName": "ServerPassword", - "InputType": "password", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.ServerPassword", - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Admin Password", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the password for server admins in-game", - "Keywords": "admin,password,AdminPassword", - "FieldName": "AdminPassword", - "InputType": "password", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.AdminPassword", - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Player Limit", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the maximum number of players allowed on the server at one time", - "Keywords": "max,players,MaxPlayers", - "FieldName": "$MaxUsers", - "InputType": "number", - "MinValue": "1", - "MaxValue": "1000", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxPlayers", - "DefaultValue": "40", - "Placeholder": "40", - "Suffix": "players", - "EnumValues": {} - }, - { - "DisplayName": "Player Limit", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "", - "Keywords": "", - "FieldName": "$MaxUsers", - "InputType": "number", - "ParamFieldName": "/Script/Engine.GameSession.MaxPlayers", - "Hidden": true, - "EnumValues": {} - }, - { - "DisplayName": "Map Rotation (Game.ini)", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Map rotations can be set in Game.ini. Format: MapRotation=RSurv-AlgaraIsle_p. One map entry per line", - "Keywords": "map,rotation,MapRotation", - "FieldName": "MapRotation", - "InputType": "hidden", - "ParamFieldName": "MapRotation", - "EnumValues": {}, - "DefaultValue": "RSurv-AlgaraIsle_p" - }, - { - "DisplayName": "Game Save Name", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the name of the game save", - "Keywords": "game,save,name,GameSaveName", - "FieldName": "GameSaveName", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.GameSaveName", - "DefaultValue": "Save 1", - "Placeholder": "Save 1", - "Required": true, - "EnumValues": {} - }, - { - "DisplayName": "Maximum Ping (Game.ini)", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the maximum ping allowed for players to join the server. 0 = no limit", - "Keywords": "max,ping,MaxPing", - "FieldName": "MaxPing", - "InputType": "number", - "MinValue": "0", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxPing", - "DefaultValue": "195", - "Placeholder": "195", - "EnumValues": {} - }, - { - "DisplayName": "RCON Chat Messages Limit", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the limit for RCON chat messages", - "Keywords": "rcon,chat,messages,limit", - "FieldName": "RCONChatMessagesLimit", - "InputType": "number", - "MinValue": "0", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONChatMessagesLimit", - "DefaultValue": "50", - "Placeholder": "50", - "EnumValues": {} - }, - { - "DisplayName": "Network Maximum Tick Rate (SteamSockets)", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Sets the maximum tick rate for the server's SteamSockets network driver", - "Keywords": "net,server,tick,rate,NetServerMaxTickRate", - "FieldName": "NetServerMaxTickRate", - "InputType": "number", - "MinValue": "1", - "ParamFieldName": "ini:Engine:[Script/SteamSockets.SteamSocketsNetDriver]:NetServerMaxTickRate", - "IncludeInCommandLine": true, - "SkipIfEmpty": true, - "DefaultValue": "30", - "Placeholder": "30", - "EnumValues": {} - }, - { - "DisplayName": "Resource Gain Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Sets the multiplier for resource gain, which determines how much players gather from resources", - "Keywords": "resource,gain,multiplier,ResourceGainMultiplier", - "FieldName": "ResourceGainMultiplier", - "InputType": "number", - "MinValue": "0", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.ResourceGainMultiplier", - "DefaultValue": "1", - "Placeholder": "1", - "EnumValues": {} - }, - { - "DisplayName": "Gold Coin Gain Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Sets the multiplier for gold coin gain, which determines how much gold players earn", - "Keywords": "gold,coin,gain,multiplier,GoldCoinGainMultiplier", - "FieldName": "GoldCoinGainMultiplier", - "InputType": "number", - "MinValue": "0", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GoldCoinGainMultiplier", - "DefaultValue": "1", - "Placeholder": "1", - "EnumValues": {} - }, - { - "DisplayName": "Global Crafting Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Sets the multiplier for crafting speed globally", - "Keywords": "crafting,multiplier,global,CraftingSpeedMultiplier", - "FieldName": "GlobalCraftingMultiplier", - "InputType": "number", - "MinValue": "0", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalCraftingMultiplier", - "DefaultValue": "1", - "Placeholder": "1", - "EnumValues": {} - }, - { - "DisplayName": "Global Smelting Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Sets the multiplier for smelting speed globally", - "Keywords": "smelting,multiplier,global,GlobalSmeltingMultiplier", - "FieldName": "GlobalSmeltingMultiplier", - "InputType": "number", - "MinValue": "0", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalSmeltingMultiplier", - "DefaultValue": "1", - "Placeholder": "1", - "EnumValues": {} - }, - { - "DisplayName": "Enable First Person Only", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "If set, the server will enforce first-person-only gameplay", - "Keywords": "first,person,only,Server.FirstPersonOnly", - "FieldName": "Server.FirstPersonOnly", - "InputType": "checkbox", - "ParamFieldName": "ini:Engine:[SystemSettings]:Server.FirstPersonOnly", - "IncludeInCommandLine": true, - "SkipIfEmpty": true, - "DefaultValue": "0", - "EnumValues": { - "False": "0", - "True": "1" - } - }, - { - "DisplayName": "RCON Server Max Uptime (sec)", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "If set, server will reboot after this uptime when commanded via RCON", - "Keywords": "RCON,uptime,reboot", - "FieldName": "RCON_ServerMaxUptime", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCON_ServerMaxUptime", - "DefaultValue": "1800", - "EnumValues": {} - }, - { - "DisplayName": "Max Server Uptime (sec)", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Hard cap on server uptime before auto-restart", - "Keywords": "max,uptime,restart", - "FieldName": "MaxServerUptime", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxServerUptime", - "DefaultValue": "28800", - "EnumValues": {} - }, - { - "DisplayName": "Public Listing", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Show this server in the public server browser", - "Keywords": "public,listing", - "FieldName": "Public", - "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.Public", - "DefaultValue": "True", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "LAN Mode", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Run the server in LAN mode (not internet listed)", - "Keywords": "LAN,bLAN", - "FieldName": "bLAN", - "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.bLAN", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Anti-Cheat Enabled", - "Category": "Renown:stadia_controller", - "Subcategory": "Security:shield:4", - "Description": "Enable built-in anti-cheat", - "Keywords": "anticheat,bAntiCheat", - "FieldName": "bAntiCheat", - "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.bAntiCheat", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Game Description", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Short description shown in server details (optional)", - "Keywords": "description,GameDescription", - "FieldName": "GameDescription", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.GameDescription", - "DefaultValue": "Renown", - "EnumValues": {} - }, - { - "DisplayName": "Admin Whitelist (comma-separated SteamIDs)", - "Category": "Renown:stadia_controller", - "Subcategory": "Security:shield:4", - "Description": "Admins that can use in-game admin controls", - "Keywords": "admin,whitelist", - "FieldName": "AdminWhitelist", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.AdminWhitelist", - "DefaultValue": "", - "Placeholder": "7656119...,7656119...", - "EnumValues": {} - }, - { - "DisplayName": "Use First Map", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "If true, load the first map from rotation on boot", - "Keywords": "UseFirstMap", - "FieldName": "UseFirstMap", - "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.UseFirstMap", - "DefaultValue": "True", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Ban List Path / IDs", - "Category": "Renown:stadia_controller", - "Subcategory": "Security:shield:4", - "Description": "Ban list (file path or comma-separated IDs)", - "Keywords": "ban,BanList", - "FieldName": "BanList", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.BanList", - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Debug RCON Logs", - "Category": "Renown:stadia_controller", - "Subcategory": "Security:shield:4", - "Description": "Verbose RCON logging", - "Keywords": "debug,DebugRCON", - "FieldName": "DebugRCON", - "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.DebugRCON", - "DefaultValue": "True", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Match Time Limit (sec)", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Time limit for match-based modes", - "Keywords": "TimeLimit", - "FieldName": "TimeLimit", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.TimeLimit", - "DefaultValue": "0", - "EnumValues": {}, - "Placeholder": "0" - }, - { - "DisplayName": "Auto Balance Teams", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Automatically balance teams in team modes", - "Keywords": "AutoBalance", - "FieldName": "AutoBalance", - "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.AutoBalance", - "DefaultValue": "0", - "EnumValues": { - "False": "0", - "True": "1" - } - }, - { - "DisplayName": "Maintenance Rate", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Tuple format for maintenance scaling. Example: (X=0.500000,Y=1.000000)", - "Keywords": "MaintenanceRate", - "FieldName": "MaintenanceRate", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.MaintenanceRate", - "DefaultValue": "(X=0.500000,Y=1.000000)", - "Placeholder": "(X=0.500000,Y=1.000000)", - "EnumValues": {} - }, - { - "DisplayName": "Global Resource Respawn Time Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Multiplier for resource respawn timers", - "Keywords": "GlobalResourceRespawnTimeMultiplier", - "FieldName": "GlobalResourceRespawnTimeMultiplier", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalResourceRespawnTimeMultiplier", - "DefaultValue": "1", - "EnumValues": {}, - "Placeholder": "1" - }, - { - "DisplayName": "Global Maintenance Cost Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Multiplier for structure upkeep costs", - "Keywords": "GlobalMaintenanceCostMultiplier", - "FieldName": "GlobalMaintenanceCostMultiplier", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalMaintenanceCostMultiplier", - "DefaultValue": "1", - "EnumValues": {}, - "Placeholder": "1" - }, - { - "DisplayName": "Global Decay Damage Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Multiplier for decay damage to structures", - "Keywords": "GlobalDecayDamageMultiplier", - "FieldName": "GlobalDecayDamageMultiplier", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalDecayDamageMultiplier", - "DefaultValue": "1", - "EnumValues": {}, - "Placeholder": "1" - }, - { - "DisplayName": "Kick Idle Players", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Automatically kick idle players", - "Keywords": "KickIdlePlayers", - "FieldName": "KickIdlePlayers", - "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.KickIdlePlayers", - "DefaultValue": "True", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Idle Timeout (sec)", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Time before idle player is kicked", - "Keywords": "IdleTimeOutTime", - "FieldName": "IdleTimeOutTime", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.IdleTimeOutTime", - "DefaultValue": "300", - "EnumValues": {}, - "Placeholder": "300" - }, - { - "DisplayName": "Max Players Per Banner (clan)", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Limit of players per banner/clan (0 = unlimited)", - "Keywords": "MaxPlayersPerBanner", - "FieldName": "MaxPlayersPerBanner", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.MaxPlayersPerBanner", - "DefaultValue": "0", - "EnumValues": {}, - "Placeholder": "0" - }, - { - "DisplayName": "Auto Reboot Interval (min)", - "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:refresh-cw:5", - "Description": "Periodically reboot the server to keep performance healthy", - "Keywords": "ServerRebootTimeMinutes", - "FieldName": "ServerRebootTimeMinutes", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.ServerRebootTimeMinutes", - "DefaultValue": "120", - "EnumValues": {}, - "Placeholder": "120" - }, - { - "DisplayName": "Raid Window Times", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Raid window in tuple format. X = start hour, Y = end hour, using 24-hour time. Example: (X=16,Y=0) means 4 PM to midnight. If Y is less than X, the window wraps past midnight.", - "Keywords": "raid,window,times,RaidWindowTimes", - "FieldName": "RaidWindowTimes", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.RaidWindowTimes", - "DefaultValue": "(X=16,Y=0)", - "Placeholder": "(X=16,Y=0)", - "EnumValues": {} - }, -{ - "DisplayName": "Offline Raid Protection", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Damage reduction applied when the defending player is offline. 1.0 = 100% damage reduction (no damage), 0.0 = no protection (full damage). Recommended: 0.99 for near-complete protection.", - "Keywords": "offline,raid,protection", - "FieldName": "OfflineRaidProtectionMultiplier", - "InputType": "number", - "MinValue": "0", - "MaxValue": ".99", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.OfflineRaidProtectionMultiplier", - "DefaultValue": "0.99", - "Placeholder": "0.99", - "EnumValues": {} -}, - { - "DisplayName": "Enable Server Queue", - "Category": "Renown:stadia_controller", - "Subcategory": "Queue:users:6", - "Description": "Enable join queue when server is full or starting", - "Keywords": "queue,bEnableServerQueue", - "FieldName": "bEnableServerQueue", - "InputType": "checkbox", - "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:bEnableServerQueue", - "DefaultValue": "True", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Run On LAN (Queue)", - "Category": "Renown:stadia_controller", - "Subcategory": "Queue:users:6", - "Description": "Run queue in LAN mode", - "Keywords": "bRunOnLan", - "FieldName": "bRunOnLan", - "InputType": "checkbox", - "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:bRunOnLan", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Client & Server Same Machine", - "Category": "Renown:stadia_controller", - "Subcategory": "Queue:users:6", - "Description": "Optimizations if client and server run on same machine", - "Keywords": "bIsServerClientRunningOnSameMachine", - "FieldName": "bIsServerClientRunningOnSameMachine", - "InputType": "checkbox", - "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:bIsServerClientRunningOnSameMachine", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Reconnection Grace (sec)", - "Category": "Renown:stadia_controller", - "Subcategory": "Queue:users:6", - "Description": "How long a disconnecting player can rejoin without losing spot", - "Keywords": "ReconnectionGracePeriodSeconds", - "FieldName": "ReconnectionGracePeriodSeconds", - "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:ReconnectionGracePeriodSeconds", - "DefaultValue": "90", - "EnumValues": {} - }, - { - "DisplayName": "Max Join Duration (sec)", - "Category": "Renown:stadia_controller", - "Subcategory": "Queue:users:6", - "Description": "Time window to complete a join from queue", - "Keywords": "ServerQueueMaxJoinDuration", - "FieldName": "ServerQueueMaxJoinDuration", - "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:ServerQueueMaxJoinDuration", - "DefaultValue": "300", - "EnumValues": {} - }, - { - "DisplayName": "Purge Pending Connections (sec)", - "Category": "Renown:stadia_controller", - "Subcategory": "Queue:users:6", - "Description": "Purge half-open connections after this time", - "Keywords": "PurgePendingPlayerConnections", - "FieldName": "PurgePendingPlayerConnections", - "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:PurgePendingPlayerConnections", - "DefaultValue": "60", - "EnumValues": {} - }, - { - "DisplayName": "Player Slots To Consume", - "Category": "Renown:stadia_controller", - "Subcategory": "Queue:users:6", - "Description": "Reserved slots consumed by queue/internal services", - "Keywords": "PlayerSlotsToConsume", - "FieldName": "PlayerSlotsToConsume", - "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:PlayerSlotsToConsume", - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Max Client Reconnect Attempts", - "Category": "Renown:stadia_controller", - "Subcategory": "Queue:users:6", - "Description": "How many reconnect tries are allowed", - "Keywords": "MaxClientReconnectAttempts", - "FieldName": "MaxClientReconnectAttempts", - "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:MaxClientReconnectAttempts", - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Default Max Party Size", - "Category": "Renown:stadia_controller", - "Subcategory": "Social:users:7", - "Description": "Max party size in lobby", - "Keywords": "party,DefaultMaxPartySize", - "FieldName": "DefaultMaxPartySize", - "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Party.Party]:DefaultMaxPartySize", - "DefaultValue": "5", - "EnumValues": {} - }, - { - "DisplayName": "Wait For Players Time Remaining (sec)", - "Category": "Renown:stadia_controller", - "Subcategory": "Social:users:7", - "Description": "Time the lobby waits before starting", - "Keywords": "Lobby,WaitForPlayersTimeRemaining", - "FieldName": "WaitForPlayersTimeRemaining", - "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Lobby.LobbyBeaconState]:WaitForPlayersTimeRemaining", - "DefaultValue": "20.0", - "EnumValues": {} - }, - { - "DisplayName": "Max Spectators", - "Category": "Renown:stadia_controller", - "Subcategory": "Social:users:7", - "Description": "Number of spectator slots", - "Keywords": "spectators,MaxSpectators", - "FieldName": "MaxSpectators", - "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Engine.GameSession]:MaxSpectators", - "DefaultValue": "2", - "EnumValues": {} - }, - { - "DisplayName": "Requires Push-To-Talk", - "Category": "Renown:stadia_controller", - "Subcategory": "Social:users:7", - "Description": "Require PTT for in-game voice", - "Keywords": "voice,bRequiresPushToTalk", - "FieldName": "bRequiresPushToTalk", - "InputType": "checkbox", - "ParamFieldName": "ini:Game:[Script/Engine.GameSession]:bRequiresPushToTalk", - "DefaultValue": "true", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Total Net Bandwidth (Game.ini)", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Server total outgoing bandwidth budget (bytes/sec)", - "Keywords": "bandwidth,TotalNetBandwidth", - "FieldName": "TotalNetBandwidth_Game", - "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Engine.GameNetworkManager]:TotalNetBandwidth", - "DefaultValue": "4000000", - "EnumValues": {} - }, - { - "DisplayName": "Max Dynamic Bandwidth (Game.ini)", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Max per-connection bandwidth cap", - "Keywords": "bandwidth,MaxDynamicBandwidth", - "FieldName": "MaxDynamicBandwidth_Game", - "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Engine.GameNetworkManager]:MaxDynamicBandwidth", - "DefaultValue": "100000", - "EnumValues": {} - }, - { - "DisplayName": "Min Dynamic Bandwidth (Game.ini)", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Min per-connection bandwidth floor", - "Keywords": "bandwidth,MinDynamicBandwidth", - "FieldName": "MinDynamicBandwidth_Game", - "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Engine.GameNetworkManager]:MinDynamicBandwidth", - "DefaultValue": "40000", - "EnumValues": {} - }, - { - "DisplayName": "Max Ping (Engine.ini override)", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Engine.ini override for maximum ping filter", - "Keywords": "MaxPing,override", - "FieldName": "MaxPing_Engine", - "InputType": "number", - "ParamFieldName": "ini:Engine:[/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C]:MaxPing", - "DefaultValue": "500", - "EnumValues": {} - }, - { - "DisplayName": "Smooth Frame Rate", - "Category": "Renown:stadia_controller", - "Subcategory": "Performance:activity:8", - "Description": "Enable UE frame smoothing on the server", - "Keywords": "bSmoothFrameRate", - "FieldName": "bSmoothFrameRate", - "InputType": "checkbox", - "ParamFieldName": "ini:Engine:[Script/Engine.GameEngine]:bSmoothFrameRate", - "DefaultValue": "True", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Total Net Bandwidth (Engine.ini)", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Engine-level total outgoing bandwidth budget (bytes/sec)", - "Keywords": "bandwidth,TotalNetBandwidth", - "FieldName": "TotalNetBandwidth_Engine", - "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/Engine.GameNetworkManager]:TotalNetBandwidth", - "DefaultValue": "500000", - "EnumValues": {} - }, - { - "DisplayName": "Max Dynamic Bandwidth (Engine.ini)", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Engine-level per-connection bandwidth cap", - "Keywords": "bandwidth,MaxDynamicBandwidth", - "FieldName": "MaxDynamicBandwidth_Engine", - "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/Engine.GameNetworkManager]:MaxDynamicBandwidth", - "DefaultValue": "80000", - "EnumValues": {} - }, - { - "DisplayName": "Min Dynamic Bandwidth (Engine.ini)", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Engine-level per-connection bandwidth floor", - "Keywords": "bandwidth,MinDynamicBandwidth", - "FieldName": "MinDynamicBandwidth_Engine", - "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/Engine.GameNetworkManager]:MinDynamicBandwidth", - "DefaultValue": "20000", - "EnumValues": {} - }, - { - "DisplayName": "IP Driver: Allow Peer Connections", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Allow peer-to-peer client connections", - "Keywords": "IpNetDriver,AllowPeerConnections", - "FieldName": "AllowPeerConnections", - "InputType": "checkbox", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:AllowPeerConnections", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "IP Driver: Connection Timeout (sec)", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Timeout for network connections", - "Keywords": "IpNetDriver,ConnectionTimeout", - "FieldName": "ConnectionTimeout", - "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:ConnectionTimeout", - "DefaultValue": "60.0", - "EnumValues": {} - }, - { - "DisplayName": "IP Driver: Initial Connect Timeout (sec)", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Initial connection timeout", - "Keywords": "IpNetDriver,InitialConnectTimeout", - "FieldName": "InitialConnectTimeout", - "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:InitialConnectTimeout", - "DefaultValue": "60.0", - "EnumValues": {} - }, - { - "DisplayName": "IP Driver: Max Client Rate", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Max client rate (bytes/sec)", - "Keywords": "IpNetDriver,MaxClientRate", - "FieldName": "MaxClientRate", - "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:MaxClientRate", - "DefaultValue": "100000", - "EnumValues": {} - }, - { - "DisplayName": "IP Driver: Max Internet Client Rate", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Max internet client rate (bytes/sec)", - "Keywords": "IpNetDriver,MaxInternetClientRate", - "FieldName": "MaxInternetClientRate", - "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:MaxInternetClientRate", - "DefaultValue": "100000", - "EnumValues": {} - }, - { - "DisplayName": "IP Driver: Relevant Timeout (sec)", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Relevancy timeout", - "Keywords": "IpNetDriver,RelevantTimeout", - "FieldName": "RelevantTimeout", - "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:RelevantTimeout", - "DefaultValue": "5.0", - "EnumValues": {} - }, - { - "DisplayName": "IP Driver: Spawn Priority Seconds", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Spawn priority seconds", - "Keywords": "IpNetDriver,SpawnPrioritySeconds", - "FieldName": "SpawnPrioritySeconds", - "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:SpawnPrioritySeconds", - "DefaultValue": "1.0", - "EnumValues": {} - }, - { - "DisplayName": "IP Driver: Server Travel Pause (sec)", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Pause during seamless travel", - "Keywords": "IpNetDriver,ServerTravelPause", - "FieldName": "ServerTravelPause", - "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:ServerTravelPause", - "DefaultValue": "4.0", - "EnumValues": {} - }, - { - "DisplayName": "IP Driver: Net Server Max Tick Rate", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Tick rate for IpNetDriver", - "Keywords": "IpNetDriver,NetServerMaxTickRate", - "FieldName": "IpNetDriver_NetServerMaxTickRate", - "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:NetServerMaxTickRate", - "DefaultValue": "30", - "EnumValues": {} - }, - { - "DisplayName": "IP Driver: Max Net Tick Rate", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Overall max network tick rate", - "Keywords": "IpNetDriver,MaxNetTickRate", - "FieldName": "MaxNetTickRate", - "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:MaxNetTickRate", - "DefaultValue": "120", - "EnumValues": {} - }, - { - "DisplayName": "DDoS Detection Enabled", - "Category": "Renown:stadia_controller", - "Subcategory": "Security:shield:4", - "Description": "Enable UE DDoS detection", - "Keywords": "DDoS,bDDoSDetection", - "FieldName": "bDDoSDetection", - "InputType": "checkbox", - "ParamFieldName": "ini:Engine:[DDoSDetection]:bDDoSDetection", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "DDoS Analytics Enabled", - "Category": "Renown:stadia_controller", - "Subcategory": "Security:shield:4", - "Description": "Enable DDoS analytics", - "Keywords": "DDoS,bDDoSAnalytics", - "FieldName": "bDDoSAnalytics", - "InputType": "checkbox", - "ParamFieldName": "ini:Engine:[DDoSDetection]:bDDoSAnalytics", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "DDoS Log Spam Limit", - "Category": "Renown:stadia_controller", - "Subcategory": "Security:shield:4", - "Description": "Limit for DDoS log spam", - "Keywords": "DDoS,Log", - "FieldName": "DDoSLogSpamLimit", - "InputType": "number", - "ParamFieldName": "ini:Engine:[DDoSDetection]:DDoSLogSpamLimit", - "DefaultValue": "64", - "EnumValues": {} - }, - { - "DisplayName": "Hitch Time Quota (ms)", - "Category": "Renown:stadia_controller", - "Subcategory": "Performance:activity:8", - "Description": "Hitch detection time quota", - "Keywords": "HitchTimeQuotaMS", - "FieldName": "HitchTimeQuotaMS", - "InputType": "number", - "ParamFieldName": "ini:Engine:[DDoSDetection]:HitchTimeQuotaMS", - "DefaultValue": "500", - "EnumValues": {} - }, - { - "DisplayName": "Hitch Frame Tolerance", - "Category": "Renown:stadia_controller", - "Subcategory": "Performance:activity:8", - "Description": "Hitch detection frame tolerance", - "Keywords": "HitchFrameTolerance", - "FieldName": "HitchFrameTolerance", - "InputType": "number", - "ParamFieldName": "ini:Engine:[DDoSDetection]:HitchFrameTolerance", - "DefaultValue": "3", - "EnumValues": {} - }, - { - "DisplayName": "Purge Logs After (days)", - "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:refresh-cw:5", - "Description": "Delete logs older than this many days", - "Keywords": "logs,PurgeLogsDays", - "FieldName": "PurgeLogsDays", - "InputType": "number", - "ParamFieldName": "ini:Engine:[LogFiles]:PurgeLogsDays", - "DefaultValue": "5", - "EnumValues": {} - }, - { - "DisplayName": "Max Log Files On Disk", - "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:refresh-cw:5", - "Description": "Limit number of rotated log files", - "Keywords": "logs,MaxLogFilesOnDisk", - "FieldName": "MaxLogFilesOnDisk", - "InputType": "number", - "ParamFieldName": "ini:Engine:[LogFiles]:MaxLogFilesOnDisk", - "DefaultValue": "10", - "EnumValues": {} - }, - { - "DisplayName": "Log Times", - "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:refresh-cw:5", - "Description": "Include timestamps in logs", - "Keywords": "logs,LogTimes", - "FieldName": "LogTimes", - "InputType": "checkbox", - "ParamFieldName": "ini:Engine:[LogFiles]:LogTimes", - "DefaultValue": "True", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Core.Log Advanced (raw block)", - "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:refresh-cw:5", - "Description": "Optional advanced Core.Log overrides; paste lines like 'Online=all off' each on new line", - "Keywords": "Core.Log,advanced", - "FieldName": "CoreLogRaw", - "InputType": "textarea", - "ParamFieldName": "ini:Engine:[Core.Log]:__raw__", - "DefaultValue": "Online=all off\nOnlineSession=log\nOnlineGame=log\nSteamCore=all off\nAssetLog=all off\nLogRedpointEOS=all off\nLogRedpointEOSIdentity=all off\nLogRedpointEOSSocket=all off\nLogRedpointEOSSocketLifecycle=all off\nLogRedpointEOSSessionListening=all off\nLogRedpointEOSNetworkTrace=all off\nLogRedpointEOSNetworkAuth=all off\nLogRedpointEOSStat=all off\nLogRedpointEOSAntiCheat=all off\nLogRedpointEOSFriends=all off\nLogRedpointEOSFileTransfer=all off\nLogRedpointEOSVoiceChat=all off\nLogBeacon=log\nLogServerQueue=log", - "EnumValues": {} - }, - { - "DisplayName": "Server Language Culture", - "Category": "Renown:stadia_controller", - "Subcategory": "Localization:languages:9", - "Description": "Set server culture/language (eg. en, es-MX)", - "Keywords": "language,culture,Internationalization", - "FieldName": "Culture", - "InputType": "text", - "ParamFieldName": "ini:GameUserSettings:[Internationalization]:Culture", - "DefaultValue": "en", - "EnumValues": {} - }, - { - "DisplayName": "EOS Voice Chat Enabled", - "Category": "Renown:stadia_controller", - "Subcategory": "Voice:mic:10", - "Description": "Enable Epic Online Services voice chat", - "Keywords": "voice,EOS,bEnabled", - "FieldName": "EOSVoiceChatEnabled", - "InputType": "checkbox", - "ParamFieldName": "ini:Engine:[EOSVoiceChat]:bEnabled", - "DefaultValue": "True", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Server Release Version", - "Category": "Updates", - "Subcategory": "Steam Downloads:download", - "Description": "Sets the server release version to install. Update the server after changing this setting", - "Keywords": "server,version,public,beta", - "FieldName": "ServerVersion", - "InputType": "enum", - "ParamFieldName": "ServerVersion", - "DefaultValue": "public", - "EnumValues": { - "public": "Public (default)", - "beta": "Beta" - } - } ] From b0968736c0e38e8e87ee5fbfb80cfa2ac048d924 Mon Sep 17 00:00:00 2001 From: IceOfWraith <96364530+IceOfWraith@users.noreply.github.com> Date: Mon, 3 Aug 2026 23:13:50 -0500 Subject: [PATCH 09/50] More space reverting --- renownmetaconfig.json | 72 +++++++++--------- renownupdates.json | 166 ++++++++++++++++++++++-------------------- 2 files changed, 125 insertions(+), 113 deletions(-) diff --git a/renownmetaconfig.json b/renownmetaconfig.json index 90367eef8..3c6ca890d 100644 --- a/renownmetaconfig.json +++ b/renownmetaconfig.json @@ -1,38 +1,38 @@ [ - { - "ConfigFile": "Renown_Combat/Saved/Config/LinuxServer/Game.ini", - "ConfigType": "ini", - "AutoMap": true, - "Importable": true - }, - { - "ConfigFile": "Renown_Combat/Saved/Config/WindowsServer/Game.ini", - "ConfigType": "ini", - "AutoMap": true, - "Importable": true - }, - { - "ConfigFile": "Renown_Combat/Saved/Config/LinuxServer/Engine.ini", - "ConfigType": "ini", - "AutoMap": true, - "Importable": true - }, - { - "ConfigFile": "Renown_Combat/Saved/Config/WindowsServer/Engine.ini", - "ConfigType": "ini", - "AutoMap": true, - "Importable": true - }, - { - "ConfigFile": "Renown_Combat/Saved/Config/LinuxServer/GameUserSettings.ini", - "ConfigType": "ini", - "AutoMap": true, - "Importable": true - }, - { - "ConfigFile": "Renown_Combat/Saved/Config/WindowsServer/GameUserSettings.ini", - "ConfigType": "ini", - "AutoMap": true, - "Importable": true - } + { + "ConfigFile": "Renown_Combat/Saved/Config/LinuxServer/Game.ini", + "ConfigType": "ini", + "AutoMap": true, + "Importable": true + }, + { + "ConfigFile": "Renown_Combat/Saved/Config/WindowsServer/Game.ini", + "ConfigType": "ini", + "AutoMap": true, + "Importable": true + }, + { + "ConfigFile": "Renown_Combat/Saved/Config/LinuxServer/Engine.ini", + "ConfigType": "ini", + "AutoMap": true, + "Importable": true + }, + { + "ConfigFile": "Renown_Combat/Saved/Config/WindowsServer/Engine.ini", + "ConfigType": "ini", + "AutoMap": true, + "Importable": true + }, + { + "ConfigFile": "Renown_Combat/Saved/Config/LinuxServer/GameUserSettings.ini", + "ConfigType": "ini", + "AutoMap": true, + "Importable": true + }, + { + "ConfigFile": "Renown_Combat/Saved/Config/WindowsServer/GameUserSettings.ini", + "ConfigType": "ini", + "AutoMap": true, + "Importable": true + } ] diff --git a/renownupdates.json b/renownupdates.json index bb932904c..33a114c0e 100644 --- a/renownupdates.json +++ b/renownupdates.json @@ -1,83 +1,95 @@ [ - { - "UpdateStageName": "SteamCMD Download", - "UpdateSourcePlatform": "All", - "UpdateSource": "SteamCMD", - "UpdateSourceData": "1512690", - "UpdateSourceArgs": "1488310", - "UpdateSourceVersion": "{{ServerVersion}}", - "SkipOnFailure": false - }, - { - "UpdateStageName": "SteamCMD Component Download", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "SteamCMD", - "UpdateSourceData": "1007", - "UpdateSourceArgs": "1488310", - "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Binaries/Win64", - "SkipOnFailure": false - }, + { + "UpdateStageName": "SteamCMD Download", + "UpdateSourcePlatform": "All", + "UpdateSource": "SteamCMD", + "UpdateSourceData": "1512690", + "UpdateSourceArgs": "1488310", + "UpdateSourceVersion": "{{ServerVersion}}", + "SkipOnFailure": false + }, + { + "UpdateStageName": "SteamCMD Component Download", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "SteamCMD", + "UpdateSourceData": "1007", + "UpdateSourceArgs": "1488310", + "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Binaries/Win64", + "SkipOnFailure": false + }, - { "UpdateStageName": "Create Config Directory (Linux)", "UpdateSourcePlatform": "Linux", "UpdateSource": "CreateDirectory", "UpdateSourceArgs": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", "SkipOnFailure": false }, - { "UpdateStageName": "Create Config Directory (Windows)", "UpdateSourcePlatform": "Windows", "UpdateSource": "CreateDirectory", "UpdateSourceArgs": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", "SkipOnFailure": false }, + { + "UpdateStageName": "Create Config Directory (Linux)", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create Config Directory (Windows)", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", + "SkipOnFailure": false + }, - // ===== Game.ini from your fork (source filename → destination Game.ini) - { - "UpdateStageName": "Game.ini Download (Linux)", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renowngame.ini", - "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", - "UpdateSourceArgs": "Game.ini", - "OverwriteExistingFiles": false - }, - { - "UpdateStageName": "Game.ini Download (Windows)", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renowngame.ini", - "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", - "UpdateSourceArgs": "Game.ini", - "OverwriteExistingFiles": false - }, + // ===== Game.ini from your fork (source filename → destination Game.ini) + { + "UpdateStageName": "Game.ini Download (Linux)", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "FetchURL", + "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renowngame.ini", + "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", + "UpdateSourceArgs": "Game.ini", + "OverwriteExistingFiles": false + }, + { + "UpdateStageName": "Game.ini Download (Windows)", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "FetchURL", + "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renowngame.ini", + "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", + "UpdateSourceArgs": "Game.ini", + "OverwriteExistingFiles": false + }, - // ===== Engine.ini from your fork (renownengine.ini → Engine.ini) - { - "UpdateStageName": "Engine.ini Download (Linux)", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renownengine.ini", - "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", - "UpdateSourceArgs": "Engine.ini", - "OverwriteExistingFiles": false - }, - { - "UpdateStageName": "Engine.ini Download (Windows)", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renownengine.ini", - "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", - "UpdateSourceArgs": "Engine.ini", - "OverwriteExistingFiles": false - }, + // ===== Engine.ini from your fork (renownengine.ini → Engine.ini) + { + "UpdateStageName": "Engine.ini Download (Linux)", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "FetchURL", + "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renownengine.ini", + "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", + "UpdateSourceArgs": "Engine.ini", + "OverwriteExistingFiles": false + }, + { + "UpdateStageName": "Engine.ini Download (Windows)", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "FetchURL", + "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renownengine.ini", + "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", + "UpdateSourceArgs": "Engine.ini", + "OverwriteExistingFiles": false + }, - // ===== GameUserSettings.ini from your fork (renowngameusersettings.ini → GameUserSettings.ini) - { - "UpdateStageName": "GameUserSettings.ini Download (Linux)", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renowngameusersettings.ini", - "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", - "UpdateSourceArgs": "GameUserSettings.ini", - "OverwriteExistingFiles": false - }, - { - "UpdateStageName": "GameUserSettings.ini Download (Windows)", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renowngameusersettings.ini", - "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", - "UpdateSourceArgs": "GameUserSettings.ini", - "OverwriteExistingFiles": false - } + // ===== GameUserSettings.ini from your fork (renowngameusersettings.ini → GameUserSettings.ini) + { + "UpdateStageName": "GameUserSettings.ini Download (Linux)", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "FetchURL", + "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renowngameusersettings.ini", + "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", + "UpdateSourceArgs": "GameUserSettings.ini", + "OverwriteExistingFiles": false + }, + { + "UpdateStageName": "GameUserSettings.ini Download (Windows)", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "FetchURL", + "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renowngameusersettings.ini", + "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", + "UpdateSourceArgs": "GameUserSettings.ini", + "OverwriteExistingFiles": false + } ] From 1391c7f926a66ea4fb0f2378ec539f95851b1ff4 Mon Sep 17 00:00:00 2001 From: IceOfWraith <96364530+IceOfWraith@users.noreply.github.com> Date: Mon, 3 Aug 2026 23:16:24 -0500 Subject: [PATCH 10/50] Remove AI comments --- renownupdates.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/renownupdates.json b/renownupdates.json index 33a114c0e..0f42a0b6e 100644 --- a/renownupdates.json +++ b/renownupdates.json @@ -32,8 +32,6 @@ "UpdateSourceArgs": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", "SkipOnFailure": false }, - - // ===== Game.ini from your fork (source filename → destination Game.ini) { "UpdateStageName": "Game.ini Download (Linux)", "UpdateSourcePlatform": "Linux", @@ -52,8 +50,6 @@ "UpdateSourceArgs": "Game.ini", "OverwriteExistingFiles": false }, - - // ===== Engine.ini from your fork (renownengine.ini → Engine.ini) { "UpdateStageName": "Engine.ini Download (Linux)", "UpdateSourcePlatform": "Linux", @@ -72,8 +68,6 @@ "UpdateSourceArgs": "Engine.ini", "OverwriteExistingFiles": false }, - - // ===== GameUserSettings.ini from your fork (renowngameusersettings.ini → GameUserSettings.ini) { "UpdateStageName": "GameUserSettings.ini Download (Linux)", "UpdateSourcePlatform": "Linux", From 74a3f26a389bf0ca8637abc8052ad23480fe7818 Mon Sep 17 00:00:00 2001 From: IceOfWraith <96364530+IceOfWraith@users.noreply.github.com> Date: Tue, 4 Aug 2026 01:32:25 -0500 Subject: [PATCH 11/50] Match Wiki settings Mirror settings to Wiki values Move from CLI to config files Switch to CubeCoders repo for update stages --- renownconfig.json | 384 ++++++++++++++++++++++----------------------- renownengine.ini | 20 +-- renowngame.ini | 19 ++- renownports.json | 2 +- renownupdates.json | 13 +- 5 files changed, 211 insertions(+), 227 deletions(-) diff --git a/renownconfig.json b/renownconfig.json index 48e4fc8a0..ce2af4665 100644 --- a/renownconfig.json +++ b/renownconfig.json @@ -50,7 +50,7 @@ "FieldName": "ServerName", "InputType": "text", "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.ServerName", - "DefaultValue": "", + "DefaultValue": "AMP Powered Renown Server", "Placeholder": "AMP Powered Renown Server", "EnumValues": {} }, @@ -113,7 +113,7 @@ "FieldName": "MOTD", "InputType": "text", "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MOTD", - "DefaultValue": "NSLOCTEXT(\"[2CF2D1E04F419B14490A65BF06750767]\", \"F67B0BE94A3C4A2665B05284056D0757\", \"Welcome to Renown, in order to play on this server you must accept the following Rules.\\r\\n\\r\\n1. **Respect and Courtesy**: Treat fellow players and staff with respect. Harassment, hate speech, or any form of discrimination will not be tolerated.\\r\\n\\r\\n2. **Cheating and Exploits**: Any use of cheats, hacks, exploits, or any unfair advantage is strictly prohibited. Players found violating this rule will face severe consequences, including permanent bans.\\r\\n\\r\\n3. **Language and Content**: Keep chat and in-game communication appropriate for all ages. Avoid using offensive language, explicit content, or engaging in discussions that may make others uncomfortable.\\r\\n\\r\\n4. **No Spamming or Advertising**: Do not spam chat with repetitive messages or advertise external services or products without permission from server staff.\\r\\n\\r\\n5. **Bug Reporting**: If you encounter any bugs or issues, report them to server staff or file a bug report promptly. Exploiting or abusing bugs for personal gain is not allowed.\\r\\n\\r\\n6. **Impersonation**: Do not impersonate server staff or other players. This includes using similar names or pretending to have authority you do not possess.\\r\\n\\r\\n7. **Final Authority**: Server staff have the final say in all matters concerning rule enforcement and disciplinary actions. Respect their decisions and cooperate with them at all times.\\r\\n\\r\\nRemember, these rules are in place to ensure a fair, enjoyable, and respectful gaming environment for all players. Violating these rules may result in warnings, temporary suspensions, or permanent bans, depending on the severity of the offense. Enjoy your time on the server and have fun gaming!\")", + "DefaultValue": "Welcome to my server!", "EnumValues": {} }, { @@ -149,7 +149,7 @@ "FieldName": "$MaxUsers", "InputType": "number", "MinValue": "1", - "MaxValue": "1000", + "MaxValue": "100", "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxPlayers", "DefaultValue": "40", "Placeholder": "40", @@ -169,7 +169,7 @@ "EnumValues": {} }, { - "DisplayName": "Map Rotation (Game.ini)", + "DisplayName": "Map Rotation", "Category": "Renown:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Map rotations can be set in Game.ini. Format: MapRotation=RSurv-AlgaraIsle_p. One map entry per line", @@ -195,7 +195,7 @@ "EnumValues": {} }, { - "DisplayName": "Maximum Ping (Game.ini)", + "DisplayName": "Maximum Ping", "Category": "Renown:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Sets the maximum ping allowed for players to join the server. 0 = no limit", @@ -225,15 +225,13 @@ { "DisplayName": "Network Maximum Tick Rate (SteamSockets)", "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", + "Subcategory": "Networking:lan:3", "Description": "Sets the maximum tick rate for the server's SteamSockets network driver", "Keywords": "net,server,tick,rate,NetServerMaxTickRate", "FieldName": "NetServerMaxTickRate", "InputType": "number", "MinValue": "1", - "ParamFieldName": "ini:Engine:[Script/SteamSockets.SteamSocketsNetDriver]:NetServerMaxTickRate", - "IncludeInCommandLine": true, - "SkipIfEmpty": true, + "ParamFieldName": "/Script/SteamSockets.SteamSocketsNetDriver.NetServerMaxTickRate", "DefaultValue": "30", "Placeholder": "30", "EnumValues": {} @@ -302,9 +300,7 @@ "Keywords": "first,person,only,Server.FirstPersonOnly", "FieldName": "Server.FirstPersonOnly", "InputType": "checkbox", - "ParamFieldName": "ini:Engine:[SystemSettings]:Server.FirstPersonOnly", - "IncludeInCommandLine": true, - "SkipIfEmpty": true, + "ParamFieldName": "SystemSettings.Server.FirstPersonOnly", "DefaultValue": "0", "EnumValues": { "False": "0", @@ -315,7 +311,7 @@ "DisplayName": "RCON Server Max Uptime (sec)", "Category": "Renown:stadia_controller", "Subcategory": "Server:dns:1", - "Description": "If set, server will reboot after this uptime when commanded via RCON", + "Description": "Server uptime limit used by the RCON uptime/restart handling, in seconds", "Keywords": "RCON,uptime,reboot", "FieldName": "RCON_ServerMaxUptime", "InputType": "number", @@ -327,7 +323,7 @@ "DisplayName": "Max Server Uptime (sec)", "Category": "Renown:stadia_controller", "Subcategory": "Server:dns:1", - "Description": "Hard cap on server uptime before auto-restart", + "Description": "Server uptime limit before the server restarts itself, in seconds. Overlaps with Auto Reboot Interval and RCON Server Max Uptime — set only one", "Keywords": "max,uptime,restart", "FieldName": "MaxServerUptime", "InputType": "number", @@ -339,7 +335,7 @@ "DisplayName": "Public Listing", "Category": "Renown:stadia_controller", "Subcategory": "Server:dns:1", - "Description": "Show this server in the public server browser", + "Description": "List this server publicly in the in-game server browser", "Keywords": "public,listing", "FieldName": "Public", "InputType": "checkbox", @@ -354,7 +350,7 @@ "DisplayName": "LAN Mode", "Category": "Renown:stadia_controller", "Subcategory": "Server:dns:1", - "Description": "Run the server in LAN mode (not internet listed)", + "Description": "Run the server in LAN mode instead of listing it over the internet", "Keywords": "LAN,bLAN", "FieldName": "bLAN", "InputType": "checkbox", @@ -368,8 +364,8 @@ { "DisplayName": "Anti-Cheat Enabled", "Category": "Renown:stadia_controller", - "Subcategory": "Security:shield:4", - "Description": "Enable built-in anti-cheat", + "Subcategory": "Security:security:4", + "Description": "Enable Renown's built-in anti-cheat", "Keywords": "anticheat,bAntiCheat", "FieldName": "bAntiCheat", "InputType": "checkbox", @@ -384,7 +380,7 @@ "DisplayName": "Game Description", "Category": "Renown:stadia_controller", "Subcategory": "Server:dns:1", - "Description": "Short description shown in server details (optional)", + "Description": "Description text shown alongside the server in the browser", "Keywords": "description,GameDescription", "FieldName": "GameDescription", "InputType": "text", @@ -393,10 +389,10 @@ "EnumValues": {} }, { - "DisplayName": "Admin Whitelist (comma-separated SteamIDs)", + "DisplayName": "Admin Whitelist", "Category": "Renown:stadia_controller", - "Subcategory": "Security:shield:4", - "Description": "Admins that can use in-game admin controls", + "Subcategory": "Security:security:4", + "Description": "Steam IDs granted persistent in-game admin access, in addition to the admin password", "Keywords": "admin,whitelist", "FieldName": "AdminWhitelist", "InputType": "text", @@ -409,7 +405,7 @@ "DisplayName": "Use First Map", "Category": "Renown:stadia_controller", "Subcategory": "Server:dns:1", - "Description": "If true, load the first map from rotation on boot", + "Description": "Load the first entry of the map rotation when the server starts", "Keywords": "UseFirstMap", "FieldName": "UseFirstMap", "InputType": "checkbox", @@ -421,10 +417,10 @@ } }, { - "DisplayName": "Ban List Path / IDs", + "DisplayName": "Ban List", "Category": "Renown:stadia_controller", - "Subcategory": "Security:shield:4", - "Description": "Ban list (file path or comma-separated IDs)", + "Subcategory": "Security:security:4", + "Description": "Server ban list entry in Game.ini", "Keywords": "ban,BanList", "FieldName": "BanList", "InputType": "text", @@ -435,13 +431,13 @@ { "DisplayName": "Debug RCON Logs", "Category": "Renown:stadia_controller", - "Subcategory": "Security:shield:4", - "Description": "Verbose RCON logging", + "Subcategory": "Security:security:4", + "Description": "Write verbose RCON diagnostics to the server log", "Keywords": "debug,DebugRCON", "FieldName": "DebugRCON", "InputType": "checkbox", "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.DebugRCON", - "DefaultValue": "True", + "DefaultValue": "False", "EnumValues": { "False": "False", "True": "True" @@ -451,7 +447,7 @@ "DisplayName": "Match Time Limit (sec)", "Category": "Renown:stadia_controller", "Subcategory": "Gameplay:joystick:2", - "Description": "Time limit for match-based modes", + "Description": "Round time limit for timed game modes. 0 disables the limit", "Keywords": "TimeLimit", "FieldName": "TimeLimit", "InputType": "number", @@ -464,7 +460,7 @@ "DisplayName": "Auto Balance Teams", "Category": "Renown:stadia_controller", "Subcategory": "Gameplay:joystick:2", - "Description": "Automatically balance teams in team modes", + "Description": "Automatically balance sides where the game mode supports it", "Keywords": "AutoBalance", "FieldName": "AutoBalance", "InputType": "checkbox", @@ -479,7 +475,7 @@ "DisplayName": "Maintenance Rate", "Category": "Renown:stadia_controller", "Subcategory": "Gameplay:joystick:2", - "Description": "Tuple format for maintenance scaling. Example: (X=0.500000,Y=1.000000)", + "Description": "Maintenance rate as an (X=,Y=) tuple, e.g. (X=0.500000,Y=1.000000)", "Keywords": "MaintenanceRate", "FieldName": "MaintenanceRate", "InputType": "text", @@ -556,10 +552,10 @@ "Placeholder": "300" }, { - "DisplayName": "Max Players Per Banner (clan)", + "DisplayName": "Max Players Per Banner", "Category": "Renown:stadia_controller", "Subcategory": "Gameplay:joystick:2", - "Description": "Limit of players per banner/clan (0 = unlimited)", + "Description": "Limit on how many players may join a single banner. 0 leaves it unlimited", "Keywords": "MaxPlayersPerBanner", "FieldName": "MaxPlayersPerBanner", "InputType": "number", @@ -571,8 +567,8 @@ { "DisplayName": "Auto Reboot Interval (min)", "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:refresh-cw:5", - "Description": "Periodically reboot the server to keep performance healthy", + "Subcategory": "Maintenance:autorenew:5", + "Description": "Automatically reboot the server on this interval, in minutes", "Keywords": "ServerRebootTimeMinutes", "FieldName": "ServerRebootTimeMinutes", "InputType": "number", @@ -585,7 +581,7 @@ "DisplayName": "Raid Window Times", "Category": "Renown:stadia_controller", "Subcategory": "Gameplay:joystick:2", - "Description": "Raid window in tuple format. X = start hour, Y = end hour, using 24-hour time. Example: (X=16,Y=0) means 4 PM to midnight. If Y is less than X, the window wraps past midnight.", + "Description": "Raid window as an (X=,Y=) tuple of 24-hour clock hours, e.g. (X=16,Y=0)", "Keywords": "raid,window,times,RaidWindowTimes", "FieldName": "RaidWindowTimes", "InputType": "text", @@ -598,12 +594,12 @@ "DisplayName": "Offline Raid Protection", "Category": "Renown:stadia_controller", "Subcategory": "Gameplay:joystick:2", - "Description": "Damage reduction applied when the defending player is offline. 1.0 = 100% damage reduction (no damage), 0.0 = no protection (full damage). Recommended: 0.99 for near-complete protection.", + "Description": "Damage multiplier applied to a base while its owner is offline. Lower values mean less damage taken", "Keywords": "offline,raid,protection", "FieldName": "OfflineRaidProtectionMultiplier", "InputType": "number", "MinValue": "0", - "MaxValue": ".99", + "MaxValue": "1", "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.OfflineRaidProtectionMultiplier", "DefaultValue": "0.99", "Placeholder": "0.99", @@ -612,12 +608,12 @@ { "DisplayName": "Enable Server Queue", "Category": "Renown:stadia_controller", - "Subcategory": "Queue:users:6", + "Subcategory": "Queue:groups:6", "Description": "Enable join queue when server is full or starting", "Keywords": "queue,bEnableServerQueue", "FieldName": "bEnableServerQueue", "InputType": "checkbox", - "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:bEnableServerQueue", + "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.bEnableServerQueue", "DefaultValue": "True", "EnumValues": { "False": "False", @@ -627,12 +623,12 @@ { "DisplayName": "Run On LAN (Queue)", "Category": "Renown:stadia_controller", - "Subcategory": "Queue:users:6", + "Subcategory": "Queue:groups:6", "Description": "Run queue in LAN mode", "Keywords": "bRunOnLan", "FieldName": "bRunOnLan", "InputType": "checkbox", - "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:bRunOnLan", + "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.bRunOnLan", "DefaultValue": "False", "EnumValues": { "False": "False", @@ -642,12 +638,12 @@ { "DisplayName": "Client & Server Same Machine", "Category": "Renown:stadia_controller", - "Subcategory": "Queue:users:6", + "Subcategory": "Queue:groups:6", "Description": "Optimizations if client and server run on same machine", "Keywords": "bIsServerClientRunningOnSameMachine", "FieldName": "bIsServerClientRunningOnSameMachine", "InputType": "checkbox", - "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:bIsServerClientRunningOnSameMachine", + "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.bIsServerClientRunningOnSameMachine", "DefaultValue": "False", "EnumValues": { "False": "False", @@ -657,345 +653,282 @@ { "DisplayName": "Reconnection Grace (sec)", "Category": "Renown:stadia_controller", - "Subcategory": "Queue:users:6", + "Subcategory": "Queue:groups:6", "Description": "How long a disconnecting player can rejoin without losing spot", "Keywords": "ReconnectionGracePeriodSeconds", "FieldName": "ReconnectionGracePeriodSeconds", "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:ReconnectionGracePeriodSeconds", + "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.ReconnectionGracePeriodSeconds", "DefaultValue": "90", "EnumValues": {} }, { "DisplayName": "Max Join Duration (sec)", "Category": "Renown:stadia_controller", - "Subcategory": "Queue:users:6", + "Subcategory": "Queue:groups:6", "Description": "Time window to complete a join from queue", "Keywords": "ServerQueueMaxJoinDuration", "FieldName": "ServerQueueMaxJoinDuration", "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:ServerQueueMaxJoinDuration", + "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.ServerQueueMaxJoinDuration", "DefaultValue": "300", "EnumValues": {} }, { "DisplayName": "Purge Pending Connections (sec)", "Category": "Renown:stadia_controller", - "Subcategory": "Queue:users:6", + "Subcategory": "Queue:groups:6", "Description": "Purge half-open connections after this time", "Keywords": "PurgePendingPlayerConnections", "FieldName": "PurgePendingPlayerConnections", "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:PurgePendingPlayerConnections", + "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.PurgePendingPlayerConnections", "DefaultValue": "60", "EnumValues": {} }, { "DisplayName": "Player Slots To Consume", "Category": "Renown:stadia_controller", - "Subcategory": "Queue:users:6", - "Description": "Reserved slots consumed by queue/internal services", + "Subcategory": "Queue:groups:6", + "Description": "Player slots reserved by the server queue", "Keywords": "PlayerSlotsToConsume", "FieldName": "PlayerSlotsToConsume", "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:PlayerSlotsToConsume", + "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.PlayerSlotsToConsume", "DefaultValue": "0", "EnumValues": {} }, { "DisplayName": "Max Client Reconnect Attempts", "Category": "Renown:stadia_controller", - "Subcategory": "Queue:users:6", + "Subcategory": "Queue:groups:6", "Description": "How many reconnect tries are allowed", "Keywords": "MaxClientReconnectAttempts", "FieldName": "MaxClientReconnectAttempts", "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Renown_Combat.RenownDeveloperSettings]:MaxClientReconnectAttempts", + "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.MaxClientReconnectAttempts", "DefaultValue": "0", "EnumValues": {} }, { "DisplayName": "Default Max Party Size", "Category": "Renown:stadia_controller", - "Subcategory": "Social:users:7", + "Subcategory": "Social:groups:7", "Description": "Max party size in lobby", "Keywords": "party,DefaultMaxPartySize", "FieldName": "DefaultMaxPartySize", "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Party.Party]:DefaultMaxPartySize", + "ParamFieldName": "/Script/Party.Party.DefaultMaxPartySize", "DefaultValue": "5", "EnumValues": {} }, { "DisplayName": "Wait For Players Time Remaining (sec)", "Category": "Renown:stadia_controller", - "Subcategory": "Social:users:7", + "Subcategory": "Social:groups:7", "Description": "Time the lobby waits before starting", "Keywords": "Lobby,WaitForPlayersTimeRemaining", "FieldName": "WaitForPlayersTimeRemaining", "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Lobby.LobbyBeaconState]:WaitForPlayersTimeRemaining", + "ParamFieldName": "/Script/Lobby.LobbyBeaconState.WaitForPlayersTimeRemaining", "DefaultValue": "20.0", "EnumValues": {} }, { "DisplayName": "Max Spectators", "Category": "Renown:stadia_controller", - "Subcategory": "Social:users:7", + "Subcategory": "Social:groups:7", "Description": "Number of spectator slots", "Keywords": "spectators,MaxSpectators", "FieldName": "MaxSpectators", "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Engine.GameSession]:MaxSpectators", + "ParamFieldName": "/Script/Engine.GameSession.MaxSpectators", "DefaultValue": "2", "EnumValues": {} }, { "DisplayName": "Requires Push-To-Talk", "Category": "Renown:stadia_controller", - "Subcategory": "Social:users:7", + "Subcategory": "Social:groups:7", "Description": "Require PTT for in-game voice", "Keywords": "voice,bRequiresPushToTalk", "FieldName": "bRequiresPushToTalk", "InputType": "checkbox", - "ParamFieldName": "ini:Game:[Script/Engine.GameSession]:bRequiresPushToTalk", - "DefaultValue": "true", + "ParamFieldName": "/Script/Engine.GameSession.bRequiresPushToTalk", + "DefaultValue": "True", "EnumValues": { "False": "False", "True": "True" } }, { - "DisplayName": "Total Net Bandwidth (Game.ini)", + "DisplayName": "Total Net Bandwidth", "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Server total outgoing bandwidth budget (bytes/sec)", + "Subcategory": "Networking:lan:3", + "Description": "Total replication bandwidth budget shared across all clients, in bytes/sec", "Keywords": "bandwidth,TotalNetBandwidth", - "FieldName": "TotalNetBandwidth_Game", + "FieldName": "TotalNetBandwidth", "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Engine.GameNetworkManager]:TotalNetBandwidth", + "ParamFieldName": "/Script/Engine.GameNetworkManager.TotalNetBandwidth", "DefaultValue": "4000000", "EnumValues": {} }, { - "DisplayName": "Max Dynamic Bandwidth (Game.ini)", + "DisplayName": "Max Dynamic Bandwidth", "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Max per-connection bandwidth cap", + "Subcategory": "Networking:lan:3", + "Description": "Upper bound on per-client bandwidth, in bytes/sec", "Keywords": "bandwidth,MaxDynamicBandwidth", - "FieldName": "MaxDynamicBandwidth_Game", + "FieldName": "MaxDynamicBandwidth", "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Engine.GameNetworkManager]:MaxDynamicBandwidth", + "ParamFieldName": "/Script/Engine.GameNetworkManager.MaxDynamicBandwidth", "DefaultValue": "100000", "EnumValues": {} }, { - "DisplayName": "Min Dynamic Bandwidth (Game.ini)", + "DisplayName": "Min Dynamic Bandwidth", "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Min per-connection bandwidth floor", + "Subcategory": "Networking:lan:3", + "Description": "Lower bound on per-client bandwidth, in bytes/sec", "Keywords": "bandwidth,MinDynamicBandwidth", - "FieldName": "MinDynamicBandwidth_Game", + "FieldName": "MinDynamicBandwidth", "InputType": "number", - "ParamFieldName": "ini:Game:[Script/Engine.GameNetworkManager]:MinDynamicBandwidth", + "ParamFieldName": "/Script/Engine.GameNetworkManager.MinDynamicBandwidth", "DefaultValue": "40000", "EnumValues": {} }, - { - "DisplayName": "Max Ping (Engine.ini override)", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Engine.ini override for maximum ping filter", - "Keywords": "MaxPing,override", - "FieldName": "MaxPing_Engine", - "InputType": "number", - "ParamFieldName": "ini:Engine:[/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C]:MaxPing", - "DefaultValue": "500", - "EnumValues": {} - }, { "DisplayName": "Smooth Frame Rate", "Category": "Renown:stadia_controller", - "Subcategory": "Performance:activity:8", - "Description": "Enable UE frame smoothing on the server", + "Subcategory": "Performance:speed:8", + "Description": "Enable Unreal frame rate smoothing", "Keywords": "bSmoothFrameRate", "FieldName": "bSmoothFrameRate", "InputType": "checkbox", - "ParamFieldName": "ini:Engine:[Script/Engine.GameEngine]:bSmoothFrameRate", + "ParamFieldName": "/Script/Engine.Engine.bSmoothFrameRate", "DefaultValue": "True", "EnumValues": { "False": "False", "True": "True" } }, - { - "DisplayName": "Total Net Bandwidth (Engine.ini)", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Engine-level total outgoing bandwidth budget (bytes/sec)", - "Keywords": "bandwidth,TotalNetBandwidth", - "FieldName": "TotalNetBandwidth_Engine", - "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/Engine.GameNetworkManager]:TotalNetBandwidth", - "DefaultValue": "500000", - "EnumValues": {} - }, - { - "DisplayName": "Max Dynamic Bandwidth (Engine.ini)", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Engine-level per-connection bandwidth cap", - "Keywords": "bandwidth,MaxDynamicBandwidth", - "FieldName": "MaxDynamicBandwidth_Engine", - "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/Engine.GameNetworkManager]:MaxDynamicBandwidth", - "DefaultValue": "80000", - "EnumValues": {} - }, - { - "DisplayName": "Min Dynamic Bandwidth (Engine.ini)", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Engine-level per-connection bandwidth floor", - "Keywords": "bandwidth,MinDynamicBandwidth", - "FieldName": "MinDynamicBandwidth_Engine", - "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/Engine.GameNetworkManager]:MinDynamicBandwidth", - "DefaultValue": "20000", - "EnumValues": {} - }, - { - "DisplayName": "IP Driver: Allow Peer Connections", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", - "Description": "Allow peer-to-peer client connections", - "Keywords": "IpNetDriver,AllowPeerConnections", - "FieldName": "AllowPeerConnections", - "InputType": "checkbox", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:AllowPeerConnections", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, { "DisplayName": "IP Driver: Connection Timeout (sec)", "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", + "Subcategory": "Networking:lan:3", "Description": "Timeout for network connections", "Keywords": "IpNetDriver,ConnectionTimeout", "FieldName": "ConnectionTimeout", "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:ConnectionTimeout", + "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.ConnectionTimeout", "DefaultValue": "60.0", "EnumValues": {} }, { "DisplayName": "IP Driver: Initial Connect Timeout (sec)", "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", + "Subcategory": "Networking:lan:3", "Description": "Initial connection timeout", "Keywords": "IpNetDriver,InitialConnectTimeout", "FieldName": "InitialConnectTimeout", "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:InitialConnectTimeout", + "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.InitialConnectTimeout", "DefaultValue": "60.0", "EnumValues": {} }, { "DisplayName": "IP Driver: Max Client Rate", "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", + "Subcategory": "Networking:lan:3", "Description": "Max client rate (bytes/sec)", "Keywords": "IpNetDriver,MaxClientRate", "FieldName": "MaxClientRate", "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:MaxClientRate", + "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.MaxClientRate", "DefaultValue": "100000", "EnumValues": {} }, { "DisplayName": "IP Driver: Max Internet Client Rate", "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", + "Subcategory": "Networking:lan:3", "Description": "Max internet client rate (bytes/sec)", "Keywords": "IpNetDriver,MaxInternetClientRate", "FieldName": "MaxInternetClientRate", "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:MaxInternetClientRate", + "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.MaxInternetClientRate", "DefaultValue": "100000", "EnumValues": {} }, { "DisplayName": "IP Driver: Relevant Timeout (sec)", "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", + "Subcategory": "Networking:lan:3", "Description": "Relevancy timeout", "Keywords": "IpNetDriver,RelevantTimeout", "FieldName": "RelevantTimeout", "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:RelevantTimeout", + "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.RelevantTimeout", "DefaultValue": "5.0", "EnumValues": {} }, { "DisplayName": "IP Driver: Spawn Priority Seconds", "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", + "Subcategory": "Networking:lan:3", "Description": "Spawn priority seconds", "Keywords": "IpNetDriver,SpawnPrioritySeconds", "FieldName": "SpawnPrioritySeconds", "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:SpawnPrioritySeconds", + "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.SpawnPrioritySeconds", "DefaultValue": "1.0", "EnumValues": {} }, { "DisplayName": "IP Driver: Server Travel Pause (sec)", "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", + "Subcategory": "Networking:lan:3", "Description": "Pause during seamless travel", "Keywords": "IpNetDriver,ServerTravelPause", "FieldName": "ServerTravelPause", "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:ServerTravelPause", + "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.ServerTravelPause", "DefaultValue": "4.0", "EnumValues": {} }, { "DisplayName": "IP Driver: Net Server Max Tick Rate", "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", + "Subcategory": "Networking:lan:3", "Description": "Tick rate for IpNetDriver", "Keywords": "IpNetDriver,NetServerMaxTickRate", "FieldName": "IpNetDriver_NetServerMaxTickRate", "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:NetServerMaxTickRate", + "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.NetServerMaxTickRate", "DefaultValue": "30", "EnumValues": {} }, { "DisplayName": "IP Driver: Max Net Tick Rate", "Category": "Renown:stadia_controller", - "Subcategory": "Networking:globe-2:3", + "Subcategory": "Networking:lan:3", "Description": "Overall max network tick rate", "Keywords": "IpNetDriver,MaxNetTickRate", "FieldName": "MaxNetTickRate", "InputType": "number", - "ParamFieldName": "ini:Engine:[Script/OnlineSubsystemUtils.IpNetDriver]:MaxNetTickRate", + "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.MaxNetTickRate", "DefaultValue": "120", "EnumValues": {} }, { "DisplayName": "DDoS Detection Enabled", "Category": "Renown:stadia_controller", - "Subcategory": "Security:shield:4", + "Subcategory": "Security:security:4", "Description": "Enable UE DDoS detection", "Keywords": "DDoS,bDDoSDetection", "FieldName": "bDDoSDetection", "InputType": "checkbox", - "ParamFieldName": "ini:Engine:[DDoSDetection]:bDDoSDetection", + "ParamFieldName": "DDoSDetection.bDDoSDetection", "DefaultValue": "False", "EnumValues": { "False": "False", @@ -1005,12 +938,12 @@ { "DisplayName": "DDoS Analytics Enabled", "Category": "Renown:stadia_controller", - "Subcategory": "Security:shield:4", + "Subcategory": "Security:security:4", "Description": "Enable DDoS analytics", "Keywords": "DDoS,bDDoSAnalytics", "FieldName": "bDDoSAnalytics", "InputType": "checkbox", - "ParamFieldName": "ini:Engine:[DDoSDetection]:bDDoSAnalytics", + "ParamFieldName": "DDoSDetection.bDDoSAnalytics", "DefaultValue": "False", "EnumValues": { "False": "False", @@ -1020,99 +953,87 @@ { "DisplayName": "DDoS Log Spam Limit", "Category": "Renown:stadia_controller", - "Subcategory": "Security:shield:4", + "Subcategory": "Security:security:4", "Description": "Limit for DDoS log spam", "Keywords": "DDoS,Log", "FieldName": "DDoSLogSpamLimit", "InputType": "number", - "ParamFieldName": "ini:Engine:[DDoSDetection]:DDoSLogSpamLimit", + "ParamFieldName": "DDoSDetection.DDoSLogSpamLimit", "DefaultValue": "64", "EnumValues": {} }, { "DisplayName": "Hitch Time Quota (ms)", "Category": "Renown:stadia_controller", - "Subcategory": "Performance:activity:8", + "Subcategory": "Performance:speed:8", "Description": "Hitch detection time quota", "Keywords": "HitchTimeQuotaMS", "FieldName": "HitchTimeQuotaMS", "InputType": "number", - "ParamFieldName": "ini:Engine:[DDoSDetection]:HitchTimeQuotaMS", + "ParamFieldName": "DDoSDetection.HitchTimeQuotaMS", "DefaultValue": "500", "EnumValues": {} }, { "DisplayName": "Hitch Frame Tolerance", "Category": "Renown:stadia_controller", - "Subcategory": "Performance:activity:8", + "Subcategory": "Performance:speed:8", "Description": "Hitch detection frame tolerance", "Keywords": "HitchFrameTolerance", "FieldName": "HitchFrameTolerance", "InputType": "number", - "ParamFieldName": "ini:Engine:[DDoSDetection]:HitchFrameTolerance", + "ParamFieldName": "DDoSDetection.HitchFrameTolerance", "DefaultValue": "3", "EnumValues": {} }, { "DisplayName": "Purge Logs After (days)", "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:refresh-cw:5", + "Subcategory": "Maintenance:autorenew:5", "Description": "Delete logs older than this many days", "Keywords": "logs,PurgeLogsDays", "FieldName": "PurgeLogsDays", "InputType": "number", - "ParamFieldName": "ini:Engine:[LogFiles]:PurgeLogsDays", + "ParamFieldName": "LogFiles.PurgeLogsDays", "DefaultValue": "5", "EnumValues": {} }, { "DisplayName": "Max Log Files On Disk", "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:refresh-cw:5", + "Subcategory": "Maintenance:autorenew:5", "Description": "Limit number of rotated log files", "Keywords": "logs,MaxLogFilesOnDisk", "FieldName": "MaxLogFilesOnDisk", "InputType": "number", - "ParamFieldName": "ini:Engine:[LogFiles]:MaxLogFilesOnDisk", + "ParamFieldName": "LogFiles.MaxLogFilesOnDisk", "DefaultValue": "10", "EnumValues": {} }, { "DisplayName": "Log Times", "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:refresh-cw:5", + "Subcategory": "Maintenance:autorenew:5", "Description": "Include timestamps in logs", "Keywords": "logs,LogTimes", "FieldName": "LogTimes", "InputType": "checkbox", - "ParamFieldName": "ini:Engine:[LogFiles]:LogTimes", + "ParamFieldName": "LogFiles.LogTimes", "DefaultValue": "True", "EnumValues": { "False": "False", "True": "True" } }, - { - "DisplayName": "Core.Log Advanced (raw block)", - "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:refresh-cw:5", - "Description": "Optional advanced Core.Log overrides; paste lines like 'Online=all off' each on new line", - "Keywords": "Core.Log,advanced", - "FieldName": "CoreLogRaw", - "InputType": "textarea", - "ParamFieldName": "ini:Engine:[Core.Log]:__raw__", - "DefaultValue": "Online=all off\nOnlineSession=log\nOnlineGame=log\nSteamCore=all off\nAssetLog=all off\nLogRedpointEOS=all off\nLogRedpointEOSIdentity=all off\nLogRedpointEOSSocket=all off\nLogRedpointEOSSocketLifecycle=all off\nLogRedpointEOSSessionListening=all off\nLogRedpointEOSNetworkTrace=all off\nLogRedpointEOSNetworkAuth=all off\nLogRedpointEOSStat=all off\nLogRedpointEOSAntiCheat=all off\nLogRedpointEOSFriends=all off\nLogRedpointEOSFileTransfer=all off\nLogRedpointEOSVoiceChat=all off\nLogBeacon=log\nLogServerQueue=log", - "EnumValues": {} - }, { "DisplayName": "Server Language Culture", "Category": "Renown:stadia_controller", - "Subcategory": "Localization:languages:9", - "Description": "Set server culture/language (eg. en, es-MX)", + "Subcategory": "Localization:language:9", + "Description": "Server locale, e.g. en or es-MX", "Keywords": "language,culture,Internationalization", "FieldName": "Culture", "InputType": "text", - "ParamFieldName": "ini:GameUserSettings:[Internationalization]:Culture", + "ParamFieldName": "Internationalization.Culture", "DefaultValue": "en", "EnumValues": {} }, @@ -1124,13 +1045,84 @@ "Keywords": "voice,EOS,bEnabled", "FieldName": "EOSVoiceChatEnabled", "InputType": "checkbox", - "ParamFieldName": "ini:Engine:[EOSVoiceChat]:bEnabled", + "ParamFieldName": "EOSVoiceChat.bEnabled", "DefaultValue": "True", "EnumValues": { "False": "False", "True": "True" } }, + { + "DisplayName": "Use Official Wipe Schedule", + "Subcategory": "Maintenance:autorenew:5", + "Description": "Follow the official wipe schedule instead of the interval below", + "Keywords": "wipe,schedule", + "FieldName": "bOfficialWipeSchedule", + "InputType": "checkbox", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.bOfficialWipeSchedule", + "DefaultValue": "False", + "EnumValues": { + "False": "False", + "True": "True" + }, + "Category": "Renown:stadia_controller" + }, + { + "DisplayName": "Wipe Interval (days)", + "Subcategory": "Maintenance:autorenew:5", + "Description": "How many days between scheduled wipes", + "Keywords": "wipe,interval", + "FieldName": "WipeInterval", + "InputType": "number", + "MinValue": "1", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.WipeInterval", + "DefaultValue": "7", + "Placeholder": "7", + "EnumValues": {}, + "Category": "Renown:stadia_controller" + }, + { + "DisplayName": "Wipe Start Day Of Week", + "Subcategory": "Maintenance:autorenew:5", + "Description": "Day of the week the wipe schedule starts from", + "Keywords": "wipe,day", + "FieldName": "WipeStartDayOfWeek", + "InputType": "number", + "MinValue": "0", + "MaxValue": "6", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.WipeStartDayOfWeek", + "DefaultValue": "5", + "Placeholder": "5", + "EnumValues": {}, + "Category": "Renown:stadia_controller" + }, + { + "DisplayName": "Wipe Time (HH:MM)", + "Subcategory": "Maintenance:autorenew:5", + "Description": "Time of day the wipe runs, in 24-hour HH:MM form", + "Keywords": "wipe,time", + "FieldName": "WipeHourMinute", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.WipeHourMinute", + "DefaultValue": "18:00", + "Placeholder": "18:00", + "EnumValues": {}, + "Category": "Renown:stadia_controller" + }, + { + "DisplayName": "Wipe Scheduler Check Interval (sec)", + "Subcategory": "Maintenance:autorenew:5", + "Description": "How often the wipe scheduler checks for a due wipe. Do not set below the default of 300 seconds or wipe scheduling can misfire", + "Keywords": "wipe,scheduler", + "FieldName": "WipeSchedulerInterval", + "InputType": "number", + "MinValue": "300", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.WipeSchedulerInterval", + "DefaultValue": "300", + "Placeholder": "300", + "EnumValues": {}, + "Category": "Renown:stadia_controller" + }, { "DisplayName": "Server Release Version", "Category": "Updates", diff --git a/renownengine.ini b/renownengine.ini index 81997fdba..f09c6c5e6 100644 --- a/renownengine.ini +++ b/renownengine.ini @@ -3,21 +3,11 @@ NetServerMaxTickRate=30 [SystemSettings] Server.FirstPersonOnly=0 -RollingSavesLimit=250 -[/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C] -MaxPing=500 - -[/Script/Engine.GameEngine] +[/Script/Engine.Engine] bSmoothFrameRate=True -[/Script/Engine.GameNetworkManager] -TotalNetBandwidth=500000 -MaxDynamicBandwidth=80000 -MinDynamicBandwidth=20000 - [/Script/OnlineSubsystemUtils.IpNetDriver] -AllowPeerConnections=False ConnectionTimeout=60.0 InitialConnectTimeout=60.0 MaxClientRate=100000 @@ -29,8 +19,8 @@ NetServerMaxTickRate=30 MaxNetTickRate=120 [DDoSDetection] -bDDoSDetection=false -bDDoSAnalytics=false +bDDoSDetection=False +bDDoSAnalytics=False DDoSLogSpamLimit=64 HitchTimeQuotaMS=500 HitchFrameTolerance=3 @@ -41,10 +31,10 @@ MaxLogFilesOnDisk=10 LogTimes=True [Core.Log] -Online=all off +Online=log OnlineSession=log OnlineGame=log -SteamCore=all off +SteamCore=log AssetLog=all off LogRedpointEOS=all off LogRedpointEOSIdentity=all off diff --git a/renowngame.ini b/renowngame.ini index 96730d97d..fd2b02444 100644 --- a/renowngame.ini +++ b/renowngame.ini @@ -5,7 +5,7 @@ RCONChatMessagesLimit=50 RCONPassword= RCON_ServerMaxUptime=1800 ServerPassword= -ServerName= +ServerName=AMP Powered Renown Server MaxPlayers=40 bLAN=False bAntiCheat=False @@ -19,10 +19,15 @@ MapRotation=RSurv-AlgaraIsle_p BanList= PrivateSession=False MaxPing=195 -MOTD="NSLOCTEXT("[2CF2D1E04F419B14490A65BF06750767]", "F67B0BE94A3C4A2665B05284056D0757", "Welcome to Renown, in order to play on this server you must accept the following Rules.\r\n\r\n1. **Respect and Courtesy**: Treat fellow players and staff with respect. Harassment, hate speech, or any form of discrimination will not be tolerated.\r\n\r\n2. **Cheating and Exploits**: Any use of cheats, hacks, exploits, or any unfair advantage is strictly prohibited. Players found violating this rule will face severe consequences, including permanent bans.\r\n\r\n3. **Language and Content**: Keep chat and in-game communication appropriate for all ages. Avoid using offensive language, explicit content, or engaging in discussions that may make others uncomfortable.\r\n\r\n4. **No Spamming or Advertising**: Do not spam chat with repetitive messages or advertise external services or products without permission from server staff.\r\n\r\n5. **Bug Reporting**: If you encounter any bugs or issues, report them to server staff or file a bug report promptly. Exploiting or abusing bugs for personal gain is not allowed.\r\n\r\n6. **Impersonation**: Do not impersonate server staff or other players. This includes using similar names or pretending to have authority you do not possess.\r\n\r\n7. **Final Authority**: Server staff have the final say in all matters concerning rule enforcement and disciplinary actions. Respect their decisions and cooperate with them at all times.\r\n\r\nRemember, these rules are in place to ensure a fair, enjoyable, and respectful gaming environment for all players. Violating these rules may result in warnings, temporary suspensions, or permanent bans, depending on the severity of the offense. Enjoy your time on the server and have fun gaming!")" +MOTD=Welcome to my server! Region= MaxServerUptime=28800 -DebugRCON=True +DebugRCON=False +bOfficialWipeSchedule=False +WipeInterval=7 +WipeStartDayOfWeek=5 +WipeHourMinute=18:00 +WipeSchedulerInterval=300 [/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C] TimeLimit=0 @@ -40,9 +45,7 @@ IdleTimeOutTime=300 MaxPlayersPerBanner=0 ServerRebootTimeMinutes=120 RaidWindowTimes=(X=16,Y=0) -OfflineRaidProtectionMultiplier=.99 -[/Game/Core/Blueprints/GameModes/Renown_Horde_GameMode.Renown_Horde_GameMode_C] -[/Game/Core/Blueprints/GameModes/Renown_Duels_GameMode.Renown_Duels_GameMode_C] +OfflineRaidProtectionMultiplier=0.99 [/Script/Renown_Combat.RenownDeveloperSettings] bEnableServerQueue=True @@ -61,9 +64,9 @@ DefaultMaxPartySize=5 WaitForPlayersTimeRemaining=20.0 [/Script/Engine.GameSession] +MaxPlayers=40 MaxSpectators=2 -bRequiresPushToTalk=true - +bRequiresPushToTalk=True [/Script/Engine.GameNetworkManager] TotalNetBandwidth=4000000 diff --git a/renownports.json b/renownports.json index 07781e3d5..697b97f03 100644 --- a/renownports.json +++ b/renownports.json @@ -27,4 +27,4 @@ "Name": "RCON Port", "Description": "Port used for RCON traffic" } -] \ No newline at end of file +] diff --git a/renownupdates.json b/renownupdates.json index 0f42a0b6e..0b1b980b1 100644 --- a/renownupdates.json +++ b/renownupdates.json @@ -17,7 +17,6 @@ "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Binaries/Win64", "SkipOnFailure": false }, - { "UpdateStageName": "Create Config Directory (Linux)", "UpdateSourcePlatform": "Linux", @@ -36,7 +35,7 @@ "UpdateStageName": "Game.ini Download (Linux)", "UpdateSourcePlatform": "Linux", "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renowngame.ini", + "UpdateSourceData": "https://raw.githubusercontent.com/CubeCoders/AMPTemplates/main/renowngame.ini", "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", "UpdateSourceArgs": "Game.ini", "OverwriteExistingFiles": false @@ -45,7 +44,7 @@ "UpdateStageName": "Game.ini Download (Windows)", "UpdateSourcePlatform": "Windows", "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renowngame.ini", + "UpdateSourceData": "https://raw.githubusercontent.com/CubeCoders/AMPTemplates/main/renowngame.ini", "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", "UpdateSourceArgs": "Game.ini", "OverwriteExistingFiles": false @@ -54,7 +53,7 @@ "UpdateStageName": "Engine.ini Download (Linux)", "UpdateSourcePlatform": "Linux", "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renownengine.ini", + "UpdateSourceData": "https://raw.githubusercontent.com/CubeCoders/AMPTemplates/main/renownengine.ini", "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", "UpdateSourceArgs": "Engine.ini", "OverwriteExistingFiles": false @@ -63,7 +62,7 @@ "UpdateStageName": "Engine.ini Download (Windows)", "UpdateSourcePlatform": "Windows", "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renownengine.ini", + "UpdateSourceData": "https://raw.githubusercontent.com/CubeCoders/AMPTemplates/main/renownengine.ini", "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", "UpdateSourceArgs": "Engine.ini", "OverwriteExistingFiles": false @@ -72,7 +71,7 @@ "UpdateStageName": "GameUserSettings.ini Download (Linux)", "UpdateSourcePlatform": "Linux", "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renowngameusersettings.ini", + "UpdateSourceData": "https://raw.githubusercontent.com/CubeCoders/AMPTemplates/main/renowngameusersettings.ini", "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", "UpdateSourceArgs": "GameUserSettings.ini", "OverwriteExistingFiles": false @@ -81,7 +80,7 @@ "UpdateStageName": "GameUserSettings.ini Download (Windows)", "UpdateSourcePlatform": "Windows", "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/HuguesDePayens/AMPTemplates/main/renowngameusersettings.ini", + "UpdateSourceData": "https://raw.githubusercontent.com/CubeCoders/AMPTemplates/main/renowngameusersettings.ini", "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", "UpdateSourceArgs": "GameUserSettings.ini", "OverwriteExistingFiles": false From 231d729a3b8fface88eccfdd0b158c6e50ddaf25 Mon Sep 17 00:00:00 2001 From: IceOfWraith <96364530+IceOfWraith@users.noreply.github.com> Date: Tue, 4 Aug 2026 02:08:10 -0500 Subject: [PATCH 12/50] Further cleanup --- renownconfig.json | 120 +++++++++++++++++++++++++++------------------- 1 file changed, 70 insertions(+), 50 deletions(-) diff --git a/renownconfig.json b/renownconfig.json index ce2af4665..61cda06b9 100644 --- a/renownconfig.json +++ b/renownconfig.json @@ -24,8 +24,8 @@ "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONPassword", "Hidden": true, "ExcludeFromImport": true, - "EnumValues": {}, - "DefaultValue": "" + "DefaultValue": "", + "EnumValues": {} }, { "DisplayName": "RCON Port", @@ -38,8 +38,7 @@ "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONPort", "Hidden": true, "ExcludeFromImport": true, - "EnumValues": {}, - "DefaultValue": "25575" + "EnumValues": {} }, { "DisplayName": "Server Name", @@ -177,8 +176,8 @@ "FieldName": "MapRotation", "InputType": "hidden", "ParamFieldName": "MapRotation", - "EnumValues": {}, - "DefaultValue": "RSurv-AlgaraIsle_p" + "DefaultValue": "RSurv-AlgaraIsle_p", + "EnumValues": {} }, { "DisplayName": "Game Save Name", @@ -308,7 +307,7 @@ } }, { - "DisplayName": "RCON Server Max Uptime (sec)", + "DisplayName": "RCON Server Max Uptime", "Category": "Renown:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Server uptime limit used by the RCON uptime/restart handling, in seconds", @@ -317,10 +316,11 @@ "InputType": "number", "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCON_ServerMaxUptime", "DefaultValue": "1800", + "Suffix": "seconds", "EnumValues": {} }, { - "DisplayName": "Max Server Uptime (sec)", + "DisplayName": "Max Server Uptime", "Category": "Renown:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Server uptime limit before the server restarts itself, in seconds. Overlaps with Auto Reboot Interval and RCON Server Max Uptime — set only one", @@ -329,6 +329,7 @@ "InputType": "number", "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxServerUptime", "DefaultValue": "28800", + "Suffix": "seconds", "EnumValues": {} }, { @@ -444,7 +445,7 @@ } }, { - "DisplayName": "Match Time Limit (sec)", + "DisplayName": "Match Time Limit", "Category": "Renown:stadia_controller", "Subcategory": "Gameplay:joystick:2", "Description": "Round time limit for timed game modes. 0 disables the limit", @@ -453,8 +454,9 @@ "InputType": "number", "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.TimeLimit", "DefaultValue": "0", - "EnumValues": {}, - "Placeholder": "0" + "Placeholder": "0", + "Suffix": "seconds", + "EnumValues": {} }, { "DisplayName": "Auto Balance Teams", @@ -494,8 +496,8 @@ "InputType": "number", "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalResourceRespawnTimeMultiplier", "DefaultValue": "1", - "EnumValues": {}, - "Placeholder": "1" + "Placeholder": "1", + "EnumValues": {} }, { "DisplayName": "Global Maintenance Cost Multiplier", @@ -507,8 +509,8 @@ "InputType": "number", "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalMaintenanceCostMultiplier", "DefaultValue": "1", - "EnumValues": {}, - "Placeholder": "1" + "Placeholder": "1", + "EnumValues": {} }, { "DisplayName": "Global Decay Damage Multiplier", @@ -520,8 +522,8 @@ "InputType": "number", "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalDecayDamageMultiplier", "DefaultValue": "1", - "EnumValues": {}, - "Placeholder": "1" + "Placeholder": "1", + "EnumValues": {} }, { "DisplayName": "Kick Idle Players", @@ -539,7 +541,7 @@ } }, { - "DisplayName": "Idle Timeout (sec)", + "DisplayName": "Idle Timeout", "Category": "Renown:stadia_controller", "Subcategory": "Gameplay:joystick:2", "Description": "Time before idle player is kicked", @@ -548,8 +550,9 @@ "InputType": "number", "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.IdleTimeOutTime", "DefaultValue": "300", - "EnumValues": {}, - "Placeholder": "300" + "Placeholder": "300", + "Suffix": "seconds", + "EnumValues": {} }, { "DisplayName": "Max Players Per Banner", @@ -561,11 +564,11 @@ "InputType": "number", "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.MaxPlayersPerBanner", "DefaultValue": "0", - "EnumValues": {}, - "Placeholder": "0" + "Placeholder": "0", + "EnumValues": {} }, { - "DisplayName": "Auto Reboot Interval (min)", + "DisplayName": "Auto Reboot Interval", "Category": "Renown:stadia_controller", "Subcategory": "Maintenance:autorenew:5", "Description": "Automatically reboot the server on this interval, in minutes", @@ -574,8 +577,9 @@ "InputType": "number", "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.ServerRebootTimeMinutes", "DefaultValue": "120", - "EnumValues": {}, - "Placeholder": "120" + "Placeholder": "120", + "Suffix": "minutes", + "EnumValues": {} }, { "DisplayName": "Raid Window Times", @@ -651,7 +655,7 @@ } }, { - "DisplayName": "Reconnection Grace (sec)", + "DisplayName": "Reconnection Grace", "Category": "Renown:stadia_controller", "Subcategory": "Queue:groups:6", "Description": "How long a disconnecting player can rejoin without losing spot", @@ -660,10 +664,11 @@ "InputType": "number", "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.ReconnectionGracePeriodSeconds", "DefaultValue": "90", + "Suffix": "seconds", "EnumValues": {} }, { - "DisplayName": "Max Join Duration (sec)", + "DisplayName": "Max Join Duration", "Category": "Renown:stadia_controller", "Subcategory": "Queue:groups:6", "Description": "Time window to complete a join from queue", @@ -672,10 +677,11 @@ "InputType": "number", "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.ServerQueueMaxJoinDuration", "DefaultValue": "300", + "Suffix": "seconds", "EnumValues": {} }, { - "DisplayName": "Purge Pending Connections (sec)", + "DisplayName": "Purge Pending Connections", "Category": "Renown:stadia_controller", "Subcategory": "Queue:groups:6", "Description": "Purge half-open connections after this time", @@ -684,6 +690,7 @@ "InputType": "number", "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.PurgePendingPlayerConnections", "DefaultValue": "60", + "Suffix": "seconds", "EnumValues": {} }, { @@ -723,7 +730,7 @@ "EnumValues": {} }, { - "DisplayName": "Wait For Players Time Remaining (sec)", + "DisplayName": "Wait For Players Time Remaining", "Category": "Renown:stadia_controller", "Subcategory": "Social:groups:7", "Description": "Time the lobby waits before starting", @@ -732,6 +739,7 @@ "InputType": "number", "ParamFieldName": "/Script/Lobby.LobbyBeaconState.WaitForPlayersTimeRemaining", "DefaultValue": "20.0", + "Suffix": "seconds", "EnumValues": {} }, { @@ -813,7 +821,7 @@ } }, { - "DisplayName": "IP Driver: Connection Timeout (sec)", + "DisplayName": "IP Driver: Connection Timeout", "Category": "Renown:stadia_controller", "Subcategory": "Networking:lan:3", "Description": "Timeout for network connections", @@ -822,10 +830,11 @@ "InputType": "number", "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.ConnectionTimeout", "DefaultValue": "60.0", + "Suffix": "seconds", "EnumValues": {} }, { - "DisplayName": "IP Driver: Initial Connect Timeout (sec)", + "DisplayName": "IP Driver: Initial Connect Timeout", "Category": "Renown:stadia_controller", "Subcategory": "Networking:lan:3", "Description": "Initial connection timeout", @@ -834,34 +843,37 @@ "InputType": "number", "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.InitialConnectTimeout", "DefaultValue": "60.0", + "Suffix": "seconds", "EnumValues": {} }, { "DisplayName": "IP Driver: Max Client Rate", "Category": "Renown:stadia_controller", "Subcategory": "Networking:lan:3", - "Description": "Max client rate (bytes/sec)", + "Description": "Max client rate", "Keywords": "IpNetDriver,MaxClientRate", "FieldName": "MaxClientRate", "InputType": "number", "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.MaxClientRate", "DefaultValue": "100000", + "Suffix": "bytes/sec", "EnumValues": {} }, { "DisplayName": "IP Driver: Max Internet Client Rate", "Category": "Renown:stadia_controller", "Subcategory": "Networking:lan:3", - "Description": "Max internet client rate (bytes/sec)", + "Description": "Max internet client rate", "Keywords": "IpNetDriver,MaxInternetClientRate", "FieldName": "MaxInternetClientRate", "InputType": "number", "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.MaxInternetClientRate", "DefaultValue": "100000", + "Suffix": "bytes/sec", "EnumValues": {} }, { - "DisplayName": "IP Driver: Relevant Timeout (sec)", + "DisplayName": "IP Driver: Relevant Timeout", "Category": "Renown:stadia_controller", "Subcategory": "Networking:lan:3", "Description": "Relevancy timeout", @@ -870,6 +882,7 @@ "InputType": "number", "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.RelevantTimeout", "DefaultValue": "5.0", + "Suffix": "seconds", "EnumValues": {} }, { @@ -882,10 +895,11 @@ "InputType": "number", "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.SpawnPrioritySeconds", "DefaultValue": "1.0", + "Suffix": "seconds", "EnumValues": {} }, { - "DisplayName": "IP Driver: Server Travel Pause (sec)", + "DisplayName": "IP Driver: Server Travel Pause", "Category": "Renown:stadia_controller", "Subcategory": "Networking:lan:3", "Description": "Pause during seamless travel", @@ -894,6 +908,7 @@ "InputType": "number", "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.ServerTravelPause", "DefaultValue": "4.0", + "Suffix": "seconds", "EnumValues": {} }, { @@ -963,7 +978,7 @@ "EnumValues": {} }, { - "DisplayName": "Hitch Time Quota (ms)", + "DisplayName": "Hitch Time Quota", "Category": "Renown:stadia_controller", "Subcategory": "Performance:speed:8", "Description": "Hitch detection time quota", @@ -972,6 +987,7 @@ "InputType": "number", "ParamFieldName": "DDoSDetection.HitchTimeQuotaMS", "DefaultValue": "500", + "Suffix": "milliseconds", "EnumValues": {} }, { @@ -987,7 +1003,7 @@ "EnumValues": {} }, { - "DisplayName": "Purge Logs After (days)", + "DisplayName": "Purge Logs After", "Category": "Renown:stadia_controller", "Subcategory": "Maintenance:autorenew:5", "Description": "Delete logs older than this many days", @@ -996,6 +1012,7 @@ "InputType": "number", "ParamFieldName": "LogFiles.PurgeLogsDays", "DefaultValue": "5", + "Suffix": "days", "EnumValues": {} }, { @@ -1054,6 +1071,7 @@ }, { "DisplayName": "Use Official Wipe Schedule", + "Category": "Renown:stadia_controller", "Subcategory": "Maintenance:autorenew:5", "Description": "Follow the official wipe schedule instead of the interval below", "Keywords": "wipe,schedule", @@ -1064,11 +1082,11 @@ "EnumValues": { "False": "False", "True": "True" - }, - "Category": "Renown:stadia_controller" + } }, { - "DisplayName": "Wipe Interval (days)", + "DisplayName": "Wipe Interval", + "Category": "Renown:stadia_controller", "Subcategory": "Maintenance:autorenew:5", "Description": "How many days between scheduled wipes", "Keywords": "wipe,interval", @@ -1078,11 +1096,12 @@ "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.WipeInterval", "DefaultValue": "7", "Placeholder": "7", - "EnumValues": {}, - "Category": "Renown:stadia_controller" + "Suffix": "days", + "EnumValues": {} }, { "DisplayName": "Wipe Start Day Of Week", + "Category": "Renown:stadia_controller", "Subcategory": "Maintenance:autorenew:5", "Description": "Day of the week the wipe schedule starts from", "Keywords": "wipe,day", @@ -1093,11 +1112,11 @@ "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.WipeStartDayOfWeek", "DefaultValue": "5", "Placeholder": "5", - "EnumValues": {}, - "Category": "Renown:stadia_controller" + "EnumValues": {} }, { - "DisplayName": "Wipe Time (HH:MM)", + "DisplayName": "Wipe Time", + "Category": "Renown:stadia_controller", "Subcategory": "Maintenance:autorenew:5", "Description": "Time of day the wipe runs, in 24-hour HH:MM form", "Keywords": "wipe,time", @@ -1106,11 +1125,12 @@ "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.WipeHourMinute", "DefaultValue": "18:00", "Placeholder": "18:00", - "EnumValues": {}, - "Category": "Renown:stadia_controller" + "Suffix": "HH:MM", + "EnumValues": {} }, { - "DisplayName": "Wipe Scheduler Check Interval (sec)", + "DisplayName": "Wipe Scheduler Check Interval", + "Category": "Renown:stadia_controller", "Subcategory": "Maintenance:autorenew:5", "Description": "How often the wipe scheduler checks for a due wipe. Do not set below the default of 300 seconds or wipe scheduling can misfire", "Keywords": "wipe,scheduler", @@ -1120,8 +1140,8 @@ "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.WipeSchedulerInterval", "DefaultValue": "300", "Placeholder": "300", - "EnumValues": {}, - "Category": "Renown:stadia_controller" + "Suffix": "seconds", + "EnumValues": {} }, { "DisplayName": "Server Release Version", From 94bd6d05c97d404774a6a30ccc7a2f1da0ecd210 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Fri, 7 Aug 2026 13:23:19 -0500 Subject: [PATCH 13/50] Add files via upload --- nimbus-proxy.kvp | 87 ++++++++++++ nimbus-proxyconfig.json | 252 ++++++++++++++++++++++++++++++++++ nimbus-proxymetaconfig.json | 1 + nimbus-proxyports.json | 30 ++++ nimbus-proxystart.json | 19 +++ nimbus-proxyupdates.json | 68 +++++++++ stratum-nimbus.kvp | 89 ++++++++++++ stratum-nimbusconfig.json | 45 ++++++ stratum-nimbusmetaconfig.json | 27 ++++ stratum-nimbusports.json | 9 ++ stratum-nimbusupdates.json | 15 ++ 11 files changed, 642 insertions(+) create mode 100644 nimbus-proxy.kvp create mode 100644 nimbus-proxyconfig.json create mode 100644 nimbus-proxymetaconfig.json create mode 100644 nimbus-proxyports.json create mode 100644 nimbus-proxystart.json create mode 100644 nimbus-proxyupdates.json create mode 100644 stratum-nimbus.kvp create mode 100644 stratum-nimbusconfig.json create mode 100644 stratum-nimbusmetaconfig.json create mode 100644 stratum-nimbusports.json create mode 100644 stratum-nimbusupdates.json diff --git a/nimbus-proxy.kvp b/nimbus-proxy.kvp new file mode 100644 index 000000000..11cbac9a8 --- /dev/null +++ b/nimbus-proxy.kvp @@ -0,0 +1,87 @@ +Meta.DisplayName=Nimbus Proxy for Vintage Story +Meta.Description=Nimbus proxy with an embedded registry for routing multiple Vintage Story backend servers +Meta.OS=Windows, Linux +Meta.AarchSupport=Native +Meta.Arch=x86_64 +Meta.Author=StratumServer +Meta.URL=https://github.com/StratumServer/Nimbus +Meta.DisplayImageSource=url:https://wiki.vintagestory.at/images/thumb/8/8a/Gamelogo-vintagestory.png/340px-Gamelogo-vintagestory.png +Meta.EndpointURIFormat= +Meta.ConfigManifest=nimbus-proxyconfig.json +Meta.MetaConfigManifest=nimbus-proxymetaconfig.json +Meta.ConfigRoot=nimbus-proxy.kvp +Meta.MinAMPVersion=2.4.6.0 +Meta.SpecificDockerImage=cubecoders/ampbase:debian +Meta.DockerRequired=False +Meta.ContainerPolicy=Supported +Meta.Prerequisites=[] +Meta.ConfigReleaseState=NotSpecified +Meta.NoCommercialUsage=True +Meta.ConfigVersion=1 +Meta.AppConfigId=1937f89c-43e2-48cd-97b9-b71ca9440124 +App.DisplayName=Nimbus Proxy +App.RootDir=./nimbus-proxy/ +App.BaseDirectory=./nimbus-proxy/ +App.ExecutableWin=dotnet\dotnet.exe +App.ExecutableLinux=dotnet/dotnet +App.WorkingDir= +App.LinuxCommandLineArgs= +App.WindowsCommandLineArgs= +App.CommandLineArgs=app/Nimbus.Proxy.dll +App.UseLinuxIOREDIR=False +App.AppSettings={} +App.EnvironmentVariables={"DOTNET_ROOT":"{{$FullBaseDir}}dotnet"} +App.CommandLineParameterFormat={0} {1} +App.CommandLineParameterDelimiter= +App.ExitMethod=OS_CLOSE +App.ExitMethodWindows=CtrlC +App.ExitTimeout=30 +App.ExitString= +App.ExitFile= +App.HasWriteableConsole=True +App.HasReadableConsole=True +App.SupportsLiveSettingsChanges=False +App.LiveSettingChangeCommandFormat= +App.ApplicationIPBinding=0.0.0.0 +App.Ports=@IncludeJson[nimbus-proxyports.json] +App.AdminPortRef=AdminPort +App.PrimaryApplicationPortRef=ProxyPort +App.UniversalSleepApplicationUDPPortRef=ProxyPort +App.UniversalSleepSteamQueryPortRef=ProxyPort +App.MaxUsers={{ProxyMaxPlayers}} +App.UseRandomAdminPassword=False +App.RemoteAdminPassword= +App.AdminMethod=None +App.RCONConnectDelaySeconds=5 +App.RCONConnectRetrySeconds=5 +App.RCONHeartbeatMinutes=0 +App.RCONHeartbeatCommand= +App.UpdateSources=@IncludeJson[nimbus-proxyupdates.json] +App.PreStartStages=@IncludeJson[nimbus-proxystart.json] +App.Compatibility=None +App.SteamUpdateAnonymousLogin=True +App.SteamForceLoginPrompt=False +App.RapidStartup=False +App.SmartExcludeExemptions=["*.cfg","*.conf","*.config","*.ini","*.json","*.xml","*.properties","*.kvp","*.yml","*.yaml","*.toml","*.lua"] +App.MonitorChildProcess=False +App.SupportsUniversalSleep=False +App.WakeupMode=Any +App.ApplicationReadyMode=RegexMatch +Console.FilterMatchRegex= +Console.FilterMatchReplacement= +Console.ThrowawayMessageRegex=^$ +Console.AppReadyRegex=^.*\[nimbus\] listening on .+$ +Console.UserJoinRegex=^.*session (?[^ ]+) connected.*$ +Console.UserLeaveRegex=^.*session (?[^ ]+) closed.*$ +Console.UserChatRegex=^$ +Console.UpdateAvailableRegex=^.*Nimbus update available:.*$ +Console.MetricsRegex= +Console.SuppressLogAtStart=False +Console.ActivateLogRegex= +Console.UserActions={} +Limits.SleepMode=False +Limits.SleepOnStart=False +Limits.SleepDelayMinutes=5 +Limits.DozeDelay=2 +Limits.AutoRetryCount=2 +Limits.SleepStartThresholdSeconds=25 diff --git a/nimbus-proxyconfig.json b/nimbus-proxyconfig.json new file mode 100644 index 000000000..20cd9a5d7 --- /dev/null +++ b/nimbus-proxyconfig.json @@ -0,0 +1,252 @@ +[ + { + "DisplayName": "Proxy Port", + "Category": "Nimbus Proxy:share", + "Subcategory": "Network:dns:1", + "Description": "Player-facing proxy port", + "Keywords": "proxy,port", + "FieldName": "$ProxyPort", + "InputType": "number", + "Hidden": true, + "ParamFieldName": "ProxyPort", + "IncludeInCommandLine": false, + "EnumValues": {} + }, + { + "DisplayName": "Registry Port", + "Category": "Nimbus Proxy:share", + "Subcategory": "Network:dns:1", + "Description": "Embedded registry heartbeat port", + "Keywords": "registry,port", + "FieldName": "$RegistryPort", + "InputType": "number", + "Hidden": true, + "ParamFieldName": "RegistryPort", + "IncludeInCommandLine": false, + "EnumValues": {} + }, + { + "DisplayName": "Admin Port", + "Category": "Nimbus Proxy:share", + "Subcategory": "Network:dns:1", + "Description": "Local nimctl administration port", + "Keywords": "admin,port,nimctl", + "FieldName": "$AdminPort", + "InputType": "number", + "Hidden": true, + "ParamFieldName": "AdminPort", + "IncludeInCommandLine": false, + "EnumValues": {} + }, + { + "DisplayName": "Metrics Port", + "Category": "Nimbus Proxy:share", + "Subcategory": "Network:dns:1", + "Description": "Local metrics and status port", + "Keywords": "metrics,status,port", + "FieldName": "$MetricsPort", + "InputType": "number", + "Hidden": true, + "ParamFieldName": "MetricsPort", + "IncludeInCommandLine": false, + "EnumValues": {} + }, + { + "DisplayName": "Vintage Story Version", + "Category": "Updates", + "Subcategory": "Compatibility:verified_user:-1", + "Description": "Vintage Story version used to select a compatible Nimbus release. Automatic updates stop instead of installing a release built for a different game version", + "Keywords": "vintage,story,version,compatibility", + "FieldName": "ServerVersion", + "InputType": "text", + "ParamFieldName": "ServerVersion", + "IncludeInCommandLine": false, + "Required": true, + "DefaultValue": "1.22.6", + "Placeholder": "1.22.6", + "EnumValues": {} + }, + { + "DisplayName": "Nimbus Version", + "Category": "Updates", + "Subcategory": "Compatibility:verified_user:-1", + "Description": "Optional Nimbus release tag such as v0.5.0. Empty selects the newest stable release whose tagged README states it was built and tested against the configured Vintage Story version", + "Keywords": "nimbus,version,release", + "FieldName": "NimbusVersion", + "InputType": "text", + "ParamFieldName": "NimbusVersion", + "IncludeInCommandLine": false, + "DefaultValue": "", + "Placeholder": "v0.5.0", + "EnumValues": {} + }, + { + "DisplayName": ".NET Release Stream", + "Category": "Updates", + "Subcategory": "Runtime:memory:-1", + "Description": ".NET SDK release stream required by Nimbus", + "Keywords": "dotnet,runtime,sdk", + "FieldName": "DotnetRelease", + "InputType": "enum", + "ParamFieldName": "DotnetRelease", + "IncludeInCommandLine": false, + "DefaultValue": "10.0", + "EnumValues": { + "10.0": "10.0" + } + }, + { + "DisplayName": ".NET SDK Version", + "Category": "Updates", + "Subcategory": "Runtime:memory:-1", + "Description": "Optional exact .NET SDK version. Empty installs the newest SDK in the selected release stream", + "Keywords": "dotnet,version,sdk", + "FieldName": "DotnetSDKVersion", + "InputType": "text", + "ParamFieldName": "DotnetSDKVersion", + "IncludeInCommandLine": false, + "DefaultValue": "", + "Placeholder": "10.0.100", + "EnumValues": {} + }, + { + "DisplayName": "Proxy Bind Address", + "Category": "Nimbus Proxy:share", + "Subcategory": "Network:dns:1", + "Description": "IP address on which players reach the proxy", + "Keywords": "proxy,bind,address", + "FieldName": "ProxyBindAddress", + "InputType": "text", + "ParamFieldName": "ProxyBindAddress", + "IncludeInCommandLine": false, + "Required": true, + "DefaultValue": "0.0.0.0", + "EnumValues": {} + }, + { + "DisplayName": "Backend Servers", + "Category": "Nimbus Proxy:share", + "Subcategory": "Backend Pool:dns:2", + "Description": "Semicolon-separated serverId=host:port entries. Every server ID must match that backend's Nimbus Server ID. Example: hub=127.0.0.1:42421;survival=127.0.0.1:42422", + "Keywords": "backend,servers,pool", + "FieldName": "BackendServers", + "InputType": "text", + "ParamFieldName": "BackendServers", + "IncludeInCommandLine": false, + "Required": true, + "DefaultValue": "backend-1=127.0.0.1:42421", + "EnumValues": {} + }, + { + "DisplayName": "Initial Server Order", + "Category": "Nimbus Proxy:share", + "Subcategory": "Backend Pool:dns:2", + "Description": "Comma-separated backend server IDs tried for a player's initial connection", + "Keywords": "try,initial,backend,order", + "FieldName": "TryServers", + "InputType": "text", + "ParamFieldName": "TryServers", + "IncludeInCommandLine": false, + "Required": true, + "DefaultValue": "backend-1", + "EnumValues": {} + }, + { + "DisplayName": "Registry Bind Address", + "Category": "Nimbus Proxy:share", + "Subcategory": "Embedded Registry:dns:3", + "Description": "Registry IP address. Use 127.0.0.1 when all backends are on this host, or 0.0.0.0 when remote backends must heartbeat to it", + "Keywords": "registry,bind,address", + "FieldName": "RegistryBindAddress", + "InputType": "text", + "ParamFieldName": "RegistryBindAddress", + "IncludeInCommandLine": false, + "Required": true, + "DefaultValue": "127.0.0.1", + "EnumValues": {} + }, + { + "DisplayName": "Proxy ID", + "Category": "Nimbus Proxy:share", + "Subcategory": "Embedded Registry:dns:3", + "Description": "Unique identifier for this proxy", + "Keywords": "proxy,id,registry", + "FieldName": "ProxyId", + "InputType": "text", + "ParamFieldName": "ProxyId", + "IncludeInCommandLine": false, + "Required": true, + "DefaultValue": "nimbus-proxy", + "EnumValues": {} + }, + { + "DisplayName": "Redirect Address", + "Category": "Nimbus Proxy:share", + "Subcategory": "Transfers:swap_horiz:4", + "Description": "Public proxy host or host:port stamped into redirect packets. Leave empty for the legacy behavior", + "Keywords": "redirect,address,transfer", + "FieldName": "RedirectAddress", + "InputType": "text", + "ParamFieldName": "RedirectAddress", + "IncludeInCommandLine": false, + "DefaultValue": "", + "Placeholder": "play.example.com:42420", + "EnumValues": {} + }, + { + "DisplayName": "Server List Name", + "Category": "Nimbus Proxy:share", + "Subcategory": "Server List:public:5", + "Description": "Name returned by the proxy to server-list queries", + "Keywords": "status,name,server,list", + "FieldName": "ProxyStatusName", + "InputType": "text", + "ParamFieldName": "ProxyStatusName", + "IncludeInCommandLine": false, + "DefaultValue": "Nimbus", + "EnumValues": {} + }, + { + "DisplayName": "Server List Message", + "Category": "Nimbus Proxy:share", + "Subcategory": "Server List:public:5", + "Description": "Message returned by the proxy to server-list queries", + "Keywords": "status,motd,message", + "FieldName": "ProxyStatusMotd", + "InputType": "text", + "ParamFieldName": "ProxyStatusMotd", + "IncludeInCommandLine": false, + "DefaultValue": "Vintage Story network", + "EnumValues": {} + }, + { + "DisplayName": "Network Player Limit", + "Category": "Nimbus Proxy:share", + "Subcategory": "Server List:public:5", + "Description": "Maximum player count shown in proxy status responses", + "Keywords": "players,max,status", + "FieldName": "ProxyMaxPlayers", + "InputType": "number", + "ParamFieldName": "ProxyMaxPlayers", + "IncludeInCommandLine": false, + "DefaultValue": "100", + "MinValue": "1", + "EnumValues": {} + }, + { + "DisplayName": "Verbose Logging", + "Category": "Nimbus Proxy:share", + "Subcategory": "Logging:description:6", + "Description": "Enable verbose Nimbus proxy logs for troubleshooting", + "Keywords": "verbose,logging,debug", + "FieldName": "VerboseLogging", + "InputType": "checkbox", + "ParamFieldName": "VerboseLogging", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + } +] diff --git a/nimbus-proxymetaconfig.json b/nimbus-proxymetaconfig.json new file mode 100644 index 000000000..fe51488c7 --- /dev/null +++ b/nimbus-proxymetaconfig.json @@ -0,0 +1 @@ +[] diff --git a/nimbus-proxyports.json b/nimbus-proxyports.json new file mode 100644 index 000000000..2c9cdce9b --- /dev/null +++ b/nimbus-proxyports.json @@ -0,0 +1,30 @@ +[ + { + "Protocol": "Both", + "Name": "Proxy Port", + "Description": "Player-facing Vintage Story proxy port", + "Port": 42420, + "Ref": "ProxyPort" + }, + { + "Protocol": "TCP", + "Name": "Registry Port", + "Description": "Embedded registry HTTP port used by backend heartbeats", + "Port": 8765, + "Ref": "RegistryPort" + }, + { + "Protocol": "TCP", + "Name": "Admin Port", + "Description": "Local nimctl administration socket", + "Port": 42499, + "Ref": "AdminPort" + }, + { + "Protocol": "TCP", + "Name": "Metrics Port", + "Description": "Local metrics and status HTTP endpoint", + "Port": 42500, + "Ref": "MetricsPort" + } +] diff --git a/nimbus-proxystart.json b/nimbus-proxystart.json new file mode 100644 index 000000000..ee2ec6470 --- /dev/null +++ b/nimbus-proxystart.json @@ -0,0 +1,19 @@ +[ + { + "UpdateStageName": "Write Nimbus proxy configuration", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -Command \"$ErrorActionPreference='Stop'; $path='{{$FullBaseDir}}app/nimbus.proxy.toml'; $secret=''; if (Test-Path $path) { $text=Get-Content $path -Raw; $m=[regex]::Match($text,'(?m)^embedded_shared_secret\\s*=\\s*''([^'']+)'''); if (-not $m.Success) { $m=[regex]::Match($text,'(?m)^embedded_shared_secret\\s*=\\s*\\x22([^\\x22]+)\\x22') }; if ($m.Success) { $secret=$m.Groups[1].Value } }; if ([string]::IsNullOrWhiteSpace($secret) -or $secret -in @('change-me-and-keep-secret','REPLACE_ME_WITH_A_LONG_RANDOM_STRING','REPLACE-ME-THE-INSTALL-REFUSES-THIS-VALUE')) { $bytes=New-Object byte[] 32; [System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($bytes); $secret=($bytes | ForEach-Object { $_.ToString('x2') }) -join '' }; $serverLines=New-Object System.Collections.Generic.List[string]; $serverIds=New-Object System.Collections.Generic.HashSet[string]([System.StringComparer]::OrdinalIgnoreCase); foreach ($entry in '{{BackendServers}}'.Split(';',[System.StringSplitOptions]::RemoveEmptyEntries)) { $pair=$entry.Trim().Split('=',2); if ($pair.Count -ne 2 -or $pair[0].Trim() -notmatch '^[A-Za-z0-9_-]+$' -or $pair[1].Trim() -notmatch '^[^\\s:]+:[0-9]{1,5}$') { throw 'Backend Servers must use serverId=host:port entries separated by semicolons' }; $port=[int]($pair[1].Trim().Split(':')[-1]); if ($port -lt 1 -or $port -gt 65535) { throw 'A backend port is outside 1-65535' }; $id=$pair[0].Trim(); if (-not $serverIds.Add($id)) { throw ('Duplicate backend server ID: ' + $id) }; $serverLines.Add($id + ' = ''' + $pair[1].Trim() + '''') }; if ($serverLines.Count -eq 0) { throw 'At least one backend server is required' }; $tryIds=@('{{TryServers}}'.Split(',',[System.StringSplitOptions]::RemoveEmptyEntries) | ForEach-Object { $_.Trim() }); foreach ($id in $tryIds) { if (-not $serverIds.Contains($id)) { throw ('Initial Server Order contains an unknown backend ID: ' + $id) } }; $tryValue=($tryIds | ForEach-Object { '''' + $_ + '''' }) -join ', '; $lines=New-Object System.Collections.Generic.List[string]; $lines.Add('bind = ''{{ProxyBindAddress}}:{{$ProxyPort}}'''); $lines.Add('try = [ ' + $tryValue + ' ]'); $lines.Add(''); $lines.Add('[servers]'); $lines.AddRange($serverLines); $lines.Add(''); $lines.Add('[transfers]'); $lines.Add('default_mode = ''redirect'''); $lines.Add('allow_seamless = false'); $lines.Add('require_seamless_capability = true'); $lines.Add('fallback_to_redirect_when_seamless_unavailable = true'); $lines.Add('redirect_address = ''{{RedirectAddress}}'''); $lines.Add('enable_unsafe_seamless_splice = false'); $lines.Add(''); $lines.Add('[admin]'); $lines.Add('bind = ''127.0.0.1:{{$AdminPort}}'''); $lines.Add('secret = '''''); $lines.Add('enabled = true'); $lines.Add('granted_permissions = [ ''*'' ]'); $lines.Add(''); $lines.Add('[registry]'); $lines.Add('mode = ''embedded'''); $lines.Add('proxy_id = ''{{ProxyId}}'''); $lines.Add('embedded_bind = ''http://{{RegistryBindAddress}}:{{$RegistryPort}}'''); $lines.Add('embedded_shared_secret = ''' + $secret + ''''); $lines.Add('embedded_state_dir = ''.'''); $lines.Add(''); $lines.Add('[logging]'); $lines.Add('verbose = {{VerboseLogging}}'); $lines.Add('sniff_frames = false'); $lines.Add('log_traffic_bytes = false'); $lines.Add(''); $lines.Add('[metrics]'); $lines.Add('enabled = true'); $lines.Add('bind = ''http://127.0.0.1:{{$MetricsPort}}'''); $lines.Add('path = ''/metrics'''); $lines.Add('status_api = true'); $lines.Add('status_api_token = '''''); $lines.Add(''); $lines.Add('[status]'); $lines.Add('enabled = true'); $lines.Add('name = ''{{ProxyStatusName}}'''); $lines.Add('motd = ''{{ProxyStatusMotd}}'''); $lines.Add('game_mode = ''survival'''); $lines.Add('password = false'); $lines.Add('server_version = ''{{ServerVersion}}'''); $lines.Add('max_players = {{ProxyMaxPlayers}}'); New-Item -ItemType Directory -Path (Split-Path $path) -Force | Out-Null; [IO.File]::WriteAllLines($path,$lines,[Text.UTF8Encoding]::new($false)); Write-Output 'Nimbus proxy configuration written'\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Write Nimbus proxy configuration", + "UpdateSourcePlatform": "Linux", + "UpdateSourceArch": "x86_64", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"set -euo pipefail; path='{{$FullBaseDir}}app/nimbus.proxy.toml'; secret=''; if [[ -f \\\"$path\\\" ]]; then secret=$(awk -F'\\\"' '/^embedded_shared_secret[[:space:]]*=/{print $2; exit}' \\\"$path\\\"); fi; case \\\"$secret\\\" in ''|'change-me-and-keep-secret'|'REPLACE_ME_WITH_A_LONG_RANDOM_STRING'|'REPLACE-ME-THE-INSTALL-REFUSES-THIS-VALUE') secret=$(od -An -N32 -tx1 /dev/urandom | tr -d ' \\n');; esac; backends='{{BackendServers}}'; try_servers='{{TryServers}}'; tmp=\\\"$path.tmp\\\"; mkdir -p \\\"$(dirname \\\"$path\\\")\\\"; declare -A ids=(); server_lines=''; IFS=';' read -ra entries <<< \\\"$backends\\\"; for entry in \\\"${entries[@]}\\\"; do entry=$(echo \\\"$entry\\\" | xargs); [[ \\\"$entry\\\" =~ ^([A-Za-z0-9_-]+)=([^[:space:]:]+):([0-9]{1,5})$ ]] || { echo 'Backend Servers must use serverId=host:port entries separated by semicolons'; exit 1; }; id=\\\"${BASH_REMATCH[1]}\\\"; host=\\\"${BASH_REMATCH[2]}\\\"; port=\\\"${BASH_REMATCH[3]}\\\"; (( port >= 1 && port <= 65535 )) || { echo 'A backend port is outside 1-65535'; exit 1; }; [[ -z \\\"${ids[$id]+x}\\\" ]] || { echo \\\"Duplicate backend server ID: $id\\\"; exit 1; }; ids[$id]=1; server_lines+=\\\"$id = \\\\\\\"$host:$port\\\\\\\"\\n\\\"; done; (( ${#ids[@]} > 0 )) || { echo 'At least one backend server is required'; exit 1; }; try_value=''; IFS=',' read -ra tries <<< \\\"$try_servers\\\"; for id in \\\"${tries[@]}\\\"; do id=$(echo \\\"$id\\\" | xargs); [[ -n \\\"${ids[$id]+x}\\\" ]] || { echo \\\"Initial Server Order contains an unknown backend ID: $id\\\"; exit 1; }; [[ -z \\\"$try_value\\\" ]] || try_value+=', '; try_value+=\\\"\\\\\\\"$id\\\\\\\"\\\"; done; printf 'bind = \\\"{{ProxyBindAddress}}:{{$ProxyPort}}\\\"\\ntry = [ %s ]\\n\\n[servers]\\n%b\\n[transfers]\\ndefault_mode = \\\"redirect\\\"\\nallow_seamless = false\\nrequire_seamless_capability = true\\nfallback_to_redirect_when_seamless_unavailable = true\\nredirect_address = \\\"{{RedirectAddress}}\\\"\\nenable_unsafe_seamless_splice = false\\n\\n[admin]\\nbind = \\\"127.0.0.1:{{$AdminPort}}\\\"\\nsecret = \\\"\\\"\\nenabled = true\\ngranted_permissions = [ \\\"*\\\" ]\\n\\n[registry]\\nmode = \\\"embedded\\\"\\nproxy_id = \\\"{{ProxyId}}\\\"\\nembedded_bind = \\\"http://{{RegistryBindAddress}}:{{$RegistryPort}}\\\"\\nembedded_shared_secret = \\\"%s\\\"\\nembedded_state_dir = \\\".\\\"\\n\\n[logging]\\nverbose = {{VerboseLogging}}\\nsniff_frames = false\\nlog_traffic_bytes = false\\n\\n[metrics]\\nenabled = true\\nbind = \\\"http://127.0.0.1:{{$MetricsPort}}\\\"\\npath = \\\"/metrics\\\"\\nstatus_api = true\\nstatus_api_token = \\\"\\\"\\n\\n[status]\\nenabled = true\\nname = \\\"{{ProxyStatusName}}\\\"\\nmotd = \\\"{{ProxyStatusMotd}}\\\"\\ngame_mode = \\\"survival\\\"\\npassword = false\\nserver_version = \\\"{{ServerVersion}}\\\"\\nmax_players = {{ProxyMaxPlayers}}\\n' \\\"$try_value\\\" \\\"$server_lines\\\" \\\"$secret\\\" > \\\"$tmp\\\"; mv \\\"$tmp\\\" \\\"$path\\\"; echo 'Nimbus proxy configuration written'\"", + "SkipOnFailure": false + } +] diff --git a/nimbus-proxyupdates.json b/nimbus-proxyupdates.json new file mode 100644 index 000000000..3c42f3f0d --- /dev/null +++ b/nimbus-proxyupdates.json @@ -0,0 +1,68 @@ +[ + { + "UpdateStageName": "Application Directory Creation", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullBaseDir}}app", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Dotnet Directory Creation", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullBaseDir}}dotnet", + "SkipOnFailure": false + }, + { + "UpdateStageName": ".NET SDK Download", + "UpdateSourcePlatform": "Linux", + "UpdateSourceArch": "x86_64", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"DotnetVersion=\\\"{{DotnetSDKVersion}}\\\"; cd \\\"{{$FullBaseDir}}\\\" && if [[ -x dotnet/dotnet ]]; then InstalledVersion=$(dotnet/dotnet --version | xargs); else InstalledVersion=\\\"\\\"; fi; if [[ -z \\\"$DotnetVersion\\\" ]]; then DotnetVersion=$(wget -qO- https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json | jq -r \\\".[\\\\\\\"latest-sdk\\\\\\\"]\\\"); fi; if [[ ! \\\"$DotnetVersion\\\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+$ ]]; then echo \\\"Invalid .NET SDK version format specified\\\" && exit 1; elif [[ \\\"$InstalledVersion\\\" == \\\"$DotnetVersion\\\" ]]; then echo \\\".NET SDK v$DotnetVersion already installed. Skipping\\\" && exit 0; else rm -f dotnet.tar.gz; wget -qO dotnet.tar.gz https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-linux-x64.tar.gz || { echo \\\".NET SDK download failed\\\"; exit 1; }; rm -rf dotnet/* && tar -xzf dotnet.tar.gz -C dotnet && rm -f dotnet.tar.gz && echo \\\".NET SDK v$DotnetVersion downloaded\\\"; fi\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": ".NET SDK Download", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -Command \"$ProgressPreference='SilentlyContinue'; [Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $DotnetVersion='{{DotnetSDKVersion}}'; Set-Location '{{$FullBaseDir}}'; if (Test-Path 'dotnet/dotnet.exe') { $InstalledVersion=(& dotnet/dotnet.exe --version).Trim() } else { $InstalledVersion='' }; if ([string]::IsNullOrWhiteSpace($DotnetVersion)) { $DotnetVersion=(Invoke-RestMethod -UseBasicParsing 'https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json').'latest-sdk' }; if ($DotnetVersion -notmatch '^\\d+\\.\\d+\\.\\d+$') { throw 'Invalid .NET SDK version format specified' }; if ($InstalledVersion -eq $DotnetVersion) { Write-Output \\\".NET SDK v$DotnetVersion already installed. Skipping\\\"; exit 0 }; Invoke-WebRequest -UseBasicParsing -Uri \\\"https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-win-x64.zip\\\" -OutFile dotnet.zip -ErrorAction Stop; Remove-Item 'dotnet/*' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive dotnet.zip dotnet -Force; Remove-Item dotnet.zip -Force; Write-Output \\\".NET SDK v$DotnetVersion downloaded\\\"\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Nimbus Proxy Download", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -Command \"$ErrorActionPreference='Stop'; $ProgressPreference='SilentlyContinue'; $game='{{ServerVersion}}'.Trim(); if ($game -notmatch '^\\d+\\.\\d+\\.\\d+(-rc\\.\\d+|-pre\\.\\d+)?$') { throw 'Invalid Vintage Story version' }; $requested='{{NimbusVersion}}'.Trim(); if ($requested -and -not $requested.StartsWith('v')) { $requested='v'+$requested }; $releases=Invoke-RestMethod -UseBasicParsing 'https://api.github.com/repos/StratumServer/Nimbus/releases?per_page=100'; if ($requested) { $candidates=@($releases | Where-Object { $_.tag_name -eq $requested -and -not $_.draft }) } else { $candidates=@($releases | Where-Object { -not $_.draft -and -not $_.prerelease }) }; $selected=$null; foreach ($release in $candidates) { try { $readme=Invoke-WebRequest -UseBasicParsing -Uri ('https://raw.githubusercontent.com/StratumServer/Nimbus/'+$release.tag_name+'/README.md') | Select-Object -ExpandProperty Content } catch { continue }; $match=[regex]::Match($readme,'Built and tested against Vintage Story\\s+([0-9]+\\.[0-9]+\\.[0-9]+(?:-rc\\.[0-9]+|-pre\\.[0-9]+)?)',[Text.RegularExpressions.RegexOptions]::IgnoreCase); if ($match.Success -and $match.Groups[1].Value -eq $game) { $selected=$release; break } }; if (-not $selected) { throw \\\"No Nimbus release declares compatibility with Vintage Story $game\\\" }; $assetName='Nimbus-'+$selected.tag_name+'.zip'; $asset=$selected.assets | Where-Object { $_.name -eq $assetName } | Select-Object -First 1; if (-not $asset -or $asset.browser_download_url -notmatch '^https://') { throw \\\"Release asset $assetName was not found\\\" }; Invoke-WebRequest -UseBasicParsing -Uri $asset.browser_download_url -OutFile '{{$FullBaseDir}}nimbus.zip'; Remove-Item '{{$FullBaseDir}}nimbus-temp' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive '{{$FullBaseDir}}nimbus.zip' '{{$FullBaseDir}}nimbus-temp' -Force; $source=Get-ChildItem '{{$FullBaseDir}}nimbus-temp' -Directory -Recurse | Where-Object { $_.Name -eq 'Nimbus' } | Select-Object -First 1; if (-not $source -or -not (Test-Path (Join-Path $source.FullName 'Nimbus.Proxy.dll'))) { throw 'Nimbus proxy folder was not found in the release' }; Copy-Item (Join-Path $source.FullName '*') '{{$FullBaseDir}}app' -Recurse -Force; [IO.File]::WriteAllText('{{$FullBaseDir}}.nimbus-version',$selected.tag_name); Remove-Item '{{$FullBaseDir}}nimbus-temp','{{$FullBaseDir}}nimbus.zip' -Recurse -Force; Write-Output (\\\"Nimbus $($selected.tag_name) installed for Vintage Story $game\\\")\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Nimbus Proxy Download", + "UpdateSourcePlatform": "Linux", + "UpdateSourceArch": "x86_64", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"set -euo pipefail; game='{{ServerVersion}}'; requested='{{NimbusVersion}}'; [[ \\\"$game\\\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+(-rc\\.[0-9]+|-pre\\.[0-9]+)?$ ]] || { echo 'Invalid Vintage Story version'; exit 1; }; [[ -z \\\"$requested\\\" || \\\"$requested\\\" == v* ]] || requested=\\\"v$requested\\\"; releases='{{$FullBaseDir}}nimbus-releases.json'; wget -qO \\\"$releases\\\" 'https://api.github.com/repos/StratumServer/Nimbus/releases?per_page=100'; if [[ -n \\\"$requested\\\" ]]; then tags=\\\"$requested\\\"; else tags=$(jq -r '.[] | select((.draft|not) and (.prerelease|not)) | .tag_name' \\\"$releases\\\"); fi; selected=''; while IFS= read -r tag; do [[ -n \\\"$tag\\\" ]] || continue; readme=$(wget -qO- \\\"https://raw.githubusercontent.com/StratumServer/Nimbus/$tag/README.md\\\" || true); compatible=$(printf '%s' \\\"$readme\\\" | grep -Eio 'Built and tested against Vintage Story[[:space:]]+[0-9]+\\.[0-9]+\\.[0-9]+(-rc\\.[0-9]+|-pre\\.[0-9]+)?' | head -1 | awk '{print $7}'); if [[ \\\"$compatible\\\" == \\\"$game\\\" ]]; then selected=\\\"$tag\\\"; break; fi; done <<< \\\"$tags\\\"; [[ -n \\\"$selected\\\" ]] || { echo \\\"No Nimbus release declares compatibility with Vintage Story $game\\\"; exit 1; }; asset=\\\"Nimbus-$selected.zip\\\"; url=$(jq -r --arg tag \\\"$selected\\\" --arg asset \\\"$asset\\\" '.[] | select(.tag_name==$tag) | .assets[] | select(.name==$asset) | .browser_download_url' \\\"$releases\\\" | head -1); [[ \\\"$url\\\" == https://* ]] || { echo \\\"Release asset $asset was not found\\\"; exit 1; }; wget -qO '{{$FullBaseDir}}nimbus.zip' \\\"$url\\\"; rm -rf '{{$FullBaseDir}}nimbus-temp'; mkdir -p '{{$FullBaseDir}}nimbus-temp'; unzip -qo '{{$FullBaseDir}}nimbus.zip' -d '{{$FullBaseDir}}nimbus-temp'; source_dir=$(find '{{$FullBaseDir}}nimbus-temp' -type d -name Nimbus | head -1); [[ -n \\\"$source_dir\\\" && -f \\\"$source_dir/Nimbus.Proxy.dll\\\" ]] || { echo 'Nimbus proxy folder was not found in the release'; exit 1; }; cp -rf \\\"$source_dir/.\\\" '{{$FullBaseDir}}app/'; printf '%s' \\\"$selected\\\" > '{{$FullBaseDir}}.nimbus-version'; rm -rf '{{$FullBaseDir}}nimbus-temp' '{{$FullBaseDir}}nimbus.zip' \\\"$releases\\\"; echo \\\"Nimbus $selected installed for Vintage Story $game\\\"\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Start Nimbus Proxy", + "UpdateSourcePlatform": "All", + "UpdateSource": "StartApplication", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Wait For Nimbus Proxy Start", + "UpdateSourcePlatform": "All", + "UpdateSource": "WaitForStartupComplete", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Stop Nimbus Proxy", + "UpdateSourcePlatform": "All", + "UpdateSource": "ShutdownApplication", + "SkipOnFailure": false + } +] diff --git a/stratum-nimbus.kvp b/stratum-nimbus.kvp new file mode 100644 index 000000000..d3efa5afe --- /dev/null +++ b/stratum-nimbus.kvp @@ -0,0 +1,89 @@ +Meta.DisplayName=Vintage Story Stratum + Nimbus Backend +Meta.Description=Stratum-powered Vintage Story server with Nimbus.ServerMod for multi-server networks +Meta.OS=Windows, Linux +Meta.AarchSupport=Native +Meta.Arch=x86_64 +Meta.Author=StratumServer +Meta.URL=https://github.com/StratumServer/Stratum +Meta.DisplayImageSource=url:https://wiki.vintagestory.at/images/thumb/8/8a/Gamelogo-vintagestory.png/340px-Gamelogo-vintagestory.png +Meta.EndpointURIFormat= +Meta.ConfigManifest=stratum-nimbusconfig.json +Meta.MetaConfigManifest=stratum-nimbusmetaconfig.json +Meta.ConfigRoot=stratum-nimbus.kvp +Meta.MinAMPVersion=2.4.6.0 +Meta.SpecificDockerImage=cubecoders/ampbase:debian +Meta.DockerRequired=False +Meta.ContainerPolicy=Supported +Meta.Prerequisites=[] +Meta.ConfigReleaseState=NotSpecified +Meta.NoCommercialUsage=True +Meta.ConfigVersion=1 +Meta.AppConfigId=e7e85f22-3665-43a1-ada6-c7e7e4eecb1f +App.DisplayName=Vintage Story Stratum + Nimbus +App.RootDir=./stratum-nimbus/ +App.BaseDirectory=./stratum-nimbus/ +App.ExecutableWin=server\StratumServer.exe +App.ExecutableLinux=server/StratumServer +App.WorkingDir=server +App.LinuxCommandLineArgs= +App.WindowsCommandLineArgs= +App.CommandLineArgs=--port {{$ServerPort}} --dataPath "../data" {{$FormattedArgs}} +App.UseLinuxIOREDIR=False +App.AppSettings={} +App.EnvironmentVariables={"DOTNET_ROOT":"{{$FullBaseDir}}dotnet"} +App.CommandLineParameterFormat=--{0} {1} +App.CommandLineParameterDelimiter= +App.ExitMethod=String +App.ExitTimeout=30 +App.ExitString=/stop +App.ExitFile=lock +App.HasWriteableConsole=True +App.HasReadableConsole=True +App.SupportsLiveSettingsChanges=False +App.LiveSettingChangeCommandFormat=set {0} "{1}" +App.ApplicationIPBinding=0.0.0.0 +App.Ports=@IncludeJson[stratum-nimbusports.json] +App.AdminPortRef=ServerPort +App.PrimaryApplicationPortRef=ServerPort +App.UniversalSleepApplicationUDPPortRef=ServerPort +App.UniversalSleepSteamQueryPortRef=ServerPort +App.MaxUsers={{$MaxUsers}} +App.UseRandomAdminPassword=False +App.RemoteAdminPassword= +App.AdminMethod=STDIO +App.AdminLoginTransform=None +App.RCONConnectDelaySeconds=5 +App.RCONConnectRetrySeconds=5 +App.RCONHeartbeatMinutes=0 +App.RCONHeartbeatCommand=ping +App.TelnetLoginFormat={0} +App.UpdateSources=@IncludeJson[stratum-nimbusupdates.json] +App.Compatibility=None +App.SteamUpdateAnonymousLogin=True +App.SteamForceLoginPrompt=False +App.RapidStartup=False +App.SmartExcludeExemptions=["*.cfg","*.conf","*.config","*.ini","*.json","*.xml","*.properties","*.kvp","*.yml","*.yaml","*.toml","*.lua","*.vcdbs"] +App.MonitorChildProcess=True +App.MonitorChildProcessWaitMs=100 +App.MonitorChildProcessName= +App.SupportsUniversalSleep=False +App.WakeupMode=Any +App.ApplicationReadyMode=RegexMatch +Console.FilterMatchRegex=|<\/font> +Console.FilterMatchReplacement= +Console.ThrowawayMessageRegex=^(WARNING|ERROR): Shader.+$ +Console.AppReadyRegex=^[\d\.]*\s*[\d:\.]+ \[.*Event\] (?:Dedicated Server|Serveur dédié|Dedizierter Server) now running on Port \d+ and (?:all ips|ip .*)!$ +Console.UserJoinRegex=^[\d\.]*\s*[\d:\.]+ \[.*Event\] (?.+?) [\[\]a-f\d:.]+ joins\.$ +Console.UserLeaveRegex=^[\d\.]*\s*[\d:\.]+ \[.*Event\] Player (?.+?) (left|got removed\. Reason: Server shutting down - Shutdown via server command).*$ +Console.UserChatRegex=^[\d\.]*\s*[\d:\.]+ \[.*Chat\] (?.+?): (?.+?):<\/strong> (?.+)$ +Console.UpdateAvailableRegex=^.*Stratum update available:.*$ +Console.MetricsRegex= +Console.SuppressLogAtStart=False +Console.ActivateLogRegex= +Console.UserActions={} +Limits.SleepMode=True +Limits.SleepOnStart=False +Limits.SleepDelayMinutes=5 +Limits.DozeDelay=2 +Limits.AutoRetryCount=2 +Limits.SleepStartThresholdSeconds=25 diff --git a/stratum-nimbusconfig.json b/stratum-nimbusconfig.json new file mode 100644 index 000000000..ed3516a6d --- /dev/null +++ b/stratum-nimbusconfig.json @@ -0,0 +1,45 @@ +[ + { "DisplayName": "Backend Port", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Private backend port reached by Nimbus", "Keywords": "port,backend", "FieldName": "$ServerPort", "InputType": "number", "Hidden": true, "ParamFieldName": "$.Port", "IncludeInCommandLine": false, "EnumValues": {} }, + { "DisplayName": "Make Backend Public", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Normally disabled because players should connect through the Nimbus proxy", "Keywords": "public,advertise", "FieldName": "AdvertiseServer", "InputType": "checkbox", "ParamFieldName": "$.AdvertiseServer", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Server Name", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Name of this backend server", "Keywords": "server,name", "FieldName": "ServerName", "InputType": "text", "ParamFieldName": "$.ServerName", "IncludeInCommandLine": false, "DefaultValue": "Stratum Nimbus Backend", "EnumValues": {} }, + { "DisplayName": "Welcome Message", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Welcome message shown when a player joins", "Keywords": "welcome,message", "FieldName": "WelcomeMessage", "InputType": "text", "ParamFieldName": "$.WelcomeMessage", "IncludeInCommandLine": false, "DefaultValue": "Welcome, {0}, may you survive well and prosper", "EnumValues": {} }, + { "DisplayName": "Player Limit", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Maximum simultaneous players on this backend", "Keywords": "players,limit", "FieldName": "$MaxUsers", "InputType": "number", "ParamFieldName": "$.MaxClients", "IncludeInCommandLine": false, "DefaultValue": "16", "MinValue": "1", "EnumValues": {} }, + { "DisplayName": "Whitelist Mode", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Vintage Story whitelist mode", "Keywords": "whitelist", "FieldName": "WhitelistMode", "InputType": "enum", "ParamFieldName": "$.WhitelistMode", "IncludeInCommandLine": false, "DefaultValue": "0", "EnumValues": { "0": "Default", "1": "Off", "2": "On" } }, + { "DisplayName": "Allow PvP", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Allow players to damage other players", "Keywords": "pvp", "FieldName": "AllowPvP", "InputType": "checkbox", "ParamFieldName": "$.AllowPvP", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Enable UPnP", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Normally disabled for a private Nimbus backend", "Keywords": "upnp", "FieldName": "Upnp", "InputType": "checkbox", "ParamFieldName": "$.Upnp", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Vintage Story Version", "Category": "Updates", "Subcategory": "Compatibility:verified_user:-1", "Description": "Required Vintage Story base version. AMP only selects Stratum and Nimbus releases that declare this exact game version", "Keywords": "vintage,story,version", "FieldName": "ServerVersion", "InputType": "text", "ParamFieldName": "ServerVersion", "IncludeInCommandLine": false, "Required": true, "DefaultValue": "1.22.6", "Placeholder": "1.22.6", "EnumValues": {} }, + { "DisplayName": "Stratum Version", "Category": "Updates", "Subcategory": "Compatibility:verified_user:-1", "Description": "Optional exact Stratum release tag. Empty selects the highest stable Stratum revision for the configured Vintage Story version", "Keywords": "stratum,version,release", "FieldName": "StratumVersion", "InputType": "text", "ParamFieldName": "StratumVersion", "IncludeInCommandLine": false, "DefaultValue": "", "Placeholder": "v1.22.6-stratum.2", "EnumValues": {} }, + { "DisplayName": "Nimbus Version", "Category": "Updates", "Subcategory": "Compatibility:verified_user:-1", "Description": "Optional exact Nimbus release tag. Empty selects the newest stable release whose tagged README declares the configured Vintage Story version", "Keywords": "nimbus,version,release", "FieldName": "NimbusVersion", "InputType": "text", "ParamFieldName": "NimbusVersion", "IncludeInCommandLine": false, "DefaultValue": "", "Placeholder": "v0.5.0", "EnumValues": {} }, + { "DisplayName": ".NET Release Stream", "Category": "Updates", "Subcategory": "Runtime:memory:-1", "Description": ".NET SDK release stream required by current Stratum and Nimbus releases", "Keywords": "dotnet,sdk,runtime", "FieldName": "DotnetRelease", "InputType": "enum", "ParamFieldName": "DotnetRelease", "IncludeInCommandLine": false, "DefaultValue": "10.0", "EnumValues": { "10.0": "10.0" } }, + { "DisplayName": ".NET SDK Version", "Category": "Updates", "Subcategory": "Runtime:memory:-1", "Description": "Optional exact SDK version. Empty installs the newest SDK in the selected stream", "Keywords": "dotnet,sdk,version", "FieldName": "DotnetSDKVersion", "InputType": "text", "ParamFieldName": "DotnetSDKVersion", "IncludeInCommandLine": false, "DefaultValue": "", "Placeholder": "10.0.100", "EnumValues": {} }, + { "DisplayName": "Enable Nimbus", "Category": "Nimbus Backend:share", "Subcategory": "Network:dns:1", "Description": "Enable Nimbus.ServerMod on this backend", "Keywords": "nimbus,enable", "FieldName": "NimbusEnabled", "InputType": "checkbox", "ParamFieldName": "$.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Nimbus Server ID", "Category": "Nimbus Backend:share", "Subcategory": "Network:dns:1", "Description": "Unique backend ID matching a key in the proxy Backend Servers setting", "Keywords": "nimbus,server,id", "FieldName": "NimbusServerId", "InputType": "text", "ParamFieldName": "$.ServerId", "IncludeInCommandLine": false, "Required": true, "DefaultValue": "backend-1", "EnumValues": {} }, + { "DisplayName": "Nimbus Display Name", "Category": "Nimbus Backend:share", "Subcategory": "Network:dns:1", "Description": "Human-readable backend name", "Keywords": "nimbus,display,name", "FieldName": "NimbusDisplayName", "InputType": "text", "ParamFieldName": "$.DisplayName", "IncludeInCommandLine": false, "DefaultValue": "Backend 1", "EnumValues": {} }, + { "DisplayName": "Nimbus Public Host", "Category": "Nimbus Backend:share", "Subcategory": "Network:dns:1", "Description": "Host address the proxy network uses to reach this backend", "Keywords": "nimbus,host,address", "FieldName": "NimbusPublicHost", "InputType": "text", "ParamFieldName": "$.PublicHost", "IncludeInCommandLine": false, "Required": true, "DefaultValue": "127.0.0.1", "EnumValues": {} }, + { "DisplayName": "Nimbus Public Port", "Category": "Nimbus Backend:share", "Subcategory": "Network:dns:1", "Description": "Port the proxy network uses to reach this backend", "Keywords": "nimbus,port", "FieldName": "NimbusPublicPort", "InputType": "number", "ParamFieldName": "$.PublicPort", "IncludeInCommandLine": false, "DefaultValue": "42421", "MinValue": "1", "MaxValue": "65535", "EnumValues": {} }, + { "DisplayName": "Nimbus Registry URL", "Category": "Nimbus Backend:share", "Subcategory": "Registry:dns:2", "Description": "Reachable HTTP URL of the proxy's embedded registry", "Keywords": "nimbus,registry,url", "FieldName": "NimbusRegistryUrl", "InputType": "text", "ParamFieldName": "$.RegistryUrl", "IncludeInCommandLine": false, "Required": true, "DefaultValue": "http://127.0.0.1:8765", "EnumValues": {} }, + { "DisplayName": "Nimbus Shared Secret", "Category": "Nimbus Backend:share", "Subcategory": "Registry:dns:2", "Description": "Copy registry.embedded_shared_secret from the proxy's nimbus.proxy.toml. Every backend must use the exact same value", "Keywords": "nimbus,secret,hmac", "FieldName": "NimbusSharedSecret", "InputType": "password", "ParamFieldName": "$.SharedSecret", "IncludeInCommandLine": false, "Required": true, "DefaultValue": "PASTE-THE-SECRET-FROM-nimbus.proxy.toml", "EnumValues": {} }, + { "DisplayName": "Maintenance Mode", "Category": "Nimbus Backend:share", "Subcategory": "Routing:swap_horiz:3", "Description": "Remove this backend from routing while keeping it online", "Keywords": "maintenance,routing", "FieldName": "NimbusMaintenance", "InputType": "checkbox", "ParamFieldName": "$.Maintenance", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Require Proxy Reservation", "Category": "Nimbus Backend:share", "Subcategory": "Routing:swap_horiz:3", "Description": "Reject direct joins that did not receive a Nimbus proxy reservation", "Keywords": "reservation,proxy", "FieldName": "NimbusReservationRequired", "InputType": "checkbox", "ParamFieldName": "$.ReservationRequired", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Fail Closed When Registry Is Unreachable", "Category": "Nimbus Backend:share", "Subcategory": "Routing:swap_horiz:3", "Description": "Reject joins during registry outages instead of failing open", "Keywords": "registry,fail,closed", "FieldName": "NimbusFailClosed", "InputType": "checkbox", "ParamFieldName": "$.FailClosedWhenRegistryUnreachable", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Allow Player Server Command", "Category": "Nimbus Backend:share", "Subcategory": "Transfers:swap_horiz:4", "Description": "Allow players to use /server and /join", "Keywords": "player,server,command", "FieldName": "NimbusAllowPlayerServerCommand", "InputType": "checkbox", "ParamFieldName": "$.AllowPlayerServerCommand", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Transfer Mode", "Category": "Nimbus Backend:share", "Subcategory": "Transfers:swap_horiz:4", "Description": "Redirect is the supported production transfer mode", "Keywords": "transfer,redirect", "FieldName": "NimbusTransferMode", "InputType": "enum", "ParamFieldName": "$.TransferMode", "IncludeInCommandLine": false, "DefaultValue": "redirect", "EnumValues": { "redirect": "Redirect" } }, + { "DisplayName": "Stratum Update Checks", "Category": "Stratum:security", "Subcategory": "Updates:update:1", "Description": "Let Stratum notify staff about matching updates in game", "Keywords": "stratum,update,check", "FieldName": "StratumUpdateChecks", "InputType": "checkbox", "ParamFieldName": "$.UpdateChecker.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Anonymous Stratum Statistics", "Category": "Stratum:security", "Subcategory": "Privacy:visibility:2", "Description": "Send anonymous Stratum version and player-count statistics", "Keywords": "statistics,privacy", "FieldName": "StratumServerStats", "InputType": "checkbox", "ParamFieldName": "$.ServerStats.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Preserve Vanilla Protocol", "Category": "Stratum:security", "Subcategory": "Compatibility:verified_user:3", "Description": "Keep Stratum compatible with the vanilla network protocol", "Keywords": "protocol,compatibility", "FieldName": "StratumPreserveProtocol", "InputType": "checkbox", "ParamFieldName": "$.Hardening.PreserveVanillaProtocol", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Packet Limits", "Category": "Stratum:security", "Subcategory": "Hardening:shield:4", "Description": "Enable per-client packet rate and size limits", "Keywords": "packet,limits,hardening", "FieldName": "StratumPacketLimits", "InputType": "checkbox", "ParamFieldName": "$.PacketLimits.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Log Packet Violations", "Category": "Stratum:security", "Subcategory": "Hardening:shield:4", "Description": "Log packet-limit violations", "Keywords": "packet,log,violation", "FieldName": "StratumLogPacketViolations", "InputType": "checkbox", "ParamFieldName": "$.PacketLimits.LogViolations", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Packet Violations Before Kick", "Category": "Stratum:security", "Subcategory": "Hardening:shield:4", "Description": "Number of packet violations in the window before disconnecting a client", "Keywords": "packet,kick,violations", "FieldName": "StratumPacketKickThreshold", "InputType": "number", "ParamFieldName": "$.PacketLimits.KickAfterViolations", "IncludeInCommandLine": false, "DefaultValue": "8", "MinValue": "0", "EnumValues": {} }, + { "DisplayName": "Packet Back-Pressure", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Cap main-thread packet drain work per tick", "Keywords": "packet,backpressure,performance", "FieldName": "StratumPacketBackPressure", "InputType": "checkbox", "ParamFieldName": "$.PacketBackPressure.Enabled", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Strict Client Mod Whitelist", "Category": "Stratum:security", "Subcategory": "Hardening:shield:4", "Description": "Only permit client mods included by Stratum's client mod policy", "Keywords": "client,mod,whitelist", "FieldName": "StratumStrictClientMods", "InputType": "checkbox", "ParamFieldName": "$.ClientModPolicy.StrictWhitelist", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Split Terrain Pass", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Run terrain generation as two stages; automatic compatibility fallback remains enabled", "Keywords": "worldgen,terrain,performance", "FieldName": "StratumSplitTerrain", "InputType": "checkbox", "ParamFieldName": "$.Worldgen.SplitTerrainPass", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Login Protection", "Category": "Stratum:security", "Subcategory": "Hardening:shield:4", "Description": "Temporarily protect players from damage after joining", "Keywords": "login,protection", "FieldName": "StratumLoginProtection", "InputType": "checkbox", "ParamFieldName": "$.LoginProtection.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Player Privacy", "Category": "Stratum:security", "Subcategory": "Privacy:visibility:2", "Description": "Enable Stratum map-pin and coordinate privacy controls", "Keywords": "player,privacy,map", "FieldName": "StratumPlayerPrivacy", "InputType": "checkbox", "ParamFieldName": "$.PlayerPrivacy.Enabled", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Stratum Backups", "Category": "Stratum:security", "Subcategory": "Backups:save:6", "Description": "Enable Stratum's scheduled backup system", "Keywords": "backup,save", "FieldName": "StratumBackups", "InputType": "checkbox", "ParamFieldName": "$.Backup.Enabled", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Chunk Sending Optimizations", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Enable Stratum chunk-send scheduling and overload controls", "Keywords": "chunks,sending,performance", "FieldName": "StratumChunkSending", "InputType": "checkbox", "ParamFieldName": "$.ChunkSending.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Chunk Generation Optimizations", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Enable Stratum chunk-generation request limits", "Keywords": "chunks,generation,performance", "FieldName": "StratumChunkGeneration", "InputType": "checkbox", "ParamFieldName": "$.ChunkGeneration.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Entity Ticking Optimizations", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Enable distance-aware entity ticking", "Keywords": "entity,ticking,performance", "FieldName": "StratumEntityTicking", "InputType": "checkbox", "ParamFieldName": "$.EntityTicking.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Autosave Smoothing", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Enable incremental autosave and chunk-pressure delays", "Keywords": "autosave,performance", "FieldName": "StratumAutosave", "InputType": "checkbox", "ParamFieldName": "$.AutoSave.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Block Tick Smoothing", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Enable caps and smoothing for block tick work", "Keywords": "block,tick,performance", "FieldName": "StratumBlockTicks", "InputType": "checkbox", "ParamFieldName": "$.BlockTicks.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, + { "DisplayName": "Windows Timer Resolution", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Request high-resolution Windows timers; ignored on Linux", "Keywords": "windows,timer,performance", "FieldName": "StratumTimerResolution", "InputType": "checkbox", "ParamFieldName": "$.TimerResolution.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } } +] diff --git a/stratum-nimbusmetaconfig.json b/stratum-nimbusmetaconfig.json new file mode 100644 index 000000000..576fdc6f7 --- /dev/null +++ b/stratum-nimbusmetaconfig.json @@ -0,0 +1,27 @@ +[ + { + "ConfigFile": "data/serverconfig.json", + "AutoMap": true, + "ConfigType": "json" + }, + { + "ConfigFile": "data/ModConfig/nimbus-server.json", + "AutoMap": true, + "ConfigType": "json" + }, + { + "ConfigFile": "data/ModConfig/stratum.json", + "AutoMap": true, + "ConfigType": "json" + }, + { + "ConfigFile": "data/ModConfig/stratum-commands.json", + "AutoMap": true, + "ConfigType": "json" + }, + { + "ConfigFile": "data/ModConfig/stratum-performance.json", + "AutoMap": true, + "ConfigType": "json" + } +] diff --git a/stratum-nimbusports.json b/stratum-nimbusports.json new file mode 100644 index 000000000..f87761f76 --- /dev/null +++ b/stratum-nimbusports.json @@ -0,0 +1,9 @@ +[ + { + "Protocol": "Both", + "Name": "Backend Server Port", + "Description": "Private game port used by the Nimbus proxy to reach this backend", + "Port": 42421, + "Ref": "ServerPort" + } +] diff --git a/stratum-nimbusupdates.json b/stratum-nimbusupdates.json new file mode 100644 index 000000000..836501be3 --- /dev/null +++ b/stratum-nimbusupdates.json @@ -0,0 +1,15 @@ +[ + { "UpdateStageName": "Server Directory Creation", "UpdateSourcePlatform": "All", "UpdateSource": "CreateDirectory", "UpdateSourceArgs": "{{$FullBaseDir}}server", "SkipOnFailure": false }, + { "UpdateStageName": "Data Directory Creation", "UpdateSourcePlatform": "All", "UpdateSource": "CreateDirectory", "UpdateSourceArgs": "{{$FullBaseDir}}data", "SkipOnFailure": false }, + { "UpdateStageName": "Mods Directory Creation", "UpdateSourcePlatform": "All", "UpdateSource": "CreateDirectory", "UpdateSourceArgs": "{{$FullBaseDir}}data/Mods", "SkipOnFailure": false }, + { "UpdateStageName": "Dotnet Directory Creation", "UpdateSourcePlatform": "All", "UpdateSource": "CreateDirectory", "UpdateSourceArgs": "{{$FullBaseDir}}dotnet", "SkipOnFailure": false }, + { "UpdateStageName": ".NET SDK Download", "UpdateSourcePlatform": "Linux", "UpdateSourceArch": "x86_64", "UpdateSource": "Executable", "UpdateSourceData": "/bin/bash", "UpdateSourceArgs": "-c \"DotnetVersion=\\\"{{DotnetSDKVersion}}\\\"; cd \\\"{{$FullBaseDir}}\\\" && if [[ -x dotnet/dotnet ]]; then InstalledVersion=$(dotnet/dotnet --version | xargs); else InstalledVersion=\\\"\\\"; fi; if [[ -z \\\"$DotnetVersion\\\" ]]; then DotnetVersion=$(wget -qO- https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json | jq -r \\\".[\\\\\\\"latest-sdk\\\\\\\"]\\\"); fi; if [[ ! \\\"$DotnetVersion\\\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+$ ]]; then echo \\\"Invalid .NET SDK version format specified\\\" && exit 1; elif [[ \\\"$InstalledVersion\\\" == \\\"$DotnetVersion\\\" ]]; then echo \\\".NET SDK v$DotnetVersion already installed. Skipping\\\" && exit 0; else rm -f dotnet.tar.gz; wget -qO dotnet.tar.gz https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-linux-x64.tar.gz || { echo \\\".NET SDK download failed\\\"; exit 1; }; rm -rf dotnet/* && tar -xzf dotnet.tar.gz -C dotnet && rm -f dotnet.tar.gz && echo \\\".NET SDK v$DotnetVersion downloaded\\\"; fi\"", "SkipOnFailure": false }, + { "UpdateStageName": ".NET SDK Download", "UpdateSourcePlatform": "Windows", "UpdateSource": "Executable", "UpdateSourceData": "powershell.exe", "UpdateSourceArgs": "-NoProfile -Command \"$ProgressPreference='SilentlyContinue'; [Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $DotnetVersion='{{DotnetSDKVersion}}'; Set-Location '{{$FullBaseDir}}'; if (Test-Path 'dotnet/dotnet.exe') { $InstalledVersion=(& dotnet/dotnet.exe --version).Trim() } else { $InstalledVersion='' }; if ([string]::IsNullOrWhiteSpace($DotnetVersion)) { $DotnetVersion=(Invoke-RestMethod -UseBasicParsing 'https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json').'latest-sdk' }; if ($DotnetVersion -notmatch '^\\d+\\.\\d+\\.\\d+$') { throw 'Invalid .NET SDK version format specified' }; if ($InstalledVersion -eq $DotnetVersion) { Write-Output \\\".NET SDK v$DotnetVersion already installed. Skipping\\\"; exit 0 }; Invoke-WebRequest -UseBasicParsing -Uri \\\"https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-win-x64.zip\\\" -OutFile dotnet.zip -ErrorAction Stop; Remove-Item 'dotnet/*' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive dotnet.zip dotnet -Force; Remove-Item dotnet.zip -Force; Write-Output \\\".NET SDK v$DotnetVersion downloaded\\\"\"", "SkipOnFailure": false }, + { "UpdateStageName": "Stratum Download", "UpdateSourcePlatform": "Windows", "UpdateSource": "Executable", "UpdateSourceData": "powershell.exe", "UpdateSourceArgs": "-NoProfile -Command \"$ErrorActionPreference='Stop'; $ProgressPreference='SilentlyContinue'; $game='{{ServerVersion}}'.Trim(); if ($game -notmatch '^\\d+\\.\\d+\\.\\d+(-rc\\.\\d+|-pre\\.\\d+)?$') { throw 'Invalid Vintage Story version' }; $requested='{{StratumVersion}}'.Trim(); if ($requested -and -not $requested.StartsWith('v')) { $requested='v'+$requested }; $releases=Invoke-RestMethod -UseBasicParsing 'https://api.github.com/repos/StratumServer/Stratum/releases?per_page=100'; if ($requested) { if ($requested -notmatch ('^v'+[regex]::Escape($game)+'-stratum\\.[0-9]+(?:\\.[0-9]+)*(?:-[0-9A-Za-z.-]+)?$')) { throw 'The requested Stratum tag does not match the configured Vintage Story version' }; $selected=$releases | Where-Object { $_.tag_name -eq $requested -and -not $_.draft } | Select-Object -First 1 } else { $pattern='^v'+[regex]::Escape($game)+'-stratum\\.([0-9]+(?:\\.[0-9]+)*)\\z'; $selected=$releases | Where-Object { -not $_.draft -and -not $_.prerelease -and $_.tag_name -match $pattern } | Sort-Object { [datetimeoffset]$_.published_at } -Descending | Select-Object -First 1 }; if (-not $selected) { throw \\\"No stable Stratum release was found for Vintage Story $game\\\" }; $version=$selected.tag_name.Substring(1); $assetName=\\\"stratum-$version-win-x64.zip\\\"; $asset=$selected.assets | Where-Object { $_.name -eq $assetName } | Select-Object -First 1; if (-not $asset -or $asset.browser_download_url -notmatch '^https://') { throw \\\"Release asset $assetName was not found\\\" }; Invoke-WebRequest -UseBasicParsing -Uri $asset.browser_download_url -OutFile '{{$FullBaseDir}}stratum.zip'; Remove-Item '{{$FullBaseDir}}stratum-temp' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive '{{$FullBaseDir}}stratum.zip' '{{$FullBaseDir}}stratum-temp' -Force; if (-not (Test-Path '{{$FullBaseDir}}stratum-temp/StratumServer.exe')) { throw 'StratumServer.exe was not found in the release' }; Copy-Item '{{$FullBaseDir}}stratum-temp/*' '{{$FullBaseDir}}server' -Recurse -Force; [IO.File]::WriteAllText('{{$FullBaseDir}}.stratum-version',$selected.tag_name); Remove-Item '{{$FullBaseDir}}stratum-temp','{{$FullBaseDir}}stratum.zip' -Recurse -Force; Write-Output (\\\"Stratum $($selected.tag_name) installed for Vintage Story $game\\\")\"", "SkipOnFailure": false }, + { "UpdateStageName": "Stratum Download", "UpdateSourcePlatform": "Linux", "UpdateSourceArch": "x86_64", "UpdateSource": "Executable", "UpdateSourceData": "/bin/bash", "UpdateSourceArgs": "-c \"set -euo pipefail; game='{{ServerVersion}}'; requested='{{StratumVersion}}'; [[ \\\"$game\\\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+(-rc\\.[0-9]+|-pre\\.[0-9]+)?$ ]] || { echo 'Invalid Vintage Story version'; exit 1; }; [[ -z \\\"$requested\\\" || \\\"$requested\\\" == v* ]] || requested=\\\"v$requested\\\"; releases='{{$FullBaseDir}}stratum-releases.json'; wget -qO \\\"$releases\\\" 'https://api.github.com/repos/StratumServer/Stratum/releases?per_page=100'; escaped_game=${game//./\\.}; if [[ -n \\\"$requested\\\" ]]; then [[ \\\"$requested\\\" =~ ^v${escaped_game}-stratum\\.[0-9]+(\\.[0-9]+)*(-[0-9A-Za-z.-]+)?$ ]] || { echo 'The requested Stratum tag does not match the configured Vintage Story version'; exit 1; }; selected=$(jq -r --arg tag \\\"$requested\\\" '.[] | select(.tag_name==$tag and (.draft|not)) | .tag_name' \\\"$releases\\\" | head -1); else selected=$(jq -r '.[] | select((.draft|not) and (.prerelease|not)) | .tag_name' \\\"$releases\\\" | grep -E \\\"^v${escaped_game}-stratum\\\\.[0-9]+(\\\\.[0-9]+)*$\\\" | sort -V | tail -1); fi; [[ -n \\\"$selected\\\" ]] || { echo \\\"No stable Stratum release was found for Vintage Story $game\\\"; exit 1; }; version=${selected#v}; asset=\\\"stratum-$version-linux-x64.zip\\\"; url=$(jq -r --arg tag \\\"$selected\\\" --arg asset \\\"$asset\\\" '.[] | select(.tag_name==$tag) | .assets[] | select(.name==$asset) | .browser_download_url' \\\"$releases\\\" | head -1); [[ \\\"$url\\\" == https://* ]] || { echo \\\"Release asset $asset was not found\\\"; exit 1; }; wget -qO '{{$FullBaseDir}}stratum.zip' \\\"$url\\\"; rm -rf '{{$FullBaseDir}}stratum-temp'; mkdir -p '{{$FullBaseDir}}stratum-temp'; unzip -qo '{{$FullBaseDir}}stratum.zip' -d '{{$FullBaseDir}}stratum-temp'; [[ -f '{{$FullBaseDir}}stratum-temp/StratumServer' ]] || { echo 'StratumServer was not found in the release'; exit 1; }; cp -rf '{{$FullBaseDir}}stratum-temp/.' '{{$FullBaseDir}}server/'; chmod +x '{{$FullBaseDir}}server/StratumServer'; printf '%s' \\\"$selected\\\" > '{{$FullBaseDir}}.stratum-version'; rm -rf '{{$FullBaseDir}}stratum-temp' '{{$FullBaseDir}}stratum.zip' \\\"$releases\\\"; echo \\\"Stratum $selected installed for Vintage Story $game\\\"\"", "SkipOnFailure": false }, + { "UpdateStageName": "Nimbus Server Mod Download", "UpdateSourcePlatform": "Windows", "UpdateSource": "Executable", "UpdateSourceData": "powershell.exe", "UpdateSourceArgs": "-NoProfile -Command \"$ErrorActionPreference='Stop'; $ProgressPreference='SilentlyContinue'; $game='{{ServerVersion}}'.Trim(); $requested='{{NimbusVersion}}'.Trim(); if ($requested -and -not $requested.StartsWith('v')) { $requested='v'+$requested }; $releases=Invoke-RestMethod -UseBasicParsing 'https://api.github.com/repos/StratumServer/Nimbus/releases?per_page=100'; if ($requested) { $candidates=@($releases | Where-Object { $_.tag_name -eq $requested -and -not $_.draft }) } else { $candidates=@($releases | Where-Object { -not $_.draft -and -not $_.prerelease }) }; $selected=$null; foreach ($release in $candidates) { try { $readme=Invoke-WebRequest -UseBasicParsing -Uri ('https://raw.githubusercontent.com/StratumServer/Nimbus/'+$release.tag_name+'/README.md') | Select-Object -ExpandProperty Content } catch { continue }; $match=[regex]::Match($readme,'Built and tested against Vintage Story\\s+([0-9]+\\.[0-9]+\\.[0-9]+(?:-rc\\.[0-9]+|-pre\\.[0-9]+)?)',[Text.RegularExpressions.RegexOptions]::IgnoreCase); if ($match.Success -and $match.Groups[1].Value -eq $game) { $selected=$release; break } }; if (-not $selected) { throw \\\"No Nimbus release declares compatibility with Vintage Story $game\\\" }; $assetName='Nimbus.ServerMod-'+$selected.tag_name+'.zip'; $asset=$selected.assets | Where-Object { $_.name -eq $assetName } | Select-Object -First 1; if (-not $asset -or $asset.browser_download_url -notmatch '^https://') { throw \\\"Release asset $assetName was not found\\\" }; Invoke-WebRequest -UseBasicParsing -Uri $asset.browser_download_url -OutFile '{{$FullBaseDir}}nimbus-mod.zip'; Remove-Item '{{$FullBaseDir}}nimbus-mod-temp' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive '{{$FullBaseDir}}nimbus-mod.zip' '{{$FullBaseDir}}nimbus-mod-temp' -Force; if (-not (Test-Path '{{$FullBaseDir}}nimbus-mod-temp/modinfo.json')) { throw 'Nimbus ServerMod modinfo.json was not found in the release' }; Remove-Item '{{$FullBaseDir}}data/Mods/Nimbus.ServerMod' -Recurse -Force -ErrorAction SilentlyContinue; New-Item -ItemType Directory '{{$FullBaseDir}}data/Mods/Nimbus.ServerMod' -Force | Out-Null; Copy-Item '{{$FullBaseDir}}nimbus-mod-temp/*' '{{$FullBaseDir}}data/Mods/Nimbus.ServerMod' -Recurse -Force; [IO.File]::WriteAllText('{{$FullBaseDir}}.nimbus-version',$selected.tag_name); Remove-Item '{{$FullBaseDir}}nimbus-mod-temp','{{$FullBaseDir}}nimbus-mod.zip' -Recurse -Force; Write-Output (\\\"Nimbus ServerMod $($selected.tag_name) installed for Vintage Story $game\\\")\"", "SkipOnFailure": false }, + { "UpdateStageName": "Nimbus Server Mod Download", "UpdateSourcePlatform": "Linux", "UpdateSourceArch": "x86_64", "UpdateSource": "Executable", "UpdateSourceData": "/bin/bash", "UpdateSourceArgs": "-c \"set -euo pipefail; game='{{ServerVersion}}'; requested='{{NimbusVersion}}'; [[ -z \\\"$requested\\\" || \\\"$requested\\\" == v* ]] || requested=\\\"v$requested\\\"; releases='{{$FullBaseDir}}nimbus-releases.json'; wget -qO \\\"$releases\\\" 'https://api.github.com/repos/StratumServer/Nimbus/releases?per_page=100'; if [[ -n \\\"$requested\\\" ]]; then tags=\\\"$requested\\\"; else tags=$(jq -r '.[] | select((.draft|not) and (.prerelease|not)) | .tag_name' \\\"$releases\\\"); fi; selected=''; while IFS= read -r tag; do [[ -n \\\"$tag\\\" ]] || continue; readme=$(wget -qO- \\\"https://raw.githubusercontent.com/StratumServer/Nimbus/$tag/README.md\\\" || true); compatible=$(printf '%s' \\\"$readme\\\" | grep -Eio 'Built and tested against Vintage Story[[:space:]]+[0-9]+\\.[0-9]+\\.[0-9]+(-rc\\.[0-9]+|-pre\\.[0-9]+)?' | head -1 | awk '{print $7}'); if [[ \\\"$compatible\\\" == \\\"$game\\\" ]]; then selected=\\\"$tag\\\"; break; fi; done <<< \\\"$tags\\\"; [[ -n \\\"$selected\\\" ]] || { echo \\\"No Nimbus release declares compatibility with Vintage Story $game\\\"; exit 1; }; asset=\\\"Nimbus.ServerMod-$selected.zip\\\"; url=$(jq -r --arg tag \\\"$selected\\\" --arg asset \\\"$asset\\\" '.[] | select(.tag_name==$tag) | .assets[] | select(.name==$asset) | .browser_download_url' \\\"$releases\\\" | head -1); [[ \\\"$url\\\" == https://* ]] || { echo \\\"Release asset $asset was not found\\\"; exit 1; }; wget -qO '{{$FullBaseDir}}nimbus-mod.zip' \\\"$url\\\"; rm -rf '{{$FullBaseDir}}nimbus-mod-temp'; mkdir -p '{{$FullBaseDir}}nimbus-mod-temp'; unzip -qo '{{$FullBaseDir}}nimbus-mod.zip' -d '{{$FullBaseDir}}nimbus-mod-temp'; [[ -f '{{$FullBaseDir}}nimbus-mod-temp/modinfo.json' ]] || { echo 'Nimbus ServerMod modinfo.json was not found in the release'; exit 1; }; rm -rf '{{$FullBaseDir}}data/Mods/Nimbus.ServerMod'; mkdir -p '{{$FullBaseDir}}data/Mods/Nimbus.ServerMod'; cp -rf '{{$FullBaseDir}}nimbus-mod-temp/.' '{{$FullBaseDir}}data/Mods/Nimbus.ServerMod/'; printf '%s' \\\"$selected\\\" > '{{$FullBaseDir}}.nimbus-version'; rm -rf '{{$FullBaseDir}}nimbus-mod-temp' '{{$FullBaseDir}}nimbus-mod.zip' \\\"$releases\\\"; echo \\\"Nimbus ServerMod $selected installed for Vintage Story $game\\\"\"", "SkipOnFailure": false }, + { "UpdateStageName": "Start Server", "UpdateSourcePlatform": "All", "UpdateSource": "StartApplication", "SkipOnFailure": false }, + { "UpdateStageName": "Wait For Server Start", "UpdateSourcePlatform": "All", "UpdateSource": "WaitForStartupComplete", "SkipOnFailure": false }, + { "UpdateStageName": "Stop Server", "UpdateSourcePlatform": "All", "UpdateSource": "ShutdownApplication", "SkipOnFailure": false } +] From b59918dd5557c10ccc577b21fb59c89470730974 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Fri, 7 Aug 2026 14:06:45 -0500 Subject: [PATCH 14/50] Add files via upload --- nimbus-proxy.kvp | 2 +- stratum-nimbus.kvp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nimbus-proxy.kvp b/nimbus-proxy.kvp index 11cbac9a8..e3ddc6e0e 100644 --- a/nimbus-proxy.kvp +++ b/nimbus-proxy.kvp @@ -3,7 +3,7 @@ Meta.Description=Nimbus proxy with an embedded registry for routing multiple Vin Meta.OS=Windows, Linux Meta.AarchSupport=Native Meta.Arch=x86_64 -Meta.Author=StratumServer +Meta.Author=HuguesDePayens Meta.URL=https://github.com/StratumServer/Nimbus Meta.DisplayImageSource=url:https://wiki.vintagestory.at/images/thumb/8/8a/Gamelogo-vintagestory.png/340px-Gamelogo-vintagestory.png Meta.EndpointURIFormat= diff --git a/stratum-nimbus.kvp b/stratum-nimbus.kvp index d3efa5afe..6b5d043f9 100644 --- a/stratum-nimbus.kvp +++ b/stratum-nimbus.kvp @@ -3,7 +3,7 @@ Meta.Description=Stratum-powered Vintage Story server with Nimbus.ServerMod for Meta.OS=Windows, Linux Meta.AarchSupport=Native Meta.Arch=x86_64 -Meta.Author=StratumServer +Meta.Author=HuguesDePayens Meta.URL=https://github.com/StratumServer/Stratum Meta.DisplayImageSource=url:https://wiki.vintagestory.at/images/thumb/8/8a/Gamelogo-vintagestory.png/340px-Gamelogo-vintagestory.png Meta.EndpointURIFormat= From 58f85e21d7d1469122757faac70a909e3b054de7 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Fri, 7 Aug 2026 18:50:39 -0500 Subject: [PATCH 15/50] Add files via upload --- nimbus-proxy.kvp | 72 +- nimbus-proxyconfig.json | 1132 ++- nimbus-proxyports.json | 14 +- nimbus-proxystart.json | 17 +- nimbus-proxyupdates.json | 100 +- nimbus-registry.kvp | 97 + nimbus-registryconfig.json | 582 ++ nimbus-registrymetaconfig.json | 1 + nimbus-registryports.json | 9 + nimbus-registrystart.json | 18 + nimbus-registryupdates.json | 109 + vintage-story-stratum.kvp | 96 + vintage-story-stratumconfig.json | 9795 ++++++++++++++++++++++++++ vintage-story-stratummetaconfig.json | 22 + vintage-story-stratumports.json | 9 + vintage-story-stratumstart.json | 22 + vintage-story-stratumupdates.json | 213 + 17 files changed, 12084 insertions(+), 224 deletions(-) create mode 100644 nimbus-registry.kvp create mode 100644 nimbus-registryconfig.json create mode 100644 nimbus-registrymetaconfig.json create mode 100644 nimbus-registryports.json create mode 100644 nimbus-registrystart.json create mode 100644 nimbus-registryupdates.json create mode 100644 vintage-story-stratum.kvp create mode 100644 vintage-story-stratumconfig.json create mode 100644 vintage-story-stratummetaconfig.json create mode 100644 vintage-story-stratumports.json create mode 100644 vintage-story-stratumstart.json create mode 100644 vintage-story-stratumupdates.json diff --git a/nimbus-proxy.kvp b/nimbus-proxy.kvp index e3ddc6e0e..b59e75393 100644 --- a/nimbus-proxy.kvp +++ b/nimbus-proxy.kvp @@ -1,7 +1,7 @@ -Meta.DisplayName=Nimbus Proxy for Vintage Story -Meta.Description=Nimbus proxy with an embedded registry for routing multiple Vintage Story backend servers +Meta.DisplayName=Nimbus Proxy (Vintage Story) +Meta.Description=Nimbus proxy for Vintage Story. Players connect to this one instance and it routes them to any number of Stratum or vanilla backend servers, with transfers, reservations, bans and a network wide whitelist. Can host the Nimbus registry in-process (embedded mode) or point at a standalone registry instance. Meta.OS=Windows, Linux -Meta.AarchSupport=Native +Meta.AarchSupport=None Meta.Arch=x86_64 Meta.Author=HuguesDePayens Meta.URL=https://github.com/StratumServer/Nimbus @@ -14,67 +14,77 @@ Meta.MinAMPVersion=2.4.6.0 Meta.SpecificDockerImage=cubecoders/ampbase:debian Meta.DockerRequired=False Meta.ContainerPolicy=Supported +Meta.ExtraContainerPackages=["jq","unzip","curl","ca-certificates"] Meta.Prerequisites=[] Meta.ConfigReleaseState=NotSpecified -Meta.NoCommercialUsage=True +Meta.NoCommercialUsage=False Meta.ConfigVersion=1 -Meta.AppConfigId=1937f89c-43e2-48cd-97b9-b71ca9440124 +Meta.AppConfigId=b41d7e08-9c56-4f3a-8d17-6ae2b90c5f44 +Meta.AppIsMultiIPAware=True +Meta.ResourceUsageInfo=1 CPU core and 512MB RAM is plenty for the proxy itself; it relays traffic and holds no world data +Meta.ImportableExtensions=[] App.DisplayName=Nimbus Proxy -App.RootDir=./nimbus-proxy/ -App.BaseDirectory=./nimbus-proxy/ +App.RootDir=./nimbus/ +App.BaseDirectory=./nimbus/ App.ExecutableWin=dotnet\dotnet.exe App.ExecutableLinux=dotnet/dotnet -App.WorkingDir= -App.LinuxCommandLineArgs= -App.WindowsCommandLineArgs= -App.CommandLineArgs=app/Nimbus.Proxy.dll +App.WorkingDir=Nimbus +App.LinuxCommandLineArgs="{{$FullRootDir}}Nimbus/Nimbus.Proxy.dll" +App.WindowsCommandLineArgs="{{$FullRootDir}}Nimbus\Nimbus.Proxy.dll" +App.CommandLineArgs={{$PlatformArgs}} {{ProxyExtraArgs}} App.UseLinuxIOREDIR=False App.AppSettings={} -App.EnvironmentVariables={"DOTNET_ROOT":"{{$FullBaseDir}}dotnet"} -App.CommandLineParameterFormat={0} {1} +App.EnvironmentVariables={"DOTNET_ROOT":"{{$FullRootDir}}dotnet","DOTNET_CLI_TELEMETRY_OPTOUT":"1","DOTNET_NOLOGO":"1"} +App.CommandLineParameterFormat=--{0} {1} App.CommandLineParameterDelimiter= -App.ExitMethod=OS_CLOSE -App.ExitMethodWindows=CtrlC +App.ExitMethod=SIGTERM +App.ExitMethodWindows=None App.ExitTimeout=30 App.ExitString= -App.ExitFile= -App.HasWriteableConsole=True +App.ExitFile=lock +App.HasWriteableConsole=False App.HasReadableConsole=True App.SupportsLiveSettingsChanges=False App.LiveSettingChangeCommandFormat= App.ApplicationIPBinding=0.0.0.0 App.Ports=@IncludeJson[nimbus-proxyports.json] App.AdminPortRef=AdminPort -App.PrimaryApplicationPortRef=ProxyPort -App.UniversalSleepApplicationUDPPortRef=ProxyPort -App.UniversalSleepSteamQueryPortRef=ProxyPort -App.MaxUsers={{ProxyMaxPlayers}} +App.PrimaryApplicationPortRef=ServerPort +App.UniversalSleepApplicationUDPPortRef=ServerPort +App.UniversalSleepSteamQueryPortRef=ServerPort +App.MaxUsers=100 App.UseRandomAdminPassword=False App.RemoteAdminPassword= -App.AdminMethod=None +App.AdminMethod=STDIO +App.AdminLoginTransform=None App.RCONConnectDelaySeconds=5 App.RCONConnectRetrySeconds=5 App.RCONHeartbeatMinutes=0 -App.RCONHeartbeatCommand= -App.UpdateSources=@IncludeJson[nimbus-proxyupdates.json] +App.RCONHeartbeatCommand=ping +App.TelnetLoginFormat={0} App.PreStartStages=@IncludeJson[nimbus-proxystart.json] +App.UpdateSources=@IncludeJson[nimbus-proxyupdates.json] App.Compatibility=None App.SteamUpdateAnonymousLogin=True App.SteamForceLoginPrompt=False App.RapidStartup=False -App.SmartExcludeExemptions=["*.cfg","*.conf","*.config","*.ini","*.json","*.xml","*.properties","*.kvp","*.yml","*.yaml","*.toml","*.lua"] +App.SmartExcludeSupported=True +App.SmartExcludeExemptions=["*.toml","*.json","*.cfg","*.conf","*.config","*.ini","*.kvp","*.yml","*.yaml"] App.MonitorChildProcess=False +App.MonitorChildProcessWaitMs=100 +App.MonitorChildProcessName= App.SupportsUniversalSleep=False App.WakeupMode=Any App.ApplicationReadyMode=RegexMatch +App.StripANSIControlCodes=True Console.FilterMatchRegex= Console.FilterMatchReplacement= -Console.ThrowawayMessageRegex=^$ -Console.AppReadyRegex=^.*\[nimbus\] listening on .+$ -Console.UserJoinRegex=^.*session (?[^ ]+) connected.*$ -Console.UserLeaveRegex=^.*session (?[^ ]+) closed.*$ -Console.UserChatRegex=^$ -Console.UpdateAvailableRegex=^.*Nimbus update available:.*$ +Console.ThrowawayMessageRegex= +Console.AppReadyRegex=^[\d:]+ \[nimbus\] listening on .+ -> .+$ +Console.UserJoinRegex=^[\d:]+ \[nimbus\] \[s\d+\] (?.+?) \([\[\]a-fA-F\d:.]+\) . .+$ +Console.UserLeaveRegex=^[\d:]+ \[nimbus\] \[s\d+\] (?.+?) disconnected \(.+\)$ +Console.UserChatRegex= +Console.UpdateAvailableRegex=^[\d:]+ \[nimbus\] warn: update available: .*$ Console.MetricsRegex= Console.SuppressLogAtStart=False Console.ActivateLogRegex= diff --git a/nimbus-proxyconfig.json b/nimbus-proxyconfig.json index 20cd9a5d7..2d9c23f3b 100644 --- a/nimbus-proxyconfig.json +++ b/nimbus-proxyconfig.json @@ -1,252 +1,1082 @@ [ { - "DisplayName": "Proxy Port", - "Category": "Nimbus Proxy:share", - "Subcategory": "Network:dns:1", - "Description": "Player-facing proxy port", - "Keywords": "proxy,port", - "FieldName": "$ProxyPort", - "InputType": "number", - "Hidden": true, - "ParamFieldName": "ProxyPort", + "DisplayName": "Let AMP Manage nimbus.proxy.toml", + "Category": "Updates", + "Subcategory": "Nimbus Updates:build:-1", + "Description": "When on, AMP rewrites Nimbus/nimbus.proxy.toml from the settings in this panel every time the instance starts. Turn it off to hand-edit that file instead; every proxy setting in this panel is then ignored.", + "Keywords": "nimbus,config,manage", + "FieldName": "ProxyWriteConfig", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyWriteConfig", "IncludeInCommandLine": false, - "EnumValues": {} + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } }, { - "DisplayName": "Registry Port", - "Category": "Nimbus Proxy:share", - "Subcategory": "Network:dns:1", - "Description": "Embedded registry heartbeat port", - "Keywords": "registry,port", - "FieldName": "$RegistryPort", - "InputType": "number", - "Hidden": true, - "ParamFieldName": "RegistryPort", + "DisplayName": "Nimbus Version Tag", + "Category": "Updates", + "Subcategory": "Nimbus Updates:build:-1", + "Description": "Pin a specific Nimbus release tag, for example v0.5.0. Leave empty to take the newest release on the channel below. Every part of a Nimbus network - proxy, registry and the server mod on each backend - must run the same Nimbus version, so pin this once you go live and bump all of them together.", + "Keywords": "nimbus,version,tag", + "FieldName": "NimbusVersionTag", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "NimbusVersionTag", "IncludeInCommandLine": false, - "EnumValues": {} + "DefaultValue": "", + "EnumValues": {}, + "Placeholder": "v0.5.0" }, { - "DisplayName": "Admin Port", - "Category": "Nimbus Proxy:share", - "Subcategory": "Network:dns:1", - "Description": "Local nimctl administration port", - "Keywords": "admin,port,nimctl", - "FieldName": "$AdminPort", - "InputType": "number", - "Hidden": true, - "ParamFieldName": "AdminPort", + "DisplayName": "Nimbus Release Channel", + "Category": "Updates", + "Subcategory": "Nimbus Updates:build:-1", + "Description": "stable takes the newest non prerelease. prerelease also considers releases marked as pre-release, which is only for test networks.", + "Keywords": "nimbus,channel,prerelease", + "FieldName": "NimbusReleaseChannel", + "InputType": "enum", + "IsFlagArgument": false, + "ParamFieldName": "NimbusReleaseChannel", "IncludeInCommandLine": false, - "EnumValues": {} + "DefaultValue": "stable", + "EnumValues": { + "Stable releases only": "stable", + "Include pre-releases": "prerelease" + } }, { - "DisplayName": "Metrics Port", - "Category": "Nimbus Proxy:share", - "Subcategory": "Network:dns:1", - "Description": "Local metrics and status port", - "Keywords": "metrics,status,port", - "FieldName": "$MetricsPort", - "InputType": "number", - "Hidden": true, - "ParamFieldName": "MetricsPort", + "DisplayName": "GitHub Token (optional)", + "Category": "Updates", + "Subcategory": "Nimbus Updates:build:-1", + "Description": "Optional GitHub personal access token used only to raise the API rate limit while looking up releases. Nothing here needs a private repository, so leave it empty unless updates start failing with a rate limit message.", + "Keywords": "github,token,ratelimit", + "FieldName": "NimbusGitHubToken", + "InputType": "password", + "IsFlagArgument": false, + "ParamFieldName": "NimbusGitHubToken", "IncludeInCommandLine": false, + "DefaultValue": "", "EnumValues": {} }, { - "DisplayName": "Vintage Story Version", + "DisplayName": "Components To Install", "Category": "Updates", - "Subcategory": "Compatibility:verified_user:-1", - "Description": "Vintage Story version used to select a compatible Nimbus release. Automatic updates stop instead of installing a release built for a different game version", - "Keywords": "vintage,story,version,compatibility", - "FieldName": "ServerVersion", - "InputType": "text", - "ParamFieldName": "ServerVersion", + "Subcategory": "Nimbus Updates:build:-1", + "Description": "Which parts of the Nimbus release are unpacked into this instance. Nimbus is the proxy itself. Nimbus Nimbus.Registry also unpacks the standalone registry next to it, which is only useful if you want to run both out of one instance.", + "Keywords": "nimbus,components", + "FieldName": "NimbusUpdateComponents", + "InputType": "enum", + "IsFlagArgument": false, + "ParamFieldName": "NimbusUpdateComponents", "IncludeInCommandLine": false, - "Required": true, - "DefaultValue": "1.22.6", - "Placeholder": "1.22.6", - "EnumValues": {} + "DefaultValue": "Nimbus", + "EnumValues": { + "Proxy only": "Nimbus", + "Proxy and standalone registry": "Nimbus Nimbus.Registry" + } }, { - "DisplayName": "Nimbus Version", + "DisplayName": ".NET SDK Version", "Category": "Updates", - "Subcategory": "Compatibility:verified_user:-1", - "Description": "Optional Nimbus release tag such as v0.5.0. Empty selects the newest stable release whose tagged README states it was built and tested against the configured Vintage Story version", - "Keywords": "nimbus,version,release", - "FieldName": "NimbusVersion", + "Subcategory": "Runtime:memory:-1", + "Description": "Exact .NET SDK version to install, for example 10.0.100. Leave this empty to always take the latest SDK from the channel below, which is what you want unless a specific build broke something.", + "Keywords": "dotnet,sdk,version", + "FieldName": "DotnetSDKVersion", "InputType": "text", - "ParamFieldName": "NimbusVersion", + "IsFlagArgument": false, + "ParamFieldName": "DotnetSDKVersion", "IncludeInCommandLine": false, "DefaultValue": "", - "Placeholder": "v0.5.0", - "EnumValues": {} + "EnumValues": {}, + "Placeholder": "10.0.100" }, { - "DisplayName": ".NET Release Stream", + "DisplayName": ".NET Release Channel", "Category": "Updates", "Subcategory": "Runtime:memory:-1", - "Description": ".NET SDK release stream required by Nimbus", - "Keywords": "dotnet,runtime,sdk", + "Description": "The .NET release channel the SDK is fetched from. Nimbus Proxy targets .NET 10 and needs the ASP.NET Core runtime, which the SDK includes, so leave this at 10.0 unless Nimbus itself moves to a newer runtime.", + "Keywords": "dotnet,release,channel", "FieldName": "DotnetRelease", - "InputType": "enum", + "InputType": "text", + "IsFlagArgument": false, "ParamFieldName": "DotnetRelease", "IncludeInCommandLine": false, "DefaultValue": "10.0", - "EnumValues": { - "10.0": "10.0" - } + "EnumValues": {}, + "Placeholder": "10.0" }, { - "DisplayName": ".NET SDK Version", + "DisplayName": "Additional Command Line Arguments", "Category": "Updates", - "Subcategory": "Runtime:memory:-1", - "Description": "Optional exact .NET SDK version. Empty installs the newest SDK in the selected release stream", - "Keywords": "dotnet,version,sdk", - "FieldName": "DotnetSDKVersion", + "Subcategory": "Nimbus Updates:build:-1", + "Description": "Extra arguments appended to the proxy command line. Nimbus takes no arguments of its own, so leave this empty unless a plugin documents one.", + "Keywords": "args,commandline", + "FieldName": "ProxyExtraArgs", "InputType": "text", - "ParamFieldName": "DotnetSDKVersion", + "IsFlagArgument": false, + "ParamFieldName": "ProxyExtraArgs", "IncludeInCommandLine": false, "DefaultValue": "", - "Placeholder": "10.0.100", "EnumValues": {} }, { "DisplayName": "Proxy Bind Address", - "Category": "Nimbus Proxy:share", - "Subcategory": "Network:dns:1", - "Description": "IP address on which players reach the proxy", - "Keywords": "proxy,bind,address", - "FieldName": "ProxyBindAddress", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Listener:settings_input_antenna:1", + "Description": "Interface the proxy listens on for players. 0.0.0.0 means every interface. The port is taken from the instance's Server Port setting, so change the port there, not here. (Config file key: bind)", + "Keywords": "proxybindhost", + "FieldName": "ProxyBindHost", "InputType": "text", - "ParamFieldName": "ProxyBindAddress", + "IsFlagArgument": false, + "ParamFieldName": "ProxyBindHost", "IncludeInCommandLine": false, - "Required": true, - "DefaultValue": "0.0.0.0", - "EnumValues": {} + "DefaultValue": "0.0.0.0:42420", + "EnumValues": {}, + "Placeholder": "0.0.0.0" }, { "DisplayName": "Backend Servers", - "Category": "Nimbus Proxy:share", - "Subcategory": "Backend Pool:dns:2", - "Description": "Semicolon-separated serverId=host:port entries. Every server ID must match that backend's Nimbus Server ID. Example: hub=127.0.0.1:42421;survival=127.0.0.1:42422", - "Keywords": "backend,servers,pool", - "FieldName": "BackendServers", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Listener:settings_input_antenna:1", + "Description": "The [servers] table: comma separated list of id=host:port entries, for example hub=127.0.0.1:42421,creative=127.0.0.1:42422. Each id must match the Server ID configured in that backend's Nimbus settings, and each host:port is the address the PROXY uses to reach the backend, not the address players use. (Config file key: servers)", + "Keywords": "proxyservers", + "FieldName": "ProxyServers", "InputType": "text", - "ParamFieldName": "BackendServers", + "IsFlagArgument": false, + "ParamFieldName": "ProxyServers", "IncludeInCommandLine": false, - "Required": true, - "DefaultValue": "backend-1=127.0.0.1:42421", - "EnumValues": {} + "DefaultValue": "hub=127.0.0.1:42421", + "EnumValues": {}, + "Placeholder": "hub=127.0.0.1:42421,creative=127.0.0.1:42422" }, { - "DisplayName": "Initial Server Order", - "Category": "Nimbus Proxy:share", - "Subcategory": "Backend Pool:dns:2", - "Description": "Comma-separated backend server IDs tried for a player's initial connection", - "Keywords": "try,initial,backend,order", - "FieldName": "TryServers", + "DisplayName": "Initial Connect Order", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Listener:settings_input_antenna:1", + "Description": "Comma separated backend ids tried in order when a player first joins the proxy. The first one that accepts the connection wins. Unknown ids are skipped with a warning. (Config file key: try)", + "Keywords": "proxytrylist", + "FieldName": "ProxyTryList", "InputType": "text", - "ParamFieldName": "TryServers", + "IsFlagArgument": false, + "ParamFieldName": "ProxyTryList", "IncludeInCommandLine": false, - "Required": true, - "DefaultValue": "backend-1", - "EnumValues": {} + "DefaultValue": "hub", + "EnumValues": {}, + "Placeholder": "hub" + }, + { + "DisplayName": "PROXY Protocol Backends", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Listener:settings_input_antenna:1", + "Description": "Comma separated backend ids that should receive a PROXY protocol v2 header on every upstream connection, so the backend sees the player's real IP. The backend must trust this proxy's IP or it will reject the connection. Leave empty for unmodified backends. (Config file key: proxy_protocol_servers)", + "Keywords": "proxyprotocolservers", + "FieldName": "ProxyProtocolServers", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "ProxyProtocolServers", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Placeholder": "hub,creative" }, { - "DisplayName": "Registry Bind Address", - "Category": "Nimbus Proxy:share", - "Subcategory": "Embedded Registry:dns:3", - "Description": "Registry IP address. Use 127.0.0.1 when all backends are on this host, or 0.0.0.0 when remote backends must heartbeat to it", - "Keywords": "registry,bind,address", - "FieldName": "RegistryBindAddress", + "DisplayName": "Forced Hosts", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Listener:settings_input_antenna:1", + "Description": "Reserved by Nimbus for hostname based routing and not consumed yet. Format hostname=id1|id2,hostname2=id3. Safe to leave empty. (Config file key: forced_hosts)", + "Keywords": "proxyforcedhosts", + "FieldName": "ProxyForcedHosts", "InputType": "text", - "ParamFieldName": "RegistryBindAddress", + "IsFlagArgument": false, + "ParamFieldName": "ProxyForcedHosts", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Placeholder": "play.example.com=hub|creative" + }, + { + "DisplayName": "Default Transfer Mode", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Transfers:swap_horiz:2", + "Description": "How a player is moved between backends when no mode is requested explicitly. redirect is the vanilla reconnect flow and works with unmodified clients. seamless is the Nimbus visual handoff and needs the Nimbus client mod. (Config file key: transfers.default_mode)", + "Keywords": "proxytransfersdefaultmode", + "FieldName": "ProxyTransfersDefaultMode", + "InputType": "enum", + "IsFlagArgument": false, + "ParamFieldName": "ProxyTransfersDefaultMode", + "IncludeInCommandLine": false, + "DefaultValue": "redirect", + "EnumValues": { + "Redirect (vanilla reconnect)": "redirect", + "Seamless (needs Nimbus client mod)": "seamless" + } + }, + { + "DisplayName": "Allow Seamless Transfers", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Transfers:swap_horiz:2", + "Description": "Master switch for the seamless handoff path. Off means every transfer is a redirect, whatever a plugin or command asks for. (Config file key: transfers.allow_seamless)", + "Keywords": "proxytransfersallowseamless", + "FieldName": "ProxyTransfersAllowSeamless", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyTransfersAllowSeamless", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Require Seamless Capability", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Transfers:swap_horiz:2", + "Description": "Keep seamless transfers tied to a client that proved it speaks the Nimbus handshake. Turning this off will break vanilla clients that get handed a seamless transfer. (Config file key: transfers.require_seamless_capability)", + "Keywords": "proxytransfersrequireseamlesscapability", + "FieldName": "ProxyTransfersRequireSeamlessCapability", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyTransfersRequireSeamlessCapability", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Fall Back To Redirect", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Transfers:swap_horiz:2", + "Description": "When a seamless transfer was requested but the client cannot do it, send a normal redirect instead of failing the transfer. (Config file key: transfers.fallback_to_redirect_when_seamless_unavailable)", + "Keywords": "proxytransfersfallbacktoredirect", + "FieldName": "ProxyTransfersFallbackToRedirect", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyTransfersFallbackToRedirect", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Redirect Address Override", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Transfers:swap_horiz:2", + "Description": "host or host:port stamped into redirect packets instead of the target backend's own address. Set this to the proxy's player facing address so a fixed vanilla client reconnects to the proxy rather than straight to a backend. Empty keeps the old backend stamping. (Config file key: transfers.redirect_address)", + "Keywords": "proxytransfersredirectaddress", + "FieldName": "ProxyTransfersRedirectAddress", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "ProxyTransfersRedirectAddress", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Placeholder": "play.example.com:42420" + }, + { + "DisplayName": "Enable Unsafe Seamless Splice", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Transfers:swap_horiz:2", + "Description": "Re-enables the old experimental live TCP splice. Leave this off on any server you care about. (Config file key: transfers.enable_unsafe_seamless_splice)", + "Keywords": "proxytransfersenableunsafesplice", + "FieldName": "ProxyTransfersEnableUnsafeSplice", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyTransfersEnableUnsafeSplice", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enable Admin Socket", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Admin Socket:admin_panel_settings:3", + "Description": "The line-JSON admin socket used by nimctl and by panel integrations. Off disables it entirely. (Config file key: admin.enabled)", + "Keywords": "proxyadminenabled", + "FieldName": "ProxyAdminEnabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyAdminEnabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Admin Bind Address", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Admin Socket:admin_panel_settings:3", + "Description": "Interface the admin socket listens on. Keep 127.0.0.1 unless something off box has to reach it, in which case set the Admin Secret as well. The port comes from the Admin Port setting. (Config file key: admin.bind)", + "Keywords": "proxyadminbindhost", + "FieldName": "ProxyAdminBindHost", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "ProxyAdminBindHost", "IncludeInCommandLine": false, - "Required": true, "DefaultValue": "127.0.0.1", + "EnumValues": {}, + "Placeholder": "127.0.0.1" + }, + { + "DisplayName": "Admin Secret", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Admin Socket:admin_panel_settings:3", + "Description": "When set, an admin client must authenticate with this secret before issuing commands. Required whenever the admin bind is not loopback. (Config file key: admin.secret)", + "Keywords": "proxyadminsecret", + "FieldName": "ProxyAdminSecret", + "InputType": "password", + "IsFlagArgument": false, + "ParamFieldName": "ProxyAdminSecret", + "IncludeInCommandLine": false, + "DefaultValue": "", "EnumValues": {} }, + { + "DisplayName": "Granted Permissions", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Admin Socket:admin_panel_settings:3", + "Description": "Comma separated permissions handed to an admin client after it authenticates. * is full operator access. (Config file key: admin.granted_permissions)", + "Keywords": "proxyadmingrantedpermissions", + "FieldName": "ProxyAdminGrantedPermissions", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "ProxyAdminGrantedPermissions", + "IncludeInCommandLine": false, + "DefaultValue": "*", + "EnumValues": {}, + "Placeholder": "*" + }, + { + "DisplayName": "Registry Mode", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "embedded hosts the registry inside this proxy process, which is the normal single proxy setup. remote points this proxy at a standalone Nimbus registry, which is what you want with more than one proxy. disabled turns the registry off, leaving only the static [servers] table with no transfers, reservations, bans or whitelist. (Config file key: registry.mode)", + "Keywords": "proxyregistrymode", + "FieldName": "ProxyRegistryMode", + "InputType": "enum", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryMode", + "IncludeInCommandLine": false, + "DefaultValue": "embedded", + "EnumValues": { + "Embedded (registry runs inside this proxy)": "embedded", + "Remote (use a standalone registry)": "remote", + "Disabled (static server list only)": "disabled" + } + }, { "DisplayName": "Proxy ID", - "Category": "Nimbus Proxy:share", - "Subcategory": "Embedded Registry:dns:3", - "Description": "Unique identifier for this proxy", - "Keywords": "proxy,id,registry", - "FieldName": "ProxyId", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "Identity this proxy uses with the registry, and the source id stamped on reservations it mints. Give every proxy on the network its own value. (Config file key: registry.proxy_id)", + "Keywords": "proxyregistryproxyid", + "FieldName": "ProxyRegistryProxyId", "InputType": "text", - "ParamFieldName": "ProxyId", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryProxyId", "IncludeInCommandLine": false, - "Required": true, "DefaultValue": "nimbus-proxy", + "EnumValues": {}, + "Placeholder": "nimbus-proxy" + }, + { + "DisplayName": "Reservation TTL (seconds)", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "How long a slot reservation minted for a transfer stays valid before the target backend forgets it. (Config file key: registry.reservation_ttl_seconds)", + "Keywords": "proxyregistryreservationttlseconds", + "FieldName": "ProxyRegistryReservationTtlSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryReservationTtlSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "60", + "EnumValues": {}, + "MinValue": "1" + }, + { + "DisplayName": "Fail On Registry Error", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "On means a registry the proxy cannot talk to stops the affected operation instead of silently continuing without reservations, bans or whitelist checks. (Config file key: registry.fail_on_error)", + "Keywords": "proxyregistryfailonerror", + "FieldName": "ProxyRegistryFailOnError", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryFailOnError", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Transfer Intent Poll (ms)", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "How often the proxy asks the registry for queued transfer intents, in milliseconds. Lower reacts faster to /server commands issued on a backend and costs more requests. (Config file key: registry.transfer_intent_poll_ms)", + "Keywords": "proxyregistrytransferintentpollms", + "FieldName": "ProxyRegistryTransferIntentPollMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryTransferIntentPollMs", + "IncludeInCommandLine": false, + "DefaultValue": "1000", + "EnumValues": {}, + "MinValue": "50" + }, + { + "DisplayName": "Remote Registry URL", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "Remote mode only. Base URL of the standalone Nimbus registry, for example http://10.0.0.5:8765. Ignored in embedded mode. (Config file key: registry.url)", + "Keywords": "proxyregistryurl", + "FieldName": "ProxyRegistryUrl", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryUrl", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Placeholder": "http://10.0.0.5:8765" + }, + { + "DisplayName": "Remote Registry Shared Secret", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "Remote mode only. Must be byte for byte the same value as the standalone registry's shared secret and every backend's SharedSecret. (Config file key: registry.shared_secret)", + "Keywords": "proxyregistrysharedsecret", + "FieldName": "ProxyRegistrySharedSecret", + "InputType": "password", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistrySharedSecret", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Remote Registry HTTP Timeout (seconds)", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "Remote mode only. How long a single registry request may take before it is treated as a failure. (Config file key: registry.http_timeout_seconds)", + "Keywords": "proxyregistryhttptimeoutseconds", + "FieldName": "ProxyRegistryHttpTimeoutSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryHttpTimeoutSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "5", + "EnumValues": {}, + "MinValue": "1" + }, + { + "DisplayName": "Embedded Registry Bind Address", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "Embedded mode only. Interface the embedded registry serves HTTP on so backends can heartbeat to it. 127.0.0.1 only works when every backend runs on this same machine; use 0.0.0.0 for backends elsewhere and set a real Embedded Shared Secret in the same pass. The port comes from the Registry Port setting. (Config file key: registry.embedded_bind)", + "Keywords": "proxyregistryembeddedbindhost", + "FieldName": "ProxyRegistryEmbeddedBindHost", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryEmbeddedBindHost", + "IncludeInCommandLine": false, + "DefaultValue": "127.0.0.1", + "EnumValues": {}, + "Placeholder": "127.0.0.1" + }, + { + "DisplayName": "Serve Embedded Registry Over HTTP", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "Embedded mode only. Off writes an empty embedded_bind, which keeps the in process registry but stops listening on HTTP. Only useful when this proxy has no external backends at all.", + "Keywords": "proxyregistryembeddedhttpenabled", + "FieldName": "ProxyRegistryEmbeddedHttpEnabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryEmbeddedHttpEnabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Embedded Registry Shared Secret", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "Embedded mode only. The HMAC secret every backend signs its heartbeats with. Leave this empty and Nimbus generates one on first start, then read it out of nimbus.proxy.toml and paste it into each backend's Nimbus Shared Secret. If you set it here, use a long random value and never the string change-me-and-keep-secret. (Config file key: registry.embedded_shared_secret)", + "Keywords": "proxyregistryembeddedsharedsecret", + "FieldName": "ProxyRegistryEmbeddedSharedSecret", + "InputType": "password", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryEmbeddedSharedSecret", + "IncludeInCommandLine": false, + "DefaultValue": "", "EnumValues": {} }, { - "DisplayName": "Redirect Address", - "Category": "Nimbus Proxy:share", - "Subcategory": "Transfers:swap_horiz:4", - "Description": "Public proxy host or host:port stamped into redirect packets. Leave empty for the legacy behavior", - "Keywords": "redirect,address,transfer", - "FieldName": "RedirectAddress", + "DisplayName": "Backend Stale After (seconds)", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "Seconds without a heartbeat before a backend is reported as stale. (Config file key: registry.backend_stale_seconds)", + "Keywords": "proxyregistrybackendstaleseconds", + "FieldName": "ProxyRegistryBackendStaleSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryBackendStaleSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "20", + "EnumValues": {}, + "MinValue": "1" + }, + { + "DisplayName": "Backend Dropped After (seconds)", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "Seconds without a heartbeat before a backend is removed from the registry entirely. (Config file key: registry.backend_drop_seconds)", + "Keywords": "proxyregistrybackenddropseconds", + "FieldName": "ProxyRegistryBackendDropSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryBackendDropSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "120", + "EnumValues": {}, + "MinValue": "1" + }, + { + "DisplayName": "Nonce Window (seconds)", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "Replay protection window. Signed requests older than this are refused, so backend clocks must agree with the registry within roughly this margin. (Config file key: registry.nonce_window_seconds)", + "Keywords": "proxyregistrynoncewindowseconds", + "FieldName": "ProxyRegistryNonceWindowSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryNonceWindowSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "90", + "EnumValues": {}, + "MinValue": "5" + }, + { + "DisplayName": "Maximum Reservation TTL (seconds)", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "Reservations asking for a longer TTL than this are refused. 0 removes the ceiling. (Config file key: registry.max_reservation_ttl_seconds)", + "Keywords": "proxyregistrymaxreservationttlseconds", + "FieldName": "ProxyRegistryMaxReservationTtlSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryMaxReservationTtlSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "300", + "EnumValues": {}, + "MinValue": "0" + }, + { + "DisplayName": "Advertise On Master Server", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "Publishes the network as a single entry on the public Vintage Story server list. Each backend should have its own master server advertising turned off when this is on, otherwise players see the backends as separate servers. (Config file key: registry.advertise_on_master_server)", + "Keywords": "proxyregistryadvertiseonmasterserver", + "FieldName": "ProxyRegistryAdvertiseOnMasterServer", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryAdvertiseOnMasterServer", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Embedded Registry State Directory", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "Where the embedded registry keeps nimbus.bans.json, nimbus.whitelist.json and nimbus.tokens.json. A relative path resolves next to the proxy binary, which is the default. (Config file key: registry.embedded_state_dir)", + "Keywords": "proxyregistryembeddedstatedir", + "FieldName": "ProxyRegistryEmbeddedStateDir", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryEmbeddedStateDir", + "IncludeInCommandLine": false, + "DefaultValue": ".", + "EnumValues": {}, + "Placeholder": "." + }, + { + "DisplayName": "Enable API Tokens", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "Embedded mode only. Lets third party integrations authenticate with scoped bearer tokens. Tokens can be minted while this is off; this switch only decides whether the registry answers them. (Config file key: registry.api_tokens_enabled)", + "Keywords": "proxyregistryapitokensenabled", + "FieldName": "ProxyRegistryApiTokensEnabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryApiTokensEnabled", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "API Token Rate Limit (per minute)", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "Requests per minute allowed per token. A value of zero or less is a configuration error and falls back to 60. (Config file key: registry.api_tokens_rate_limit_per_minute)", + "Keywords": "proxyregistryapitokensratelimitperminute", + "FieldName": "ProxyRegistryApiTokensRateLimitPerMinute", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryApiTokensRateLimitPerMinute", + "IncludeInCommandLine": false, + "DefaultValue": "60", + "EnumValues": {}, + "MinValue": "1" + }, + { + "DisplayName": "Trust X-Forwarded-Proto For API Tokens", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Registry:dns:4", + "Description": "Only set this when a TLS terminating reverse proxy is the single route to the registry bind. Anything that can reach the bind directly can forge the header this makes the registry believe. (Config file key: registry.api_tokens_trust_forwarded_proto)", + "Keywords": "proxyregistryapitokenstrustforwardedproto", + "FieldName": "ProxyRegistryApiTokensTrustForwardedProto", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyRegistryApiTokensTrustForwardedProto", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Network Wide Whitelist", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Whitelist:playlist_add_check:5", + "Description": "On closes the entire network: only players covered by a whitelist entry get past the proxy. An empty whitelist with this on means nobody gets in. (Config file key: whitelist.network)", + "Keywords": "proxywhitelistnetwork", + "FieldName": "ProxyWhitelistNetwork", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyWhitelistNetwork", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Whitelisted Backends", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Whitelist:playlist_add_check:5", + "Description": "Comma separated backend ids that require a whitelist entry even when the network as a whole is open, for example a staff or build server inside a public network. (Config file key: whitelist.servers)", + "Keywords": "proxywhitelistservers", + "FieldName": "ProxyWhitelistServers", "InputType": "text", - "ParamFieldName": "RedirectAddress", + "IsFlagArgument": false, + "ParamFieldName": "ProxyWhitelistServers", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Placeholder": "staff,build" + }, + { + "DisplayName": "Fail Open Until First Sync", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Whitelist:playlist_add_check:5", + "Description": "Cold start behaviour only. Off keeps the door shut until the proxy has read the whitelist at least once. On lets players in meanwhile, which risks a wide open network while the registry is unreachable. (Config file key: whitelist.fail_open_until_first_sync)", + "Keywords": "proxywhitelistfailopenuntilfirstsync", + "FieldName": "ProxyWhitelistFailOpenUntilFirstSync", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyWhitelistFailOpenUntilFirstSync", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Verbose Logging", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Logging:receipt_long:6", + "Description": "Turns on debug level proxy logging. Useful while setting a network up, noisy afterwards. (Config file key: logging.verbose)", + "Keywords": "proxyloggingverbose", + "FieldName": "ProxyLoggingVerbose", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyLoggingVerbose", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Log Protocol Frames", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Logging:receipt_long:6", + "Description": "Logs individual Vintage Story protocol frames. Diagnostics only; this is extremely noisy. (Config file key: logging.sniff_frames)", + "Keywords": "proxyloggingsniffframes", + "FieldName": "ProxyLoggingSniffFrames", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyLoggingSniffFrames", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Log Traffic Byte Counts", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Logging:receipt_long:6", + "Description": "Logs per session byte counters as traffic flows rather than only on disconnect. (Config file key: logging.log_traffic_bytes)", + "Keywords": "proxylogginglogtrafficbytes", + "FieldName": "ProxyLoggingLogTrafficBytes", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyLoggingLogTrafficBytes", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enable Metrics Endpoint", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Metrics and Status:monitoring:7", + "Description": "Serves Prometheus style metrics and, optionally, the JSON status API used by panels. (Config file key: metrics.enabled)", + "Keywords": "proxymetricsenabled", + "FieldName": "ProxyMetricsEnabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyMetricsEnabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Metrics Bind Address", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Metrics and Status:monitoring:7", + "Description": "Interface the metrics HTTP listener uses. Keep it on loopback unless a scraper needs to reach it from elsewhere, and set the Status API Token if you widen it. The port comes from the Metrics Port setting. (Config file key: metrics.bind)", + "Keywords": "proxymetricsbindhost", + "FieldName": "ProxyMetricsBindHost", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "ProxyMetricsBindHost", + "IncludeInCommandLine": false, + "DefaultValue": "127.0.0.1", + "EnumValues": {}, + "Placeholder": "127.0.0.1" + }, + { + "DisplayName": "Metrics Path", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Metrics and Status:monitoring:7", + "Description": "URL path the metrics are served on. (Config file key: metrics.path)", + "Keywords": "proxymetricspath", + "FieldName": "ProxyMetricsPath", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "ProxyMetricsPath", + "IncludeInCommandLine": false, + "DefaultValue": "/metrics", + "EnumValues": {}, + "Placeholder": "/metrics" + }, + { + "DisplayName": "Enable Status API", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Metrics and Status:monitoring:7", + "Description": "Serves a read only JSON snapshot of the network at /status on the metrics listener, which is the easiest way for a dashboard to see which backends are live. (Config file key: metrics.status_api)", + "Keywords": "proxymetricsstatusapi", + "FieldName": "ProxyMetricsStatusApi", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyMetricsStatusApi", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Status API Token", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Metrics and Status:monitoring:7", + "Description": "Optional bearer token for /status. Empty leaves it open, which is acceptable on a loopback bind only. Prefer the Authorization header over the ?token= fallback, because query strings end up in access logs. (Config file key: metrics.status_api_token)", + "Keywords": "proxymetricsstatusapitoken", + "FieldName": "ProxyMetricsStatusApiToken", + "InputType": "password", + "IsFlagArgument": false, + "ParamFieldName": "ProxyMetricsStatusApiToken", "IncludeInCommandLine": false, "DefaultValue": "", - "Placeholder": "play.example.com:42420", "EnumValues": {} }, { - "DisplayName": "Server List Name", - "Category": "Nimbus Proxy:share", - "Subcategory": "Server List:public:5", - "Description": "Name returned by the proxy to server-list queries", - "Keywords": "status,name,server,list", + "DisplayName": "Answer Server Pings", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Server Listing:badge:8", + "Description": "Lets the proxy answer the ping a client sends before joining, so the network shows up in a client's server list entry instead of looking offline. (Config file key: status.enabled)", + "Keywords": "proxystatusenabled", + "FieldName": "ProxyStatusEnabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyStatusEnabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Network Name", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Server Listing:badge:8", + "Description": "Name reported for the whole network in ping replies. (Config file key: status.name)", + "Keywords": "proxystatusname", "FieldName": "ProxyStatusName", "InputType": "text", + "IsFlagArgument": false, "ParamFieldName": "ProxyStatusName", "IncludeInCommandLine": false, "DefaultValue": "Nimbus", - "EnumValues": {} + "EnumValues": {}, + "Placeholder": "Nimbus" }, { - "DisplayName": "Server List Message", - "Category": "Nimbus Proxy:share", - "Subcategory": "Server List:public:5", - "Description": "Message returned by the proxy to server-list queries", - "Keywords": "status,motd,message", + "DisplayName": "Network Description", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Server Listing:badge:8", + "Description": "Description or MOTD reported in ping replies. (Config file key: status.motd)", + "Keywords": "proxystatusmotd", "FieldName": "ProxyStatusMotd", "InputType": "text", + "IsFlagArgument": false, "ParamFieldName": "ProxyStatusMotd", "IncludeInCommandLine": false, - "DefaultValue": "Vintage Story network", + "DefaultValue": "Vintage Story proxy", "EnumValues": {} }, + { + "DisplayName": "Reported Game Mode", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Server Listing:badge:8", + "Description": "Game mode string reported in ping replies, for example survival or creative. (Config file key: status.game_mode)", + "Keywords": "proxystatusgamemode", + "FieldName": "ProxyStatusGameMode", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "ProxyStatusGameMode", + "IncludeInCommandLine": false, + "DefaultValue": "survival", + "EnumValues": {}, + "Placeholder": "survival" + }, + { + "DisplayName": "Report As Password Protected", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Server Listing:badge:8", + "Description": "Tells clients the network expects a password. Set this only if the backends actually have one. (Config file key: status.password)", + "Keywords": "proxystatuspassword", + "FieldName": "ProxyStatusPassword", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyStatusPassword", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Reported Game Version", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Server Listing:badge:8", + "Description": "Version string reported in ping replies. Leave empty to report whatever the backends report, which is what you want when every backend runs the same Stratum build. (Config file key: status.server_version)", + "Keywords": "proxystatusserverversion", + "FieldName": "ProxyStatusServerVersion", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "ProxyStatusServerVersion", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Placeholder": "1.22.6" + }, { "DisplayName": "Network Player Limit", - "Category": "Nimbus Proxy:share", - "Subcategory": "Server List:public:5", - "Description": "Maximum player count shown in proxy status responses", - "Keywords": "players,max,status", - "FieldName": "ProxyMaxPlayers", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Server Listing:badge:8", + "Description": "Player count reported for the network. This is a display value only; the real limits are the per backend player caps. (Config file key: status.max_players)", + "Keywords": "$maxusers", + "FieldName": "$MaxUsers", "InputType": "number", - "ParamFieldName": "ProxyMaxPlayers", + "IsFlagArgument": false, + "ParamFieldName": "max_players", "IncludeInCommandLine": false, "DefaultValue": "100", - "MinValue": "1", - "EnumValues": {} + "EnumValues": {}, + "MinValue": "1" }, { - "DisplayName": "Verbose Logging", - "Category": "Nimbus Proxy:share", - "Subcategory": "Logging:description:6", - "Description": "Enable verbose Nimbus proxy logs for troubleshooting", - "Keywords": "verbose,logging,debug", - "FieldName": "VerboseLogging", + "DisplayName": "Ping Query Timeout (ms)", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Server Listing:badge:8", + "Description": "How long the proxy waits for backends while assembling a ping reply. (Config file key: status.query_timeout_ms)", + "Keywords": "proxystatusquerytimeoutms", + "FieldName": "ProxyStatusQueryTimeoutMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "ProxyStatusQueryTimeoutMs", + "IncludeInCommandLine": false, + "DefaultValue": "1500", + "EnumValues": {}, + "MinValue": "100" + }, + { + "DisplayName": "Enable Plugins", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Plugins:extension:9", + "Description": "Loads Nimbus proxy plugin assemblies from the plugin directory on start. (Config file key: plugins.enabled)", + "Keywords": "proxypluginsenabled", + "FieldName": "ProxyPluginsEnabled", "InputType": "checkbox", - "ParamFieldName": "VerboseLogging", + "IsFlagArgument": false, + "ParamFieldName": "ProxyPluginsEnabled", "IncludeInCommandLine": false, - "DefaultValue": "false", + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Plugin Directory", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Plugins:extension:9", + "Description": "Where plugin .dll files are looked for. A relative path resolves next to the proxy binary. (Config file key: plugins.directory)", + "Keywords": "proxypluginsdirectory", + "FieldName": "ProxyPluginsDirectory", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "ProxyPluginsDirectory", + "IncludeInCommandLine": false, + "DefaultValue": "plugins", + "EnumValues": {}, + "Placeholder": "plugins" + }, + { + "DisplayName": "Disabled Plugins", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Plugins:extension:9", + "Description": "Comma separated plugin ids to skip even though their file is present. (Config file key: plugins.disabled)", + "Keywords": "proxypluginsdisabled", + "FieldName": "ProxyPluginsDisabled", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "ProxyPluginsDisabled", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Placeholder": "someplugin" + }, + { + "DisplayName": "Persist Drain Flags", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Advanced:tune:10", + "Description": "Remembers which backends were drained across a proxy restart, so a backend you took out of rotation does not quietly come back. (Config file key: persistence.persist_drain_flags)", + "Keywords": "proxypersistdrainflags", + "FieldName": "ProxyPersistDrainFlags", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "ProxyPersistDrainFlags", + "IncludeInCommandLine": false, + "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } + }, + { + "DisplayName": "Drain State File", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Advanced:tune:10", + "Description": "File the drain flags are written to. A relative path resolves next to the proxy binary. (Config file key: persistence.drain_flags_file)", + "Keywords": "proxydrainflagsfile", + "FieldName": "ProxyDrainFlagsFile", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "ProxyDrainFlagsFile", + "IncludeInCommandLine": false, + "DefaultValue": "nimbus.drain-state.json", + "EnumValues": {} + }, + { + "DisplayName": "Backend Connect Timeout (ms)", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Advanced:tune:10", + "Description": "How long the proxy waits for a backend TCP connection before treating it as down and trying the next candidate. (Config file key: advanced.connect_timeout_ms)", + "Keywords": "proxyconnecttimeoutms", + "FieldName": "ProxyConnectTimeoutMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "ProxyConnectTimeoutMs", + "IncludeInCommandLine": false, + "DefaultValue": "5000", + "EnumValues": {}, + "MinValue": "100" + }, + { + "DisplayName": "Relay Buffer Size (bytes)", + "Category": "Nimbus Proxy:hub", + "Subcategory": "Advanced:tune:10", + "Description": "Per direction relay buffer. 16384 suits almost everything; raising it costs memory per connected player. (Config file key: advanced.buffer_size)", + "Keywords": "proxybuffersize", + "FieldName": "ProxyBufferSize", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "ProxyBufferSize", + "IncludeInCommandLine": false, + "DefaultValue": "16384", + "EnumValues": {}, + "MinValue": "1024" } ] diff --git a/nimbus-proxyports.json b/nimbus-proxyports.json index 2c9cdce9b..002f32b16 100644 --- a/nimbus-proxyports.json +++ b/nimbus-proxyports.json @@ -2,28 +2,28 @@ { "Protocol": "Both", "Name": "Proxy Port", - "Description": "Player-facing Vintage Story proxy port", + "Description": "The port players connect to. This is the only Nimbus port that has to be reachable from the internet.", "Port": 42420, - "Ref": "ProxyPort" + "Ref": "ServerPort" }, { "Protocol": "TCP", - "Name": "Registry Port", - "Description": "Embedded registry HTTP port used by backend heartbeats", + "Name": "Embedded Registry Port", + "Description": "HTTP port the embedded registry serves on so backends can heartbeat to it. Only needs to be reachable from your backend machines, never from the internet.", "Port": 8765, "Ref": "RegistryPort" }, { "Protocol": "TCP", - "Name": "Admin Port", - "Description": "Local nimctl administration socket", + "Name": "Admin Socket Port", + "Description": "Line-JSON admin socket used by nimctl and panel integrations. Keep this on loopback unless you set an admin secret.", "Port": 42499, "Ref": "AdminPort" }, { "Protocol": "TCP", "Name": "Metrics Port", - "Description": "Local metrics and status HTTP endpoint", + "Description": "Prometheus metrics and the JSON /status endpoint. Keep this private or set a status API token.", "Port": 42500, "Ref": "MetricsPort" } diff --git a/nimbus-proxystart.json b/nimbus-proxystart.json index ee2ec6470..4e9cb2a72 100644 --- a/nimbus-proxystart.json +++ b/nimbus-proxystart.json @@ -1,19 +1,18 @@ [ { - "UpdateStageName": "Write Nimbus proxy configuration", - "UpdateSourcePlatform": "Windows", + "UpdateStageName": "Render nimbus.proxy.toml", + "UpdateSourcePlatform": "Linux", "UpdateSource": "Executable", - "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -Command \"$ErrorActionPreference='Stop'; $path='{{$FullBaseDir}}app/nimbus.proxy.toml'; $secret=''; if (Test-Path $path) { $text=Get-Content $path -Raw; $m=[regex]::Match($text,'(?m)^embedded_shared_secret\\s*=\\s*''([^'']+)'''); if (-not $m.Success) { $m=[regex]::Match($text,'(?m)^embedded_shared_secret\\s*=\\s*\\x22([^\\x22]+)\\x22') }; if ($m.Success) { $secret=$m.Groups[1].Value } }; if ([string]::IsNullOrWhiteSpace($secret) -or $secret -in @('change-me-and-keep-secret','REPLACE_ME_WITH_A_LONG_RANDOM_STRING','REPLACE-ME-THE-INSTALL-REFUSES-THIS-VALUE')) { $bytes=New-Object byte[] 32; [System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($bytes); $secret=($bytes | ForEach-Object { $_.ToString('x2') }) -join '' }; $serverLines=New-Object System.Collections.Generic.List[string]; $serverIds=New-Object System.Collections.Generic.HashSet[string]([System.StringComparer]::OrdinalIgnoreCase); foreach ($entry in '{{BackendServers}}'.Split(';',[System.StringSplitOptions]::RemoveEmptyEntries)) { $pair=$entry.Trim().Split('=',2); if ($pair.Count -ne 2 -or $pair[0].Trim() -notmatch '^[A-Za-z0-9_-]+$' -or $pair[1].Trim() -notmatch '^[^\\s:]+:[0-9]{1,5}$') { throw 'Backend Servers must use serverId=host:port entries separated by semicolons' }; $port=[int]($pair[1].Trim().Split(':')[-1]); if ($port -lt 1 -or $port -gt 65535) { throw 'A backend port is outside 1-65535' }; $id=$pair[0].Trim(); if (-not $serverIds.Add($id)) { throw ('Duplicate backend server ID: ' + $id) }; $serverLines.Add($id + ' = ''' + $pair[1].Trim() + '''') }; if ($serverLines.Count -eq 0) { throw 'At least one backend server is required' }; $tryIds=@('{{TryServers}}'.Split(',',[System.StringSplitOptions]::RemoveEmptyEntries) | ForEach-Object { $_.Trim() }); foreach ($id in $tryIds) { if (-not $serverIds.Contains($id)) { throw ('Initial Server Order contains an unknown backend ID: ' + $id) } }; $tryValue=($tryIds | ForEach-Object { '''' + $_ + '''' }) -join ', '; $lines=New-Object System.Collections.Generic.List[string]; $lines.Add('bind = ''{{ProxyBindAddress}}:{{$ProxyPort}}'''); $lines.Add('try = [ ' + $tryValue + ' ]'); $lines.Add(''); $lines.Add('[servers]'); $lines.AddRange($serverLines); $lines.Add(''); $lines.Add('[transfers]'); $lines.Add('default_mode = ''redirect'''); $lines.Add('allow_seamless = false'); $lines.Add('require_seamless_capability = true'); $lines.Add('fallback_to_redirect_when_seamless_unavailable = true'); $lines.Add('redirect_address = ''{{RedirectAddress}}'''); $lines.Add('enable_unsafe_seamless_splice = false'); $lines.Add(''); $lines.Add('[admin]'); $lines.Add('bind = ''127.0.0.1:{{$AdminPort}}'''); $lines.Add('secret = '''''); $lines.Add('enabled = true'); $lines.Add('granted_permissions = [ ''*'' ]'); $lines.Add(''); $lines.Add('[registry]'); $lines.Add('mode = ''embedded'''); $lines.Add('proxy_id = ''{{ProxyId}}'''); $lines.Add('embedded_bind = ''http://{{RegistryBindAddress}}:{{$RegistryPort}}'''); $lines.Add('embedded_shared_secret = ''' + $secret + ''''); $lines.Add('embedded_state_dir = ''.'''); $lines.Add(''); $lines.Add('[logging]'); $lines.Add('verbose = {{VerboseLogging}}'); $lines.Add('sniff_frames = false'); $lines.Add('log_traffic_bytes = false'); $lines.Add(''); $lines.Add('[metrics]'); $lines.Add('enabled = true'); $lines.Add('bind = ''http://127.0.0.1:{{$MetricsPort}}'''); $lines.Add('path = ''/metrics'''); $lines.Add('status_api = true'); $lines.Add('status_api_token = '''''); $lines.Add(''); $lines.Add('[status]'); $lines.Add('enabled = true'); $lines.Add('name = ''{{ProxyStatusName}}'''); $lines.Add('motd = ''{{ProxyStatusMotd}}'''); $lines.Add('game_mode = ''survival'''); $lines.Add('password = false'); $lines.Add('server_version = ''{{ServerVersion}}'''); $lines.Add('max_players = {{ProxyMaxPlayers}}'); New-Item -ItemType Directory -Path (Split-Path $path) -Force | Out-Null; [IO.File]::WriteAllLines($path,$lines,[Text.UTF8Encoding]::new($false)); Write-Output 'Nimbus proxy configuration written'\"", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"NP_WRITE='{{ProxyWriteConfig}}' NP_BIND='{{ProxyBindHost}}:{{$ServerPort}}' NP_SERVERS='{{ProxyServers}}' NP_TRY='{{ProxyTryList}}' NP_PPSERVERS='{{ProxyProtocolServers}}' NP_FORCEDHOSTS='{{ProxyForcedHosts}}' NP_T_MODE='{{ProxyTransfersDefaultMode}}' NP_T_ALLOWSEAMLESS='{{ProxyTransfersAllowSeamless}}' NP_T_REQCAP='{{ProxyTransfersRequireSeamlessCapability}}' NP_T_FALLBACK='{{ProxyTransfersFallbackToRedirect}}' NP_T_REDIRECTADDR='{{ProxyTransfersRedirectAddress}}' NP_T_SPLICE='{{ProxyTransfersEnableUnsafeSplice}}' NP_A_ENABLED='{{ProxyAdminEnabled}}' NP_A_BIND='{{ProxyAdminBindHost}}:{{$AdminPort}}' NP_A_SECRET='{{ProxyAdminSecret}}' NP_A_PERMS='{{ProxyAdminGrantedPermissions}}' NP_R_MODE='{{ProxyRegistryMode}}' NP_R_PROXYID='{{ProxyRegistryProxyId}}' NP_R_RESTTL='{{ProxyRegistryReservationTtlSeconds}}' NP_R_FAILONERROR='{{ProxyRegistryFailOnError}}' NP_R_INTENTPOLL='{{ProxyRegistryTransferIntentPollMs}}' NP_R_URL='{{ProxyRegistryUrl}}' NP_R_SECRET='{{ProxyRegistrySharedSecret}}' NP_R_HTTPTIMEOUT='{{ProxyRegistryHttpTimeoutSeconds}}' NP_R_EMBBIND='http://{{ProxyRegistryEmbeddedBindHost}}:{{$RegistryPort}}' NP_R_EMBHTTP='{{ProxyRegistryEmbeddedHttpEnabled}}' NP_R_EMBSECRET='{{ProxyRegistryEmbeddedSharedSecret}}' NP_R_STALE='{{ProxyRegistryBackendStaleSeconds}}' NP_R_DROP='{{ProxyRegistryBackendDropSeconds}}' NP_R_NONCE='{{ProxyRegistryNonceWindowSeconds}}' NP_R_MAXRESTTL='{{ProxyRegistryMaxReservationTtlSeconds}}' NP_R_ADVERTISE='{{ProxyRegistryAdvertiseOnMasterServer}}' NP_R_STATEDIR='{{ProxyRegistryEmbeddedStateDir}}' NP_R_APITOK='{{ProxyRegistryApiTokensEnabled}}' NP_R_APIRATE='{{ProxyRegistryApiTokensRateLimitPerMinute}}' NP_R_APIFWD='{{ProxyRegistryApiTokensTrustForwardedProto}}' NP_W_NETWORK='{{ProxyWhitelistNetwork}}' NP_W_SERVERS='{{ProxyWhitelistServers}}' NP_W_FAILOPEN='{{ProxyWhitelistFailOpenUntilFirstSync}}' NP_L_VERBOSE='{{ProxyLoggingVerbose}}' NP_L_SNIFF='{{ProxyLoggingSniffFrames}}' NP_L_TRAFFIC='{{ProxyLoggingLogTrafficBytes}}' NP_M_ENABLED='{{ProxyMetricsEnabled}}' NP_M_BIND='http://{{ProxyMetricsBindHost}}:{{$MetricsPort}}' NP_M_PATH='{{ProxyMetricsPath}}' NP_M_STATUSAPI='{{ProxyMetricsStatusApi}}' NP_M_STATUSTOKEN='{{ProxyMetricsStatusApiToken}}' NP_S_ENABLED='{{ProxyStatusEnabled}}' NP_S_NAME='{{ProxyStatusName}}' NP_S_MOTD='{{ProxyStatusMotd}}' NP_S_GAMEMODE='{{ProxyStatusGameMode}}' NP_S_PASSWORD='{{ProxyStatusPassword}}' NP_S_VERSION='{{ProxyStatusServerVersion}}' NP_S_MAXPLAYERS='{{$MaxUsers}}' NP_S_QUERYTIMEOUT='{{ProxyStatusQueryTimeoutMs}}' NP_P_ENABLED='{{ProxyPluginsEnabled}}' NP_P_DIR='{{ProxyPluginsDirectory}}' NP_P_DISABLED='{{ProxyPluginsDisabled}}' NP_PE_DRAIN='{{ProxyPersistDrainFlags}}' NP_PE_DRAINFILE='{{ProxyDrainFlagsFile}}' NP_AD_CONNTIMEOUT='{{ProxyConnectTimeoutMs}}' NP_AD_BUFSIZE='{{ProxyBufferSize}}' bash '{{$FullRootDir}}scripts/write-proxy-toml.sh' '{{$FullRootDir}}Nimbus/nimbus.proxy.toml'\"", "SkipOnFailure": false }, { - "UpdateStageName": "Write Nimbus proxy configuration", - "UpdateSourcePlatform": "Linux", - "UpdateSourceArch": "x86_64", + "UpdateStageName": "Render nimbus.proxy.toml", + "UpdateSourcePlatform": "Windows", "UpdateSource": "Executable", - "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"set -euo pipefail; path='{{$FullBaseDir}}app/nimbus.proxy.toml'; secret=''; if [[ -f \\\"$path\\\" ]]; then secret=$(awk -F'\\\"' '/^embedded_shared_secret[[:space:]]*=/{print $2; exit}' \\\"$path\\\"); fi; case \\\"$secret\\\" in ''|'change-me-and-keep-secret'|'REPLACE_ME_WITH_A_LONG_RANDOM_STRING'|'REPLACE-ME-THE-INSTALL-REFUSES-THIS-VALUE') secret=$(od -An -N32 -tx1 /dev/urandom | tr -d ' \\n');; esac; backends='{{BackendServers}}'; try_servers='{{TryServers}}'; tmp=\\\"$path.tmp\\\"; mkdir -p \\\"$(dirname \\\"$path\\\")\\\"; declare -A ids=(); server_lines=''; IFS=';' read -ra entries <<< \\\"$backends\\\"; for entry in \\\"${entries[@]}\\\"; do entry=$(echo \\\"$entry\\\" | xargs); [[ \\\"$entry\\\" =~ ^([A-Za-z0-9_-]+)=([^[:space:]:]+):([0-9]{1,5})$ ]] || { echo 'Backend Servers must use serverId=host:port entries separated by semicolons'; exit 1; }; id=\\\"${BASH_REMATCH[1]}\\\"; host=\\\"${BASH_REMATCH[2]}\\\"; port=\\\"${BASH_REMATCH[3]}\\\"; (( port >= 1 && port <= 65535 )) || { echo 'A backend port is outside 1-65535'; exit 1; }; [[ -z \\\"${ids[$id]+x}\\\" ]] || { echo \\\"Duplicate backend server ID: $id\\\"; exit 1; }; ids[$id]=1; server_lines+=\\\"$id = \\\\\\\"$host:$port\\\\\\\"\\n\\\"; done; (( ${#ids[@]} > 0 )) || { echo 'At least one backend server is required'; exit 1; }; try_value=''; IFS=',' read -ra tries <<< \\\"$try_servers\\\"; for id in \\\"${tries[@]}\\\"; do id=$(echo \\\"$id\\\" | xargs); [[ -n \\\"${ids[$id]+x}\\\" ]] || { echo \\\"Initial Server Order contains an unknown backend ID: $id\\\"; exit 1; }; [[ -z \\\"$try_value\\\" ]] || try_value+=', '; try_value+=\\\"\\\\\\\"$id\\\\\\\"\\\"; done; printf 'bind = \\\"{{ProxyBindAddress}}:{{$ProxyPort}}\\\"\\ntry = [ %s ]\\n\\n[servers]\\n%b\\n[transfers]\\ndefault_mode = \\\"redirect\\\"\\nallow_seamless = false\\nrequire_seamless_capability = true\\nfallback_to_redirect_when_seamless_unavailable = true\\nredirect_address = \\\"{{RedirectAddress}}\\\"\\nenable_unsafe_seamless_splice = false\\n\\n[admin]\\nbind = \\\"127.0.0.1:{{$AdminPort}}\\\"\\nsecret = \\\"\\\"\\nenabled = true\\ngranted_permissions = [ \\\"*\\\" ]\\n\\n[registry]\\nmode = \\\"embedded\\\"\\nproxy_id = \\\"{{ProxyId}}\\\"\\nembedded_bind = \\\"http://{{RegistryBindAddress}}:{{$RegistryPort}}\\\"\\nembedded_shared_secret = \\\"%s\\\"\\nembedded_state_dir = \\\".\\\"\\n\\n[logging]\\nverbose = {{VerboseLogging}}\\nsniff_frames = false\\nlog_traffic_bytes = false\\n\\n[metrics]\\nenabled = true\\nbind = \\\"http://127.0.0.1:{{$MetricsPort}}\\\"\\npath = \\\"/metrics\\\"\\nstatus_api = true\\nstatus_api_token = \\\"\\\"\\n\\n[status]\\nenabled = true\\nname = \\\"{{ProxyStatusName}}\\\"\\nmotd = \\\"{{ProxyStatusMotd}}\\\"\\ngame_mode = \\\"survival\\\"\\npassword = false\\nserver_version = \\\"{{ServerVersion}}\\\"\\nmax_players = {{ProxyMaxPlayers}}\\n' \\\"$try_value\\\" \\\"$server_lines\\\" \\\"$secret\\\" > \\\"$tmp\\\"; mv \\\"$tmp\\\" \\\"$path\\\"; echo 'Nimbus proxy configuration written'\"", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$env:NP_WRITE='{{ProxyWriteConfig}}'; $env:NP_BIND='{{ProxyBindHost}}:{{$ServerPort}}'; $env:NP_SERVERS='{{ProxyServers}}'; $env:NP_TRY='{{ProxyTryList}}'; $env:NP_PPSERVERS='{{ProxyProtocolServers}}'; $env:NP_FORCEDHOSTS='{{ProxyForcedHosts}}'; $env:NP_T_MODE='{{ProxyTransfersDefaultMode}}'; $env:NP_T_ALLOWSEAMLESS='{{ProxyTransfersAllowSeamless}}'; $env:NP_T_REQCAP='{{ProxyTransfersRequireSeamlessCapability}}'; $env:NP_T_FALLBACK='{{ProxyTransfersFallbackToRedirect}}'; $env:NP_T_REDIRECTADDR='{{ProxyTransfersRedirectAddress}}'; $env:NP_T_SPLICE='{{ProxyTransfersEnableUnsafeSplice}}'; $env:NP_A_ENABLED='{{ProxyAdminEnabled}}'; $env:NP_A_BIND='{{ProxyAdminBindHost}}:{{$AdminPort}}'; $env:NP_A_SECRET='{{ProxyAdminSecret}}'; $env:NP_A_PERMS='{{ProxyAdminGrantedPermissions}}'; $env:NP_R_MODE='{{ProxyRegistryMode}}'; $env:NP_R_PROXYID='{{ProxyRegistryProxyId}}'; $env:NP_R_RESTTL='{{ProxyRegistryReservationTtlSeconds}}'; $env:NP_R_FAILONERROR='{{ProxyRegistryFailOnError}}'; $env:NP_R_INTENTPOLL='{{ProxyRegistryTransferIntentPollMs}}'; $env:NP_R_URL='{{ProxyRegistryUrl}}'; $env:NP_R_SECRET='{{ProxyRegistrySharedSecret}}'; $env:NP_R_HTTPTIMEOUT='{{ProxyRegistryHttpTimeoutSeconds}}'; $env:NP_R_EMBBIND='http://{{ProxyRegistryEmbeddedBindHost}}:{{$RegistryPort}}'; $env:NP_R_EMBHTTP='{{ProxyRegistryEmbeddedHttpEnabled}}'; $env:NP_R_EMBSECRET='{{ProxyRegistryEmbeddedSharedSecret}}'; $env:NP_R_STALE='{{ProxyRegistryBackendStaleSeconds}}'; $env:NP_R_DROP='{{ProxyRegistryBackendDropSeconds}}'; $env:NP_R_NONCE='{{ProxyRegistryNonceWindowSeconds}}'; $env:NP_R_MAXRESTTL='{{ProxyRegistryMaxReservationTtlSeconds}}'; $env:NP_R_ADVERTISE='{{ProxyRegistryAdvertiseOnMasterServer}}'; $env:NP_R_STATEDIR='{{ProxyRegistryEmbeddedStateDir}}'; $env:NP_R_APITOK='{{ProxyRegistryApiTokensEnabled}}'; $env:NP_R_APIRATE='{{ProxyRegistryApiTokensRateLimitPerMinute}}'; $env:NP_R_APIFWD='{{ProxyRegistryApiTokensTrustForwardedProto}}'; $env:NP_W_NETWORK='{{ProxyWhitelistNetwork}}'; $env:NP_W_SERVERS='{{ProxyWhitelistServers}}'; $env:NP_W_FAILOPEN='{{ProxyWhitelistFailOpenUntilFirstSync}}'; $env:NP_L_VERBOSE='{{ProxyLoggingVerbose}}'; $env:NP_L_SNIFF='{{ProxyLoggingSniffFrames}}'; $env:NP_L_TRAFFIC='{{ProxyLoggingLogTrafficBytes}}'; $env:NP_M_ENABLED='{{ProxyMetricsEnabled}}'; $env:NP_M_BIND='http://{{ProxyMetricsBindHost}}:{{$MetricsPort}}'; $env:NP_M_PATH='{{ProxyMetricsPath}}'; $env:NP_M_STATUSAPI='{{ProxyMetricsStatusApi}}'; $env:NP_M_STATUSTOKEN='{{ProxyMetricsStatusApiToken}}'; $env:NP_S_ENABLED='{{ProxyStatusEnabled}}'; $env:NP_S_NAME='{{ProxyStatusName}}'; $env:NP_S_MOTD='{{ProxyStatusMotd}}'; $env:NP_S_GAMEMODE='{{ProxyStatusGameMode}}'; $env:NP_S_PASSWORD='{{ProxyStatusPassword}}'; $env:NP_S_VERSION='{{ProxyStatusServerVersion}}'; $env:NP_S_MAXPLAYERS='{{$MaxUsers}}'; $env:NP_S_QUERYTIMEOUT='{{ProxyStatusQueryTimeoutMs}}'; $env:NP_P_ENABLED='{{ProxyPluginsEnabled}}'; $env:NP_P_DIR='{{ProxyPluginsDirectory}}'; $env:NP_P_DISABLED='{{ProxyPluginsDisabled}}'; $env:NP_PE_DRAIN='{{ProxyPersistDrainFlags}}'; $env:NP_PE_DRAINFILE='{{ProxyDrainFlagsFile}}'; $env:NP_AD_CONNTIMEOUT='{{ProxyConnectTimeoutMs}}'; $env:NP_AD_BUFSIZE='{{ProxyBufferSize}}';& '{{$FullRootDir}}scripts\\write-proxy-toml.ps1' '{{$FullRootDir}}Nimbus\\nimbus.proxy.toml'\"", "SkipOnFailure": false } ] diff --git a/nimbus-proxyupdates.json b/nimbus-proxyupdates.json index 3c42f3f0d..4f59bc887 100644 --- a/nimbus-proxyupdates.json +++ b/nimbus-proxyupdates.json @@ -1,68 +1,116 @@ [ { - "UpdateStageName": "Application Directory Creation", + "UpdateStageName": "Create Nimbus directory", "UpdateSourcePlatform": "All", "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullBaseDir}}app", + "UpdateSourceArgs": "{{$FullRootDir}}Nimbus", "SkipOnFailure": false }, { - "UpdateStageName": "Dotnet Directory Creation", + "UpdateStageName": "Create plugins directory", "UpdateSourcePlatform": "All", "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullBaseDir}}dotnet", + "UpdateSourceArgs": "{{$FullRootDir}}Nimbus/plugins", "SkipOnFailure": false }, { - "UpdateStageName": ".NET SDK Download", + "UpdateStageName": "Create dotnet directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}dotnet", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create scripts directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}scripts", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Write Nimbus installer script (Linux)", "UpdateSourcePlatform": "Linux", - "UpdateSourceArch": "x86_64", - "UpdateSource": "Executable", - "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"DotnetVersion=\\\"{{DotnetSDKVersion}}\\\"; cd \\\"{{$FullBaseDir}}\\\" && if [[ -x dotnet/dotnet ]]; then InstalledVersion=$(dotnet/dotnet --version | xargs); else InstalledVersion=\\\"\\\"; fi; if [[ -z \\\"$DotnetVersion\\\" ]]; then DotnetVersion=$(wget -qO- https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json | jq -r \\\".[\\\\\\\"latest-sdk\\\\\\\"]\\\"); fi; if [[ ! \\\"$DotnetVersion\\\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+$ ]]; then echo \\\"Invalid .NET SDK version format specified\\\" && exit 1; elif [[ \\\"$InstalledVersion\\\" == \\\"$DotnetVersion\\\" ]]; then echo \\\".NET SDK v$DotnetVersion already installed. Skipping\\\" && exit 0; else rm -f dotnet.tar.gz; wget -qO dotnet.tar.gz https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-linux-x64.tar.gz || { echo \\\".NET SDK download failed\\\"; exit 1; }; rm -rf dotnet/* && tar -xzf dotnet.tar.gz -C dotnet && rm -f dotnet.tar.gz && echo \\\".NET SDK v$DotnetVersion downloaded\\\"; fi\"", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/install-nimbus.sh", + "UpdateSourceData": "#!/usr/bin/env bash\n# Generated by the AMP Nimbus instance template.\n# Resolves a Nimbus release and installs the requested components out of it.\n# The release zip lays out release_full/Nimbus (proxy), release_full/Nimbus.Registry\n# (standalone registry) and release_full/Nimbus.ServerMod (the Vintage Story mod).\nset -euo pipefail\n\nroot=\"${1:?root directory required}\"\ncomponents=\"${2:?component list required}\"\ncd \"$root\"\n\nrepo=\"StratumServer/Nimbus\"\nhdr=(-H \"User-Agent: AMP-Nimbus-Template\" -H \"Accept: application/vnd.github+json\")\nif [ -n \"${GITHUB_TOKEN:-}\" ]; then hdr+=(-H \"Authorization: Bearer ${GITHUB_TOKEN}\"); fi\n\nfor tool in curl unzip jq; do\n command -v \"$tool\" >/dev/null 2>&1 || { echo \"[AMP] $tool is required but not installed\" >&2; exit 1; }\ndone\n\ntag=\"$(printf '%s' \"${NIMBUS_TAG:-}\" | tr -d '[:space:]')\"\nif [ -z \"$tag\" ]; then\n echo \"[AMP] resolving Nimbus release (channel=${NIMBUS_CHANNEL:-stable})\"\n json=\"$(curl -fsSL \"${hdr[@]}\" \"https://api.github.com/repos/${repo}/releases?per_page=100\")\"\n filter='.[] | select(.draft == false)'\n if [ \"${NIMBUS_CHANNEL:-stable}\" != \"prerelease\" ]; then\n filter=\"${filter} | select(.prerelease == false)\"\n fi\n tag=\"$(printf '%s' \"$json\" | jq -r \"[ ${filter} ] | .[0].tag_name // empty\")\"\nfi\n[ -n \"$tag\" ] || { echo \"[AMP] no Nimbus release matched channel=${NIMBUS_CHANNEL:-stable}\" >&2; exit 1; }\ncase \"$tag\" in v*) ;; *) tag=\"v${tag}\";; esac\n\nmarker=\".amp-nimbus-release\"\nif [ -f \"$marker\" ] && [ \"$(cat \"$marker\")\" = \"$tag\" ]; then\n ok=1\n for comp in $components; do\n [ -d \"$comp\" ] || ok=0\n done\n if [ \"$ok\" = \"1\" ]; then\n echo \"[AMP] already on Nimbus ${tag}; nothing to download\"\n exit 0\n fi\nfi\n\nurl=\"https://github.com/${repo}/releases/download/${tag}/Nimbus-${tag}.zip\"\necho \"[AMP] downloading ${url}\"\nrm -rf .nimbus-extract\nmkdir -p .nimbus-extract\ncurl -fL --retry 3 -o nimbus-release.zip \"$url\"\nunzip -qo nimbus-release.zip -d .nimbus-extract\nrm -f nimbus-release.zip\n\nsrc=\".nimbus-extract/release_full\"\n[ -d \"$src\" ] || src=\".nimbus-extract\"\n\nfor comp in $components; do\n if [ ! -d \"$src/$comp\" ]; then\n echo \"[AMP] component $comp is not present in this release\" >&2\n exit 1\n fi\n mkdir -p \"$comp\"\n # Config, state and plugins live in the component directory, so replace program files\n # only and leave everything the operator or Nimbus itself wrote in place.\n find \"$comp\" -maxdepth 1 -type f \\( -name '*.dll' -o -name '*.pdb' -o -name '*.deps.json' \\\n -o -name '*.runtimeconfig.json' -o -name 'web.config' -o -name '*.staticwebassets.endpoints.json' \\) -delete\n cp -RL \"$src/$comp/.\" \"$comp/\"\ndone\n\nif [ -f \"Nimbus/Nimbus.Proxy\" ]; then chmod +x \"Nimbus/Nimbus.Proxy\"; fi\nif [ -f \"Nimbus.Registry/Nimbus.Registry\" ]; then chmod +x \"Nimbus.Registry/Nimbus.Registry\"; fi\nif [ -f \"$src/LICENSE\" ]; then cp -f \"$src/LICENSE\" ./LICENSE; fi\n\nrm -rf .nimbus-extract\nprintf '%s' \"$tag\" > \"$marker\"\necho \"[AMP] installed Nimbus ${tag} (${components}) into ${root}\"\n", + "OverwriteExistingFiles": true, "SkipOnFailure": false }, { - "UpdateStageName": ".NET SDK Download", + "UpdateStageName": "Write Nimbus installer script (Windows)", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/install-nimbus.ps1", + "UpdateSourceData": "# Generated by the AMP Nimbus instance template.\nparam(\n [Parameter(Mandatory = $true)][string]$Root,\n [Parameter(Mandatory = $true)][string]$Components\n)\n\n$ErrorActionPreference = 'Stop'\n$ProgressPreference = 'SilentlyContinue'\n[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n\n$repo = 'StratumServer/Nimbus'\n$comps = @($Components -split '[,\\s]+' | Where-Object { $_ -ne '' })\n$headers = @{ 'User-Agent' = 'AMP-Nimbus-Template'; 'Accept' = 'application/vnd.github+json' }\nif ($env:GITHUB_TOKEN) { $headers['Authorization'] = \"Bearer $($env:GITHUB_TOKEN)\" }\n\n$tag = if ($env:NIMBUS_TAG) { $env:NIMBUS_TAG.Trim() } else { '' }\nif ($tag -eq '') {\n $channel = if ($env:NIMBUS_CHANNEL) { $env:NIMBUS_CHANNEL } else { 'stable' }\n Write-Host \"[AMP] resolving Nimbus release (channel=$channel)\"\n $releases = Invoke-RestMethod -Headers $headers -Uri \"https://api.github.com/repos/$repo/releases?per_page=100\"\n $candidates = @($releases | Where-Object { -not $_.draft })\n if ($channel -ne 'prerelease') { $candidates = @($candidates | Where-Object { -not $_.prerelease }) }\n if ($candidates.Count -eq 0) { throw \"No Nimbus release matched channel=$channel\" }\n $tag = $candidates[0].tag_name\n}\nif (-not $tag.StartsWith('v')) { $tag = \"v$tag\" }\n\n$marker = Join-Path $Root '.amp-nimbus-release'\nif ((Test-Path $marker) -and ((Get-Content $marker -Raw).Trim() -eq $tag)) {\n $missing = @($comps | Where-Object { -not (Test-Path (Join-Path $Root $_)) })\n if ($missing.Count -eq 0) {\n Write-Host \"[AMP] already on Nimbus $tag; nothing to download\"\n exit 0\n }\n}\n\n$extract = Join-Path $Root '.nimbus-extract'\nif (Test-Path $extract) { Remove-Item $extract -Recurse -Force }\nNew-Item -ItemType Directory -Force -Path $extract | Out-Null\n\n$zip = Join-Path $Root 'nimbus-release.zip'\n$url = \"https://github.com/$repo/releases/download/$tag/Nimbus-$tag.zip\"\nWrite-Host \"[AMP] downloading $url\"\nInvoke-WebRequest -UseBasicParsing -Headers $headers -Uri $url -OutFile $zip\nExpand-Archive -Path $zip -DestinationPath $extract -Force\nRemove-Item $zip -Force\n\n$src = Join-Path $extract 'release_full'\nif (-not (Test-Path $src)) { $src = $extract }\n\n$programPatterns = @('*.dll', '*.pdb', '*.deps.json', '*.runtimeconfig.json', 'web.config', '*.staticwebassets.endpoints.json')\nforeach ($comp in $comps) {\n $from = Join-Path $src $comp\n if (-not (Test-Path $from)) { throw \"Component $comp is not present in this release\" }\n $to = Join-Path $Root $comp\n New-Item -ItemType Directory -Force -Path $to | Out-Null\n # Replace program files only; nimbus.proxy.toml, state files and plugins stay put.\n foreach ($pattern in $programPatterns) {\n Get-ChildItem -LiteralPath $to -Filter $pattern -File -ErrorAction SilentlyContinue | Remove-Item -Force\n }\n Copy-Item -Path (Join-Path $from '*') -Destination $to -Recurse -Force\n}\n\n$license = Join-Path $src 'LICENSE'\nif (Test-Path $license) { Copy-Item -Path $license -Destination (Join-Path $Root 'LICENSE') -Force }\n\nRemove-Item $extract -Recurse -Force\nSet-Content -Path $marker -Value $tag -NoNewline\nWrite-Host \"[AMP] installed Nimbus $tag ($Components) into $Root\"\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Write config renderer script (Linux)", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/write-proxy-toml.sh", + "UpdateSourceData": "#!/usr/bin/env bash\n# Renders nimbus.proxy.toml from environment variables set by AMP.\n# Generated by the AMP Nimbus instance template; edits here are overwritten on the next update.\nset -uf\n\nOUT=\"${1:-}\"\nif [ -z \"$OUT\" ]; then echo \"usage: $0 \" >&2; exit 1; fi\nif [ \"$(printf '%s' \"${NP_WRITE:-true}\" | tr 'A-Z' 'a-z')\" != \"true\" ]; then\n echo \"AMP management of $(basename \"$OUT\") is disabled, leaving the existing file alone\"\n exit 0\nfi\n\nTMP=\"$OUT.amptmp\"\nmkdir -p \"$(dirname \"$OUT\")\"\n: > \"$TMP\"\n\nesc() { printf '%s' \"${1-}\" | sed -e 's/\\\\/\\\\\\\\/g' -e 's/\"/\\\\\"/g'; }\nbl() { case \"$(printf '%s' \"${1-}\" | tr 'A-Z' 'a-z')\" in true|1|yes|on) printf 'true';; *) printf 'false';; esac }\nnum() { case \"${1-}\" in ''|*[!0-9-]*) printf '%s' \"${2-0}\";; *) printf '%s' \"$1\";; esac }\ntrim() { printf '%s' \"${1-}\" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'; }\nlst() {\n local out=\"\" first=1 x\n local IFS=','\n for x in ${1-}; do\n x=\"$(trim \"$x\")\"\n [ -z \"$x\" ] && continue\n if [ $first -eq 1 ]; then first=0; else out=\"$out, \"; fi\n out=\"$out\\\"$(esc \"$x\")\\\"\"\n done\n printf '[%s]' \"$out\"\n}\nsrv() {\n local x k v\n local IFS=','\n for x in ${1-}; do\n x=\"$(trim \"$x\")\"\n [ -z \"$x\" ] && continue\n case \"$x\" in *=*) ;; *) echo \"skipping malformed servers entry '$x' (expected id=host:port)\" >&2; continue;; esac\n k=\"$(trim \"${x%%=*}\")\"; v=\"$(trim \"${x#*=}\")\"\n if [ -z \"$k\" ] || [ -z \"$v\" ]; then\n echo \"skipping malformed servers entry '$x' (expected id=host:port)\" >&2\n continue\n fi\n printf '\"%s\" = \"%s\"\\n' \"$(esc \"$k\")\" \"$(esc \"$v\")\" >> \"$TMP\"\n done\n}\nfh() {\n local x k v\n local IFS=','\n for x in ${1-}; do\n x=\"$(trim \"$x\")\"\n [ -z \"$x\" ] && continue\n case \"$x\" in *=*) ;; *) echo \"skipping malformed forced_hosts entry '$x' (expected hostname=id1|id2)\" >&2; continue;; esac\n k=\"$(trim \"${x%%=*}\")\"; v=\"$(trim \"${x#*=}\")\"\n [ -z \"$k\" ] && continue\n printf '\"%s\" = %s\\n' \"$(esc \"$k\")\" \"$(lst \"$(printf '%s' \"$v\" | tr '|' ',')\")\" >> \"$TMP\"\n done\n}\nmods() {\n local out=\"\" first=1 x k v\n local IFS=','\n for x in ${1-}; do\n x=\"$(trim \"$x\")\"\n [ -z \"$x\" ] && continue\n case \"$x\" in\n *=*) k=\"$(trim \"${x%%=*}\")\"; v=\"$(trim \"${x#*=}\")\";;\n *) k=\"$x\"; v=\"\";;\n esac\n if [ $first -eq 1 ]; then first=0; else out=\"$out, \"; fi\n out=\"$out{ id = \\\"$(esc \"$k\")\\\", version = \\\"$(esc \"$v\")\\\" }\"\n done\n printf '[%s]' \"$out\"\n}\nkeep_secret() {\n local key=\"$1\" val=\"${2:-}\" f=\"$3\" cur=\"\"\n if [ -n \"$val\" ]; then printf '%s' \"$val\"; return; fi\n if [ -f \"$f\" ]; then\n cur=\"$(sed -n \"s/^[[:space:]]*${key}[[:space:]]*=[[:space:]]*\\\"\\(.*\\)\\\".*/\\1/p\" \"$f\" | head -n 1)\"\n case \"$cur\" in\n \"\"|change-me-and-keep-secret) ;;\n *) printf '%s' \"$cur\"; return;;\n esac\n fi\n echo \"[AMP] no ${key} set, generating a random one; read it out of $(basename \"$f\") and paste it into every backend\" >&2\n head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \\n'\n}\nprintf 'bind = \"%s\"\\n' \"$(esc \"${NP_BIND:-0.0.0.0:42420}\")\" >> \"$TMP\"\nprintf 'try = %s\\n' \"$(lst \"${NP_TRY:-hub}\")\" >> \"$TMP\"\nprintf 'proxy_protocol_servers = %s\\n' \"$(lst \"${NP_PPSERVERS:-}\")\" >> \"$TMP\"\nprintf '\\n[servers]\\n' >> \"$TMP\"\nsrv \"${NP_SERVERS:-hub=127.0.0.1:42421}\"\nprintf '\\n[forced_hosts]\\n' >> \"$TMP\"\nfh \"${NP_FORCEDHOSTS:-}\"\nprintf '\\n[transfers]\\n' >> \"$TMP\"\nprintf 'default_mode = \"%s\"\\n' \"$(esc \"${NP_T_MODE:-redirect}\")\" >> \"$TMP\"\nprintf 'allow_seamless = %s\\n' \"$(bl \"${NP_T_ALLOWSEAMLESS:-false}\")\" >> \"$TMP\"\nprintf 'require_seamless_capability = %s\\n' \"$(bl \"${NP_T_REQCAP:-true}\")\" >> \"$TMP\"\nprintf 'fallback_to_redirect_when_seamless_unavailable = %s\\n' \"$(bl \"${NP_T_FALLBACK:-true}\")\" >> \"$TMP\"\nprintf 'redirect_address = \"%s\"\\n' \"$(esc \"${NP_T_REDIRECTADDR:-}\")\" >> \"$TMP\"\nprintf 'enable_unsafe_seamless_splice = %s\\n' \"$(bl \"${NP_T_SPLICE:-false}\")\" >> \"$TMP\"\nprintf '\\n[admin]\\n' >> \"$TMP\"\nprintf 'enabled = %s\\n' \"$(bl \"${NP_A_ENABLED:-true}\")\" >> \"$TMP\"\nprintf 'bind = \"%s\"\\n' \"$(esc \"${NP_A_BIND:-127.0.0.1}\")\" >> \"$TMP\"\nprintf 'secret = \"%s\"\\n' \"$(esc \"${NP_A_SECRET:-}\")\" >> \"$TMP\"\nprintf 'granted_permissions = %s\\n' \"$(lst \"${NP_A_PERMS:-*}\")\" >> \"$TMP\"\nprintf '\\n[registry]\\n' >> \"$TMP\"\nprintf 'mode = \"%s\"\\n' \"$(esc \"${NP_R_MODE:-embedded}\")\" >> \"$TMP\"\nprintf 'proxy_id = \"%s\"\\n' \"$(esc \"${NP_R_PROXYID:-nimbus-proxy}\")\" >> \"$TMP\"\nprintf 'reservation_ttl_seconds = %s\\n' \"$(num \"${NP_R_RESTTL:-60}\" 60)\" >> \"$TMP\"\nprintf 'fail_on_error = %s\\n' \"$(bl \"${NP_R_FAILONERROR:-true}\")\" >> \"$TMP\"\nprintf 'transfer_intent_poll_ms = %s\\n' \"$(num \"${NP_R_INTENTPOLL:-1000}\" 1000)\" >> \"$TMP\"\nprintf 'url = \"%s\"\\n' \"$(esc \"${NP_R_URL:-}\")\" >> \"$TMP\"\nprintf 'shared_secret = \"%s\"\\n' \"$(esc \"${NP_R_SECRET:-}\")\" >> \"$TMP\"\nprintf 'http_timeout_seconds = %s\\n' \"$(num \"${NP_R_HTTPTIMEOUT:-5}\" 5)\" >> \"$TMP\"\nif [ \"$(bl \"${NP_R_EMBHTTP:-true}\")\" = \"true\" ]; then\n printf 'embedded_bind = \"%s\"\\n' \"$(esc \"${NP_R_EMBBIND:-127.0.0.1}\")\" >> \"$TMP\"\nelse\n printf 'embedded_bind = \"\"\\n' >> \"$TMP\"\nfi\nprintf 'embedded_shared_secret = \"%s\"\\n' \"$(esc \"$(keep_secret embedded_shared_secret \"${NP_R_EMBSECRET:-}\" \"$OUT\")\")\" >> \"$TMP\"\nprintf 'backend_stale_seconds = %s\\n' \"$(num \"${NP_R_STALE:-20}\" 20)\" >> \"$TMP\"\nprintf 'backend_drop_seconds = %s\\n' \"$(num \"${NP_R_DROP:-120}\" 120)\" >> \"$TMP\"\nprintf 'nonce_window_seconds = %s\\n' \"$(num \"${NP_R_NONCE:-90}\" 90)\" >> \"$TMP\"\nprintf 'max_reservation_ttl_seconds = %s\\n' \"$(num \"${NP_R_MAXRESTTL:-300}\" 300)\" >> \"$TMP\"\nprintf 'advertise_on_master_server = %s\\n' \"$(bl \"${NP_R_ADVERTISE:-false}\")\" >> \"$TMP\"\nprintf 'embedded_state_dir = \"%s\"\\n' \"$(esc \"${NP_R_STATEDIR:-.}\")\" >> \"$TMP\"\nprintf 'api_tokens_enabled = %s\\n' \"$(bl \"${NP_R_APITOK:-false}\")\" >> \"$TMP\"\nprintf 'api_tokens_rate_limit_per_minute = %s\\n' \"$(num \"${NP_R_APIRATE:-60}\" 60)\" >> \"$TMP\"\nprintf 'api_tokens_trust_forwarded_proto = %s\\n' \"$(bl \"${NP_R_APIFWD:-false}\")\" >> \"$TMP\"\nprintf '\\n[whitelist]\\n' >> \"$TMP\"\nprintf 'network = %s\\n' \"$(bl \"${NP_W_NETWORK:-false}\")\" >> \"$TMP\"\nprintf 'servers = %s\\n' \"$(lst \"${NP_W_SERVERS:-}\")\" >> \"$TMP\"\nprintf 'fail_open_until_first_sync = %s\\n' \"$(bl \"${NP_W_FAILOPEN:-false}\")\" >> \"$TMP\"\nprintf '\\n[logging]\\n' >> \"$TMP\"\nprintf 'verbose = %s\\n' \"$(bl \"${NP_L_VERBOSE:-false}\")\" >> \"$TMP\"\nprintf 'sniff_frames = %s\\n' \"$(bl \"${NP_L_SNIFF:-false}\")\" >> \"$TMP\"\nprintf 'log_traffic_bytes = %s\\n' \"$(bl \"${NP_L_TRAFFIC:-false}\")\" >> \"$TMP\"\nprintf '\\n[metrics]\\n' >> \"$TMP\"\nprintf 'enabled = %s\\n' \"$(bl \"${NP_M_ENABLED:-true}\")\" >> \"$TMP\"\nprintf 'bind = \"%s\"\\n' \"$(esc \"${NP_M_BIND:-127.0.0.1}\")\" >> \"$TMP\"\nprintf 'path = \"%s\"\\n' \"$(esc \"${NP_M_PATH:-/metrics}\")\" >> \"$TMP\"\nprintf 'status_api = %s\\n' \"$(bl \"${NP_M_STATUSAPI:-true}\")\" >> \"$TMP\"\nprintf 'status_api_token = \"%s\"\\n' \"$(esc \"${NP_M_STATUSTOKEN:-}\")\" >> \"$TMP\"\nprintf '\\n[status]\\n' >> \"$TMP\"\nprintf 'enabled = %s\\n' \"$(bl \"${NP_S_ENABLED:-true}\")\" >> \"$TMP\"\nprintf 'name = \"%s\"\\n' \"$(esc \"${NP_S_NAME:-Nimbus}\")\" >> \"$TMP\"\nprintf 'motd = \"%s\"\\n' \"$(esc \"${NP_S_MOTD:-Vintage Story proxy}\")\" >> \"$TMP\"\nprintf 'game_mode = \"%s\"\\n' \"$(esc \"${NP_S_GAMEMODE:-survival}\")\" >> \"$TMP\"\nprintf 'password = %s\\n' \"$(bl \"${NP_S_PASSWORD:-false}\")\" >> \"$TMP\"\nprintf 'server_version = \"%s\"\\n' \"$(esc \"${NP_S_VERSION:-}\")\" >> \"$TMP\"\nprintf 'max_players = %s\\n' \"$(num \"${NP_S_MAXPLAYERS:-100}\" 100)\" >> \"$TMP\"\nprintf 'query_timeout_ms = %s\\n' \"$(num \"${NP_S_QUERYTIMEOUT:-1500}\" 1500)\" >> \"$TMP\"\nprintf '\\n[plugins]\\n' >> \"$TMP\"\nprintf 'enabled = %s\\n' \"$(bl \"${NP_P_ENABLED:-true}\")\" >> \"$TMP\"\nprintf 'directory = \"%s\"\\n' \"$(esc \"${NP_P_DIR:-plugins}\")\" >> \"$TMP\"\nprintf 'disabled = %s\\n' \"$(lst \"${NP_P_DISABLED:-}\")\" >> \"$TMP\"\nprintf '\\n[persistence]\\n' >> \"$TMP\"\nprintf 'persist_drain_flags = %s\\n' \"$(bl \"${NP_PE_DRAIN:-true}\")\" >> \"$TMP\"\nprintf 'drain_flags_file = \"%s\"\\n' \"$(esc \"${NP_PE_DRAINFILE:-nimbus.drain-state.json}\")\" >> \"$TMP\"\nprintf '\\n[advanced]\\n' >> \"$TMP\"\nprintf 'connect_timeout_ms = %s\\n' \"$(num \"${NP_AD_CONNTIMEOUT:-5000}\" 5000)\" >> \"$TMP\"\nprintf 'buffer_size = %s\\n' \"$(num \"${NP_AD_BUFSIZE:-16384}\" 16384)\" >> \"$TMP\"\nmv -f \"$TMP\" \"$OUT\"\necho \"wrote $OUT\"\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Write config renderer script (Windows)", "UpdateSourcePlatform": "Windows", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/write-proxy-toml.ps1", + "UpdateSourceData": "# Renders nimbus.proxy.toml from environment variables set by AMP.\n# Generated by the AMP Nimbus instance template; edits here are overwritten on the next update.\nparam([Parameter(Mandatory = $true)][string]$Out)\n$ErrorActionPreference = 'Stop'\n\nfunction D([string]$v, [string]$d) { if ([string]::IsNullOrWhiteSpace($v)) { return $d } return $v }\nfunction Esc([string]$s) { if ($null -eq $s) { return '' } return $s.Replace('\\', '\\\\').Replace('\"', '\\\"') }\nfunction B([string]$s) { if ($null -eq $s) { return 'false' } if (@('true', '1', 'yes', 'on') -contains $s.Trim().ToLowerInvariant()) { return 'true' } return 'false' }\nfunction I([string]$s, [int]$d) { $n = 0; if ([int]::TryParse(($s -replace '\\s', ''), [ref]$n)) { return \"$n\" } return \"$d\" }\nfunction L([string]$s) {\n $parts = @()\n foreach ($x in ($s -split ',')) { $t = $x.Trim(); if ($t -ne '') { $parts += ('\"' + (Esc $t) + '\"') } }\n return '[' + ($parts -join ', ') + ']'\n}\nfunction Pair([string]$x) {\n $i = $x.IndexOf('=')\n if ($i -lt 1) { return $null }\n return @{ Key = $x.Substring(0, $i).Trim(); Value = $x.Substring($i + 1).Trim() }\n}\nfunction SrvLines($list, [string]$s) {\n foreach ($x in ($s -split ',')) {\n $t = $x.Trim(); if ($t -eq '') { continue }\n $p = Pair $t\n if ($null -eq $p -or $p.Key -eq '' -or $p.Value -eq '') { Write-Output \"skipping malformed servers entry '$t' (expected id=host:port)\"; continue }\n $list.Add('\"' + (Esc $p.Key) + '\" = \"' + (Esc $p.Value) + '\"')\n }\n}\nfunction FhLines($list, [string]$s) {\n foreach ($x in ($s -split ',')) {\n $t = $x.Trim(); if ($t -eq '') { continue }\n $p = Pair $t\n if ($null -eq $p -or $p.Key -eq '') { Write-Output \"skipping malformed forced_hosts entry '$t' (expected hostname=id1|id2)\"; continue }\n $list.Add('\"' + (Esc $p.Key) + '\" = ' + (L ($p.Value -replace '\\|', ',')))\n }\n}\nfunction Mods([string]$s) {\n $parts = @()\n foreach ($x in ($s -split ',')) {\n $t = $x.Trim(); if ($t -eq '') { continue }\n $p = Pair $t\n if ($null -eq $p) { $parts += ('{ id = \"' + (Esc $t) + '\", version = \"\" }') }\n else { $parts += ('{ id = \"' + (Esc $p.Key) + '\", version = \"' + (Esc $p.Value) + '\" }') }\n }\n return '[' + ($parts -join ', ') + ']'\n}\nfunction KeepSecret([string]$key, [string]$val, [string]$file) {\n if (-not [string]::IsNullOrWhiteSpace($val)) { return $val }\n if (Test-Path -LiteralPath $file) {\n $pattern = '^\\s*' + [regex]::Escape($key) + '\\s*=\\s*\"(.*)\"'\n $m = Select-String -LiteralPath $file -Pattern $pattern | Select-Object -First 1\n if ($m) {\n $cur = $m.Matches[0].Groups[1].Value\n if ($cur -ne '' -and $cur -ne 'change-me-and-keep-secret') { return $cur }\n }\n }\n Write-Host (\"[AMP] no $key set, generating a random one; read it out of \" + (Split-Path -Leaf $file) + \" and paste it into every backend\")\n $bytes = New-Object byte[] 32\n $rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()\n $rng.GetBytes($bytes)\n return (($bytes | ForEach-Object { $_.ToString('x2') }) -join '')\n}\n\nif ((B (D $env:NP_WRITE 'true')) -ne 'true') {\n Write-Output (\"AMP management of \" + (Split-Path -Leaf $Out) + \" is disabled, leaving the existing file alone\")\n exit 0\n}\n\n$dir = Split-Path -Parent $Out\nif ($dir -and -not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }\n$L = New-Object System.Collections.Generic.List[string]\n$L.Add('bind = \"' + (Esc (D $env:NP_BIND '0.0.0.0:42420')) + '\"')\n$L.Add('try = ' + (L (D $env:NP_TRY 'hub')))\n$L.Add('proxy_protocol_servers = ' + (L (D $env:NP_PPSERVERS '')))\n$L.Add('')\n$L.Add('[servers]')\nSrvLines $L (D $env:NP_SERVERS 'hub=127.0.0.1:42421')\n$L.Add('')\n$L.Add('[forced_hosts]')\nFhLines $L (D $env:NP_FORCEDHOSTS '')\n$L.Add('')\n$L.Add('[transfers]')\n$L.Add('default_mode = \"' + (Esc (D $env:NP_T_MODE 'redirect')) + '\"')\n$L.Add('allow_seamless = ' + (B (D $env:NP_T_ALLOWSEAMLESS 'false')))\n$L.Add('require_seamless_capability = ' + (B (D $env:NP_T_REQCAP 'true')))\n$L.Add('fallback_to_redirect_when_seamless_unavailable = ' + (B (D $env:NP_T_FALLBACK 'true')))\n$L.Add('redirect_address = \"' + (Esc (D $env:NP_T_REDIRECTADDR '')) + '\"')\n$L.Add('enable_unsafe_seamless_splice = ' + (B (D $env:NP_T_SPLICE 'false')))\n$L.Add('')\n$L.Add('[admin]')\n$L.Add('enabled = ' + (B (D $env:NP_A_ENABLED 'true')))\n$L.Add('bind = \"' + (Esc (D $env:NP_A_BIND '127.0.0.1')) + '\"')\n$L.Add('secret = \"' + (Esc (D $env:NP_A_SECRET '')) + '\"')\n$L.Add('granted_permissions = ' + (L (D $env:NP_A_PERMS '*')))\n$L.Add('')\n$L.Add('[registry]')\n$L.Add('mode = \"' + (Esc (D $env:NP_R_MODE 'embedded')) + '\"')\n$L.Add('proxy_id = \"' + (Esc (D $env:NP_R_PROXYID 'nimbus-proxy')) + '\"')\n$L.Add('reservation_ttl_seconds = ' + (I (D $env:NP_R_RESTTL '60') 60))\n$L.Add('fail_on_error = ' + (B (D $env:NP_R_FAILONERROR 'true')))\n$L.Add('transfer_intent_poll_ms = ' + (I (D $env:NP_R_INTENTPOLL '1000') 1000))\n$L.Add('url = \"' + (Esc (D $env:NP_R_URL '')) + '\"')\n$L.Add('shared_secret = \"' + (Esc (D $env:NP_R_SECRET '')) + '\"')\n$L.Add('http_timeout_seconds = ' + (I (D $env:NP_R_HTTPTIMEOUT '5') 5))\nif ((B (D $env:NP_R_EMBHTTP 'true')) -eq 'true') {\n $L.Add('embedded_bind = \"' + (Esc (D $env:NP_R_EMBBIND '127.0.0.1')) + '\"')\n} else { $L.Add('embedded_bind = \"\"') }\n$L.Add('embedded_shared_secret = \"' + (Esc (KeepSecret 'embedded_shared_secret' $env:NP_R_EMBSECRET $Out)) + '\"')\n$L.Add('backend_stale_seconds = ' + (I (D $env:NP_R_STALE '20') 20))\n$L.Add('backend_drop_seconds = ' + (I (D $env:NP_R_DROP '120') 120))\n$L.Add('nonce_window_seconds = ' + (I (D $env:NP_R_NONCE '90') 90))\n$L.Add('max_reservation_ttl_seconds = ' + (I (D $env:NP_R_MAXRESTTL '300') 300))\n$L.Add('advertise_on_master_server = ' + (B (D $env:NP_R_ADVERTISE 'false')))\n$L.Add('embedded_state_dir = \"' + (Esc (D $env:NP_R_STATEDIR '.')) + '\"')\n$L.Add('api_tokens_enabled = ' + (B (D $env:NP_R_APITOK 'false')))\n$L.Add('api_tokens_rate_limit_per_minute = ' + (I (D $env:NP_R_APIRATE '60') 60))\n$L.Add('api_tokens_trust_forwarded_proto = ' + (B (D $env:NP_R_APIFWD 'false')))\n$L.Add('')\n$L.Add('[whitelist]')\n$L.Add('network = ' + (B (D $env:NP_W_NETWORK 'false')))\n$L.Add('servers = ' + (L (D $env:NP_W_SERVERS '')))\n$L.Add('fail_open_until_first_sync = ' + (B (D $env:NP_W_FAILOPEN 'false')))\n$L.Add('')\n$L.Add('[logging]')\n$L.Add('verbose = ' + (B (D $env:NP_L_VERBOSE 'false')))\n$L.Add('sniff_frames = ' + (B (D $env:NP_L_SNIFF 'false')))\n$L.Add('log_traffic_bytes = ' + (B (D $env:NP_L_TRAFFIC 'false')))\n$L.Add('')\n$L.Add('[metrics]')\n$L.Add('enabled = ' + (B (D $env:NP_M_ENABLED 'true')))\n$L.Add('bind = \"' + (Esc (D $env:NP_M_BIND '127.0.0.1')) + '\"')\n$L.Add('path = \"' + (Esc (D $env:NP_M_PATH '/metrics')) + '\"')\n$L.Add('status_api = ' + (B (D $env:NP_M_STATUSAPI 'true')))\n$L.Add('status_api_token = \"' + (Esc (D $env:NP_M_STATUSTOKEN '')) + '\"')\n$L.Add('')\n$L.Add('[status]')\n$L.Add('enabled = ' + (B (D $env:NP_S_ENABLED 'true')))\n$L.Add('name = \"' + (Esc (D $env:NP_S_NAME 'Nimbus')) + '\"')\n$L.Add('motd = \"' + (Esc (D $env:NP_S_MOTD 'Vintage Story proxy')) + '\"')\n$L.Add('game_mode = \"' + (Esc (D $env:NP_S_GAMEMODE 'survival')) + '\"')\n$L.Add('password = ' + (B (D $env:NP_S_PASSWORD 'false')))\n$L.Add('server_version = \"' + (Esc (D $env:NP_S_VERSION '')) + '\"')\n$L.Add('max_players = ' + (I (D $env:NP_S_MAXPLAYERS '100') 100))\n$L.Add('query_timeout_ms = ' + (I (D $env:NP_S_QUERYTIMEOUT '1500') 1500))\n$L.Add('')\n$L.Add('[plugins]')\n$L.Add('enabled = ' + (B (D $env:NP_P_ENABLED 'true')))\n$L.Add('directory = \"' + (Esc (D $env:NP_P_DIR 'plugins')) + '\"')\n$L.Add('disabled = ' + (L (D $env:NP_P_DISABLED '')))\n$L.Add('')\n$L.Add('[persistence]')\n$L.Add('persist_drain_flags = ' + (B (D $env:NP_PE_DRAIN 'true')))\n$L.Add('drain_flags_file = \"' + (Esc (D $env:NP_PE_DRAINFILE 'nimbus.drain-state.json')) + '\"')\n$L.Add('')\n$L.Add('[advanced]')\n$L.Add('connect_timeout_ms = ' + (I (D $env:NP_AD_CONNTIMEOUT '5000') 5000))\n$L.Add('buffer_size = ' + (I (D $env:NP_AD_BUFSIZE '16384') 16384))\n$tmp = \"$Out.amptmp\"\nSet-Content -LiteralPath $tmp -Value $L -Encoding UTF8\nMove-Item -LiteralPath $tmp -Destination $Out -Force\nWrite-Output \"wrote $Out\"\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": ".NET SDK Download", + "UpdateSourcePlatform": "Linux", "UpdateSource": "Executable", - "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -Command \"$ProgressPreference='SilentlyContinue'; [Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $DotnetVersion='{{DotnetSDKVersion}}'; Set-Location '{{$FullBaseDir}}'; if (Test-Path 'dotnet/dotnet.exe') { $InstalledVersion=(& dotnet/dotnet.exe --version).Trim() } else { $InstalledVersion='' }; if ([string]::IsNullOrWhiteSpace($DotnetVersion)) { $DotnetVersion=(Invoke-RestMethod -UseBasicParsing 'https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json').'latest-sdk' }; if ($DotnetVersion -notmatch '^\\d+\\.\\d+\\.\\d+$') { throw 'Invalid .NET SDK version format specified' }; if ($InstalledVersion -eq $DotnetVersion) { Write-Output \\\".NET SDK v$DotnetVersion already installed. Skipping\\\"; exit 0 }; Invoke-WebRequest -UseBasicParsing -Uri \\\"https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-win-x64.zip\\\" -OutFile dotnet.zip -ErrorAction Stop; Remove-Item 'dotnet/*' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive dotnet.zip dotnet -Force; Remove-Item dotnet.zip -Force; Write-Output \\\".NET SDK v$DotnetVersion downloaded\\\"\"", + "UpdateSourceArch": "x86_64", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"DotnetVersion=\\\"{{DotnetSDKVersion}}\\\"; cd \\\"{{$FullBaseDir}}\\\" && if [[ -x dotnet/dotnet ]]; then InstalledVersion=$(dotnet/dotnet --version | xargs); else InstalledVersion=\\\"\\\"; fi; if [[ -z \\\"$DotnetVersion\\\" ]]; then DotnetVersion=$(wget -qO- https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json | jq -r \\\".[\\\\\\\"latest-sdk\\\\\\\"]\\\"); fi; if [[ ! \\\"$DotnetVersion\\\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+$ ]]; then echo \\\"Invalid .NET SDK version format specified\\\" && exit 1; elif [[ \\\"$InstalledVersion\\\" == \\\"$DotnetVersion\\\" ]]; then echo \\\".NET SDK v$DotnetVersion already installed. Skipping\\\" && exit 0; else [[ -f dotnet.tar.gz ]] && rm -f dotnet.tar.gz >/dev/null 2>&1; wget -qO dotnet.tar.gz https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-linux-x64.tar.gz || { echo \\\"Download failed from the Microsoft CDN. This is a fault with the CDN, not AMP. Aborting\\\"; exit 1; }; rm -rf dotnet/* >/dev/null 2>&1 && tar -xzf dotnet.tar.gz -C dotnet >/dev/null 2>&1 && rm -f dotnet.tar.gz >/dev/null 2>&1 && echo \\\".NET SDK v$DotnetVersion downloaded\\\"; fi\"", "SkipOnFailure": false }, { - "UpdateStageName": "Nimbus Proxy Download", + "UpdateStageName": ".NET SDK Download", "UpdateSourcePlatform": "Windows", "UpdateSource": "Executable", "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -Command \"$ErrorActionPreference='Stop'; $ProgressPreference='SilentlyContinue'; $game='{{ServerVersion}}'.Trim(); if ($game -notmatch '^\\d+\\.\\d+\\.\\d+(-rc\\.\\d+|-pre\\.\\d+)?$') { throw 'Invalid Vintage Story version' }; $requested='{{NimbusVersion}}'.Trim(); if ($requested -and -not $requested.StartsWith('v')) { $requested='v'+$requested }; $releases=Invoke-RestMethod -UseBasicParsing 'https://api.github.com/repos/StratumServer/Nimbus/releases?per_page=100'; if ($requested) { $candidates=@($releases | Where-Object { $_.tag_name -eq $requested -and -not $_.draft }) } else { $candidates=@($releases | Where-Object { -not $_.draft -and -not $_.prerelease }) }; $selected=$null; foreach ($release in $candidates) { try { $readme=Invoke-WebRequest -UseBasicParsing -Uri ('https://raw.githubusercontent.com/StratumServer/Nimbus/'+$release.tag_name+'/README.md') | Select-Object -ExpandProperty Content } catch { continue }; $match=[regex]::Match($readme,'Built and tested against Vintage Story\\s+([0-9]+\\.[0-9]+\\.[0-9]+(?:-rc\\.[0-9]+|-pre\\.[0-9]+)?)',[Text.RegularExpressions.RegexOptions]::IgnoreCase); if ($match.Success -and $match.Groups[1].Value -eq $game) { $selected=$release; break } }; if (-not $selected) { throw \\\"No Nimbus release declares compatibility with Vintage Story $game\\\" }; $assetName='Nimbus-'+$selected.tag_name+'.zip'; $asset=$selected.assets | Where-Object { $_.name -eq $assetName } | Select-Object -First 1; if (-not $asset -or $asset.browser_download_url -notmatch '^https://') { throw \\\"Release asset $assetName was not found\\\" }; Invoke-WebRequest -UseBasicParsing -Uri $asset.browser_download_url -OutFile '{{$FullBaseDir}}nimbus.zip'; Remove-Item '{{$FullBaseDir}}nimbus-temp' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive '{{$FullBaseDir}}nimbus.zip' '{{$FullBaseDir}}nimbus-temp' -Force; $source=Get-ChildItem '{{$FullBaseDir}}nimbus-temp' -Directory -Recurse | Where-Object { $_.Name -eq 'Nimbus' } | Select-Object -First 1; if (-not $source -or -not (Test-Path (Join-Path $source.FullName 'Nimbus.Proxy.dll'))) { throw 'Nimbus proxy folder was not found in the release' }; Copy-Item (Join-Path $source.FullName '*') '{{$FullBaseDir}}app' -Recurse -Force; [IO.File]::WriteAllText('{{$FullBaseDir}}.nimbus-version',$selected.tag_name); Remove-Item '{{$FullBaseDir}}nimbus-temp','{{$FullBaseDir}}nimbus.zip' -Recurse -Force; Write-Output (\\\"Nimbus $($selected.tag_name) installed for Vintage Story $game\\\")\"", + "UpdateSourceArgs": "-NoProfile -Command \"$ProgressPreference='SilentlyContinue'; [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $DotnetVersion='{{DotnetSDKVersion}}'; Set-Location -Path '{{$FullBaseDir}}'; if (Test-Path 'dotnet/dotnet.exe') { $InstalledVersion = (& dotnet/dotnet.exe --version).Trim() } else { $InstalledVersion = '' }; if ( [string]::IsNullOrWhiteSpace($DotnetVersion) ) { $DotnetVersion=(Invoke-RestMethod -UseBasicParsing -Uri https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json).\\\"latest-sdk\\\" }; if ($DotnetVersion -notmatch '^\\d+\\.\\d+\\.\\d+$') { Write-Output \\\"Invalid .NET SDK version format specified\\\"; exit 1 } elseif ( $InstalledVersion -eq $DotnetVersion ) { Write-Output \\\".NET SDK v$DotnetVersion already installed. Skipping\\\"; exit 0 } else { if ( Test-Path dotnet.zip ) { Remove-Item dotnet.zip -Force -ErrorAction SilentlyContinue *> $null }; try { Invoke-WebRequest -UseBasicParsing -Uri https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-win-x64.zip -OutFile dotnet.zip -ErrorAction Stop } catch { Write-Output \\\"Download failed from the Microsoft CDN. This is a fault with the CDN, not AMP. Aborting\\\"; exit 1; }; Remove-Item -Path 'dotnet/*' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive -Path \\\"dotnet.zip\\\" -DestinationPath \\\"dotnet\\\" -Force *> $null; if ( Test-Path dotnet.zip ) { Remove-Item dotnet.zip -Force -ErrorAction SilentlyContinue *> $null }; Write-Output \\\".NET SDK v$DotnetVersion downloaded\\\" }\"", "SkipOnFailure": false }, { - "UpdateStageName": "Nimbus Proxy Download", + "UpdateStageName": "Nimbus Download", "UpdateSourcePlatform": "Linux", - "UpdateSourceArch": "x86_64", "UpdateSource": "Executable", + "UpdateSourceArch": "x86_64", "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"set -euo pipefail; game='{{ServerVersion}}'; requested='{{NimbusVersion}}'; [[ \\\"$game\\\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+(-rc\\.[0-9]+|-pre\\.[0-9]+)?$ ]] || { echo 'Invalid Vintage Story version'; exit 1; }; [[ -z \\\"$requested\\\" || \\\"$requested\\\" == v* ]] || requested=\\\"v$requested\\\"; releases='{{$FullBaseDir}}nimbus-releases.json'; wget -qO \\\"$releases\\\" 'https://api.github.com/repos/StratumServer/Nimbus/releases?per_page=100'; if [[ -n \\\"$requested\\\" ]]; then tags=\\\"$requested\\\"; else tags=$(jq -r '.[] | select((.draft|not) and (.prerelease|not)) | .tag_name' \\\"$releases\\\"); fi; selected=''; while IFS= read -r tag; do [[ -n \\\"$tag\\\" ]] || continue; readme=$(wget -qO- \\\"https://raw.githubusercontent.com/StratumServer/Nimbus/$tag/README.md\\\" || true); compatible=$(printf '%s' \\\"$readme\\\" | grep -Eio 'Built and tested against Vintage Story[[:space:]]+[0-9]+\\.[0-9]+\\.[0-9]+(-rc\\.[0-9]+|-pre\\.[0-9]+)?' | head -1 | awk '{print $7}'); if [[ \\\"$compatible\\\" == \\\"$game\\\" ]]; then selected=\\\"$tag\\\"; break; fi; done <<< \\\"$tags\\\"; [[ -n \\\"$selected\\\" ]] || { echo \\\"No Nimbus release declares compatibility with Vintage Story $game\\\"; exit 1; }; asset=\\\"Nimbus-$selected.zip\\\"; url=$(jq -r --arg tag \\\"$selected\\\" --arg asset \\\"$asset\\\" '.[] | select(.tag_name==$tag) | .assets[] | select(.name==$asset) | .browser_download_url' \\\"$releases\\\" | head -1); [[ \\\"$url\\\" == https://* ]] || { echo \\\"Release asset $asset was not found\\\"; exit 1; }; wget -qO '{{$FullBaseDir}}nimbus.zip' \\\"$url\\\"; rm -rf '{{$FullBaseDir}}nimbus-temp'; mkdir -p '{{$FullBaseDir}}nimbus-temp'; unzip -qo '{{$FullBaseDir}}nimbus.zip' -d '{{$FullBaseDir}}nimbus-temp'; source_dir=$(find '{{$FullBaseDir}}nimbus-temp' -type d -name Nimbus | head -1); [[ -n \\\"$source_dir\\\" && -f \\\"$source_dir/Nimbus.Proxy.dll\\\" ]] || { echo 'Nimbus proxy folder was not found in the release'; exit 1; }; cp -rf \\\"$source_dir/.\\\" '{{$FullBaseDir}}app/'; printf '%s' \\\"$selected\\\" > '{{$FullBaseDir}}.nimbus-version'; rm -rf '{{$FullBaseDir}}nimbus-temp' '{{$FullBaseDir}}nimbus.zip' \\\"$releases\\\"; echo \\\"Nimbus $selected installed for Vintage Story $game\\\"\"", + "UpdateSourceArgs": "-c \"NIMBUS_TAG='{{NimbusVersionTag}}' NIMBUS_CHANNEL='{{NimbusReleaseChannel}}' GITHUB_TOKEN='{{NimbusGitHubToken}}' bash '{{$FullRootDir}}scripts/install-nimbus.sh' '{{$FullRootDir}}' '{{NimbusUpdateComponents}}'\"", "SkipOnFailure": false }, { - "UpdateStageName": "Start Nimbus Proxy", - "UpdateSourcePlatform": "All", - "UpdateSource": "StartApplication", + "UpdateStageName": "Nimbus Download", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$env:NIMBUS_TAG='{{NimbusVersionTag}}'; $env:NIMBUS_CHANNEL='{{NimbusReleaseChannel}}'; $env:GITHUB_TOKEN='{{NimbusGitHubToken}}'; & '{{$FullRootDir}}scripts\\install-nimbus.ps1' '{{$FullRootDir}}' '{{NimbusUpdateComponents}}'\"", "SkipOnFailure": false }, { - "UpdateStageName": "Wait For Nimbus Proxy Start", - "UpdateSourcePlatform": "All", - "UpdateSource": "WaitForStartupComplete", + "UpdateStageName": "Render nimbus.proxy.toml", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"NP_WRITE='{{ProxyWriteConfig}}' NP_BIND='{{ProxyBindHost}}:{{$ServerPort}}' NP_SERVERS='{{ProxyServers}}' NP_TRY='{{ProxyTryList}}' NP_PPSERVERS='{{ProxyProtocolServers}}' NP_FORCEDHOSTS='{{ProxyForcedHosts}}' NP_T_MODE='{{ProxyTransfersDefaultMode}}' NP_T_ALLOWSEAMLESS='{{ProxyTransfersAllowSeamless}}' NP_T_REQCAP='{{ProxyTransfersRequireSeamlessCapability}}' NP_T_FALLBACK='{{ProxyTransfersFallbackToRedirect}}' NP_T_REDIRECTADDR='{{ProxyTransfersRedirectAddress}}' NP_T_SPLICE='{{ProxyTransfersEnableUnsafeSplice}}' NP_A_ENABLED='{{ProxyAdminEnabled}}' NP_A_BIND='{{ProxyAdminBindHost}}:{{$AdminPort}}' NP_A_SECRET='{{ProxyAdminSecret}}' NP_A_PERMS='{{ProxyAdminGrantedPermissions}}' NP_R_MODE='{{ProxyRegistryMode}}' NP_R_PROXYID='{{ProxyRegistryProxyId}}' NP_R_RESTTL='{{ProxyRegistryReservationTtlSeconds}}' NP_R_FAILONERROR='{{ProxyRegistryFailOnError}}' NP_R_INTENTPOLL='{{ProxyRegistryTransferIntentPollMs}}' NP_R_URL='{{ProxyRegistryUrl}}' NP_R_SECRET='{{ProxyRegistrySharedSecret}}' NP_R_HTTPTIMEOUT='{{ProxyRegistryHttpTimeoutSeconds}}' NP_R_EMBBIND='http://{{ProxyRegistryEmbeddedBindHost}}:{{$RegistryPort}}' NP_R_EMBHTTP='{{ProxyRegistryEmbeddedHttpEnabled}}' NP_R_EMBSECRET='{{ProxyRegistryEmbeddedSharedSecret}}' NP_R_STALE='{{ProxyRegistryBackendStaleSeconds}}' NP_R_DROP='{{ProxyRegistryBackendDropSeconds}}' NP_R_NONCE='{{ProxyRegistryNonceWindowSeconds}}' NP_R_MAXRESTTL='{{ProxyRegistryMaxReservationTtlSeconds}}' NP_R_ADVERTISE='{{ProxyRegistryAdvertiseOnMasterServer}}' NP_R_STATEDIR='{{ProxyRegistryEmbeddedStateDir}}' NP_R_APITOK='{{ProxyRegistryApiTokensEnabled}}' NP_R_APIRATE='{{ProxyRegistryApiTokensRateLimitPerMinute}}' NP_R_APIFWD='{{ProxyRegistryApiTokensTrustForwardedProto}}' NP_W_NETWORK='{{ProxyWhitelistNetwork}}' NP_W_SERVERS='{{ProxyWhitelistServers}}' NP_W_FAILOPEN='{{ProxyWhitelistFailOpenUntilFirstSync}}' NP_L_VERBOSE='{{ProxyLoggingVerbose}}' NP_L_SNIFF='{{ProxyLoggingSniffFrames}}' NP_L_TRAFFIC='{{ProxyLoggingLogTrafficBytes}}' NP_M_ENABLED='{{ProxyMetricsEnabled}}' NP_M_BIND='http://{{ProxyMetricsBindHost}}:{{$MetricsPort}}' NP_M_PATH='{{ProxyMetricsPath}}' NP_M_STATUSAPI='{{ProxyMetricsStatusApi}}' NP_M_STATUSTOKEN='{{ProxyMetricsStatusApiToken}}' NP_S_ENABLED='{{ProxyStatusEnabled}}' NP_S_NAME='{{ProxyStatusName}}' NP_S_MOTD='{{ProxyStatusMotd}}' NP_S_GAMEMODE='{{ProxyStatusGameMode}}' NP_S_PASSWORD='{{ProxyStatusPassword}}' NP_S_VERSION='{{ProxyStatusServerVersion}}' NP_S_MAXPLAYERS='{{$MaxUsers}}' NP_S_QUERYTIMEOUT='{{ProxyStatusQueryTimeoutMs}}' NP_P_ENABLED='{{ProxyPluginsEnabled}}' NP_P_DIR='{{ProxyPluginsDirectory}}' NP_P_DISABLED='{{ProxyPluginsDisabled}}' NP_PE_DRAIN='{{ProxyPersistDrainFlags}}' NP_PE_DRAINFILE='{{ProxyDrainFlagsFile}}' NP_AD_CONNTIMEOUT='{{ProxyConnectTimeoutMs}}' NP_AD_BUFSIZE='{{ProxyBufferSize}}' bash '{{$FullRootDir}}scripts/write-proxy-toml.sh' '{{$FullRootDir}}Nimbus/nimbus.proxy.toml'\"", "SkipOnFailure": false }, { - "UpdateStageName": "Stop Nimbus Proxy", - "UpdateSourcePlatform": "All", - "UpdateSource": "ShutdownApplication", + "UpdateStageName": "Render nimbus.proxy.toml", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$env:NP_WRITE='{{ProxyWriteConfig}}'; $env:NP_BIND='{{ProxyBindHost}}:{{$ServerPort}}'; $env:NP_SERVERS='{{ProxyServers}}'; $env:NP_TRY='{{ProxyTryList}}'; $env:NP_PPSERVERS='{{ProxyProtocolServers}}'; $env:NP_FORCEDHOSTS='{{ProxyForcedHosts}}'; $env:NP_T_MODE='{{ProxyTransfersDefaultMode}}'; $env:NP_T_ALLOWSEAMLESS='{{ProxyTransfersAllowSeamless}}'; $env:NP_T_REQCAP='{{ProxyTransfersRequireSeamlessCapability}}'; $env:NP_T_FALLBACK='{{ProxyTransfersFallbackToRedirect}}'; $env:NP_T_REDIRECTADDR='{{ProxyTransfersRedirectAddress}}'; $env:NP_T_SPLICE='{{ProxyTransfersEnableUnsafeSplice}}'; $env:NP_A_ENABLED='{{ProxyAdminEnabled}}'; $env:NP_A_BIND='{{ProxyAdminBindHost}}:{{$AdminPort}}'; $env:NP_A_SECRET='{{ProxyAdminSecret}}'; $env:NP_A_PERMS='{{ProxyAdminGrantedPermissions}}'; $env:NP_R_MODE='{{ProxyRegistryMode}}'; $env:NP_R_PROXYID='{{ProxyRegistryProxyId}}'; $env:NP_R_RESTTL='{{ProxyRegistryReservationTtlSeconds}}'; $env:NP_R_FAILONERROR='{{ProxyRegistryFailOnError}}'; $env:NP_R_INTENTPOLL='{{ProxyRegistryTransferIntentPollMs}}'; $env:NP_R_URL='{{ProxyRegistryUrl}}'; $env:NP_R_SECRET='{{ProxyRegistrySharedSecret}}'; $env:NP_R_HTTPTIMEOUT='{{ProxyRegistryHttpTimeoutSeconds}}'; $env:NP_R_EMBBIND='http://{{ProxyRegistryEmbeddedBindHost}}:{{$RegistryPort}}'; $env:NP_R_EMBHTTP='{{ProxyRegistryEmbeddedHttpEnabled}}'; $env:NP_R_EMBSECRET='{{ProxyRegistryEmbeddedSharedSecret}}'; $env:NP_R_STALE='{{ProxyRegistryBackendStaleSeconds}}'; $env:NP_R_DROP='{{ProxyRegistryBackendDropSeconds}}'; $env:NP_R_NONCE='{{ProxyRegistryNonceWindowSeconds}}'; $env:NP_R_MAXRESTTL='{{ProxyRegistryMaxReservationTtlSeconds}}'; $env:NP_R_ADVERTISE='{{ProxyRegistryAdvertiseOnMasterServer}}'; $env:NP_R_STATEDIR='{{ProxyRegistryEmbeddedStateDir}}'; $env:NP_R_APITOK='{{ProxyRegistryApiTokensEnabled}}'; $env:NP_R_APIRATE='{{ProxyRegistryApiTokensRateLimitPerMinute}}'; $env:NP_R_APIFWD='{{ProxyRegistryApiTokensTrustForwardedProto}}'; $env:NP_W_NETWORK='{{ProxyWhitelistNetwork}}'; $env:NP_W_SERVERS='{{ProxyWhitelistServers}}'; $env:NP_W_FAILOPEN='{{ProxyWhitelistFailOpenUntilFirstSync}}'; $env:NP_L_VERBOSE='{{ProxyLoggingVerbose}}'; $env:NP_L_SNIFF='{{ProxyLoggingSniffFrames}}'; $env:NP_L_TRAFFIC='{{ProxyLoggingLogTrafficBytes}}'; $env:NP_M_ENABLED='{{ProxyMetricsEnabled}}'; $env:NP_M_BIND='http://{{ProxyMetricsBindHost}}:{{$MetricsPort}}'; $env:NP_M_PATH='{{ProxyMetricsPath}}'; $env:NP_M_STATUSAPI='{{ProxyMetricsStatusApi}}'; $env:NP_M_STATUSTOKEN='{{ProxyMetricsStatusApiToken}}'; $env:NP_S_ENABLED='{{ProxyStatusEnabled}}'; $env:NP_S_NAME='{{ProxyStatusName}}'; $env:NP_S_MOTD='{{ProxyStatusMotd}}'; $env:NP_S_GAMEMODE='{{ProxyStatusGameMode}}'; $env:NP_S_PASSWORD='{{ProxyStatusPassword}}'; $env:NP_S_VERSION='{{ProxyStatusServerVersion}}'; $env:NP_S_MAXPLAYERS='{{$MaxUsers}}'; $env:NP_S_QUERYTIMEOUT='{{ProxyStatusQueryTimeoutMs}}'; $env:NP_P_ENABLED='{{ProxyPluginsEnabled}}'; $env:NP_P_DIR='{{ProxyPluginsDirectory}}'; $env:NP_P_DISABLED='{{ProxyPluginsDisabled}}'; $env:NP_PE_DRAIN='{{ProxyPersistDrainFlags}}'; $env:NP_PE_DRAINFILE='{{ProxyDrainFlagsFile}}'; $env:NP_AD_CONNTIMEOUT='{{ProxyConnectTimeoutMs}}'; $env:NP_AD_BUFSIZE='{{ProxyBufferSize}}';& '{{$FullRootDir}}scripts\\write-proxy-toml.ps1' '{{$FullRootDir}}Nimbus\\nimbus.proxy.toml'\"", "SkipOnFailure": false } ] diff --git a/nimbus-registry.kvp b/nimbus-registry.kvp new file mode 100644 index 000000000..c36b7d26a --- /dev/null +++ b/nimbus-registry.kvp @@ -0,0 +1,97 @@ +Meta.DisplayName=Nimbus Registry (Vintage Story) +Meta.Description=Standalone Nimbus registry for Vintage Story networks. It is the single source of truth for which backends are alive, slot reservations, transfer intents, bans, the whitelist and API tokens. You only need this instance when you run more than one proxy, or when you want the registry to survive a proxy restart - a single proxy can host the registry itself in embedded mode. +Meta.OS=Windows, Linux +Meta.AarchSupport=None +Meta.Arch=x86_64 +Meta.Author=HuguesDePayens +Meta.URL=https://github.com/StratumServer/Nimbus +Meta.DisplayImageSource=url:https://wiki.vintagestory.at/images/thumb/8/8a/Gamelogo-vintagestory.png/340px-Gamelogo-vintagestory.png +Meta.EndpointURIFormat= +Meta.ConfigManifest=nimbus-registryconfig.json +Meta.MetaConfigManifest=nimbus-registrymetaconfig.json +Meta.ConfigRoot=nimbus-registry.kvp +Meta.MinAMPVersion=2.4.6.0 +Meta.SpecificDockerImage=cubecoders/ampbase:debian +Meta.DockerRequired=False +Meta.ContainerPolicy=Supported +Meta.ExtraContainerPackages=["jq","unzip","curl","ca-certificates"] +Meta.Prerequisites=[] +Meta.ConfigReleaseState=NotSpecified +Meta.NoCommercialUsage=False +Meta.ConfigVersion=1 +Meta.AppConfigId=c92f1a35-47b8-4d61-95e0-1f8d6c3b7a20 +Meta.AppIsMultiIPAware=True +Meta.ResourceUsageInfo=1 CPU core and 256MB RAM; the registry only answers small HTTP requests +Meta.ImportableExtensions=[] +App.DisplayName=Nimbus Registry +App.RootDir=./nimbus-registry/ +App.BaseDirectory=./nimbus-registry/ +App.ExecutableWin=dotnet\dotnet.exe +App.ExecutableLinux=dotnet/dotnet +App.WorkingDir=Nimbus.Registry +App.LinuxCommandLineArgs="{{$FullRootDir}}Nimbus.Registry/Nimbus.Registry.dll" "{{$FullRootDir}}Nimbus.Registry/nimbus.registry.toml" +App.WindowsCommandLineArgs="{{$FullRootDir}}Nimbus.Registry\Nimbus.Registry.dll" "{{$FullRootDir}}Nimbus.Registry\nimbus.registry.toml" +App.CommandLineArgs={{$PlatformArgs}} {{RegistryExtraArgs}} +App.UseLinuxIOREDIR=False +App.AppSettings={} +App.EnvironmentVariables={"DOTNET_ROOT":"{{$FullRootDir}}dotnet","DOTNET_CLI_TELEMETRY_OPTOUT":"1","DOTNET_NOLOGO":"1","ASPNETCORE_ENVIRONMENT":"Production"} +App.CommandLineParameterFormat=--{0} {1} +App.CommandLineParameterDelimiter= +App.ExitMethod=SIGTERM +App.ExitMethodWindows=None +App.ExitTimeout=30 +App.ExitString= +App.ExitFile=lock +App.HasWriteableConsole=False +App.HasReadableConsole=True +App.SupportsLiveSettingsChanges=False +App.LiveSettingChangeCommandFormat= +App.ApplicationIPBinding=0.0.0.0 +App.Ports=@IncludeJson[nimbus-registryports.json] +App.AdminPortRef=RegistryPort +App.PrimaryApplicationPortRef=RegistryPort +App.UniversalSleepApplicationUDPPortRef=RegistryPort +App.UniversalSleepSteamQueryPortRef=RegistryPort +App.MaxUsers=0 +App.UseRandomAdminPassword=False +App.RemoteAdminPassword= +App.AdminMethod=STDIO +App.AdminLoginTransform=None +App.RCONConnectDelaySeconds=5 +App.RCONConnectRetrySeconds=5 +App.RCONHeartbeatMinutes=0 +App.RCONHeartbeatCommand=ping +App.TelnetLoginFormat={0} +App.PreStartStages=@IncludeJson[nimbus-registrystart.json] +App.UpdateSources=@IncludeJson[nimbus-registryupdates.json] +App.Compatibility=None +App.SteamUpdateAnonymousLogin=True +App.SteamForceLoginPrompt=False +App.RapidStartup=False +App.SmartExcludeSupported=True +App.SmartExcludeExemptions=["*.toml","*.json","*.cfg","*.conf","*.config","*.ini","*.kvp","*.yml","*.yaml"] +App.MonitorChildProcess=False +App.MonitorChildProcessWaitMs=100 +App.MonitorChildProcessName= +App.SupportsUniversalSleep=False +App.WakeupMode=Any +App.ApplicationReadyMode=RegexMatch +App.StripANSIControlCodes=True +Console.FilterMatchRegex= +Console.FilterMatchReplacement= +Console.ThrowawayMessageRegex= +Console.AppReadyRegex=^\[Nimbus\] registry listening on .+$ +Console.UserJoinRegex= +Console.UserLeaveRegex= +Console.UserChatRegex= +Console.UpdateAvailableRegex= +Console.MetricsRegex= +Console.SuppressLogAtStart=False +Console.ActivateLogRegex= +Console.UserActions={} +Limits.SleepMode=False +Limits.SleepOnStart=False +Limits.SleepDelayMinutes=5 +Limits.DozeDelay=2 +Limits.AutoRetryCount=2 +Limits.SleepStartThresholdSeconds=25 diff --git a/nimbus-registryconfig.json b/nimbus-registryconfig.json new file mode 100644 index 000000000..45920f18a --- /dev/null +++ b/nimbus-registryconfig.json @@ -0,0 +1,582 @@ +[ + { + "DisplayName": "Let AMP Manage nimbus.registry.toml", + "Category": "Updates", + "Subcategory": "Nimbus Updates:build:-1", + "Description": "When on, AMP rewrites Nimbus.Registry/nimbus.registry.toml from the settings in this panel every time the instance starts. Turn it off to hand-edit that file instead.", + "Keywords": "nimbus,config,manage", + "FieldName": "RegistryWriteConfig", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "RegistryWriteConfig", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Nimbus Version Tag", + "Category": "Updates", + "Subcategory": "Nimbus Updates:build:-1", + "Description": "Pin a specific Nimbus release tag, for example v0.5.0. Leave empty to take the newest release on the channel below. Every part of a Nimbus network - proxy, registry and the server mod on each backend - must run the same Nimbus version, so pin this once you go live and bump all of them together.", + "Keywords": "nimbus,version,tag", + "FieldName": "NimbusVersionTag", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "NimbusVersionTag", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Placeholder": "v0.5.0" + }, + { + "DisplayName": "Nimbus Release Channel", + "Category": "Updates", + "Subcategory": "Nimbus Updates:build:-1", + "Description": "stable takes the newest non prerelease. prerelease also considers releases marked as pre-release, which is only for test networks.", + "Keywords": "nimbus,channel,prerelease", + "FieldName": "NimbusReleaseChannel", + "InputType": "enum", + "IsFlagArgument": false, + "ParamFieldName": "NimbusReleaseChannel", + "IncludeInCommandLine": false, + "DefaultValue": "stable", + "EnumValues": { + "Stable releases only": "stable", + "Include pre-releases": "prerelease" + } + }, + { + "DisplayName": "GitHub Token (optional)", + "Category": "Updates", + "Subcategory": "Nimbus Updates:build:-1", + "Description": "Optional GitHub personal access token used only to raise the API rate limit while looking up releases. Nothing here needs a private repository, so leave it empty unless updates start failing with a rate limit message.", + "Keywords": "github,token,ratelimit", + "FieldName": "NimbusGitHubToken", + "InputType": "password", + "IsFlagArgument": false, + "ParamFieldName": "NimbusGitHubToken", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Components To Install", + "Category": "Updates", + "Subcategory": "Nimbus Updates:build:-1", + "Description": "Which parts of the Nimbus release are unpacked into this instance. The standalone registry is all this instance runs. Choose the second option only if you also want the proxy binaries unpacked here for manual use.", + "Keywords": "nimbus,components", + "FieldName": "NimbusUpdateComponents", + "InputType": "enum", + "IsFlagArgument": false, + "ParamFieldName": "NimbusUpdateComponents", + "IncludeInCommandLine": false, + "DefaultValue": "Nimbus.Registry", + "EnumValues": { + "Registry only": "Nimbus.Registry", + "Registry and proxy": "Nimbus.Registry Nimbus" + } + }, + { + "DisplayName": ".NET SDK Version", + "Category": "Updates", + "Subcategory": "Runtime:memory:-1", + "Description": "Exact .NET SDK version to install, for example 10.0.100. Leave this empty to always take the latest SDK from the channel below, which is what you want unless a specific build broke something.", + "Keywords": "dotnet,sdk,version", + "FieldName": "DotnetSDKVersion", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "DotnetSDKVersion", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Placeholder": "10.0.100" + }, + { + "DisplayName": ".NET Release Channel", + "Category": "Updates", + "Subcategory": "Runtime:memory:-1", + "Description": "The .NET release channel the SDK is fetched from. Nimbus Registry targets .NET 10 and needs the ASP.NET Core runtime, which the SDK includes, so leave this at 10.0 unless Nimbus itself moves to a newer runtime.", + "Keywords": "dotnet,release,channel", + "FieldName": "DotnetRelease", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "DotnetRelease", + "IncludeInCommandLine": false, + "DefaultValue": "10.0", + "EnumValues": {}, + "Placeholder": "10.0" + }, + { + "DisplayName": "Additional Command Line Arguments", + "Category": "Updates", + "Subcategory": "Nimbus Updates:build:-1", + "Description": "Extra arguments appended to the registry command line after the config file path. Normally empty.", + "Keywords": "args,commandline", + "FieldName": "RegistryExtraArgs", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "RegistryExtraArgs", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Registry Bind URL", + "Category": "Nimbus Registry:dns", + "Subcategory": "Registry:dns:1", + "Description": "Base URL the registry listens on. The host part is taken from this field and the port from the Registry Port setting, so http://0.0.0.0 plus port 8765 becomes http://0.0.0.0:8765. A standalone registry only earns its keep when backends are not on the same box, so 0.0.0.0 is the sensible default here, and that makes setting a real shared secret mandatory. (Config file key: bind_url)", + "Keywords": "registrybindscheme", + "FieldName": "RegistryBindScheme", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "RegistryBindScheme", + "IncludeInCommandLine": false, + "DefaultValue": "http://0.0.0.0:8765", + "EnumValues": {}, + "Placeholder": "http://0.0.0.0" + }, + { + "DisplayName": "Shared Secret", + "Category": "Nimbus Registry:dns", + "Subcategory": "Registry:dns:1", + "Description": "HMAC secret every backend and every proxy signs its registry calls with. Leave empty and the registry generates one on first start, then read it out of nimbus.registry.toml and paste the same value into each backend's Nimbus Shared Secret and each proxy's Remote Registry Shared Secret. Never leave it as change-me-and-keep-secret. (Config file key: shared_secret)", + "Keywords": "registrysharedsecret", + "FieldName": "RegistrySharedSecret", + "InputType": "password", + "IsFlagArgument": false, + "ParamFieldName": "RegistrySharedSecret", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Additional Accepted Secrets", + "Category": "Nimbus Registry:dns", + "Subcategory": "Registry:dns:1", + "Description": "Comma separated secrets that are also accepted, used to rotate without downtime: add the new secret here, redeploy every backend and proxy with it, then promote it to Shared Secret and clear this field. (Config file key: accepted_secrets)", + "Keywords": "registryacceptedsecrets", + "FieldName": "RegistryAcceptedSecrets", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "RegistryAcceptedSecrets", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Backend Stale After (seconds)", + "Category": "Nimbus Registry:dns", + "Subcategory": "Registry:dns:1", + "Description": "Seconds without a heartbeat before a backend is reported as stale in the network snapshot. (Config file key: backend_stale_seconds)", + "Keywords": "registrybackendstaleseconds", + "FieldName": "RegistryBackendStaleSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "RegistryBackendStaleSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "20", + "EnumValues": {}, + "MinValue": "1" + }, + { + "DisplayName": "Backend Dropped After (seconds)", + "Category": "Nimbus Registry:dns", + "Subcategory": "Registry:dns:1", + "Description": "Seconds without a heartbeat before a backend is removed from the registry entirely. (Config file key: backend_drop_seconds)", + "Keywords": "registrybackenddropseconds", + "FieldName": "RegistryBackendDropSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "RegistryBackendDropSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "120", + "EnumValues": {}, + "MinValue": "1" + }, + { + "DisplayName": "Nonce Window (seconds)", + "Category": "Nimbus Registry:dns", + "Subcategory": "Registry:dns:1", + "Description": "Replay protection window. Signed requests older than this are refused, so every machine on the network needs its clock inside roughly this margin. (Config file key: nonce_window_seconds)", + "Keywords": "registrynoncewindowseconds", + "FieldName": "RegistryNonceWindowSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "RegistryNonceWindowSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "90", + "EnumValues": {}, + "MinValue": "5" + }, + { + "DisplayName": "Maximum Reservation TTL (seconds)", + "Category": "Nimbus Registry:dns", + "Subcategory": "Registry:dns:1", + "Description": "Reservations requesting a longer TTL than this are refused. 0 removes the ceiling. (Config file key: max_reservation_ttl_seconds)", + "Keywords": "registrymaxreservationttlseconds", + "FieldName": "RegistryMaxReservationTtlSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "RegistryMaxReservationTtlSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "300", + "EnumValues": {}, + "MinValue": "0" + }, + { + "DisplayName": "Log Every Heartbeat", + "Category": "Nimbus Registry:dns", + "Subcategory": "Registry:dns:1", + "Description": "Logs every successful backend heartbeat. Handy while wiring a network up, very noisy once it works. (Config file key: log_heartbeats)", + "Keywords": "registrylogheartbeats", + "FieldName": "RegistryLogHeartbeats", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "RegistryLogHeartbeats", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "State Directory", + "Category": "Nimbus Registry:dns", + "Subcategory": "Registry:dns:1", + "Description": "Where nimbus.bans.json, nimbus.whitelist.json and nimbus.tokens.json are kept so they survive a restart. A relative path resolves against the working directory, which is where nimbus.registry.toml lives. A file the registry cannot parse is renamed with a .bad suffix rather than trusted. (Config file key: state_dir)", + "Keywords": "registrystatedir", + "FieldName": "RegistryStateDir", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "RegistryStateDir", + "IncludeInCommandLine": false, + "DefaultValue": ".", + "EnumValues": {}, + "Placeholder": "." + }, + { + "DisplayName": "Enable API Tokens", + "Category": "Nimbus Registry:dns", + "Subcategory": "API Tokens:key:2", + "Description": "Master switch for scoped bearer tokens used by third party integrations. Off refuses bearer authentication no matter which tokens exist. Nimbus's own components always use HMAC and are unaffected. (Config file key: api_tokens.enabled)", + "Keywords": "registryapitokensenabled", + "FieldName": "RegistryApiTokensEnabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "RegistryApiTokensEnabled", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "API Token Rate Limit (per minute)", + "Category": "Nimbus Registry:dns", + "Subcategory": "API Tokens:key:2", + "Description": "Requests per minute per token. A value of zero or less is a configuration error and falls back to 60. (Config file key: api_tokens.rate_limit_per_minute)", + "Keywords": "registryapitokensratelimitperminute", + "FieldName": "RegistryApiTokensRateLimitPerMinute", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "RegistryApiTokensRateLimitPerMinute", + "IncludeInCommandLine": false, + "DefaultValue": "60", + "EnumValues": {}, + "MinValue": "1" + }, + { + "DisplayName": "Trust X-Forwarded-Proto", + "Category": "Nimbus Registry:dns", + "Subcategory": "API Tokens:key:2", + "Description": "Token authentication is only accepted over loopback or the registry's own TLS listener. Set this true only when a TLS terminating reverse proxy is the sole route to the bind URL, because anything that can reach the bind directly can forge the header. (Config file key: api_tokens.trust_forwarded_proto)", + "Keywords": "registryapitokenstrustforwardedproto", + "FieldName": "RegistryApiTokensTrustForwardedProto", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "RegistryApiTokensTrustForwardedProto", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Advertise Network On Master Server", + "Category": "Nimbus Registry:dns", + "Subcategory": "Master Server Listing:public:3", + "Description": "Registers the whole network as one entry on the public Vintage Story server list. Turn master server advertising off on every backend when you use this, otherwise players see each backend separately. (Config file key: identity.advertise_on_master_server)", + "Keywords": "registryadvertiseonmasterserver", + "FieldName": "RegistryAdvertiseOnMasterServer", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "RegistryAdvertiseOnMasterServer", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Master Server URL", + "Category": "Nimbus Registry:dns", + "Subcategory": "Master Server Listing:public:3", + "Description": "Endpoint the registration is sent to. Change this only when you self host a master server. (Config file key: identity.master_server_url)", + "Keywords": "registrymasterserverurl", + "FieldName": "RegistryMasterServerUrl", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "RegistryMasterServerUrl", + "IncludeInCommandLine": false, + "DefaultValue": "http://masterserver.vintagestory.at/api/v1/servers/", + "EnumValues": {} + }, + { + "DisplayName": "Public Host", + "Category": "Nimbus Registry:dns", + "Subcategory": "Master Server Listing:public:3", + "Description": "Address players connect to, which must be the proxy's reachable hostname or IP, never a backend's. (Config file key: identity.public_host)", + "Keywords": "registrypublichost", + "FieldName": "RegistryPublicHost", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "RegistryPublicHost", + "IncludeInCommandLine": false, + "DefaultValue": "127.0.0.1", + "EnumValues": {}, + "Placeholder": "play.example.com" + }, + { + "DisplayName": "Public Port", + "Category": "Nimbus Registry:dns", + "Subcategory": "Master Server Listing:public:3", + "Description": "Port players connect to on the proxy. (Config file key: identity.public_port)", + "Keywords": "registrypublicport", + "FieldName": "RegistryPublicPort", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "RegistryPublicPort", + "IncludeInCommandLine": false, + "DefaultValue": "42420", + "EnumValues": {}, + "MinValue": "1", + "MaxValue": "65535" + }, + { + "DisplayName": "Network Name", + "Category": "Nimbus Registry:dns", + "Subcategory": "Master Server Listing:public:3", + "Description": "Name shown in the public server list. (Config file key: identity.server_name)", + "Keywords": "registryservername", + "FieldName": "RegistryServerName", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "RegistryServerName", + "IncludeInCommandLine": false, + "DefaultValue": "Nimbus Network", + "EnumValues": {} + }, + { + "DisplayName": "Network Description", + "Category": "Nimbus Registry:dns", + "Subcategory": "Master Server Listing:public:3", + "Description": "Description shown in the public server list. (Config file key: identity.server_description)", + "Keywords": "registryserverdescription", + "FieldName": "RegistryServerDescription", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "RegistryServerDescription", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Website URL", + "Category": "Nimbus Registry:dns", + "Subcategory": "Master Server Listing:public:3", + "Description": "Optional website link shown with the listing. (Config file key: identity.server_url)", + "Keywords": "registryserverurl", + "FieldName": "RegistryServerUrl", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "RegistryServerUrl", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Placeholder": "https://example.com" + }, + { + "DisplayName": "Server Icon", + "Category": "Nimbus Registry:dns", + "Subcategory": "Master Server Listing:public:3", + "Description": "Optional icon published with the listing, in the form the master server expects. (Config file key: identity.server_icon)", + "Keywords": "registryservericon", + "FieldName": "RegistryServerIcon", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "RegistryServerIcon", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Hosting Identifier", + "Category": "Nimbus Registry:dns", + "Subcategory": "Master Server Listing:public:3", + "Description": "Optional game hosting provider identifier. Leave empty for self hosted networks. (Config file key: identity.vh_identifier)", + "Keywords": "registryvhidentifier", + "FieldName": "RegistryVhIdentifier", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "RegistryVhIdentifier", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Reported Game Version", + "Category": "Nimbus Registry:dns", + "Subcategory": "Master Server Listing:public:3", + "Description": "Vintage Story version published with the listing. Set it to the version your Stratum backends run, otherwise clients filter the network out of their list. (Config file key: identity.game_version)", + "Keywords": "registrygameversion", + "FieldName": "RegistryGameVersion", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "RegistryGameVersion", + "IncludeInCommandLine": false, + "DefaultValue": "1.22.2", + "EnumValues": {}, + "Placeholder": "1.22.6" + }, + { + "DisplayName": "Player Limit Override", + "Category": "Nimbus Registry:dns", + "Subcategory": "Master Server Listing:public:3", + "Description": "Player count published for the network. 0 publishes the sum of every live backend's own limit, which is usually right. (Config file key: identity.max_players_override)", + "Keywords": "registrymaxplayersoverride", + "FieldName": "RegistryMaxPlayersOverride", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "RegistryMaxPlayersOverride", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {}, + "MinValue": "0" + }, + { + "DisplayName": "Mod List Source", + "Category": "Nimbus Registry:dns", + "Subcategory": "Master Server Listing:public:3", + "Description": "Which mod list is published: aggregate for the union of every live backend's required client mods, explicit to publish the list below, or backend: to mirror one named backend. (Config file key: identity.mod_source)", + "Keywords": "registrymodsource", + "FieldName": "RegistryModSource", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "RegistryModSource", + "IncludeInCommandLine": false, + "DefaultValue": "aggregate", + "EnumValues": {}, + "Placeholder": "aggregate" + }, + { + "DisplayName": "Explicit Mod List", + "Category": "Nimbus Registry:dns", + "Subcategory": "Master Server Listing:public:3", + "Description": "Used only when Mod List Source is explicit. Comma separated modid=version pairs, for example nimbus=0.5.0,carryon=1.7.0. (Config file key: identity.explicit_mods)", + "Keywords": "registryexplicitmods", + "FieldName": "RegistryExplicitMods", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "RegistryExplicitMods", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Placeholder": "nimbus=0.5.0" + }, + { + "DisplayName": "Report As Whitelisted", + "Category": "Nimbus Registry:dns", + "Subcategory": "Master Server Listing:public:3", + "Description": "Flags the listing as whitelisted so players know they need to be on the list. This is a label only and enforces nothing. (Config file key: identity.whitelisted)", + "Keywords": "registrylistingwhitelisted", + "FieldName": "RegistryListingWhitelisted", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "RegistryListingWhitelisted", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Report As Password Protected", + "Category": "Nimbus Registry:dns", + "Subcategory": "Master Server Listing:public:3", + "Description": "Flags the listing as password protected. A label only; set it if the backends actually require a password. (Config file key: identity.has_password)", + "Keywords": "registrylistinghaspassword", + "FieldName": "RegistryListingHasPassword", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "RegistryListingHasPassword", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Master Server Heartbeat (seconds)", + "Category": "Nimbus Registry:dns", + "Subcategory": "Master Server Listing:public:3", + "Description": "How often the listing is refreshed. Vanilla uses 120 seconds; do not go lower. (Config file key: identity.heartbeat_interval_seconds)", + "Keywords": "registrymasterheartbeatintervalseconds", + "FieldName": "RegistryMasterHeartbeatIntervalSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "RegistryMasterHeartbeatIntervalSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "120", + "EnumValues": {}, + "MinValue": "120" + }, + { + "DisplayName": "Playstyle ID", + "Category": "Nimbus Registry:dns", + "Subcategory": "Master Server Listing:public:3", + "Description": "Playstyle id published with the listing, for example surviveandbuild, wildernesssurvival or creativebuilding. (Config file key: identity.playstyle.id)", + "Keywords": "registryplaystyleid", + "FieldName": "RegistryPlaystyleId", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "RegistryPlaystyleId", + "IncludeInCommandLine": false, + "DefaultValue": "surviveandbuild", + "EnumValues": {}, + "Placeholder": "surviveandbuild" + }, + { + "DisplayName": "Playstyle Language Code", + "Category": "Nimbus Registry:dns", + "Subcategory": "Master Server Listing:public:3", + "Description": "Translation key for the playstyle, normally preset- followed by the playstyle id. (Config file key: identity.playstyle.lang_code)", + "Keywords": "registryplaystylelangcode", + "FieldName": "RegistryPlaystyleLangCode", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "RegistryPlaystyleLangCode", + "IncludeInCommandLine": false, + "DefaultValue": "preset-surviveandbuild", + "EnumValues": {}, + "Placeholder": "preset-surviveandbuild" + } +] diff --git a/nimbus-registrymetaconfig.json b/nimbus-registrymetaconfig.json new file mode 100644 index 000000000..fe51488c7 --- /dev/null +++ b/nimbus-registrymetaconfig.json @@ -0,0 +1 @@ +[] diff --git a/nimbus-registryports.json b/nimbus-registryports.json new file mode 100644 index 000000000..4326848ea --- /dev/null +++ b/nimbus-registryports.json @@ -0,0 +1,9 @@ +[ + { + "Protocol": "TCP", + "Name": "Registry Port", + "Description": "HTTP port the registry listens on. Must be reachable from every proxy and every backend on the network, and from nowhere else.", + "Port": 8765, + "Ref": "RegistryPort" + } +] diff --git a/nimbus-registrystart.json b/nimbus-registrystart.json new file mode 100644 index 000000000..4611c2230 --- /dev/null +++ b/nimbus-registrystart.json @@ -0,0 +1,18 @@ +[ + { + "UpdateStageName": "Render nimbus.registry.toml", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"NR_WRITE='{{RegistryWriteConfig}}' NR_BIND='{{RegistryBindScheme}}:{{$RegistryPort}}' NR_SECRET='{{RegistrySharedSecret}}' NR_ACCEPTED='{{RegistryAcceptedSecrets}}' NR_STALE='{{RegistryBackendStaleSeconds}}' NR_DROP='{{RegistryBackendDropSeconds}}' NR_NONCE='{{RegistryNonceWindowSeconds}}' NR_MAXRESTTL='{{RegistryMaxReservationTtlSeconds}}' NR_LOGHB='{{RegistryLogHeartbeats}}' NR_STATEDIR='{{RegistryStateDir}}' NR_APITOK='{{RegistryApiTokensEnabled}}' NR_APIRATE='{{RegistryApiTokensRateLimitPerMinute}}' NR_APIFWD='{{RegistryApiTokensTrustForwardedProto}}' NR_I_ADVERTISE='{{RegistryAdvertiseOnMasterServer}}' NR_I_MSURL='{{RegistryMasterServerUrl}}' NR_I_HOST='{{RegistryPublicHost}}' NR_I_PORT='{{RegistryPublicPort}}' NR_I_NAME='{{RegistryServerName}}' NR_I_DESC='{{RegistryServerDescription}}' NR_I_URL='{{RegistryServerUrl}}' NR_I_ICON='{{RegistryServerIcon}}' NR_I_VHID='{{RegistryVhIdentifier}}' NR_I_GAMEVER='{{RegistryGameVersion}}' NR_I_MAXPLAYERS='{{RegistryMaxPlayersOverride}}' NR_I_MODSOURCE='{{RegistryModSource}}' NR_I_MODS='{{RegistryExplicitMods}}' NR_I_WHITELISTED='{{RegistryListingWhitelisted}}' NR_I_HASPASSWORD='{{RegistryListingHasPassword}}' NR_I_HB='{{RegistryMasterHeartbeatIntervalSeconds}}' NR_I_PSID='{{RegistryPlaystyleId}}' NR_I_PSLANG='{{RegistryPlaystyleLangCode}}' bash '{{$FullRootDir}}scripts/write-registry-toml.sh' '{{$FullRootDir}}Nimbus.Registry/nimbus.registry.toml'\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Render nimbus.registry.toml", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$env:NR_WRITE='{{RegistryWriteConfig}}'; $env:NR_BIND='{{RegistryBindScheme}}:{{$RegistryPort}}'; $env:NR_SECRET='{{RegistrySharedSecret}}'; $env:NR_ACCEPTED='{{RegistryAcceptedSecrets}}'; $env:NR_STALE='{{RegistryBackendStaleSeconds}}'; $env:NR_DROP='{{RegistryBackendDropSeconds}}'; $env:NR_NONCE='{{RegistryNonceWindowSeconds}}'; $env:NR_MAXRESTTL='{{RegistryMaxReservationTtlSeconds}}'; $env:NR_LOGHB='{{RegistryLogHeartbeats}}'; $env:NR_STATEDIR='{{RegistryStateDir}}'; $env:NR_APITOK='{{RegistryApiTokensEnabled}}'; $env:NR_APIRATE='{{RegistryApiTokensRateLimitPerMinute}}'; $env:NR_APIFWD='{{RegistryApiTokensTrustForwardedProto}}'; $env:NR_I_ADVERTISE='{{RegistryAdvertiseOnMasterServer}}'; $env:NR_I_MSURL='{{RegistryMasterServerUrl}}'; $env:NR_I_HOST='{{RegistryPublicHost}}'; $env:NR_I_PORT='{{RegistryPublicPort}}'; $env:NR_I_NAME='{{RegistryServerName}}'; $env:NR_I_DESC='{{RegistryServerDescription}}'; $env:NR_I_URL='{{RegistryServerUrl}}'; $env:NR_I_ICON='{{RegistryServerIcon}}'; $env:NR_I_VHID='{{RegistryVhIdentifier}}'; $env:NR_I_GAMEVER='{{RegistryGameVersion}}'; $env:NR_I_MAXPLAYERS='{{RegistryMaxPlayersOverride}}'; $env:NR_I_MODSOURCE='{{RegistryModSource}}'; $env:NR_I_MODS='{{RegistryExplicitMods}}'; $env:NR_I_WHITELISTED='{{RegistryListingWhitelisted}}'; $env:NR_I_HASPASSWORD='{{RegistryListingHasPassword}}'; $env:NR_I_HB='{{RegistryMasterHeartbeatIntervalSeconds}}'; $env:NR_I_PSID='{{RegistryPlaystyleId}}'; $env:NR_I_PSLANG='{{RegistryPlaystyleLangCode}}';& '{{$FullRootDir}}scripts\\write-registry-toml.ps1' '{{$FullRootDir}}Nimbus.Registry\\nimbus.registry.toml'\"", + "SkipOnFailure": false + } +] diff --git a/nimbus-registryupdates.json b/nimbus-registryupdates.json new file mode 100644 index 000000000..2823057af --- /dev/null +++ b/nimbus-registryupdates.json @@ -0,0 +1,109 @@ +[ + { + "UpdateStageName": "Create Nimbus.Registry directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}Nimbus.Registry", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create dotnet directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}dotnet", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create scripts directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}scripts", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Write Nimbus installer script (Linux)", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/install-nimbus.sh", + "UpdateSourceData": "#!/usr/bin/env bash\n# Generated by the AMP Nimbus instance template.\n# Resolves a Nimbus release and installs the requested components out of it.\n# The release zip lays out release_full/Nimbus (proxy), release_full/Nimbus.Registry\n# (standalone registry) and release_full/Nimbus.ServerMod (the Vintage Story mod).\nset -euo pipefail\n\nroot=\"${1:?root directory required}\"\ncomponents=\"${2:?component list required}\"\ncd \"$root\"\n\nrepo=\"StratumServer/Nimbus\"\nhdr=(-H \"User-Agent: AMP-Nimbus-Template\" -H \"Accept: application/vnd.github+json\")\nif [ -n \"${GITHUB_TOKEN:-}\" ]; then hdr+=(-H \"Authorization: Bearer ${GITHUB_TOKEN}\"); fi\n\nfor tool in curl unzip jq; do\n command -v \"$tool\" >/dev/null 2>&1 || { echo \"[AMP] $tool is required but not installed\" >&2; exit 1; }\ndone\n\ntag=\"$(printf '%s' \"${NIMBUS_TAG:-}\" | tr -d '[:space:]')\"\nif [ -z \"$tag\" ]; then\n echo \"[AMP] resolving Nimbus release (channel=${NIMBUS_CHANNEL:-stable})\"\n json=\"$(curl -fsSL \"${hdr[@]}\" \"https://api.github.com/repos/${repo}/releases?per_page=100\")\"\n filter='.[] | select(.draft == false)'\n if [ \"${NIMBUS_CHANNEL:-stable}\" != \"prerelease\" ]; then\n filter=\"${filter} | select(.prerelease == false)\"\n fi\n tag=\"$(printf '%s' \"$json\" | jq -r \"[ ${filter} ] | .[0].tag_name // empty\")\"\nfi\n[ -n \"$tag\" ] || { echo \"[AMP] no Nimbus release matched channel=${NIMBUS_CHANNEL:-stable}\" >&2; exit 1; }\ncase \"$tag\" in v*) ;; *) tag=\"v${tag}\";; esac\n\nmarker=\".amp-nimbus-release\"\nif [ -f \"$marker\" ] && [ \"$(cat \"$marker\")\" = \"$tag\" ]; then\n ok=1\n for comp in $components; do\n [ -d \"$comp\" ] || ok=0\n done\n if [ \"$ok\" = \"1\" ]; then\n echo \"[AMP] already on Nimbus ${tag}; nothing to download\"\n exit 0\n fi\nfi\n\nurl=\"https://github.com/${repo}/releases/download/${tag}/Nimbus-${tag}.zip\"\necho \"[AMP] downloading ${url}\"\nrm -rf .nimbus-extract\nmkdir -p .nimbus-extract\ncurl -fL --retry 3 -o nimbus-release.zip \"$url\"\nunzip -qo nimbus-release.zip -d .nimbus-extract\nrm -f nimbus-release.zip\n\nsrc=\".nimbus-extract/release_full\"\n[ -d \"$src\" ] || src=\".nimbus-extract\"\n\nfor comp in $components; do\n if [ ! -d \"$src/$comp\" ]; then\n echo \"[AMP] component $comp is not present in this release\" >&2\n exit 1\n fi\n mkdir -p \"$comp\"\n # Config, state and plugins live in the component directory, so replace program files\n # only and leave everything the operator or Nimbus itself wrote in place.\n find \"$comp\" -maxdepth 1 -type f \\( -name '*.dll' -o -name '*.pdb' -o -name '*.deps.json' \\\n -o -name '*.runtimeconfig.json' -o -name 'web.config' -o -name '*.staticwebassets.endpoints.json' \\) -delete\n cp -RL \"$src/$comp/.\" \"$comp/\"\ndone\n\nif [ -f \"Nimbus/Nimbus.Proxy\" ]; then chmod +x \"Nimbus/Nimbus.Proxy\"; fi\nif [ -f \"Nimbus.Registry/Nimbus.Registry\" ]; then chmod +x \"Nimbus.Registry/Nimbus.Registry\"; fi\nif [ -f \"$src/LICENSE\" ]; then cp -f \"$src/LICENSE\" ./LICENSE; fi\n\nrm -rf .nimbus-extract\nprintf '%s' \"$tag\" > \"$marker\"\necho \"[AMP] installed Nimbus ${tag} (${components}) into ${root}\"\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Write Nimbus installer script (Windows)", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/install-nimbus.ps1", + "UpdateSourceData": "# Generated by the AMP Nimbus instance template.\nparam(\n [Parameter(Mandatory = $true)][string]$Root,\n [Parameter(Mandatory = $true)][string]$Components\n)\n\n$ErrorActionPreference = 'Stop'\n$ProgressPreference = 'SilentlyContinue'\n[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n\n$repo = 'StratumServer/Nimbus'\n$comps = @($Components -split '[,\\s]+' | Where-Object { $_ -ne '' })\n$headers = @{ 'User-Agent' = 'AMP-Nimbus-Template'; 'Accept' = 'application/vnd.github+json' }\nif ($env:GITHUB_TOKEN) { $headers['Authorization'] = \"Bearer $($env:GITHUB_TOKEN)\" }\n\n$tag = if ($env:NIMBUS_TAG) { $env:NIMBUS_TAG.Trim() } else { '' }\nif ($tag -eq '') {\n $channel = if ($env:NIMBUS_CHANNEL) { $env:NIMBUS_CHANNEL } else { 'stable' }\n Write-Host \"[AMP] resolving Nimbus release (channel=$channel)\"\n $releases = Invoke-RestMethod -Headers $headers -Uri \"https://api.github.com/repos/$repo/releases?per_page=100\"\n $candidates = @($releases | Where-Object { -not $_.draft })\n if ($channel -ne 'prerelease') { $candidates = @($candidates | Where-Object { -not $_.prerelease }) }\n if ($candidates.Count -eq 0) { throw \"No Nimbus release matched channel=$channel\" }\n $tag = $candidates[0].tag_name\n}\nif (-not $tag.StartsWith('v')) { $tag = \"v$tag\" }\n\n$marker = Join-Path $Root '.amp-nimbus-release'\nif ((Test-Path $marker) -and ((Get-Content $marker -Raw).Trim() -eq $tag)) {\n $missing = @($comps | Where-Object { -not (Test-Path (Join-Path $Root $_)) })\n if ($missing.Count -eq 0) {\n Write-Host \"[AMP] already on Nimbus $tag; nothing to download\"\n exit 0\n }\n}\n\n$extract = Join-Path $Root '.nimbus-extract'\nif (Test-Path $extract) { Remove-Item $extract -Recurse -Force }\nNew-Item -ItemType Directory -Force -Path $extract | Out-Null\n\n$zip = Join-Path $Root 'nimbus-release.zip'\n$url = \"https://github.com/$repo/releases/download/$tag/Nimbus-$tag.zip\"\nWrite-Host \"[AMP] downloading $url\"\nInvoke-WebRequest -UseBasicParsing -Headers $headers -Uri $url -OutFile $zip\nExpand-Archive -Path $zip -DestinationPath $extract -Force\nRemove-Item $zip -Force\n\n$src = Join-Path $extract 'release_full'\nif (-not (Test-Path $src)) { $src = $extract }\n\n$programPatterns = @('*.dll', '*.pdb', '*.deps.json', '*.runtimeconfig.json', 'web.config', '*.staticwebassets.endpoints.json')\nforeach ($comp in $comps) {\n $from = Join-Path $src $comp\n if (-not (Test-Path $from)) { throw \"Component $comp is not present in this release\" }\n $to = Join-Path $Root $comp\n New-Item -ItemType Directory -Force -Path $to | Out-Null\n # Replace program files only; nimbus.proxy.toml, state files and plugins stay put.\n foreach ($pattern in $programPatterns) {\n Get-ChildItem -LiteralPath $to -Filter $pattern -File -ErrorAction SilentlyContinue | Remove-Item -Force\n }\n Copy-Item -Path (Join-Path $from '*') -Destination $to -Recurse -Force\n}\n\n$license = Join-Path $src 'LICENSE'\nif (Test-Path $license) { Copy-Item -Path $license -Destination (Join-Path $Root 'LICENSE') -Force }\n\nRemove-Item $extract -Recurse -Force\nSet-Content -Path $marker -Value $tag -NoNewline\nWrite-Host \"[AMP] installed Nimbus $tag ($Components) into $Root\"\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Write config renderer script (Linux)", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/write-registry-toml.sh", + "UpdateSourceData": "#!/usr/bin/env bash\n# Renders nimbus.registry.toml from environment variables set by AMP.\n# Generated by the AMP Nimbus instance template; edits here are overwritten on the next update.\nset -uf\n\nOUT=\"${1:-}\"\nif [ -z \"$OUT\" ]; then echo \"usage: $0 \" >&2; exit 1; fi\nif [ \"$(printf '%s' \"${NR_WRITE:-true}\" | tr 'A-Z' 'a-z')\" != \"true\" ]; then\n echo \"AMP management of $(basename \"$OUT\") is disabled, leaving the existing file alone\"\n exit 0\nfi\n\nTMP=\"$OUT.amptmp\"\nmkdir -p \"$(dirname \"$OUT\")\"\n: > \"$TMP\"\n\nesc() { printf '%s' \"${1-}\" | sed -e 's/\\\\/\\\\\\\\/g' -e 's/\"/\\\\\"/g'; }\nbl() { case \"$(printf '%s' \"${1-}\" | tr 'A-Z' 'a-z')\" in true|1|yes|on) printf 'true';; *) printf 'false';; esac }\nnum() { case \"${1-}\" in ''|*[!0-9-]*) printf '%s' \"${2-0}\";; *) printf '%s' \"$1\";; esac }\ntrim() { printf '%s' \"${1-}\" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'; }\nlst() {\n local out=\"\" first=1 x\n local IFS=','\n for x in ${1-}; do\n x=\"$(trim \"$x\")\"\n [ -z \"$x\" ] && continue\n if [ $first -eq 1 ]; then first=0; else out=\"$out, \"; fi\n out=\"$out\\\"$(esc \"$x\")\\\"\"\n done\n printf '[%s]' \"$out\"\n}\nsrv() {\n local x k v\n local IFS=','\n for x in ${1-}; do\n x=\"$(trim \"$x\")\"\n [ -z \"$x\" ] && continue\n case \"$x\" in *=*) ;; *) echo \"skipping malformed servers entry '$x' (expected id=host:port)\" >&2; continue;; esac\n k=\"$(trim \"${x%%=*}\")\"; v=\"$(trim \"${x#*=}\")\"\n if [ -z \"$k\" ] || [ -z \"$v\" ]; then\n echo \"skipping malformed servers entry '$x' (expected id=host:port)\" >&2\n continue\n fi\n printf '\"%s\" = \"%s\"\\n' \"$(esc \"$k\")\" \"$(esc \"$v\")\" >> \"$TMP\"\n done\n}\nfh() {\n local x k v\n local IFS=','\n for x in ${1-}; do\n x=\"$(trim \"$x\")\"\n [ -z \"$x\" ] && continue\n case \"$x\" in *=*) ;; *) echo \"skipping malformed forced_hosts entry '$x' (expected hostname=id1|id2)\" >&2; continue;; esac\n k=\"$(trim \"${x%%=*}\")\"; v=\"$(trim \"${x#*=}\")\"\n [ -z \"$k\" ] && continue\n printf '\"%s\" = %s\\n' \"$(esc \"$k\")\" \"$(lst \"$(printf '%s' \"$v\" | tr '|' ',')\")\" >> \"$TMP\"\n done\n}\nmods() {\n local out=\"\" first=1 x k v\n local IFS=','\n for x in ${1-}; do\n x=\"$(trim \"$x\")\"\n [ -z \"$x\" ] && continue\n case \"$x\" in\n *=*) k=\"$(trim \"${x%%=*}\")\"; v=\"$(trim \"${x#*=}\")\";;\n *) k=\"$x\"; v=\"\";;\n esac\n if [ $first -eq 1 ]; then first=0; else out=\"$out, \"; fi\n out=\"$out{ id = \\\"$(esc \"$k\")\\\", version = \\\"$(esc \"$v\")\\\" }\"\n done\n printf '[%s]' \"$out\"\n}\nkeep_secret() {\n local key=\"$1\" val=\"${2:-}\" f=\"$3\" cur=\"\"\n if [ -n \"$val\" ]; then printf '%s' \"$val\"; return; fi\n if [ -f \"$f\" ]; then\n cur=\"$(sed -n \"s/^[[:space:]]*${key}[[:space:]]*=[[:space:]]*\\\"\\(.*\\)\\\".*/\\1/p\" \"$f\" | head -n 1)\"\n case \"$cur\" in\n \"\"|change-me-and-keep-secret) ;;\n *) printf '%s' \"$cur\"; return;;\n esac\n fi\n echo \"[AMP] no ${key} set, generating a random one; read it out of $(basename \"$f\") and paste it into every backend\" >&2\n head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \\n'\n}\nprintf 'bind_url = \"%s\"\\n' \"$(esc \"${NR_BIND:-http://0.0.0.0:8765}\")\" >> \"$TMP\"\nprintf 'shared_secret = \"%s\"\\n' \"$(esc \"$(keep_secret shared_secret \"${NR_SECRET:-}\" \"$OUT\")\")\" >> \"$TMP\"\nprintf 'accepted_secrets = %s\\n' \"$(lst \"${NR_ACCEPTED:-}\")\" >> \"$TMP\"\nprintf 'backend_stale_seconds = %s\\n' \"$(num \"${NR_STALE:-20}\" 20)\" >> \"$TMP\"\nprintf 'backend_drop_seconds = %s\\n' \"$(num \"${NR_DROP:-120}\" 120)\" >> \"$TMP\"\nprintf 'nonce_window_seconds = %s\\n' \"$(num \"${NR_NONCE:-90}\" 90)\" >> \"$TMP\"\nprintf 'max_reservation_ttl_seconds = %s\\n' \"$(num \"${NR_MAXRESTTL:-300}\" 300)\" >> \"$TMP\"\nprintf 'log_heartbeats = %s\\n' \"$(bl \"${NR_LOGHB:-false}\")\" >> \"$TMP\"\nprintf 'state_dir = \"%s\"\\n' \"$(esc \"${NR_STATEDIR:-.}\")\" >> \"$TMP\"\nprintf '\\n[api_tokens]\\n' >> \"$TMP\"\nprintf 'enabled = %s\\n' \"$(bl \"${NR_APITOK:-false}\")\" >> \"$TMP\"\nprintf 'rate_limit_per_minute = %s\\n' \"$(num \"${NR_APIRATE:-60}\" 60)\" >> \"$TMP\"\nprintf 'trust_forwarded_proto = %s\\n' \"$(bl \"${NR_APIFWD:-false}\")\" >> \"$TMP\"\nprintf '\\n[identity]\\n' >> \"$TMP\"\nprintf 'advertise_on_master_server = %s\\n' \"$(bl \"${NR_I_ADVERTISE:-false}\")\" >> \"$TMP\"\nprintf 'master_server_url = \"%s\"\\n' \"$(esc \"${NR_I_MSURL:-http://masterserver.vintagestory.at/api/v1/servers/}\")\" >> \"$TMP\"\nprintf 'public_host = \"%s\"\\n' \"$(esc \"${NR_I_HOST:-127.0.0.1}\")\" >> \"$TMP\"\nprintf 'public_port = %s\\n' \"$(num \"${NR_I_PORT:-42420}\" 42420)\" >> \"$TMP\"\nprintf 'server_name = \"%s\"\\n' \"$(esc \"${NR_I_NAME:-Nimbus Network}\")\" >> \"$TMP\"\nprintf 'server_description = \"%s\"\\n' \"$(esc \"${NR_I_DESC:-}\")\" >> \"$TMP\"\nprintf 'server_url = \"%s\"\\n' \"$(esc \"${NR_I_URL:-}\")\" >> \"$TMP\"\nprintf 'server_icon = \"%s\"\\n' \"$(esc \"${NR_I_ICON:-}\")\" >> \"$TMP\"\nprintf 'vh_identifier = \"%s\"\\n' \"$(esc \"${NR_I_VHID:-}\")\" >> \"$TMP\"\nprintf 'game_version = \"%s\"\\n' \"$(esc \"${NR_I_GAMEVER:-1.22.2}\")\" >> \"$TMP\"\nprintf 'max_players_override = %s\\n' \"$(num \"${NR_I_MAXPLAYERS:-0}\" 0)\" >> \"$TMP\"\nprintf 'mod_source = \"%s\"\\n' \"$(esc \"${NR_I_MODSOURCE:-aggregate}\")\" >> \"$TMP\"\nprintf 'explicit_mods = %s\\n' \"$(mods \"${NR_I_MODS:-}\")\" >> \"$TMP\"\nprintf 'whitelisted = %s\\n' \"$(bl \"${NR_I_WHITELISTED:-false}\")\" >> \"$TMP\"\nprintf 'has_password = %s\\n' \"$(bl \"${NR_I_HASPASSWORD:-false}\")\" >> \"$TMP\"\nprintf 'heartbeat_interval_seconds = %s\\n' \"$(num \"${NR_I_HB:-120}\" 120)\" >> \"$TMP\"\nprintf '\\n[identity.playstyle]\\n' >> \"$TMP\"\nprintf 'id = \"%s\"\\n' \"$(esc \"${NR_I_PSID:-surviveandbuild}\")\" >> \"$TMP\"\nprintf 'lang_code = \"%s\"\\n' \"$(esc \"${NR_I_PSLANG:-preset-surviveandbuild}\")\" >> \"$TMP\"\nmv -f \"$TMP\" \"$OUT\"\necho \"wrote $OUT\"\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Write config renderer script (Windows)", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/write-registry-toml.ps1", + "UpdateSourceData": "# Renders nimbus.registry.toml from environment variables set by AMP.\n# Generated by the AMP Nimbus instance template; edits here are overwritten on the next update.\nparam([Parameter(Mandatory = $true)][string]$Out)\n$ErrorActionPreference = 'Stop'\n\nfunction D([string]$v, [string]$d) { if ([string]::IsNullOrWhiteSpace($v)) { return $d } return $v }\nfunction Esc([string]$s) { if ($null -eq $s) { return '' } return $s.Replace('\\', '\\\\').Replace('\"', '\\\"') }\nfunction B([string]$s) { if ($null -eq $s) { return 'false' } if (@('true', '1', 'yes', 'on') -contains $s.Trim().ToLowerInvariant()) { return 'true' } return 'false' }\nfunction I([string]$s, [int]$d) { $n = 0; if ([int]::TryParse(($s -replace '\\s', ''), [ref]$n)) { return \"$n\" } return \"$d\" }\nfunction L([string]$s) {\n $parts = @()\n foreach ($x in ($s -split ',')) { $t = $x.Trim(); if ($t -ne '') { $parts += ('\"' + (Esc $t) + '\"') } }\n return '[' + ($parts -join ', ') + ']'\n}\nfunction Pair([string]$x) {\n $i = $x.IndexOf('=')\n if ($i -lt 1) { return $null }\n return @{ Key = $x.Substring(0, $i).Trim(); Value = $x.Substring($i + 1).Trim() }\n}\nfunction SrvLines($list, [string]$s) {\n foreach ($x in ($s -split ',')) {\n $t = $x.Trim(); if ($t -eq '') { continue }\n $p = Pair $t\n if ($null -eq $p -or $p.Key -eq '' -or $p.Value -eq '') { Write-Output \"skipping malformed servers entry '$t' (expected id=host:port)\"; continue }\n $list.Add('\"' + (Esc $p.Key) + '\" = \"' + (Esc $p.Value) + '\"')\n }\n}\nfunction FhLines($list, [string]$s) {\n foreach ($x in ($s -split ',')) {\n $t = $x.Trim(); if ($t -eq '') { continue }\n $p = Pair $t\n if ($null -eq $p -or $p.Key -eq '') { Write-Output \"skipping malformed forced_hosts entry '$t' (expected hostname=id1|id2)\"; continue }\n $list.Add('\"' + (Esc $p.Key) + '\" = ' + (L ($p.Value -replace '\\|', ',')))\n }\n}\nfunction Mods([string]$s) {\n $parts = @()\n foreach ($x in ($s -split ',')) {\n $t = $x.Trim(); if ($t -eq '') { continue }\n $p = Pair $t\n if ($null -eq $p) { $parts += ('{ id = \"' + (Esc $t) + '\", version = \"\" }') }\n else { $parts += ('{ id = \"' + (Esc $p.Key) + '\", version = \"' + (Esc $p.Value) + '\" }') }\n }\n return '[' + ($parts -join ', ') + ']'\n}\nfunction KeepSecret([string]$key, [string]$val, [string]$file) {\n if (-not [string]::IsNullOrWhiteSpace($val)) { return $val }\n if (Test-Path -LiteralPath $file) {\n $pattern = '^\\s*' + [regex]::Escape($key) + '\\s*=\\s*\"(.*)\"'\n $m = Select-String -LiteralPath $file -Pattern $pattern | Select-Object -First 1\n if ($m) {\n $cur = $m.Matches[0].Groups[1].Value\n if ($cur -ne '' -and $cur -ne 'change-me-and-keep-secret') { return $cur }\n }\n }\n Write-Host (\"[AMP] no $key set, generating a random one; read it out of \" + (Split-Path -Leaf $file) + \" and paste it into every backend\")\n $bytes = New-Object byte[] 32\n $rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()\n $rng.GetBytes($bytes)\n return (($bytes | ForEach-Object { $_.ToString('x2') }) -join '')\n}\n\nif ((B (D $env:NR_WRITE 'true')) -ne 'true') {\n Write-Output (\"AMP management of \" + (Split-Path -Leaf $Out) + \" is disabled, leaving the existing file alone\")\n exit 0\n}\n\n$dir = Split-Path -Parent $Out\nif ($dir -and -not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }\n$L = New-Object System.Collections.Generic.List[string]\n$L.Add('bind_url = \"' + (Esc (D $env:NR_BIND 'http://0.0.0.0:8765')) + '\"')\n$L.Add('shared_secret = \"' + (Esc (KeepSecret 'shared_secret' $env:NR_SECRET $Out)) + '\"')\n$L.Add('accepted_secrets = ' + (L (D $env:NR_ACCEPTED '')))\n$L.Add('backend_stale_seconds = ' + (I (D $env:NR_STALE '20') 20))\n$L.Add('backend_drop_seconds = ' + (I (D $env:NR_DROP '120') 120))\n$L.Add('nonce_window_seconds = ' + (I (D $env:NR_NONCE '90') 90))\n$L.Add('max_reservation_ttl_seconds = ' + (I (D $env:NR_MAXRESTTL '300') 300))\n$L.Add('log_heartbeats = ' + (B (D $env:NR_LOGHB 'false')))\n$L.Add('state_dir = \"' + (Esc (D $env:NR_STATEDIR '.')) + '\"')\n$L.Add('')\n$L.Add('[api_tokens]')\n$L.Add('enabled = ' + (B (D $env:NR_APITOK 'false')))\n$L.Add('rate_limit_per_minute = ' + (I (D $env:NR_APIRATE '60') 60))\n$L.Add('trust_forwarded_proto = ' + (B (D $env:NR_APIFWD 'false')))\n$L.Add('')\n$L.Add('[identity]')\n$L.Add('advertise_on_master_server = ' + (B (D $env:NR_I_ADVERTISE 'false')))\n$L.Add('master_server_url = \"' + (Esc (D $env:NR_I_MSURL 'http://masterserver.vintagestory.at/api/v1/servers/')) + '\"')\n$L.Add('public_host = \"' + (Esc (D $env:NR_I_HOST '127.0.0.1')) + '\"')\n$L.Add('public_port = ' + (I (D $env:NR_I_PORT '42420') 42420))\n$L.Add('server_name = \"' + (Esc (D $env:NR_I_NAME 'Nimbus Network')) + '\"')\n$L.Add('server_description = \"' + (Esc (D $env:NR_I_DESC '')) + '\"')\n$L.Add('server_url = \"' + (Esc (D $env:NR_I_URL '')) + '\"')\n$L.Add('server_icon = \"' + (Esc (D $env:NR_I_ICON '')) + '\"')\n$L.Add('vh_identifier = \"' + (Esc (D $env:NR_I_VHID '')) + '\"')\n$L.Add('game_version = \"' + (Esc (D $env:NR_I_GAMEVER '1.22.2')) + '\"')\n$L.Add('max_players_override = ' + (I (D $env:NR_I_MAXPLAYERS '0') 0))\n$L.Add('mod_source = \"' + (Esc (D $env:NR_I_MODSOURCE 'aggregate')) + '\"')\n$L.Add('explicit_mods = ' + (Mods (D $env:NR_I_MODS '')))\n$L.Add('whitelisted = ' + (B (D $env:NR_I_WHITELISTED 'false')))\n$L.Add('has_password = ' + (B (D $env:NR_I_HASPASSWORD 'false')))\n$L.Add('heartbeat_interval_seconds = ' + (I (D $env:NR_I_HB '120') 120))\n$L.Add('')\n$L.Add('[identity.playstyle]')\n$L.Add('id = \"' + (Esc (D $env:NR_I_PSID 'surviveandbuild')) + '\"')\n$L.Add('lang_code = \"' + (Esc (D $env:NR_I_PSLANG 'preset-surviveandbuild')) + '\"')\n$tmp = \"$Out.amptmp\"\nSet-Content -LiteralPath $tmp -Value $L -Encoding UTF8\nMove-Item -LiteralPath $tmp -Destination $Out -Force\nWrite-Output \"wrote $Out\"\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": ".NET SDK Download", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "Executable", + "UpdateSourceArch": "x86_64", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"DotnetVersion=\\\"{{DotnetSDKVersion}}\\\"; cd \\\"{{$FullBaseDir}}\\\" && if [[ -x dotnet/dotnet ]]; then InstalledVersion=$(dotnet/dotnet --version | xargs); else InstalledVersion=\\\"\\\"; fi; if [[ -z \\\"$DotnetVersion\\\" ]]; then DotnetVersion=$(wget -qO- https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json | jq -r \\\".[\\\\\\\"latest-sdk\\\\\\\"]\\\"); fi; if [[ ! \\\"$DotnetVersion\\\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+$ ]]; then echo \\\"Invalid .NET SDK version format specified\\\" && exit 1; elif [[ \\\"$InstalledVersion\\\" == \\\"$DotnetVersion\\\" ]]; then echo \\\".NET SDK v$DotnetVersion already installed. Skipping\\\" && exit 0; else [[ -f dotnet.tar.gz ]] && rm -f dotnet.tar.gz >/dev/null 2>&1; wget -qO dotnet.tar.gz https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-linux-x64.tar.gz || { echo \\\"Download failed from the Microsoft CDN. This is a fault with the CDN, not AMP. Aborting\\\"; exit 1; }; rm -rf dotnet/* >/dev/null 2>&1 && tar -xzf dotnet.tar.gz -C dotnet >/dev/null 2>&1 && rm -f dotnet.tar.gz >/dev/null 2>&1 && echo \\\".NET SDK v$DotnetVersion downloaded\\\"; fi\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": ".NET SDK Download", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -Command \"$ProgressPreference='SilentlyContinue'; [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $DotnetVersion='{{DotnetSDKVersion}}'; Set-Location -Path '{{$FullBaseDir}}'; if (Test-Path 'dotnet/dotnet.exe') { $InstalledVersion = (& dotnet/dotnet.exe --version).Trim() } else { $InstalledVersion = '' }; if ( [string]::IsNullOrWhiteSpace($DotnetVersion) ) { $DotnetVersion=(Invoke-RestMethod -UseBasicParsing -Uri https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json).\\\"latest-sdk\\\" }; if ($DotnetVersion -notmatch '^\\d+\\.\\d+\\.\\d+$') { Write-Output \\\"Invalid .NET SDK version format specified\\\"; exit 1 } elseif ( $InstalledVersion -eq $DotnetVersion ) { Write-Output \\\".NET SDK v$DotnetVersion already installed. Skipping\\\"; exit 0 } else { if ( Test-Path dotnet.zip ) { Remove-Item dotnet.zip -Force -ErrorAction SilentlyContinue *> $null }; try { Invoke-WebRequest -UseBasicParsing -Uri https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-win-x64.zip -OutFile dotnet.zip -ErrorAction Stop } catch { Write-Output \\\"Download failed from the Microsoft CDN. This is a fault with the CDN, not AMP. Aborting\\\"; exit 1; }; Remove-Item -Path 'dotnet/*' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive -Path \\\"dotnet.zip\\\" -DestinationPath \\\"dotnet\\\" -Force *> $null; if ( Test-Path dotnet.zip ) { Remove-Item dotnet.zip -Force -ErrorAction SilentlyContinue *> $null }; Write-Output \\\".NET SDK v$DotnetVersion downloaded\\\" }\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Nimbus Download", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "Executable", + "UpdateSourceArch": "x86_64", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"NIMBUS_TAG='{{NimbusVersionTag}}' NIMBUS_CHANNEL='{{NimbusReleaseChannel}}' GITHUB_TOKEN='{{NimbusGitHubToken}}' bash '{{$FullRootDir}}scripts/install-nimbus.sh' '{{$FullRootDir}}' '{{NimbusUpdateComponents}}'\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Nimbus Download", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$env:NIMBUS_TAG='{{NimbusVersionTag}}'; $env:NIMBUS_CHANNEL='{{NimbusReleaseChannel}}'; $env:GITHUB_TOKEN='{{NimbusGitHubToken}}'; & '{{$FullRootDir}}scripts\\install-nimbus.ps1' '{{$FullRootDir}}' '{{NimbusUpdateComponents}}'\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Render nimbus.registry.toml", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"NR_WRITE='{{RegistryWriteConfig}}' NR_BIND='{{RegistryBindScheme}}:{{$RegistryPort}}' NR_SECRET='{{RegistrySharedSecret}}' NR_ACCEPTED='{{RegistryAcceptedSecrets}}' NR_STALE='{{RegistryBackendStaleSeconds}}' NR_DROP='{{RegistryBackendDropSeconds}}' NR_NONCE='{{RegistryNonceWindowSeconds}}' NR_MAXRESTTL='{{RegistryMaxReservationTtlSeconds}}' NR_LOGHB='{{RegistryLogHeartbeats}}' NR_STATEDIR='{{RegistryStateDir}}' NR_APITOK='{{RegistryApiTokensEnabled}}' NR_APIRATE='{{RegistryApiTokensRateLimitPerMinute}}' NR_APIFWD='{{RegistryApiTokensTrustForwardedProto}}' NR_I_ADVERTISE='{{RegistryAdvertiseOnMasterServer}}' NR_I_MSURL='{{RegistryMasterServerUrl}}' NR_I_HOST='{{RegistryPublicHost}}' NR_I_PORT='{{RegistryPublicPort}}' NR_I_NAME='{{RegistryServerName}}' NR_I_DESC='{{RegistryServerDescription}}' NR_I_URL='{{RegistryServerUrl}}' NR_I_ICON='{{RegistryServerIcon}}' NR_I_VHID='{{RegistryVhIdentifier}}' NR_I_GAMEVER='{{RegistryGameVersion}}' NR_I_MAXPLAYERS='{{RegistryMaxPlayersOverride}}' NR_I_MODSOURCE='{{RegistryModSource}}' NR_I_MODS='{{RegistryExplicitMods}}' NR_I_WHITELISTED='{{RegistryListingWhitelisted}}' NR_I_HASPASSWORD='{{RegistryListingHasPassword}}' NR_I_HB='{{RegistryMasterHeartbeatIntervalSeconds}}' NR_I_PSID='{{RegistryPlaystyleId}}' NR_I_PSLANG='{{RegistryPlaystyleLangCode}}' bash '{{$FullRootDir}}scripts/write-registry-toml.sh' '{{$FullRootDir}}Nimbus.Registry/nimbus.registry.toml'\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Render nimbus.registry.toml", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$env:NR_WRITE='{{RegistryWriteConfig}}'; $env:NR_BIND='{{RegistryBindScheme}}:{{$RegistryPort}}'; $env:NR_SECRET='{{RegistrySharedSecret}}'; $env:NR_ACCEPTED='{{RegistryAcceptedSecrets}}'; $env:NR_STALE='{{RegistryBackendStaleSeconds}}'; $env:NR_DROP='{{RegistryBackendDropSeconds}}'; $env:NR_NONCE='{{RegistryNonceWindowSeconds}}'; $env:NR_MAXRESTTL='{{RegistryMaxReservationTtlSeconds}}'; $env:NR_LOGHB='{{RegistryLogHeartbeats}}'; $env:NR_STATEDIR='{{RegistryStateDir}}'; $env:NR_APITOK='{{RegistryApiTokensEnabled}}'; $env:NR_APIRATE='{{RegistryApiTokensRateLimitPerMinute}}'; $env:NR_APIFWD='{{RegistryApiTokensTrustForwardedProto}}'; $env:NR_I_ADVERTISE='{{RegistryAdvertiseOnMasterServer}}'; $env:NR_I_MSURL='{{RegistryMasterServerUrl}}'; $env:NR_I_HOST='{{RegistryPublicHost}}'; $env:NR_I_PORT='{{RegistryPublicPort}}'; $env:NR_I_NAME='{{RegistryServerName}}'; $env:NR_I_DESC='{{RegistryServerDescription}}'; $env:NR_I_URL='{{RegistryServerUrl}}'; $env:NR_I_ICON='{{RegistryServerIcon}}'; $env:NR_I_VHID='{{RegistryVhIdentifier}}'; $env:NR_I_GAMEVER='{{RegistryGameVersion}}'; $env:NR_I_MAXPLAYERS='{{RegistryMaxPlayersOverride}}'; $env:NR_I_MODSOURCE='{{RegistryModSource}}'; $env:NR_I_MODS='{{RegistryExplicitMods}}'; $env:NR_I_WHITELISTED='{{RegistryListingWhitelisted}}'; $env:NR_I_HASPASSWORD='{{RegistryListingHasPassword}}'; $env:NR_I_HB='{{RegistryMasterHeartbeatIntervalSeconds}}'; $env:NR_I_PSID='{{RegistryPlaystyleId}}'; $env:NR_I_PSLANG='{{RegistryPlaystyleLangCode}}';& '{{$FullRootDir}}scripts\\write-registry-toml.ps1' '{{$FullRootDir}}Nimbus.Registry\\nimbus.registry.toml'\"", + "SkipOnFailure": false + } +] diff --git a/vintage-story-stratum.kvp b/vintage-story-stratum.kvp new file mode 100644 index 000000000..86725ad8e --- /dev/null +++ b/vintage-story-stratum.kvp @@ -0,0 +1,96 @@ +Meta.DisplayName=Vintage Story (Stratum + Nimbus) +Meta.Description=Vintage Story dedicated server running the Stratum performance/hardening fork, with the Nimbus backend mod for multi-server networks. Stratum releases pin the exact Vintage Story version and download the matching vanilla assets automatically. +Meta.OS=Windows, Linux +Meta.AarchSupport=None +Meta.Arch=x86_64 +Meta.Author=HuguesDePayens +Meta.URL=https://github.com/StratumServer/Stratum +Meta.DisplayImageSource=url:https://wiki.vintagestory.at/images/thumb/8/8a/Gamelogo-vintagestory.png/340px-Gamelogo-vintagestory.png +Meta.EndpointURIFormat= +Meta.ConfigManifest=vintage-story-stratumconfig.json +Meta.MetaConfigManifest=vintage-story-stratummetaconfig.json +Meta.ConfigRoot=vintage-story-stratum.kvp +Meta.MinAMPVersion=2.4.6.0 +Meta.SpecificDockerImage=cubecoders/ampbase:debian +Meta.DockerRequired=False +Meta.ContainerPolicy=Supported +Meta.ExtraContainerPackages=["jq","unzip","curl","ca-certificates"] +Meta.Prerequisites=[] +Meta.ConfigReleaseState=NotSpecified +Meta.NoCommercialUsage=False +Meta.ConfigVersion=1 +Meta.AppConfigId=7f3b1c42-5d18-4a6e-9b21-2c7f5ea41d90 +Meta.AppIsMultiIPAware=True +Meta.ResourceUsageInfo=2 CPU cores and 4GB RAM minimum per backend server, 4 cores and 8GB recommended for busy worlds +Meta.ImportableExtensions=[] +App.DisplayName=Vintage Story (Stratum) +App.RootDir=./vintage-story/ +App.BaseDirectory=./vintage-story/ +App.ExecutableWin=server\StratumServer.exe +App.ExecutableLinux=server/StratumServer +App.WorkingDir=server +App.LinuxCommandLineArgs= +App.WindowsCommandLineArgs= +App.CommandLineArgs={{$PlatformArgs}} --port {{$ServerPort}} --dataPath "../data" {{StratumExtraArgs}} {{$FormattedArgs}} +App.UseLinuxIOREDIR=False +App.AppSettings={} +App.EnvironmentVariables={"DOTNET_ROOT":"{{$FullRootDir}}dotnet","DOTNET_CLI_TELEMETRY_OPTOUT":"1","DOTNET_NOLOGO":"1"} +App.CommandLineParameterFormat=--{0} {1} +App.CommandLineParameterDelimiter= +App.ExitMethod=String +App.ExitTimeout=45 +App.ExitString=/stop +App.ExitFile=lock +App.HasWriteableConsole=True +App.HasReadableConsole=True +App.SupportsLiveSettingsChanges=False +App.LiveSettingChangeCommandFormat=set {0} "{1}" +App.ApplicationIPBinding=0.0.0.0 +App.Ports=@IncludeJson[vintage-story-stratumports.json] +App.AdminPortRef=ServerPort +App.PrimaryApplicationPortRef=ServerPort +App.UniversalSleepApplicationUDPPortRef=ServerPort +App.UniversalSleepSteamQueryPortRef=ServerPort +App.MaxUsers=16 +App.UseRandomAdminPassword=False +App.RemoteAdminPassword=Password123 +App.AdminMethod=STDIO +App.AdminLoginTransform=None +App.RCONConnectDelaySeconds=5 +App.RCONConnectRetrySeconds=5 +App.RCONHeartbeatMinutes=0 +App.RCONHeartbeatCommand=ping +App.TelnetLoginFormat={0} +App.PreStartStages=@IncludeJson[vintage-story-stratumstart.json] +App.UpdateSources=@IncludeJson[vintage-story-stratumupdates.json] +App.Compatibility=None +App.SteamUpdateAnonymousLogin=True +App.SteamForceLoginPrompt=False +App.RapidStartup=False +App.SmartExcludeSupported=True +App.SmartExcludeExemptions=["*.cfg","*.conf","*.config","*.ini","*.json","*.xml","*.properties","*.kvp","*.yml","*.yaml","*.toml","*.lua","*.vcdbs"] +App.MonitorChildProcess=True +App.MonitorChildProcessWaitMs=100 +App.MonitorChildProcessName= +App.SupportsUniversalSleep=False +App.WakeupMode=Any +App.ApplicationReadyMode=RegexMatch +App.StripANSIControlCodes=True +Console.FilterMatchRegex=|<\/font> +Console.FilterMatchReplacement= +Console.ThrowawayMessageRegex=^(WARNING|ERROR): Shader.+$ +Console.AppReadyRegex=^[\d\.]*\s*[\d:\.]+ \[.*Event\] (?:Dedicated Server|Serveur dédié|Dedizierter Server) now running on Port \d+ and (?:all ips|ip .*)!$ +Console.UserJoinRegex=^[\d\.]*\s*[\d:\.]+ \[.*Event\] (?.+?) [\[\]a-f\d:.]+ joins\.$ +Console.UserLeaveRegex=^[\d\.]*\s*[\d:\.]+ \[.*Event\] Player (?.+?) (left|got removed\. Reason: Server shutting down - Shutdown via server command).*$ +Console.UserChatRegex=^[\d\.]*\s*[\d:\.]+ \[.*Chat\] (?.+?): (?.+?): (?.+)$ +Console.UpdateAvailableRegex=^.*(?:A new server update is available!|UPDATE AVAILABLE: running ).*$ +Console.MetricsRegex= +Console.SuppressLogAtStart=False +Console.ActivateLogRegex= +Console.UserActions={} +Limits.SleepMode=True +Limits.SleepOnStart=False +Limits.SleepDelayMinutes=5 +Limits.DozeDelay=2 +Limits.AutoRetryCount=2 +Limits.SleepStartThresholdSeconds=25 diff --git a/vintage-story-stratumconfig.json b/vintage-story-stratumconfig.json new file mode 100644 index 000000000..986c6ed50 --- /dev/null +++ b/vintage-story-stratumconfig.json @@ -0,0 +1,9795 @@ +[ + { + "DisplayName": "Port", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Game port. Managed by AMP - change it under Configuration -> Network, not here.", + "Keywords": "port", + "FieldName": "$ServerPort", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Port", + "IncludeInCommandLine": false, + "DefaultValue": "42420", + "EnumValues": {}, + "Hidden": true + }, + { + "DisplayName": "Server Name", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Server name shown in the server browser and to the Nimbus network.", + "Keywords": "server,name", + "FieldName": "VS_ServerName", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.ServerName", + "IncludeInCommandLine": false, + "DefaultValue": "Vintage Story Server - Powered by AMP", + "EnumValues": {} + }, + { + "DisplayName": "Server Description", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Longer description shown in the server browser. VTML markup is supported.", + "Keywords": "description,motd", + "FieldName": "VS_ServerDescription", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.ServerDescription", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Server URL", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Website shown alongside the server listing.", + "Keywords": "url,website", + "FieldName": "VS_ServerUrl", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.ServerUrl", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Welcome Message", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Message sent when a player joins. {0} is replaced with the player name. Must not be empty on 1.19 and below.", + "Keywords": "welcome,message,motd", + "FieldName": "VS_WelcomeMessage", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.WelcomeMessage", + "IncludeInCommandLine": false, + "DefaultValue": "Welcome, {0}, may you survive well and prosper", + "EnumValues": {} + }, + { + "DisplayName": "Server Password", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Password players must enter. Leave empty for an open server. On a Nimbus network set this on the proxy instead.", + "Keywords": "password", + "FieldName": "VS_Password", + "InputType": "password", + "IsFlagArgument": false, + "ParamFieldName": "$.Password", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Make Server Public", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Publish this server to the public server list. On a Nimbus network leave this OFF for backends and let the proxy or registry advertise the network instead.", + "Keywords": "public,advertise", + "FieldName": "VS_AdvertiseServer", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.AdvertiseServer", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Master Server URL", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Master server used for the public listing. Only change this when self-hosting a master server. Keep the trailing slash.", + "Keywords": "masterserver", + "FieldName": "VS_MasterserverUrl", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.MasterserverUrl", + "IncludeInCommandLine": false, + "DefaultValue": "http://masterserver.vintagestory.at/api/v1/servers/", + "EnumValues": {} + }, + { + "DisplayName": "Mod DB URL", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Mod database used by the server for mod lookups.", + "Keywords": "moddb", + "FieldName": "VS_ModDbUrl", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.ModDbUrl", + "IncludeInCommandLine": false, + "DefaultValue": "https://mods.vintagestory.at/", + "EnumValues": {} + }, + { + "DisplayName": "Compress Packets", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Compress network packets. Leave on unless profiling says otherwise.", + "Keywords": "compress,packets", + "FieldName": "VS_CompressPackets", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.CompressPackets", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enable UPnP", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Ask the router to forward the game port automatically. Leave off on hosted machines.", + "Keywords": "upnp", + "FieldName": "VS_Upnp", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Upnp", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "UPnP Infinite Lifetime", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Request a port mapping with no expiry instead of a renewed lease.", + "Keywords": "upnp,lifetime", + "FieldName": "VS_UpnpInfiniteLifetime", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.UpnpInfiniteLifetime", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Player Limit", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Players:group:2", + "Description": "Maximum number of players allowed on this server.", + "Keywords": "players,limit,slots", + "FieldName": "$MaxUsers", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.MaxClients", + "IncludeInCommandLine": false, + "DefaultValue": "16", + "EnumValues": {}, + "Suffix": "players", + "MinValue": "1" + }, + { + "DisplayName": "Queue Size", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Players:group:2", + "Description": "How many extra players may wait in the connection queue when the server is full. 0 disables the queue.", + "Keywords": "queue", + "FieldName": "VS_MaxClientsInQueue", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.MaxClientsInQueue", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {}, + "Suffix": "players", + "MinValue": "0" + }, + { + "DisplayName": "Whitelist Mode", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Players:group:2", + "Description": "Whitelist behaviour on 1.20+. Default means on for dedicated servers.", + "Keywords": "whitelist", + "FieldName": "VS_WhitelistMode", + "InputType": "enum", + "IsFlagArgument": false, + "ParamFieldName": "$.WhitelistMode", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": { + "0": "Default", + "1": "Off", + "2": "On" + } + }, + { + "DisplayName": "Enable Whitelist (Legacy)", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Players:group:2", + "Description": "Legacy whitelist switch for 1.19 and below. Ignored on 1.20+.", + "Keywords": "whitelist,legacy", + "FieldName": "VS_OnlyWhitelisted", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.OnlyWhitelisted", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Verify Player Auth", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Players:group:2", + "Description": "Require players to be authenticated game owners. Turning this off allows cracked clients.", + "Keywords": "auth,verify", + "FieldName": "VS_VerifyPlayerAuth", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.VerifyPlayerAuth", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Login Flood Protection", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Players:group:2", + "Description": "Rate limit repeated connection attempts from the same address.", + "Keywords": "login,flood", + "FieldName": "VS_LoginFloodProtection", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.LoginFloodProtection", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Temporary IP Block List", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Players:group:2", + "Description": "Temporarily block addresses that trip abuse protection.", + "Keywords": "ip,block", + "FieldName": "VS_TemporaryIpBlockList", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.TemporaryIpBlockList", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Client Connection Timeout", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Players:group:2", + "Description": "Seconds without traffic before a client is dropped.", + "Keywords": "timeout", + "FieldName": "VS_ClientConnectionTimeout", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ClientConnectionTimeout", + "IncludeInCommandLine": false, + "DefaultValue": "150", + "EnumValues": {}, + "Suffix": "seconds", + "MinValue": "10" + }, + { + "DisplayName": "AFK Warn After", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Players:group:2", + "Description": "Warn a player after this many idle seconds. 0 disables AFK warnings.", + "Keywords": "afk,warn", + "FieldName": "VS_WarnClientsAfterAfkSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.WarnClientsAfterAfkSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {}, + "Suffix": "seconds", + "MinValue": "0" + }, + { + "DisplayName": "AFK Kick After", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Players:group:2", + "Description": "Kick a player after this many idle seconds. 0 disables AFK kicking.", + "Keywords": "afk,kick", + "FieldName": "VS_KickClientsAfterAfkSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.KickClientsAfterAfkSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {}, + "Suffix": "seconds", + "MinValue": "0" + }, + { + "DisplayName": "Anti Abuse Level", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Players:group:2", + "Description": "Vanilla abuse protection level. Stratum's own anticheat is configured under the Stratum categories and is far more granular.", + "Keywords": "antiabuse,cheat", + "FieldName": "VS_AntiAbuse", + "InputType": "enum", + "IsFlagArgument": false, + "ParamFieldName": "$.AntiAbuse", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": { + "0": "0 - Off", + "1": "1 - Basic", + "2": "2 - Strict" + } + }, + { + "DisplayName": "Group Chat History Size", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Players:group:2", + "Description": "Number of group chat messages kept in history.", + "Keywords": "chat,group,history", + "FieldName": "VS_GroupChatHistorySize", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.GroupChatHistorySize", + "IncludeInCommandLine": false, + "DefaultValue": "20", + "EnumValues": {}, + "MinValue": "0" + }, + { + "DisplayName": "Max Group Channels Per Player", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Players:group:2", + "Description": "How many chat groups a single player may own.", + "Keywords": "chat,group,channels", + "FieldName": "VS_MaxOwnedGroupChannelsPerUser", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.MaxOwnedGroupChannelsPerUser", + "IncludeInCommandLine": false, + "DefaultValue": "10", + "EnumValues": {}, + "MinValue": "0" + }, + { + "DisplayName": "Allow PvP", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Gameplay:sports_esports:3", + "Description": "Allow players to damage each other.", + "Keywords": "pvp", + "FieldName": "VS_AllowPvP", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.AllowPvP", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Allow Fire Spread", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Gameplay:sports_esports:3", + "Description": "Allow fire to spread to neighbouring blocks.", + "Keywords": "fire", + "FieldName": "VS_AllowFireSpread", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.AllowFireSpread", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Allow Falling Blocks", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Gameplay:sports_esports:3", + "Description": "Allow gravity-affected blocks to fall.", + "Keywords": "gravity,blocks", + "FieldName": "VS_AllowFallingBlocks", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.AllowFallingBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Pass Time When Empty", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Gameplay:sports_esports:3", + "Description": "Keep advancing world time while no players are online.", + "Keywords": "time,empty", + "FieldName": "VS_PassTimeWhenEmpty", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.PassTimeWhenEmpty", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Entity Debug Mode", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Gameplay:sports_esports:3", + "Description": "Send entity debug information to clients.", + "Keywords": "debug,entity", + "FieldName": "VS_EntityDebugMode", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityDebugMode", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Startup Commands", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Gameplay:sports_esports:3", + "Description": "Server commands run on every start, separated by \\n. Example: /time set 8:00\\n/weather clear", + "Keywords": "startup,commands", + "FieldName": "VS_StartupCommands", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.StartupCommands", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Spawn Cap Player Scaling", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Gameplay:sports_esports:3", + "Description": "How much the creature cap grows per additional player.", + "Keywords": "spawn,cap,mobs", + "FieldName": "VS_SpawnCapPlayerScaling", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.SpawnCapPlayerScaling", + "IncludeInCommandLine": false, + "DefaultValue": "0.5", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "World Name", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "World:public:4", + "Description": "Display name of the world save.", + "Keywords": "world,name", + "FieldName": "VS_WorldConfig_WorldName", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.WorldConfig.WorldName", + "IncludeInCommandLine": false, + "DefaultValue": "A new world", + "EnumValues": {} + }, + { + "DisplayName": "Play Style", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "World:public:4", + "Description": "World preset id, applied when the world is first created: surviveandbuild, wildernesssurvival, exploration, homosapiens, creativebuilding.", + "Keywords": "playstyle,preset", + "FieldName": "VS_WorldConfig_PlayStyle", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.WorldConfig.PlayStyle", + "IncludeInCommandLine": false, + "DefaultValue": "surviveandbuild", + "EnumValues": {} + }, + { + "DisplayName": "Play Style Lang Code", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "World:public:4", + "Description": "Language code that belongs to the chosen play style, for example surviveandbuild-bands.", + "Keywords": "playstyle,lang", + "FieldName": "VS_WorldConfig_PlayStyleLangCode", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.WorldConfig.PlayStyleLangCode", + "IncludeInCommandLine": false, + "DefaultValue": "surviveandbuild-bands", + "EnumValues": {} + }, + { + "DisplayName": "World Type", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "World:public:4", + "Description": "standard or superflat. Only used when the world is created.", + "Keywords": "worldtype,superflat", + "FieldName": "VS_WorldConfig_WorldType", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.WorldConfig.WorldType", + "IncludeInCommandLine": false, + "DefaultValue": "standard", + "EnumValues": {} + }, + { + "DisplayName": "World Seed", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "World:public:4", + "Description": "Seed used when the world is created. Empty means random.", + "Keywords": "seed", + "FieldName": "VS_WorldConfig_Seed", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.WorldConfig.Seed", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Allow Creative Mode", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "World:public:4", + "Description": "Allow creative mode in this world.", + "Keywords": "creative", + "FieldName": "VS_WorldConfig_AllowCreativeMode", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.WorldConfig.AllowCreativeMode", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "World Height", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "World:public:4", + "Description": "World height in blocks. Only applied when the world is created.", + "Keywords": "height,mapsize", + "FieldName": "VS_WorldConfig_MapSizeY", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.WorldConfig.MapSizeY", + "IncludeInCommandLine": false, + "DefaultValue": "256", + "EnumValues": {}, + "MinValue": "0" + }, + { + "DisplayName": "Save File Location", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "World:public:4", + "Description": "Full path of the .vcdbs world file this instance loads. Leave as generated unless you are switching worlds deliberately.", + "Keywords": "save,world,file", + "FieldName": "VS_WorldConfig_SaveFileLocation", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.WorldConfig.SaveFileLocation", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "World Repair Mode", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "World:public:4", + "Description": "Load the world in repair mode. Diagnostic use only.", + "Keywords": "repair", + "FieldName": "VS_WorldConfig_RepairMode", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.WorldConfig.RepairMode", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Max Chunk Radius", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Performance:speed:5", + "Description": "Server side view distance in chunks. Stratum's adaptive radius controller can override this at runtime.", + "Keywords": "chunks,radius,viewdistance", + "FieldName": "VS_MaxChunkRadius", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.MaxChunkRadius", + "IncludeInCommandLine": false, + "DefaultValue": "12", + "EnumValues": {}, + "Suffix": "chunks", + "MinValue": "1" + }, + { + "DisplayName": "Tick Time", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Performance:speed:5", + "Description": "Target milliseconds per server tick. 33.333332 is 30 ticks per second.", + "Keywords": "tick,tps", + "FieldName": "VS_TickTime", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.TickTime", + "IncludeInCommandLine": false, + "DefaultValue": "33.333332", + "EnumValues": {}, + "Decimal": true, + "Suffix": "ms" + }, + { + "DisplayName": "Block Tick Interval", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Performance:speed:5", + "Description": "Milliseconds between random block tick passes.", + "Keywords": "blocktick", + "FieldName": "VS_BlockTickInterval", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockTickInterval", + "IncludeInCommandLine": false, + "DefaultValue": "300", + "EnumValues": {}, + "Suffix": "ms", + "MinValue": "1" + }, + { + "DisplayName": "Random Block Ticks Per Chunk", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Performance:speed:5", + "Description": "How many random block ticks each chunk gets per pass.", + "Keywords": "blocktick,random", + "FieldName": "VS_RandomBlockTicksPerChunk", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.RandomBlockTicksPerChunk", + "IncludeInCommandLine": false, + "DefaultValue": "16", + "EnumValues": {}, + "MinValue": "0" + }, + { + "DisplayName": "Block Tick Chunk Range", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Performance:speed:5", + "Description": "Radius in chunks around players that receives random block ticks.", + "Keywords": "blocktick,range", + "FieldName": "VS_BlockTickChunkRange", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockTickChunkRange", + "IncludeInCommandLine": false, + "DefaultValue": "5", + "EnumValues": {}, + "Suffix": "chunks", + "MinValue": "0" + }, + { + "DisplayName": "Max Main Thread Block Ticks", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Performance:speed:5", + "Description": "Upper bound of block ticks executed on the main thread per tick.", + "Keywords": "blocktick,mainthread", + "FieldName": "VS_MaxMainThreadBlockTicks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.MaxMainThreadBlockTicks", + "IncludeInCommandLine": false, + "DefaultValue": "10000", + "EnumValues": {}, + "MinValue": "0" + }, + { + "DisplayName": "Corruption Protection", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Reliability:health_and_safety:6", + "Description": "Write extra checksums so corrupt chunks can be detected.", + "Keywords": "corruption", + "FieldName": "VS_CorruptionProtection", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.CorruptionProtection", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Regenerate Corrupt Chunks", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Reliability:health_and_safety:6", + "Description": "Regenerate chunks that fail the corruption check instead of failing the load.", + "Keywords": "corruption,regenerate", + "FieldName": "VS_RegenerateCorruptChunks", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.RegenerateCorruptChunks", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Log Block Break/Place", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Reliability:health_and_safety:6", + "Description": "Log every block break and place. Useful for grief investigations, noisy on busy servers.", + "Keywords": "log,blocks,griefing", + "FieldName": "VS_LogBlockBreakPlace", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.LogBlockBreakPlace", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Split Log After Lines", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Reliability:health_and_safety:6", + "Description": "Start a new log file after this many lines.", + "Keywords": "log,split", + "FieldName": "VS_LogFileSplitAfterLine", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.LogFileSplitAfterLine", + "IncludeInCommandLine": false, + "DefaultValue": "500000", + "EnumValues": {}, + "MinValue": "1000" + }, + { + "DisplayName": "Shut Down Below Disk Space", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Reliability:health_and_safety:6", + "Description": "Shut the server down when free disk space drops below this, protecting the save from a truncated write.", + "Keywords": "disk,space", + "FieldName": "VS_DieBelowDiskSpaceMb", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.DieBelowDiskSpaceMb", + "IncludeInCommandLine": false, + "DefaultValue": "400", + "EnumValues": {}, + "Suffix": "MB", + "MinValue": "0" + }, + { + "DisplayName": "Shut Down Above Memory Usage", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Reliability:health_and_safety:6", + "Description": "Shut the server down when memory use exceeds this value.", + "Keywords": "memory,ram", + "FieldName": "VS_DieAboveMemoryUsageMb", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.DieAboveMemoryUsageMb", + "IncludeInCommandLine": false, + "DefaultValue": "50000", + "EnumValues": {}, + "Suffix": "MB", + "MinValue": "0" + }, + { + "DisplayName": "Shut Down Above Error Count", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Reliability:health_and_safety:6", + "Description": "Shut the server down after this many logged errors.", + "Keywords": "errors", + "FieldName": "VS_DieAboveErrorCount", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.DieAboveErrorCount", + "IncludeInCommandLine": false, + "DefaultValue": "100000", + "EnumValues": {}, + "MinValue": "0" + }, + { + "DisplayName": "Disable Mod Safety Check", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Mods & Advanced:extension:7", + "Description": "Skip the mod sandbox checks. Only for trusted mod sets.", + "Keywords": "mods,safety,sandbox", + "FieldName": "VS_DisableModSafetyCheck", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.DisableModSafetyCheck", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Disable Auto Remap", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Mods & Advanced:extension:7", + "Description": "Disable automatic block id remapping when the mod set changes.", + "Keywords": "mods,remap", + "FieldName": "VS_DisableAutoRemap", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.DisableAutoRemap", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Hosted Mode", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Mods & Advanced:extension:7", + "Description": "Locks down settings a hosting provider controls: max clients, chunk radius, UPnP, tick time and block ticking. Leave off on AMP.", + "Keywords": "hosted", + "FieldName": "VS_HostedMode", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.HostedMode", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Hosted Mode Allow Mods", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Mods & Advanced:extension:7", + "Description": "Allow mods while hosted mode is enabled.", + "Keywords": "hosted,mods", + "FieldName": "VS_HostedModeAllowMods", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.HostedModeAllowMods", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Repair Mode", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Mods & Advanced:extension:7", + "Description": "Start the server in repair mode. Diagnostic use only.", + "Keywords": "repair", + "FieldName": "VS_RepairMode", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.RepairMode", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Analyze Mode", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Mods & Advanced:extension:7", + "Description": "Start the server in analyze mode. Diagnostic use only.", + "Keywords": "analyze", + "FieldName": "VS_AnalyzeMode", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.AnalyzeMode", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Let AMP Manage nimbus-server.json", + "Category": "Nimbus:cloud", + "Subcategory": "Nimbus Backend:hub:1", + "Description": "When on, AMP rewrites data/ModConfig/nimbus-server.json from the settings below every time the instance starts. Turn it off if you want to hand-edit that file instead; every Nimbus setting in this panel is then ignored.", + "Keywords": "nimbus,config,manage", + "FieldName": "NimbusWriteConfig", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "NimbusWriteConfig", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enable Nimbus Backend Mod", + "Category": "Nimbus:cloud", + "Subcategory": "Nimbus Backend:hub:1", + "Description": "Master switch inside nimbus-server.json. Off means the mod loads but never heartbeats to the registry, so this server is not part of the network.", + "Keywords": "nimbus,enabled", + "FieldName": "NimbusEnabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "NimbusEnabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Server ID", + "Category": "Nimbus:cloud", + "Subcategory": "Nimbus Backend:hub:1", + "Description": "Unique id of this backend on the network, lower case, no spaces, for example hub, creative, mining-1. Players use it as /server , the proxy uses it in its [servers] table, and it must be unique across the whole network.", + "Keywords": "nimbus,serverid,name", + "FieldName": "NimbusServerId", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "NimbusServerId", + "IncludeInCommandLine": false, + "DefaultValue": "hub", + "EnumValues": {}, + "Placeholder": "hub" + }, + { + "DisplayName": "Display Name", + "Category": "Nimbus:cloud", + "Subcategory": "Nimbus Backend:hub:1", + "Description": "Friendly name shown in /servers and in transfer messages.", + "Keywords": "nimbus,displayname", + "FieldName": "NimbusDisplayName", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "NimbusDisplayName", + "IncludeInCommandLine": false, + "DefaultValue": "Hub", + "EnumValues": {} + }, + { + "DisplayName": "Advertised Host", + "Category": "Nimbus:cloud", + "Subcategory": "Nimbus Backend:hub:1", + "Description": "Address the PROXY uses to reach this backend, not the address players use. Use 127.0.0.1 when the proxy runs on the same machine, otherwise the LAN or WAN address of this instance.", + "Keywords": "nimbus,host,publichost", + "FieldName": "NimbusPublicHost", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "NimbusPublicHost", + "IncludeInCommandLine": false, + "DefaultValue": "127.0.0.1", + "EnumValues": {}, + "Placeholder": "127.0.0.1" + }, + { + "DisplayName": "Advertised Port", + "Category": "Nimbus:cloud", + "Subcategory": "Nimbus Backend:hub:1", + "Description": "Port the proxy dials for this backend. 0 means use this instance's own game port, which is almost always what you want.", + "Keywords": "nimbus,port,publicport", + "FieldName": "NimbusPublicPort", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "NimbusPublicPort", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {}, + "MinValue": "0" + }, + { + "DisplayName": "Tags", + "Category": "Nimbus:cloud", + "Subcategory": "Nimbus Backend:hub:1", + "Description": "Comma separated tags published with the heartbeat, for example survival,pvp. Plugins and shortcut logic can select servers by tag.", + "Keywords": "nimbus,tags", + "FieldName": "NimbusTags", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "NimbusTags", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Placeholder": "survival,pvp" + }, + { + "DisplayName": "Registry URL", + "Category": "Nimbus:cloud", + "Subcategory": "Nimbus Backend:hub:1", + "Description": "Base URL of the Nimbus registry. Use the proxy's embedded registry bind (default http://127.0.0.1:8765) or the standalone registry's bind. Must be reachable from this instance.", + "Keywords": "nimbus,registry,url", + "FieldName": "NimbusRegistryUrl", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "NimbusRegistryUrl", + "IncludeInCommandLine": false, + "DefaultValue": "http://127.0.0.1:8765", + "EnumValues": {}, + "Placeholder": "http://127.0.0.1:8765" + }, + { + "DisplayName": "Registry Shared Secret", + "Category": "Nimbus:cloud", + "Subcategory": "Nimbus Backend:hub:1", + "Description": "HMAC secret this backend signs heartbeats with. It must be byte for byte the same value as the registry's shared secret. Never generate it here: copy the one the proxy or registry wrote on its first run.", + "Keywords": "nimbus,secret,hmac", + "FieldName": "NimbusSharedSecret", + "InputType": "password", + "IsFlagArgument": false, + "ParamFieldName": "NimbusSharedSecret", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Heartbeat Interval", + "Category": "Nimbus:cloud", + "Subcategory": "Nimbus Backend:hub:1", + "Description": "Seconds between heartbeats to the registry. Must be well below the registry's stale window.", + "Keywords": "nimbus,heartbeat", + "FieldName": "NimbusHeartbeatIntervalSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "NimbusHeartbeatIntervalSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "5", + "EnumValues": {}, + "Suffix": "seconds", + "MinValue": "1" + }, + { + "DisplayName": "Registry HTTP Timeout", + "Category": "Nimbus:cloud", + "Subcategory": "Nimbus Backend:hub:1", + "Description": "Seconds before a registry call is abandoned.", + "Keywords": "nimbus,timeout", + "FieldName": "NimbusRegistryHttpTimeoutSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "NimbusRegistryHttpTimeoutSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "5", + "EnumValues": {}, + "Suffix": "seconds", + "MinValue": "1" + }, + { + "DisplayName": "Maintenance Mode", + "Category": "Nimbus:cloud", + "Subcategory": "Nimbus Backend:hub:1", + "Description": "Advertise this backend as in maintenance. The proxy keeps it out of the join try-list and out of shortcut targets while players already on it stay.", + "Keywords": "nimbus,maintenance", + "FieldName": "NimbusMaintenance", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "NimbusMaintenance", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Require Proxy Reservation", + "Category": "Nimbus:cloud", + "Subcategory": "Nimbus Backend:hub:1", + "Description": "Only let players in who hold a reservation issued by the proxy. This is what stops players bypassing the proxy by connecting to the backend port directly.", + "Keywords": "nimbus,reservation", + "FieldName": "NimbusReservationRequired", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "NimbusReservationRequired", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Fail Closed On Registry Outage", + "Category": "Nimbus:cloud", + "Subcategory": "Nimbus Backend:hub:1", + "Description": "Off (default) lets players in when the registry cannot be reached, so an outage does not lock everyone out. On kicks them instead, so an outage cannot be used to bypass the proxy.", + "Keywords": "nimbus,failclosed", + "FieldName": "NimbusFailClosedWhenRegistryUnreachable", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "NimbusFailClosedWhenRegistryUnreachable", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Allow /server For Players", + "Category": "Nimbus:cloud", + "Subcategory": "Nimbus Transfers:swap_horiz:2", + "Description": "Let ordinary players run /server and /servers. Turn it off to restrict movement to shortcuts and staff commands.", + "Keywords": "nimbus,server,command", + "FieldName": "NimbusAllowPlayerServerCommand", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "NimbusAllowPlayerServerCommand", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Transfer Mode", + "Category": "Nimbus:cloud", + "Subcategory": "Nimbus Transfers:swap_horiz:2", + "Description": "How this backend hands a player to another server. redirect uses the vanilla redirect packet and needs no client mod. seamless keeps the same TCP connection and requires the proxy to allow seamless transfers.", + "Keywords": "nimbus,transfer,mode", + "FieldName": "NimbusTransferMode", + "InputType": "enum", + "IsFlagArgument": false, + "ParamFieldName": "NimbusTransferMode", + "IncludeInCommandLine": false, + "DefaultValue": "redirect", + "EnumValues": { + "redirect": "Redirect (safe default)", + "seamless": "Seamless (proxy must allow it)" + } + }, + { + "DisplayName": "Seamless Prepare Ack Timeout", + "Category": "Nimbus:cloud", + "Subcategory": "Nimbus Transfers:swap_horiz:2", + "Description": "Seconds to wait for the target server to confirm it is ready during a seamless transfer. Clamped to 1-30.", + "Keywords": "nimbus,seamless,timeout", + "FieldName": "NimbusSeamlessPrepareAckTimeoutSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "NimbusSeamlessPrepareAckTimeoutSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "8", + "EnumValues": {}, + "Suffix": "seconds", + "MinValue": "1", + "MaxValue": "30" + }, + { + "DisplayName": "Shortcut Commands", + "Category": "Nimbus:cloud", + "Subcategory": "Nimbus Transfers:swap_horiz:2", + "Description": "Named /commands that move a player, semicolon separated. Format: name=target1|target2@privilege. Example: hub=hub;creative=creative|hub;staff=staff@controlserver. Targets are tried in order and the first healthy one that is not this server wins. Privilege defaults to chat.", + "Keywords": "nimbus,shortcuts,commands", + "FieldName": "NimbusShortcutCommands", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "NimbusShortcutCommands", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Placeholder": "hub=hub;creative=creative|hub" + }, + { + "DisplayName": "Stratum Release Channel", + "Category": "Updates", + "Subcategory": "Server Updates:build:-1", + "Description": "Which Stratum releases this instance is allowed to install. Stable only takes tagged releases; Prerelease also accepts -indev builds.", + "Keywords": "stratum,channel,release", + "FieldName": "StratumReleaseChannel", + "InputType": "enum", + "IsFlagArgument": false, + "ParamFieldName": "StratumReleaseChannel", + "IncludeInCommandLine": false, + "DefaultValue": "stable", + "EnumValues": { + "stable": "Stable (default)", + "prerelease": "Prerelease / indev" + } + }, + { + "DisplayName": "Vintage Story Version", + "Category": "Updates", + "Subcategory": "Server Updates:build:-1", + "Description": "The Vintage Story version Stratum must be built against, for example 1.22.6. Empty means the newest version available on the selected channel. Stratum tags are v-stratum., and the matching vanilla assets are downloaded automatically, so this single field is what pins the game version.", + "Keywords": "stratum,version,vintagestory", + "FieldName": "StratumGameVersion", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "StratumGameVersion", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Placeholder": "1.22.6" + }, + { + "DisplayName": "Stratum Release Tag Override", + "Category": "Updates", + "Subcategory": "Server Updates:build:-1", + "Description": "Exact release tag to install, for example v1.22.6-stratum.2. Overrides both the channel and the version field above. Use it to pin or roll back a build.", + "Keywords": "stratum,tag,pin", + "FieldName": "StratumVersionTag", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "StratumVersionTag", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Placeholder": "v1.22.6-stratum.2" + }, + { + "DisplayName": "Re-download Vanilla Assets", + "Category": "Updates", + "Subcategory": "Server Updates:build:-1", + "Description": "Force Stratum to discard its cached vanilla game files and fetch them again on the next update. Use this if an update left the server folder in a broken state.", + "Keywords": "stratum,vanilla,refresh", + "FieldName": "StratumRefreshVanilla", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "StratumRefreshVanilla", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "GitHub Token (optional)", + "Category": "Updates", + "Subcategory": "Server Updates:build:-1", + "Description": "Optional GitHub token used only to raise the API rate limit while resolving release tags. A read-only token is enough and it is never sent anywhere else.", + "Keywords": "github,token,ratelimit", + "FieldName": "StratumGitHubToken", + "InputType": "password", + "IsFlagArgument": false, + "ParamFieldName": "StratumGitHubToken", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Install Nimbus Server Mod", + "Category": "Updates", + "Subcategory": "Nimbus Updates:cloud_download:0", + "Description": "Download Nimbus.ServerMod into data/Mods on every update. Required for this server to join a Nimbus network. Turn it off for a stand-alone Stratum server.", + "Keywords": "nimbus,mod,install", + "FieldName": "NimbusInstall", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "NimbusInstall", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Nimbus Version", + "Category": "Updates", + "Subcategory": "Nimbus Updates:cloud_download:0", + "Description": "Nimbus release to install, for example v0.5.0. Empty means the newest release on the selected channel. The proxy, the registry and every backend mod on a network must run the same Nimbus version.", + "Keywords": "nimbus,version", + "FieldName": "NimbusModVersion", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "NimbusModVersion", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Placeholder": "v0.5.0" + }, + { + "DisplayName": "Nimbus Release Channel", + "Category": "Updates", + "Subcategory": "Nimbus Updates:cloud_download:0", + "Description": "Whether prerelease Nimbus builds are eligible when no explicit version is set.", + "Keywords": "nimbus,channel", + "FieldName": "NimbusReleaseChannel", + "InputType": "enum", + "IsFlagArgument": false, + "ParamFieldName": "NimbusReleaseChannel", + "IncludeInCommandLine": false, + "DefaultValue": "stable", + "EnumValues": { + "stable": "Stable (default)", + "prerelease": "Prerelease" + } + }, + { + "DisplayName": "Dotnet Release Stream", + "Category": "Updates", + "Subcategory": "Server Updates:build:-1", + "Description": "Which .NET SDK stream to install. Vintage Story 1.22 and Nimbus both need 10.0; 1.21 and below need 8.0.", + "Keywords": "dotnet,release", + "FieldName": "DotnetRelease", + "InputType": "enum", + "IsFlagArgument": false, + "ParamFieldName": "DotnetRelease", + "IncludeInCommandLine": false, + "DefaultValue": "10.0", + "EnumValues": { + "10.0": "10.0 (default)", + "8.0": "8.0" + } + }, + { + "DisplayName": "Dotnet Version", + "Category": "Updates", + "Subcategory": "Server Updates:build:-1", + "Description": "Exact .NET SDK version to install. Empty means the newest in the selected stream.", + "Keywords": "dotnet,version", + "FieldName": "DotnetSDKVersion", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "DotnetSDKVersion", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Placeholder": "10.0.100" + }, + { + "DisplayName": "Additional Command Line Arguments", + "Category": "Updates", + "Subcategory": "Server Updates:build:-1", + "Description": "Extra arguments appended to the StratumServer command line, for example --tracelog. Leave empty unless you know you need one.", + "Keywords": "args,commandline", + "FieldName": "StratumExtraArgs", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "StratumExtraArgs", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Log Startup Summary", + "Category": "Stratum:filter_alt", + "Subcategory": "Diagnostics:monitor_heart:10", + "Description": "data/stratum.json -> $.Diagnostics.LogStartupSummary", + "Keywords": "diagnostics,logstartupsummary", + "FieldName": "Stratum_main_Diagnostics_LogStartupSummary", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Diagnostics.LogStartupSummary", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Run Startup Preflight", + "Category": "Stratum:filter_alt", + "Subcategory": "Diagnostics:monitor_heart:10", + "Description": "data/stratum.json -> $.Diagnostics.RunStartupPreflight", + "Keywords": "diagnostics,runstartuppreflight", + "FieldName": "Stratum_main_Diagnostics_RunStartupPreflight", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Diagnostics.RunStartupPreflight", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Log Preflight Warnings", + "Category": "Stratum:filter_alt", + "Subcategory": "Diagnostics:monitor_heart:10", + "Description": "data/stratum.json -> $.Diagnostics.LogPreflightWarnings", + "Keywords": "diagnostics,logpreflightwarnings", + "FieldName": "Stratum_main_Diagnostics_LogPreflightWarnings", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Diagnostics.LogPreflightWarnings", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Log Mod Harmony Patches", + "Category": "Stratum:filter_alt", + "Subcategory": "Diagnostics:monitor_heart:10", + "Description": "Logs every mod-owned Harmony patch at startup, grouped by mod. Visibility only, it does not cross-reference Stratum's own source-patched methods -- see StratumHarmonyVisibility. On by default because a mod patch landing on something Stratum reshaped usually goes missing silently rather than erroring, and this log is what makes it traceable. (data/stratum.json -> $.Diagnostics.LogModHarmonyPatches)", + "Keywords": "diagnostics,logmodharmonypatches", + "FieldName": "Stratum_main_Diagnostics_LogModHarmonyPatches", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Diagnostics.LogModHarmonyPatches", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Update Checker:system_update:10", + "Description": "data/stratum.json -> $.UpdateChecker.Enabled", + "Keywords": "updatechecker,enabled", + "FieldName": "Stratum_main_UpdateChecker_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.UpdateChecker.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Check On Startup", + "Category": "Stratum:filter_alt", + "Subcategory": "Update Checker:system_update:10", + "Description": "data/stratum.json -> $.UpdateChecker.CheckOnStartup", + "Keywords": "updatechecker,checkonstartup", + "FieldName": "Stratum_main_UpdateChecker_CheckOnStartup", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.UpdateChecker.CheckOnStartup", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Check Interval Hours", + "Category": "Stratum:filter_alt", + "Subcategory": "Update Checker:system_update:10", + "Description": "data/stratum.json -> $.UpdateChecker.CheckIntervalHours", + "Keywords": "updatechecker,checkintervalhours", + "FieldName": "Stratum_main_UpdateChecker_CheckIntervalHours", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.UpdateChecker.CheckIntervalHours", + "IncludeInCommandLine": false, + "DefaultValue": "12", + "EnumValues": {} + }, + { + "DisplayName": "Notify Staff In Game", + "Category": "Stratum:filter_alt", + "Subcategory": "Update Checker:system_update:10", + "Description": "data/stratum.json -> $.UpdateChecker.NotifyStaffInGame", + "Keywords": "updatechecker,notifystaffingame", + "FieldName": "Stratum_main_UpdateChecker_NotifyStaffInGame", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.UpdateChecker.NotifyStaffInGame", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Latest Release Url", + "Category": "Stratum:filter_alt", + "Subcategory": "Update Checker:system_update:10", + "Description": "data/stratum.json -> $.UpdateChecker.LatestReleaseUrl", + "Keywords": "updatechecker,latestreleaseurl", + "FieldName": "Stratum_main_UpdateChecker_LatestReleaseUrl", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.UpdateChecker.LatestReleaseUrl", + "IncludeInCommandLine": false, + "DefaultValue": "https://api.github.com/repos/StratumServer/Stratum/releases/latest", + "EnumValues": {} + }, + { + "DisplayName": "Timeout Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Update Checker:system_update:10", + "Description": "data/stratum.json -> $.UpdateChecker.TimeoutSeconds", + "Keywords": "updatechecker,timeoutseconds", + "FieldName": "Stratum_main_UpdateChecker_TimeoutSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.UpdateChecker.TimeoutSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "5", + "EnumValues": {} + }, + { + "DisplayName": "Preserve Vanilla Protocol", + "Category": "Stratum:filter_alt", + "Subcategory": "Hardening:shield:10", + "Description": "data/stratum.json -> $.Hardening.PreserveVanillaProtocol", + "Keywords": "hardening,preservevanillaprotocol", + "FieldName": "Stratum_main_Hardening_PreserveVanillaProtocol", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Hardening.PreserveVanillaProtocol", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Packet Monitoring", + "Category": "Stratum:filter_alt", + "Subcategory": "Hardening:shield:10", + "Description": "data/stratum.json -> $.Hardening.PacketMonitoring", + "Keywords": "hardening,packetmonitoring", + "FieldName": "Stratum_main_Hardening_PacketMonitoring", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Hardening.PacketMonitoring", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Block Break Guards", + "Category": "Stratum:filter_alt", + "Subcategory": "Hardening:shield:10", + "Description": "data/stratum.json -> $.Hardening.BlockBreakGuards", + "Keywords": "hardening,blockbreakguards", + "FieldName": "Stratum_main_Hardening_BlockBreakGuards", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Hardening.BlockBreakGuards", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Inventory Guards", + "Category": "Stratum:filter_alt", + "Subcategory": "Hardening:shield:10", + "Description": "data/stratum.json -> $.Hardening.InventoryGuards", + "Keywords": "hardening,inventoryguards", + "FieldName": "Stratum_main_Hardening_InventoryGuards", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Hardening.InventoryGuards", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Entity Guards", + "Category": "Stratum:filter_alt", + "Subcategory": "Hardening:shield:10", + "Description": "data/stratum.json -> $.Hardening.EntityGuards", + "Keywords": "hardening,entityguards", + "FieldName": "Stratum_main_Hardening_EntityGuards", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Hardening.EntityGuards", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Limits:speed:10", + "Description": "data/stratum.json -> $.PacketLimits.Enabled", + "Keywords": "packetlimits,enabled", + "FieldName": "Stratum_main_PacketLimits_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketLimits.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Drop Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Limits:speed:10", + "Description": "data/stratum.json -> $.PacketLimits.DropViolations", + "Keywords": "packetlimits,dropviolations", + "FieldName": "Stratum_main_PacketLimits_DropViolations", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketLimits.DropViolations", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Log Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Limits:speed:10", + "Description": "data/stratum.json -> $.PacketLimits.LogViolations", + "Keywords": "packetlimits,logviolations", + "FieldName": "Stratum_main_PacketLimits_LogViolations", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketLimits.LogViolations", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Kick Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Limits:speed:10", + "Description": "data/stratum.json -> $.PacketLimits.KickViolations", + "Keywords": "packetlimits,kickviolations", + "FieldName": "Stratum_main_PacketLimits_KickViolations", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketLimits.KickViolations", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Kick Invalid Packets", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Limits:speed:10", + "Description": "data/stratum.json -> $.PacketLimits.KickInvalidPackets", + "Keywords": "packetlimits,kickinvalidpackets", + "FieldName": "Stratum_main_PacketLimits_KickInvalidPackets", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketLimits.KickInvalidPackets", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Kick Oversized Custom Packets", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Limits:speed:10", + "Description": "data/stratum.json -> $.PacketLimits.KickOversizedCustomPackets", + "Keywords": "packetlimits,kickoversizedcustompackets", + "FieldName": "Stratum_main_PacketLimits_KickOversizedCustomPackets", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketLimits.KickOversizedCustomPackets", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Monitor Only Sensitive Packets", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Limits:speed:10", + "Description": "data/stratum.json -> $.PacketLimits.MonitorOnlySensitivePackets", + "Keywords": "packetlimits,monitoronlysensitivepackets", + "FieldName": "Stratum_main_PacketLimits_MonitorOnlySensitivePackets", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketLimits.MonitorOnlySensitivePackets", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Kick After Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Limits:speed:10", + "Description": "data/stratum.json -> $.PacketLimits.KickAfterViolations", + "Keywords": "packetlimits,kickafterviolations", + "FieldName": "Stratum_main_PacketLimits_KickAfterViolations", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketLimits.KickAfterViolations", + "IncludeInCommandLine": false, + "DefaultValue": "8", + "EnumValues": {} + }, + { + "DisplayName": "Kick Message", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Limits:speed:10", + "Description": "data/stratum.json -> $.PacketLimits.KickMessage", + "Keywords": "packetlimits,kickmessage", + "FieldName": "Stratum_main_PacketLimits_KickMessage", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketLimits.KickMessage", + "IncludeInCommandLine": false, + "DefaultValue": "Disconnected by Stratum packet protection", + "EnumValues": {} + }, + { + "DisplayName": "Window Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Limits:speed:10", + "Description": "data/stratum.json -> $.PacketLimits.WindowSeconds", + "Keywords": "packetlimits,windowseconds", + "FieldName": "Stratum_main_PacketLimits_WindowSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketLimits.WindowSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "5", + "EnumValues": {} + }, + { + "DisplayName": "Default Max Packets", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Limits:speed:10", + "Description": "data/stratum.json -> $.PacketLimits.DefaultMaxPackets", + "Keywords": "packetlimits,defaultmaxpackets", + "FieldName": "Stratum_main_PacketLimits_DefaultMaxPackets", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketLimits.DefaultMaxPackets", + "IncludeInCommandLine": false, + "DefaultValue": "300", + "EnumValues": {} + }, + { + "DisplayName": "Movement Max Packets", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Limits:speed:10", + "Description": "data/stratum.json -> $.PacketLimits.MovementMaxPackets", + "Keywords": "packetlimits,movementmaxpackets", + "FieldName": "Stratum_main_PacketLimits_MovementMaxPackets", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketLimits.MovementMaxPackets", + "IncludeInCommandLine": false, + "DefaultValue": "420", + "EnumValues": {} + }, + { + "DisplayName": "Inventory Max Packets", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Limits:speed:10", + "Description": "data/stratum.json -> $.PacketLimits.InventoryMaxPackets", + "Keywords": "packetlimits,inventorymaxpackets", + "FieldName": "Stratum_main_PacketLimits_InventoryMaxPackets", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketLimits.InventoryMaxPackets", + "IncludeInCommandLine": false, + "DefaultValue": "90", + "EnumValues": {} + }, + { + "DisplayName": "Block Interaction Max Packets", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Limits:speed:10", + "Description": "data/stratum.json -> $.PacketLimits.BlockInteractionMaxPackets", + "Keywords": "packetlimits,blockinteractionmaxpackets", + "FieldName": "Stratum_main_PacketLimits_BlockInteractionMaxPackets", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketLimits.BlockInteractionMaxPackets", + "IncludeInCommandLine": false, + "DefaultValue": "140", + "EnumValues": {} + }, + { + "DisplayName": "Entity Interaction Max Packets", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Limits:speed:10", + "Description": "data/stratum.json -> $.PacketLimits.EntityInteractionMaxPackets", + "Keywords": "packetlimits,entityinteractionmaxpackets", + "FieldName": "Stratum_main_PacketLimits_EntityInteractionMaxPackets", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketLimits.EntityInteractionMaxPackets", + "IncludeInCommandLine": false, + "DefaultValue": "140", + "EnumValues": {} + }, + { + "DisplayName": "Hand Interaction Max Packets", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Limits:speed:10", + "Description": "data/stratum.json -> $.PacketLimits.HandInteractionMaxPackets", + "Keywords": "packetlimits,handinteractionmaxpackets", + "FieldName": "Stratum_main_PacketLimits_HandInteractionMaxPackets", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketLimits.HandInteractionMaxPackets", + "IncludeInCommandLine": false, + "DefaultValue": "90", + "EnumValues": {} + }, + { + "DisplayName": "Custom Packet Max Packets", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Limits:speed:10", + "Description": "data/stratum.json -> $.PacketLimits.CustomPacketMaxPackets", + "Keywords": "packetlimits,custompacketmaxpackets", + "FieldName": "Stratum_main_PacketLimits_CustomPacketMaxPackets", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketLimits.CustomPacketMaxPackets", + "IncludeInCommandLine": false, + "DefaultValue": "120", + "EnumValues": {} + }, + { + "DisplayName": "Custom Packet Max Bytes", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Limits:speed:10", + "Description": "data/stratum.json -> $.PacketLimits.CustomPacketMaxBytes", + "Keywords": "packetlimits,custompacketmaxbytes", + "FieldName": "Stratum_main_PacketLimits_CustomPacketMaxBytes", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketLimits.CustomPacketMaxBytes", + "IncludeInCommandLine": false, + "DefaultValue": "262144", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Back Pressure:compress:10", + "Description": "data/stratum.json -> $.PacketBackPressure.Enabled", + "Keywords": "packetbackpressure,enabled", + "FieldName": "Stratum_main_PacketBackPressure_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketBackPressure.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Max Milliseconds Per Tick", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Back Pressure:compress:10", + "Description": "data/stratum.json -> $.PacketBackPressure.MaxMillisecondsPerTick", + "Keywords": "packetbackpressure,maxmillisecondspertick", + "FieldName": "Stratum_main_PacketBackPressure_MaxMillisecondsPerTick", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketBackPressure.MaxMillisecondsPerTick", + "IncludeInCommandLine": false, + "DefaultValue": "25", + "EnumValues": {} + }, + { + "DisplayName": "Max Packets Per Client Per Tick", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Back Pressure:compress:10", + "Description": "data/stratum.json -> $.PacketBackPressure.MaxPacketsPerClientPerTick", + "Keywords": "packetbackpressure,maxpacketsperclientpertick", + "FieldName": "Stratum_main_PacketBackPressure_MaxPacketsPerClientPerTick", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketBackPressure.MaxPacketsPerClientPerTick", + "IncludeInCommandLine": false, + "DefaultValue": "32", + "EnumValues": {} + }, + { + "DisplayName": "Max Queue Depth Per Client", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Back Pressure:compress:10", + "Description": "data/stratum.json -> $.PacketBackPressure.MaxQueueDepthPerClient", + "Keywords": "packetbackpressure,maxqueuedepthperclient", + "FieldName": "Stratum_main_PacketBackPressure_MaxQueueDepthPerClient", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketBackPressure.MaxQueueDepthPerClient", + "IncludeInCommandLine": false, + "DefaultValue": "2000", + "EnumValues": {} + }, + { + "DisplayName": "Kick On Queue Overflow", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Back Pressure:compress:10", + "Description": "data/stratum.json -> $.PacketBackPressure.KickOnQueueOverflow", + "Keywords": "packetbackpressure,kickonqueueoverflow", + "FieldName": "Stratum_main_PacketBackPressure_KickOnQueueOverflow", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketBackPressure.KickOnQueueOverflow", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Kick Message", + "Category": "Stratum:filter_alt", + "Subcategory": "Packet Back Pressure:compress:10", + "Description": "data/stratum.json -> $.PacketBackPressure.KickMessage", + "Keywords": "packetbackpressure,kickmessage", + "FieldName": "Stratum_main_PacketBackPressure_KickMessage", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.PacketBackPressure.KickMessage", + "IncludeInCommandLine": false, + "DefaultValue": "Disconnected by Stratum packet back-pressure", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Block Break Guards:construction:10", + "Description": "data/stratum.json -> $.BlockBreakGuards.Enabled", + "Keywords": "blockbreakguards,enabled", + "FieldName": "Stratum_main_BlockBreakGuards_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockBreakGuards.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Require Server Selection", + "Category": "Stratum:filter_alt", + "Subcategory": "Block Break Guards:construction:10", + "Description": "data/stratum.json -> $.BlockBreakGuards.RequireServerSelection", + "Keywords": "blockbreakguards,requireserverselection", + "FieldName": "Stratum_main_BlockBreakGuards_RequireServerSelection", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockBreakGuards.RequireServerSelection", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Drop Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Block Break Guards:construction:10", + "Description": "data/stratum.json -> $.BlockBreakGuards.DropViolations", + "Keywords": "blockbreakguards,dropviolations", + "FieldName": "Stratum_main_BlockBreakGuards_DropViolations", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockBreakGuards.DropViolations", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Log Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Block Break Guards:construction:10", + "Description": "data/stratum.json -> $.BlockBreakGuards.LogViolations", + "Keywords": "blockbreakguards,logviolations", + "FieldName": "Stratum_main_BlockBreakGuards_LogViolations", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockBreakGuards.LogViolations", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Required Progress Ratio", + "Category": "Stratum:filter_alt", + "Subcategory": "Block Break Guards:construction:10", + "Description": "data/stratum.json -> $.BlockBreakGuards.RequiredProgressRatio", + "Keywords": "blockbreakguards,requiredprogressratio", + "FieldName": "Stratum_main_BlockBreakGuards_RequiredProgressRatio", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockBreakGuards.RequiredProgressRatio", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Grace Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Block Break Guards:construction:10", + "Description": "data/stratum.json -> $.BlockBreakGuards.GraceSeconds", + "Keywords": "blockbreakguards,graceseconds", + "FieldName": "Stratum_main_BlockBreakGuards_GraceSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockBreakGuards.GraceSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Minimum Tracked Break Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Block Break Guards:construction:10", + "Description": "data/stratum.json -> $.BlockBreakGuards.MinimumTrackedBreakSeconds", + "Keywords": "blockbreakguards,minimumtrackedbreakseconds", + "FieldName": "Stratum_main_BlockBreakGuards_MinimumTrackedBreakSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockBreakGuards.MinimumTrackedBreakSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Partial Progress Retention Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Block Break Guards:construction:10", + "Description": "data/stratum.json -> $.BlockBreakGuards.PartialProgressRetentionSeconds", + "Keywords": "blockbreakguards,partialprogressretentionseconds", + "FieldName": "Stratum_main_BlockBreakGuards_PartialProgressRetentionSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockBreakGuards.PartialProgressRetentionSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Max Remembered Progress Ratio", + "Category": "Stratum:filter_alt", + "Subcategory": "Block Break Guards:construction:10", + "Description": "data/stratum.json -> $.BlockBreakGuards.MaxRememberedProgressRatio", + "Keywords": "blockbreakguards,maxrememberedprogressratio", + "FieldName": "Stratum_main_BlockBreakGuards_MaxRememberedProgressRatio", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockBreakGuards.MaxRememberedProgressRatio", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Max Remembered Partial Breaks Per Client", + "Category": "Stratum:filter_alt", + "Subcategory": "Block Break Guards:construction:10", + "Description": "data/stratum.json -> $.BlockBreakGuards.MaxRememberedPartialBreaksPerClient", + "Keywords": "blockbreakguards,maxrememberedpartialbreaksperclient", + "FieldName": "Stratum_main_BlockBreakGuards_MaxRememberedPartialBreaksPerClient", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockBreakGuards.MaxRememberedPartialBreaksPerClient", + "IncludeInCommandLine": false, + "DefaultValue": "24", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Enabled", + "Keywords": "anticheat,enabled", + "FieldName": "Stratum_main_Anticheat_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Staff Alerts", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.StaffAlerts", + "Keywords": "anticheat,staffalerts", + "FieldName": "Stratum_main_Anticheat_StaffAlerts", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.StaffAlerts", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Max Stored Violations Per Player", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MaxStoredViolationsPerPlayer", + "Keywords": "anticheat,maxstoredviolationsperplayer", + "FieldName": "Stratum_main_Anticheat_MaxStoredViolationsPerPlayer", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MaxStoredViolationsPerPlayer", + "IncludeInCommandLine": false, + "DefaultValue": "128", + "EnumValues": {} + }, + { + "DisplayName": "Keep Player Violations Minutes", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.KeepPlayerViolationsMinutes", + "Keywords": "anticheat,keepplayerviolationsminutes", + "FieldName": "Stratum_main_Anticheat_KeepPlayerViolationsMinutes", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.KeepPlayerViolationsMinutes", + "IncludeInCommandLine": false, + "DefaultValue": "60", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Entity Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockEntityOutOfRange.Enabled", + "Keywords": "anticheat,blockentityoutofrange,enabled", + "FieldName": "Stratum_main_Anticheat_BlockEntityOutOfRange_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockEntityOutOfRange.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Alert After Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Entity Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockEntityOutOfRange.AlertAfterViolations", + "Keywords": "anticheat,blockentityoutofrange,alertafterviolations", + "FieldName": "Stratum_main_Anticheat_BlockEntityOutOfRange_AlertAfterViolations", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockEntityOutOfRange.AlertAfterViolations", + "IncludeInCommandLine": false, + "DefaultValue": "8", + "EnumValues": {} + }, + { + "DisplayName": "Alert Window Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Entity Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockEntityOutOfRange.AlertWindowSeconds", + "Keywords": "anticheat,blockentityoutofrange,alertwindowseconds", + "FieldName": "Stratum_main_Anticheat_BlockEntityOutOfRange_AlertWindowSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockEntityOutOfRange.AlertWindowSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "10", + "EnumValues": {} + }, + { + "DisplayName": "Repeat Alert Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Entity Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockEntityOutOfRange.RepeatAlertSeconds", + "Keywords": "anticheat,blockentityoutofrange,repeatalertseconds", + "FieldName": "Stratum_main_Anticheat_BlockEntityOutOfRange_RepeatAlertSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockEntityOutOfRange.RepeatAlertSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "20", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Interaction Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockInteractionOutOfRange.Enabled", + "Keywords": "anticheat,blockinteractionoutofrange,enabled", + "FieldName": "Stratum_main_Anticheat_BlockInteractionOutOfRange_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockInteractionOutOfRange.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Alert After Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Interaction Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockInteractionOutOfRange.AlertAfterViolations", + "Keywords": "anticheat,blockinteractionoutofrange,alertafterviolations", + "FieldName": "Stratum_main_Anticheat_BlockInteractionOutOfRange_AlertAfterViolations", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockInteractionOutOfRange.AlertAfterViolations", + "IncludeInCommandLine": false, + "DefaultValue": "8", + "EnumValues": {} + }, + { + "DisplayName": "Alert Window Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Interaction Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockInteractionOutOfRange.AlertWindowSeconds", + "Keywords": "anticheat,blockinteractionoutofrange,alertwindowseconds", + "FieldName": "Stratum_main_Anticheat_BlockInteractionOutOfRange_AlertWindowSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockInteractionOutOfRange.AlertWindowSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "10", + "EnumValues": {} + }, + { + "DisplayName": "Repeat Alert Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Interaction Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockInteractionOutOfRange.RepeatAlertSeconds", + "Keywords": "anticheat,blockinteractionoutofrange,repeatalertseconds", + "FieldName": "Stratum_main_Anticheat_BlockInteractionOutOfRange_RepeatAlertSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockInteractionOutOfRange.RepeatAlertSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "20", + "EnumValues": {} + }, + { + "DisplayName": "Range Slack", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Interaction Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockInteractionOutOfRange.RangeSlack", + "Keywords": "anticheat,blockinteractionoutofrange,rangeslack", + "FieldName": "Stratum_main_Anticheat_BlockInteractionOutOfRange_RangeSlack", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockInteractionOutOfRange.RangeSlack", + "IncludeInCommandLine": false, + "DefaultValue": "0.75", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Kick Confirmed Cheats", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Interaction Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockInteractionOutOfRange.KickConfirmedCheats", + "Keywords": "anticheat,blockinteractionoutofrange,kickconfirmedcheats", + "FieldName": "Stratum_main_Anticheat_BlockInteractionOutOfRange_KickConfirmedCheats", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockInteractionOutOfRange.KickConfirmedCheats", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Kick After Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Interaction Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockInteractionOutOfRange.KickAfterViolations", + "Keywords": "anticheat,blockinteractionoutofrange,kickafterviolations", + "FieldName": "Stratum_main_Anticheat_BlockInteractionOutOfRange_KickAfterViolations", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockInteractionOutOfRange.KickAfterViolations", + "IncludeInCommandLine": false, + "DefaultValue": "3", + "EnumValues": {} + }, + { + "DisplayName": "Kick Message", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Interaction Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockInteractionOutOfRange.KickMessage", + "Keywords": "anticheat,blockinteractionoutofrange,kickmessage", + "FieldName": "Stratum_main_Anticheat_BlockInteractionOutOfRange_KickMessage", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockInteractionOutOfRange.KickMessage", + "IncludeInCommandLine": false, + "DefaultValue": "Disconnected by Stratum block reach protection", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Entity Interaction Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.EntityInteractionOutOfRange.Enabled", + "Keywords": "anticheat,entityinteractionoutofrange,enabled", + "FieldName": "Stratum_main_Anticheat_EntityInteractionOutOfRange_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.EntityInteractionOutOfRange.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Alert After Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Entity Interaction Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.EntityInteractionOutOfRange.AlertAfterViolations", + "Keywords": "anticheat,entityinteractionoutofrange,alertafterviolations", + "FieldName": "Stratum_main_Anticheat_EntityInteractionOutOfRange_AlertAfterViolations", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.EntityInteractionOutOfRange.AlertAfterViolations", + "IncludeInCommandLine": false, + "DefaultValue": "8", + "EnumValues": {} + }, + { + "DisplayName": "Alert Window Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Entity Interaction Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.EntityInteractionOutOfRange.AlertWindowSeconds", + "Keywords": "anticheat,entityinteractionoutofrange,alertwindowseconds", + "FieldName": "Stratum_main_Anticheat_EntityInteractionOutOfRange_AlertWindowSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.EntityInteractionOutOfRange.AlertWindowSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "10", + "EnumValues": {} + }, + { + "DisplayName": "Repeat Alert Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Entity Interaction Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.EntityInteractionOutOfRange.RepeatAlertSeconds", + "Keywords": "anticheat,entityinteractionoutofrange,repeatalertseconds", + "FieldName": "Stratum_main_Anticheat_EntityInteractionOutOfRange_RepeatAlertSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.EntityInteractionOutOfRange.RepeatAlertSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "20", + "EnumValues": {} + }, + { + "DisplayName": "Range Slack", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Entity Interaction Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.EntityInteractionOutOfRange.RangeSlack", + "Keywords": "anticheat,entityinteractionoutofrange,rangeslack", + "FieldName": "Stratum_main_Anticheat_EntityInteractionOutOfRange_RangeSlack", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.EntityInteractionOutOfRange.RangeSlack", + "IncludeInCommandLine": false, + "DefaultValue": "1.0", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Kick Confirmed Cheats", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Entity Interaction Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.EntityInteractionOutOfRange.KickConfirmedCheats", + "Keywords": "anticheat,entityinteractionoutofrange,kickconfirmedcheats", + "FieldName": "Stratum_main_Anticheat_EntityInteractionOutOfRange_KickConfirmedCheats", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.EntityInteractionOutOfRange.KickConfirmedCheats", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Kick After Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Entity Interaction Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.EntityInteractionOutOfRange.KickAfterViolations", + "Keywords": "anticheat,entityinteractionoutofrange,kickafterviolations", + "FieldName": "Stratum_main_Anticheat_EntityInteractionOutOfRange_KickAfterViolations", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.EntityInteractionOutOfRange.KickAfterViolations", + "IncludeInCommandLine": false, + "DefaultValue": "3", + "EnumValues": {} + }, + { + "DisplayName": "Kick Message", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Entity Interaction Out Of Range:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.EntityInteractionOutOfRange.KickMessage", + "Keywords": "anticheat,entityinteractionoutofrange,kickmessage", + "FieldName": "Stratum_main_Anticheat_EntityInteractionOutOfRange_KickMessage", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.EntityInteractionOutOfRange.KickMessage", + "IncludeInCommandLine": false, + "DefaultValue": "Disconnected by Stratum entity reach protection", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Break Progress:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockBreakProgress.Enabled", + "Keywords": "anticheat,blockbreakprogress,enabled", + "FieldName": "Stratum_main_Anticheat_BlockBreakProgress_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockBreakProgress.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Alert After Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Break Progress:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockBreakProgress.AlertAfterViolations", + "Keywords": "anticheat,blockbreakprogress,alertafterviolations", + "FieldName": "Stratum_main_Anticheat_BlockBreakProgress_AlertAfterViolations", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockBreakProgress.AlertAfterViolations", + "IncludeInCommandLine": false, + "DefaultValue": "8", + "EnumValues": {} + }, + { + "DisplayName": "Alert Window Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Break Progress:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockBreakProgress.AlertWindowSeconds", + "Keywords": "anticheat,blockbreakprogress,alertwindowseconds", + "FieldName": "Stratum_main_Anticheat_BlockBreakProgress_AlertWindowSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockBreakProgress.AlertWindowSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "10", + "EnumValues": {} + }, + { + "DisplayName": "Repeat Alert Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Break Progress:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockBreakProgress.RepeatAlertSeconds", + "Keywords": "anticheat,blockbreakprogress,repeatalertseconds", + "FieldName": "Stratum_main_Anticheat_BlockBreakProgress_RepeatAlertSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockBreakProgress.RepeatAlertSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "20", + "EnumValues": {} + }, + { + "DisplayName": "Kick Confirmed Cheats", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Break Progress:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockBreakProgress.KickConfirmedCheats", + "Keywords": "anticheat,blockbreakprogress,kickconfirmedcheats", + "FieldName": "Stratum_main_Anticheat_BlockBreakProgress_KickConfirmedCheats", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockBreakProgress.KickConfirmedCheats", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Kick After Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Break Progress:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockBreakProgress.KickAfterViolations", + "Keywords": "anticheat,blockbreakprogress,kickafterviolations", + "FieldName": "Stratum_main_Anticheat_BlockBreakProgress_KickAfterViolations", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockBreakProgress.KickAfterViolations", + "IncludeInCommandLine": false, + "DefaultValue": "3", + "EnumValues": {} + }, + { + "DisplayName": "Kick Message", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Block Break Progress:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.BlockBreakProgress.KickMessage", + "Keywords": "anticheat,blockbreakprogress,kickmessage", + "FieldName": "Stratum_main_Anticheat_BlockBreakProgress_KickMessage", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.BlockBreakProgress.KickMessage", + "IncludeInCommandLine": false, + "DefaultValue": "Disconnected by Stratum block break protection", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.Enabled", + "Keywords": "anticheat,movement,enabled", + "FieldName": "Stratum_main_Anticheat_Movement_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Alert After Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.AlertAfterViolations", + "Keywords": "anticheat,movement,alertafterviolations", + "FieldName": "Stratum_main_Anticheat_Movement_AlertAfterViolations", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.AlertAfterViolations", + "IncludeInCommandLine": false, + "DefaultValue": "8", + "EnumValues": {} + }, + { + "DisplayName": "Alert Window Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.AlertWindowSeconds", + "Keywords": "anticheat,movement,alertwindowseconds", + "FieldName": "Stratum_main_Anticheat_Movement_AlertWindowSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.AlertWindowSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "10", + "EnumValues": {} + }, + { + "DisplayName": "Repeat Alert Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.RepeatAlertSeconds", + "Keywords": "anticheat,movement,repeatalertseconds", + "FieldName": "Stratum_main_Anticheat_Movement_RepeatAlertSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.RepeatAlertSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "20", + "EnumValues": {} + }, + { + "DisplayName": "Use Stat Based Speed Limits", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.UseStatBasedSpeedLimits", + "Keywords": "anticheat,movement,usestatbasedspeedlimits", + "FieldName": "Stratum_main_Anticheat_Movement_UseStatBasedSpeedLimits", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.UseStatBasedSpeedLimits", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Horizontal Speed Multiplier", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.HorizontalSpeedMultiplier", + "Keywords": "anticheat,movement,horizontalspeedmultiplier", + "FieldName": "Stratum_main_Anticheat_Movement_HorizontalSpeedMultiplier", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.HorizontalSpeedMultiplier", + "IncludeInCommandLine": false, + "DefaultValue": "3.0", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Airborne Horizontal Multiplier", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.AirborneHorizontalMultiplier", + "Keywords": "anticheat,movement,airbornehorizontalmultiplier", + "FieldName": "Stratum_main_Anticheat_Movement_AirborneHorizontalMultiplier", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.AirborneHorizontalMultiplier", + "IncludeInCommandLine": false, + "DefaultValue": "1.75", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Minimum Horizontal Blocks Per Second", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.MinimumHorizontalBlocksPerSecond", + "Keywords": "anticheat,movement,minimumhorizontalblockspersecond", + "FieldName": "Stratum_main_Anticheat_Movement_MinimumHorizontalBlocksPerSecond", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.MinimumHorizontalBlocksPerSecond", + "IncludeInCommandLine": false, + "DefaultValue": "8.0", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Position Version Accept Distance", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.PositionVersionAcceptDistance", + "Keywords": "anticheat,movement,positionversionacceptdistance", + "FieldName": "Stratum_main_Anticheat_Movement_PositionVersionAcceptDistance", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.PositionVersionAcceptDistance", + "IncludeInCommandLine": false, + "DefaultValue": "4.0", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Max Horizontal Blocks Per Second", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "Fallback cap when stat-based speed limits are disabled, and hard ceiling when they are on. (data/stratum.json -> $.Anticheat.Movement.MaxHorizontalBlocksPerSecond)", + "Keywords": "anticheat,movement,maxhorizontalblockspersecond", + "FieldName": "Stratum_main_Anticheat_Movement_MaxHorizontalBlocksPerSecond", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.MaxHorizontalBlocksPerSecond", + "IncludeInCommandLine": false, + "DefaultValue": "36", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Max Vertical Up Blocks Per Second", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.MaxVerticalUpBlocksPerSecond", + "Keywords": "anticheat,movement,maxverticalupblockspersecond", + "FieldName": "Stratum_main_Anticheat_Movement_MaxVerticalUpBlocksPerSecond", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.MaxVerticalUpBlocksPerSecond", + "IncludeInCommandLine": false, + "DefaultValue": "18", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Cumulative Speed Multiplier", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.CumulativeSpeedMultiplier", + "Keywords": "anticheat,movement,cumulativespeedmultiplier", + "FieldName": "Stratum_main_Anticheat_Movement_CumulativeSpeedMultiplier", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.CumulativeSpeedMultiplier", + "IncludeInCommandLine": false, + "DefaultValue": "2.5", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Max Cumulative Blocks Per Second", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "Hard ceiling for repeated smaller teleports that stay under the per-packet cap. (data/stratum.json -> $.Anticheat.Movement.MaxCumulativeBlocksPerSecond)", + "Keywords": "anticheat,movement,maxcumulativeblockspersecond", + "FieldName": "Stratum_main_Anticheat_Movement_MaxCumulativeBlocksPerSecond", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.MaxCumulativeBlocksPerSecond", + "IncludeInCommandLine": false, + "DefaultValue": "64", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Slack Blocks", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.SlackBlocks", + "Keywords": "anticheat,movement,slackblocks", + "FieldName": "Stratum_main_Anticheat_Movement_SlackBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.SlackBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "2.5", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Mount Max Horizontal Blocks Per Second", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.MountMaxHorizontalBlocksPerSecond", + "Keywords": "anticheat,movement,mountmaxhorizontalblockspersecond", + "FieldName": "Stratum_main_Anticheat_Movement_MountMaxHorizontalBlocksPerSecond", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.MountMaxHorizontalBlocksPerSecond", + "IncludeInCommandLine": false, + "DefaultValue": "96", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Mount Max Vertical Up Blocks Per Second", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.MountMaxVerticalUpBlocksPerSecond", + "Keywords": "anticheat,movement,mountmaxverticalupblockspersecond", + "FieldName": "Stratum_main_Anticheat_Movement_MountMaxVerticalUpBlocksPerSecond", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.MountMaxVerticalUpBlocksPerSecond", + "IncludeInCommandLine": false, + "DefaultValue": "36", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Mount Max Cumulative Blocks Per Second", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.MountMaxCumulativeBlocksPerSecond", + "Keywords": "anticheat,movement,mountmaxcumulativeblockspersecond", + "FieldName": "Stratum_main_Anticheat_Movement_MountMaxCumulativeBlocksPerSecond", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.MountMaxCumulativeBlocksPerSecond", + "IncludeInCommandLine": false, + "DefaultValue": "160", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Mount Slack Blocks", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.MountSlackBlocks", + "Keywords": "anticheat,movement,mountslackblocks", + "FieldName": "Stratum_main_Anticheat_Movement_MountSlackBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.MountSlackBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "8", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Kick Confirmed Cheats", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.KickConfirmedCheats", + "Keywords": "anticheat,movement,kickconfirmedcheats", + "FieldName": "Stratum_main_Anticheat_Movement_KickConfirmedCheats", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.KickConfirmedCheats", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Kick After Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.KickAfterViolations", + "Keywords": "anticheat,movement,kickafterviolations", + "FieldName": "Stratum_main_Anticheat_Movement_KickAfterViolations", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.KickAfterViolations", + "IncludeInCommandLine": false, + "DefaultValue": "10", + "EnumValues": {} + }, + { + "DisplayName": "Kick Message", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.KickMessage", + "Keywords": "anticheat,movement,kickmessage", + "FieldName": "Stratum_main_Anticheat_Movement_KickMessage", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.KickMessage", + "IncludeInCommandLine": false, + "DefaultValue": "Disconnected by Stratum movement protection", + "EnumValues": {} + }, + { + "DisplayName": "Detect Flight", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "Handles slow hover and air-walk cases that never trip the speed caps. (data/stratum.json -> $.Anticheat.Movement.DetectFlight)", + "Keywords": "anticheat,movement,detectflight", + "FieldName": "Stratum_main_Anticheat_Movement_DetectFlight", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.DetectFlight", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Detect Water Walk", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.DetectWaterWalk", + "Keywords": "anticheat,movement,detectwaterwalk", + "FieldName": "Stratum_main_Anticheat_Movement_DetectWaterWalk", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.DetectWaterWalk", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Water Walk Consecutive Ticks", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.WaterWalkConsecutiveTicks", + "Keywords": "anticheat,movement,waterwalkconsecutiveticks", + "FieldName": "Stratum_main_Anticheat_Movement_WaterWalkConsecutiveTicks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.WaterWalkConsecutiveTicks", + "IncludeInCommandLine": false, + "DefaultValue": "3", + "EnumValues": {} + }, + { + "DisplayName": "Water Walk Entry Grace Ms", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.WaterWalkEntryGraceMs", + "Keywords": "anticheat,movement,waterwalkentrygracems", + "FieldName": "Stratum_main_Anticheat_Movement_WaterWalkEntryGraceMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.WaterWalkEntryGraceMs", + "IncludeInCommandLine": false, + "DefaultValue": "900", + "EnumValues": {} + }, + { + "DisplayName": "Ground Contact Tolerance", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.GroundContactTolerance", + "Keywords": "anticheat,movement,groundcontacttolerance", + "FieldName": "Stratum_main_Anticheat_Movement_GroundContactTolerance", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.GroundContactTolerance", + "IncludeInCommandLine": false, + "DefaultValue": "0.04", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Flight Ground Scan Depth", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "Extra cells below the real ground contact check. Keep this low unless testing proves otherwise. (data/stratum.json -> $.Anticheat.Movement.FlightGroundScanDepth)", + "Keywords": "anticheat,movement,flightgroundscandepth", + "FieldName": "Stratum_main_Anticheat_Movement_FlightGroundScanDepth", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.FlightGroundScanDepth", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Flight Min Airborne Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.FlightMinAirborneSeconds", + "Keywords": "anticheat,movement,flightminairborneseconds", + "FieldName": "Stratum_main_Anticheat_Movement_FlightMinAirborneSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.FlightMinAirborneSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "1.75", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Flight Required Descent Blocks", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.FlightRequiredDescentBlocks", + "Keywords": "anticheat,movement,flightrequireddescentblocks", + "FieldName": "Stratum_main_Anticheat_Movement_FlightRequiredDescentBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.FlightRequiredDescentBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "0.35", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Detect Noclip", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "Chest-only by design. Feet collide with too many normal partial blocks. (data/stratum.json -> $.Anticheat.Movement.DetectNoclip)", + "Keywords": "anticheat,movement,detectnoclip", + "FieldName": "Stratum_main_Anticheat_Movement_DetectNoclip", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.DetectNoclip", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Noclip Consecutive Ticks", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Movement.NoclipConsecutiveTicks", + "Keywords": "anticheat,movement,noclipconsecutiveticks", + "FieldName": "Stratum_main_Anticheat_Movement_NoclipConsecutiveTicks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Movement.NoclipConsecutiveTicks", + "IncludeInCommandLine": false, + "DefaultValue": "3", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Combat:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Combat.Enabled", + "Keywords": "anticheat,combat,enabled", + "FieldName": "Stratum_main_Anticheat_Combat_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Combat.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Alert After Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Combat:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Combat.AlertAfterViolations", + "Keywords": "anticheat,combat,alertafterviolations", + "FieldName": "Stratum_main_Anticheat_Combat_AlertAfterViolations", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Combat.AlertAfterViolations", + "IncludeInCommandLine": false, + "DefaultValue": "8", + "EnumValues": {} + }, + { + "DisplayName": "Alert Window Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Combat:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Combat.AlertWindowSeconds", + "Keywords": "anticheat,combat,alertwindowseconds", + "FieldName": "Stratum_main_Anticheat_Combat_AlertWindowSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Combat.AlertWindowSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "10", + "EnumValues": {} + }, + { + "DisplayName": "Repeat Alert Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Combat:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Combat.RepeatAlertSeconds", + "Keywords": "anticheat,combat,repeatalertseconds", + "FieldName": "Stratum_main_Anticheat_Combat_RepeatAlertSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Combat.RepeatAlertSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "20", + "EnumValues": {} + }, + { + "DisplayName": "Detect Multi Target", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Combat:gpp_maybe:10", + "Description": "Attacking several distinct entities in a tiny window is physically impossible with a real client (one target per swing, one crosshair). This is the highest-confidence signal here. (data/stratum.json -> $.Anticheat.Combat.DetectMultiTarget)", + "Keywords": "anticheat,combat,detectmultitarget", + "FieldName": "Stratum_main_Anticheat_Combat_DetectMultiTarget", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Combat.DetectMultiTarget", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Multi Target Window Ms", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Combat:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Combat.MultiTargetWindowMs", + "Keywords": "anticheat,combat,multitargetwindowms", + "FieldName": "Stratum_main_Anticheat_Combat_MultiTargetWindowMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Combat.MultiTargetWindowMs", + "IncludeInCommandLine": false, + "DefaultValue": "400", + "EnumValues": {} + }, + { + "DisplayName": "Multi Target Threshold", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Combat:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Combat.MultiTargetThreshold", + "Keywords": "anticheat,combat,multitargetthreshold", + "FieldName": "Stratum_main_Anticheat_Combat_MultiTargetThreshold", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Combat.MultiTargetThreshold", + "IncludeInCommandLine": false, + "DefaultValue": "3", + "EnumValues": {} + }, + { + "DisplayName": "Detect Aim Cone", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Combat:gpp_maybe:10", + "Description": "Flags an attack whose target sits outside the player's aim cone. Kept generous so ordinary aiming plus lag never trips it; the point is to catch hits landed on entities beside or behind the player, which only an aura does. (data/stratum.json -> $.Anticheat.Combat.DetectAimCone)", + "Keywords": "anticheat,combat,detectaimcone", + "FieldName": "Stratum_main_Anticheat_Combat_DetectAimCone", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Combat.DetectAimCone", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Max Attack Angle Degrees", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Combat:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Combat.MaxAttackAngleDegrees", + "Keywords": "anticheat,combat,maxattackangledegrees", + "FieldName": "Stratum_main_Anticheat_Combat_MaxAttackAngleDegrees", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Combat.MaxAttackAngleDegrees", + "IncludeInCommandLine": false, + "DefaultValue": "75.0", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Min Angle Check Distance", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Combat:gpp_maybe:10", + "Description": "Skip the cone test when the target is basically touching the player, where the geometry of a large hitbox makes the angle meaningless. (data/stratum.json -> $.Anticheat.Combat.MinAngleCheckDistance)", + "Keywords": "anticheat,combat,minanglecheckdistance", + "FieldName": "Stratum_main_Anticheat_Combat_MinAngleCheckDistance", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Combat.MinAngleCheckDistance", + "IncludeInCommandLine": false, + "DefaultValue": "1.5", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Kick Confirmed Cheats", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Combat:gpp_maybe:10", + "Description": "Combat heuristics start as monitor-only. Turn this on once a server has watched the /stratum ac combat data and is comfortable the false-positive rate is zero. (data/stratum.json -> $.Anticheat.Combat.KickConfirmedCheats)", + "Keywords": "anticheat,combat,kickconfirmedcheats", + "FieldName": "Stratum_main_Anticheat_Combat_KickConfirmedCheats", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Combat.KickConfirmedCheats", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Kick After Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Combat:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Combat.KickAfterViolations", + "Keywords": "anticheat,combat,kickafterviolations", + "FieldName": "Stratum_main_Anticheat_Combat_KickAfterViolations", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Combat.KickAfterViolations", + "IncludeInCommandLine": false, + "DefaultValue": "12", + "EnumValues": {} + }, + { + "DisplayName": "Kick Message", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Combat:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.Combat.KickMessage", + "Keywords": "anticheat,combat,kickmessage", + "FieldName": "Stratum_main_Anticheat_Combat_KickMessage", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Combat.KickMessage", + "IncludeInCommandLine": false, + "DefaultValue": "Disconnected by Stratum combat protection", + "EnumValues": {} + }, + { + "DisplayName": "Cancel Flagged Hits", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Combat:gpp_maybe:10", + "Description": "When on, a flagged hit is dropped instead of applied. Off by default so v1 never changes the outcome of any hit; a real client can't trigger these checks anyway. (data/stratum.json -> $.Anticheat.Combat.CancelFlaggedHits)", + "Keywords": "anticheat,combat,cancelflaggedhits", + "FieldName": "Stratum_main_Anticheat_Combat_CancelFlaggedHits", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.Combat.CancelFlaggedHits", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > No Fall:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.NoFall.Enabled", + "Keywords": "anticheat,nofall,enabled", + "FieldName": "Stratum_main_Anticheat_NoFall_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.NoFall.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Alert After Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > No Fall:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.NoFall.AlertAfterViolations", + "Keywords": "anticheat,nofall,alertafterviolations", + "FieldName": "Stratum_main_Anticheat_NoFall_AlertAfterViolations", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.NoFall.AlertAfterViolations", + "IncludeInCommandLine": false, + "DefaultValue": "8", + "EnumValues": {} + }, + { + "DisplayName": "Alert Window Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > No Fall:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.NoFall.AlertWindowSeconds", + "Keywords": "anticheat,nofall,alertwindowseconds", + "FieldName": "Stratum_main_Anticheat_NoFall_AlertWindowSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.NoFall.AlertWindowSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "10", + "EnumValues": {} + }, + { + "DisplayName": "Repeat Alert Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > No Fall:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.NoFall.RepeatAlertSeconds", + "Keywords": "anticheat,nofall,repeatalertseconds", + "FieldName": "Stratum_main_Anticheat_NoFall_RepeatAlertSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.NoFall.RepeatAlertSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "20", + "EnumValues": {} + }, + { + "DisplayName": "Min Fall Blocks", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > No Fall:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.NoFall.MinFallBlocks", + "Keywords": "anticheat,nofall,minfallblocks", + "FieldName": "Stratum_main_Anticheat_NoFall_MinFallBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.NoFall.MinFallBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "5.0", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Min Descent Speed", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > No Fall:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.NoFall.MinDescentSpeed", + "Keywords": "anticheat,nofall,mindescentspeed", + "FieldName": "Stratum_main_Anticheat_NoFall_MinDescentSpeed", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.NoFall.MinDescentSpeed", + "IncludeInCommandLine": false, + "DefaultValue": "4.0", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Kick Confirmed Cheats", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > No Fall:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.NoFall.KickConfirmedCheats", + "Keywords": "anticheat,nofall,kickconfirmedcheats", + "FieldName": "Stratum_main_Anticheat_NoFall_KickConfirmedCheats", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.NoFall.KickConfirmedCheats", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Kick After Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > No Fall:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.NoFall.KickAfterViolations", + "Keywords": "anticheat,nofall,kickafterviolations", + "FieldName": "Stratum_main_Anticheat_NoFall_KickAfterViolations", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.NoFall.KickAfterViolations", + "IncludeInCommandLine": false, + "DefaultValue": "10", + "EnumValues": {} + }, + { + "DisplayName": "Kick Message", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > No Fall:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.NoFall.KickMessage", + "Keywords": "anticheat,nofall,kickmessage", + "FieldName": "Stratum_main_Anticheat_NoFall_KickMessage", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.NoFall.KickMessage", + "IncludeInCommandLine": false, + "DefaultValue": "Disconnected by Stratum no-fall protection", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MultiBreak.Enabled", + "Keywords": "anticheat,multibreak,enabled", + "FieldName": "Stratum_main_Anticheat_MultiBreak_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MultiBreak.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Alert After Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MultiBreak.AlertAfterViolations", + "Keywords": "anticheat,multibreak,alertafterviolations", + "FieldName": "Stratum_main_Anticheat_MultiBreak_AlertAfterViolations", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MultiBreak.AlertAfterViolations", + "IncludeInCommandLine": false, + "DefaultValue": "8", + "EnumValues": {} + }, + { + "DisplayName": "Alert Window Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MultiBreak.AlertWindowSeconds", + "Keywords": "anticheat,multibreak,alertwindowseconds", + "FieldName": "Stratum_main_Anticheat_MultiBreak_AlertWindowSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MultiBreak.AlertWindowSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "10", + "EnumValues": {} + }, + { + "DisplayName": "Repeat Alert Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MultiBreak.RepeatAlertSeconds", + "Keywords": "anticheat,multibreak,repeatalertseconds", + "FieldName": "Stratum_main_Anticheat_MultiBreak_RepeatAlertSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MultiBreak.RepeatAlertSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "20", + "EnumValues": {} + }, + { + "DisplayName": "Window Ms", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MultiBreak.WindowMs", + "Keywords": "anticheat,multibreak,windowms", + "FieldName": "Stratum_main_Anticheat_MultiBreak_WindowMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MultiBreak.WindowMs", + "IncludeInCommandLine": false, + "DefaultValue": "300", + "EnumValues": {} + }, + { + "DisplayName": "Max Breaks In Window", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MultiBreak.MaxBreaksInWindow", + "Keywords": "anticheat,multibreak,maxbreaksinwindow", + "FieldName": "Stratum_main_Anticheat_MultiBreak_MaxBreaksInWindow", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MultiBreak.MaxBreaksInWindow", + "IncludeInCommandLine": false, + "DefaultValue": "6", + "EnumValues": {} + }, + { + "DisplayName": "Max Tracked Breaks", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", + "Description": "Cap on tracked positions per player so a huge radius nuke can't grow memory (data/stratum.json -> $.Anticheat.MultiBreak.MaxTrackedBreaks)", + "Keywords": "anticheat,multibreak,maxtrackedbreaks", + "FieldName": "Stratum_main_Anticheat_MultiBreak_MaxTrackedBreaks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MultiBreak.MaxTrackedBreaks", + "IncludeInCommandLine": false, + "DefaultValue": "128", + "EnumValues": {} + }, + { + "DisplayName": "Kick Confirmed Cheats", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", + "Description": "Off by default: monitor-only (data/stratum.json -> $.Anticheat.MultiBreak.KickConfirmedCheats)", + "Keywords": "anticheat,multibreak,kickconfirmedcheats", + "FieldName": "Stratum_main_Anticheat_MultiBreak_KickConfirmedCheats", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MultiBreak.KickConfirmedCheats", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Kick After Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MultiBreak.KickAfterViolations", + "Keywords": "anticheat,multibreak,kickafterviolations", + "FieldName": "Stratum_main_Anticheat_MultiBreak_KickAfterViolations", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MultiBreak.KickAfterViolations", + "IncludeInCommandLine": false, + "DefaultValue": "4", + "EnumValues": {} + }, + { + "DisplayName": "Kick Message", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MultiBreak.KickMessage", + "Keywords": "anticheat,multibreak,kickmessage", + "FieldName": "Stratum_main_Anticheat_MultiBreak_KickMessage", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MultiBreak.KickMessage", + "IncludeInCommandLine": false, + "DefaultValue": "Disconnected by Stratum multi-break protection", + "EnumValues": {} + }, + { + "DisplayName": "Kick On Fingerprint", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", + "Description": "when every hit lands dead-centre (0.5,0.5,0.5) can't come from a real raytrace, which always strikes a block surface. Combined with the superhuman burst rate this is near-zero false-positive, so such a burst may kick immediately even while KickConfirmedCheats stays off. (data/stratum.json -> $.Anticheat.MultiBreak.KickOnFingerprint)", + "Keywords": "anticheat,multibreak,kickonfingerprint", + "FieldName": "Stratum_main_Anticheat_MultiBreak_KickOnFingerprint", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MultiBreak.KickOnFingerprint", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.Enabled", + "Keywords": "anticheat,movementauthority,enabled", + "FieldName": "Stratum_main_Anticheat_MovementAuthority_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MovementAuthority.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Alert After Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.AlertAfterViolations", + "Keywords": "anticheat,movementauthority,alertafterviolations", + "FieldName": "Stratum_main_Anticheat_MovementAuthority_AlertAfterViolations", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MovementAuthority.AlertAfterViolations", + "IncludeInCommandLine": false, + "DefaultValue": "8", + "EnumValues": {} + }, + { + "DisplayName": "Alert Window Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.AlertWindowSeconds", + "Keywords": "anticheat,movementauthority,alertwindowseconds", + "FieldName": "Stratum_main_Anticheat_MovementAuthority_AlertWindowSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MovementAuthority.AlertWindowSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "10", + "EnumValues": {} + }, + { + "DisplayName": "Repeat Alert Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.RepeatAlertSeconds", + "Keywords": "anticheat,movementauthority,repeatalertseconds", + "FieldName": "Stratum_main_Anticheat_MovementAuthority_RepeatAlertSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MovementAuthority.RepeatAlertSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "20", + "EnumValues": {} + }, + { + "DisplayName": "Detect Step Height", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.DetectStepHeight", + "Keywords": "anticheat,movementauthority,detectstepheight", + "FieldName": "Stratum_main_Anticheat_MovementAuthority_DetectStepHeight", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MovementAuthority.DetectStepHeight", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Max Step Height Blocks", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.MaxStepHeightBlocks", + "Keywords": "anticheat,movementauthority,maxstepheightblocks", + "FieldName": "Stratum_main_Anticheat_MovementAuthority_MaxStepHeightBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MovementAuthority.MaxStepHeightBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "1.3", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Step Max Horizontal Blocks", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.StepMaxHorizontalBlocks", + "Keywords": "anticheat,movementauthority,stepmaxhorizontalblocks", + "FieldName": "Stratum_main_Anticheat_MovementAuthority_StepMaxHorizontalBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MovementAuthority.StepMaxHorizontalBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "1.5", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Detect Acceleration", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.DetectAcceleration", + "Keywords": "anticheat,movementauthority,detectacceleration", + "FieldName": "Stratum_main_Anticheat_MovementAuthority_DetectAcceleration", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MovementAuthority.DetectAcceleration", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Max Speed Jump Blocks Per Second", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.MaxSpeedJumpBlocksPerSecond", + "Keywords": "anticheat,movementauthority,maxspeedjumpblockspersecond", + "FieldName": "Stratum_main_Anticheat_MovementAuthority_MaxSpeedJumpBlocksPerSecond", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MovementAuthority.MaxSpeedJumpBlocksPerSecond", + "IncludeInCommandLine": false, + "DefaultValue": "16.0", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Min Flagged Speed", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.MinFlaggedSpeed", + "Keywords": "anticheat,movementauthority,minflaggedspeed", + "FieldName": "Stratum_main_Anticheat_MovementAuthority_MinFlaggedSpeed", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MovementAuthority.MinFlaggedSpeed", + "IncludeInCommandLine": false, + "DefaultValue": "12.0", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Kick Confirmed Cheats", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.KickConfirmedCheats", + "Keywords": "anticheat,movementauthority,kickconfirmedcheats", + "FieldName": "Stratum_main_Anticheat_MovementAuthority_KickConfirmedCheats", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MovementAuthority.KickConfirmedCheats", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Kick After Violations", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.KickAfterViolations", + "Keywords": "anticheat,movementauthority,kickafterviolations", + "FieldName": "Stratum_main_Anticheat_MovementAuthority_KickAfterViolations", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MovementAuthority.KickAfterViolations", + "IncludeInCommandLine": false, + "DefaultValue": "8", + "EnumValues": {} + }, + { + "DisplayName": "Kick Message", + "Category": "Stratum:filter_alt", + "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", + "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.KickMessage", + "Keywords": "anticheat,movementauthority,kickmessage", + "FieldName": "Stratum_main_Anticheat_MovementAuthority_KickMessage", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Anticheat.MovementAuthority.KickMessage", + "IncludeInCommandLine": false, + "DefaultValue": "Disconnected by Stratum movement protection", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Client Mod Policy:extension:10", + "Description": "data/stratum.json -> $.ClientModPolicy.Enabled", + "Keywords": "clientmodpolicy,enabled", + "FieldName": "Stratum_main_ClientModPolicy_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ClientModPolicy.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Strict Whitelist", + "Category": "Stratum:filter_alt", + "Subcategory": "Client Mod Policy:extension:10", + "Description": "data/stratum.json -> $.ClientModPolicy.StrictWhitelist", + "Keywords": "clientmodpolicy,strictwhitelist", + "FieldName": "Stratum_main_ClientModPolicy_StrictWhitelist", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ClientModPolicy.StrictWhitelist", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Include Server Universal Mods", + "Category": "Stratum:filter_alt", + "Subcategory": "Client Mod Policy:extension:10", + "Description": "data/stratum.json -> $.ClientModPolicy.IncludeServerUniversalMods", + "Keywords": "clientmodpolicy,includeserveruniversalmods", + "FieldName": "Stratum_main_ClientModPolicy_IncludeServerUniversalMods", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ClientModPolicy.IncludeServerUniversalMods", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Log Policy On Startup", + "Category": "Stratum:filter_alt", + "Subcategory": "Client Mod Policy:extension:10", + "Description": "data/stratum.json -> $.ClientModPolicy.LogPolicyOnStartup", + "Keywords": "clientmodpolicy,logpolicyonstartup", + "FieldName": "Stratum_main_ClientModPolicy_LogPolicyOnStartup", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ClientModPolicy.LogPolicyOnStartup", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Split Terrain Pass", + "Category": "Stratum:filter_alt", + "Subcategory": "Worldgen:public:10", + "Description": "Runs the Terrain pass as two sub-stages so two threads can share it. Off gives the stock single-stage pass. See StratumWorldgenCompat. (data/stratum.json -> $.Worldgen.SplitTerrainPass)", + "Keywords": "worldgen,splitterrainpass", + "FieldName": "Stratum_main_Worldgen_SplitTerrainPass", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Worldgen.SplitTerrainPass", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Auto Disable Split For Mods", + "Category": "Stratum:filter_alt", + "Subcategory": "Worldgen:public:10", + "Description": "Drops back to the vanilla single-stage pass when a mod registers a handler there or patches a generator inside it. Leave on unless you have checked this server's mods. (data/stratum.json -> $.Worldgen.AutoDisableSplitForMods)", + "Keywords": "worldgen,autodisablesplitformods", + "FieldName": "Stratum_main_Worldgen_AutoDisableSplitForMods", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Worldgen.AutoDisableSplitForMods", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Chat:chat:10", + "Description": "data/stratum.json -> $.Chat.Enabled", + "Keywords": "chat,enabled", + "FieldName": "Stratum_main_Chat_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Chat.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Linkify Urls", + "Category": "Stratum:filter_alt", + "Subcategory": "Chat:chat:10", + "Description": "data/stratum.json -> $.Chat.LinkifyUrls", + "Keywords": "chat,linkifyurls", + "FieldName": "Stratum_main_Chat_LinkifyUrls", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Chat.LinkifyUrls", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Show Joins", + "Category": "Stratum:filter_alt", + "Subcategory": "Chat > Connection Messages:chat:10", + "Description": "data/stratum.json -> $.Chat.ConnectionMessages.ShowJoins", + "Keywords": "chat,connectionmessages,showjoins", + "FieldName": "Stratum_main_Chat_ConnectionMessages_ShowJoins", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Chat.ConnectionMessages.ShowJoins", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Show Leaves", + "Category": "Stratum:filter_alt", + "Subcategory": "Chat > Connection Messages:chat:10", + "Description": "data/stratum.json -> $.Chat.ConnectionMessages.ShowLeaves", + "Keywords": "chat,connectionmessages,showleaves", + "FieldName": "Stratum_main_Chat_ConnectionMessages_ShowLeaves", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Chat.ConnectionMessages.ShowLeaves", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Show Disconnects", + "Category": "Stratum:filter_alt", + "Subcategory": "Chat > Connection Messages:chat:10", + "Description": "data/stratum.json -> $.Chat.ConnectionMessages.ShowDisconnects", + "Keywords": "chat,connectionmessages,showdisconnects", + "FieldName": "Stratum_main_Chat_ConnectionMessages_ShowDisconnects", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Chat.ConnectionMessages.ShowDisconnects", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Chat > Rate Limit:chat:10", + "Description": "data/stratum.json -> $.Chat.RateLimit.Enabled", + "Keywords": "chat,ratelimit,enabled", + "FieldName": "Stratum_main_Chat_RateLimit_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Chat.RateLimit.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Minimum Interval Ms", + "Category": "Stratum:filter_alt", + "Subcategory": "Chat > Rate Limit:chat:10", + "Description": "data/stratum.json -> $.Chat.RateLimit.MinimumIntervalMs", + "Keywords": "chat,ratelimit,minimumintervalms", + "FieldName": "Stratum_main_Chat_RateLimit_MinimumIntervalMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Chat.RateLimit.MinimumIntervalMs", + "IncludeInCommandLine": false, + "DefaultValue": "750", + "EnumValues": {} + }, + { + "DisplayName": "Drop Duplicates", + "Category": "Stratum:filter_alt", + "Subcategory": "Chat > Rate Limit:chat:10", + "Description": "data/stratum.json -> $.Chat.RateLimit.DropDuplicates", + "Keywords": "chat,ratelimit,dropduplicates", + "FieldName": "Stratum_main_Chat_RateLimit_DropDuplicates", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Chat.RateLimit.DropDuplicates", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Duplicate Window Ms", + "Category": "Stratum:filter_alt", + "Subcategory": "Chat > Rate Limit:chat:10", + "Description": "data/stratum.json -> $.Chat.RateLimit.DuplicateWindowMs", + "Keywords": "chat,ratelimit,duplicatewindowms", + "FieldName": "Stratum_main_Chat_RateLimit_DuplicateWindowMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Chat.RateLimit.DuplicateWindowMs", + "IncludeInCommandLine": false, + "DefaultValue": "3000", + "EnumValues": {} + }, + { + "DisplayName": "Exempt Commands", + "Category": "Stratum:filter_alt", + "Subcategory": "Chat > Rate Limit:chat:10", + "Description": "data/stratum.json -> $.Chat.RateLimit.ExemptCommands", + "Keywords": "chat,ratelimit,exemptcommands", + "FieldName": "Stratum_main_Chat_RateLimit_ExemptCommands", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Chat.RateLimit.ExemptCommands", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Appearance > Theme:palette:10", + "Description": "data/stratum.json -> $.Appearance.Theme.Enabled", + "Keywords": "appearance,theme,enabled", + "FieldName": "Stratum_main_Appearance_Theme_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Appearance.Theme.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Style Disconnect Screens", + "Category": "Stratum:filter_alt", + "Subcategory": "Appearance > Theme:palette:10", + "Description": "data/stratum.json -> $.Appearance.Theme.StyleDisconnectScreens", + "Keywords": "appearance,theme,styledisconnectscreens", + "FieldName": "Stratum_main_Appearance_Theme_StyleDisconnectScreens", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Appearance.Theme.StyleDisconnectScreens", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Style Join Leave Messages", + "Category": "Stratum:filter_alt", + "Subcategory": "Appearance > Theme:palette:10", + "Description": "data/stratum.json -> $.Appearance.Theme.StyleJoinLeaveMessages", + "Keywords": "appearance,theme,stylejoinleavemessages", + "FieldName": "Stratum_main_Appearance_Theme_StyleJoinLeaveMessages", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Appearance.Theme.StyleJoinLeaveMessages", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Style Welcome Messages", + "Category": "Stratum:filter_alt", + "Subcategory": "Appearance > Theme:palette:10", + "Description": "data/stratum.json -> $.Appearance.Theme.StyleWelcomeMessages", + "Keywords": "appearance,theme,stylewelcomemessages", + "FieldName": "Stratum_main_Appearance_Theme_StyleWelcomeMessages", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Appearance.Theme.StyleWelcomeMessages", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Brand Name", + "Category": "Stratum:filter_alt", + "Subcategory": "Appearance > Theme:palette:10", + "Description": "data/stratum.json -> $.Appearance.Theme.BrandName", + "Keywords": "appearance,theme,brandname", + "FieldName": "Stratum_main_Appearance_Theme_BrandName", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Appearance.Theme.BrandName", + "IncludeInCommandLine": false, + "DefaultValue": "Stratum", + "EnumValues": {} + }, + { + "DisplayName": "Accent Color", + "Category": "Stratum:filter_alt", + "Subcategory": "Appearance > Theme:palette:10", + "Description": "data/stratum.json -> $.Appearance.Theme.AccentColor", + "Keywords": "appearance,theme,accentcolor", + "FieldName": "Stratum_main_Appearance_Theme_AccentColor", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Appearance.Theme.AccentColor", + "IncludeInCommandLine": false, + "DefaultValue": "#8bd5ff", + "EnumValues": {} + }, + { + "DisplayName": "Good Color", + "Category": "Stratum:filter_alt", + "Subcategory": "Appearance > Theme:palette:10", + "Description": "data/stratum.json -> $.Appearance.Theme.GoodColor", + "Keywords": "appearance,theme,goodcolor", + "FieldName": "Stratum_main_Appearance_Theme_GoodColor", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Appearance.Theme.GoodColor", + "IncludeInCommandLine": false, + "DefaultValue": "#9bd77e", + "EnumValues": {} + }, + { + "DisplayName": "Warn Color", + "Category": "Stratum:filter_alt", + "Subcategory": "Appearance > Theme:palette:10", + "Description": "data/stratum.json -> $.Appearance.Theme.WarnColor", + "Keywords": "appearance,theme,warncolor", + "FieldName": "Stratum_main_Appearance_Theme_WarnColor", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Appearance.Theme.WarnColor", + "IncludeInCommandLine": false, + "DefaultValue": "#e6c15f", + "EnumValues": {} + }, + { + "DisplayName": "Bad Color", + "Category": "Stratum:filter_alt", + "Subcategory": "Appearance > Theme:palette:10", + "Description": "data/stratum.json -> $.Appearance.Theme.BadColor", + "Keywords": "appearance,theme,badcolor", + "FieldName": "Stratum_main_Appearance_Theme_BadColor", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Appearance.Theme.BadColor", + "IncludeInCommandLine": false, + "DefaultValue": "#e47d68", + "EnumValues": {} + }, + { + "DisplayName": "Muted Color", + "Category": "Stratum:filter_alt", + "Subcategory": "Appearance > Theme:palette:10", + "Description": "data/stratum.json -> $.Appearance.Theme.MutedColor", + "Keywords": "appearance,theme,mutedcolor", + "FieldName": "Stratum_main_Appearance_Theme_MutedColor", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Appearance.Theme.MutedColor", + "IncludeInCommandLine": false, + "DefaultValue": "#9aa8b5", + "EnumValues": {} + }, + { + "DisplayName": "Label Color", + "Category": "Stratum:filter_alt", + "Subcategory": "Appearance > Theme:palette:10", + "Description": "data/stratum.json -> $.Appearance.Theme.LabelColor", + "Keywords": "appearance,theme,labelcolor", + "FieldName": "Stratum_main_Appearance_Theme_LabelColor", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Appearance.Theme.LabelColor", + "IncludeInCommandLine": false, + "DefaultValue": "#c9d6e2", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Appearance > Role Prefixes:palette:10", + "Description": "data/stratum.json -> $.Appearance.RolePrefixes.Enabled", + "Keywords": "appearance,roleprefixes,enabled", + "FieldName": "Stratum_main_Appearance_RolePrefixes_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Appearance.RolePrefixes.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Format", + "Category": "Stratum:filter_alt", + "Subcategory": "Appearance > Role Prefixes:palette:10", + "Description": "data/stratum.json -> $.Appearance.RolePrefixes.Format", + "Keywords": "appearance,roleprefixes,format", + "FieldName": "Stratum_main_Appearance_RolePrefixes_Format", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Appearance.RolePrefixes.Format", + "IncludeInCommandLine": false, + "DefaultValue": "[{tag}]", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Appearance > Nametags:palette:10", + "Description": "data/stratum.json -> $.Appearance.Nametags.Enabled", + "Keywords": "appearance,nametags,enabled", + "FieldName": "Stratum_main_Appearance_Nametags_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Appearance.Nametags.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Apply Role Prefix", + "Category": "Stratum:filter_alt", + "Subcategory": "Appearance > Nametags:palette:10", + "Description": "data/stratum.json -> $.Appearance.Nametags.ApplyRolePrefix", + "Keywords": "appearance,nametags,applyroleprefix", + "FieldName": "Stratum_main_Appearance_Nametags_ApplyRolePrefix", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Appearance.Nametags.ApplyRolePrefix", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Prefix Format", + "Category": "Stratum:filter_alt", + "Subcategory": "Appearance > Nametags:palette:10", + "Description": "data/stratum.json -> $.Appearance.Nametags.PrefixFormat", + "Keywords": "appearance,nametags,prefixformat", + "FieldName": "Stratum_main_Appearance_Nametags_PrefixFormat", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Appearance.Nametags.PrefixFormat", + "IncludeInCommandLine": false, + "DefaultValue": "[{tag}] ", + "EnumValues": {} + }, + { + "DisplayName": "Only Inject If No Existing Entitlement", + "Category": "Stratum:filter_alt", + "Subcategory": "Appearance > Nametags:palette:10", + "Description": "data/stratum.json -> $.Appearance.Nametags.OnlyInjectIfNoExistingEntitlement", + "Keywords": "appearance,nametags,onlyinjectifnoexistingentitlement", + "FieldName": "Stratum_main_Appearance_Nametags_OnlyInjectIfNoExistingEntitlement", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Appearance.Nametags.OnlyInjectIfNoExistingEntitlement", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Rules", + "Category": "Stratum:filter_alt", + "Subcategory": "Server Info:info:10", + "Description": "data/stratum.json -> $.ServerInfo.Rules", + "Keywords": "serverinfo,rules", + "FieldName": "Stratum_main_ServerInfo_Rules", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.ServerInfo.Rules", + "IncludeInCommandLine": false, + "DefaultValue": "Rules: be respectful, no griefing, no cheating, no harassment, and do not abuse exploits.", + "EnumValues": {} + }, + { + "DisplayName": "Discord Url", + "Category": "Stratum:filter_alt", + "Subcategory": "Server Info:info:10", + "Description": "data/stratum.json -> $.ServerInfo.DiscordUrl", + "Keywords": "serverinfo,discordurl", + "FieldName": "Stratum_main_ServerInfo_DiscordUrl", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.ServerInfo.DiscordUrl", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Website Url", + "Category": "Stratum:filter_alt", + "Subcategory": "Server Info:info:10", + "Description": "data/stratum.json -> $.ServerInfo.WebsiteUrl", + "Keywords": "serverinfo,websiteurl", + "FieldName": "Stratum_main_ServerInfo_WebsiteUrl", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.ServerInfo.WebsiteUrl", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Motd", + "Category": "Stratum:filter_alt", + "Subcategory": "Server Info:info:10", + "Description": "data/stratum.json -> $.ServerInfo.Motd", + "Keywords": "serverinfo,motd", + "FieldName": "Stratum_main_ServerInfo_Motd", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.ServerInfo.Motd", + "IncludeInCommandLine": false, + "DefaultValue": "Welcome to this Stratum server.", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Crowd Spawn:groups:10", + "Description": "data/stratum.json -> $.CrowdSpawn.Enabled", + "Keywords": "crowdspawn,enabled", + "FieldName": "Stratum_main_CrowdSpawn_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.CrowdSpawn.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Minimum Nearby Players", + "Category": "Stratum:filter_alt", + "Subcategory": "Crowd Spawn:groups:10", + "Description": "data/stratum.json -> $.CrowdSpawn.MinimumNearbyPlayers", + "Keywords": "crowdspawn,minimumnearbyplayers", + "FieldName": "Stratum_main_CrowdSpawn_MinimumNearbyPlayers", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.CrowdSpawn.MinimumNearbyPlayers", + "IncludeInCommandLine": false, + "DefaultValue": "24", + "EnumValues": {} + }, + { + "DisplayName": "Detection Radius Blocks", + "Category": "Stratum:filter_alt", + "Subcategory": "Crowd Spawn:groups:10", + "Description": "data/stratum.json -> $.CrowdSpawn.DetectionRadiusBlocks", + "Keywords": "crowdspawn,detectionradiusblocks", + "FieldName": "Stratum_main_CrowdSpawn_DetectionRadiusBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.CrowdSpawn.DetectionRadiusBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "48", + "EnumValues": {} + }, + { + "DisplayName": "Spread Radius Blocks", + "Category": "Stratum:filter_alt", + "Subcategory": "Crowd Spawn:groups:10", + "Description": "data/stratum.json -> $.CrowdSpawn.SpreadRadiusBlocks", + "Keywords": "crowdspawn,spreadradiusblocks", + "FieldName": "Stratum_main_CrowdSpawn_SpreadRadiusBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.CrowdSpawn.SpreadRadiusBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "64", + "EnumValues": {} + }, + { + "DisplayName": "Safe Position Tries", + "Category": "Stratum:filter_alt", + "Subcategory": "Crowd Spawn:groups:10", + "Description": "data/stratum.json -> $.CrowdSpawn.SafePositionTries", + "Keywords": "crowdspawn,safepositiontries", + "FieldName": "Stratum_main_CrowdSpawn_SafePositionTries", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.CrowdSpawn.SafePositionTries", + "IncludeInCommandLine": false, + "DefaultValue": "15", + "EnumValues": {} + }, + { + "DisplayName": "Include Returning Players", + "Category": "Stratum:filter_alt", + "Subcategory": "Crowd Spawn:groups:10", + "Description": "data/stratum.json -> $.CrowdSpawn.IncludeReturningPlayers", + "Keywords": "crowdspawn,includereturningplayers", + "FieldName": "Stratum_main_CrowdSpawn_IncludeReturningPlayers", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.CrowdSpawn.IncludeReturningPlayers", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Allow Unauthenticated Clients", + "Category": "Stratum:filter_alt", + "Subcategory": "Load Testing:science:10", + "Description": "data/stratum.json -> $.LoadTesting.AllowUnauthenticatedClients", + "Keywords": "loadtesting,allowunauthenticatedclients", + "FieldName": "Stratum_main_LoadTesting_AllowUnauthenticatedClients", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.LoadTesting.AllowUnauthenticatedClients", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Required Player Name Prefix", + "Category": "Stratum:filter_alt", + "Subcategory": "Load Testing:science:10", + "Description": "data/stratum.json -> $.LoadTesting.RequiredPlayerNamePrefix", + "Keywords": "loadtesting,requiredplayernameprefix", + "FieldName": "Stratum_main_LoadTesting_RequiredPlayerNamePrefix", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.LoadTesting.RequiredPlayerNamePrefix", + "IncludeInCommandLine": false, + "DefaultValue": "StratumBot", + "EnumValues": {} + }, + { + "DisplayName": "Required Player Uid Prefix", + "Category": "Stratum:filter_alt", + "Subcategory": "Load Testing:science:10", + "Description": "data/stratum.json -> $.LoadTesting.RequiredPlayerUidPrefix", + "Keywords": "loadtesting,requiredplayeruidprefix", + "FieldName": "Stratum_main_LoadTesting_RequiredPlayerUidPrefix", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.LoadTesting.RequiredPlayerUidPrefix", + "IncludeInCommandLine": false, + "DefaultValue": "stratum-loadtest-", + "EnumValues": {} + }, + { + "DisplayName": "Log Accepted Clients", + "Category": "Stratum:filter_alt", + "Subcategory": "Load Testing:science:10", + "Description": "data/stratum.json -> $.LoadTesting.LogAcceptedClients", + "Keywords": "loadtesting,logacceptedclients", + "FieldName": "Stratum_main_LoadTesting_LogAcceptedClients", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.LoadTesting.LogAcceptedClients", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Login Protection:login:10", + "Description": "/ Enable join/spawn damage immunity. (data/stratum.json -> $.LoginProtection.Enabled)", + "Keywords": "loginprotection,enabled", + "FieldName": "Stratum_main_LoginProtection_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.LoginProtection.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Protection Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Login Protection:login:10", + "Description": "/ How long the player is invulnerable after joining the world, in seconds. (data/stratum.json -> $.LoginProtection.ProtectionSeconds)", + "Keywords": "loginprotection,protectionseconds", + "FieldName": "Stratum_main_LoginProtection_ProtectionSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.LoginProtection.ProtectionSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "5", + "EnumValues": {} + }, + { + "DisplayName": "Cancel On Horizontal Move", + "Category": "Stratum:filter_alt", + "Subcategory": "Login Protection:login:10", + "Description": "/ End protection as soon as the player moves horizontally past . (data/stratum.json -> $.LoginProtection.CancelOnHorizontalMove)", + "Keywords": "loginprotection,cancelonhorizontalmove", + "FieldName": "Stratum_main_LoginProtection_CancelOnHorizontalMove", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.LoginProtection.CancelOnHorizontalMove", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Move Threshold Blocks", + "Category": "Stratum:filter_alt", + "Subcategory": "Login Protection:login:10", + "Description": "/ How far (in blocks) a player must move horizontally from their join position to end protection. (data/stratum.json -> $.LoginProtection.MoveThresholdBlocks)", + "Keywords": "loginprotection,movethresholdblocks", + "FieldName": "Stratum_main_LoginProtection_MoveThresholdBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.LoginProtection.MoveThresholdBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "0.5", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Cancel In Fire Or Lava", + "Category": "Stratum:filter_alt", + "Subcategory": "Login Protection:login:10", + "Description": "/ If true, protection ends immediately when the player is on fire or standing in lava. (data/stratum.json -> $.LoginProtection.CancelInFireOrLava)", + "Keywords": "loginprotection,cancelinfireorlava", + "FieldName": "Stratum_main_LoginProtection_CancelInFireOrLava", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.LoginProtection.CancelInFireOrLava", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Announce On Start", + "Category": "Stratum:filter_alt", + "Subcategory": "Login Protection:login:10", + "Description": "/ If true, send the player a chat message when protection starts. (data/stratum.json -> $.LoginProtection.AnnounceOnStart)", + "Keywords": "loginprotection,announceonstart", + "FieldName": "Stratum_main_LoginProtection_AnnounceOnStart", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.LoginProtection.AnnounceOnStart", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Announce On End", + "Category": "Stratum:filter_alt", + "Subcategory": "Login Protection:login:10", + "Description": "/ If true, send the player a chat message when protection ends. (data/stratum.json -> $.LoginProtection.AnnounceOnEnd)", + "Keywords": "loginprotection,announceonend", + "FieldName": "Stratum_main_LoginProtection_AnnounceOnEnd", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.LoginProtection.AnnounceOnEnd", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Start Message", + "Category": "Stratum:filter_alt", + "Subcategory": "Login Protection:login:10", + "Description": "/ Message sent when protection starts. {0} = seconds. (data/stratum.json -> $.LoginProtection.StartMessage)", + "Keywords": "loginprotection,startmessage", + "FieldName": "Stratum_main_LoginProtection_StartMessage", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.LoginProtection.StartMessage", + "IncludeInCommandLine": false, + "DefaultValue": "You are protected from damage for {0} seconds. Move to cancel.", + "EnumValues": {} + }, + { + "DisplayName": "End Message", + "Category": "Stratum:filter_alt", + "Subcategory": "Login Protection:login:10", + "Description": "/ Message sent when protection ends. (data/stratum.json -> $.LoginProtection.EndMessage)", + "Keywords": "loginprotection,endmessage", + "FieldName": "Stratum_main_LoginProtection_EndMessage", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.LoginProtection.EndMessage", + "IncludeInCommandLine": false, + "DefaultValue": "Login protection ended.", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Player Privacy:visibility_off:10", + "Description": "/ Enable the player-privacy disclosure hook. Disabled by default \\u2014 opt-in. (data/stratum.json -> $.PlayerPrivacy.Enabled)", + "Keywords": "playerprivacy,enabled", + "FieldName": "Stratum_main_PlayerPrivacy_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.PlayerPrivacy.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Hide Map Pins", + "Category": "Stratum:filter_alt", + "Subcategory": "Player Privacy:visibility_off:10", + "Description": "/ Hide player pins on the world map from other players (other than staff / group, per settings). (data/stratum.json -> $.PlayerPrivacy.HideMapPins)", + "Keywords": "playerprivacy,hidemappins", + "FieldName": "Stratum_main_PlayerPrivacy_HideMapPins", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.PlayerPrivacy.HideMapPins", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Allow Group Map Visibility", + "Category": "Stratum:filter_alt", + "Subcategory": "Player Privacy:visibility_off:10", + "Description": "/ Players in the same player-group can still see each other on the map. (data/stratum.json -> $.PlayerPrivacy.AllowGroupMapVisibility)", + "Keywords": "playerprivacy,allowgroupmapvisibility", + "FieldName": "Stratum_main_PlayerPrivacy_AllowGroupMapVisibility", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.PlayerPrivacy.AllowGroupMapVisibility", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Player Privacy > Staff Override:visibility_off:10", + "Description": "data/stratum.json -> $.PlayerPrivacy.StaffOverride.Enabled", + "Keywords": "playerprivacy,staffoverride,enabled", + "FieldName": "Stratum_main_PlayerPrivacy_StaffOverride_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.PlayerPrivacy.StaffOverride.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum:filter_alt", + "Subcategory": "Player Privacy > Staff Override:visibility_off:10", + "Description": "data/stratum.json -> $.PlayerPrivacy.StaffOverride.Privilege", + "Keywords": "playerprivacy,staffoverride,privilege", + "FieldName": "Stratum_main_PlayerPrivacy_StaffOverride_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.PlayerPrivacy.StaffOverride.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Player Privacy > Staff Override:visibility_off:10", + "Description": "data/stratum.json -> $.PlayerPrivacy.StaffOverride.CooldownSeconds", + "Keywords": "playerprivacy,staffoverride,cooldownseconds", + "FieldName": "Stratum_main_PlayerPrivacy_StaffOverride_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.PlayerPrivacy.StaffOverride.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum:filter_alt", + "Subcategory": "Player Privacy > Staff Override:visibility_off:10", + "Description": "data/stratum.json -> $.PlayerPrivacy.StaffOverride.CooldownBypassForStaff", + "Keywords": "playerprivacy,staffoverride,cooldownbypassforstaff", + "FieldName": "Stratum_main_PlayerPrivacy_StaffOverride_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.PlayerPrivacy.StaffOverride.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Show Staff Pins To All", + "Category": "Stratum:filter_alt", + "Subcategory": "Player Privacy:visibility_off:10", + "Description": "/ If true, staff with the override are also visible to everyone (their own pin is shown). If false, staff are hidden like other players. (data/stratum.json -> $.PlayerPrivacy.ShowStaffPinsToAll)", + "Keywords": "playerprivacy,showstaffpinstoall", + "FieldName": "Stratum_main_PlayerPrivacy_ShowStaffPinsToAll", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.PlayerPrivacy.ShowStaffPinsToAll", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Coordinate Snap Blocks", + "Category": "Stratum:filter_alt", + "Subcategory": "Player Privacy:visibility_off:10", + "Description": "/ / Snap broadcast pin coordinates to a grid of this many blocks for non-staff, non-group receivers. / 0 = exact. Use e.g. 32 to round nearest 32-block bucket so a hostile client can't deduce / exact location even from a sneaked-in receiver. Only applies when HideMapPins is false (i.e., / when pins are being sent at all). / (data/stratum.json -> $.PlayerPrivacy.CoordinateSnapBlocks)", + "Keywords": "playerprivacy,coordinatesnapblocks", + "FieldName": "Stratum_main_PlayerPrivacy_CoordinateSnapBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.PlayerPrivacy.CoordinateSnapBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Max Broadcast Distance Blocks", + "Category": "Stratum:filter_alt", + "Subcategory": "Player Privacy:visibility_off:10", + "Description": "/ / If \\u22650, overrides the world's mapPlayerRenderDistance at startup so map pins are / only sent within this many blocks. -1 = leave worldconfig alone. / (data/stratum.json -> $.PlayerPrivacy.MaxBroadcastDistanceBlocks)", + "Keywords": "playerprivacy,maxbroadcastdistanceblocks", + "FieldName": "Stratum_main_PlayerPrivacy_MaxBroadcastDistanceBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.PlayerPrivacy.MaxBroadcastDistanceBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "-1", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Backup:backup:10", + "Description": "data/stratum.json -> $.Backup.Enabled", + "Keywords": "backup,enabled", + "FieldName": "Stratum_main_Backup_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Backup.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Interval Minutes", + "Category": "Stratum:filter_alt", + "Subcategory": "Backup:backup:10", + "Description": "data/stratum.json -> $.Backup.IntervalMinutes", + "Keywords": "backup,intervalminutes", + "FieldName": "Stratum_main_Backup_IntervalMinutes", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Backup.IntervalMinutes", + "IncludeInCommandLine": false, + "DefaultValue": "360", + "EnumValues": {} + }, + { + "DisplayName": "Retain Count", + "Category": "Stratum:filter_alt", + "Subcategory": "Backup:backup:10", + "Description": "data/stratum.json -> $.Backup.RetainCount", + "Keywords": "backup,retaincount", + "FieldName": "Stratum_main_Backup_RetainCount", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Backup.RetainCount", + "IncludeInCommandLine": false, + "DefaultValue": "5", + "EnumValues": {} + }, + { + "DisplayName": "Log Backups", + "Category": "Stratum:filter_alt", + "Subcategory": "Backup:backup:10", + "Description": "data/stratum.json -> $.Backup.LogBackups", + "Keywords": "backup,logbackups", + "FieldName": "Stratum_main_Backup_LogBackups", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Backup.LogBackups", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Announcements:campaign:10", + "Description": "data/stratum.json -> $.Announcements.Enabled", + "Keywords": "announcements,enabled", + "FieldName": "Stratum_main_Announcements_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Announcements.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Interval Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Announcements:campaign:10", + "Description": "Seconds between broadcasts. (data/stratum.json -> $.Announcements.IntervalSeconds)", + "Keywords": "announcements,intervalseconds", + "FieldName": "Stratum_main_Announcements_IntervalSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Announcements.IntervalSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "300", + "EnumValues": {} + }, + { + "DisplayName": "Prefix", + "Category": "Stratum:filter_alt", + "Subcategory": "Announcements:campaign:10", + "Description": "Prepended to every message. Default matches /announce orange bold styling. (data/stratum.json -> $.Announcements.Prefix)", + "Keywords": "announcements,prefix", + "FieldName": "Stratum_main_Announcements_Prefix", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Announcements.Prefix", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Suffix", + "Category": "Stratum:filter_alt", + "Subcategory": "Announcements:campaign:10", + "Description": "Appended to every message. Closes the Prefix tags. (data/stratum.json -> $.Announcements.Suffix)", + "Keywords": "announcements,suffix", + "FieldName": "Stratum_main_Announcements_Suffix", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Announcements.Suffix", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Random Order", + "Category": "Stratum:filter_alt", + "Subcategory": "Announcements:campaign:10", + "Description": "If true, pick a random message each time instead of sequential rotation. (data/stratum.json -> $.Announcements.RandomOrder)", + "Keywords": "announcements,randomorder", + "FieldName": "Stratum_main_Announcements_RandomOrder", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Announcements.RandomOrder", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum:filter_alt", + "Subcategory": "Server Stats:insights:10", + "Description": "data/stratum.json -> $.ServerStats.Enabled", + "Keywords": "serverstats,enabled", + "FieldName": "Stratum_main_ServerStats_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ServerStats.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Report Url", + "Category": "Stratum:filter_alt", + "Subcategory": "Server Stats:insights:10", + "Description": "Central endpoint that receives the report (HTTP POST, application/json). Point this at your aggregator. Leave empty to keep reporting off even when Enabled is true. (data/stratum.json -> $.ServerStats.ReportUrl)", + "Keywords": "serverstats,reporturl", + "FieldName": "Stratum_main_ServerStats_ReportUrl", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.ServerStats.ReportUrl", + "IncludeInCommandLine": false, + "DefaultValue": "https://my.stratumvs.dev/stratum-stats.php", + "EnumValues": {} + }, + { + "DisplayName": "Interval Minutes", + "Category": "Stratum:filter_alt", + "Subcategory": "Server Stats:insights:10", + "Description": "data/stratum.json -> $.ServerStats.IntervalMinutes", + "Keywords": "serverstats,intervalminutes", + "FieldName": "Stratum_main_ServerStats_IntervalMinutes", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ServerStats.IntervalMinutes", + "IncludeInCommandLine": false, + "DefaultValue": "30", + "EnumValues": {} + }, + { + "DisplayName": "Timeout Seconds", + "Category": "Stratum:filter_alt", + "Subcategory": "Server Stats:insights:10", + "Description": "data/stratum.json -> $.ServerStats.TimeoutSeconds", + "Keywords": "serverstats,timeoutseconds", + "FieldName": "Stratum_main_ServerStats_TimeoutSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ServerStats.TimeoutSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "10", + "EnumValues": {} + }, + { + "DisplayName": "Server Id", + "Category": "Stratum:filter_alt", + "Subcategory": "Server Stats:insights:10", + "Description": "Random, anonymous, per-install id. Generated once on first run and kept so restarts are not counted as new servers. Delete it to reset this server's identity. (data/stratum.json -> $.ServerStats.ServerId)", + "Keywords": "serverstats,serverid", + "FieldName": "Stratum_main_ServerStats_ServerId", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.ServerStats.ServerId", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "General:terminal:20", + "Description": "data/stratum-commands.json -> $.Enabled", + "Keywords": "enabled", + "FieldName": "Stratum_cmd_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Spawn:terminal:20", + "Description": "data/stratum-commands.json -> $.Spawn.Enabled", + "Keywords": "spawn,enabled", + "FieldName": "Stratum_cmd_Spawn_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Spawn.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Spawn:terminal:20", + "Description": "data/stratum-commands.json -> $.Spawn.Privilege", + "Keywords": "spawn,privilege", + "FieldName": "Stratum_cmd_Spawn_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Spawn.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Spawn:terminal:20", + "Description": "data/stratum-commands.json -> $.Spawn.CooldownSeconds", + "Keywords": "spawn,cooldownseconds", + "FieldName": "Stratum_cmd_Spawn_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Spawn.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Spawn:terminal:20", + "Description": "data/stratum-commands.json -> $.Spawn.CooldownBypassForStaff", + "Keywords": "spawn,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_Spawn_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Spawn.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Set Spawn:terminal:20", + "Description": "data/stratum-commands.json -> $.SetSpawn.Enabled", + "Keywords": "setspawn,enabled", + "FieldName": "Stratum_cmd_SetSpawn_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.SetSpawn.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Set Spawn:terminal:20", + "Description": "data/stratum-commands.json -> $.SetSpawn.Privilege", + "Keywords": "setspawn,privilege", + "FieldName": "Stratum_cmd_SetSpawn_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.SetSpawn.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Set Spawn:terminal:20", + "Description": "data/stratum-commands.json -> $.SetSpawn.CooldownSeconds", + "Keywords": "setspawn,cooldownseconds", + "FieldName": "Stratum_cmd_SetSpawn_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.SetSpawn.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Set Spawn:terminal:20", + "Description": "data/stratum-commands.json -> $.SetSpawn.CooldownBypassForStaff", + "Keywords": "setspawn,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_SetSpawn_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.SetSpawn.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Teleport Requests > Request:terminal:20", + "Description": "data/stratum-commands.json -> $.TeleportRequests.Request.Enabled", + "Keywords": "teleportrequests,request,enabled", + "FieldName": "Stratum_cmd_TeleportRequests_Request_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.TeleportRequests.Request.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Teleport Requests > Request:terminal:20", + "Description": "data/stratum-commands.json -> $.TeleportRequests.Request.Privilege", + "Keywords": "teleportrequests,request,privilege", + "FieldName": "Stratum_cmd_TeleportRequests_Request_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.TeleportRequests.Request.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Teleport Requests > Request:terminal:20", + "Description": "data/stratum-commands.json -> $.TeleportRequests.Request.CooldownSeconds", + "Keywords": "teleportrequests,request,cooldownseconds", + "FieldName": "Stratum_cmd_TeleportRequests_Request_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.TeleportRequests.Request.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Teleport Requests > Request:terminal:20", + "Description": "data/stratum-commands.json -> $.TeleportRequests.Request.CooldownBypassForStaff", + "Keywords": "teleportrequests,request,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_TeleportRequests_Request_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.TeleportRequests.Request.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Teleport Requests > Here:terminal:20", + "Description": "data/stratum-commands.json -> $.TeleportRequests.Here.Enabled", + "Keywords": "teleportrequests,here,enabled", + "FieldName": "Stratum_cmd_TeleportRequests_Here_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.TeleportRequests.Here.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Teleport Requests > Here:terminal:20", + "Description": "data/stratum-commands.json -> $.TeleportRequests.Here.Privilege", + "Keywords": "teleportrequests,here,privilege", + "FieldName": "Stratum_cmd_TeleportRequests_Here_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.TeleportRequests.Here.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Teleport Requests > Here:terminal:20", + "Description": "data/stratum-commands.json -> $.TeleportRequests.Here.CooldownSeconds", + "Keywords": "teleportrequests,here,cooldownseconds", + "FieldName": "Stratum_cmd_TeleportRequests_Here_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.TeleportRequests.Here.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Teleport Requests > Here:terminal:20", + "Description": "data/stratum-commands.json -> $.TeleportRequests.Here.CooldownBypassForStaff", + "Keywords": "teleportrequests,here,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_TeleportRequests_Here_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.TeleportRequests.Here.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Allow Tpa Here", + "Category": "Stratum Commands:terminal", + "Subcategory": "Teleport Requests:terminal:20", + "Description": "data/stratum-commands.json -> $.TeleportRequests.AllowTpaHere", + "Keywords": "teleportrequests,allowtpahere", + "FieldName": "Stratum_cmd_TeleportRequests_AllowTpaHere", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.TeleportRequests.AllowTpaHere", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Timeout Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Teleport Requests:terminal:20", + "Description": "data/stratum-commands.json -> $.TeleportRequests.TimeoutSeconds", + "Keywords": "teleportrequests,timeoutseconds", + "FieldName": "Stratum_cmd_TeleportRequests_TimeoutSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.TeleportRequests.TimeoutSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "60", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Teleport Requests:terminal:20", + "Description": "data/stratum-commands.json -> $.TeleportRequests.CooldownSeconds", + "Keywords": "teleportrequests,cooldownseconds", + "FieldName": "Stratum_cmd_TeleportRequests_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.TeleportRequests.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "15", + "EnumValues": {} + }, + { + "DisplayName": "Warmup Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Teleport Requests:terminal:20", + "Description": "data/stratum-commands.json -> $.TeleportRequests.WarmupSeconds", + "Keywords": "teleportrequests,warmupseconds", + "FieldName": "Stratum_cmd_TeleportRequests_WarmupSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.TeleportRequests.WarmupSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "5", + "EnumValues": {} + }, + { + "DisplayName": "Teleport Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Teleport Requests:terminal:20", + "Description": "data/stratum-commands.json -> $.TeleportRequests.TeleportCooldownSeconds", + "Keywords": "teleportrequests,teleportcooldownseconds", + "FieldName": "Stratum_cmd_TeleportRequests_TeleportCooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.TeleportRequests.TeleportCooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "30", + "EnumValues": {} + }, + { + "DisplayName": "Cancel Move Distance Blocks", + "Category": "Stratum Commands:terminal", + "Subcategory": "Teleport Requests:terminal:20", + "Description": "data/stratum-commands.json -> $.TeleportRequests.CancelMoveDistanceBlocks", + "Keywords": "teleportrequests,cancelmovedistanceblocks", + "FieldName": "Stratum_cmd_TeleportRequests_CancelMoveDistanceBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.TeleportRequests.CancelMoveDistanceBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "0.35", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Cancel On Move", + "Category": "Stratum Commands:terminal", + "Subcategory": "Teleport Requests:terminal:20", + "Description": "data/stratum-commands.json -> $.TeleportRequests.CancelOnMove", + "Keywords": "teleportrequests,cancelonmove", + "FieldName": "Stratum_cmd_TeleportRequests_CancelOnMove", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.TeleportRequests.CancelOnMove", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Cancel On Damage", + "Category": "Stratum Commands:terminal", + "Subcategory": "Teleport Requests:terminal:20", + "Description": "data/stratum-commands.json -> $.TeleportRequests.CancelOnDamage", + "Keywords": "teleportrequests,cancelondamage", + "FieldName": "Stratum_cmd_TeleportRequests_CancelOnDamage", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.TeleportRequests.CancelOnDamage", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Bypass Warmup For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Teleport Requests:terminal:20", + "Description": "data/stratum-commands.json -> $.TeleportRequests.BypassWarmupForStaff", + "Keywords": "teleportrequests,bypasswarmupforstaff", + "FieldName": "Stratum_cmd_TeleportRequests_BypassWarmupForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.TeleportRequests.BypassWarmupForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Homes > Home:terminal:20", + "Description": "data/stratum-commands.json -> $.Homes.Home.Enabled", + "Keywords": "homes,home,enabled", + "FieldName": "Stratum_cmd_Homes_Home_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Homes.Home.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Homes > Home:terminal:20", + "Description": "data/stratum-commands.json -> $.Homes.Home.Privilege", + "Keywords": "homes,home,privilege", + "FieldName": "Stratum_cmd_Homes_Home_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Homes.Home.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Homes > Home:terminal:20", + "Description": "data/stratum-commands.json -> $.Homes.Home.CooldownSeconds", + "Keywords": "homes,home,cooldownseconds", + "FieldName": "Stratum_cmd_Homes_Home_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Homes.Home.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Homes > Home:terminal:20", + "Description": "data/stratum-commands.json -> $.Homes.Home.CooldownBypassForStaff", + "Keywords": "homes,home,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_Homes_Home_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Homes.Home.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Homes > Set Home:terminal:20", + "Description": "data/stratum-commands.json -> $.Homes.SetHome.Enabled", + "Keywords": "homes,sethome,enabled", + "FieldName": "Stratum_cmd_Homes_SetHome_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Homes.SetHome.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Homes > Set Home:terminal:20", + "Description": "data/stratum-commands.json -> $.Homes.SetHome.Privilege", + "Keywords": "homes,sethome,privilege", + "FieldName": "Stratum_cmd_Homes_SetHome_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Homes.SetHome.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Homes > Set Home:terminal:20", + "Description": "data/stratum-commands.json -> $.Homes.SetHome.CooldownSeconds", + "Keywords": "homes,sethome,cooldownseconds", + "FieldName": "Stratum_cmd_Homes_SetHome_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Homes.SetHome.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Homes > Set Home:terminal:20", + "Description": "data/stratum-commands.json -> $.Homes.SetHome.CooldownBypassForStaff", + "Keywords": "homes,sethome,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_Homes_SetHome_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Homes.SetHome.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Homes > Delete Home:terminal:20", + "Description": "data/stratum-commands.json -> $.Homes.DeleteHome.Enabled", + "Keywords": "homes,deletehome,enabled", + "FieldName": "Stratum_cmd_Homes_DeleteHome_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Homes.DeleteHome.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Homes > Delete Home:terminal:20", + "Description": "data/stratum-commands.json -> $.Homes.DeleteHome.Privilege", + "Keywords": "homes,deletehome,privilege", + "FieldName": "Stratum_cmd_Homes_DeleteHome_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Homes.DeleteHome.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Homes > Delete Home:terminal:20", + "Description": "data/stratum-commands.json -> $.Homes.DeleteHome.CooldownSeconds", + "Keywords": "homes,deletehome,cooldownseconds", + "FieldName": "Stratum_cmd_Homes_DeleteHome_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Homes.DeleteHome.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Homes > Delete Home:terminal:20", + "Description": "data/stratum-commands.json -> $.Homes.DeleteHome.CooldownBypassForStaff", + "Keywords": "homes,deletehome,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_Homes_DeleteHome_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Homes.DeleteHome.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Default Max Homes", + "Category": "Stratum Commands:terminal", + "Subcategory": "Homes:terminal:20", + "Description": "data/stratum-commands.json -> $.Homes.DefaultMaxHomes", + "Keywords": "homes,defaultmaxhomes", + "FieldName": "Stratum_cmd_Homes_DefaultMaxHomes", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Homes.DefaultMaxHomes", + "IncludeInCommandLine": false, + "DefaultValue": "3", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Seen:terminal:20", + "Description": "data/stratum-commands.json -> $.Seen.Enabled", + "Keywords": "seen,enabled", + "FieldName": "Stratum_cmd_Seen_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Seen.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Seen:terminal:20", + "Description": "data/stratum-commands.json -> $.Seen.Privilege", + "Keywords": "seen,privilege", + "FieldName": "Stratum_cmd_Seen_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Seen.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Seen:terminal:20", + "Description": "data/stratum-commands.json -> $.Seen.CooldownSeconds", + "Keywords": "seen,cooldownseconds", + "FieldName": "Stratum_cmd_Seen_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Seen.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Seen:terminal:20", + "Description": "data/stratum-commands.json -> $.Seen.CooldownBypassForStaff", + "Keywords": "seen,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_Seen_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Seen.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Whois:terminal:20", + "Description": "data/stratum-commands.json -> $.Whois.Enabled", + "Keywords": "whois,enabled", + "FieldName": "Stratum_cmd_Whois_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Whois.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Whois:terminal:20", + "Description": "data/stratum-commands.json -> $.Whois.Privilege", + "Keywords": "whois,privilege", + "FieldName": "Stratum_cmd_Whois_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Whois.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Whois:terminal:20", + "Description": "data/stratum-commands.json -> $.Whois.CooldownSeconds", + "Keywords": "whois,cooldownseconds", + "FieldName": "Stratum_cmd_Whois_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Whois.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Whois:terminal:20", + "Description": "data/stratum-commands.json -> $.Whois.CooldownBypassForStaff", + "Keywords": "whois,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_Whois_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Whois.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Near:terminal:20", + "Description": "data/stratum-commands.json -> $.Near.Enabled", + "Keywords": "near,enabled", + "FieldName": "Stratum_cmd_Near_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Near.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Near:terminal:20", + "Description": "data/stratum-commands.json -> $.Near.Privilege", + "Keywords": "near,privilege", + "FieldName": "Stratum_cmd_Near_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Near.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Near:terminal:20", + "Description": "data/stratum-commands.json -> $.Near.CooldownSeconds", + "Keywords": "near,cooldownseconds", + "FieldName": "Stratum_cmd_Near_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Near.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Near:terminal:20", + "Description": "data/stratum-commands.json -> $.Near.CooldownBypassForStaff", + "Keywords": "near,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_Near_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Near.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Back:terminal:20", + "Description": "data/stratum-commands.json -> $.Back.Enabled", + "Keywords": "back,enabled", + "FieldName": "Stratum_cmd_Back_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Back.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Back:terminal:20", + "Description": "data/stratum-commands.json -> $.Back.Privilege", + "Keywords": "back,privilege", + "FieldName": "Stratum_cmd_Back_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Back.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Back:terminal:20", + "Description": "data/stratum-commands.json -> $.Back.CooldownSeconds", + "Keywords": "back,cooldownseconds", + "FieldName": "Stratum_cmd_Back_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Back.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Back:terminal:20", + "Description": "data/stratum-commands.json -> $.Back.CooldownBypassForStaff", + "Keywords": "back,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_Back_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Back.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Message:terminal:20", + "Description": "data/stratum-commands.json -> $.Message.Enabled", + "Keywords": "message,enabled", + "FieldName": "Stratum_cmd_Message_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Message.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Message:terminal:20", + "Description": "data/stratum-commands.json -> $.Message.Privilege", + "Keywords": "message,privilege", + "FieldName": "Stratum_cmd_Message_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Message.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Message:terminal:20", + "Description": "data/stratum-commands.json -> $.Message.CooldownSeconds", + "Keywords": "message,cooldownseconds", + "FieldName": "Stratum_cmd_Message_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Message.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Message:terminal:20", + "Description": "data/stratum-commands.json -> $.Message.CooldownBypassForStaff", + "Keywords": "message,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_Message_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Message.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Staff Chat:terminal:20", + "Description": "data/stratum-commands.json -> $.StaffChat.Enabled", + "Keywords": "staffchat,enabled", + "FieldName": "Stratum_cmd_StaffChat_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.StaffChat.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Staff Chat:terminal:20", + "Description": "data/stratum-commands.json -> $.StaffChat.Privilege", + "Keywords": "staffchat,privilege", + "FieldName": "Stratum_cmd_StaffChat_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.StaffChat.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Staff Chat:terminal:20", + "Description": "data/stratum-commands.json -> $.StaffChat.CooldownSeconds", + "Keywords": "staffchat,cooldownseconds", + "FieldName": "Stratum_cmd_StaffChat_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.StaffChat.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Staff Chat:terminal:20", + "Description": "data/stratum-commands.json -> $.StaffChat.CooldownBypassForStaff", + "Keywords": "staffchat,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_StaffChat_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.StaffChat.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Chat Control:terminal:20", + "Description": "data/stratum-commands.json -> $.ChatControl.Enabled", + "Keywords": "chatcontrol,enabled", + "FieldName": "Stratum_cmd_ChatControl_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ChatControl.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Chat Control:terminal:20", + "Description": "data/stratum-commands.json -> $.ChatControl.Privilege", + "Keywords": "chatcontrol,privilege", + "FieldName": "Stratum_cmd_ChatControl_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.ChatControl.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Chat Control:terminal:20", + "Description": "data/stratum-commands.json -> $.ChatControl.CooldownSeconds", + "Keywords": "chatcontrol,cooldownseconds", + "FieldName": "Stratum_cmd_ChatControl_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChatControl.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Chat Control:terminal:20", + "Description": "data/stratum-commands.json -> $.ChatControl.CooldownBypassForStaff", + "Keywords": "chatcontrol,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_ChatControl_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ChatControl.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Staff Broadcast:terminal:20", + "Description": "data/stratum-commands.json -> $.StaffBroadcast.Enabled", + "Keywords": "staffbroadcast,enabled", + "FieldName": "Stratum_cmd_StaffBroadcast_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.StaffBroadcast.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Staff Broadcast:terminal:20", + "Description": "data/stratum-commands.json -> $.StaffBroadcast.Privilege", + "Keywords": "staffbroadcast,privilege", + "FieldName": "Stratum_cmd_StaffBroadcast_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.StaffBroadcast.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Staff Broadcast:terminal:20", + "Description": "data/stratum-commands.json -> $.StaffBroadcast.CooldownSeconds", + "Keywords": "staffbroadcast,cooldownseconds", + "FieldName": "Stratum_cmd_StaffBroadcast_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.StaffBroadcast.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Staff Broadcast:terminal:20", + "Description": "data/stratum-commands.json -> $.StaffBroadcast.CooldownBypassForStaff", + "Keywords": "staffbroadcast,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_StaffBroadcast_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.StaffBroadcast.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Info Commands:terminal:20", + "Description": "data/stratum-commands.json -> $.InfoCommands.Enabled", + "Keywords": "infocommands,enabled", + "FieldName": "Stratum_cmd_InfoCommands_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.InfoCommands.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Info Commands:terminal:20", + "Description": "data/stratum-commands.json -> $.InfoCommands.Privilege", + "Keywords": "infocommands,privilege", + "FieldName": "Stratum_cmd_InfoCommands_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.InfoCommands.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Info Commands:terminal:20", + "Description": "data/stratum-commands.json -> $.InfoCommands.CooldownSeconds", + "Keywords": "infocommands,cooldownseconds", + "FieldName": "Stratum_cmd_InfoCommands_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.InfoCommands.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Info Commands:terminal:20", + "Description": "data/stratum-commands.json -> $.InfoCommands.CooldownBypassForStaff", + "Keywords": "infocommands,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_InfoCommands_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.InfoCommands.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Vanish:terminal:20", + "Description": "data/stratum-commands.json -> $.Vanish.Enabled", + "Keywords": "vanish,enabled", + "FieldName": "Stratum_cmd_Vanish_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Vanish.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Vanish:terminal:20", + "Description": "data/stratum-commands.json -> $.Vanish.Privilege", + "Keywords": "vanish,privilege", + "FieldName": "Stratum_cmd_Vanish_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Vanish.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Vanish:terminal:20", + "Description": "data/stratum-commands.json -> $.Vanish.CooldownSeconds", + "Keywords": "vanish,cooldownseconds", + "FieldName": "Stratum_cmd_Vanish_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Vanish.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Vanish:terminal:20", + "Description": "data/stratum-commands.json -> $.Vanish.CooldownBypassForStaff", + "Keywords": "vanish,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_Vanish_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Vanish.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Pvp:terminal:20", + "Description": "data/stratum-commands.json -> $.Pvp.Enabled", + "Keywords": "pvp,enabled", + "FieldName": "Stratum_cmd_Pvp_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Pvp.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Pvp:terminal:20", + "Description": "data/stratum-commands.json -> $.Pvp.Privilege", + "Keywords": "pvp,privilege", + "FieldName": "Stratum_cmd_Pvp_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Pvp.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Pvp:terminal:20", + "Description": "data/stratum-commands.json -> $.Pvp.CooldownSeconds", + "Keywords": "pvp,cooldownseconds", + "FieldName": "Stratum_cmd_Pvp_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Pvp.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Pvp:terminal:20", + "Description": "data/stratum-commands.json -> $.Pvp.CooldownBypassForStaff", + "Keywords": "pvp,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_Pvp_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Pvp.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Vanish Reminder Interval Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "General:terminal:20", + "Description": "data/stratum-commands.json -> $.VanishReminderIntervalSeconds", + "Keywords": "vanishreminderintervalseconds", + "FieldName": "Stratum_cmd_VanishReminderIntervalSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.VanishReminderIntervalSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "4", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Freeze:terminal:20", + "Description": "data/stratum-commands.json -> $.Freeze.Enabled", + "Keywords": "freeze,enabled", + "FieldName": "Stratum_cmd_Freeze_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Freeze.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Freeze:terminal:20", + "Description": "data/stratum-commands.json -> $.Freeze.Privilege", + "Keywords": "freeze,privilege", + "FieldName": "Stratum_cmd_Freeze_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Freeze.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Freeze:terminal:20", + "Description": "data/stratum-commands.json -> $.Freeze.CooldownSeconds", + "Keywords": "freeze,cooldownseconds", + "FieldName": "Stratum_cmd_Freeze_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Freeze.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Freeze:terminal:20", + "Description": "data/stratum-commands.json -> $.Freeze.CooldownBypassForStaff", + "Keywords": "freeze,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_Freeze_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Freeze.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Revive:terminal:20", + "Description": "data/stratum-commands.json -> $.Revive.Enabled", + "Keywords": "revive,enabled", + "FieldName": "Stratum_cmd_Revive_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Revive.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Revive:terminal:20", + "Description": "data/stratum-commands.json -> $.Revive.Privilege", + "Keywords": "revive,privilege", + "FieldName": "Stratum_cmd_Revive_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Revive.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Revive:terminal:20", + "Description": "data/stratum-commands.json -> $.Revive.CooldownSeconds", + "Keywords": "revive,cooldownseconds", + "FieldName": "Stratum_cmd_Revive_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Revive.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Revive:terminal:20", + "Description": "data/stratum-commands.json -> $.Revive.CooldownBypassForStaff", + "Keywords": "revive,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_Revive_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Revive.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Jail:terminal:20", + "Description": "data/stratum-commands.json -> $.Jail.Enabled", + "Keywords": "jail,enabled", + "FieldName": "Stratum_cmd_Jail_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Jail.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Jail:terminal:20", + "Description": "data/stratum-commands.json -> $.Jail.Privilege", + "Keywords": "jail,privilege", + "FieldName": "Stratum_cmd_Jail_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Jail.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Jail:terminal:20", + "Description": "data/stratum-commands.json -> $.Jail.CooldownSeconds", + "Keywords": "jail,cooldownseconds", + "FieldName": "Stratum_cmd_Jail_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Jail.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Jail:terminal:20", + "Description": "data/stratum-commands.json -> $.Jail.CooldownBypassForStaff", + "Keywords": "jail,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_Jail_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Jail.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Warn:terminal:20", + "Description": "data/stratum-commands.json -> $.Warn.Enabled", + "Keywords": "warn,enabled", + "FieldName": "Stratum_cmd_Warn_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Warn.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Warn:terminal:20", + "Description": "data/stratum-commands.json -> $.Warn.Privilege", + "Keywords": "warn,privilege", + "FieldName": "Stratum_cmd_Warn_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Warn.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Warn:terminal:20", + "Description": "data/stratum-commands.json -> $.Warn.CooldownSeconds", + "Keywords": "warn,cooldownseconds", + "FieldName": "Stratum_cmd_Warn_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Warn.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Warn:terminal:20", + "Description": "data/stratum-commands.json -> $.Warn.CooldownBypassForStaff", + "Keywords": "warn,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_Warn_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Warn.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Mute:terminal:20", + "Description": "data/stratum-commands.json -> $.Mute.Enabled", + "Keywords": "mute,enabled", + "FieldName": "Stratum_cmd_Mute_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Mute.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Mute:terminal:20", + "Description": "data/stratum-commands.json -> $.Mute.Privilege", + "Keywords": "mute,privilege", + "FieldName": "Stratum_cmd_Mute_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Mute.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Mute:terminal:20", + "Description": "data/stratum-commands.json -> $.Mute.CooldownSeconds", + "Keywords": "mute,cooldownseconds", + "FieldName": "Stratum_cmd_Mute_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Mute.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Mute:terminal:20", + "Description": "data/stratum-commands.json -> $.Mute.CooldownBypassForStaff", + "Keywords": "mute,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_Mute_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Mute.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Notes:terminal:20", + "Description": "data/stratum-commands.json -> $.Notes.Enabled", + "Keywords": "notes,enabled", + "FieldName": "Stratum_cmd_Notes_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Notes.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Notes:terminal:20", + "Description": "data/stratum-commands.json -> $.Notes.Privilege", + "Keywords": "notes,privilege", + "FieldName": "Stratum_cmd_Notes_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Notes.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Notes:terminal:20", + "Description": "data/stratum-commands.json -> $.Notes.CooldownSeconds", + "Keywords": "notes,cooldownseconds", + "FieldName": "Stratum_cmd_Notes_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Notes.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Notes:terminal:20", + "Description": "data/stratum-commands.json -> $.Notes.CooldownBypassForStaff", + "Keywords": "notes,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_Notes_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Notes.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Report:terminal:20", + "Description": "data/stratum-commands.json -> $.Report.Enabled", + "Keywords": "report,enabled", + "FieldName": "Stratum_cmd_Report_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Report.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Report:terminal:20", + "Description": "data/stratum-commands.json -> $.Report.Privilege", + "Keywords": "report,privilege", + "FieldName": "Stratum_cmd_Report_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.Report.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Report:terminal:20", + "Description": "data/stratum-commands.json -> $.Report.CooldownSeconds", + "Keywords": "report,cooldownseconds", + "FieldName": "Stratum_cmd_Report_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Report.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Report:terminal:20", + "Description": "data/stratum-commands.json -> $.Report.CooldownBypassForStaff", + "Keywords": "report,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_Report_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Report.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Commands:terminal", + "Subcategory": "Report Manage:terminal:20", + "Description": "data/stratum-commands.json -> $.ReportManage.Enabled", + "Keywords": "reportmanage,enabled", + "FieldName": "Stratum_cmd_ReportManage_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ReportManage.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Privilege", + "Category": "Stratum Commands:terminal", + "Subcategory": "Report Manage:terminal:20", + "Description": "data/stratum-commands.json -> $.ReportManage.Privilege", + "Keywords": "reportmanage,privilege", + "FieldName": "Stratum_cmd_ReportManage_Privilege", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.ReportManage.Privilege", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "Report Manage:terminal:20", + "Description": "data/stratum-commands.json -> $.ReportManage.CooldownSeconds", + "Keywords": "reportmanage,cooldownseconds", + "FieldName": "Stratum_cmd_ReportManage_CooldownSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ReportManage.CooldownSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Cooldown Bypass For Staff", + "Category": "Stratum Commands:terminal", + "Subcategory": "Report Manage:terminal:20", + "Description": "data/stratum-commands.json -> $.ReportManage.CooldownBypassForStaff", + "Keywords": "reportmanage,cooldownbypassforstaff", + "FieldName": "Stratum_cmd_ReportManage_CooldownBypassForStaff", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ReportManage.CooldownBypassForStaff", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Near Default Radius Blocks", + "Category": "Stratum Commands:terminal", + "Subcategory": "General:terminal:20", + "Description": "data/stratum-commands.json -> $.NearDefaultRadiusBlocks", + "Keywords": "neardefaultradiusblocks", + "FieldName": "Stratum_cmd_NearDefaultRadiusBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.NearDefaultRadiusBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "128", + "EnumValues": {} + }, + { + "DisplayName": "Near Max Radius Blocks", + "Category": "Stratum Commands:terminal", + "Subcategory": "General:terminal:20", + "Description": "data/stratum-commands.json -> $.NearMaxRadiusBlocks", + "Keywords": "nearmaxradiusblocks", + "FieldName": "Stratum_cmd_NearMaxRadiusBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.NearMaxRadiusBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "512", + "EnumValues": {} + }, + { + "DisplayName": "Slowmode Max Seconds", + "Category": "Stratum Commands:terminal", + "Subcategory": "General:terminal:20", + "Description": "data/stratum-commands.json -> $.SlowmodeMaxSeconds", + "Keywords": "slowmodemaxseconds", + "FieldName": "Stratum_cmd_SlowmodeMaxSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.SlowmodeMaxSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "3600", + "EnumValues": {} + }, + { + "DisplayName": "Clear Chat Lines", + "Category": "Stratum Commands:terminal", + "Subcategory": "General:terminal:20", + "Description": "data/stratum-commands.json -> $.ClearChatLines", + "Keywords": "clearchatlines", + "FieldName": "Stratum_cmd_ClearChatLines", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ClearChatLines", + "IncludeInCommandLine": false, + "DefaultValue": "80", + "EnumValues": {} + }, + { + "DisplayName": "Set", + "Category": "Stratum Commands:terminal", + "Subcategory": "Jail Settings > Location:terminal:20", + "Description": "data/stratum-commands.json -> $.JailSettings.Location.Set", + "Keywords": "jailsettings,location,set", + "FieldName": "Stratum_cmd_JailSettings_Location_Set", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.JailSettings.Location.Set", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "X", + "Category": "Stratum Commands:terminal", + "Subcategory": "Jail Settings > Location:terminal:20", + "Description": "data/stratum-commands.json -> $.JailSettings.Location.X", + "Keywords": "jailsettings,location,x", + "FieldName": "Stratum_cmd_JailSettings_Location_X", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.JailSettings.Location.X", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Y", + "Category": "Stratum Commands:terminal", + "Subcategory": "Jail Settings > Location:terminal:20", + "Description": "data/stratum-commands.json -> $.JailSettings.Location.Y", + "Keywords": "jailsettings,location,y", + "FieldName": "Stratum_cmd_JailSettings_Location_Y", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.JailSettings.Location.Y", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Z", + "Category": "Stratum Commands:terminal", + "Subcategory": "Jail Settings > Location:terminal:20", + "Description": "data/stratum-commands.json -> $.JailSettings.Location.Z", + "Keywords": "jailsettings,location,z", + "FieldName": "Stratum_cmd_JailSettings_Location_Z", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.JailSettings.Location.Z", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Dimension", + "Category": "Stratum Commands:terminal", + "Subcategory": "Jail Settings > Location:terminal:20", + "Description": "data/stratum-commands.json -> $.JailSettings.Location.Dimension", + "Keywords": "jailsettings,location,dimension", + "FieldName": "Stratum_cmd_JailSettings_Location_Dimension", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.JailSettings.Location.Dimension", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Yaw", + "Category": "Stratum Commands:terminal", + "Subcategory": "Jail Settings > Location:terminal:20", + "Description": "data/stratum-commands.json -> $.JailSettings.Location.Yaw", + "Keywords": "jailsettings,location,yaw", + "FieldName": "Stratum_cmd_JailSettings_Location_Yaw", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.JailSettings.Location.Yaw", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Pitch", + "Category": "Stratum Commands:terminal", + "Subcategory": "Jail Settings > Location:terminal:20", + "Description": "data/stratum-commands.json -> $.JailSettings.Location.Pitch", + "Keywords": "jailsettings,location,pitch", + "FieldName": "Stratum_cmd_JailSettings_Location_Pitch", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.JailSettings.Location.Pitch", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Max Distance Blocks", + "Category": "Stratum Commands:terminal", + "Subcategory": "Jail Settings:terminal:20", + "Description": "data/stratum-commands.json -> $.JailSettings.MaxDistanceBlocks", + "Keywords": "jailsettings,maxdistanceblocks", + "FieldName": "Stratum_cmd_JailSettings_MaxDistanceBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.JailSettings.MaxDistanceBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "6", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Return On Unjail", + "Category": "Stratum Commands:terminal", + "Subcategory": "Jail Settings:terminal:20", + "Description": "data/stratum-commands.json -> $.JailSettings.ReturnOnUnjail", + "Keywords": "jailsettings,returnonunjail", + "FieldName": "Stratum_cmd_JailSettings_ReturnOnUnjail", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.JailSettings.ReturnOnUnjail", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.Enabled", + "Keywords": "chunksending,enabled", + "FieldName": "Stratum_perf_ChunkSending_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Max Chunks Per Server Tick", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.MaxChunksPerServerTick", + "Keywords": "chunksending,maxchunksperservertick", + "FieldName": "Stratum_perf_ChunkSending_MaxChunksPerServerTick", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.MaxChunksPerServerTick", + "IncludeInCommandLine": false, + "DefaultValue": "384", + "EnumValues": {} + }, + { + "DisplayName": "Max Chunks Per Client Tick", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.MaxChunksPerClientTick", + "Keywords": "chunksending,maxchunksperclienttick", + "FieldName": "Stratum_perf_ChunkSending_MaxChunksPerClientTick", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.MaxChunksPerClientTick", + "IncludeInCommandLine": false, + "DefaultValue": "64", + "EnumValues": {} + }, + { + "DisplayName": "Include Local Clients", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.IncludeLocalClients", + "Keywords": "chunksending,includelocalclients", + "FieldName": "Stratum_perf_ChunkSending_IncludeLocalClients", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.IncludeLocalClients", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Adaptive Under Overload", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.AdaptiveUnderOverload", + "Keywords": "chunksending,adaptiveunderoverload", + "FieldName": "Stratum_perf_ChunkSending_AdaptiveUnderOverload", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.AdaptiveUnderOverload", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Overload Tick Ms", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.OverloadTickMs", + "Keywords": "chunksending,overloadtickms", + "FieldName": "Stratum_perf_ChunkSending_OverloadTickMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.OverloadTickMs", + "IncludeInCommandLine": false, + "DefaultValue": "45", + "EnumValues": {} + }, + { + "DisplayName": "Overload Scale", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.OverloadScale", + "Keywords": "chunksending,overloadscale", + "FieldName": "Stratum_perf_ChunkSending_OverloadScale", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.OverloadScale", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Overload Floor Server Tick", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.OverloadFloorServerTick", + "Keywords": "chunksending,overloadfloorservertick", + "FieldName": "Stratum_perf_ChunkSending_OverloadFloorServerTick", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.OverloadFloorServerTick", + "IncludeInCommandLine": false, + "DefaultValue": "64", + "EnumValues": {} + }, + { + "DisplayName": "Overload Floor Client Tick", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.OverloadFloorClientTick", + "Keywords": "chunksending,overloadfloorclienttick", + "FieldName": "Stratum_perf_ChunkSending_OverloadFloorClientTick", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.OverloadFloorClientTick", + "IncludeInCommandLine": false, + "DefaultValue": "8", + "EnumValues": {} + }, + { + "DisplayName": "Fair Scheduling Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.FairSchedulingEnabled", + "Keywords": "chunksending,fairschedulingenabled", + "FieldName": "Stratum_perf_ChunkSending_FairSchedulingEnabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.FairSchedulingEnabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Fair Window Milliseconds", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.FairWindowMilliseconds", + "Keywords": "chunksending,fairwindowmilliseconds", + "FieldName": "Stratum_perf_ChunkSending_FairWindowMilliseconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.FairWindowMilliseconds", + "IncludeInCommandLine": false, + "DefaultValue": "5000", + "EnumValues": {} + }, + { + "DisplayName": "Near Ring Radius Chunks", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.NearRingRadiusChunks", + "Keywords": "chunksending,nearringradiuschunks", + "FieldName": "Stratum_perf_ChunkSending_NearRingRadiusChunks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.NearRingRadiusChunks", + "IncludeInCommandLine": false, + "DefaultValue": "2", + "EnumValues": {} + }, + { + "DisplayName": "Outbound Pressure Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.OutboundPressureEnabled", + "Keywords": "chunksending,outboundpressureenabled", + "FieldName": "Stratum_perf_ChunkSending_OutboundPressureEnabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.OutboundPressureEnabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Outbound Pressure Pending Sends Soft Limit", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.OutboundPressurePendingSendsSoftLimit", + "Keywords": "chunksending,outboundpressurependingsendssoftlimit", + "FieldName": "Stratum_perf_ChunkSending_OutboundPressurePendingSendsSoftLimit", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.OutboundPressurePendingSendsSoftLimit", + "IncludeInCommandLine": false, + "DefaultValue": "8", + "EnumValues": {} + }, + { + "DisplayName": "Outbound Pressure Pending Sends Hard Limit", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.OutboundPressurePendingSendsHardLimit", + "Keywords": "chunksending,outboundpressurependingsendshardlimit", + "FieldName": "Stratum_perf_ChunkSending_OutboundPressurePendingSendsHardLimit", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.OutboundPressurePendingSendsHardLimit", + "IncludeInCommandLine": false, + "DefaultValue": "32", + "EnumValues": {} + }, + { + "DisplayName": "Outbound Pressure Pending Bytes Soft Limit", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.OutboundPressurePendingBytesSoftLimit", + "Keywords": "chunksending,outboundpressurependingbytessoftlimit", + "FieldName": "Stratum_perf_ChunkSending_OutboundPressurePendingBytesSoftLimit", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.OutboundPressurePendingBytesSoftLimit", + "IncludeInCommandLine": false, + "DefaultValue": "262144", + "EnumValues": {} + }, + { + "DisplayName": "Outbound Pressure Pending Bytes Hard Limit", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.OutboundPressurePendingBytesHardLimit", + "Keywords": "chunksending,outboundpressurependingbyteshardlimit", + "FieldName": "Stratum_perf_ChunkSending_OutboundPressurePendingBytesHardLimit", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.OutboundPressurePendingBytesHardLimit", + "IncludeInCommandLine": false, + "DefaultValue": "1048576", + "EnumValues": {} + }, + { + "DisplayName": "Outbound Pressure Scale", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.OutboundPressureScale", + "Keywords": "chunksending,outboundpressurescale", + "FieldName": "Stratum_perf_ChunkSending_OutboundPressureScale", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.OutboundPressureScale", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Outbound Pressure Minimum Client Budget", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Sending:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkSending.OutboundPressureMinimumClientBudget", + "Keywords": "chunksending,outboundpressureminimumclientbudget", + "FieldName": "Stratum_perf_ChunkSending_OutboundPressureMinimumClientBudget", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkSending.OutboundPressureMinimumClientBudget", + "IncludeInCommandLine": false, + "DefaultValue": "2", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Generation:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkGeneration.Enabled", + "Keywords": "chunkgeneration,enabled", + "FieldName": "Stratum_perf_ChunkGeneration_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkGeneration.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Max Column Requests Per Server Tick", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Generation:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkGeneration.MaxColumnRequestsPerServerTick", + "Keywords": "chunkgeneration,maxcolumnrequestsperservertick", + "FieldName": "Stratum_perf_ChunkGeneration_MaxColumnRequestsPerServerTick", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkGeneration.MaxColumnRequestsPerServerTick", + "IncludeInCommandLine": false, + "DefaultValue": "32", + "EnumValues": {} + }, + { + "DisplayName": "Max Column Requests Per Client Tick", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Generation:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkGeneration.MaxColumnRequestsPerClientTick", + "Keywords": "chunkgeneration,maxcolumnrequestsperclienttick", + "FieldName": "Stratum_perf_ChunkGeneration_MaxColumnRequestsPerClientTick", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkGeneration.MaxColumnRequestsPerClientTick", + "IncludeInCommandLine": false, + "DefaultValue": "4", + "EnumValues": {} + }, + { + "DisplayName": "Include Local Clients", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Generation:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkGeneration.IncludeLocalClients", + "Keywords": "chunkgeneration,includelocalclients", + "FieldName": "Stratum_perf_ChunkGeneration_IncludeLocalClients", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkGeneration.IncludeLocalClients", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Adaptive Under Overload", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Generation:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkGeneration.AdaptiveUnderOverload", + "Keywords": "chunkgeneration,adaptiveunderoverload", + "FieldName": "Stratum_perf_ChunkGeneration_AdaptiveUnderOverload", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkGeneration.AdaptiveUnderOverload", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Overload Tick Ms", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Generation:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkGeneration.OverloadTickMs", + "Keywords": "chunkgeneration,overloadtickms", + "FieldName": "Stratum_perf_ChunkGeneration_OverloadTickMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkGeneration.OverloadTickMs", + "IncludeInCommandLine": false, + "DefaultValue": "45", + "EnumValues": {} + }, + { + "DisplayName": "Overload Scale", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Generation:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkGeneration.OverloadScale", + "Keywords": "chunkgeneration,overloadscale", + "FieldName": "Stratum_perf_ChunkGeneration_OverloadScale", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkGeneration.OverloadScale", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Overload Floor Server Tick", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Generation:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkGeneration.OverloadFloorServerTick", + "Keywords": "chunkgeneration,overloadfloorservertick", + "FieldName": "Stratum_perf_ChunkGeneration_OverloadFloorServerTick", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkGeneration.OverloadFloorServerTick", + "IncludeInCommandLine": false, + "DefaultValue": "4", + "EnumValues": {} + }, + { + "DisplayName": "Overload Floor Client Tick", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Generation:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkGeneration.OverloadFloorClientTick", + "Keywords": "chunkgeneration,overloadfloorclienttick", + "FieldName": "Stratum_perf_ChunkGeneration_OverloadFloorClientTick", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkGeneration.OverloadFloorClientTick", + "IncludeInCommandLine": false, + "DefaultValue": "1", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Request Management:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.Enabled", + "Keywords": "chunkrequestmanagement,enabled", + "FieldName": "Stratum_perf_ChunkRequestManagement_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkRequestManagement.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Cancel Stale Pending Requests", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Request Management:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.CancelStalePendingRequests", + "Keywords": "chunkrequestmanagement,cancelstalependingrequests", + "FieldName": "Stratum_perf_ChunkRequestManagement_CancelStalePendingRequests", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkRequestManagement.CancelStalePendingRequests", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Minimum Pending Age Seconds", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Request Management:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.MinimumPendingAgeSeconds", + "Keywords": "chunkrequestmanagement,minimumpendingageseconds", + "FieldName": "Stratum_perf_ChunkRequestManagement_MinimumPendingAgeSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkRequestManagement.MinimumPendingAgeSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "3", + "EnumValues": {} + }, + { + "DisplayName": "Max Distance Beyond View Chunks", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Request Management:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.MaxDistanceBeyondViewChunks", + "Keywords": "chunkrequestmanagement,maxdistancebeyondviewchunks", + "FieldName": "Stratum_perf_ChunkRequestManagement_MaxDistanceBeyondViewChunks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkRequestManagement.MaxDistanceBeyondViewChunks", + "IncludeInCommandLine": false, + "DefaultValue": "2", + "EnumValues": {} + }, + { + "DisplayName": "Cleanup Interval Milliseconds", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Request Management:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.CleanupIntervalMilliseconds", + "Keywords": "chunkrequestmanagement,cleanupintervalmilliseconds", + "FieldName": "Stratum_perf_ChunkRequestManagement_CleanupIntervalMilliseconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkRequestManagement.CleanupIntervalMilliseconds", + "IncludeInCommandLine": false, + "DefaultValue": "1000", + "EnumValues": {} + }, + { + "DisplayName": "Max Tracked Requests Per Cleanup", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Request Management:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.MaxTrackedRequestsPerCleanup", + "Keywords": "chunkrequestmanagement,maxtrackedrequestspercleanup", + "FieldName": "Stratum_perf_ChunkRequestManagement_MaxTrackedRequestsPerCleanup", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkRequestManagement.MaxTrackedRequestsPerCleanup", + "IncludeInCommandLine": false, + "DefaultValue": "512", + "EnumValues": {} + }, + { + "DisplayName": "Max Cancelled Requests Per Cleanup", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Request Management:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.MaxCancelledRequestsPerCleanup", + "Keywords": "chunkrequestmanagement,maxcancelledrequestspercleanup", + "FieldName": "Stratum_perf_ChunkRequestManagement_MaxCancelledRequestsPerCleanup", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkRequestManagement.MaxCancelledRequestsPerCleanup", + "IncludeInCommandLine": false, + "DefaultValue": "128", + "EnumValues": {} + }, + { + "DisplayName": "Prioritize Moving Direction", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Request Management:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.PrioritizeMovingDirection", + "Keywords": "chunkrequestmanagement,prioritizemovingdirection", + "FieldName": "Stratum_perf_ChunkRequestManagement_PrioritizeMovingDirection", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkRequestManagement.PrioritizeMovingDirection", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Forward Prediction Blocks", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Request Management:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.ForwardPredictionBlocks", + "Keywords": "chunkrequestmanagement,forwardpredictionblocks", + "FieldName": "Stratum_perf_ChunkRequestManagement_ForwardPredictionBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkRequestManagement.ForwardPredictionBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "48", + "EnumValues": {} + }, + { + "DisplayName": "Minimum Movement Speed", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Request Management:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.MinimumMovementSpeed", + "Keywords": "chunkrequestmanagement,minimummovementspeed", + "FieldName": "Stratum_perf_ChunkRequestManagement_MinimumMovementSpeed", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkRequestManagement.MinimumMovementSpeed", + "IncludeInCommandLine": false, + "DefaultValue": "0.05", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Pregen:speed:30", + "Description": "data/stratum-performance.json -> $.Pregen.Enabled", + "Keywords": "pregen,enabled", + "FieldName": "Stratum_perf_Pregen_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Pregen.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Max Columns Per Second", + "Category": "Stratum Performance:speed", + "Subcategory": "Pregen:speed:30", + "Description": "data/stratum-performance.json -> $.Pregen.MaxColumnsPerSecond", + "Keywords": "pregen,maxcolumnspersecond", + "FieldName": "Stratum_perf_Pregen_MaxColumnsPerSecond", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Pregen.MaxColumnsPerSecond", + "IncludeInCommandLine": false, + "DefaultValue": "500", + "EnumValues": {} + }, + { + "DisplayName": "Max Scans Per Second", + "Category": "Stratum Performance:speed", + "Subcategory": "Pregen:speed:30", + "Description": "data/stratum-performance.json -> $.Pregen.MaxScansPerSecond", + "Keywords": "pregen,maxscanspersecond", + "FieldName": "Stratum_perf_Pregen_MaxScansPerSecond", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Pregen.MaxScansPerSecond", + "IncludeInCommandLine": false, + "DefaultValue": "4096", + "EnumValues": {} + }, + { + "DisplayName": "Max Pending Column Queue", + "Category": "Stratum Performance:speed", + "Subcategory": "Pregen:speed:30", + "Description": "data/stratum-performance.json -> $.Pregen.MaxPendingColumnQueue", + "Keywords": "pregen,maxpendingcolumnqueue", + "FieldName": "Stratum_perf_Pregen_MaxPendingColumnQueue", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Pregen.MaxPendingColumnQueue", + "IncludeInCommandLine": false, + "DefaultValue": "500", + "EnumValues": {} + }, + { + "DisplayName": "Max Worker Column Queue", + "Category": "Stratum Performance:speed", + "Subcategory": "Pregen:speed:30", + "Description": "data/stratum-performance.json -> $.Pregen.MaxWorkerColumnQueue", + "Keywords": "pregen,maxworkercolumnqueue", + "FieldName": "Stratum_perf_Pregen_MaxWorkerColumnQueue", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Pregen.MaxWorkerColumnQueue", + "IncludeInCommandLine": false, + "DefaultValue": "1000", + "EnumValues": {} + }, + { + "DisplayName": "Max Loaded Chunk Columns", + "Category": "Stratum Performance:speed", + "Subcategory": "Pregen:speed:30", + "Description": "data/stratum-performance.json -> $.Pregen.MaxLoadedChunkColumns", + "Keywords": "pregen,maxloadedchunkcolumns", + "FieldName": "Stratum_perf_Pregen_MaxLoadedChunkColumns", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Pregen.MaxLoadedChunkColumns", + "IncludeInCommandLine": false, + "DefaultValue": "4096", + "EnumValues": {} + }, + { + "DisplayName": "Max Radius Chunks", + "Category": "Stratum Performance:speed", + "Subcategory": "Pregen:speed:30", + "Description": "data/stratum-performance.json -> $.Pregen.MaxRadiusChunks", + "Keywords": "pregen,maxradiuschunks", + "FieldName": "Stratum_perf_Pregen_MaxRadiusChunks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Pregen.MaxRadiusChunks", + "IncludeInCommandLine": false, + "DefaultValue": "1000", + "EnumValues": {} + }, + { + "DisplayName": "Max Area Columns", + "Category": "Stratum Performance:speed", + "Subcategory": "Pregen:speed:30", + "Description": "data/stratum-performance.json -> $.Pregen.MaxAreaColumns", + "Keywords": "pregen,maxareacolumns", + "FieldName": "Stratum_perf_Pregen_MaxAreaColumns", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Pregen.MaxAreaColumns", + "IncludeInCommandLine": false, + "DefaultValue": "1000000", + "EnumValues": {} + }, + { + "DisplayName": "Pause When Players Online", + "Category": "Stratum Performance:speed", + "Subcategory": "Pregen:speed:30", + "Description": "data/stratum-performance.json -> $.Pregen.PauseWhenPlayersOnline", + "Keywords": "pregen,pausewhenplayersonline", + "FieldName": "Stratum_perf_Pregen_PauseWhenPlayersOnline", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Pregen.PauseWhenPlayersOnline", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Pause Below Tps", + "Category": "Stratum Performance:speed", + "Subcategory": "Pregen:speed:30", + "Description": "data/stratum-performance.json -> $.Pregen.PauseBelowTps", + "Keywords": "pregen,pausebelowtps", + "FieldName": "Stratum_perf_Pregen_PauseBelowTps", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Pregen.PauseBelowTps", + "IncludeInCommandLine": false, + "DefaultValue": "15.0", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Progress Log Interval Seconds", + "Category": "Stratum Performance:speed", + "Subcategory": "Pregen:speed:30", + "Description": "data/stratum-performance.json -> $.Pregen.ProgressLogIntervalSeconds", + "Keywords": "pregen,progresslogintervalseconds", + "FieldName": "Stratum_perf_Pregen_ProgressLogIntervalSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Pregen.ProgressLogIntervalSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "60", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Simulation Distance:speed:30", + "Description": "data/stratum-performance.json -> $.SimulationDistance.Enabled", + "Keywords": "simulationdistance,enabled", + "FieldName": "Stratum_perf_SimulationDistance_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.SimulationDistance.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Limit Random Ticks", + "Category": "Stratum Performance:speed", + "Subcategory": "Simulation Distance:speed:30", + "Description": "data/stratum-performance.json -> $.SimulationDistance.LimitRandomTicks", + "Keywords": "simulationdistance,limitrandomticks", + "FieldName": "Stratum_perf_SimulationDistance_LimitRandomTicks", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.SimulationDistance.LimitRandomTicks", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Random Tick Distance Blocks", + "Category": "Stratum Performance:speed", + "Subcategory": "Simulation Distance:speed:30", + "Description": "data/stratum-performance.json -> $.SimulationDistance.RandomTickDistanceBlocks", + "Keywords": "simulationdistance,randomtickdistanceblocks", + "FieldName": "Stratum_perf_SimulationDistance_RandomTickDistanceBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.SimulationDistance.RandomTickDistanceBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "96", + "EnumValues": {} + }, + { + "DisplayName": "Limit Block Game Tick Listeners", + "Category": "Stratum Performance:speed", + "Subcategory": "Simulation Distance:speed:30", + "Description": "data/stratum-performance.json -> $.SimulationDistance.LimitBlockGameTickListeners", + "Keywords": "simulationdistance,limitblockgameticklisteners", + "FieldName": "Stratum_perf_SimulationDistance_LimitBlockGameTickListeners", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.SimulationDistance.LimitBlockGameTickListeners", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Block Game Tick Listener Distance Blocks", + "Category": "Stratum Performance:speed", + "Subcategory": "Simulation Distance:speed:30", + "Description": "data/stratum-performance.json -> $.SimulationDistance.BlockGameTickListenerDistanceBlocks", + "Keywords": "simulationdistance,blockgameticklistenerdistanceblocks", + "FieldName": "Stratum_perf_SimulationDistance_BlockGameTickListenerDistanceBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.SimulationDistance.BlockGameTickListenerDistanceBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "128", + "EnumValues": {} + }, + { + "DisplayName": "Tick Force Loaded Block Listeners", + "Category": "Stratum Performance:speed", + "Subcategory": "Simulation Distance:speed:30", + "Description": "data/stratum-performance.json -> $.SimulationDistance.TickForceLoadedBlockListeners", + "Keywords": "simulationdistance,tickforceloadedblocklisteners", + "FieldName": "Stratum_perf_SimulationDistance_TickForceLoadedBlockListeners", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.SimulationDistance.TickForceLoadedBlockListeners", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Physics:speed:30", + "Description": "data/stratum-performance.json -> $.Physics.Enabled", + "Keywords": "physics,enabled", + "FieldName": "Stratum_perf_Physics_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Physics.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Max Catch Up Ticks Per Server Tick", + "Category": "Stratum Performance:speed", + "Subcategory": "Physics:speed:30", + "Description": "Max physics steps consolidated into a single server tick (catchup). Vanilla used 3, which works fine on a CPU-bound server where every tick is already busy. With Stratum's EAR freeing headroom, the server accumulates spare time during idle ticks and would otherwise dump 2-3 physics steps on the next tick (visible as 15-30ms spikes in an otherwise 4ms average). (data/stratum-performance.json -> $.Physics.MaxCatchUpTicksPerServerTick)", + "Keywords": "physics,maxcatchupticksperservertick", + "FieldName": "Stratum_perf_Physics_MaxCatchUpTicksPerServerTick", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Physics.MaxCatchUpTicksPerServerTick", + "IncludeInCommandLine": false, + "DefaultValue": "2", + "EnumValues": {} + }, + { + "DisplayName": "Overloaded Max Catch Up Ticks Per Server Tick", + "Category": "Stratum Performance:speed", + "Subcategory": "Physics:speed:30", + "Description": "data/stratum-performance.json -> $.Physics.OverloadedMaxCatchUpTicksPerServerTick", + "Keywords": "physics,overloadedmaxcatchupticksperservertick", + "FieldName": "Stratum_perf_Physics_OverloadedMaxCatchUpTicksPerServerTick", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Physics.OverloadedMaxCatchUpTicksPerServerTick", + "IncludeInCommandLine": false, + "DefaultValue": "1", + "EnumValues": {} + }, + { + "DisplayName": "Minimum State Update Interval Ms", + "Category": "Stratum Performance:speed", + "Subcategory": "Physics:speed:30", + "Description": "data/stratum-performance.json -> $.Physics.MinimumStateUpdateIntervalMs", + "Keywords": "physics,minimumstateupdateintervalms", + "FieldName": "Stratum_perf_Physics_MinimumStateUpdateIntervalMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Physics.MinimumStateUpdateIntervalMs", + "IncludeInCommandLine": false, + "DefaultValue": "500", + "EnumValues": {} + }, + { + "DisplayName": "Overloaded State Update Interval Ms", + "Category": "Stratum Performance:speed", + "Subcategory": "Physics:speed:30", + "Description": "data/stratum-performance.json -> $.Physics.OverloadedStateUpdateIntervalMs", + "Keywords": "physics,overloadedstateupdateintervalms", + "FieldName": "Stratum_perf_Physics_OverloadedStateUpdateIntervalMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Physics.OverloadedStateUpdateIntervalMs", + "IncludeInCommandLine": false, + "DefaultValue": "1500", + "EnumValues": {} + }, + { + "DisplayName": "Overloaded Tick Threshold Ms", + "Category": "Stratum Performance:speed", + "Subcategory": "Physics:speed:30", + "Description": "data/stratum-performance.json -> $.Physics.OverloadedTickThresholdMs", + "Keywords": "physics,overloadedtickthresholdms", + "FieldName": "Stratum_perf_Physics_OverloadedTickThresholdMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Physics.OverloadedTickThresholdMs", + "IncludeInCommandLine": false, + "DefaultValue": "60", + "EnumValues": {} + }, + { + "DisplayName": "Parallel Threshold", + "Category": "Stratum Performance:speed", + "Subcategory": "Physics:speed:30", + "Description": "Tickables count threshold to switch from single-thread to parallel physics (vanilla = 800). Lowering this makes parallel physics kick in earlier on busy servers. 32 means: as soon as there are more than ~4 tickables per available physics thread, run in parallel. (data/stratum-performance.json -> $.Physics.ParallelThreshold)", + "Keywords": "physics,parallelthreshold", + "FieldName": "Stratum_perf_Physics_ParallelThreshold", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Physics.ParallelThreshold", + "IncludeInCommandLine": false, + "DefaultValue": "32", + "EnumValues": {} + }, + { + "DisplayName": "Max Threads Override", + "Category": "Stratum Performance:speed", + "Subcategory": "Physics:speed:30", + "Description": "Override for the MagicNum.MaxPhysicsThreads ceiling. 0 = use vanilla MagicNum value. Effective threads are still clamped to [1, 8] internally. (data/stratum-performance.json -> $.Physics.MaxThreadsOverride)", + "Keywords": "physics,maxthreadsoverride", + "FieldName": "Stratum_perf_Physics_MaxThreadsOverride", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Physics.MaxThreadsOverride", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Even Thread Partition", + "Category": "Stratum Performance:speed", + "Subcategory": "Physics:speed:30", + "Description": "When true, evenly split tickables across all physics threads instead of vanilla's \"thread 1 gets the first 480 + a share\" partition (which overloads thread 1). (data/stratum-performance.json -> $.Physics.EvenThreadPartition)", + "Keywords": "physics,eventhreadpartition", + "FieldName": "Stratum_perf_Physics_EvenThreadPartition", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Physics.EvenThreadPartition", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Activation Range Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Physics:speed:30", + "Description": "Stratum: Paper-style Entity Activation Range for PhysicsManager. Far-tracked entities (IsTracked == 1, >50 blocks from any player) tick threadsafe behaviors and OnPhysicsTick at reduced frequency, interleaved deterministically by EntityId so the cost spreads evenly across physics steps. (data/stratum-performance.json -> $.Physics.ActivationRangeEnabled)", + "Keywords": "physics,activationrangeenabled", + "FieldName": "Stratum_perf_Physics_ActivationRangeEnabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Physics.ActivationRangeEnabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Far Tracked Tick Stride", + "Category": "Stratum Performance:speed", + "Subcategory": "Physics:speed:30", + "Description": "Frame stride for entities in the MID band (NearActivationRadiusBlocks .. MidActivationRadiusBlocks). 2 = half-rate (~15Hz instead of 30Hz). Was the old \"far-tracked\" stride when EAR keyed off the binary IsTracked field; now drives the configurable distance band. (data/stratum-performance.json -> $.Physics.FarTrackedTickStride)", + "Keywords": "physics,fartrackedtickstride", + "FieldName": "Stratum_perf_Physics_FarTrackedTickStride", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Physics.FarTrackedTickStride", + "IncludeInCommandLine": false, + "DefaultValue": "2", + "EnumValues": {} + }, + { + "DisplayName": "Untracked Behavior Tick Stride", + "Category": "Stratum Performance:speed", + "Subcategory": "Physics:speed:30", + "Description": "Frame stride for OnGameTick behaviors of untracked entities (IsTracked == 0). These entities are skipped for OnPhysicsTick already, but vanilla still runs all threadsafe behaviors every physics step. 4 = quarter-rate. 1 disables throttling. (data/stratum-performance.json -> $.Physics.UntrackedBehaviorTickStride)", + "Keywords": "physics,untrackedbehaviortickstride", + "FieldName": "Stratum_perf_Physics_UntrackedBehaviorTickStride", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Physics.UntrackedBehaviorTickStride", + "IncludeInCommandLine": false, + "DefaultValue": "4", + "EnumValues": {} + }, + { + "DisplayName": "Near Activation Radius Blocks", + "Category": "Stratum Performance:speed", + "Subcategory": "Physics:speed:30", + "Description": "Distance bands for EAR (Paper-style activation range). Uses Entity.NearestPlayerDistance directly instead of the binary IsTracked field, so EAR provides benefit even on solo/low-pop servers where vanilla's hardcoded 50-block IsTracked boundary engulfs all entities. (data/stratum-performance.json -> $.Physics.NearActivationRadiusBlocks)", + "Keywords": "physics,nearactivationradiusblocks", + "FieldName": "Stratum_perf_Physics_NearActivationRadiusBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Physics.NearActivationRadiusBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Mid Activation Radius Blocks", + "Category": "Stratum Performance:speed", + "Subcategory": "Physics:speed:30", + "Description": "data/stratum-performance.json -> $.Physics.MidActivationRadiusBlocks", + "Keywords": "physics,midactivationradiusblocks", + "FieldName": "Stratum_perf_Physics_MidActivationRadiusBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Physics.MidActivationRadiusBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Far Band Tick Stride", + "Category": "Stratum Performance:speed", + "Subcategory": "Physics:speed:30", + "Description": "Stride for entities beyond MidActivationRadiusBlocks but still tracked (IsTracked > 0). (data/stratum-performance.json -> $.Physics.FarBandTickStride)", + "Keywords": "physics,farbandtickstride", + "FieldName": "Stratum_perf_Physics_FarBandTickStride", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Physics.FarBandTickStride", + "IncludeInCommandLine": false, + "DefaultValue": "3", + "EnumValues": {} + }, + { + "DisplayName": "Max Activations Per Tick", + "Category": "Stratum Performance:speed", + "Subcategory": "Physics:speed:30", + "Description": "Max entities to dequeue from the toAdd queue per tick. Prevents spikes when multiple chunks load simultaneously and dump 50-100 new physics tickables in one frame. Deferred entities stay in the queue and drain on subsequent ticks. 0 = no limit. (data/stratum-performance.json -> $.Physics.MaxActivationsPerTick)", + "Keywords": "physics,maxactivationspertick", + "FieldName": "Stratum_perf_Physics_MaxActivationsPerTick", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Physics.MaxActivationsPerTick", + "IncludeInCommandLine": false, + "DefaultValue": "50", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "data/stratum-performance.json -> $.EntityTicking.Enabled", + "Keywords": "entityticking,enabled", + "FieldName": "Stratum_perf_EntityTicking_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Near Distance Blocks", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "Near zone: entities within this distance of any player tick every server tick. (data/stratum-performance.json -> $.EntityTicking.NearDistanceBlocks)", + "Keywords": "entityticking,neardistanceblocks", + "FieldName": "Stratum_perf_EntityTicking_NearDistanceBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.NearDistanceBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "32", + "EnumValues": {} + }, + { + "DisplayName": "Mid Distance Blocks", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "Mid zone: entities within this distance tick every Nth tick. (data/stratum-performance.json -> $.EntityTicking.MidDistanceBlocks)", + "Keywords": "entityticking,middistanceblocks", + "FieldName": "Stratum_perf_EntityTicking_MidDistanceBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.MidDistanceBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "64", + "EnumValues": {} + }, + { + "DisplayName": "Mid Tick Interval", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "data/stratum-performance.json -> $.EntityTicking.MidTickInterval", + "Keywords": "entityticking,midtickinterval", + "FieldName": "Stratum_perf_EntityTicking_MidTickInterval", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.MidTickInterval", + "IncludeInCommandLine": false, + "DefaultValue": "2", + "EnumValues": {} + }, + { + "DisplayName": "Far Entity Distance Blocks", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "Far zone: entities within this distance tick every Nth tick. (data/stratum-performance.json -> $.EntityTicking.FarEntityDistanceBlocks)", + "Keywords": "entityticking,farentitydistanceblocks", + "FieldName": "Stratum_perf_EntityTicking_FarEntityDistanceBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.FarEntityDistanceBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "96", + "EnumValues": {} + }, + { + "DisplayName": "Far Entity Tick Interval", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "data/stratum-performance.json -> $.EntityTicking.FarEntityTickInterval", + "Keywords": "entityticking,farentitytickinterval", + "FieldName": "Stratum_perf_EntityTicking_FarEntityTickInterval", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.FarEntityTickInterval", + "IncludeInCommandLine": false, + "DefaultValue": "5", + "EnumValues": {} + }, + { + "DisplayName": "Very Far Tick Interval", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "Very-far zone: entities beyond Far tick every Nth tick. 1 = same as no throttle. (data/stratum-performance.json -> $.EntityTicking.VeryFarTickInterval)", + "Keywords": "entityticking,veryfartickinterval", + "FieldName": "Stratum_perf_EntityTicking_VeryFarTickInterval", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.VeryFarTickInterval", + "IncludeInCommandLine": false, + "DefaultValue": "10", + "EnumValues": {} + }, + { + "DisplayName": "Throttle Creatures", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "data/stratum-performance.json -> $.EntityTicking.ThrottleCreatures", + "Keywords": "entityticking,throttlecreatures", + "FieldName": "Stratum_perf_EntityTicking_ThrottleCreatures", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.ThrottleCreatures", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Throttle Inanimate", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "data/stratum-performance.json -> $.EntityTicking.ThrottleInanimate", + "Keywords": "entityticking,throttleinanimate", + "FieldName": "Stratum_perf_EntityTicking_ThrottleInanimate", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.ThrottleInanimate", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Skip Moving Entities", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "data/stratum-performance.json -> $.EntityTicking.SkipMovingEntities", + "Keywords": "entityticking,skipmovingentities", + "FieldName": "Stratum_perf_EntityTicking_SkipMovingEntities", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.SkipMovingEntities", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Moving Entity Speed Threshold", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "data/stratum-performance.json -> $.EntityTicking.MovingEntitySpeedThreshold", + "Keywords": "entityticking,movingentityspeedthreshold", + "FieldName": "Stratum_perf_EntityTicking_MovingEntitySpeedThreshold", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.MovingEntitySpeedThreshold", + "IncludeInCommandLine": false, + "DefaultValue": "0.01", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Max Creature Ticks Per Tick", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "Hard cap on creature entities ticked per server tick (round-robin fairness via accumulated dt). 0 = unlimited. Recommended ~ (target tick ms) * (ticks-per-ms creature budget). (data/stratum-performance.json -> $.EntityTicking.MaxCreatureTicksPerTick)", + "Keywords": "entityticking,maxcreaturetickspertick", + "FieldName": "Stratum_perf_EntityTicking_MaxCreatureTicksPerTick", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.MaxCreatureTicksPerTick", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Ambient Fauna Tier Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "Paper-style ambient fauna tier. Entities whose code path matches one of these prefixes get an extra stride multiplier on top of the distance-band tickInterval. Ambient creatures (fish, butterflies, bees, hens etc.) are background mood and don't need 30Hz AI even when a player is nearby. Lazy-resolved per-entity and cached. (data/stratum-performance.json -> $.EntityTicking.AmbientFaunaTierEnabled)", + "Keywords": "entityticking,ambientfaunatierenabled", + "FieldName": "Stratum_perf_EntityTicking_AmbientFaunaTierEnabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.AmbientFaunaTierEnabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Ambient Fauna Tick Multiplier", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "data/stratum-performance.json -> $.EntityTicking.AmbientFaunaTickMultiplier", + "Keywords": "entityticking,ambientfaunatickmultiplier", + "FieldName": "Stratum_perf_EntityTicking_AmbientFaunaTickMultiplier", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.AmbientFaunaTickMultiplier", + "IncludeInCommandLine": false, + "DefaultValue": "2", + "EnumValues": {} + }, + { + "DisplayName": "Hard Despawn Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "Paper-style hard despawn: creatures that have been beyond HardDespawnDistanceBlocks from every player for HardDespawnGracePeriodSeconds get unloaded. Off by default. Enable only on long-running worlds where stray mobs accumulate in old chunks. (data/stratum-performance.json -> $.EntityTicking.HardDespawnEnabled)", + "Keywords": "entityticking,harddespawnenabled", + "FieldName": "Stratum_perf_EntityTicking_HardDespawnEnabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.HardDespawnEnabled", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Hard Despawn Distance Blocks", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "data/stratum-performance.json -> $.EntityTicking.HardDespawnDistanceBlocks", + "Keywords": "entityticking,harddespawndistanceblocks", + "FieldName": "Stratum_perf_EntityTicking_HardDespawnDistanceBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.HardDespawnDistanceBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "128", + "EnumValues": {} + }, + { + "DisplayName": "Hard Despawn Grace Period Seconds", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "data/stratum-performance.json -> $.EntityTicking.HardDespawnGracePeriodSeconds", + "Keywords": "entityticking,harddespawngraceperiodseconds", + "FieldName": "Stratum_perf_EntityTicking_HardDespawnGracePeriodSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.HardDespawnGracePeriodSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "30", + "EnumValues": {} + }, + { + "DisplayName": "Hard Despawn Exempt If Named", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "Skip entities whose nametag attribute has been set (Name Tag item, custom-named mobs). (data/stratum-performance.json -> $.EntityTicking.HardDespawnExemptIfNamed)", + "Keywords": "entityticking,harddespawnexemptifnamed", + "FieldName": "Stratum_perf_EntityTicking_HardDespawnExemptIfNamed", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.HardDespawnExemptIfNamed", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Entity Caps Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "Stratum per-chunk-column entity caps. Periodically scans loaded entities and culls the oldest excess in any column that exceeds the cap. Creatures honor the same exempt prefixes and named-entity rule as hard despawn so livestock & tames aren't culled. Item entities (ground drops) ignore those exemptions; uncollected loot is fair game. (data/stratum-performance.json -> $.EntityTicking.EntityCapsEnabled)", + "Keywords": "entityticking,entitycapsenabled", + "FieldName": "Stratum_perf_EntityTicking_EntityCapsEnabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.EntityCapsEnabled", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Entity Caps Enforcement Interval Seconds", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "data/stratum-performance.json -> $.EntityTicking.EntityCapsEnforcementIntervalSeconds", + "Keywords": "entityticking,entitycapsenforcementintervalseconds", + "FieldName": "Stratum_perf_EntityTicking_EntityCapsEnforcementIntervalSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.EntityCapsEnforcementIntervalSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "10", + "EnumValues": {} + }, + { + "DisplayName": "Max Creatures Per Chunk Column", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "data/stratum-performance.json -> $.EntityTicking.MaxCreaturesPerChunkColumn", + "Keywords": "entityticking,maxcreaturesperchunkcolumn", + "FieldName": "Stratum_perf_EntityTicking_MaxCreaturesPerChunkColumn", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.MaxCreaturesPerChunkColumn", + "IncludeInCommandLine": false, + "DefaultValue": "32", + "EnumValues": {} + }, + { + "DisplayName": "Max Item Entities Per Chunk Column", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Ticking:speed:30", + "Description": "data/stratum-performance.json -> $.EntityTicking.MaxItemEntitiesPerChunkColumn", + "Keywords": "entityticking,maxitementitiesperchunkcolumn", + "FieldName": "Stratum_perf_EntityTicking_MaxItemEntitiesPerChunkColumn", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityTicking.MaxItemEntitiesPerChunkColumn", + "IncludeInCommandLine": false, + "DefaultValue": "64", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Io:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkIo.Enabled", + "Keywords": "chunkio,enabled", + "FieldName": "Stratum_perf_ChunkIo_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkIo.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Worker Threads", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Io:speed:30", + "Description": "Worker connections in the pool. Each is a fully-prepared read-only SqliteConnection; cost is one OS file handle + a few KB per connection. Useful range is 2-8; saturating SSDs usually happens around 4. (data/stratum-performance.json -> $.ChunkIo.WorkerThreads)", + "Keywords": "chunkio,workerthreads", + "FieldName": "Stratum_perf_ChunkIo_WorkerThreads", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkIo.WorkerThreads", + "IncludeInCommandLine": false, + "DefaultValue": "4", + "EnumValues": {} + }, + { + "DisplayName": "Min Chunk Y Levels For Parallel", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Io:speed:30", + "Description": "Threshold below which the parallel read path is bypassed (small columns aren't worth the dispatch overhead). (data/stratum-performance.json -> $.ChunkIo.MinChunkYLevelsForParallel)", + "Keywords": "chunkio,minchunkylevelsforparallel", + "FieldName": "Stratum_perf_ChunkIo_MinChunkYLevelsForParallel", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkIo.MinChunkYLevelsForParallel", + "IncludeInCommandLine": false, + "DefaultValue": "4", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Priority:speed:30", + "Description": "data/stratum-performance.json -> $.ChunkPriority.Enabled", + "Keywords": "chunkpriority,enabled", + "FieldName": "Stratum_perf_ChunkPriority_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkPriority.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Max Sorted Per Tick", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Priority:speed:30", + "Description": "Cap on requests pulled into the sort window each chunk-thread iteration. Keeps the sort cost bounded regardless of queue size. (data/stratum-performance.json -> $.ChunkPriority.MaxSortedPerTick)", + "Keywords": "chunkpriority,maxsortedpertick", + "FieldName": "Stratum_perf_ChunkPriority_MaxSortedPerTick", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkPriority.MaxSortedPerTick", + "IncludeInCommandLine": false, + "DefaultValue": "64", + "EnumValues": {} + }, + { + "DisplayName": "Prediction Seconds", + "Category": "Stratum Performance:speed", + "Subcategory": "Chunk Priority:speed:30", + "Description": "Forward-predict each player's chunk position by this many seconds based on .Motion so chunks ahead of motion are loaded earlier than chunks behind. 0 disables prediction. (data/stratum-performance.json -> $.ChunkPriority.PredictionSeconds)", + "Keywords": "chunkpriority,predictionseconds", + "FieldName": "Stratum_perf_ChunkPriority_PredictionSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ChunkPriority.PredictionSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Auto Save:speed:30", + "Description": "data/stratum-performance.json -> $.AutoSave.Enabled", + "Keywords": "autosave,enabled", + "FieldName": "Stratum_perf_AutoSave_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.AutoSave.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Delay During Chunk Pressure", + "Category": "Stratum Performance:speed", + "Subcategory": "Auto Save:speed:30", + "Description": "data/stratum-performance.json -> $.AutoSave.DelayDuringChunkPressure", + "Keywords": "autosave,delayduringchunkpressure", + "FieldName": "Stratum_perf_AutoSave_DelayDuringChunkPressure", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.AutoSave.DelayDuringChunkPressure", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Incremental Dirty Flush", + "Category": "Stratum Performance:speed", + "Subcategory": "Auto Save:speed:30", + "Description": "data/stratum-performance.json -> $.AutoSave.IncrementalDirtyFlush", + "Keywords": "autosave,incrementaldirtyflush", + "FieldName": "Stratum_perf_AutoSave_IncrementalDirtyFlush", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.AutoSave.IncrementalDirtyFlush", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Max Pending Chunk Columns", + "Category": "Stratum Performance:speed", + "Subcategory": "Auto Save:speed:30", + "Description": "data/stratum-performance.json -> $.AutoSave.MaxPendingChunkColumns", + "Keywords": "autosave,maxpendingchunkcolumns", + "FieldName": "Stratum_perf_AutoSave_MaxPendingChunkColumns", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.AutoSave.MaxPendingChunkColumns", + "IncludeInCommandLine": false, + "DefaultValue": "256", + "EnumValues": {} + }, + { + "DisplayName": "Max Worker Chunk Columns", + "Category": "Stratum Performance:speed", + "Subcategory": "Auto Save:speed:30", + "Description": "data/stratum-performance.json -> $.AutoSave.MaxWorkerChunkColumns", + "Keywords": "autosave,maxworkerchunkcolumns", + "FieldName": "Stratum_perf_AutoSave_MaxWorkerChunkColumns", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.AutoSave.MaxWorkerChunkColumns", + "IncludeInCommandLine": false, + "DefaultValue": "512", + "EnumValues": {} + }, + { + "DisplayName": "Max Delay Seconds", + "Category": "Stratum Performance:speed", + "Subcategory": "Auto Save:speed:30", + "Description": "data/stratum-performance.json -> $.AutoSave.MaxDelaySeconds", + "Keywords": "autosave,maxdelayseconds", + "FieldName": "Stratum_perf_AutoSave_MaxDelaySeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.AutoSave.MaxDelaySeconds", + "IncludeInCommandLine": false, + "DefaultValue": "120", + "EnumValues": {} + }, + { + "DisplayName": "Incremental Flush Interval Seconds", + "Category": "Stratum Performance:speed", + "Subcategory": "Auto Save:speed:30", + "Description": "data/stratum-performance.json -> $.AutoSave.IncrementalFlushIntervalSeconds", + "Keywords": "autosave,incrementalflushintervalseconds", + "FieldName": "Stratum_perf_AutoSave_IncrementalFlushIntervalSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.AutoSave.IncrementalFlushIntervalSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "10", + "EnumValues": {} + }, + { + "DisplayName": "Max Loaded Chunks Per Flush", + "Category": "Stratum Performance:speed", + "Subcategory": "Auto Save:speed:30", + "Description": "data/stratum-performance.json -> $.AutoSave.MaxLoadedChunksPerFlush", + "Keywords": "autosave,maxloadedchunksperflush", + "FieldName": "Stratum_perf_AutoSave_MaxLoadedChunksPerFlush", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.AutoSave.MaxLoadedChunksPerFlush", + "IncludeInCommandLine": false, + "DefaultValue": "256", + "EnumValues": {} + }, + { + "DisplayName": "Max Map Chunks Per Flush", + "Category": "Stratum Performance:speed", + "Subcategory": "Auto Save:speed:30", + "Description": "data/stratum-performance.json -> $.AutoSave.MaxMapChunksPerFlush", + "Keywords": "autosave,maxmapchunksperflush", + "FieldName": "Stratum_perf_AutoSave_MaxMapChunksPerFlush", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.AutoSave.MaxMapChunksPerFlush", + "IncludeInCommandLine": false, + "DefaultValue": "128", + "EnumValues": {} + }, + { + "DisplayName": "Max Loaded Chunk Scans Per Flush", + "Category": "Stratum Performance:speed", + "Subcategory": "Auto Save:speed:30", + "Description": "data/stratum-performance.json -> $.AutoSave.MaxLoadedChunkScansPerFlush", + "Keywords": "autosave,maxloadedchunkscansperflush", + "FieldName": "Stratum_perf_AutoSave_MaxLoadedChunkScansPerFlush", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.AutoSave.MaxLoadedChunkScansPerFlush", + "IncludeInCommandLine": false, + "DefaultValue": "4096", + "EnumValues": {} + }, + { + "DisplayName": "Max Map Chunk Scans Per Flush", + "Category": "Stratum Performance:speed", + "Subcategory": "Auto Save:speed:30", + "Description": "data/stratum-performance.json -> $.AutoSave.MaxMapChunkScansPerFlush", + "Keywords": "autosave,maxmapchunkscansperflush", + "FieldName": "Stratum_perf_AutoSave_MaxMapChunkScansPerFlush", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.AutoSave.MaxMapChunkScansPerFlush", + "IncludeInCommandLine": false, + "DefaultValue": "2048", + "EnumValues": {} + }, + { + "DisplayName": "Save Scan Refresh Seconds", + "Category": "Stratum Performance:speed", + "Subcategory": "Auto Save:speed:30", + "Description": "data/stratum-performance.json -> $.AutoSave.SaveScanRefreshSeconds", + "Keywords": "autosave,savescanrefreshseconds", + "FieldName": "Stratum_perf_AutoSave_SaveScanRefreshSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.AutoSave.SaveScanRefreshSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "30", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Block Ticks:speed:30", + "Description": "data/stratum-performance.json -> $.BlockTicks.Enabled", + "Keywords": "blockticks,enabled", + "FieldName": "Stratum_perf_BlockTicks_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockTicks.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Max Chunks Per Pass", + "Category": "Stratum Performance:speed", + "Subcategory": "Block Ticks:speed:30", + "Description": "data/stratum-performance.json -> $.BlockTicks.MaxChunksPerPass", + "Keywords": "blockticks,maxchunksperpass", + "FieldName": "Stratum_perf_BlockTicks_MaxChunksPerPass", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockTicks.MaxChunksPerPass", + "IncludeInCommandLine": false, + "DefaultValue": "512", + "EnumValues": {} + }, + { + "DisplayName": "Max Random Ticks Per Chunk", + "Category": "Stratum Performance:speed", + "Subcategory": "Block Ticks:speed:30", + "Description": "data/stratum-performance.json -> $.BlockTicks.MaxRandomTicksPerChunk", + "Keywords": "blockticks,maxrandomticksperchunk", + "FieldName": "Stratum_perf_BlockTicks_MaxRandomTicksPerChunk", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockTicks.MaxRandomTicksPerChunk", + "IncludeInCommandLine": false, + "DefaultValue": "8", + "EnumValues": {} + }, + { + "DisplayName": "Max Main Thread Block Ticks Per Pass", + "Category": "Stratum Performance:speed", + "Subcategory": "Block Ticks:speed:30", + "Description": "data/stratum-performance.json -> $.BlockTicks.MaxMainThreadBlockTicksPerPass", + "Keywords": "blockticks,maxmainthreadblockticksperpass", + "FieldName": "Stratum_perf_BlockTicks_MaxMainThreadBlockTicksPerPass", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockTicks.MaxMainThreadBlockTicksPerPass", + "IncludeInCommandLine": false, + "DefaultValue": "5000", + "EnumValues": {} + }, + { + "DisplayName": "Random Tick Slice Count", + "Category": "Stratum Performance:speed", + "Subcategory": "Block Ticks:speed:30", + "Description": "Spread the random tick pass across N smaller slices instead of one burst. Each slice runs at BlockTickInterval/SliceCount ms and processes 1/SliceCount of the chunk set. Same aggregate rate per chunk, removes the periodic sawtooth spike. 1 = vanilla batch. (data/stratum-performance.json -> $.BlockTicks.RandomTickSliceCount)", + "Keywords": "blockticks,randomtickslicecount", + "FieldName": "Stratum_perf_BlockTicks_RandomTickSliceCount", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockTicks.RandomTickSliceCount", + "IncludeInCommandLine": false, + "DefaultValue": "8", + "EnumValues": {} + }, + { + "DisplayName": "Adaptive Under Overload", + "Category": "Stratum Performance:speed", + "Subcategory": "Block Ticks:speed:30", + "Description": "Self-tuning under load: when the recent average server tick exceeds OverloadTickMs the per-chunk random-tick budget is scaled down (multiplied by OverloadScale, then floored at OverloadFloor). Lets crops/fluids/fire tick at full rate when the server has headroom and dial back automatically when it doesn't, instead of needing a manual config bump under load. (data/stratum-performance.json -> $.BlockTicks.AdaptiveUnderOverload)", + "Keywords": "blockticks,adaptiveunderoverload", + "FieldName": "Stratum_perf_BlockTicks_AdaptiveUnderOverload", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockTicks.AdaptiveUnderOverload", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Overload Tick Ms", + "Category": "Stratum Performance:speed", + "Subcategory": "Block Ticks:speed:30", + "Description": "data/stratum-performance.json -> $.BlockTicks.OverloadTickMs", + "Keywords": "blockticks,overloadtickms", + "FieldName": "Stratum_perf_BlockTicks_OverloadTickMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockTicks.OverloadTickMs", + "IncludeInCommandLine": false, + "DefaultValue": "45", + "EnumValues": {} + }, + { + "DisplayName": "Overload Scale", + "Category": "Stratum Performance:speed", + "Subcategory": "Block Ticks:speed:30", + "Description": "data/stratum-performance.json -> $.BlockTicks.OverloadScale", + "Keywords": "blockticks,overloadscale", + "FieldName": "Stratum_perf_BlockTicks_OverloadScale", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockTicks.OverloadScale", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Overload Floor", + "Category": "Stratum Performance:speed", + "Subcategory": "Block Ticks:speed:30", + "Description": "data/stratum-performance.json -> $.BlockTicks.OverloadFloor", + "Keywords": "blockticks,overloadfloor", + "FieldName": "Stratum_perf_BlockTicks_OverloadFloor", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockTicks.OverloadFloor", + "IncludeInCommandLine": false, + "DefaultValue": "2", + "EnumValues": {} + }, + { + "DisplayName": "Enabled On Startup", + "Category": "Stratum Performance:speed", + "Subcategory": "Timings:speed:30", + "Description": "data/stratum-performance.json -> $.Timings.EnabledOnStartup", + "Keywords": "timings,enabledonstartup", + "FieldName": "Stratum_perf_Timings_EnabledOnStartup", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Timings.EnabledOnStartup", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Report Top Entries", + "Category": "Stratum Performance:speed", + "Subcategory": "Timings:speed:30", + "Description": "data/stratum-performance.json -> $.Timings.ReportTopEntries", + "Keywords": "timings,reporttopentries", + "FieldName": "Stratum_perf_Timings_ReportTopEntries", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Timings.ReportTopEntries", + "IncludeInCommandLine": false, + "DefaultValue": "30", + "EnumValues": {} + }, + { + "DisplayName": "Slow Sample Threshold Ms", + "Category": "Stratum Performance:speed", + "Subcategory": "Timings:speed:30", + "Description": "data/stratum-performance.json -> $.Timings.SlowSampleThresholdMs", + "Keywords": "timings,slowsamplethresholdms", + "FieldName": "Stratum_perf_Timings_SlowSampleThresholdMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Timings.SlowSampleThresholdMs", + "IncludeInCommandLine": false, + "DefaultValue": "50", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Async", + "Category": "Stratum Performance:speed", + "Subcategory": "Pathfinding:speed:30", + "Description": "Move pathfinding tasks off the main thread onto a dedicated worker pool. (data/stratum-performance.json -> $.Pathfinding.Async)", + "Keywords": "pathfinding,async", + "FieldName": "Stratum_perf_Pathfinding_Async", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Pathfinding.Async", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Worker Threads", + "Category": "Stratum Performance:speed", + "Subcategory": "Pathfinding:speed:30", + "Description": "Worker thread count for async pathfinding. 0 = auto (max(2, Environment.ProcessorCount / 2)). (data/stratum-performance.json -> $.Pathfinding.WorkerThreads)", + "Keywords": "pathfinding,workerthreads", + "FieldName": "Stratum_perf_Pathfinding_WorkerThreads", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Pathfinding.WorkerThreads", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Max Queued", + "Category": "Stratum Performance:speed", + "Subcategory": "Pathfinding:speed:30", + "Description": "Max queued pathfind requests before stale or oldest queued work is dropped. 0 = unbounded. (data/stratum-performance.json -> $.Pathfinding.MaxQueued)", + "Keywords": "pathfinding,maxqueued", + "FieldName": "Stratum_perf_Pathfinding_MaxQueued", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Pathfinding.MaxQueued", + "IncludeInCommandLine": false, + "DefaultValue": "512", + "EnumValues": {} + }, + { + "DisplayName": "Max Task Age Ms", + "Category": "Stratum Performance:speed", + "Subcategory": "Pathfinding:speed:30", + "Description": "Queued async path requests older than this are considered stale and can be discarded before useful work is dropped. 0 = never stale by age. (data/stratum-performance.json -> $.Pathfinding.MaxTaskAgeMs)", + "Keywords": "pathfinding,maxtaskagems", + "FieldName": "Stratum_perf_Pathfinding_MaxTaskAgeMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Pathfinding.MaxTaskAgeMs", + "IncludeInCommandLine": false, + "DefaultValue": "2000", + "EnumValues": {} + }, + { + "DisplayName": "Priority Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Pathfinding:speed:30", + "Description": "Reorders queued work near players first once the queue is backed up. (data/stratum-performance.json -> $.Pathfinding.PriorityEnabled)", + "Keywords": "pathfinding,priorityenabled", + "FieldName": "Stratum_perf_Pathfinding_PriorityEnabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Pathfinding.PriorityEnabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Priority Queue Threshold", + "Category": "Stratum Performance:speed", + "Subcategory": "Pathfinding:speed:30", + "Description": "Queue depth that enables priority sorting and pressure-only far task drops. (data/stratum-performance.json -> $.Pathfinding.PriorityQueueThreshold)", + "Keywords": "pathfinding,priorityqueuethreshold", + "FieldName": "Stratum_perf_Pathfinding_PriorityQueueThreshold", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Pathfinding.PriorityQueueThreshold", + "IncludeInCommandLine": false, + "DefaultValue": "64", + "EnumValues": {} + }, + { + "DisplayName": "Far Task Distance Blocks", + "Category": "Stratum Performance:speed", + "Subcategory": "Pathfinding:speed:30", + "Description": "Queued tasks whose owner is farther than this from all players can be dropped under queue pressure. 0 disables distance-based dropping. (data/stratum-performance.json -> $.Pathfinding.FarTaskDistanceBlocks)", + "Keywords": "pathfinding,fartaskdistanceblocks", + "FieldName": "Stratum_perf_Pathfinding_FarTaskDistanceBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Pathfinding.FarTaskDistanceBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "160", + "EnumValues": {} + }, + { + "DisplayName": "Drop Far Tasks Under Pressure", + "Category": "Stratum Performance:speed", + "Subcategory": "Pathfinding:speed:30", + "Description": "data/stratum-performance.json -> $.Pathfinding.DropFarTasksUnderPressure", + "Keywords": "pathfinding,dropfartasksunderpressure", + "FieldName": "Stratum_perf_Pathfinding_DropFarTasksUnderPressure", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Pathfinding.DropFarTasksUnderPressure", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Failure Cooldown After Failures", + "Category": "Stratum Performance:speed", + "Subcategory": "Pathfinding:speed:30", + "Description": "A short per-traverser cooldown after repeated no-path results. Keeps mobs from burning worker time on the same impossible goal every tick. (data/stratum-performance.json -> $.Pathfinding.FailureCooldownAfterFailures)", + "Keywords": "pathfinding,failurecooldownafterfailures", + "FieldName": "Stratum_perf_Pathfinding_FailureCooldownAfterFailures", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Pathfinding.FailureCooldownAfterFailures", + "IncludeInCommandLine": false, + "DefaultValue": "3", + "EnumValues": {} + }, + { + "DisplayName": "Failure Cooldown Ms", + "Category": "Stratum Performance:speed", + "Subcategory": "Pathfinding:speed:30", + "Description": "data/stratum-performance.json -> $.Pathfinding.FailureCooldownMs", + "Keywords": "pathfinding,failurecooldownms", + "FieldName": "Stratum_perf_Pathfinding_FailureCooldownMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Pathfinding.FailureCooldownMs", + "IncludeInCommandLine": false, + "DefaultValue": "1500", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Region Ticking:speed:30", + "Description": "Folia-style regionized entity ticking. Splits LoadedEntities into spatial regions (region size in chunks) and ticks each region on a worker thread in parallel. Behaviors that throw repeatedly get runtime-blocked via FallbackAfterExceptions. Disabled by default: entity behaviors from mods may not be thread-safe. Enable after validating your mod set under load. Unsafe behaviors self-quarantine to serial. (data/stratum-performance.json -> $.RegionTicking.Enabled)", + "Keywords": "regionticking,enabled", + "FieldName": "Stratum_perf_RegionTicking_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.RegionTicking.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Region Size Chunks", + "Category": "Stratum Performance:speed", + "Subcategory": "Region Ticking:speed:30", + "Description": "Region size in chunks (e.g. 8 = 8x8 chunk regions = 256x256 blocks). (data/stratum-performance.json -> $.RegionTicking.RegionSizeChunks)", + "Keywords": "regionticking,regionsizechunks", + "FieldName": "Stratum_perf_RegionTicking_RegionSizeChunks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.RegionTicking.RegionSizeChunks", + "IncludeInCommandLine": false, + "DefaultValue": "8", + "EnumValues": {} + }, + { + "DisplayName": "Worker Threads", + "Category": "Stratum Performance:speed", + "Subcategory": "Region Ticking:speed:30", + "Description": "Worker thread count. 0 = auto (max(1, Environment.ProcessorCount - 2)). (data/stratum-performance.json -> $.RegionTicking.WorkerThreads)", + "Keywords": "regionticking,workerthreads", + "FieldName": "Stratum_perf_RegionTicking_WorkerThreads", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.RegionTicking.WorkerThreads", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": {} + }, + { + "DisplayName": "Min Entities Per Region", + "Category": "Stratum Performance:speed", + "Subcategory": "Region Ticking:speed:30", + "Description": "Min entities required in a region to consider parallel ticking (small regions stay on main thread). (data/stratum-performance.json -> $.RegionTicking.MinEntitiesPerRegion)", + "Keywords": "regionticking,minentitiesperregion", + "FieldName": "Stratum_perf_RegionTicking_MinEntitiesPerRegion", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.RegionTicking.MinEntitiesPerRegion", + "IncludeInCommandLine": false, + "DefaultValue": "16", + "EnumValues": {} + }, + { + "DisplayName": "Entity Filter Mode", + "Category": "Stratum Performance:speed", + "Subcategory": "Region Ticking:speed:30", + "Description": "Entity filter mode. Controls which entities tick in parallel worker threads vs main thread. \"all\" = current behavior (all non-players go parallel). \"denylist\" = entities matching BlockedEntityCodePrefixes or BlockedEntityClasses tick on main thread. \"allowlist\" = only entities matching AllowedEntityCodePrefixes go parallel, everything else stays serial. (data/stratum-performance.json -> $.RegionTicking.EntityFilterMode)", + "Keywords": "regionticking,entityfiltermode", + "FieldName": "Stratum_perf_RegionTicking_EntityFilterMode", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.RegionTicking.EntityFilterMode", + "IncludeInCommandLine": false, + "DefaultValue": "all", + "EnumValues": {} + }, + { + "DisplayName": "Fallback After Exceptions", + "Category": "Stratum Performance:speed", + "Subcategory": "Region Ticking:speed:30", + "Description": "Automatic fallback: max exceptions a single entity type (Properties.Class) can throw within FallbackWindowSeconds before it gets runtime-blocked from parallel ticking. 0 = disabled (no automatic fallback). (data/stratum-performance.json -> $.RegionTicking.FallbackAfterExceptions)", + "Keywords": "regionticking,fallbackafterexceptions", + "FieldName": "Stratum_perf_RegionTicking_FallbackAfterExceptions", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.RegionTicking.FallbackAfterExceptions", + "IncludeInCommandLine": false, + "DefaultValue": "5", + "EnumValues": {} + }, + { + "DisplayName": "Fallback Window Seconds", + "Category": "Stratum Performance:speed", + "Subcategory": "Region Ticking:speed:30", + "Description": "Time window in seconds for counting exceptions per entity type. (data/stratum-performance.json -> $.RegionTicking.FallbackWindowSeconds)", + "Keywords": "regionticking,fallbackwindowseconds", + "FieldName": "Stratum_perf_RegionTicking_FallbackWindowSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.RegionTicking.FallbackWindowSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "60", + "EnumValues": {} + }, + { + "DisplayName": "Persist Fallback Until Restart", + "Category": "Stratum Performance:speed", + "Subcategory": "Region Ticking:speed:30", + "Description": "When true, the runtime-blocked set persists until server restart. When false (default), /stratum reload clears the blocked set. (data/stratum-performance.json -> $.RegionTicking.PersistFallbackUntilRestart)", + "Keywords": "regionticking,persistfallbackuntilrestart", + "FieldName": "Stratum_perf_RegionTicking_PersistFallbackUntilRestart", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.RegionTicking.PersistFallbackUntilRestart", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Body Temperature:speed:30", + "Description": "When enabled, vanilla bodytemperature accumulator thresholds are replaced with the values below + per-entity jitter (so 150 players don't all run the expensive RoomRegistry + climate sampling on the same tick). (data/stratum-performance.json -> $.BodyTemperature.Enabled)", + "Keywords": "bodytemperature,enabled", + "FieldName": "Stratum_perf_BodyTemperature_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.BodyTemperature.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Update Interval Seconds", + "Category": "Stratum Performance:speed", + "Subcategory": "Body Temperature:speed:30", + "Description": "How often per player to run the main ambient-temp/wetness update (vanilla = 2s). (data/stratum-performance.json -> $.BodyTemperature.UpdateIntervalSeconds)", + "Keywords": "bodytemperature,updateintervalseconds", + "FieldName": "Stratum_perf_BodyTemperature_UpdateIntervalSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BodyTemperature.UpdateIntervalSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Heat Source Interval Seconds", + "Category": "Stratum Performance:speed", + "Subcategory": "Body Temperature:speed:30", + "Description": "How often to recompute heat-source strength (the RoomRegistry flood-fill, vanilla = 5s). (data/stratum-performance.json -> $.BodyTemperature.HeatSourceIntervalSeconds)", + "Keywords": "bodytemperature,heatsourceintervalseconds", + "FieldName": "Stratum_perf_BodyTemperature_HeatSourceIntervalSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BodyTemperature.HeatSourceIntervalSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Freezing Anim Interval Seconds", + "Category": "Stratum Performance:speed", + "Subcategory": "Body Temperature:speed:30", + "Description": "How often to refresh the freezing visual state (vanilla = 1s). (data/stratum-performance.json -> $.BodyTemperature.FreezingAnimIntervalSeconds)", + "Keywords": "bodytemperature,freezinganimintervalseconds", + "FieldName": "Stratum_perf_BodyTemperature_FreezingAnimIntervalSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BodyTemperature.FreezingAnimIntervalSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Damage Check Interval Seconds", + "Category": "Stratum Performance:speed", + "Subcategory": "Body Temperature:speed:30", + "Description": "How often to do the frost-damage check (vanilla = 10s). (data/stratum-performance.json -> $.BodyTemperature.DamageCheckIntervalSeconds)", + "Keywords": "bodytemperature,damagecheckintervalseconds", + "FieldName": "Stratum_perf_BodyTemperature_DamageCheckIntervalSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BodyTemperature.DamageCheckIntervalSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Jitter Percent", + "Category": "Stratum Performance:speed", + "Subcategory": "Body Temperature:speed:30", + "Description": "Per-entity random jitter applied to each interval (0..1 = +/- this fraction). 0.25 means a 5s interval ends up between 3.75s and 6.25s per entity. (data/stratum-performance.json -> $.BodyTemperature.JitterPercent)", + "Keywords": "bodytemperature,jitterpercent", + "FieldName": "Stratum_perf_BodyTemperature_JitterPercent", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BodyTemperature.JitterPercent", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Event Tick:speed:30", + "Description": "data/stratum-performance.json -> $.EventTick.Enabled", + "Keywords": "eventtick,enabled", + "FieldName": "Stratum_perf_EventTick_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.EventTick.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Record Subsection Timings", + "Category": "Stratum Performance:speed", + "Subcategory": "Event Tick:speed:30", + "Description": "When true, records per-subsection timings for server.eventTick into PerformanceStats: eventTick.gtEntity, eventTick.gtBlock, eventTick.dcEntity, eventTick.dcBlock. (data/stratum-performance.json -> $.EventTick.RecordSubsectionTimings)", + "Keywords": "eventtick,recordsubsectiontimings", + "FieldName": "Stratum_perf_EventTick_RecordSubsectionTimings", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.EventTick.RecordSubsectionTimings", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Slow Block Listener Threshold Ms", + "Category": "Stratum Performance:speed", + "Subcategory": "Event Tick:speed:30", + "Description": "When a single block-listener tick exceeds this many milliseconds, record its profiler name for diagnosis. 0 disables. (data/stratum-performance.json -> $.EventTick.SlowBlockListenerThresholdMs)", + "Keywords": "eventtick,slowblocklistenerthresholdms", + "FieldName": "Stratum_perf_EventTick_SlowBlockListenerThresholdMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EventTick.SlowBlockListenerThresholdMs", + "IncludeInCommandLine": false, + "DefaultValue": "5", + "EnumValues": {} + }, + { + "DisplayName": "Slow Entity Listener Threshold Ms", + "Category": "Stratum Performance:speed", + "Subcategory": "Event Tick:speed:30", + "Description": "When a single entity-listener tick exceeds this many milliseconds, record its profiler name. 0 disables. Note: 'entity listeners' here = RegisterGameTickListener handlers (not entity OnGameTick). (data/stratum-performance.json -> $.EventTick.SlowEntityListenerThresholdMs)", + "Keywords": "eventtick,slowentitylistenerthresholdms", + "FieldName": "Stratum_perf_EventTick_SlowEntityListenerThresholdMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EventTick.SlowEntityListenerThresholdMs", + "IncludeInCommandLine": false, + "DefaultValue": "5", + "EnumValues": {} + }, + { + "DisplayName": "Adaptive Throttle When Overloaded", + "Category": "Stratum Performance:speed", + "Subcategory": "Event Tick:speed:30", + "Description": "Paper-style adaptive throttle: when the previous server tick exceeded the overloaded threshold, stretch the effective interval of non-critical entity listeners by this factor. 1 disables. Critical listeners (interval <= AdaptiveCriticalIntervalMs) are never throttled so packet, physics, and netcode listeners always fire on time. (data/stratum-performance.json -> $.EventTick.AdaptiveThrottleWhenOverloaded)", + "Keywords": "eventtick,adaptivethrottlewhenoverloaded", + "FieldName": "Stratum_perf_EventTick_AdaptiveThrottleWhenOverloaded", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.EventTick.AdaptiveThrottleWhenOverloaded", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Adaptive Overloaded Multiplier", + "Category": "Stratum Performance:speed", + "Subcategory": "Event Tick:speed:30", + "Description": "data/stratum-performance.json -> $.EventTick.AdaptiveOverloadedMultiplier", + "Keywords": "eventtick,adaptiveoverloadedmultiplier", + "FieldName": "Stratum_perf_EventTick_AdaptiveOverloadedMultiplier", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EventTick.AdaptiveOverloadedMultiplier", + "IncludeInCommandLine": false, + "DefaultValue": "2", + "EnumValues": {} + }, + { + "DisplayName": "Adaptive Critical Interval Ms", + "Category": "Stratum Performance:speed", + "Subcategory": "Event Tick:speed:30", + "Description": "Listeners whose configured interval is <= this many ms are exempt from adaptive throttling. (data/stratum-performance.json -> $.EventTick.AdaptiveCriticalIntervalMs)", + "Keywords": "eventtick,adaptivecriticalintervalms", + "FieldName": "Stratum_perf_EventTick_AdaptiveCriticalIntervalMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EventTick.AdaptiveCriticalIntervalMs", + "IncludeInCommandLine": false, + "DefaultValue": "50", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Collisions:speed:30", + "Description": "data/stratum-performance.json -> $.EntityCollisions.Enabled", + "Keywords": "entitycollisions,enabled", + "FieldName": "Stratum_perf_EntityCollisions_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityCollisions.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Max Collisions Per Entity", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Collisions:speed:30", + "Description": "0 disables the cap. Paper default is 8; we use 12 to be more permissive of pushing. (data/stratum-performance.json -> $.EntityCollisions.MaxCollisionsPerEntity)", + "Keywords": "entitycollisions,maxcollisionsperentity", + "FieldName": "Stratum_perf_EntityCollisions_MaxCollisionsPerEntity", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityCollisions.MaxCollisionsPerEntity", + "IncludeInCommandLine": false, + "DefaultValue": "12", + "EnumValues": {} + }, + { + "DisplayName": "Distance Gate Blocks", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Collisions:speed:30", + "Description": "Distance gate for RepulseAgents (non-player creatures skip entirely beyond this range). (data/stratum-performance.json -> $.EntityCollisions.DistanceGateBlocks)", + "Keywords": "entitycollisions,distancegateblocks", + "FieldName": "Stratum_perf_EntityCollisions_DistanceGateBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityCollisions.DistanceGateBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Near Band Blocks", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Collisions:speed:30", + "Description": "data/stratum-performance.json -> $.EntityCollisions.NearBandBlocks", + "Keywords": "entitycollisions,nearbandblocks", + "FieldName": "Stratum_perf_EntityCollisions_NearBandBlocks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityCollisions.NearBandBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Far Band Skip Ticks", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Collisions:speed:30", + "Description": "data/stratum-performance.json -> $.EntityCollisions.FarBandSkipTicks", + "Keywords": "entitycollisions,farbandskipticks", + "FieldName": "Stratum_perf_EntityCollisions_FarBandSkipTicks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityCollisions.FarBandSkipTicks", + "IncludeInCommandLine": false, + "DefaultValue": "4", + "EnumValues": {} + }, + { + "DisplayName": "Collect Stride Interval", + "Category": "Stratum Performance:speed", + "Subcategory": "Entity Collisions:speed:30", + "Description": "CollectEntities scan stride. Only run the spatial query every N ticks per entity, phase-offset by EntityId. Reduces allocations from GetEntitiesAround. 1 = every tick. (data/stratum-performance.json -> $.EntityCollisions.CollectStrideInterval)", + "Keywords": "entitycollisions,collectstrideinterval", + "FieldName": "Stratum_perf_EntityCollisions_CollectStrideInterval", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.EntityCollisions.CollectStrideInterval", + "IncludeInCommandLine": false, + "DefaultValue": "3", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Block Entity Init:speed:30", + "Description": "data/stratum-performance.json -> $.BlockEntityInit.Enabled", + "Keywords": "blockentityinit,enabled", + "FieldName": "Stratum_perf_BlockEntityInit_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockEntityInit.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Max Stagger Ms", + "Category": "Stratum Performance:speed", + "Subcategory": "Block Entity Init:speed:30", + "Description": "Max stagger window in ms. The actual offset for a given BE is (Pos.HashCode % min(MaxStaggerMs, millisecondInterval)). 0 disables. 250ms = up to ~7 ticks of stagger at 30Hz. (data/stratum-performance.json -> $.BlockEntityInit.MaxStaggerMs)", + "Keywords": "blockentityinit,maxstaggerms", + "FieldName": "Stratum_perf_BlockEntityInit_MaxStaggerMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.BlockEntityInit.MaxStaggerMs", + "IncludeInCommandLine": false, + "DefaultValue": "250", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Timer Resolution:speed:30", + "Description": "data/stratum-performance.json -> $.TimerResolution.Enabled", + "Keywords": "timerresolution,enabled", + "FieldName": "Stratum_perf_TimerResolution_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.TimerResolution.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Period Ms", + "Category": "Stratum Performance:speed", + "Subcategory": "Timer Resolution:speed:30", + "Description": "Requested timer period in ms. 1 = highest practical resolution. Range 1-15. (data/stratum-performance.json -> $.TimerResolution.PeriodMs)", + "Keywords": "timerresolution,periodms", + "FieldName": "Stratum_perf_TimerResolution_PeriodMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.TimerResolution.PeriodMs", + "IncludeInCommandLine": false, + "DefaultValue": "1", + "EnumValues": {} + }, + { + "DisplayName": "Cache Startup Packets", + "Category": "Stratum Performance:speed", + "Subcategory": "Join:speed:30", + "Description": "data/stratum-performance.json -> $.Join.CacheStartupPackets", + "Keywords": "join,cachestartuppackets", + "FieldName": "Stratum_perf_Join_CacheStartupPackets", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Join.CacheStartupPackets", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Max Queue Admissions Per Pass", + "Category": "Stratum Performance:speed", + "Subcategory": "Join:speed:30", + "Description": "Limits how many queued players are admitted in one queue pass. 0 = vanilla behavior. (data/stratum-performance.json -> $.Join.MaxQueueAdmissionsPerPass)", + "Keywords": "join,maxqueueadmissionsperpass", + "FieldName": "Stratum_perf_Join_MaxQueueAdmissionsPerPass", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Join.MaxQueueAdmissionsPerPass", + "IncludeInCommandLine": false, + "DefaultValue": "2", + "EnumValues": {} + }, + { + "DisplayName": "Max Joins Per Tick", + "Category": "Stratum Performance:speed", + "Subcategory": "Join:speed:30", + "Description": "Limits how many RequestJoin packets (Id 11) are processed per tick. Deferred joins drain on subsequent ticks. Keeps the main thread responsive during join storms. 0 = no limit (vanilla behavior). (data/stratum-performance.json -> $.Join.MaxJoinsPerTick)", + "Keywords": "join,maxjoinspertick", + "FieldName": "Stratum_perf_Join_MaxJoinsPerTick", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Join.MaxJoinsPerTick", + "IncludeInCommandLine": false, + "DefaultValue": "3", + "EnumValues": {} + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Adaptive Radius:speed:30", + "Description": "data/stratum-performance.json -> $.AdaptiveRadius.Enabled", + "Keywords": "adaptiveradius,enabled", + "FieldName": "Stratum_perf_AdaptiveRadius_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.AdaptiveRadius.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Smoothing Alpha", + "Category": "Stratum Performance:speed", + "Subcategory": "Adaptive Radius:speed:30", + "Description": "data/stratum-performance.json -> $.AdaptiveRadius.SmoothingAlpha", + "Keywords": "adaptiveradius,smoothingalpha", + "FieldName": "Stratum_perf_AdaptiveRadius_SmoothingAlpha", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.AdaptiveRadius.SmoothingAlpha", + "IncludeInCommandLine": false, + "DefaultValue": "0.15", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Decrease Mspt Threshold", + "Category": "Stratum Performance:speed", + "Subcategory": "Adaptive Radius:speed:30", + "Description": "data/stratum-performance.json -> $.AdaptiveRadius.DecreaseMsptThreshold", + "Keywords": "adaptiveradius,decreasemsptthreshold", + "FieldName": "Stratum_perf_AdaptiveRadius_DecreaseMsptThreshold", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.AdaptiveRadius.DecreaseMsptThreshold", + "IncludeInCommandLine": false, + "DefaultValue": "45.0", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Increase Mspt Threshold", + "Category": "Stratum Performance:speed", + "Subcategory": "Adaptive Radius:speed:30", + "Description": "data/stratum-performance.json -> $.AdaptiveRadius.IncreaseMsptThreshold", + "Keywords": "adaptiveradius,increasemsptthreshold", + "FieldName": "Stratum_perf_AdaptiveRadius_IncreaseMsptThreshold", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.AdaptiveRadius.IncreaseMsptThreshold", + "IncludeInCommandLine": false, + "DefaultValue": "35.0", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Overload Drop Threshold Ms", + "Category": "Stratum Performance:speed", + "Subcategory": "Adaptive Radius:speed:30", + "Description": "Instant radius drop when a single tick exceeds this value (ms). (data/stratum-performance.json -> $.AdaptiveRadius.OverloadDropThresholdMs)", + "Keywords": "adaptiveradius,overloaddropthresholdms", + "FieldName": "Stratum_perf_AdaptiveRadius_OverloadDropThresholdMs", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.AdaptiveRadius.OverloadDropThresholdMs", + "IncludeInCommandLine": false, + "DefaultValue": "500.0", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Floor Chunks", + "Category": "Stratum Performance:speed", + "Subcategory": "Adaptive Radius:speed:30", + "Description": "data/stratum-performance.json -> $.AdaptiveRadius.FloorChunks", + "Keywords": "adaptiveradius,floorchunks", + "FieldName": "Stratum_perf_AdaptiveRadius_FloorChunks", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.AdaptiveRadius.FloorChunks", + "IncludeInCommandLine": false, + "DefaultValue": "4", + "EnumValues": {} + }, + { + "DisplayName": "Adjustment Interval Seconds", + "Category": "Stratum Performance:speed", + "Subcategory": "Adaptive Radius:speed:30", + "Description": "data/stratum-performance.json -> $.AdaptiveRadius.AdjustmentIntervalSeconds", + "Keywords": "adaptiveradius,adjustmentintervalseconds", + "FieldName": "Stratum_perf_AdaptiveRadius_AdjustmentIntervalSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.AdaptiveRadius.AdjustmentIntervalSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": {}, + "Decimal": true + }, + { + "DisplayName": "Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Item Cleanup:speed:30", + "Description": "data/stratum-performance.json -> $.ItemCleanup.Enabled", + "Keywords": "itemcleanup,enabled", + "FieldName": "Stratum_perf_ItemCleanup_Enabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.ItemCleanup.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Interval Seconds", + "Category": "Stratum Performance:speed", + "Subcategory": "Item Cleanup:speed:30", + "Description": "data/stratum-performance.json -> $.ItemCleanup.IntervalSeconds", + "Keywords": "itemcleanup,intervalseconds", + "FieldName": "Stratum_perf_ItemCleanup_IntervalSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ItemCleanup.IntervalSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "60", + "EnumValues": {} + }, + { + "DisplayName": "Minimum Entity Age Seconds", + "Category": "Stratum Performance:speed", + "Subcategory": "Item Cleanup:speed:30", + "Description": "data/stratum-performance.json -> $.ItemCleanup.MinimumEntityAgeSeconds", + "Keywords": "itemcleanup,minimumentityageseconds", + "FieldName": "Stratum_perf_ItemCleanup_MinimumEntityAgeSeconds", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.ItemCleanup.MinimumEntityAgeSeconds", + "IncludeInCommandLine": false, + "DefaultValue": "10", + "EnumValues": {} + }, + { + "DisplayName": "Cleanup Warning Message", + "Category": "Stratum Performance:speed", + "Subcategory": "Item Cleanup:speed:30", + "Description": "data/stratum-performance.json -> $.ItemCleanup.CleanupWarningMessage", + "Keywords": "itemcleanup,cleanupwarningmessage", + "FieldName": "Stratum_perf_ItemCleanup_CleanupWarningMessage", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.ItemCleanup.CleanupWarningMessage", + "IncludeInCommandLine": false, + "DefaultValue": "Cleaning up dropped items in {0} seconds.", + "EnumValues": {} + }, + { + "DisplayName": "Cleanup Starting Message", + "Category": "Stratum Performance:speed", + "Subcategory": "Item Cleanup:speed:30", + "Description": "data/stratum-performance.json -> $.ItemCleanup.CleanupStartingMessage", + "Keywords": "itemcleanup,cleanupstartingmessage", + "FieldName": "Stratum_perf_ItemCleanup_CleanupStartingMessage", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.ItemCleanup.CleanupStartingMessage", + "IncludeInCommandLine": false, + "DefaultValue": "Cleaning up dropped items...", + "EnumValues": {} + }, + { + "DisplayName": "Cleanup Done Message", + "Category": "Stratum Performance:speed", + "Subcategory": "Item Cleanup:speed:30", + "Description": "data/stratum-performance.json -> $.ItemCleanup.CleanupDoneMessage", + "Keywords": "itemcleanup,cleanupdonemessage", + "FieldName": "Stratum_perf_ItemCleanup_CleanupDoneMessage", + "InputType": "text", + "IsFlagArgument": false, + "ParamFieldName": "$.ItemCleanup.CleanupDoneMessage", + "IncludeInCommandLine": false, + "DefaultValue": "Cleaned up {0} items.", + "EnumValues": {} + }, + { + "DisplayName": "Send Queue Enabled", + "Category": "Stratum Performance:speed", + "Subcategory": "Network:speed:30", + "Description": "Off by default. The queue removes the packet reordering bug from the old StratumNetworkFlush (disabled after client crashes, see PR #138), but it is new code on the hottest path in the server. Soak on a community server before flipping the shipped default. (data/stratum-performance.json -> $.Network.SendQueueEnabled)", + "Keywords": "network,sendqueueenabled", + "FieldName": "Stratum_perf_Network_SendQueueEnabled", + "InputType": "checkbox", + "IsFlagArgument": false, + "ParamFieldName": "$.Network.SendQueueEnabled", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Large Threshold Bytes", + "Category": "Stratum Performance:speed", + "Subcategory": "Network:speed:30", + "Description": "Packets at or above this size skip coalescing and go out alone. Matches the TCP MTU assumption the old flush buffer used. (data/stratum-performance.json -> $.Network.LargeThresholdBytes)", + "Keywords": "network,largethresholdbytes", + "FieldName": "Stratum_perf_Network_LargeThresholdBytes", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Network.LargeThresholdBytes", + "IncludeInCommandLine": false, + "DefaultValue": "1400", + "EnumValues": {} + }, + { + "DisplayName": "Coalesce Limit Bytes", + "Category": "Stratum Performance:speed", + "Subcategory": "Network:speed:30", + "Description": "Upper bound on one coalesced send. Caps the reusable drain buffer and how much data a single SendAsync call carries. (data/stratum-performance.json -> $.Network.CoalesceLimitBytes)", + "Keywords": "network,coalescelimitbytes", + "FieldName": "Stratum_perf_Network_CoalesceLimitBytes", + "InputType": "number", + "IsFlagArgument": false, + "ParamFieldName": "$.Network.CoalesceLimitBytes", + "IncludeInCommandLine": false, + "DefaultValue": "65536", + "EnumValues": {} + } +] diff --git a/vintage-story-stratummetaconfig.json b/vintage-story-stratummetaconfig.json new file mode 100644 index 000000000..be40a6ee2 --- /dev/null +++ b/vintage-story-stratummetaconfig.json @@ -0,0 +1,22 @@ +[ + { + "ConfigFile": "data/serverconfig.json", + "AutoMap": true, + "ConfigType": "json" + }, + { + "ConfigFile": "data/stratum.json", + "AutoMap": true, + "ConfigType": "json" + }, + { + "ConfigFile": "data/stratum-commands.json", + "AutoMap": true, + "ConfigType": "json" + }, + { + "ConfigFile": "data/stratum-performance.json", + "AutoMap": true, + "ConfigType": "json" + } +] diff --git a/vintage-story-stratumports.json b/vintage-story-stratumports.json new file mode 100644 index 000000000..a9f7d0f4b --- /dev/null +++ b/vintage-story-stratumports.json @@ -0,0 +1,9 @@ +[ + { + "Protocol": "Both", + "Name": "Server Port", + "Description": "Vintage Story game traffic. On a Nimbus network this is the port the PROXY dials, not the port players use - keep it unique per backend instance and do not expose it publicly.", + "Port": 42420, + "Ref": "ServerPort" + } +] diff --git a/vintage-story-stratumstart.json b/vintage-story-stratumstart.json new file mode 100644 index 000000000..cdd2859af --- /dev/null +++ b/vintage-story-stratumstart.json @@ -0,0 +1,22 @@ +[ + { + "UpdateStageName": "Render Nimbus backend config", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"NIMBUS_WRITE_CONFIG='{{NimbusWriteConfig}}' NIMBUS_ENABLED='{{NimbusEnabled}}' NIMBUS_SERVER_ID='{{NimbusServerId}}' NIMBUS_DISPLAY_NAME='{{NimbusDisplayName}}' NIMBUS_PUBLIC_HOST='{{NimbusPublicHost}}' NIMBUS_PUBLIC_PORT='{{NimbusPublicPort}}' NIMBUS_FALLBACK_PORT='{{$ServerPort}}' NIMBUS_TAGS='{{NimbusTags}}' NIMBUS_REGISTRY_URL='{{NimbusRegistryUrl}}' NIMBUS_SHARED_SECRET='{{NimbusSharedSecret}}' NIMBUS_HEARTBEAT='{{NimbusHeartbeatIntervalSeconds}}' NIMBUS_HTTP_TIMEOUT='{{NimbusRegistryHttpTimeoutSeconds}}' NIMBUS_MAINTENANCE='{{NimbusMaintenance}}' NIMBUS_RESERVATION_REQUIRED='{{NimbusReservationRequired}}' NIMBUS_FAIL_CLOSED='{{NimbusFailClosedWhenRegistryUnreachable}}' NIMBUS_ALLOW_SERVER_COMMAND='{{NimbusAllowPlayerServerCommand}}' NIMBUS_TRANSFER_MODE='{{NimbusTransferMode}}' NIMBUS_SEAMLESS_ACK='{{NimbusSeamlessPrepareAckTimeoutSeconds}}' NIMBUS_SHORTCUTS='{{NimbusShortcutCommands}}' bash '{{$FullRootDir}}scripts/write-nimbus-server.sh' '{{$FullRootDir}}data/ModConfig/nimbus-server.json'\"", + "UpdateSourceConditionSetting": "NimbusInstall", + "UpdateSourceConditionValue": "true", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Render Nimbus backend config", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$env:NIMBUS_WRITE_CONFIG='{{NimbusWriteConfig}}'; $env:NIMBUS_ENABLED='{{NimbusEnabled}}'; $env:NIMBUS_SERVER_ID='{{NimbusServerId}}'; $env:NIMBUS_DISPLAY_NAME='{{NimbusDisplayName}}'; $env:NIMBUS_PUBLIC_HOST='{{NimbusPublicHost}}'; $env:NIMBUS_PUBLIC_PORT='{{NimbusPublicPort}}'; $env:NIMBUS_FALLBACK_PORT='{{$ServerPort}}'; $env:NIMBUS_TAGS='{{NimbusTags}}'; $env:NIMBUS_REGISTRY_URL='{{NimbusRegistryUrl}}'; $env:NIMBUS_SHARED_SECRET='{{NimbusSharedSecret}}'; $env:NIMBUS_HEARTBEAT='{{NimbusHeartbeatIntervalSeconds}}'; $env:NIMBUS_HTTP_TIMEOUT='{{NimbusRegistryHttpTimeoutSeconds}}'; $env:NIMBUS_MAINTENANCE='{{NimbusMaintenance}}'; $env:NIMBUS_RESERVATION_REQUIRED='{{NimbusReservationRequired}}'; $env:NIMBUS_FAIL_CLOSED='{{NimbusFailClosedWhenRegistryUnreachable}}'; $env:NIMBUS_ALLOW_SERVER_COMMAND='{{NimbusAllowPlayerServerCommand}}'; $env:NIMBUS_TRANSFER_MODE='{{NimbusTransferMode}}'; $env:NIMBUS_SEAMLESS_ACK='{{NimbusSeamlessPrepareAckTimeoutSeconds}}'; $env:NIMBUS_SHORTCUTS='{{NimbusShortcutCommands}}'; & '{{$FullRootDir}}scripts\\write-nimbus-server.ps1' '{{$FullRootDir}}data\\ModConfig\\nimbus-server.json'\"", + "UpdateSourceConditionSetting": "NimbusInstall", + "UpdateSourceConditionValue": "true", + "SkipOnFailure": false + } +] diff --git a/vintage-story-stratumupdates.json b/vintage-story-stratumupdates.json new file mode 100644 index 000000000..922bc1592 --- /dev/null +++ b/vintage-story-stratumupdates.json @@ -0,0 +1,213 @@ +[ + { + "UpdateStageName": "Create server directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}server", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create dotnet directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}dotnet", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create data directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}data", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create Mods directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}data/Mods", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create ModConfig directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}data/ModConfig", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create scripts directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}scripts", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Write Stratum installer script (Linux)", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/install-stratum.sh", + "UpdateSourceData": "#!/usr/bin/env bash\n# Generated by the AMP \"Vintage Story (Stratum + Nimbus)\" template.\n# Resolves and installs a Stratum release. The release tag pins the Vintage Story\n# version (tags look like v1.22.6-stratum.2); Stratum then downloads the matching\n# vanilla server assets itself on the next start or during the prepare stage.\nset -euo pipefail\n\nroot=\"${1:?root directory required}\"\ncd \"$root\"\nmkdir -p server\n\nrepo=\"StratumServer/Stratum\"\nrid=\"linux-x64\"\nhdr=(-H \"User-Agent: AMP-Stratum-Template\" -H \"Accept: application/vnd.github+json\")\nif [ -n \"${GITHUB_TOKEN:-}\" ]; then hdr+=(-H \"Authorization: Bearer ${GITHUB_TOKEN}\"); fi\n\nfor tool in curl unzip jq; do\n command -v \"$tool\" >/dev/null 2>&1 || { echo \"[AMP] $tool is required but not installed\" >&2; exit 1; }\ndone\n\ntag=\"$(printf '%s' \"${STRATUM_TAG:-}\" | tr -d '[:space:]')\"\nif [ -z \"$tag\" ]; then\n echo \"[AMP] resolving Stratum release (channel=${STRATUM_CHANNEL:-stable} gameVersion=${STRATUM_GAMEVER:-latest})\"\n json=\"$(curl -fsSL \"${hdr[@]}\" \"https://api.github.com/repos/${repo}/releases?per_page=100\")\"\n filter='.[] | select(.draft == false)'\n if [ \"${STRATUM_CHANNEL:-stable}\" != \"prerelease\" ]; then\n filter=\"${filter} | select(.prerelease == false)\"\n fi\n if [ -n \"${STRATUM_GAMEVER:-}\" ]; then\n filter=\"${filter} | select(.tag_name | startswith(\\\"v${STRATUM_GAMEVER}-stratum.\\\"))\"\n fi\n tag=\"$(printf '%s' \"$json\" | jq -r \"[ ${filter} ] | .[0].tag_name // empty\")\"\nfi\n\nif [ -z \"$tag\" ]; then\n echo \"[AMP] no Stratum release matched channel=${STRATUM_CHANNEL:-stable} gameVersion=${STRATUM_GAMEVER:-}\" >&2\n exit 1\nfi\n\nversion=\"${tag#v}\"\ngamever=\"${version%%-stratum.*}\"\nasset=\"stratum-${version}-${rid}.zip\"\nmarker=\"server/.amp-stratum-release\"\n\necho \"[AMP] Stratum ${version} selected (Vintage Story ${gamever})\"\n\nif [ -f \"$marker\" ] && [ \"$(cat \"$marker\")\" = \"$tag\" ] && [ -x server/StratumServer ]; then\n echo \"[AMP] already on ${tag}; nothing to download\"\n exit 0\nfi\n\nurl=\"https://github.com/${repo}/releases/download/${tag}/${asset}\"\necho \"[AMP] downloading ${url}\"\ncurl -fL --retry 3 -o stratum-release.zip \"$url\"\nunzip -qo stratum-release.zip -d server\nrm -f stratum-release.zip\nchmod +x server/StratumServer\nprintf '%s' \"$tag\" > \"$marker\"\nprintf '%s' \"$gamever\" > server/.amp-stratum-gameversion\necho \"[AMP] installed Stratum ${tag} into ${root}server\"\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Write Stratum installer script (Windows)", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/install-stratum.ps1", + "UpdateSourceData": "# Generated by the AMP \"Vintage Story (Stratum + Nimbus)\" template.\nparam([Parameter(Mandatory = $true)][string]$Root)\n\n$ErrorActionPreference = 'Stop'\n$ProgressPreference = 'SilentlyContinue'\n[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n\n$repo = 'StratumServer/Stratum'\n$rid = 'win-x64'\n$serverDir = Join-Path $Root 'server'\nNew-Item -ItemType Directory -Force -Path $serverDir | Out-Null\n\n$headers = @{ 'User-Agent' = 'AMP-Stratum-Template'; 'Accept' = 'application/vnd.github+json' }\nif ($env:GITHUB_TOKEN) { $headers['Authorization'] = \"Bearer $($env:GITHUB_TOKEN)\" }\n\nif ($env:STRATUM_TAG) { $tag = $env:STRATUM_TAG.Trim() } else { $tag = '' }\n\nif ($tag -eq '') {\n $channel = if ($env:STRATUM_CHANNEL) { $env:STRATUM_CHANNEL } else { 'stable' }\n $gameVer = if ($env:STRATUM_GAMEVER) { $env:STRATUM_GAMEVER.Trim() } else { '' }\n Write-Host \"[AMP] resolving Stratum release (channel=$channel gameVersion=$(if ($gameVer) { $gameVer } else { 'latest' }))\"\n $releases = Invoke-RestMethod -Headers $headers -Uri \"https://api.github.com/repos/$repo/releases?per_page=100\"\n $candidates = @($releases | Where-Object { -not $_.draft })\n if ($channel -ne 'prerelease') { $candidates = @($candidates | Where-Object { -not $_.prerelease }) }\n if ($gameVer -ne '') { $candidates = @($candidates | Where-Object { $_.tag_name.StartsWith(\"v$gameVer-stratum.\") }) }\n if ($candidates.Count -eq 0) { throw \"No Stratum release matched channel=$channel gameVersion=$gameVer\" }\n $tag = $candidates[0].tag_name\n}\n\n$version = $tag.TrimStart('v')\n$gamever = ($version -split '-stratum\\.')[0]\n$asset = \"stratum-$version-$rid.zip\"\n$marker = Join-Path $serverDir '.amp-stratum-release'\n\nWrite-Host \"[AMP] Stratum $version selected (Vintage Story $gamever)\"\n\nif ((Test-Path $marker) -and ((Get-Content $marker -Raw).Trim() -eq $tag) -and (Test-Path (Join-Path $serverDir 'StratumServer.exe'))) {\n Write-Host \"[AMP] already on $tag; nothing to download\"\n exit 0\n}\n\n$zip = Join-Path $Root 'stratum-release.zip'\n$url = \"https://github.com/$repo/releases/download/$tag/$asset\"\nWrite-Host \"[AMP] downloading $url\"\nInvoke-WebRequest -UseBasicParsing -Uri $url -OutFile $zip\nExpand-Archive -Path $zip -DestinationPath $serverDir -Force\nRemove-Item $zip -Force\nSet-Content -Path $marker -Value $tag -NoNewline\nSet-Content -Path (Join-Path $serverDir '.amp-stratum-gameversion') -Value $gamever -NoNewline\nWrite-Host \"[AMP] installed Stratum $tag into $serverDir\"\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Write Nimbus mod installer script (Linux)", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/install-nimbus-mod.sh", + "UpdateSourceData": "#!/usr/bin/env bash\n# Generated by the AMP \"Vintage Story (Stratum + Nimbus)\" template.\n# Installs Nimbus.ServerMod into data/Mods so this backend can join a Nimbus network.\nset -euo pipefail\n\nroot=\"${1:?root directory required}\"\ncd \"$root\"\n\nistrue() { [ \"$(printf '%s' \"${1:-}\" | tr '[:upper:]' '[:lower:]')\" = \"true\" ]; }\nif ! istrue \"${NIMBUS_INSTALL:-true}\"; then\n echo \"[AMP] Nimbus server mod installation is disabled\"\n exit 0\nfi\n\nrepo=\"StratumServer/Nimbus\"\nhdr=(-H \"User-Agent: AMP-Stratum-Template\" -H \"Accept: application/vnd.github+json\")\nif [ -n \"${GITHUB_TOKEN:-}\" ]; then hdr+=(-H \"Authorization: Bearer ${GITHUB_TOKEN}\"); fi\n\nfor tool in curl unzip jq; do\n command -v \"$tool\" >/dev/null 2>&1 || { echo \"[AMP] $tool is required but not installed\" >&2; exit 1; }\ndone\n\ntag=\"$(printf '%s' \"${NIMBUS_MOD_VERSION:-}\" | tr -d '[:space:]')\"\nif [ -z \"$tag\" ]; then\n json=\"$(curl -fsSL \"${hdr[@]}\" \"https://api.github.com/repos/${repo}/releases?per_page=100\")\"\n filter='.[] | select(.draft == false)'\n if [ \"${NIMBUS_CHANNEL:-stable}\" != \"prerelease\" ]; then\n filter=\"${filter} | select(.prerelease == false)\"\n fi\n tag=\"$(printf '%s' \"$json\" | jq -r \"[ ${filter} ] | .[0].tag_name // empty\")\"\nfi\n[ -n \"$tag\" ] || { echo \"[AMP] no Nimbus release found\" >&2; exit 1; }\ncase \"$tag\" in v*) ;; *) tag=\"v${tag}\";; esac\n\nmkdir -p data/Mods data/ModConfig\nmarker=\"data/Mods/Nimbus.ServerMod/.amp-nimbus-release\"\nif [ -f \"$marker\" ] && [ \"$(cat \"$marker\")\" = \"$tag\" ]; then\n echo \"[AMP] Nimbus server mod already on ${tag}\"\n exit 0\nfi\n\nurl=\"https://github.com/${repo}/releases/download/${tag}/Nimbus.ServerMod-${tag}.zip\"\necho \"[AMP] downloading ${url}\"\ncurl -fL --retry 3 -o nimbus-mod.zip \"$url\"\nrm -rf data/Mods/Nimbus.ServerMod\nmkdir -p data/Mods/Nimbus.ServerMod\nunzip -qo nimbus-mod.zip -d data/Mods/Nimbus.ServerMod\nrm -f nimbus-mod.zip\nprintf '%s' \"$tag\" > \"$marker\"\necho \"[AMP] installed Nimbus server mod ${tag} into ${root}data/Mods/Nimbus.ServerMod\"\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Write Nimbus mod installer script (Windows)", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/install-nimbus-mod.ps1", + "UpdateSourceData": "# Generated by the AMP \"Vintage Story (Stratum + Nimbus)\" template.\nparam([Parameter(Mandatory = $true)][string]$Root)\n\n$ErrorActionPreference = 'Stop'\n$ProgressPreference = 'SilentlyContinue'\n[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n\nif ($env:NIMBUS_INSTALL -and $env:NIMBUS_INSTALL.Trim().ToLowerInvariant() -ne 'true') {\n Write-Host '[AMP] Nimbus server mod installation is disabled'\n exit 0\n}\n\n$repo = 'StratumServer/Nimbus'\n$headers = @{ 'User-Agent' = 'AMP-Stratum-Template'; 'Accept' = 'application/vnd.github+json' }\nif ($env:GITHUB_TOKEN) { $headers['Authorization'] = \"Bearer $($env:GITHUB_TOKEN)\" }\n\n$tag = if ($env:NIMBUS_MOD_VERSION) { $env:NIMBUS_MOD_VERSION.Trim() } else { '' }\nif ($tag -eq '') {\n $channel = if ($env:NIMBUS_CHANNEL) { $env:NIMBUS_CHANNEL } else { 'stable' }\n $releases = Invoke-RestMethod -Headers $headers -Uri \"https://api.github.com/repos/$repo/releases?per_page=100\"\n $candidates = @($releases | Where-Object { -not $_.draft })\n if ($channel -ne 'prerelease') { $candidates = @($candidates | Where-Object { -not $_.prerelease }) }\n if ($candidates.Count -eq 0) { throw 'No Nimbus release found' }\n $tag = $candidates[0].tag_name\n}\nif (-not $tag.StartsWith('v')) { $tag = \"v$tag\" }\n\n$modDir = Join-Path $Root 'data\\Mods\\Nimbus.ServerMod'\nNew-Item -ItemType Directory -Force -Path (Join-Path $Root 'data\\ModConfig') | Out-Null\n$marker = Join-Path $modDir '.amp-nimbus-release'\nif ((Test-Path $marker) -and ((Get-Content $marker -Raw).Trim() -eq $tag)) {\n Write-Host \"[AMP] Nimbus server mod already on $tag\"\n exit 0\n}\n\n$zip = Join-Path $Root 'nimbus-mod.zip'\n$url = \"https://github.com/$repo/releases/download/$tag/Nimbus.ServerMod-$tag.zip\"\nWrite-Host \"[AMP] downloading $url\"\nInvoke-WebRequest -UseBasicParsing -Uri $url -OutFile $zip\nif (Test-Path $modDir) { Remove-Item $modDir -Recurse -Force }\nNew-Item -ItemType Directory -Force -Path $modDir | Out-Null\nExpand-Archive -Path $zip -DestinationPath $modDir -Force\nRemove-Item $zip -Force\nSet-Content -Path $marker -Value $tag -NoNewline\nWrite-Host \"[AMP] installed Nimbus server mod $tag into $modDir\"\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Write Nimbus backend config script (Linux)", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/write-nimbus-server.sh", + "UpdateSourceData": "#!/usr/bin/env bash\n# Generated by the AMP \"Vintage Story (Stratum + Nimbus)\" template.\n# Renders data/ModConfig/nimbus-server.json from the instance settings before every start.\n# Do not edit: it is overwritten on every update. Set \"Let AMP Manage nimbus-server.json\"\n# to false if you would rather hand-edit the JSON.\nset -euo pipefail\n\ntarget=\"${1:?target path required}\"\nmkdir -p \"$(dirname \"$target\")\"\n\nistrue() { [ \"$(printf '%s' \"${1:-}\" | tr '[:upper:]' '[:lower:]')\" = \"true\" ]; }\n\nif ! istrue \"${NIMBUS_WRITE_CONFIG:-true}\"; then\n echo \"[AMP] Nimbus config management is off; leaving $target as it is\"\n exit 0\nfi\n\nif ! command -v jq >/dev/null 2>&1; then\n echo \"[AMP] jq is required to render $target but was not found on this system\" >&2\n exit 1\nfi\n\nport=\"${NIMBUS_PUBLIC_PORT:-0}\"\ncase \"$port\" in ''|0|*[!0-9]*) port=\"${NIMBUS_FALLBACK_PORT:-42420}\";; esac\nhost=\"${NIMBUS_PUBLIC_HOST:-}\"\n[ -n \"$host\" ] || host=\"127.0.0.1\"\n\nbool() { if istrue \"${1:-}\"; then printf 'true'; else printf 'false'; fi; }\n\njq -n \\\n --arg enabled \"$(bool \"${NIMBUS_ENABLED:-true}\")\" \\\n --arg id \"${NIMBUS_SERVER_ID:-}\" \\\n --arg dname \"${NIMBUS_DISPLAY_NAME:-}\" \\\n --arg host \"$host\" \\\n --arg port \"$port\" \\\n --arg tags \"${NIMBUS_TAGS:-}\" \\\n --arg regurl \"${NIMBUS_REGISTRY_URL:-}\" \\\n --arg secret \"${NIMBUS_SHARED_SECRET:-}\" \\\n --arg hb \"${NIMBUS_HEARTBEAT:-5}\" \\\n --arg httpto \"${NIMBUS_HTTP_TIMEOUT:-5}\" \\\n --arg maint \"$(bool \"${NIMBUS_MAINTENANCE:-false}\")\" \\\n --arg resv \"$(bool \"${NIMBUS_RESERVATION_REQUIRED:-true}\")\" \\\n --arg failclosed \"$(bool \"${NIMBUS_FAIL_CLOSED:-false}\")\" \\\n --arg allowcmd \"$(bool \"${NIMBUS_ALLOW_SERVER_COMMAND:-true}\")\" \\\n --arg tmode \"${NIMBUS_TRANSFER_MODE:-redirect}\" \\\n --arg sack \"${NIMBUS_SEAMLESS_ACK:-8}\" \\\n --arg shortcuts \"${NIMBUS_SHORTCUTS:-}\" \\\n '{\n Enabled: ($enabled == \"true\"),\n ServerId: $id,\n DisplayName: $dname,\n PublicHost: $host,\n PublicPort: ($port | tonumber),\n Tags: ($tags | split(\",\") | map(gsub(\"^\\\\s+|\\\\s+$\"; \"\")) | map(select(length > 0))),\n RegistryUrl: $regurl,\n SharedSecret: $secret,\n HeartbeatIntervalSeconds: ($hb | tonumber),\n RegistryHttpTimeoutSeconds: ($httpto | tonumber),\n Maintenance: ($maint == \"true\"),\n ReservationRequired: ($resv == \"true\"),\n FailClosedWhenRegistryUnreachable: ($failclosed == \"true\"),\n AllowPlayerServerCommand: ($allowcmd == \"true\"),\n TransferMode: $tmode,\n SeamlessPrepareAckTimeoutSeconds: ($sack | tonumber),\n ShortcutCommands: ($shortcuts | split(\";\") | map(select(length > 0)) | map(\n (split(\"@\")) as $parts |\n (($parts[0]) | split(\"=\")) as $kv |\n {\n Name: ($kv[0] | gsub(\"^\\\\s+|\\\\s+$\"; \"\") | ltrimstr(\"/\")),\n Targets: ((($kv[1]) // \"\") | split(\"|\") | map(gsub(\"^\\\\s+|\\\\s+$\"; \"\")) | map(select(length > 0))),\n Privilege: ((($parts[1]) // \"chat\") | gsub(\"^\\\\s+|\\\\s+$\"; \"\")),\n Description: \"\"\n }) | map(select((.Name | length) > 0 and (.Targets | length) > 0)))\n }' > \"$target.amptmp\"\n\nmv \"$target.amptmp\" \"$target\"\necho \"[AMP] wrote $target serverId=${NIMBUS_SERVER_ID:-} advertised=${host}:${port} registry=${NIMBUS_REGISTRY_URL:-} transferMode=${NIMBUS_TRANSFER_MODE:-redirect}\"\nif [ -z \"${NIMBUS_SHARED_SECRET:-}\" ]; then\n echo \"[AMP] WARNING: no registry shared secret is set, so heartbeats will be rejected. Copy the secret from the proxy or registry into this instance's Nimbus settings.\"\nfi\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Write Nimbus backend config script (Windows)", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/write-nimbus-server.ps1", + "UpdateSourceData": "# Generated by the AMP \"Vintage Story (Stratum + Nimbus)\" template.\n# Renders data\\ModConfig\\nimbus-server.json from the instance settings before every start.\nparam([Parameter(Mandatory = $true)][string]$Target)\n\n$ErrorActionPreference = 'Stop'\n\nfunction Get-Env([string]$name, [string]$fallback = '') {\n $v = [Environment]::GetEnvironmentVariable($name)\n if ([string]::IsNullOrWhiteSpace($v)) { return $fallback }\n return $v\n}\nfunction Get-Bool([string]$name, [bool]$fallback) {\n $v = Get-Env $name ''\n if ($v -eq '') { return $fallback }\n return ($v.Trim().ToLowerInvariant() -eq 'true')\n}\nfunction Split-List([string]$value, [string]$sep) {\n if ([string]::IsNullOrWhiteSpace($value)) { return @() }\n return @($value.Split($sep) | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne '' })\n}\n\nif (-not (Get-Bool 'NIMBUS_WRITE_CONFIG' $true)) {\n Write-Host \"[AMP] Nimbus config management is off; leaving $Target as it is\"\n exit 0\n}\n\n$dir = Split-Path -Parent $Target\nif ($dir -and -not (Test-Path $dir)) { New-Item -ItemType Directory -Force -Path $dir | Out-Null }\n\n$port = 0\n[void][int]::TryParse((Get-Env 'NIMBUS_PUBLIC_PORT' '0'), [ref]$port)\nif ($port -le 0) { [void][int]::TryParse((Get-Env 'NIMBUS_FALLBACK_PORT' '42420'), [ref]$port) }\nif ($port -le 0) { $port = 42420 }\n\n$host_ = Get-Env 'NIMBUS_PUBLIC_HOST' '127.0.0.1'\n\n$shortcuts = @()\nforeach ($raw in (Split-List (Get-Env 'NIMBUS_SHORTCUTS' '') ';')) {\n $privilege = 'chat'\n $body = $raw\n $at = $raw.LastIndexOf('@')\n if ($at -ge 0) {\n $body = $raw.Substring(0, $at)\n $privilege = $raw.Substring($at + 1).Trim()\n if ($privilege -eq '') { $privilege = 'chat' }\n }\n $kv = $body.Split('=', 2)\n $name = $kv[0].Trim().TrimStart('/')\n $targets = @()\n if ($kv.Length -gt 1) { $targets = Split-List $kv[1] '|' }\n if ($name -ne '' -and $targets.Count -gt 0) {\n $shortcuts += [ordered]@{ Name = $name; Targets = $targets; Privilege = $privilege; Description = '' }\n }\n}\n\n# Windows PowerShell 5.1 turns single element arrays into scalars when it converts to\n# JSON, which would produce \"Targets\": \"hub\" instead of a list, so the JSON is written by\n# hand here. Keep it that way.\nfunction Esc([string]$s) {\n if ($null -eq $s) { return '\"\"' }\n $s = $s.Replace('\\', '\\\\').Replace('\"', '\\\"').Replace(\"`r\", '\\r').Replace(\"`n\", '\\n').Replace(\"`t\", '\\t')\n return '\"' + $s + '\"'\n}\nfunction JList($items) {\n if (-not $items -or @($items).Count -eq 0) { return '[]' }\n return '[' + ((@($items) | ForEach-Object { Esc $_ }) -join ', ') + ']'\n}\nfunction JBool([bool]$b) { if ($b) { return 'true' } else { return 'false' } }\n\n$serverId = Get-Env 'NIMBUS_SERVER_ID' ''\n$registryUrl = Get-Env 'NIMBUS_REGISTRY_URL' ''\n$transferMode = Get-Env 'NIMBUS_TRANSFER_MODE' 'redirect'\n$secret = Get-Env 'NIMBUS_SHARED_SECRET' ''\n\n$sc = @()\nforeach ($s in $shortcuts) {\n $sc += @\"\n {\n \"Name\": $(Esc $s.Name),\n \"Targets\": $(JList $s.Targets),\n \"Privilege\": $(Esc $s.Privilege),\n \"Description\": \"\"\n }\n\"@\n}\n\n$json = @\"\n{\n \"Enabled\": $(JBool (Get-Bool 'NIMBUS_ENABLED' $true)),\n \"ServerId\": $(Esc $serverId),\n \"DisplayName\": $(Esc (Get-Env 'NIMBUS_DISPLAY_NAME' '')),\n \"PublicHost\": $(Esc $host_),\n \"PublicPort\": $port,\n \"Tags\": $(JList (Split-List (Get-Env 'NIMBUS_TAGS' '') ',')),\n \"RegistryUrl\": $(Esc $registryUrl),\n \"SharedSecret\": $(Esc $secret),\n \"HeartbeatIntervalSeconds\": $([int](Get-Env 'NIMBUS_HEARTBEAT' '5')),\n \"RegistryHttpTimeoutSeconds\": $([int](Get-Env 'NIMBUS_HTTP_TIMEOUT' '5')),\n \"Maintenance\": $(JBool (Get-Bool 'NIMBUS_MAINTENANCE' $false)),\n \"ReservationRequired\": $(JBool (Get-Bool 'NIMBUS_RESERVATION_REQUIRED' $true)),\n \"FailClosedWhenRegistryUnreachable\": $(JBool (Get-Bool 'NIMBUS_FAIL_CLOSED' $false)),\n \"AllowPlayerServerCommand\": $(JBool (Get-Bool 'NIMBUS_ALLOW_SERVER_COMMAND' $true)),\n \"TransferMode\": $(Esc $transferMode),\n \"SeamlessPrepareAckTimeoutSeconds\": $([int](Get-Env 'NIMBUS_SEAMLESS_ACK' '8')),\n \"ShortcutCommands\": [\n$($sc -join \",`r`n\")\n ]\n}\n\"@\n\n[IO.File]::WriteAllText($Target, $json, (New-Object Text.UTF8Encoding($false)))\nWrite-Host (\"[AMP] wrote {0} serverId={1} advertised={2}:{3} registry={4} transferMode={5}\" -f $Target, $serverId, $host_, $port, $registryUrl, $transferMode)\nif ([string]::IsNullOrWhiteSpace($secret)) {\n Write-Host \"[AMP] WARNING: no registry shared secret is set, so heartbeats will be rejected. Copy the secret from the proxy or registry into this instance's Nimbus settings.\"\n}\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": ".NET SDK Download", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "Executable", + "UpdateSourceArch": "x86_64", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"DotnetVersion=\\\"{{DotnetSDKVersion}}\\\"; cd \\\"{{$FullBaseDir}}\\\" && if [[ -x dotnet/dotnet ]]; then InstalledVersion=$(dotnet/dotnet --version | xargs); else InstalledVersion=\\\"\\\"; fi; if [[ -z \\\"$DotnetVersion\\\" ]]; then DotnetVersion=$(wget -qO- https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json | jq -r \\\".[\\\\\\\"latest-sdk\\\\\\\"]\\\"); fi; if [[ ! \\\"$DotnetVersion\\\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+$ ]]; then echo \\\"Invalid .NET SDK version format specified\\\" && exit 1; elif [[ \\\"$InstalledVersion\\\" == \\\"$DotnetVersion\\\" ]]; then echo \\\".NET SDK v$DotnetVersion already installed. Skipping\\\" && exit 0; else [[ -f dotnet.tar.gz ]] && rm -f dotnet.tar.gz >/dev/null 2>&1; wget -qO dotnet.tar.gz https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-linux-x64.tar.gz || { echo \\\"Download failed from the Microsoft CDN. This is a fault with the CDN, not AMP. Aborting\\\"; exit 1; }; rm -rf dotnet/* >/dev/null 2>&1 && tar -xzf dotnet.tar.gz -C dotnet >/dev/null 2>&1 && rm -f dotnet.tar.gz >/dev/null 2>&1 && echo \\\".NET SDK v$DotnetVersion downloaded\\\"; fi\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": ".NET SDK Download", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -Command \"$ProgressPreference='SilentlyContinue'; [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $DotnetVersion='{{DotnetSDKVersion}}'; Set-Location -Path '{{$FullBaseDir}}'; if (Test-Path 'dotnet/dotnet.exe') { $InstalledVersion = (& dotnet/dotnet.exe --version).Trim() } else { $InstalledVersion = '' }; if ( [string]::IsNullOrWhiteSpace($DotnetVersion) ) { $DotnetVersion=(Invoke-RestMethod -UseBasicParsing -Uri https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json).\\\"latest-sdk\\\" }; if ($DotnetVersion -notmatch '^\\d+\\.\\d+\\.\\d+$') { Write-Output \\\"Invalid .NET SDK version format specified\\\"; exit 1 } elseif ( $InstalledVersion -eq $DotnetVersion ) { Write-Output \\\".NET SDK v$DotnetVersion already installed. Skipping\\\"; exit 0 } else { if ( Test-Path dotnet.zip ) { Remove-Item dotnet.zip -Force -ErrorAction SilentlyContinue *> $null }; try { Invoke-WebRequest -UseBasicParsing -Uri https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-win-x64.zip -OutFile dotnet.zip -ErrorAction Stop } catch { Write-Output \\\"Download failed from the Microsoft CDN. This is a fault with the CDN, not AMP. Aborting\\\"; exit 1; }; Remove-Item -Path 'dotnet/*' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive -Path \\\"dotnet.zip\\\" -DestinationPath \\\"dotnet\\\" -Force *> $null; if ( Test-Path dotnet.zip ) { Remove-Item dotnet.zip -Force -ErrorAction SilentlyContinue *> $null }; Write-Output \\\".NET SDK v$DotnetVersion downloaded\\\" }\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Stratum Server Download", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "Executable", + "UpdateSourceArch": "x86_64", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"STRATUM_TAG='{{StratumVersionTag}}' STRATUM_CHANNEL='{{StratumReleaseChannel}}' STRATUM_GAMEVER='{{StratumGameVersion}}' GITHUB_TOKEN='{{StratumGitHubToken}}' bash '{{$FullRootDir}}scripts/install-stratum.sh' '{{$FullRootDir}}'\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Stratum Server Download", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$env:STRATUM_TAG='{{StratumVersionTag}}'; $env:STRATUM_CHANNEL='{{StratumReleaseChannel}}'; $env:STRATUM_GAMEVER='{{StratumGameVersion}}'; $env:GITHUB_TOKEN='{{StratumGitHubToken}}'; & '{{$FullRootDir}}scripts\\install-stratum.ps1' '{{$FullRootDir}}'\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Bootstrap Vintage Story Assets", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "Executable", + "UpdateSourceArch": "x86_64", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"export DOTNET_ROOT='{{$FullRootDir}}dotnet'; cd '{{$FullRootDir}}server' && ./StratumServer --stratum-prepare-only --stratum-no-banner --dataPath '{{$FullRootDir}}data'\"", + "UpdateSourceConditionSetting": "StratumRefreshVanilla", + "UpdateSourceConditionValue": "false", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Bootstrap Vintage Story Assets (forced refresh)", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "Executable", + "UpdateSourceArch": "x86_64", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"export DOTNET_ROOT='{{$FullRootDir}}dotnet'; cd '{{$FullRootDir}}server' && ./StratumServer --stratum-prepare-only --stratum-refresh --stratum-no-banner --dataPath '{{$FullRootDir}}data'\"", + "UpdateSourceConditionSetting": "StratumRefreshVanilla", + "UpdateSourceConditionValue": "true", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Bootstrap Vintage Story Assets", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -Command \"$env:DOTNET_ROOT='{{$FullRootDir}}dotnet'; Set-Location '{{$FullRootDir}}server'; & '.\\StratumServer.exe' --stratum-prepare-only --stratum-no-banner --dataPath '{{$FullRootDir}}data'\"", + "UpdateSourceConditionSetting": "StratumRefreshVanilla", + "UpdateSourceConditionValue": "false", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Bootstrap Vintage Story Assets (forced refresh)", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -Command \"$env:DOTNET_ROOT='{{$FullRootDir}}dotnet'; Set-Location '{{$FullRootDir}}server'; & '.\\StratumServer.exe' --stratum-prepare-only --stratum-refresh --stratum-no-banner --dataPath '{{$FullRootDir}}data'\"", + "UpdateSourceConditionSetting": "StratumRefreshVanilla", + "UpdateSourceConditionValue": "true", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Nimbus Server Mod Download", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "Executable", + "UpdateSourceArch": "x86_64", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"NIMBUS_INSTALL='{{NimbusInstall}}' NIMBUS_MOD_VERSION='{{NimbusModVersion}}' NIMBUS_CHANNEL='{{NimbusReleaseChannel}}' GITHUB_TOKEN='{{StratumGitHubToken}}' bash '{{$FullRootDir}}scripts/install-nimbus-mod.sh' '{{$FullRootDir}}'\"", + "UpdateSourceConditionSetting": "NimbusInstall", + "UpdateSourceConditionValue": "true", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Nimbus Server Mod Download", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$env:NIMBUS_INSTALL='{{NimbusInstall}}'; $env:NIMBUS_MOD_VERSION='{{NimbusModVersion}}'; $env:NIMBUS_CHANNEL='{{NimbusReleaseChannel}}'; $env:GITHUB_TOKEN='{{StratumGitHubToken}}'; & '{{$FullRootDir}}scripts\\install-nimbus-mod.ps1' '{{$FullRootDir}}'\"", + "UpdateSourceConditionSetting": "NimbusInstall", + "UpdateSourceConditionValue": "true", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Start Server", + "UpdateSourcePlatform": "All", + "UpdateSource": "StartApplication", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Wait For Server Start", + "UpdateSourcePlatform": "All", + "UpdateSource": "WaitForStartupComplete", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Stop Server", + "UpdateSourcePlatform": "All", + "UpdateSource": "ShutdownApplication", + "SkipOnFailure": false + } +] From c9e6aab3dca3ac7575810b32400fa9be5639e690 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Fri, 7 Aug 2026 19:15:10 -0500 Subject: [PATCH 16/50] Add files via upload --- vintage-story-stratumconfig.json | 14 ------------- vintage-story-stratumstart.json | 16 +++++++++++++++ vintage-story-stratumupdates.json | 34 +++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 14 deletions(-) diff --git a/vintage-story-stratumconfig.json b/vintage-story-stratumconfig.json index 986c6ed50..6c551f5d1 100644 --- a/vintage-story-stratumconfig.json +++ b/vintage-story-stratumconfig.json @@ -610,20 +610,6 @@ "EnumValues": {}, "MinValue": "0" }, - { - "DisplayName": "Save File Location", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "World:public:4", - "Description": "Full path of the .vcdbs world file this instance loads. Leave as generated unless you are switching worlds deliberately.", - "Keywords": "save,world,file", - "FieldName": "VS_WorldConfig_SaveFileLocation", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.WorldConfig.SaveFileLocation", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, { "DisplayName": "World Repair Mode", "Category": "Vintage Story:stadia_controller", diff --git a/vintage-story-stratumstart.json b/vintage-story-stratumstart.json index cdd2859af..9933d496f 100644 --- a/vintage-story-stratumstart.json +++ b/vintage-story-stratumstart.json @@ -1,4 +1,20 @@ [ + { + "UpdateStageName": "Repair savegame path", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"bash '{{$FullRootDir}}scripts/fix-serverconfig.sh' '{{$FullRootDir}}data'\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Repair savegame path", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"& '{{$FullRootDir}}scripts\\fix-serverconfig.ps1' '{{$FullRootDir}}data'\"", + "SkipOnFailure": false + }, { "UpdateStageName": "Render Nimbus backend config", "UpdateSourcePlatform": "Linux", diff --git a/vintage-story-stratumupdates.json b/vintage-story-stratumupdates.json index 922bc1592..9f95adcc8 100644 --- a/vintage-story-stratumupdates.json +++ b/vintage-story-stratumupdates.json @@ -77,6 +77,24 @@ "OverwriteExistingFiles": true, "SkipOnFailure": false }, + { + "UpdateStageName": "Write savegame path repair script (Linux)", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/fix-serverconfig.sh", + "UpdateSourceData": "#!/usr/bin/env bash\n# Generated by the AMP \"Vintage Story (Stratum + Nimbus)\" template.\n# Repairs WorldConfig.SaveFileLocation in data/serverconfig.json before every start.\n# Vintage Story stores an absolute path to the .vcdbs world file in that key and never\n# recalculates it, so an empty, missing or stale value makes the server abort with\n# \"Unable to open or create savegame\". This script puts a valid path back without\n# touching or reformatting any other part of the file.\nset -euo pipefail\n\ndata=\"${1:?data directory required}\"\ndata=\"${data%/}\"\ncfg=\"$data/serverconfig.json\"\n\n[ -f \"$cfg\" ] || exit 0\n\nsaves=\"$data/Saves\"\ndesired=\"$saves/default.vcdbs\"\nif [ -d \"$saves\" ] && [ ! -f \"$desired\" ]; then\n found=\"\"\n count=0\n for f in \"$saves\"/*.vcdbs; do\n [ -f \"$f\" ] || continue\n found=\"$f\"\n count=$((count + 1))\n done\n if [ \"$count\" = \"1\" ]; then\n desired=\"$found\"\n fi\nfi\n\nneed=0\nif ! grep -q '\"SaveFileLocation\"' \"$cfg\"; then\n need=2\nelse\n cur=$(sed -n 's|.*\"SaveFileLocation\"[[:space:]]*:[[:space:]]*\"\\(.*\\)\".*|\\1|p' \"$cfg\" | head -n 1)\n if [ -z \"$cur\" ]; then\n need=1\n elif [ ! -d \"$(dirname \"$cur\")\" ]; then\n echo \"[AMP] serverconfig.json points at $cur but that folder does not exist on this system\"\n need=1\n fi\nfi\n\nif [ \"$need\" = \"0\" ]; then\n exit 0\nfi\n\nmkdir -p \"$saves\"\nesc=$(printf '%s' \"$desired\" | sed -e 's/[\\\\&|]/\\\\&/g')\n\nif [ \"$need\" = \"1\" ]; then\n sed -i \"s|\\\"SaveFileLocation\\\"[[:space:]]*:[[:space:]]*\\\"[^\\\"]*\\\"|\\\"SaveFileLocation\\\": \\\"$esc\\\"|\" \"$cfg\"\nelif grep -q '\"WorldConfig\"' \"$cfg\"; then\n sed -i \"s|\\\"WorldConfig\\\"[[:space:]]*:[[:space:]]*{|&\\\"SaveFileLocation\\\": \\\"$esc\\\",|\" \"$cfg\"\nelse\n echo \"[AMP] WARNING: no WorldConfig section in $cfg, cannot repair the save file location\" >&2\n exit 0\nfi\n\necho \"[AMP] repaired SaveFileLocation in serverconfig.json -> $desired\"\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Write savegame path repair script (Windows)", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/fix-serverconfig.ps1", + "UpdateSourceData": "# Generated by the AMP \"Vintage Story (Stratum + Nimbus)\" template.\n# Repairs WorldConfig.SaveFileLocation in data\\serverconfig.json before every start.\n# Vintage Story stores an absolute path to the .vcdbs world file in that key and never\n# recalculates it, so an empty, missing or stale value makes the server abort with\n# \"Unable to open or create savegame\". This script puts a valid path back without\n# touching or reformatting any other part of the file.\nparam([Parameter(Mandatory = $true)][string]$DataDir)\n\n$ErrorActionPreference = 'Stop'\n\n$DataDir = $DataDir.TrimEnd('\\', '/')\n$cfg = Join-Path $DataDir 'serverconfig.json'\nif (-not (Test-Path -LiteralPath $cfg)) { exit 0 }\n\n$saves = Join-Path $DataDir 'Saves'\n$desired = Join-Path $saves 'default.vcdbs'\nif ((Test-Path -LiteralPath $saves) -and -not (Test-Path -LiteralPath $desired)) {\n $found = @(Get-ChildItem -LiteralPath $saves -Filter '*.vcdbs' -File -ErrorAction SilentlyContinue)\n if ($found.Count -eq 1) { $desired = $found[0].FullName }\n}\n\n$text = [IO.File]::ReadAllText($cfg)\n$rx = '\"SaveFileLocation\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.)*)\"'\n$m = [regex]::Match($text, $rx)\n\n$need = 0\nif (-not $m.Success) {\n $need = 2\n}\nelse {\n $cur = $m.Groups[1].Value -replace '\\\\\\\\', '\\'\n if ([string]::IsNullOrWhiteSpace($cur)) {\n $need = 1\n }\n else {\n $parent = Split-Path -Path $cur -Parent\n if ([string]::IsNullOrWhiteSpace($parent) -or -not (Test-Path -LiteralPath $parent)) {\n Write-Output \"[AMP] serverconfig.json points at $cur but that folder does not exist on this system\"\n $need = 1\n }\n }\n}\n\nif ($need -eq 0) { exit 0 }\n\nNew-Item -ItemType Directory -Path $saves -Force | Out-Null\n$bs = [string][char]92\n$dl = [string][char]36\n$esc = $desired.Replace($bs, $bs + $bs)\n$rep = $esc.Replace($dl, $dl + $dl)\n\nif ($need -eq 1) {\n $text = [regex]::new($rx).Replace($text, ('\"SaveFileLocation\": \"' + $rep + '\"'), 1)\n}\nelseif ($text -match '\"WorldConfig\"\\s*:\\s*\\{') {\n $text = [regex]::new('\"WorldConfig\"\\s*:\\s*\\{').Replace($text, ('$0\"SaveFileLocation\": \"' + $rep + '\",'), 1)\n}\nelse {\n Write-Warning \"[AMP] no WorldConfig section in $cfg, cannot repair the save file location\"\n exit 0\n}\n\n[IO.File]::WriteAllText($cfg, $text, (New-Object Text.UTF8Encoding $false))\nWrite-Output \"[AMP] repaired SaveFileLocation in serverconfig.json -> $desired\"\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, { "UpdateStageName": "Write Nimbus backend config script (Linux)", "UpdateSourcePlatform": "Linux", @@ -192,6 +210,22 @@ "UpdateSourceConditionValue": "true", "SkipOnFailure": false }, + { + "UpdateStageName": "Repair savegame path", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"bash '{{$FullRootDir}}scripts/fix-serverconfig.sh' '{{$FullRootDir}}data'\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Repair savegame path", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"& '{{$FullRootDir}}scripts\\fix-serverconfig.ps1' '{{$FullRootDir}}data'\"", + "SkipOnFailure": false + }, { "UpdateStageName": "Start Server", "UpdateSourcePlatform": "All", From 95fcac30e91851af9885cb1cbd032a971341cadb Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Fri, 7 Aug 2026 19:25:47 -0500 Subject: [PATCH 17/50] Add files via upload --- vintage-story-stratumconfig.json | 40 ++++++++++++++++---------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/vintage-story-stratumconfig.json b/vintage-story-stratumconfig.json index 6c551f5d1..ffffec017 100644 --- a/vintage-story-stratumconfig.json +++ b/vintage-story-stratumconfig.json @@ -2083,7 +2083,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.BlockBreakGuards.RequiredProgressRatio", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "0.8", "EnumValues": {}, "Decimal": true }, @@ -2098,7 +2098,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.BlockBreakGuards.GraceSeconds", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "0.25", "EnumValues": {}, "Decimal": true }, @@ -2113,7 +2113,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.BlockBreakGuards.MinimumTrackedBreakSeconds", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "0.15", "EnumValues": {}, "Decimal": true }, @@ -2128,7 +2128,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.BlockBreakGuards.PartialProgressRetentionSeconds", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "8", "EnumValues": {}, "Decimal": true }, @@ -2143,7 +2143,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.BlockBreakGuards.MaxRememberedProgressRatio", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "0.95", "EnumValues": {}, "Decimal": true }, @@ -7141,7 +7141,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.ChunkSending.OverloadScale", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "0.5", "EnumValues": {}, "Decimal": true }, @@ -7302,7 +7302,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.ChunkSending.OutboundPressureScale", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "0.5", "EnumValues": {}, "Decimal": true }, @@ -7424,7 +7424,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.ChunkGeneration.OverloadScale", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "0.5", "EnumValues": {}, "Decimal": true }, @@ -8051,7 +8051,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.Physics.NearActivationRadiusBlocks", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "24", "EnumValues": {}, "Decimal": true }, @@ -8066,7 +8066,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.Physics.MidActivationRadiusBlocks", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "60", "EnumValues": {}, "Decimal": true }, @@ -8518,7 +8518,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.ChunkPriority.PredictionSeconds", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "1.5", "EnumValues": {}, "Decimal": true }, @@ -8814,7 +8814,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.BlockTicks.OverloadScale", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "0.5", "EnumValues": {}, "Decimal": true }, @@ -9173,7 +9173,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.BodyTemperature.UpdateIntervalSeconds", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "3", "EnumValues": {}, "Decimal": true }, @@ -9188,7 +9188,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.BodyTemperature.HeatSourceIntervalSeconds", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "15", "EnumValues": {}, "Decimal": true }, @@ -9203,7 +9203,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.BodyTemperature.FreezingAnimIntervalSeconds", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "2", "EnumValues": {}, "Decimal": true }, @@ -9218,7 +9218,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.BodyTemperature.DamageCheckIntervalSeconds", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "12", "EnumValues": {}, "Decimal": true }, @@ -9233,7 +9233,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.BodyTemperature.JitterPercent", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "0.25", "EnumValues": {}, "Decimal": true }, @@ -9386,7 +9386,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.EntityCollisions.DistanceGateBlocks", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "24", "EnumValues": {}, "Decimal": true }, @@ -9401,7 +9401,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.EntityCollisions.NearBandBlocks", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "12", "EnumValues": {}, "Decimal": true }, @@ -9642,7 +9642,7 @@ "IsFlagArgument": false, "ParamFieldName": "$.AdaptiveRadius.AdjustmentIntervalSeconds", "IncludeInCommandLine": false, - "DefaultValue": "", + "DefaultValue": "2.0", "EnumValues": {}, "Decimal": true }, From 896d6107f3aa34adf5d04f715c14de4cd77aa50f Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Tue, 11 Aug 2026 17:33:51 -0500 Subject: [PATCH 18/50] Add files via upload --- nimbus-proxy.kvp | 38 +- nimbus-proxyconfig.json | 1098 +-- nimbus-proxyports.json | 32 +- nimbus-proxystart.json | 32 +- nimbus-proxyupdates.json | 191 +- nimbus-registry.kvp | 34 +- nimbus-registryconfig.json | 591 +- nimbus-registryports.json | 8 +- nimbus-registrystart.json | 32 +- nimbus-registryupdates.json | 184 +- vintage-story-stratum.kvp | 29 +- vintage-story-stratumconfig.json | 9803 +------------------------- vintage-story-stratummetaconfig.json | 23 +- vintage-story-stratumports.json | 14 +- vintage-story-stratumupdates.json | 353 +- 15 files changed, 406 insertions(+), 12056 deletions(-) diff --git a/nimbus-proxy.kvp b/nimbus-proxy.kvp index b59e75393..311b4a72a 100644 --- a/nimbus-proxy.kvp +++ b/nimbus-proxy.kvp @@ -1,14 +1,13 @@ -Meta.DisplayName=Nimbus Proxy (Vintage Story) -Meta.Description=Nimbus proxy for Vintage Story. Players connect to this one instance and it routes them to any number of Stratum or vanilla backend servers, with transfers, reservations, bans and a network wide whitelist. Can host the Nimbus registry in-process (embedded mode) or point at a standalone registry instance. +Meta.DisplayName=Nimbus Proxy +Meta.Description=Player-facing Nimbus proxy with an embedded Registry by default Meta.OS=Windows, Linux Meta.AarchSupport=None Meta.Arch=x86_64 Meta.Author=HuguesDePayens Meta.URL=https://github.com/StratumServer/Nimbus -Meta.DisplayImageSource=url:https://wiki.vintagestory.at/images/thumb/8/8a/Gamelogo-vintagestory.png/340px-Gamelogo-vintagestory.png Meta.EndpointURIFormat= Meta.ConfigManifest=nimbus-proxyconfig.json -Meta.MetaConfigManifest=nimbus-proxymetaconfig.json +Meta.MetaConfigManifest= Meta.ConfigRoot=nimbus-proxy.kvp Meta.MinAMPVersion=2.4.6.0 Meta.SpecificDockerImage=cubecoders/ampbase:debian @@ -19,29 +18,28 @@ Meta.Prerequisites=[] Meta.ConfigReleaseState=NotSpecified Meta.NoCommercialUsage=False Meta.ConfigVersion=1 -Meta.AppConfigId=b41d7e08-9c56-4f3a-8d17-6ae2b90c5f44 +Meta.AppConfigId=6ce2a583-1448-46f5-9f9d-b505d5eab311 Meta.AppIsMultiIPAware=True -Meta.ResourceUsageInfo=1 CPU core and 512MB RAM is plenty for the proxy itself; it relays traffic and holds no world data +Meta.ResourceUsageInfo=Lightweight network service; size the backend servers separately Meta.ImportableExtensions=[] App.DisplayName=Nimbus Proxy App.RootDir=./nimbus/ App.BaseDirectory=./nimbus/ -App.ExecutableWin=dotnet\dotnet.exe App.ExecutableLinux=dotnet/dotnet +App.ExecutableWin=dotnet\dotnet.exe App.WorkingDir=Nimbus App.LinuxCommandLineArgs="{{$FullRootDir}}Nimbus/Nimbus.Proxy.dll" App.WindowsCommandLineArgs="{{$FullRootDir}}Nimbus\Nimbus.Proxy.dll" -App.CommandLineArgs={{$PlatformArgs}} {{ProxyExtraArgs}} +App.CommandLineArgs={{$PlatformArgs}} App.UseLinuxIOREDIR=False App.AppSettings={} App.EnvironmentVariables={"DOTNET_ROOT":"{{$FullRootDir}}dotnet","DOTNET_CLI_TELEMETRY_OPTOUT":"1","DOTNET_NOLOGO":"1"} -App.CommandLineParameterFormat=--{0} {1} +App.CommandLineParameterFormat={0} {1} App.CommandLineParameterDelimiter= -App.ExitMethod=SIGTERM -App.ExitMethodWindows=None +App.ExitMethod=OS_CLOSE App.ExitTimeout=30 App.ExitString= -App.ExitFile=lock +App.ExitFile= App.HasWriteableConsole=False App.HasReadableConsole=True App.SupportsLiveSettingsChanges=False @@ -52,7 +50,7 @@ App.AdminPortRef=AdminPort App.PrimaryApplicationPortRef=ServerPort App.UniversalSleepApplicationUDPPortRef=ServerPort App.UniversalSleepSteamQueryPortRef=ServerPort -App.MaxUsers=100 +App.MaxUsers={{$MaxUsers}} App.UseRandomAdminPassword=False App.RemoteAdminPassword= App.AdminMethod=STDIO @@ -60,7 +58,7 @@ App.AdminLoginTransform=None App.RCONConnectDelaySeconds=5 App.RCONConnectRetrySeconds=5 App.RCONHeartbeatMinutes=0 -App.RCONHeartbeatCommand=ping +App.RCONHeartbeatCommand= App.TelnetLoginFormat={0} App.PreStartStages=@IncludeJson[nimbus-proxystart.json] App.UpdateSources=@IncludeJson[nimbus-proxyupdates.json] @@ -69,8 +67,8 @@ App.SteamUpdateAnonymousLogin=True App.SteamForceLoginPrompt=False App.RapidStartup=False App.SmartExcludeSupported=True -App.SmartExcludeExemptions=["*.toml","*.json","*.cfg","*.conf","*.config","*.ini","*.kvp","*.yml","*.yaml"] -App.MonitorChildProcess=False +App.SmartExcludeExemptions=["*.toml","*.json","plugins/*"] +App.MonitorChildProcess=True App.MonitorChildProcessWaitMs=100 App.MonitorChildProcessName= App.SupportsUniversalSleep=False @@ -80,11 +78,11 @@ App.StripANSIControlCodes=True Console.FilterMatchRegex= Console.FilterMatchReplacement= Console.ThrowawayMessageRegex= -Console.AppReadyRegex=^[\d:]+ \[nimbus\] listening on .+ -> .+$ -Console.UserJoinRegex=^[\d:]+ \[nimbus\] \[s\d+\] (?.+?) \([\[\]a-fA-F\d:.]+\) . .+$ -Console.UserLeaveRegex=^[\d:]+ \[nimbus\] \[s\d+\] (?.+?) disconnected \(.+\)$ +Console.AppReadyRegex=^[\d:]+ \[nimbus\] listening on .+ -> (?:pool of \d+ backend\(s\)|backend .+)$ +Console.UserJoinRegex= +Console.UserLeaveRegex= Console.UserChatRegex= -Console.UpdateAvailableRegex=^[\d:]+ \[nimbus\] warn: update available: .*$ +Console.UpdateAvailableRegex= Console.MetricsRegex= Console.SuppressLogAtStart=False Console.ActivateLogRegex= diff --git a/nimbus-proxyconfig.json b/nimbus-proxyconfig.json index 2d9c23f3b..91d5d6095 100644 --- a/nimbus-proxyconfig.json +++ b/nimbus-proxyconfig.json @@ -1,1082 +1,20 @@ [ - { - "DisplayName": "Let AMP Manage nimbus.proxy.toml", - "Category": "Updates", - "Subcategory": "Nimbus Updates:build:-1", - "Description": "When on, AMP rewrites Nimbus/nimbus.proxy.toml from the settings in this panel every time the instance starts. Turn it off to hand-edit that file instead; every proxy setting in this panel is then ignored.", - "Keywords": "nimbus,config,manage", - "FieldName": "ProxyWriteConfig", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyWriteConfig", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Nimbus Version Tag", - "Category": "Updates", - "Subcategory": "Nimbus Updates:build:-1", - "Description": "Pin a specific Nimbus release tag, for example v0.5.0. Leave empty to take the newest release on the channel below. Every part of a Nimbus network - proxy, registry and the server mod on each backend - must run the same Nimbus version, so pin this once you go live and bump all of them together.", - "Keywords": "nimbus,version,tag", - "FieldName": "NimbusVersionTag", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "NimbusVersionTag", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "v0.5.0" - }, - { - "DisplayName": "Nimbus Release Channel", - "Category": "Updates", - "Subcategory": "Nimbus Updates:build:-1", - "Description": "stable takes the newest non prerelease. prerelease also considers releases marked as pre-release, which is only for test networks.", - "Keywords": "nimbus,channel,prerelease", - "FieldName": "NimbusReleaseChannel", - "InputType": "enum", - "IsFlagArgument": false, - "ParamFieldName": "NimbusReleaseChannel", - "IncludeInCommandLine": false, - "DefaultValue": "stable", - "EnumValues": { - "Stable releases only": "stable", - "Include pre-releases": "prerelease" - } - }, - { - "DisplayName": "GitHub Token (optional)", - "Category": "Updates", - "Subcategory": "Nimbus Updates:build:-1", - "Description": "Optional GitHub personal access token used only to raise the API rate limit while looking up releases. Nothing here needs a private repository, so leave it empty unless updates start failing with a rate limit message.", - "Keywords": "github,token,ratelimit", - "FieldName": "NimbusGitHubToken", - "InputType": "password", - "IsFlagArgument": false, - "ParamFieldName": "NimbusGitHubToken", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Components To Install", - "Category": "Updates", - "Subcategory": "Nimbus Updates:build:-1", - "Description": "Which parts of the Nimbus release are unpacked into this instance. Nimbus is the proxy itself. Nimbus Nimbus.Registry also unpacks the standalone registry next to it, which is only useful if you want to run both out of one instance.", - "Keywords": "nimbus,components", - "FieldName": "NimbusUpdateComponents", - "InputType": "enum", - "IsFlagArgument": false, - "ParamFieldName": "NimbusUpdateComponents", - "IncludeInCommandLine": false, - "DefaultValue": "Nimbus", - "EnumValues": { - "Proxy only": "Nimbus", - "Proxy and standalone registry": "Nimbus Nimbus.Registry" - } - }, - { - "DisplayName": ".NET SDK Version", - "Category": "Updates", - "Subcategory": "Runtime:memory:-1", - "Description": "Exact .NET SDK version to install, for example 10.0.100. Leave this empty to always take the latest SDK from the channel below, which is what you want unless a specific build broke something.", - "Keywords": "dotnet,sdk,version", - "FieldName": "DotnetSDKVersion", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "DotnetSDKVersion", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "10.0.100" - }, - { - "DisplayName": ".NET Release Channel", - "Category": "Updates", - "Subcategory": "Runtime:memory:-1", - "Description": "The .NET release channel the SDK is fetched from. Nimbus Proxy targets .NET 10 and needs the ASP.NET Core runtime, which the SDK includes, so leave this at 10.0 unless Nimbus itself moves to a newer runtime.", - "Keywords": "dotnet,release,channel", - "FieldName": "DotnetRelease", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "DotnetRelease", - "IncludeInCommandLine": false, - "DefaultValue": "10.0", - "EnumValues": {}, - "Placeholder": "10.0" - }, - { - "DisplayName": "Additional Command Line Arguments", - "Category": "Updates", - "Subcategory": "Nimbus Updates:build:-1", - "Description": "Extra arguments appended to the proxy command line. Nimbus takes no arguments of its own, so leave this empty unless a plugin documents one.", - "Keywords": "args,commandline", - "FieldName": "ProxyExtraArgs", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyExtraArgs", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Proxy Bind Address", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Listener:settings_input_antenna:1", - "Description": "Interface the proxy listens on for players. 0.0.0.0 means every interface. The port is taken from the instance's Server Port setting, so change the port there, not here. (Config file key: bind)", - "Keywords": "proxybindhost", - "FieldName": "ProxyBindHost", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyBindHost", - "IncludeInCommandLine": false, - "DefaultValue": "0.0.0.0:42420", - "EnumValues": {}, - "Placeholder": "0.0.0.0" - }, - { - "DisplayName": "Backend Servers", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Listener:settings_input_antenna:1", - "Description": "The [servers] table: comma separated list of id=host:port entries, for example hub=127.0.0.1:42421,creative=127.0.0.1:42422. Each id must match the Server ID configured in that backend's Nimbus settings, and each host:port is the address the PROXY uses to reach the backend, not the address players use. (Config file key: servers)", - "Keywords": "proxyservers", - "FieldName": "ProxyServers", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyServers", - "IncludeInCommandLine": false, - "DefaultValue": "hub=127.0.0.1:42421", - "EnumValues": {}, - "Placeholder": "hub=127.0.0.1:42421,creative=127.0.0.1:42422" - }, - { - "DisplayName": "Initial Connect Order", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Listener:settings_input_antenna:1", - "Description": "Comma separated backend ids tried in order when a player first joins the proxy. The first one that accepts the connection wins. Unknown ids are skipped with a warning. (Config file key: try)", - "Keywords": "proxytrylist", - "FieldName": "ProxyTryList", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyTryList", - "IncludeInCommandLine": false, - "DefaultValue": "hub", - "EnumValues": {}, - "Placeholder": "hub" - }, - { - "DisplayName": "PROXY Protocol Backends", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Listener:settings_input_antenna:1", - "Description": "Comma separated backend ids that should receive a PROXY protocol v2 header on every upstream connection, so the backend sees the player's real IP. The backend must trust this proxy's IP or it will reject the connection. Leave empty for unmodified backends. (Config file key: proxy_protocol_servers)", - "Keywords": "proxyprotocolservers", - "FieldName": "ProxyProtocolServers", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyProtocolServers", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "hub,creative" - }, - { - "DisplayName": "Forced Hosts", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Listener:settings_input_antenna:1", - "Description": "Reserved by Nimbus for hostname based routing and not consumed yet. Format hostname=id1|id2,hostname2=id3. Safe to leave empty. (Config file key: forced_hosts)", - "Keywords": "proxyforcedhosts", - "FieldName": "ProxyForcedHosts", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyForcedHosts", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "play.example.com=hub|creative" - }, - { - "DisplayName": "Default Transfer Mode", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Transfers:swap_horiz:2", - "Description": "How a player is moved between backends when no mode is requested explicitly. redirect is the vanilla reconnect flow and works with unmodified clients. seamless is the Nimbus visual handoff and needs the Nimbus client mod. (Config file key: transfers.default_mode)", - "Keywords": "proxytransfersdefaultmode", - "FieldName": "ProxyTransfersDefaultMode", - "InputType": "enum", - "IsFlagArgument": false, - "ParamFieldName": "ProxyTransfersDefaultMode", - "IncludeInCommandLine": false, - "DefaultValue": "redirect", - "EnumValues": { - "Redirect (vanilla reconnect)": "redirect", - "Seamless (needs Nimbus client mod)": "seamless" - } - }, - { - "DisplayName": "Allow Seamless Transfers", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Transfers:swap_horiz:2", - "Description": "Master switch for the seamless handoff path. Off means every transfer is a redirect, whatever a plugin or command asks for. (Config file key: transfers.allow_seamless)", - "Keywords": "proxytransfersallowseamless", - "FieldName": "ProxyTransfersAllowSeamless", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyTransfersAllowSeamless", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Require Seamless Capability", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Transfers:swap_horiz:2", - "Description": "Keep seamless transfers tied to a client that proved it speaks the Nimbus handshake. Turning this off will break vanilla clients that get handed a seamless transfer. (Config file key: transfers.require_seamless_capability)", - "Keywords": "proxytransfersrequireseamlesscapability", - "FieldName": "ProxyTransfersRequireSeamlessCapability", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyTransfersRequireSeamlessCapability", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Fall Back To Redirect", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Transfers:swap_horiz:2", - "Description": "When a seamless transfer was requested but the client cannot do it, send a normal redirect instead of failing the transfer. (Config file key: transfers.fallback_to_redirect_when_seamless_unavailable)", - "Keywords": "proxytransfersfallbacktoredirect", - "FieldName": "ProxyTransfersFallbackToRedirect", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyTransfersFallbackToRedirect", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Redirect Address Override", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Transfers:swap_horiz:2", - "Description": "host or host:port stamped into redirect packets instead of the target backend's own address. Set this to the proxy's player facing address so a fixed vanilla client reconnects to the proxy rather than straight to a backend. Empty keeps the old backend stamping. (Config file key: transfers.redirect_address)", - "Keywords": "proxytransfersredirectaddress", - "FieldName": "ProxyTransfersRedirectAddress", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyTransfersRedirectAddress", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "play.example.com:42420" - }, - { - "DisplayName": "Enable Unsafe Seamless Splice", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Transfers:swap_horiz:2", - "Description": "Re-enables the old experimental live TCP splice. Leave this off on any server you care about. (Config file key: transfers.enable_unsafe_seamless_splice)", - "Keywords": "proxytransfersenableunsafesplice", - "FieldName": "ProxyTransfersEnableUnsafeSplice", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyTransfersEnableUnsafeSplice", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enable Admin Socket", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Admin Socket:admin_panel_settings:3", - "Description": "The line-JSON admin socket used by nimctl and by panel integrations. Off disables it entirely. (Config file key: admin.enabled)", - "Keywords": "proxyadminenabled", - "FieldName": "ProxyAdminEnabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyAdminEnabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Admin Bind Address", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Admin Socket:admin_panel_settings:3", - "Description": "Interface the admin socket listens on. Keep 127.0.0.1 unless something off box has to reach it, in which case set the Admin Secret as well. The port comes from the Admin Port setting. (Config file key: admin.bind)", - "Keywords": "proxyadminbindhost", - "FieldName": "ProxyAdminBindHost", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyAdminBindHost", - "IncludeInCommandLine": false, - "DefaultValue": "127.0.0.1", - "EnumValues": {}, - "Placeholder": "127.0.0.1" - }, - { - "DisplayName": "Admin Secret", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Admin Socket:admin_panel_settings:3", - "Description": "When set, an admin client must authenticate with this secret before issuing commands. Required whenever the admin bind is not loopback. (Config file key: admin.secret)", - "Keywords": "proxyadminsecret", - "FieldName": "ProxyAdminSecret", - "InputType": "password", - "IsFlagArgument": false, - "ParamFieldName": "ProxyAdminSecret", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Granted Permissions", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Admin Socket:admin_panel_settings:3", - "Description": "Comma separated permissions handed to an admin client after it authenticates. * is full operator access. (Config file key: admin.granted_permissions)", - "Keywords": "proxyadmingrantedpermissions", - "FieldName": "ProxyAdminGrantedPermissions", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyAdminGrantedPermissions", - "IncludeInCommandLine": false, - "DefaultValue": "*", - "EnumValues": {}, - "Placeholder": "*" - }, - { - "DisplayName": "Registry Mode", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "embedded hosts the registry inside this proxy process, which is the normal single proxy setup. remote points this proxy at a standalone Nimbus registry, which is what you want with more than one proxy. disabled turns the registry off, leaving only the static [servers] table with no transfers, reservations, bans or whitelist. (Config file key: registry.mode)", - "Keywords": "proxyregistrymode", - "FieldName": "ProxyRegistryMode", - "InputType": "enum", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryMode", - "IncludeInCommandLine": false, - "DefaultValue": "embedded", - "EnumValues": { - "Embedded (registry runs inside this proxy)": "embedded", - "Remote (use a standalone registry)": "remote", - "Disabled (static server list only)": "disabled" - } - }, - { - "DisplayName": "Proxy ID", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "Identity this proxy uses with the registry, and the source id stamped on reservations it mints. Give every proxy on the network its own value. (Config file key: registry.proxy_id)", - "Keywords": "proxyregistryproxyid", - "FieldName": "ProxyRegistryProxyId", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryProxyId", - "IncludeInCommandLine": false, - "DefaultValue": "nimbus-proxy", - "EnumValues": {}, - "Placeholder": "nimbus-proxy" - }, - { - "DisplayName": "Reservation TTL (seconds)", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "How long a slot reservation minted for a transfer stays valid before the target backend forgets it. (Config file key: registry.reservation_ttl_seconds)", - "Keywords": "proxyregistryreservationttlseconds", - "FieldName": "ProxyRegistryReservationTtlSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryReservationTtlSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "60", - "EnumValues": {}, - "MinValue": "1" - }, - { - "DisplayName": "Fail On Registry Error", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "On means a registry the proxy cannot talk to stops the affected operation instead of silently continuing without reservations, bans or whitelist checks. (Config file key: registry.fail_on_error)", - "Keywords": "proxyregistryfailonerror", - "FieldName": "ProxyRegistryFailOnError", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryFailOnError", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Transfer Intent Poll (ms)", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "How often the proxy asks the registry for queued transfer intents, in milliseconds. Lower reacts faster to /server commands issued on a backend and costs more requests. (Config file key: registry.transfer_intent_poll_ms)", - "Keywords": "proxyregistrytransferintentpollms", - "FieldName": "ProxyRegistryTransferIntentPollMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryTransferIntentPollMs", - "IncludeInCommandLine": false, - "DefaultValue": "1000", - "EnumValues": {}, - "MinValue": "50" - }, - { - "DisplayName": "Remote Registry URL", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "Remote mode only. Base URL of the standalone Nimbus registry, for example http://10.0.0.5:8765. Ignored in embedded mode. (Config file key: registry.url)", - "Keywords": "proxyregistryurl", - "FieldName": "ProxyRegistryUrl", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryUrl", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "http://10.0.0.5:8765" - }, - { - "DisplayName": "Remote Registry Shared Secret", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "Remote mode only. Must be byte for byte the same value as the standalone registry's shared secret and every backend's SharedSecret. (Config file key: registry.shared_secret)", - "Keywords": "proxyregistrysharedsecret", - "FieldName": "ProxyRegistrySharedSecret", - "InputType": "password", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistrySharedSecret", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Remote Registry HTTP Timeout (seconds)", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "Remote mode only. How long a single registry request may take before it is treated as a failure. (Config file key: registry.http_timeout_seconds)", - "Keywords": "proxyregistryhttptimeoutseconds", - "FieldName": "ProxyRegistryHttpTimeoutSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryHttpTimeoutSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "5", - "EnumValues": {}, - "MinValue": "1" - }, - { - "DisplayName": "Embedded Registry Bind Address", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "Embedded mode only. Interface the embedded registry serves HTTP on so backends can heartbeat to it. 127.0.0.1 only works when every backend runs on this same machine; use 0.0.0.0 for backends elsewhere and set a real Embedded Shared Secret in the same pass. The port comes from the Registry Port setting. (Config file key: registry.embedded_bind)", - "Keywords": "proxyregistryembeddedbindhost", - "FieldName": "ProxyRegistryEmbeddedBindHost", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryEmbeddedBindHost", - "IncludeInCommandLine": false, - "DefaultValue": "127.0.0.1", - "EnumValues": {}, - "Placeholder": "127.0.0.1" - }, - { - "DisplayName": "Serve Embedded Registry Over HTTP", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "Embedded mode only. Off writes an empty embedded_bind, which keeps the in process registry but stops listening on HTTP. Only useful when this proxy has no external backends at all.", - "Keywords": "proxyregistryembeddedhttpenabled", - "FieldName": "ProxyRegistryEmbeddedHttpEnabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryEmbeddedHttpEnabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Embedded Registry Shared Secret", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "Embedded mode only. The HMAC secret every backend signs its heartbeats with. Leave this empty and Nimbus generates one on first start, then read it out of nimbus.proxy.toml and paste it into each backend's Nimbus Shared Secret. If you set it here, use a long random value and never the string change-me-and-keep-secret. (Config file key: registry.embedded_shared_secret)", - "Keywords": "proxyregistryembeddedsharedsecret", - "FieldName": "ProxyRegistryEmbeddedSharedSecret", - "InputType": "password", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryEmbeddedSharedSecret", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Backend Stale After (seconds)", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "Seconds without a heartbeat before a backend is reported as stale. (Config file key: registry.backend_stale_seconds)", - "Keywords": "proxyregistrybackendstaleseconds", - "FieldName": "ProxyRegistryBackendStaleSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryBackendStaleSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "20", - "EnumValues": {}, - "MinValue": "1" - }, - { - "DisplayName": "Backend Dropped After (seconds)", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "Seconds without a heartbeat before a backend is removed from the registry entirely. (Config file key: registry.backend_drop_seconds)", - "Keywords": "proxyregistrybackenddropseconds", - "FieldName": "ProxyRegistryBackendDropSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryBackendDropSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "120", - "EnumValues": {}, - "MinValue": "1" - }, - { - "DisplayName": "Nonce Window (seconds)", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "Replay protection window. Signed requests older than this are refused, so backend clocks must agree with the registry within roughly this margin. (Config file key: registry.nonce_window_seconds)", - "Keywords": "proxyregistrynoncewindowseconds", - "FieldName": "ProxyRegistryNonceWindowSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryNonceWindowSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "90", - "EnumValues": {}, - "MinValue": "5" - }, - { - "DisplayName": "Maximum Reservation TTL (seconds)", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "Reservations asking for a longer TTL than this are refused. 0 removes the ceiling. (Config file key: registry.max_reservation_ttl_seconds)", - "Keywords": "proxyregistrymaxreservationttlseconds", - "FieldName": "ProxyRegistryMaxReservationTtlSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryMaxReservationTtlSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "300", - "EnumValues": {}, - "MinValue": "0" - }, - { - "DisplayName": "Advertise On Master Server", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "Publishes the network as a single entry on the public Vintage Story server list. Each backend should have its own master server advertising turned off when this is on, otherwise players see the backends as separate servers. (Config file key: registry.advertise_on_master_server)", - "Keywords": "proxyregistryadvertiseonmasterserver", - "FieldName": "ProxyRegistryAdvertiseOnMasterServer", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryAdvertiseOnMasterServer", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Embedded Registry State Directory", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "Where the embedded registry keeps nimbus.bans.json, nimbus.whitelist.json and nimbus.tokens.json. A relative path resolves next to the proxy binary, which is the default. (Config file key: registry.embedded_state_dir)", - "Keywords": "proxyregistryembeddedstatedir", - "FieldName": "ProxyRegistryEmbeddedStateDir", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryEmbeddedStateDir", - "IncludeInCommandLine": false, - "DefaultValue": ".", - "EnumValues": {}, - "Placeholder": "." - }, - { - "DisplayName": "Enable API Tokens", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "Embedded mode only. Lets third party integrations authenticate with scoped bearer tokens. Tokens can be minted while this is off; this switch only decides whether the registry answers them. (Config file key: registry.api_tokens_enabled)", - "Keywords": "proxyregistryapitokensenabled", - "FieldName": "ProxyRegistryApiTokensEnabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryApiTokensEnabled", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "API Token Rate Limit (per minute)", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "Requests per minute allowed per token. A value of zero or less is a configuration error and falls back to 60. (Config file key: registry.api_tokens_rate_limit_per_minute)", - "Keywords": "proxyregistryapitokensratelimitperminute", - "FieldName": "ProxyRegistryApiTokensRateLimitPerMinute", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryApiTokensRateLimitPerMinute", - "IncludeInCommandLine": false, - "DefaultValue": "60", - "EnumValues": {}, - "MinValue": "1" - }, - { - "DisplayName": "Trust X-Forwarded-Proto For API Tokens", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Registry:dns:4", - "Description": "Only set this when a TLS terminating reverse proxy is the single route to the registry bind. Anything that can reach the bind directly can forge the header this makes the registry believe. (Config file key: registry.api_tokens_trust_forwarded_proto)", - "Keywords": "proxyregistryapitokenstrustforwardedproto", - "FieldName": "ProxyRegistryApiTokensTrustForwardedProto", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyRegistryApiTokensTrustForwardedProto", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Network Wide Whitelist", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Whitelist:playlist_add_check:5", - "Description": "On closes the entire network: only players covered by a whitelist entry get past the proxy. An empty whitelist with this on means nobody gets in. (Config file key: whitelist.network)", - "Keywords": "proxywhitelistnetwork", - "FieldName": "ProxyWhitelistNetwork", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyWhitelistNetwork", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Whitelisted Backends", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Whitelist:playlist_add_check:5", - "Description": "Comma separated backend ids that require a whitelist entry even when the network as a whole is open, for example a staff or build server inside a public network. (Config file key: whitelist.servers)", - "Keywords": "proxywhitelistservers", - "FieldName": "ProxyWhitelistServers", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyWhitelistServers", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "staff,build" - }, - { - "DisplayName": "Fail Open Until First Sync", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Whitelist:playlist_add_check:5", - "Description": "Cold start behaviour only. Off keeps the door shut until the proxy has read the whitelist at least once. On lets players in meanwhile, which risks a wide open network while the registry is unreachable. (Config file key: whitelist.fail_open_until_first_sync)", - "Keywords": "proxywhitelistfailopenuntilfirstsync", - "FieldName": "ProxyWhitelistFailOpenUntilFirstSync", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyWhitelistFailOpenUntilFirstSync", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Verbose Logging", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Logging:receipt_long:6", - "Description": "Turns on debug level proxy logging. Useful while setting a network up, noisy afterwards. (Config file key: logging.verbose)", - "Keywords": "proxyloggingverbose", - "FieldName": "ProxyLoggingVerbose", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyLoggingVerbose", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Log Protocol Frames", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Logging:receipt_long:6", - "Description": "Logs individual Vintage Story protocol frames. Diagnostics only; this is extremely noisy. (Config file key: logging.sniff_frames)", - "Keywords": "proxyloggingsniffframes", - "FieldName": "ProxyLoggingSniffFrames", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyLoggingSniffFrames", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Log Traffic Byte Counts", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Logging:receipt_long:6", - "Description": "Logs per session byte counters as traffic flows rather than only on disconnect. (Config file key: logging.log_traffic_bytes)", - "Keywords": "proxylogginglogtrafficbytes", - "FieldName": "ProxyLoggingLogTrafficBytes", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyLoggingLogTrafficBytes", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enable Metrics Endpoint", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Metrics and Status:monitoring:7", - "Description": "Serves Prometheus style metrics and, optionally, the JSON status API used by panels. (Config file key: metrics.enabled)", - "Keywords": "proxymetricsenabled", - "FieldName": "ProxyMetricsEnabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyMetricsEnabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Metrics Bind Address", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Metrics and Status:monitoring:7", - "Description": "Interface the metrics HTTP listener uses. Keep it on loopback unless a scraper needs to reach it from elsewhere, and set the Status API Token if you widen it. The port comes from the Metrics Port setting. (Config file key: metrics.bind)", - "Keywords": "proxymetricsbindhost", - "FieldName": "ProxyMetricsBindHost", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyMetricsBindHost", - "IncludeInCommandLine": false, - "DefaultValue": "127.0.0.1", - "EnumValues": {}, - "Placeholder": "127.0.0.1" - }, - { - "DisplayName": "Metrics Path", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Metrics and Status:monitoring:7", - "Description": "URL path the metrics are served on. (Config file key: metrics.path)", - "Keywords": "proxymetricspath", - "FieldName": "ProxyMetricsPath", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyMetricsPath", - "IncludeInCommandLine": false, - "DefaultValue": "/metrics", - "EnumValues": {}, - "Placeholder": "/metrics" - }, - { - "DisplayName": "Enable Status API", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Metrics and Status:monitoring:7", - "Description": "Serves a read only JSON snapshot of the network at /status on the metrics listener, which is the easiest way for a dashboard to see which backends are live. (Config file key: metrics.status_api)", - "Keywords": "proxymetricsstatusapi", - "FieldName": "ProxyMetricsStatusApi", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyMetricsStatusApi", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Status API Token", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Metrics and Status:monitoring:7", - "Description": "Optional bearer token for /status. Empty leaves it open, which is acceptable on a loopback bind only. Prefer the Authorization header over the ?token= fallback, because query strings end up in access logs. (Config file key: metrics.status_api_token)", - "Keywords": "proxymetricsstatusapitoken", - "FieldName": "ProxyMetricsStatusApiToken", - "InputType": "password", - "IsFlagArgument": false, - "ParamFieldName": "ProxyMetricsStatusApiToken", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Answer Server Pings", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Server Listing:badge:8", - "Description": "Lets the proxy answer the ping a client sends before joining, so the network shows up in a client's server list entry instead of looking offline. (Config file key: status.enabled)", - "Keywords": "proxystatusenabled", - "FieldName": "ProxyStatusEnabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyStatusEnabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Network Name", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Server Listing:badge:8", - "Description": "Name reported for the whole network in ping replies. (Config file key: status.name)", - "Keywords": "proxystatusname", - "FieldName": "ProxyStatusName", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyStatusName", - "IncludeInCommandLine": false, - "DefaultValue": "Nimbus", - "EnumValues": {}, - "Placeholder": "Nimbus" - }, - { - "DisplayName": "Network Description", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Server Listing:badge:8", - "Description": "Description or MOTD reported in ping replies. (Config file key: status.motd)", - "Keywords": "proxystatusmotd", - "FieldName": "ProxyStatusMotd", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyStatusMotd", - "IncludeInCommandLine": false, - "DefaultValue": "Vintage Story proxy", - "EnumValues": {} - }, - { - "DisplayName": "Reported Game Mode", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Server Listing:badge:8", - "Description": "Game mode string reported in ping replies, for example survival or creative. (Config file key: status.game_mode)", - "Keywords": "proxystatusgamemode", - "FieldName": "ProxyStatusGameMode", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyStatusGameMode", - "IncludeInCommandLine": false, - "DefaultValue": "survival", - "EnumValues": {}, - "Placeholder": "survival" - }, - { - "DisplayName": "Report As Password Protected", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Server Listing:badge:8", - "Description": "Tells clients the network expects a password. Set this only if the backends actually have one. (Config file key: status.password)", - "Keywords": "proxystatuspassword", - "FieldName": "ProxyStatusPassword", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyStatusPassword", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Reported Game Version", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Server Listing:badge:8", - "Description": "Version string reported in ping replies. Leave empty to report whatever the backends report, which is what you want when every backend runs the same Stratum build. (Config file key: status.server_version)", - "Keywords": "proxystatusserverversion", - "FieldName": "ProxyStatusServerVersion", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyStatusServerVersion", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "1.22.6" - }, - { - "DisplayName": "Network Player Limit", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Server Listing:badge:8", - "Description": "Player count reported for the network. This is a display value only; the real limits are the per backend player caps. (Config file key: status.max_players)", - "Keywords": "$maxusers", - "FieldName": "$MaxUsers", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "max_players", - "IncludeInCommandLine": false, - "DefaultValue": "100", - "EnumValues": {}, - "MinValue": "1" - }, - { - "DisplayName": "Ping Query Timeout (ms)", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Server Listing:badge:8", - "Description": "How long the proxy waits for backends while assembling a ping reply. (Config file key: status.query_timeout_ms)", - "Keywords": "proxystatusquerytimeoutms", - "FieldName": "ProxyStatusQueryTimeoutMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "ProxyStatusQueryTimeoutMs", - "IncludeInCommandLine": false, - "DefaultValue": "1500", - "EnumValues": {}, - "MinValue": "100" - }, - { - "DisplayName": "Enable Plugins", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Plugins:extension:9", - "Description": "Loads Nimbus proxy plugin assemblies from the plugin directory on start. (Config file key: plugins.enabled)", - "Keywords": "proxypluginsenabled", - "FieldName": "ProxyPluginsEnabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyPluginsEnabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Plugin Directory", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Plugins:extension:9", - "Description": "Where plugin .dll files are looked for. A relative path resolves next to the proxy binary. (Config file key: plugins.directory)", - "Keywords": "proxypluginsdirectory", - "FieldName": "ProxyPluginsDirectory", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyPluginsDirectory", - "IncludeInCommandLine": false, - "DefaultValue": "plugins", - "EnumValues": {}, - "Placeholder": "plugins" - }, - { - "DisplayName": "Disabled Plugins", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Plugins:extension:9", - "Description": "Comma separated plugin ids to skip even though their file is present. (Config file key: plugins.disabled)", - "Keywords": "proxypluginsdisabled", - "FieldName": "ProxyPluginsDisabled", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyPluginsDisabled", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "someplugin" - }, - { - "DisplayName": "Persist Drain Flags", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Advanced:tune:10", - "Description": "Remembers which backends were drained across a proxy restart, so a backend you took out of rotation does not quietly come back. (Config file key: persistence.persist_drain_flags)", - "Keywords": "proxypersistdrainflags", - "FieldName": "ProxyPersistDrainFlags", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "ProxyPersistDrainFlags", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Drain State File", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Advanced:tune:10", - "Description": "File the drain flags are written to. A relative path resolves next to the proxy binary. (Config file key: persistence.drain_flags_file)", - "Keywords": "proxydrainflagsfile", - "FieldName": "ProxyDrainFlagsFile", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "ProxyDrainFlagsFile", - "IncludeInCommandLine": false, - "DefaultValue": "nimbus.drain-state.json", - "EnumValues": {} - }, - { - "DisplayName": "Backend Connect Timeout (ms)", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Advanced:tune:10", - "Description": "How long the proxy waits for a backend TCP connection before treating it as down and trying the next candidate. (Config file key: advanced.connect_timeout_ms)", - "Keywords": "proxyconnecttimeoutms", - "FieldName": "ProxyConnectTimeoutMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "ProxyConnectTimeoutMs", - "IncludeInCommandLine": false, - "DefaultValue": "5000", - "EnumValues": {}, - "MinValue": "100" - }, - { - "DisplayName": "Relay Buffer Size (bytes)", - "Category": "Nimbus Proxy:hub", - "Subcategory": "Advanced:tune:10", - "Description": "Per direction relay buffer. 16384 suits almost everything; raising it costs memory per connected player. (Config file key: advanced.buffer_size)", - "Keywords": "proxybuffersize", - "FieldName": "ProxyBufferSize", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "ProxyBufferSize", - "IncludeInCommandLine": false, - "DefaultValue": "16384", - "EnumValues": {}, - "MinValue": "1024" - } + {"DisplayName":"Player Port","Category":"Network:share","Subcategory":"Ports:dns:1","Description":"Public player-facing Vintage Story port.","Keywords":"player,port","FieldName":"$ServerPort","InputType":"number","Hidden":true,"ParamFieldName":"ServerPort","IncludeInCommandLine":false,"DefaultValue":"42420","MinValue":1,"MaxValue":65535,"EnumValues":{}}, + {"DisplayName":"Registry Port","Category":"Network:share","Subcategory":"Ports:dns:1","Description":"Embedded Registry HTTP port used by backends.","Keywords":"registry,port","FieldName":"$RegistryPort","InputType":"number","Hidden":true,"ParamFieldName":"RegistryPort","IncludeInCommandLine":false,"DefaultValue":"8765","MinValue":1,"MaxValue":65535,"EnumValues":{}}, + {"DisplayName":"Admin Port","Category":"Network:share","Subcategory":"Ports:dns:1","Description":"Loopback administration port.","Keywords":"admin,port","FieldName":"$AdminPort","InputType":"number","Hidden":true,"ParamFieldName":"AdminPort","IncludeInCommandLine":false,"DefaultValue":"42499","MinValue":1,"MaxValue":65535,"EnumValues":{}}, + {"DisplayName":"Metrics Port","Category":"Network:share","Subcategory":"Ports:dns:1","Description":"Loopback metrics and status API port.","Keywords":"metrics,status,port","FieldName":"$MetricsPort","InputType":"number","Hidden":true,"ParamFieldName":"MetricsPort","IncludeInCommandLine":false,"DefaultValue":"42500","MinValue":1,"MaxValue":65535,"EnumValues":{}}, + {"DisplayName":"Nimbus Release Tag","Category":"Updates:update","Subcategory":"Version:verified_user:1","Description":"Optional exact Nimbus release tag. Leave blank for the latest stable release.","Keywords":"nimbus,version","FieldName":"NimbusVersionTag","InputType":"text","ParamFieldName":"NimbusVersionTag","IncludeInCommandLine":false,"DefaultValue":"","Placeholder":"v0.5.0","EnumValues":{}}, + {"DisplayName":"Backend Servers","Category":"Routing:swap_horiz","Subcategory":"Backends:dns:1","Description":"Semicolon-separated id=host:port map. Each ID must match that backend's Nimbus Server ID.","Keywords":"backend,servers,map","FieldName":"ProxyServers","InputType":"text","ParamFieldName":"ProxyServers","IncludeInCommandLine":false,"Required":true,"DefaultValue":"hub=127.0.0.1:42421","Placeholder":"hub=127.0.0.1:42421;survival=127.0.0.1:42422","EnumValues":{}}, + {"DisplayName":"Try Order","Category":"Routing:swap_horiz","Subcategory":"Backends:dns:1","Description":"Comma-separated backend IDs tried for a new connection.","Keywords":"backend,order","FieldName":"ProxyTryList","InputType":"text","ParamFieldName":"ProxyTryList","IncludeInCommandLine":false,"Required":true,"DefaultValue":"hub","EnumValues":{}}, + {"DisplayName":"Registry Mode","Category":"Registry:hub","Subcategory":"Topology:account_tree:1","Description":"Embedded is recommended for one Proxy. Remote uses the optional standalone Registry.","Keywords":"registry,mode","FieldName":"ProxyRegistryMode","InputType":"enum","ParamFieldName":"ProxyRegistryMode","IncludeInCommandLine":false,"DefaultValue":"embedded","EnumValues":{"embedded":"Embedded (recommended)","remote":"Remote standalone Registry"}}, + {"DisplayName":"Embedded Registry Access","Category":"Registry:hub","Subcategory":"Topology:account_tree:1","Description":"Same host binds Registry to loopback. Other hosts exposes it on all instance interfaces.","Keywords":"registry,access","FieldName":"ProxyRegistryAccess","InputType":"enum","ParamFieldName":"ProxyRegistryAccess","IncludeInCommandLine":false,"DefaultValue":"same-host","EnumValues":{"same-host":"Backends on same host","other-hosts":"Backends on other hosts"}}, + {"DisplayName":"Remote Registry URL","Category":"Registry:hub","Subcategory":"Topology:account_tree:1","Description":"Required only in remote mode, for example http://registry-host:8765.","Keywords":"registry,url","FieldName":"ProxyRegistryUrl","InputType":"text","ParamFieldName":"ProxyRegistryUrl","IncludeInCommandLine":false,"DefaultValue":"","Placeholder":"http://registry-host:8765","EnumValues":{}}, + {"DisplayName":"Registry Shared Secret","Category":"Registry:hub","Subcategory":"Security:lock:2","Description":"Blank generates and then preserves a secret in embedded mode. Remote mode requires the standalone Registry secret.","Keywords":"registry,secret","FieldName":"ProxySharedSecret","InputType":"password","ParamFieldName":"ProxySharedSecret","IncludeInCommandLine":false,"DefaultValue":"","EnumValues":{}}, + {"DisplayName":"Proxy ID","Category":"Registry:hub","Subcategory":"Topology:account_tree:1","Description":"Stable identifier for this Proxy in the Registry.","Keywords":"proxy,id","FieldName":"ProxyId","InputType":"text","ParamFieldName":"ProxyId","IncludeInCommandLine":false,"Required":true,"DefaultValue":"nimbus-proxy","EnumValues":{}}, + {"DisplayName":"Network Name","Category":"Status:info","Subcategory":"Server List:list:1","Description":"Name returned by the Proxy status response.","Keywords":"status,name","FieldName":"ProxyStatusName","InputType":"text","ParamFieldName":"ProxyStatusName","IncludeInCommandLine":false,"DefaultValue":"Nimbus","EnumValues":{}}, + {"DisplayName":"Network Message","Category":"Status:info","Subcategory":"Server List:list:1","Description":"Message returned by the Proxy status response.","Keywords":"status,motd","FieldName":"ProxyStatusMotd","InputType":"text","ParamFieldName":"ProxyStatusMotd","IncludeInCommandLine":false,"DefaultValue":"Vintage Story proxy","EnumValues":{}}, + {"DisplayName":"Player Limit","Category":"Status:info","Subcategory":"Server List:list:1","Description":"Maximum player count reported by the Proxy.","Keywords":"players,limit","FieldName":"$MaxUsers","InputType":"number","ParamFieldName":"MaxUsers","IncludeInCommandLine":false,"DefaultValue":"100","MinValue":1,"MaxValue":65535,"EnumValues":{}}, + {"DisplayName":"Network Whitelist","Category":"Access:lock","Subcategory":"Whitelist:verified_user:1","Description":"Require Registry-synchronized whitelist access across the network.","Keywords":"network,whitelist","FieldName":"ProxyWhitelistNetwork","InputType":"checkbox","ParamFieldName":"ProxyWhitelistNetwork","IncludeInCommandLine":false,"DefaultValue":"false","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Whitelisted Backends","Category":"Access:lock","Subcategory":"Whitelist:verified_user:1","Description":"Optional comma-separated backend IDs subject to the network whitelist.","Keywords":"backend,whitelist","FieldName":"ProxyWhitelistServers","InputType":"text","ParamFieldName":"ProxyWhitelistServers","IncludeInCommandLine":false,"DefaultValue":"","EnumValues":{}}, + {"DisplayName":"Verbose Logging","Category":"Logging:description","Subcategory":"Detail:manage_search:1","Description":"Enable extra Nimbus diagnostic messages. Packet sniffing and traffic-byte logs remain off.","Keywords":"verbose,logging","FieldName":"ProxyVerboseLogging","InputType":"checkbox","ParamFieldName":"ProxyVerboseLogging","IncludeInCommandLine":false,"DefaultValue":"false","EnumValues":{"True":"true","False":"false"}} ] diff --git a/nimbus-proxyports.json b/nimbus-proxyports.json index 002f32b16..853e5a44a 100644 --- a/nimbus-proxyports.json +++ b/nimbus-proxyports.json @@ -1,30 +1,6 @@ [ - { - "Protocol": "Both", - "Name": "Proxy Port", - "Description": "The port players connect to. This is the only Nimbus port that has to be reachable from the internet.", - "Port": 42420, - "Ref": "ServerPort" - }, - { - "Protocol": "TCP", - "Name": "Embedded Registry Port", - "Description": "HTTP port the embedded registry serves on so backends can heartbeat to it. Only needs to be reachable from your backend machines, never from the internet.", - "Port": 8765, - "Ref": "RegistryPort" - }, - { - "Protocol": "TCP", - "Name": "Admin Socket Port", - "Description": "Line-JSON admin socket used by nimctl and panel integrations. Keep this on loopback unless you set an admin secret.", - "Port": 42499, - "Ref": "AdminPort" - }, - { - "Protocol": "TCP", - "Name": "Metrics Port", - "Description": "Prometheus metrics and the JSON /status endpoint. Keep this private or set a status API token.", - "Port": 42500, - "Ref": "MetricsPort" - } + {"Protocol":"Both","Name":"Player Port","Description":"Public Vintage Story port players connect to","Port":42420,"Ref":"ServerPort"}, + {"Protocol":"TCP","Name":"Registry Port","Description":"Embedded Registry HTTP endpoint used by backends","Port":8765,"Ref":"RegistryPort"}, + {"Protocol":"TCP","Name":"Admin Port","Description":"Loopback Nimbus administration endpoint","Port":42499,"Ref":"AdminPort"}, + {"Protocol":"TCP","Name":"Metrics and Status Port","Description":"Loopback metrics and status endpoint","Port":42500,"Ref":"MetricsPort"} ] diff --git a/nimbus-proxystart.json b/nimbus-proxystart.json index 4e9cb2a72..578909085 100644 --- a/nimbus-proxystart.json +++ b/nimbus-proxystart.json @@ -1,18 +1,18 @@ [ - { - "UpdateStageName": "Render nimbus.proxy.toml", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "Executable", - "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"NP_WRITE='{{ProxyWriteConfig}}' NP_BIND='{{ProxyBindHost}}:{{$ServerPort}}' NP_SERVERS='{{ProxyServers}}' NP_TRY='{{ProxyTryList}}' NP_PPSERVERS='{{ProxyProtocolServers}}' NP_FORCEDHOSTS='{{ProxyForcedHosts}}' NP_T_MODE='{{ProxyTransfersDefaultMode}}' NP_T_ALLOWSEAMLESS='{{ProxyTransfersAllowSeamless}}' NP_T_REQCAP='{{ProxyTransfersRequireSeamlessCapability}}' NP_T_FALLBACK='{{ProxyTransfersFallbackToRedirect}}' NP_T_REDIRECTADDR='{{ProxyTransfersRedirectAddress}}' NP_T_SPLICE='{{ProxyTransfersEnableUnsafeSplice}}' NP_A_ENABLED='{{ProxyAdminEnabled}}' NP_A_BIND='{{ProxyAdminBindHost}}:{{$AdminPort}}' NP_A_SECRET='{{ProxyAdminSecret}}' NP_A_PERMS='{{ProxyAdminGrantedPermissions}}' NP_R_MODE='{{ProxyRegistryMode}}' NP_R_PROXYID='{{ProxyRegistryProxyId}}' NP_R_RESTTL='{{ProxyRegistryReservationTtlSeconds}}' NP_R_FAILONERROR='{{ProxyRegistryFailOnError}}' NP_R_INTENTPOLL='{{ProxyRegistryTransferIntentPollMs}}' NP_R_URL='{{ProxyRegistryUrl}}' NP_R_SECRET='{{ProxyRegistrySharedSecret}}' NP_R_HTTPTIMEOUT='{{ProxyRegistryHttpTimeoutSeconds}}' NP_R_EMBBIND='http://{{ProxyRegistryEmbeddedBindHost}}:{{$RegistryPort}}' NP_R_EMBHTTP='{{ProxyRegistryEmbeddedHttpEnabled}}' NP_R_EMBSECRET='{{ProxyRegistryEmbeddedSharedSecret}}' NP_R_STALE='{{ProxyRegistryBackendStaleSeconds}}' NP_R_DROP='{{ProxyRegistryBackendDropSeconds}}' NP_R_NONCE='{{ProxyRegistryNonceWindowSeconds}}' NP_R_MAXRESTTL='{{ProxyRegistryMaxReservationTtlSeconds}}' NP_R_ADVERTISE='{{ProxyRegistryAdvertiseOnMasterServer}}' NP_R_STATEDIR='{{ProxyRegistryEmbeddedStateDir}}' NP_R_APITOK='{{ProxyRegistryApiTokensEnabled}}' NP_R_APIRATE='{{ProxyRegistryApiTokensRateLimitPerMinute}}' NP_R_APIFWD='{{ProxyRegistryApiTokensTrustForwardedProto}}' NP_W_NETWORK='{{ProxyWhitelistNetwork}}' NP_W_SERVERS='{{ProxyWhitelistServers}}' NP_W_FAILOPEN='{{ProxyWhitelistFailOpenUntilFirstSync}}' NP_L_VERBOSE='{{ProxyLoggingVerbose}}' NP_L_SNIFF='{{ProxyLoggingSniffFrames}}' NP_L_TRAFFIC='{{ProxyLoggingLogTrafficBytes}}' NP_M_ENABLED='{{ProxyMetricsEnabled}}' NP_M_BIND='http://{{ProxyMetricsBindHost}}:{{$MetricsPort}}' NP_M_PATH='{{ProxyMetricsPath}}' NP_M_STATUSAPI='{{ProxyMetricsStatusApi}}' NP_M_STATUSTOKEN='{{ProxyMetricsStatusApiToken}}' NP_S_ENABLED='{{ProxyStatusEnabled}}' NP_S_NAME='{{ProxyStatusName}}' NP_S_MOTD='{{ProxyStatusMotd}}' NP_S_GAMEMODE='{{ProxyStatusGameMode}}' NP_S_PASSWORD='{{ProxyStatusPassword}}' NP_S_VERSION='{{ProxyStatusServerVersion}}' NP_S_MAXPLAYERS='{{$MaxUsers}}' NP_S_QUERYTIMEOUT='{{ProxyStatusQueryTimeoutMs}}' NP_P_ENABLED='{{ProxyPluginsEnabled}}' NP_P_DIR='{{ProxyPluginsDirectory}}' NP_P_DISABLED='{{ProxyPluginsDisabled}}' NP_PE_DRAIN='{{ProxyPersistDrainFlags}}' NP_PE_DRAINFILE='{{ProxyDrainFlagsFile}}' NP_AD_CONNTIMEOUT='{{ProxyConnectTimeoutMs}}' NP_AD_BUFSIZE='{{ProxyBufferSize}}' bash '{{$FullRootDir}}scripts/write-proxy-toml.sh' '{{$FullRootDir}}Nimbus/nimbus.proxy.toml'\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Render nimbus.proxy.toml", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "Executable", - "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$env:NP_WRITE='{{ProxyWriteConfig}}'; $env:NP_BIND='{{ProxyBindHost}}:{{$ServerPort}}'; $env:NP_SERVERS='{{ProxyServers}}'; $env:NP_TRY='{{ProxyTryList}}'; $env:NP_PPSERVERS='{{ProxyProtocolServers}}'; $env:NP_FORCEDHOSTS='{{ProxyForcedHosts}}'; $env:NP_T_MODE='{{ProxyTransfersDefaultMode}}'; $env:NP_T_ALLOWSEAMLESS='{{ProxyTransfersAllowSeamless}}'; $env:NP_T_REQCAP='{{ProxyTransfersRequireSeamlessCapability}}'; $env:NP_T_FALLBACK='{{ProxyTransfersFallbackToRedirect}}'; $env:NP_T_REDIRECTADDR='{{ProxyTransfersRedirectAddress}}'; $env:NP_T_SPLICE='{{ProxyTransfersEnableUnsafeSplice}}'; $env:NP_A_ENABLED='{{ProxyAdminEnabled}}'; $env:NP_A_BIND='{{ProxyAdminBindHost}}:{{$AdminPort}}'; $env:NP_A_SECRET='{{ProxyAdminSecret}}'; $env:NP_A_PERMS='{{ProxyAdminGrantedPermissions}}'; $env:NP_R_MODE='{{ProxyRegistryMode}}'; $env:NP_R_PROXYID='{{ProxyRegistryProxyId}}'; $env:NP_R_RESTTL='{{ProxyRegistryReservationTtlSeconds}}'; $env:NP_R_FAILONERROR='{{ProxyRegistryFailOnError}}'; $env:NP_R_INTENTPOLL='{{ProxyRegistryTransferIntentPollMs}}'; $env:NP_R_URL='{{ProxyRegistryUrl}}'; $env:NP_R_SECRET='{{ProxyRegistrySharedSecret}}'; $env:NP_R_HTTPTIMEOUT='{{ProxyRegistryHttpTimeoutSeconds}}'; $env:NP_R_EMBBIND='http://{{ProxyRegistryEmbeddedBindHost}}:{{$RegistryPort}}'; $env:NP_R_EMBHTTP='{{ProxyRegistryEmbeddedHttpEnabled}}'; $env:NP_R_EMBSECRET='{{ProxyRegistryEmbeddedSharedSecret}}'; $env:NP_R_STALE='{{ProxyRegistryBackendStaleSeconds}}'; $env:NP_R_DROP='{{ProxyRegistryBackendDropSeconds}}'; $env:NP_R_NONCE='{{ProxyRegistryNonceWindowSeconds}}'; $env:NP_R_MAXRESTTL='{{ProxyRegistryMaxReservationTtlSeconds}}'; $env:NP_R_ADVERTISE='{{ProxyRegistryAdvertiseOnMasterServer}}'; $env:NP_R_STATEDIR='{{ProxyRegistryEmbeddedStateDir}}'; $env:NP_R_APITOK='{{ProxyRegistryApiTokensEnabled}}'; $env:NP_R_APIRATE='{{ProxyRegistryApiTokensRateLimitPerMinute}}'; $env:NP_R_APIFWD='{{ProxyRegistryApiTokensTrustForwardedProto}}'; $env:NP_W_NETWORK='{{ProxyWhitelistNetwork}}'; $env:NP_W_SERVERS='{{ProxyWhitelistServers}}'; $env:NP_W_FAILOPEN='{{ProxyWhitelistFailOpenUntilFirstSync}}'; $env:NP_L_VERBOSE='{{ProxyLoggingVerbose}}'; $env:NP_L_SNIFF='{{ProxyLoggingSniffFrames}}'; $env:NP_L_TRAFFIC='{{ProxyLoggingLogTrafficBytes}}'; $env:NP_M_ENABLED='{{ProxyMetricsEnabled}}'; $env:NP_M_BIND='http://{{ProxyMetricsBindHost}}:{{$MetricsPort}}'; $env:NP_M_PATH='{{ProxyMetricsPath}}'; $env:NP_M_STATUSAPI='{{ProxyMetricsStatusApi}}'; $env:NP_M_STATUSTOKEN='{{ProxyMetricsStatusApiToken}}'; $env:NP_S_ENABLED='{{ProxyStatusEnabled}}'; $env:NP_S_NAME='{{ProxyStatusName}}'; $env:NP_S_MOTD='{{ProxyStatusMotd}}'; $env:NP_S_GAMEMODE='{{ProxyStatusGameMode}}'; $env:NP_S_PASSWORD='{{ProxyStatusPassword}}'; $env:NP_S_VERSION='{{ProxyStatusServerVersion}}'; $env:NP_S_MAXPLAYERS='{{$MaxUsers}}'; $env:NP_S_QUERYTIMEOUT='{{ProxyStatusQueryTimeoutMs}}'; $env:NP_P_ENABLED='{{ProxyPluginsEnabled}}'; $env:NP_P_DIR='{{ProxyPluginsDirectory}}'; $env:NP_P_DISABLED='{{ProxyPluginsDisabled}}'; $env:NP_PE_DRAIN='{{ProxyPersistDrainFlags}}'; $env:NP_PE_DRAINFILE='{{ProxyDrainFlagsFile}}'; $env:NP_AD_CONNTIMEOUT='{{ProxyConnectTimeoutMs}}'; $env:NP_AD_BUFSIZE='{{ProxyBufferSize}}';& '{{$FullRootDir}}scripts\\write-proxy-toml.ps1' '{{$FullRootDir}}Nimbus\\nimbus.proxy.toml'\"", - "SkipOnFailure": false - } + { + "UpdateStageName":"Render Nimbus Proxy configuration", + "UpdateSourcePlatform":"Linux", + "UpdateSource":"Executable", + "UpdateSourceData":"/bin/bash", + "UpdateSourceArgs":"-c \"NP_BIND_ADDRESS='{{$ApplicationIPBinding}}' NP_SERVER_PORT='{{$ServerPort}}' NP_REGISTRY_PORT='{{$RegistryPort}}' NP_ADMIN_PORT='{{$AdminPort}}' NP_METRICS_PORT='{{$MetricsPort}}' NP_SERVERS='{{ProxyServers}}' NP_TRY='{{ProxyTryList}}' NP_REGISTRY_MODE='{{ProxyRegistryMode}}' NP_REGISTRY_ACCESS='{{ProxyRegistryAccess}}' NP_REGISTRY_URL='{{ProxyRegistryUrl}}' NP_SHARED_SECRET='{{ProxySharedSecret}}' NP_PROXY_ID='{{ProxyId}}' NP_STATUS_NAME='{{ProxyStatusName}}' NP_STATUS_MOTD='{{ProxyStatusMotd}}' NP_MAX_USERS='{{$MaxUsers}}' NP_WHITELIST_NETWORK='{{ProxyWhitelistNetwork}}' NP_WHITELIST_SERVERS='{{ProxyWhitelistServers}}' NP_VERBOSE='{{ProxyVerboseLogging}}' bash '{{$FullRootDir}}scripts/write-proxy-toml.sh' '{{$FullRootDir}}Nimbus/nimbus.proxy.toml'\"", + "SkipOnFailure":false + }, + { + "UpdateStageName":"Render Nimbus Proxy configuration", + "UpdateSourcePlatform":"Windows", + "UpdateSource":"Executable", + "UpdateSourceData":"powershell.exe", + "UpdateSourceArgs":"-NoProfile -ExecutionPolicy Bypass -Command \"$env:NP_BIND_ADDRESS='{{$ApplicationIPBinding}}'; $env:NP_SERVER_PORT='{{$ServerPort}}'; $env:NP_REGISTRY_PORT='{{$RegistryPort}}'; $env:NP_ADMIN_PORT='{{$AdminPort}}'; $env:NP_METRICS_PORT='{{$MetricsPort}}'; $env:NP_SERVERS='{{ProxyServers}}'; $env:NP_TRY='{{ProxyTryList}}'; $env:NP_REGISTRY_MODE='{{ProxyRegistryMode}}'; $env:NP_REGISTRY_ACCESS='{{ProxyRegistryAccess}}'; $env:NP_REGISTRY_URL='{{ProxyRegistryUrl}}'; $env:NP_SHARED_SECRET='{{ProxySharedSecret}}'; $env:NP_PROXY_ID='{{ProxyId}}'; $env:NP_STATUS_NAME='{{ProxyStatusName}}'; $env:NP_STATUS_MOTD='{{ProxyStatusMotd}}'; $env:NP_MAX_USERS='{{$MaxUsers}}'; $env:NP_WHITELIST_NETWORK='{{ProxyWhitelistNetwork}}'; $env:NP_WHITELIST_SERVERS='{{ProxyWhitelistServers}}'; $env:NP_VERBOSE='{{ProxyVerboseLogging}}'; & '{{$FullRootDir}}scripts\\write-proxy-toml.ps1' '{{$FullRootDir}}Nimbus\\nimbus.proxy.toml'\"", + "SkipOnFailure":false + } ] diff --git a/nimbus-proxyupdates.json b/nimbus-proxyupdates.json index 4f59bc887..cc0cb149f 100644 --- a/nimbus-proxyupdates.json +++ b/nimbus-proxyupdates.json @@ -1,116 +1,75 @@ -[ - { - "UpdateStageName": "Create Nimbus directory", - "UpdateSourcePlatform": "All", - "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullRootDir}}Nimbus", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Create plugins directory", - "UpdateSourcePlatform": "All", - "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullRootDir}}Nimbus/plugins", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Create dotnet directory", - "UpdateSourcePlatform": "All", - "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullRootDir}}dotnet", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Create scripts directory", - "UpdateSourcePlatform": "All", - "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullRootDir}}scripts", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Write Nimbus installer script (Linux)", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}scripts/install-nimbus.sh", - "UpdateSourceData": "#!/usr/bin/env bash\n# Generated by the AMP Nimbus instance template.\n# Resolves a Nimbus release and installs the requested components out of it.\n# The release zip lays out release_full/Nimbus (proxy), release_full/Nimbus.Registry\n# (standalone registry) and release_full/Nimbus.ServerMod (the Vintage Story mod).\nset -euo pipefail\n\nroot=\"${1:?root directory required}\"\ncomponents=\"${2:?component list required}\"\ncd \"$root\"\n\nrepo=\"StratumServer/Nimbus\"\nhdr=(-H \"User-Agent: AMP-Nimbus-Template\" -H \"Accept: application/vnd.github+json\")\nif [ -n \"${GITHUB_TOKEN:-}\" ]; then hdr+=(-H \"Authorization: Bearer ${GITHUB_TOKEN}\"); fi\n\nfor tool in curl unzip jq; do\n command -v \"$tool\" >/dev/null 2>&1 || { echo \"[AMP] $tool is required but not installed\" >&2; exit 1; }\ndone\n\ntag=\"$(printf '%s' \"${NIMBUS_TAG:-}\" | tr -d '[:space:]')\"\nif [ -z \"$tag\" ]; then\n echo \"[AMP] resolving Nimbus release (channel=${NIMBUS_CHANNEL:-stable})\"\n json=\"$(curl -fsSL \"${hdr[@]}\" \"https://api.github.com/repos/${repo}/releases?per_page=100\")\"\n filter='.[] | select(.draft == false)'\n if [ \"${NIMBUS_CHANNEL:-stable}\" != \"prerelease\" ]; then\n filter=\"${filter} | select(.prerelease == false)\"\n fi\n tag=\"$(printf '%s' \"$json\" | jq -r \"[ ${filter} ] | .[0].tag_name // empty\")\"\nfi\n[ -n \"$tag\" ] || { echo \"[AMP] no Nimbus release matched channel=${NIMBUS_CHANNEL:-stable}\" >&2; exit 1; }\ncase \"$tag\" in v*) ;; *) tag=\"v${tag}\";; esac\n\nmarker=\".amp-nimbus-release\"\nif [ -f \"$marker\" ] && [ \"$(cat \"$marker\")\" = \"$tag\" ]; then\n ok=1\n for comp in $components; do\n [ -d \"$comp\" ] || ok=0\n done\n if [ \"$ok\" = \"1\" ]; then\n echo \"[AMP] already on Nimbus ${tag}; nothing to download\"\n exit 0\n fi\nfi\n\nurl=\"https://github.com/${repo}/releases/download/${tag}/Nimbus-${tag}.zip\"\necho \"[AMP] downloading ${url}\"\nrm -rf .nimbus-extract\nmkdir -p .nimbus-extract\ncurl -fL --retry 3 -o nimbus-release.zip \"$url\"\nunzip -qo nimbus-release.zip -d .nimbus-extract\nrm -f nimbus-release.zip\n\nsrc=\".nimbus-extract/release_full\"\n[ -d \"$src\" ] || src=\".nimbus-extract\"\n\nfor comp in $components; do\n if [ ! -d \"$src/$comp\" ]; then\n echo \"[AMP] component $comp is not present in this release\" >&2\n exit 1\n fi\n mkdir -p \"$comp\"\n # Config, state and plugins live in the component directory, so replace program files\n # only and leave everything the operator or Nimbus itself wrote in place.\n find \"$comp\" -maxdepth 1 -type f \\( -name '*.dll' -o -name '*.pdb' -o -name '*.deps.json' \\\n -o -name '*.runtimeconfig.json' -o -name 'web.config' -o -name '*.staticwebassets.endpoints.json' \\) -delete\n cp -RL \"$src/$comp/.\" \"$comp/\"\ndone\n\nif [ -f \"Nimbus/Nimbus.Proxy\" ]; then chmod +x \"Nimbus/Nimbus.Proxy\"; fi\nif [ -f \"Nimbus.Registry/Nimbus.Registry\" ]; then chmod +x \"Nimbus.Registry/Nimbus.Registry\"; fi\nif [ -f \"$src/LICENSE\" ]; then cp -f \"$src/LICENSE\" ./LICENSE; fi\n\nrm -rf .nimbus-extract\nprintf '%s' \"$tag\" > \"$marker\"\necho \"[AMP] installed Nimbus ${tag} (${components}) into ${root}\"\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, - { - "UpdateStageName": "Write Nimbus installer script (Windows)", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}scripts/install-nimbus.ps1", - "UpdateSourceData": "# Generated by the AMP Nimbus instance template.\nparam(\n [Parameter(Mandatory = $true)][string]$Root,\n [Parameter(Mandatory = $true)][string]$Components\n)\n\n$ErrorActionPreference = 'Stop'\n$ProgressPreference = 'SilentlyContinue'\n[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n\n$repo = 'StratumServer/Nimbus'\n$comps = @($Components -split '[,\\s]+' | Where-Object { $_ -ne '' })\n$headers = @{ 'User-Agent' = 'AMP-Nimbus-Template'; 'Accept' = 'application/vnd.github+json' }\nif ($env:GITHUB_TOKEN) { $headers['Authorization'] = \"Bearer $($env:GITHUB_TOKEN)\" }\n\n$tag = if ($env:NIMBUS_TAG) { $env:NIMBUS_TAG.Trim() } else { '' }\nif ($tag -eq '') {\n $channel = if ($env:NIMBUS_CHANNEL) { $env:NIMBUS_CHANNEL } else { 'stable' }\n Write-Host \"[AMP] resolving Nimbus release (channel=$channel)\"\n $releases = Invoke-RestMethod -Headers $headers -Uri \"https://api.github.com/repos/$repo/releases?per_page=100\"\n $candidates = @($releases | Where-Object { -not $_.draft })\n if ($channel -ne 'prerelease') { $candidates = @($candidates | Where-Object { -not $_.prerelease }) }\n if ($candidates.Count -eq 0) { throw \"No Nimbus release matched channel=$channel\" }\n $tag = $candidates[0].tag_name\n}\nif (-not $tag.StartsWith('v')) { $tag = \"v$tag\" }\n\n$marker = Join-Path $Root '.amp-nimbus-release'\nif ((Test-Path $marker) -and ((Get-Content $marker -Raw).Trim() -eq $tag)) {\n $missing = @($comps | Where-Object { -not (Test-Path (Join-Path $Root $_)) })\n if ($missing.Count -eq 0) {\n Write-Host \"[AMP] already on Nimbus $tag; nothing to download\"\n exit 0\n }\n}\n\n$extract = Join-Path $Root '.nimbus-extract'\nif (Test-Path $extract) { Remove-Item $extract -Recurse -Force }\nNew-Item -ItemType Directory -Force -Path $extract | Out-Null\n\n$zip = Join-Path $Root 'nimbus-release.zip'\n$url = \"https://github.com/$repo/releases/download/$tag/Nimbus-$tag.zip\"\nWrite-Host \"[AMP] downloading $url\"\nInvoke-WebRequest -UseBasicParsing -Headers $headers -Uri $url -OutFile $zip\nExpand-Archive -Path $zip -DestinationPath $extract -Force\nRemove-Item $zip -Force\n\n$src = Join-Path $extract 'release_full'\nif (-not (Test-Path $src)) { $src = $extract }\n\n$programPatterns = @('*.dll', '*.pdb', '*.deps.json', '*.runtimeconfig.json', 'web.config', '*.staticwebassets.endpoints.json')\nforeach ($comp in $comps) {\n $from = Join-Path $src $comp\n if (-not (Test-Path $from)) { throw \"Component $comp is not present in this release\" }\n $to = Join-Path $Root $comp\n New-Item -ItemType Directory -Force -Path $to | Out-Null\n # Replace program files only; nimbus.proxy.toml, state files and plugins stay put.\n foreach ($pattern in $programPatterns) {\n Get-ChildItem -LiteralPath $to -Filter $pattern -File -ErrorAction SilentlyContinue | Remove-Item -Force\n }\n Copy-Item -Path (Join-Path $from '*') -Destination $to -Recurse -Force\n}\n\n$license = Join-Path $src 'LICENSE'\nif (Test-Path $license) { Copy-Item -Path $license -Destination (Join-Path $Root 'LICENSE') -Force }\n\nRemove-Item $extract -Recurse -Force\nSet-Content -Path $marker -Value $tag -NoNewline\nWrite-Host \"[AMP] installed Nimbus $tag ($Components) into $Root\"\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, - { - "UpdateStageName": "Write config renderer script (Linux)", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}scripts/write-proxy-toml.sh", - "UpdateSourceData": "#!/usr/bin/env bash\n# Renders nimbus.proxy.toml from environment variables set by AMP.\n# Generated by the AMP Nimbus instance template; edits here are overwritten on the next update.\nset -uf\n\nOUT=\"${1:-}\"\nif [ -z \"$OUT\" ]; then echo \"usage: $0 \" >&2; exit 1; fi\nif [ \"$(printf '%s' \"${NP_WRITE:-true}\" | tr 'A-Z' 'a-z')\" != \"true\" ]; then\n echo \"AMP management of $(basename \"$OUT\") is disabled, leaving the existing file alone\"\n exit 0\nfi\n\nTMP=\"$OUT.amptmp\"\nmkdir -p \"$(dirname \"$OUT\")\"\n: > \"$TMP\"\n\nesc() { printf '%s' \"${1-}\" | sed -e 's/\\\\/\\\\\\\\/g' -e 's/\"/\\\\\"/g'; }\nbl() { case \"$(printf '%s' \"${1-}\" | tr 'A-Z' 'a-z')\" in true|1|yes|on) printf 'true';; *) printf 'false';; esac }\nnum() { case \"${1-}\" in ''|*[!0-9-]*) printf '%s' \"${2-0}\";; *) printf '%s' \"$1\";; esac }\ntrim() { printf '%s' \"${1-}\" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'; }\nlst() {\n local out=\"\" first=1 x\n local IFS=','\n for x in ${1-}; do\n x=\"$(trim \"$x\")\"\n [ -z \"$x\" ] && continue\n if [ $first -eq 1 ]; then first=0; else out=\"$out, \"; fi\n out=\"$out\\\"$(esc \"$x\")\\\"\"\n done\n printf '[%s]' \"$out\"\n}\nsrv() {\n local x k v\n local IFS=','\n for x in ${1-}; do\n x=\"$(trim \"$x\")\"\n [ -z \"$x\" ] && continue\n case \"$x\" in *=*) ;; *) echo \"skipping malformed servers entry '$x' (expected id=host:port)\" >&2; continue;; esac\n k=\"$(trim \"${x%%=*}\")\"; v=\"$(trim \"${x#*=}\")\"\n if [ -z \"$k\" ] || [ -z \"$v\" ]; then\n echo \"skipping malformed servers entry '$x' (expected id=host:port)\" >&2\n continue\n fi\n printf '\"%s\" = \"%s\"\\n' \"$(esc \"$k\")\" \"$(esc \"$v\")\" >> \"$TMP\"\n done\n}\nfh() {\n local x k v\n local IFS=','\n for x in ${1-}; do\n x=\"$(trim \"$x\")\"\n [ -z \"$x\" ] && continue\n case \"$x\" in *=*) ;; *) echo \"skipping malformed forced_hosts entry '$x' (expected hostname=id1|id2)\" >&2; continue;; esac\n k=\"$(trim \"${x%%=*}\")\"; v=\"$(trim \"${x#*=}\")\"\n [ -z \"$k\" ] && continue\n printf '\"%s\" = %s\\n' \"$(esc \"$k\")\" \"$(lst \"$(printf '%s' \"$v\" | tr '|' ',')\")\" >> \"$TMP\"\n done\n}\nmods() {\n local out=\"\" first=1 x k v\n local IFS=','\n for x in ${1-}; do\n x=\"$(trim \"$x\")\"\n [ -z \"$x\" ] && continue\n case \"$x\" in\n *=*) k=\"$(trim \"${x%%=*}\")\"; v=\"$(trim \"${x#*=}\")\";;\n *) k=\"$x\"; v=\"\";;\n esac\n if [ $first -eq 1 ]; then first=0; else out=\"$out, \"; fi\n out=\"$out{ id = \\\"$(esc \"$k\")\\\", version = \\\"$(esc \"$v\")\\\" }\"\n done\n printf '[%s]' \"$out\"\n}\nkeep_secret() {\n local key=\"$1\" val=\"${2:-}\" f=\"$3\" cur=\"\"\n if [ -n \"$val\" ]; then printf '%s' \"$val\"; return; fi\n if [ -f \"$f\" ]; then\n cur=\"$(sed -n \"s/^[[:space:]]*${key}[[:space:]]*=[[:space:]]*\\\"\\(.*\\)\\\".*/\\1/p\" \"$f\" | head -n 1)\"\n case \"$cur\" in\n \"\"|change-me-and-keep-secret) ;;\n *) printf '%s' \"$cur\"; return;;\n esac\n fi\n echo \"[AMP] no ${key} set, generating a random one; read it out of $(basename \"$f\") and paste it into every backend\" >&2\n head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \\n'\n}\nprintf 'bind = \"%s\"\\n' \"$(esc \"${NP_BIND:-0.0.0.0:42420}\")\" >> \"$TMP\"\nprintf 'try = %s\\n' \"$(lst \"${NP_TRY:-hub}\")\" >> \"$TMP\"\nprintf 'proxy_protocol_servers = %s\\n' \"$(lst \"${NP_PPSERVERS:-}\")\" >> \"$TMP\"\nprintf '\\n[servers]\\n' >> \"$TMP\"\nsrv \"${NP_SERVERS:-hub=127.0.0.1:42421}\"\nprintf '\\n[forced_hosts]\\n' >> \"$TMP\"\nfh \"${NP_FORCEDHOSTS:-}\"\nprintf '\\n[transfers]\\n' >> \"$TMP\"\nprintf 'default_mode = \"%s\"\\n' \"$(esc \"${NP_T_MODE:-redirect}\")\" >> \"$TMP\"\nprintf 'allow_seamless = %s\\n' \"$(bl \"${NP_T_ALLOWSEAMLESS:-false}\")\" >> \"$TMP\"\nprintf 'require_seamless_capability = %s\\n' \"$(bl \"${NP_T_REQCAP:-true}\")\" >> \"$TMP\"\nprintf 'fallback_to_redirect_when_seamless_unavailable = %s\\n' \"$(bl \"${NP_T_FALLBACK:-true}\")\" >> \"$TMP\"\nprintf 'redirect_address = \"%s\"\\n' \"$(esc \"${NP_T_REDIRECTADDR:-}\")\" >> \"$TMP\"\nprintf 'enable_unsafe_seamless_splice = %s\\n' \"$(bl \"${NP_T_SPLICE:-false}\")\" >> \"$TMP\"\nprintf '\\n[admin]\\n' >> \"$TMP\"\nprintf 'enabled = %s\\n' \"$(bl \"${NP_A_ENABLED:-true}\")\" >> \"$TMP\"\nprintf 'bind = \"%s\"\\n' \"$(esc \"${NP_A_BIND:-127.0.0.1}\")\" >> \"$TMP\"\nprintf 'secret = \"%s\"\\n' \"$(esc \"${NP_A_SECRET:-}\")\" >> \"$TMP\"\nprintf 'granted_permissions = %s\\n' \"$(lst \"${NP_A_PERMS:-*}\")\" >> \"$TMP\"\nprintf '\\n[registry]\\n' >> \"$TMP\"\nprintf 'mode = \"%s\"\\n' \"$(esc \"${NP_R_MODE:-embedded}\")\" >> \"$TMP\"\nprintf 'proxy_id = \"%s\"\\n' \"$(esc \"${NP_R_PROXYID:-nimbus-proxy}\")\" >> \"$TMP\"\nprintf 'reservation_ttl_seconds = %s\\n' \"$(num \"${NP_R_RESTTL:-60}\" 60)\" >> \"$TMP\"\nprintf 'fail_on_error = %s\\n' \"$(bl \"${NP_R_FAILONERROR:-true}\")\" >> \"$TMP\"\nprintf 'transfer_intent_poll_ms = %s\\n' \"$(num \"${NP_R_INTENTPOLL:-1000}\" 1000)\" >> \"$TMP\"\nprintf 'url = \"%s\"\\n' \"$(esc \"${NP_R_URL:-}\")\" >> \"$TMP\"\nprintf 'shared_secret = \"%s\"\\n' \"$(esc \"${NP_R_SECRET:-}\")\" >> \"$TMP\"\nprintf 'http_timeout_seconds = %s\\n' \"$(num \"${NP_R_HTTPTIMEOUT:-5}\" 5)\" >> \"$TMP\"\nif [ \"$(bl \"${NP_R_EMBHTTP:-true}\")\" = \"true\" ]; then\n printf 'embedded_bind = \"%s\"\\n' \"$(esc \"${NP_R_EMBBIND:-127.0.0.1}\")\" >> \"$TMP\"\nelse\n printf 'embedded_bind = \"\"\\n' >> \"$TMP\"\nfi\nprintf 'embedded_shared_secret = \"%s\"\\n' \"$(esc \"$(keep_secret embedded_shared_secret \"${NP_R_EMBSECRET:-}\" \"$OUT\")\")\" >> \"$TMP\"\nprintf 'backend_stale_seconds = %s\\n' \"$(num \"${NP_R_STALE:-20}\" 20)\" >> \"$TMP\"\nprintf 'backend_drop_seconds = %s\\n' \"$(num \"${NP_R_DROP:-120}\" 120)\" >> \"$TMP\"\nprintf 'nonce_window_seconds = %s\\n' \"$(num \"${NP_R_NONCE:-90}\" 90)\" >> \"$TMP\"\nprintf 'max_reservation_ttl_seconds = %s\\n' \"$(num \"${NP_R_MAXRESTTL:-300}\" 300)\" >> \"$TMP\"\nprintf 'advertise_on_master_server = %s\\n' \"$(bl \"${NP_R_ADVERTISE:-false}\")\" >> \"$TMP\"\nprintf 'embedded_state_dir = \"%s\"\\n' \"$(esc \"${NP_R_STATEDIR:-.}\")\" >> \"$TMP\"\nprintf 'api_tokens_enabled = %s\\n' \"$(bl \"${NP_R_APITOK:-false}\")\" >> \"$TMP\"\nprintf 'api_tokens_rate_limit_per_minute = %s\\n' \"$(num \"${NP_R_APIRATE:-60}\" 60)\" >> \"$TMP\"\nprintf 'api_tokens_trust_forwarded_proto = %s\\n' \"$(bl \"${NP_R_APIFWD:-false}\")\" >> \"$TMP\"\nprintf '\\n[whitelist]\\n' >> \"$TMP\"\nprintf 'network = %s\\n' \"$(bl \"${NP_W_NETWORK:-false}\")\" >> \"$TMP\"\nprintf 'servers = %s\\n' \"$(lst \"${NP_W_SERVERS:-}\")\" >> \"$TMP\"\nprintf 'fail_open_until_first_sync = %s\\n' \"$(bl \"${NP_W_FAILOPEN:-false}\")\" >> \"$TMP\"\nprintf '\\n[logging]\\n' >> \"$TMP\"\nprintf 'verbose = %s\\n' \"$(bl \"${NP_L_VERBOSE:-false}\")\" >> \"$TMP\"\nprintf 'sniff_frames = %s\\n' \"$(bl \"${NP_L_SNIFF:-false}\")\" >> \"$TMP\"\nprintf 'log_traffic_bytes = %s\\n' \"$(bl \"${NP_L_TRAFFIC:-false}\")\" >> \"$TMP\"\nprintf '\\n[metrics]\\n' >> \"$TMP\"\nprintf 'enabled = %s\\n' \"$(bl \"${NP_M_ENABLED:-true}\")\" >> \"$TMP\"\nprintf 'bind = \"%s\"\\n' \"$(esc \"${NP_M_BIND:-127.0.0.1}\")\" >> \"$TMP\"\nprintf 'path = \"%s\"\\n' \"$(esc \"${NP_M_PATH:-/metrics}\")\" >> \"$TMP\"\nprintf 'status_api = %s\\n' \"$(bl \"${NP_M_STATUSAPI:-true}\")\" >> \"$TMP\"\nprintf 'status_api_token = \"%s\"\\n' \"$(esc \"${NP_M_STATUSTOKEN:-}\")\" >> \"$TMP\"\nprintf '\\n[status]\\n' >> \"$TMP\"\nprintf 'enabled = %s\\n' \"$(bl \"${NP_S_ENABLED:-true}\")\" >> \"$TMP\"\nprintf 'name = \"%s\"\\n' \"$(esc \"${NP_S_NAME:-Nimbus}\")\" >> \"$TMP\"\nprintf 'motd = \"%s\"\\n' \"$(esc \"${NP_S_MOTD:-Vintage Story proxy}\")\" >> \"$TMP\"\nprintf 'game_mode = \"%s\"\\n' \"$(esc \"${NP_S_GAMEMODE:-survival}\")\" >> \"$TMP\"\nprintf 'password = %s\\n' \"$(bl \"${NP_S_PASSWORD:-false}\")\" >> \"$TMP\"\nprintf 'server_version = \"%s\"\\n' \"$(esc \"${NP_S_VERSION:-}\")\" >> \"$TMP\"\nprintf 'max_players = %s\\n' \"$(num \"${NP_S_MAXPLAYERS:-100}\" 100)\" >> \"$TMP\"\nprintf 'query_timeout_ms = %s\\n' \"$(num \"${NP_S_QUERYTIMEOUT:-1500}\" 1500)\" >> \"$TMP\"\nprintf '\\n[plugins]\\n' >> \"$TMP\"\nprintf 'enabled = %s\\n' \"$(bl \"${NP_P_ENABLED:-true}\")\" >> \"$TMP\"\nprintf 'directory = \"%s\"\\n' \"$(esc \"${NP_P_DIR:-plugins}\")\" >> \"$TMP\"\nprintf 'disabled = %s\\n' \"$(lst \"${NP_P_DISABLED:-}\")\" >> \"$TMP\"\nprintf '\\n[persistence]\\n' >> \"$TMP\"\nprintf 'persist_drain_flags = %s\\n' \"$(bl \"${NP_PE_DRAIN:-true}\")\" >> \"$TMP\"\nprintf 'drain_flags_file = \"%s\"\\n' \"$(esc \"${NP_PE_DRAINFILE:-nimbus.drain-state.json}\")\" >> \"$TMP\"\nprintf '\\n[advanced]\\n' >> \"$TMP\"\nprintf 'connect_timeout_ms = %s\\n' \"$(num \"${NP_AD_CONNTIMEOUT:-5000}\" 5000)\" >> \"$TMP\"\nprintf 'buffer_size = %s\\n' \"$(num \"${NP_AD_BUFSIZE:-16384}\" 16384)\" >> \"$TMP\"\nmv -f \"$TMP\" \"$OUT\"\necho \"wrote $OUT\"\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, - { - "UpdateStageName": "Write config renderer script (Windows)", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}scripts/write-proxy-toml.ps1", - "UpdateSourceData": "# Renders nimbus.proxy.toml from environment variables set by AMP.\n# Generated by the AMP Nimbus instance template; edits here are overwritten on the next update.\nparam([Parameter(Mandatory = $true)][string]$Out)\n$ErrorActionPreference = 'Stop'\n\nfunction D([string]$v, [string]$d) { if ([string]::IsNullOrWhiteSpace($v)) { return $d } return $v }\nfunction Esc([string]$s) { if ($null -eq $s) { return '' } return $s.Replace('\\', '\\\\').Replace('\"', '\\\"') }\nfunction B([string]$s) { if ($null -eq $s) { return 'false' } if (@('true', '1', 'yes', 'on') -contains $s.Trim().ToLowerInvariant()) { return 'true' } return 'false' }\nfunction I([string]$s, [int]$d) { $n = 0; if ([int]::TryParse(($s -replace '\\s', ''), [ref]$n)) { return \"$n\" } return \"$d\" }\nfunction L([string]$s) {\n $parts = @()\n foreach ($x in ($s -split ',')) { $t = $x.Trim(); if ($t -ne '') { $parts += ('\"' + (Esc $t) + '\"') } }\n return '[' + ($parts -join ', ') + ']'\n}\nfunction Pair([string]$x) {\n $i = $x.IndexOf('=')\n if ($i -lt 1) { return $null }\n return @{ Key = $x.Substring(0, $i).Trim(); Value = $x.Substring($i + 1).Trim() }\n}\nfunction SrvLines($list, [string]$s) {\n foreach ($x in ($s -split ',')) {\n $t = $x.Trim(); if ($t -eq '') { continue }\n $p = Pair $t\n if ($null -eq $p -or $p.Key -eq '' -or $p.Value -eq '') { Write-Output \"skipping malformed servers entry '$t' (expected id=host:port)\"; continue }\n $list.Add('\"' + (Esc $p.Key) + '\" = \"' + (Esc $p.Value) + '\"')\n }\n}\nfunction FhLines($list, [string]$s) {\n foreach ($x in ($s -split ',')) {\n $t = $x.Trim(); if ($t -eq '') { continue }\n $p = Pair $t\n if ($null -eq $p -or $p.Key -eq '') { Write-Output \"skipping malformed forced_hosts entry '$t' (expected hostname=id1|id2)\"; continue }\n $list.Add('\"' + (Esc $p.Key) + '\" = ' + (L ($p.Value -replace '\\|', ',')))\n }\n}\nfunction Mods([string]$s) {\n $parts = @()\n foreach ($x in ($s -split ',')) {\n $t = $x.Trim(); if ($t -eq '') { continue }\n $p = Pair $t\n if ($null -eq $p) { $parts += ('{ id = \"' + (Esc $t) + '\", version = \"\" }') }\n else { $parts += ('{ id = \"' + (Esc $p.Key) + '\", version = \"' + (Esc $p.Value) + '\" }') }\n }\n return '[' + ($parts -join ', ') + ']'\n}\nfunction KeepSecret([string]$key, [string]$val, [string]$file) {\n if (-not [string]::IsNullOrWhiteSpace($val)) { return $val }\n if (Test-Path -LiteralPath $file) {\n $pattern = '^\\s*' + [regex]::Escape($key) + '\\s*=\\s*\"(.*)\"'\n $m = Select-String -LiteralPath $file -Pattern $pattern | Select-Object -First 1\n if ($m) {\n $cur = $m.Matches[0].Groups[1].Value\n if ($cur -ne '' -and $cur -ne 'change-me-and-keep-secret') { return $cur }\n }\n }\n Write-Host (\"[AMP] no $key set, generating a random one; read it out of \" + (Split-Path -Leaf $file) + \" and paste it into every backend\")\n $bytes = New-Object byte[] 32\n $rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()\n $rng.GetBytes($bytes)\n return (($bytes | ForEach-Object { $_.ToString('x2') }) -join '')\n}\n\nif ((B (D $env:NP_WRITE 'true')) -ne 'true') {\n Write-Output (\"AMP management of \" + (Split-Path -Leaf $Out) + \" is disabled, leaving the existing file alone\")\n exit 0\n}\n\n$dir = Split-Path -Parent $Out\nif ($dir -and -not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }\n$L = New-Object System.Collections.Generic.List[string]\n$L.Add('bind = \"' + (Esc (D $env:NP_BIND '0.0.0.0:42420')) + '\"')\n$L.Add('try = ' + (L (D $env:NP_TRY 'hub')))\n$L.Add('proxy_protocol_servers = ' + (L (D $env:NP_PPSERVERS '')))\n$L.Add('')\n$L.Add('[servers]')\nSrvLines $L (D $env:NP_SERVERS 'hub=127.0.0.1:42421')\n$L.Add('')\n$L.Add('[forced_hosts]')\nFhLines $L (D $env:NP_FORCEDHOSTS '')\n$L.Add('')\n$L.Add('[transfers]')\n$L.Add('default_mode = \"' + (Esc (D $env:NP_T_MODE 'redirect')) + '\"')\n$L.Add('allow_seamless = ' + (B (D $env:NP_T_ALLOWSEAMLESS 'false')))\n$L.Add('require_seamless_capability = ' + (B (D $env:NP_T_REQCAP 'true')))\n$L.Add('fallback_to_redirect_when_seamless_unavailable = ' + (B (D $env:NP_T_FALLBACK 'true')))\n$L.Add('redirect_address = \"' + (Esc (D $env:NP_T_REDIRECTADDR '')) + '\"')\n$L.Add('enable_unsafe_seamless_splice = ' + (B (D $env:NP_T_SPLICE 'false')))\n$L.Add('')\n$L.Add('[admin]')\n$L.Add('enabled = ' + (B (D $env:NP_A_ENABLED 'true')))\n$L.Add('bind = \"' + (Esc (D $env:NP_A_BIND '127.0.0.1')) + '\"')\n$L.Add('secret = \"' + (Esc (D $env:NP_A_SECRET '')) + '\"')\n$L.Add('granted_permissions = ' + (L (D $env:NP_A_PERMS '*')))\n$L.Add('')\n$L.Add('[registry]')\n$L.Add('mode = \"' + (Esc (D $env:NP_R_MODE 'embedded')) + '\"')\n$L.Add('proxy_id = \"' + (Esc (D $env:NP_R_PROXYID 'nimbus-proxy')) + '\"')\n$L.Add('reservation_ttl_seconds = ' + (I (D $env:NP_R_RESTTL '60') 60))\n$L.Add('fail_on_error = ' + (B (D $env:NP_R_FAILONERROR 'true')))\n$L.Add('transfer_intent_poll_ms = ' + (I (D $env:NP_R_INTENTPOLL '1000') 1000))\n$L.Add('url = \"' + (Esc (D $env:NP_R_URL '')) + '\"')\n$L.Add('shared_secret = \"' + (Esc (D $env:NP_R_SECRET '')) + '\"')\n$L.Add('http_timeout_seconds = ' + (I (D $env:NP_R_HTTPTIMEOUT '5') 5))\nif ((B (D $env:NP_R_EMBHTTP 'true')) -eq 'true') {\n $L.Add('embedded_bind = \"' + (Esc (D $env:NP_R_EMBBIND '127.0.0.1')) + '\"')\n} else { $L.Add('embedded_bind = \"\"') }\n$L.Add('embedded_shared_secret = \"' + (Esc (KeepSecret 'embedded_shared_secret' $env:NP_R_EMBSECRET $Out)) + '\"')\n$L.Add('backend_stale_seconds = ' + (I (D $env:NP_R_STALE '20') 20))\n$L.Add('backend_drop_seconds = ' + (I (D $env:NP_R_DROP '120') 120))\n$L.Add('nonce_window_seconds = ' + (I (D $env:NP_R_NONCE '90') 90))\n$L.Add('max_reservation_ttl_seconds = ' + (I (D $env:NP_R_MAXRESTTL '300') 300))\n$L.Add('advertise_on_master_server = ' + (B (D $env:NP_R_ADVERTISE 'false')))\n$L.Add('embedded_state_dir = \"' + (Esc (D $env:NP_R_STATEDIR '.')) + '\"')\n$L.Add('api_tokens_enabled = ' + (B (D $env:NP_R_APITOK 'false')))\n$L.Add('api_tokens_rate_limit_per_minute = ' + (I (D $env:NP_R_APIRATE '60') 60))\n$L.Add('api_tokens_trust_forwarded_proto = ' + (B (D $env:NP_R_APIFWD 'false')))\n$L.Add('')\n$L.Add('[whitelist]')\n$L.Add('network = ' + (B (D $env:NP_W_NETWORK 'false')))\n$L.Add('servers = ' + (L (D $env:NP_W_SERVERS '')))\n$L.Add('fail_open_until_first_sync = ' + (B (D $env:NP_W_FAILOPEN 'false')))\n$L.Add('')\n$L.Add('[logging]')\n$L.Add('verbose = ' + (B (D $env:NP_L_VERBOSE 'false')))\n$L.Add('sniff_frames = ' + (B (D $env:NP_L_SNIFF 'false')))\n$L.Add('log_traffic_bytes = ' + (B (D $env:NP_L_TRAFFIC 'false')))\n$L.Add('')\n$L.Add('[metrics]')\n$L.Add('enabled = ' + (B (D $env:NP_M_ENABLED 'true')))\n$L.Add('bind = \"' + (Esc (D $env:NP_M_BIND '127.0.0.1')) + '\"')\n$L.Add('path = \"' + (Esc (D $env:NP_M_PATH '/metrics')) + '\"')\n$L.Add('status_api = ' + (B (D $env:NP_M_STATUSAPI 'true')))\n$L.Add('status_api_token = \"' + (Esc (D $env:NP_M_STATUSTOKEN '')) + '\"')\n$L.Add('')\n$L.Add('[status]')\n$L.Add('enabled = ' + (B (D $env:NP_S_ENABLED 'true')))\n$L.Add('name = \"' + (Esc (D $env:NP_S_NAME 'Nimbus')) + '\"')\n$L.Add('motd = \"' + (Esc (D $env:NP_S_MOTD 'Vintage Story proxy')) + '\"')\n$L.Add('game_mode = \"' + (Esc (D $env:NP_S_GAMEMODE 'survival')) + '\"')\n$L.Add('password = ' + (B (D $env:NP_S_PASSWORD 'false')))\n$L.Add('server_version = \"' + (Esc (D $env:NP_S_VERSION '')) + '\"')\n$L.Add('max_players = ' + (I (D $env:NP_S_MAXPLAYERS '100') 100))\n$L.Add('query_timeout_ms = ' + (I (D $env:NP_S_QUERYTIMEOUT '1500') 1500))\n$L.Add('')\n$L.Add('[plugins]')\n$L.Add('enabled = ' + (B (D $env:NP_P_ENABLED 'true')))\n$L.Add('directory = \"' + (Esc (D $env:NP_P_DIR 'plugins')) + '\"')\n$L.Add('disabled = ' + (L (D $env:NP_P_DISABLED '')))\n$L.Add('')\n$L.Add('[persistence]')\n$L.Add('persist_drain_flags = ' + (B (D $env:NP_PE_DRAIN 'true')))\n$L.Add('drain_flags_file = \"' + (Esc (D $env:NP_PE_DRAINFILE 'nimbus.drain-state.json')) + '\"')\n$L.Add('')\n$L.Add('[advanced]')\n$L.Add('connect_timeout_ms = ' + (I (D $env:NP_AD_CONNTIMEOUT '5000') 5000))\n$L.Add('buffer_size = ' + (I (D $env:NP_AD_BUFSIZE '16384') 16384))\n$tmp = \"$Out.amptmp\"\nSet-Content -LiteralPath $tmp -Value $L -Encoding UTF8\nMove-Item -LiteralPath $tmp -Destination $Out -Force\nWrite-Output \"wrote $Out\"\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, - { - "UpdateStageName": ".NET SDK Download", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "Executable", - "UpdateSourceArch": "x86_64", - "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"DotnetVersion=\\\"{{DotnetSDKVersion}}\\\"; cd \\\"{{$FullBaseDir}}\\\" && if [[ -x dotnet/dotnet ]]; then InstalledVersion=$(dotnet/dotnet --version | xargs); else InstalledVersion=\\\"\\\"; fi; if [[ -z \\\"$DotnetVersion\\\" ]]; then DotnetVersion=$(wget -qO- https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json | jq -r \\\".[\\\\\\\"latest-sdk\\\\\\\"]\\\"); fi; if [[ ! \\\"$DotnetVersion\\\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+$ ]]; then echo \\\"Invalid .NET SDK version format specified\\\" && exit 1; elif [[ \\\"$InstalledVersion\\\" == \\\"$DotnetVersion\\\" ]]; then echo \\\".NET SDK v$DotnetVersion already installed. Skipping\\\" && exit 0; else [[ -f dotnet.tar.gz ]] && rm -f dotnet.tar.gz >/dev/null 2>&1; wget -qO dotnet.tar.gz https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-linux-x64.tar.gz || { echo \\\"Download failed from the Microsoft CDN. This is a fault with the CDN, not AMP. Aborting\\\"; exit 1; }; rm -rf dotnet/* >/dev/null 2>&1 && tar -xzf dotnet.tar.gz -C dotnet >/dev/null 2>&1 && rm -f dotnet.tar.gz >/dev/null 2>&1 && echo \\\".NET SDK v$DotnetVersion downloaded\\\"; fi\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": ".NET SDK Download", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "Executable", - "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -Command \"$ProgressPreference='SilentlyContinue'; [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $DotnetVersion='{{DotnetSDKVersion}}'; Set-Location -Path '{{$FullBaseDir}}'; if (Test-Path 'dotnet/dotnet.exe') { $InstalledVersion = (& dotnet/dotnet.exe --version).Trim() } else { $InstalledVersion = '' }; if ( [string]::IsNullOrWhiteSpace($DotnetVersion) ) { $DotnetVersion=(Invoke-RestMethod -UseBasicParsing -Uri https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json).\\\"latest-sdk\\\" }; if ($DotnetVersion -notmatch '^\\d+\\.\\d+\\.\\d+$') { Write-Output \\\"Invalid .NET SDK version format specified\\\"; exit 1 } elseif ( $InstalledVersion -eq $DotnetVersion ) { Write-Output \\\".NET SDK v$DotnetVersion already installed. Skipping\\\"; exit 0 } else { if ( Test-Path dotnet.zip ) { Remove-Item dotnet.zip -Force -ErrorAction SilentlyContinue *> $null }; try { Invoke-WebRequest -UseBasicParsing -Uri https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-win-x64.zip -OutFile dotnet.zip -ErrorAction Stop } catch { Write-Output \\\"Download failed from the Microsoft CDN. This is a fault with the CDN, not AMP. Aborting\\\"; exit 1; }; Remove-Item -Path 'dotnet/*' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive -Path \\\"dotnet.zip\\\" -DestinationPath \\\"dotnet\\\" -Force *> $null; if ( Test-Path dotnet.zip ) { Remove-Item dotnet.zip -Force -ErrorAction SilentlyContinue *> $null }; Write-Output \\\".NET SDK v$DotnetVersion downloaded\\\" }\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Nimbus Download", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "Executable", - "UpdateSourceArch": "x86_64", - "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"NIMBUS_TAG='{{NimbusVersionTag}}' NIMBUS_CHANNEL='{{NimbusReleaseChannel}}' GITHUB_TOKEN='{{NimbusGitHubToken}}' bash '{{$FullRootDir}}scripts/install-nimbus.sh' '{{$FullRootDir}}' '{{NimbusUpdateComponents}}'\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Nimbus Download", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "Executable", - "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$env:NIMBUS_TAG='{{NimbusVersionTag}}'; $env:NIMBUS_CHANNEL='{{NimbusReleaseChannel}}'; $env:GITHUB_TOKEN='{{NimbusGitHubToken}}'; & '{{$FullRootDir}}scripts\\install-nimbus.ps1' '{{$FullRootDir}}' '{{NimbusUpdateComponents}}'\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Render nimbus.proxy.toml", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "Executable", - "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"NP_WRITE='{{ProxyWriteConfig}}' NP_BIND='{{ProxyBindHost}}:{{$ServerPort}}' NP_SERVERS='{{ProxyServers}}' NP_TRY='{{ProxyTryList}}' NP_PPSERVERS='{{ProxyProtocolServers}}' NP_FORCEDHOSTS='{{ProxyForcedHosts}}' NP_T_MODE='{{ProxyTransfersDefaultMode}}' NP_T_ALLOWSEAMLESS='{{ProxyTransfersAllowSeamless}}' NP_T_REQCAP='{{ProxyTransfersRequireSeamlessCapability}}' NP_T_FALLBACK='{{ProxyTransfersFallbackToRedirect}}' NP_T_REDIRECTADDR='{{ProxyTransfersRedirectAddress}}' NP_T_SPLICE='{{ProxyTransfersEnableUnsafeSplice}}' NP_A_ENABLED='{{ProxyAdminEnabled}}' NP_A_BIND='{{ProxyAdminBindHost}}:{{$AdminPort}}' NP_A_SECRET='{{ProxyAdminSecret}}' NP_A_PERMS='{{ProxyAdminGrantedPermissions}}' NP_R_MODE='{{ProxyRegistryMode}}' NP_R_PROXYID='{{ProxyRegistryProxyId}}' NP_R_RESTTL='{{ProxyRegistryReservationTtlSeconds}}' NP_R_FAILONERROR='{{ProxyRegistryFailOnError}}' NP_R_INTENTPOLL='{{ProxyRegistryTransferIntentPollMs}}' NP_R_URL='{{ProxyRegistryUrl}}' NP_R_SECRET='{{ProxyRegistrySharedSecret}}' NP_R_HTTPTIMEOUT='{{ProxyRegistryHttpTimeoutSeconds}}' NP_R_EMBBIND='http://{{ProxyRegistryEmbeddedBindHost}}:{{$RegistryPort}}' NP_R_EMBHTTP='{{ProxyRegistryEmbeddedHttpEnabled}}' NP_R_EMBSECRET='{{ProxyRegistryEmbeddedSharedSecret}}' NP_R_STALE='{{ProxyRegistryBackendStaleSeconds}}' NP_R_DROP='{{ProxyRegistryBackendDropSeconds}}' NP_R_NONCE='{{ProxyRegistryNonceWindowSeconds}}' NP_R_MAXRESTTL='{{ProxyRegistryMaxReservationTtlSeconds}}' NP_R_ADVERTISE='{{ProxyRegistryAdvertiseOnMasterServer}}' NP_R_STATEDIR='{{ProxyRegistryEmbeddedStateDir}}' NP_R_APITOK='{{ProxyRegistryApiTokensEnabled}}' NP_R_APIRATE='{{ProxyRegistryApiTokensRateLimitPerMinute}}' NP_R_APIFWD='{{ProxyRegistryApiTokensTrustForwardedProto}}' NP_W_NETWORK='{{ProxyWhitelistNetwork}}' NP_W_SERVERS='{{ProxyWhitelistServers}}' NP_W_FAILOPEN='{{ProxyWhitelistFailOpenUntilFirstSync}}' NP_L_VERBOSE='{{ProxyLoggingVerbose}}' NP_L_SNIFF='{{ProxyLoggingSniffFrames}}' NP_L_TRAFFIC='{{ProxyLoggingLogTrafficBytes}}' NP_M_ENABLED='{{ProxyMetricsEnabled}}' NP_M_BIND='http://{{ProxyMetricsBindHost}}:{{$MetricsPort}}' NP_M_PATH='{{ProxyMetricsPath}}' NP_M_STATUSAPI='{{ProxyMetricsStatusApi}}' NP_M_STATUSTOKEN='{{ProxyMetricsStatusApiToken}}' NP_S_ENABLED='{{ProxyStatusEnabled}}' NP_S_NAME='{{ProxyStatusName}}' NP_S_MOTD='{{ProxyStatusMotd}}' NP_S_GAMEMODE='{{ProxyStatusGameMode}}' NP_S_PASSWORD='{{ProxyStatusPassword}}' NP_S_VERSION='{{ProxyStatusServerVersion}}' NP_S_MAXPLAYERS='{{$MaxUsers}}' NP_S_QUERYTIMEOUT='{{ProxyStatusQueryTimeoutMs}}' NP_P_ENABLED='{{ProxyPluginsEnabled}}' NP_P_DIR='{{ProxyPluginsDirectory}}' NP_P_DISABLED='{{ProxyPluginsDisabled}}' NP_PE_DRAIN='{{ProxyPersistDrainFlags}}' NP_PE_DRAINFILE='{{ProxyDrainFlagsFile}}' NP_AD_CONNTIMEOUT='{{ProxyConnectTimeoutMs}}' NP_AD_BUFSIZE='{{ProxyBufferSize}}' bash '{{$FullRootDir}}scripts/write-proxy-toml.sh' '{{$FullRootDir}}Nimbus/nimbus.proxy.toml'\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Render nimbus.proxy.toml", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "Executable", - "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$env:NP_WRITE='{{ProxyWriteConfig}}'; $env:NP_BIND='{{ProxyBindHost}}:{{$ServerPort}}'; $env:NP_SERVERS='{{ProxyServers}}'; $env:NP_TRY='{{ProxyTryList}}'; $env:NP_PPSERVERS='{{ProxyProtocolServers}}'; $env:NP_FORCEDHOSTS='{{ProxyForcedHosts}}'; $env:NP_T_MODE='{{ProxyTransfersDefaultMode}}'; $env:NP_T_ALLOWSEAMLESS='{{ProxyTransfersAllowSeamless}}'; $env:NP_T_REQCAP='{{ProxyTransfersRequireSeamlessCapability}}'; $env:NP_T_FALLBACK='{{ProxyTransfersFallbackToRedirect}}'; $env:NP_T_REDIRECTADDR='{{ProxyTransfersRedirectAddress}}'; $env:NP_T_SPLICE='{{ProxyTransfersEnableUnsafeSplice}}'; $env:NP_A_ENABLED='{{ProxyAdminEnabled}}'; $env:NP_A_BIND='{{ProxyAdminBindHost}}:{{$AdminPort}}'; $env:NP_A_SECRET='{{ProxyAdminSecret}}'; $env:NP_A_PERMS='{{ProxyAdminGrantedPermissions}}'; $env:NP_R_MODE='{{ProxyRegistryMode}}'; $env:NP_R_PROXYID='{{ProxyRegistryProxyId}}'; $env:NP_R_RESTTL='{{ProxyRegistryReservationTtlSeconds}}'; $env:NP_R_FAILONERROR='{{ProxyRegistryFailOnError}}'; $env:NP_R_INTENTPOLL='{{ProxyRegistryTransferIntentPollMs}}'; $env:NP_R_URL='{{ProxyRegistryUrl}}'; $env:NP_R_SECRET='{{ProxyRegistrySharedSecret}}'; $env:NP_R_HTTPTIMEOUT='{{ProxyRegistryHttpTimeoutSeconds}}'; $env:NP_R_EMBBIND='http://{{ProxyRegistryEmbeddedBindHost}}:{{$RegistryPort}}'; $env:NP_R_EMBHTTP='{{ProxyRegistryEmbeddedHttpEnabled}}'; $env:NP_R_EMBSECRET='{{ProxyRegistryEmbeddedSharedSecret}}'; $env:NP_R_STALE='{{ProxyRegistryBackendStaleSeconds}}'; $env:NP_R_DROP='{{ProxyRegistryBackendDropSeconds}}'; $env:NP_R_NONCE='{{ProxyRegistryNonceWindowSeconds}}'; $env:NP_R_MAXRESTTL='{{ProxyRegistryMaxReservationTtlSeconds}}'; $env:NP_R_ADVERTISE='{{ProxyRegistryAdvertiseOnMasterServer}}'; $env:NP_R_STATEDIR='{{ProxyRegistryEmbeddedStateDir}}'; $env:NP_R_APITOK='{{ProxyRegistryApiTokensEnabled}}'; $env:NP_R_APIRATE='{{ProxyRegistryApiTokensRateLimitPerMinute}}'; $env:NP_R_APIFWD='{{ProxyRegistryApiTokensTrustForwardedProto}}'; $env:NP_W_NETWORK='{{ProxyWhitelistNetwork}}'; $env:NP_W_SERVERS='{{ProxyWhitelistServers}}'; $env:NP_W_FAILOPEN='{{ProxyWhitelistFailOpenUntilFirstSync}}'; $env:NP_L_VERBOSE='{{ProxyLoggingVerbose}}'; $env:NP_L_SNIFF='{{ProxyLoggingSniffFrames}}'; $env:NP_L_TRAFFIC='{{ProxyLoggingLogTrafficBytes}}'; $env:NP_M_ENABLED='{{ProxyMetricsEnabled}}'; $env:NP_M_BIND='http://{{ProxyMetricsBindHost}}:{{$MetricsPort}}'; $env:NP_M_PATH='{{ProxyMetricsPath}}'; $env:NP_M_STATUSAPI='{{ProxyMetricsStatusApi}}'; $env:NP_M_STATUSTOKEN='{{ProxyMetricsStatusApiToken}}'; $env:NP_S_ENABLED='{{ProxyStatusEnabled}}'; $env:NP_S_NAME='{{ProxyStatusName}}'; $env:NP_S_MOTD='{{ProxyStatusMotd}}'; $env:NP_S_GAMEMODE='{{ProxyStatusGameMode}}'; $env:NP_S_PASSWORD='{{ProxyStatusPassword}}'; $env:NP_S_VERSION='{{ProxyStatusServerVersion}}'; $env:NP_S_MAXPLAYERS='{{$MaxUsers}}'; $env:NP_S_QUERYTIMEOUT='{{ProxyStatusQueryTimeoutMs}}'; $env:NP_P_ENABLED='{{ProxyPluginsEnabled}}'; $env:NP_P_DIR='{{ProxyPluginsDirectory}}'; $env:NP_P_DISABLED='{{ProxyPluginsDisabled}}'; $env:NP_PE_DRAIN='{{ProxyPersistDrainFlags}}'; $env:NP_PE_DRAINFILE='{{ProxyDrainFlagsFile}}'; $env:NP_AD_CONNTIMEOUT='{{ProxyConnectTimeoutMs}}'; $env:NP_AD_BUFSIZE='{{ProxyBufferSize}}';& '{{$FullRootDir}}scripts\\write-proxy-toml.ps1' '{{$FullRootDir}}Nimbus\\nimbus.proxy.toml'\"", - "SkipOnFailure": false - } -] +[ + { + "UpdateStageName": "Create dotnet directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}dotnet", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create Nimbus directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}Nimbus", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create scripts directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}scripts", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Install local .NET 10 runtime", + "UpdateSourcePlatform": "Linux", + "UpdateSourceArch": "x86_64", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"set -euo pipefail; root=\u0027{{$FullRootDir}}\u0027; if [ -x \\\"$root/dotnet/dotnet\\\" ] \u0026\u0026 \\\"$root/dotnet/dotnet\\\" --list-runtimes | grep -q \u0027^Microsoft.NETCore.App 10\\.\u0027; then echo \u0027[AMP] .NET 10 runtime already installed\u0027; else tmp=\\\"$(mktemp)\\\"; curl -fsSL https://dot.net/v1/dotnet-install.sh -o \\\"$tmp\\\"; bash \\\"$tmp\\\" --channel 10.0 --runtime dotnet --install-dir \\\"$root/dotnet\\\" --no-path; rm -f \\\"$tmp\\\"; fi\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Install local .NET 10 runtime", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference=\u0027Stop\u0027; $root=\u0027{{$FullRootDir}}\u0027; $dotnet=Join-Path $root \u0027dotnet\\dotnet.exe\u0027; $ready=$false; if (Test-Path -LiteralPath $dotnet) { $ready=[bool]((\u0026 $dotnet --list-runtimes) -match \u0027^Microsoft.NETCore.App 10\\.\u0027) }; if ($ready) { Write-Output \u0027[AMP] .NET 10 runtime already installed\u0027 } else { $script=Join-Path $env:TEMP (\u0027dotnet-install-\u0027+[guid]::NewGuid().ToString(\u0027N\u0027)+\u0027.ps1\u0027); try { Invoke-WebRequest -UseBasicParsing -Uri https://dot.net/v1/dotnet-install.ps1 -OutFile $script; \u0026 $script -Channel 10.0 -Runtime dotnet -InstallDir (Join-Path $root \u0027dotnet\u0027) -NoPath } finally { Remove-Item -LiteralPath $script -Force -ErrorAction SilentlyContinue } }\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Install Nimbus Proxy", + "UpdateSourcePlatform": "Linux", + "UpdateSourceArch": "x86_64", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"set -euo pipefail; root=\u0027{{$FullRootDir}}\u0027; tag=\u0027{{NimbusVersionTag}}\u0027; if [ -z \\\"$tag\\\" ]; then tag=\\\"$(curl -fsSL -H \u0027User-Agent: AMP-Clean-Template\u0027 https://api.github.com/repos/StratumServer/Nimbus/releases/latest | jq -r .tag_name)\\\"; fi; case \\\"$tag\\\" in v*) ;; *) tag=\\\"v$tag\\\";; esac; stage=\\\"$root/.amp-nimbus-stage\\\"; archive=\\\"$root/.amp-nimbus.zip\\\"; old=\\\"$root/.amp-nimbus-old\\\"; rm -rf \\\"$stage\\\" \\\"$old\\\"; mkdir -p \\\"$stage\\\"; curl -fL --retry 3 -o \\\"$archive\\\" \\\"https://github.com/StratumServer/Nimbus/releases/download/$tag/Nimbus-$tag.zip\\\"; unzip -q \\\"$archive\\\" -d \\\"$stage\\\"; rm -f \\\"$archive\\\"; fresh_dll=\\\"$(find \\\"$stage\\\" -type f -name Nimbus.Proxy.dll -print -quit)\\\"; [ -n \\\"$fresh_dll\\\" ]; fresh=\\\"$(dirname \\\"$fresh_dll\\\")\\\"; if [ -d \\\"$root/Nimbus/plugins\\\" ]; then rm -rf \\\"$fresh/plugins\\\"; cp -a \\\"$root/Nimbus/plugins\\\" \\\"$fresh/plugins\\\"; fi; if [ -f \\\"$root/Nimbus/nimbus.proxy.toml\\\" ]; then cp \\\"$root/Nimbus/nimbus.proxy.toml\\\" \\\"$fresh/nimbus.proxy.toml\\\"; fi; if [ -d \\\"$root/Nimbus\\\" ]; then mv \\\"$root/Nimbus\\\" \\\"$old\\\"; fi; mv \\\"$fresh\\\" \\\"$root/Nimbus\\\"; rm -rf \\\"$stage\\\" \\\"$old\\\"; printf \u0027%s\u0027 \\\"$tag\\\" \u003e \\\"$root/Nimbus/.amp-nimbus-release\\\"\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Install Nimbus Proxy", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference=\u0027Stop\u0027; $ProgressPreference=\u0027SilentlyContinue\u0027; $root=\u0027{{$FullRootDir}}\u0027; $tag=\u0027{{NimbusVersionTag}}\u0027.Trim(); $headers=@{\u0027User-Agent\u0027=\u0027AMP-Clean-Template\u0027}; if (-not $tag) { $tag=(Invoke-RestMethod -Headers $headers -Uri https://api.github.com/repos/StratumServer/Nimbus/releases/latest).tag_name }; if (-not $tag.StartsWith(\u0027v\u0027)) { $tag=\u0027v\u0027+$tag }; $stage=Join-Path $root \u0027.amp-nimbus-stage\u0027; $archive=Join-Path $root \u0027.amp-nimbus.zip\u0027; $target=Join-Path $root \u0027Nimbus\u0027; $old=Join-Path $root \u0027.amp-nimbus-old\u0027; Remove-Item -LiteralPath $stage,$old,$archive -Recurse -Force -ErrorAction SilentlyContinue; New-Item -ItemType Directory -Path $stage | Out-Null; Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri (\u0027https://github.com/StratumServer/Nimbus/releases/download/\u0027+$tag+\u0027/Nimbus-\u0027+$tag+\u0027.zip\u0027) -OutFile $archive; Expand-Archive -LiteralPath $archive -DestinationPath $stage -Force; Remove-Item -LiteralPath $archive -Force; $freshDll=Get-ChildItem -LiteralPath $stage -Filter \u0027Nimbus.Proxy.dll\u0027 -File -Recurse | Select-Object -First 1; if ($null -eq $freshDll) { throw \u0027Nimbus archive did not contain Nimbus.Proxy.dll\u0027 }; $fresh=$freshDll.Directory.FullName; if (Test-Path -LiteralPath (Join-Path $target \u0027plugins\u0027)) { Copy-Item -LiteralPath (Join-Path $target \u0027plugins\u0027) -Destination (Join-Path $fresh \u0027plugins\u0027) -Recurse -Force }; if (Test-Path -LiteralPath (Join-Path $target \u0027nimbus.proxy.toml\u0027)) { Copy-Item -LiteralPath (Join-Path $target \u0027nimbus.proxy.toml\u0027) -Destination (Join-Path $fresh \u0027nimbus.proxy.toml\u0027) -Force }; if (Test-Path -LiteralPath $target) { Move-Item -LiteralPath $target -Destination $old }; try { Move-Item -LiteralPath $fresh -Destination $target; Remove-Item -LiteralPath $stage,$old -Recurse -Force -ErrorAction SilentlyContinue } catch { if ((Test-Path -LiteralPath $old) -and -not (Test-Path -LiteralPath $target)) { Move-Item -LiteralPath $old -Destination $target }; throw }; [IO.File]::WriteAllText((Join-Path $target \u0027.amp-nimbus-release\u0027),$tag,(New-Object Text.UTF8Encoding $false))\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Deploy Proxy renderer (Linux)", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/write-proxy-toml.sh", + "UpdateSourceData": "#!/usr/bin/env bash\nset -euo pipefail\n\ntarget=\"${1:?target path required}\"\n\nTomlQuote() {\n local value=\"${1-}\"\n value=${value//\\/\\\\}\n value=${value//\\\"/\\\\\\\"}\n value=${value//$\u0027\\r\u0027/\\\\r}\n value=${value//$\u0027\\n\u0027/\\\\n}\n value=${value//$\u0027\\t\u0027/\\\\t}\n printf \u0027\"%s\"\u0027 \"$value\"\n}\n\nParseBackendMap() {\n BACKEND_LINES=\"\"\n BACKEND_IDS=\"\"\n local raw entry id endpoint host port\n IFS=\u0027;\u0027 read -ra entries \u003c\u003c\u003c \"${NP_SERVERS:-hub=127.0.0.1:42421}\"\n for raw in \"${entries[@]}\"; do\n entry=\"$(printf \u0027%s\u0027 \"$raw\" | sed \u0027s/^[[:space:]]*//;s/[[:space:]]*$//\u0027)\"\n [ -z \"$entry\" ] \u0026\u0026 continue\n [[ \"$entry\" == *=* ]] || { echo \"Malformed backend entry \u0027$entry\u0027; expected id=host:port\" \u003e\u00262; return 1; }\n id=\"${entry%%=*}\"; endpoint=\"${entry#*=}\"\n id=\"$(printf \u0027%s\u0027 \"$id\" | sed \u0027s/^[[:space:]]*//;s/[[:space:]]*$//\u0027)\"\n endpoint=\"$(printf \u0027%s\u0027 \"$endpoint\" | sed \u0027s/^[[:space:]]*//;s/[[:space:]]*$//\u0027)\"\n [[ \"$id\" =~ ^[A-Za-z0-9][A-Za-z0-9_.-]*$ ]] || { echo \"Invalid backend ID \u0027$id\u0027\" \u003e\u00262; return 1; }\n case \",$BACKEND_IDS,\" in *\",$id,\"*) echo \"Duplicate backend ID \u0027$id\u0027\" \u003e\u00262; return 1;; esac\n if [[ \"$endpoint\" =~ ^(\\[[^]]+\\]|[^:[:space:]]+):([0-9]+)$ ]]; then port=\"${BASH_REMATCH[2]}\"; else echo \"Invalid backend endpoint \u0027$endpoint\u0027\" \u003e\u00262; return 1; fi\n (( port \u003e= 1 \u0026\u0026 port \u003c= 65535 )) || { echo \"Backend port is outside 1-65535 in \u0027$endpoint\u0027\" \u003e\u00262; return 1; }\n BACKEND_IDS=\"${BACKEND_IDS:+$BACKEND_IDS,}$id\"\n BACKEND_LINES+=\"$(TomlQuote \"$id\") = $(TomlQuote \"$endpoint\")\"$\u0027\\n\u0027\n done\n [ -n \"$BACKEND_IDS\" ] || { echo \u0027At least one backend is required\u0027 \u003e\u00262; return 1; }\n}\n\nParseIdList() {\n local value=\"$1\" allow_empty=\"$2\" result=\"\" raw id\n IFS=\u0027,\u0027 read -ra ids \u003c\u003c\u003c \"$value\"\n for raw in \"${ids[@]}\"; do\n id=\"$(printf \u0027%s\u0027 \"$raw\" | sed \u0027s/^[[:space:]]*//;s/[[:space:]]*$//\u0027)\"\n [ -z \"$id\" ] \u0026\u0026 continue\n case \",$BACKEND_IDS,\" in *\",$id,\"*) ;; *) echo \"Unknown backend ID \u0027$id\u0027\" \u003e\u00262; return 1;; esac\n case \",$result,\" in *\",$id,\"*) ;; *) result=\"${result:+$result,}$id\";; esac\n done\n if [ \"$allow_empty\" != true ] \u0026\u0026 [ -z \"$result\" ]; then echo \u0027At least one backend ID is required\u0027 \u003e\u00262; return 1; fi\n printf \u0027%s\u0027 \"$result\"\n}\n\nReadExistingSecret() {\n local path=\"$1\" mode=\"$2\" key\n [ \"$mode\" = embedded ] \u0026\u0026 key=embedded_shared_secret || key=shared_secret\n [ -f \"$path\" ] || return 0\n sed -n \"s/^[[:space:]]*${key}[[:space:]]*=[[:space:]]*\\\"\\([0-9A-Fa-f]*\\)\\\"[[:space:]]*$/\\1/p\" \"$path\" | head -n 1\n}\n\nNewRandomSecret() { od -An -N32 -tx1 /dev/urandom | tr -d \u0027 \\n\u0027; }\n\nResolveSecret() {\n local panel=\"$1\" existing=\"$2\" mode=\"$3\" lower\n panel=\"$(printf \u0027%s\u0027 \"$panel\" | sed \u0027s/^[[:space:]]*//;s/[[:space:]]*$//\u0027)\"\n lower=\"$(printf \u0027%s\u0027 \"$panel\" | tr \u0027[:upper:]\u0027 \u0027[:lower:]\u0027)\"\n case \"$lower\" in change-me*|paste*secret*|shared-secret|shared_secret|\"shared secret\"|your-secret|your_secret|\"your secret\"|replace-me*) echo \u0027The shared secret is a documented placeholder, not a usable secret\u0027 \u003e\u00262; return 1;; esac\n if [ -n \"$panel\" ]; then printf \u0027%s\u0027 \"$panel\"; elif [ -n \"$existing\" ]; then printf \u0027%s\u0027 \"$existing\"; elif [ \"$mode\" = embedded ]; then NewRandomSecret; else echo \u0027Remote Registry mode requires an explicit or previously saved shared secret\u0027 \u003e\u00262; return 1; fi\n}\n\nParsePort() { local value=\"$1\" name=\"$2\"; [[ \"$value\" =~ ^[0-9]+$ ]] \u0026\u0026 (( value \u003e= 1 \u0026\u0026 value \u003c= 65535 )) || { echo \"$name must be from 1 through 65535\" \u003e\u00262; return 1; }; printf \u0027%s\u0027 \"$value\"; }\nParseBool() { local value=\"${1,,}\" name=\"$2\"; case \"$value\" in true|false) printf \u0027%s\u0027 \"$value\";; *) echo \"$name must be true or false\" \u003e\u00262; return 1;; esac; }\nTomlArray() { local value=\"$1\" result=\"\" raw; IFS=\u0027,\u0027 read -ra values \u003c\u003c\u003c \"$value\"; for raw in \"${values[@]}\"; do [ -z \"$raw\" ] \u0026\u0026 continue; result=\"${result:+$result, }$(TomlQuote \"$raw\")\"; done; printf \u0027[%s]\u0027 \"$result\"; }\n\nWriteAtomic() {\n local path=\"$1\" content=\"$2\" directory temporary\n directory=\"$(dirname \"$path\")\"; mkdir -p \"$directory\"\n temporary=\"$directory/.$(basename \"$path\").$$.$RANDOM.tmp\"\n trap \u0027rm -f \"$temporary\"\u0027 RETURN\n printf \u0027%s\u0027 \"$content\" \u003e \"$temporary\"\n mv -f \"$temporary\" \"$path\"\n trap - RETURN\n}\n\nParseBackendMap\ntry_ids=\"$(ParseIdList \"${NP_TRY:-hub}\" false)\"\nwhitelist_ids=\"$(ParseIdList \"${NP_WHITELIST_SERVERS:-}\" true)\"\nmode=\"${NP_REGISTRY_MODE:-embedded}\"; mode=\"${mode,,}\"\n[[ \"$mode\" = embedded || \"$mode\" = remote ]] || { echo \u0027Registry mode must be embedded or remote\u0027 \u003e\u00262; exit 1; }\naccess=\"${NP_REGISTRY_ACCESS:-same-host}\"; access=\"${access,,}\"\n[[ \"$access\" = same-host || \"$access\" = other-hosts ]] || { echo \u0027Registry access must be same-host or other-hosts\u0027 \u003e\u00262; exit 1; }\nregistry_url=\"${NP_REGISTRY_URL:-}\"\nif [ \"$mode\" = remote ] \u0026\u0026 [[ ! \"$registry_url\" =~ ^https?://[^[:space:]]+$ ]]; then echo \u0027Remote Registry mode requires an HTTP or HTTPS URL\u0027 \u003e\u00262; exit 1; fi\nexisting=\"$(ReadExistingSecret \"$target\" \"$mode\")\"\nsecret=\"$(ResolveSecret \"${NP_SHARED_SECRET:-}\" \"$existing\" \"$mode\")\"\nserver_port=\"$(ParsePort \"${NP_SERVER_PORT:-42420}\" \u0027Server port\u0027)\"\nregistry_port=\"$(ParsePort \"${NP_REGISTRY_PORT:-8765}\" \u0027Registry port\u0027)\"\nadmin_port=\"$(ParsePort \"${NP_ADMIN_PORT:-42499}\" \u0027Admin port\u0027)\"\nmetrics_port=\"$(ParsePort \"${NP_METRICS_PORT:-42500}\" \u0027Metrics port\u0027)\"\nmax_users=\"$(ParsePort \"${NP_MAX_USERS:-100}\" \u0027Player limit\u0027)\"\nwhitelist=\"$(ParseBool \"${NP_WHITELIST_NETWORK:-false}\" \u0027Network whitelist\u0027)\"\nverbose=\"$(ParseBool \"${NP_VERBOSE:-false}\" \u0027Verbose logging\u0027)\"\n[ \"$access\" = same-host ] \u0026\u0026 embedded_host=127.0.0.1 || embedded_host=0.0.0.0\nif [ \"$mode\" = embedded ]; then remote_secret=\"\"; embedded_secret=\"$secret\"; embedded_bind=\"http://${embedded_host}:${registry_port}\"; registry_url=\"\"; else remote_secret=\"$secret\"; embedded_secret=\"\"; embedded_bind=\"\"; fi\n\ncontent=\"bind = $(TomlQuote \"${NP_BIND_ADDRESS:-0.0.0.0}:${server_port}\")\ntry = $(TomlArray \"$try_ids\")\n\n[servers]\n${BACKEND_LINES}\n[transfers]\ndefault_mode = \\\"redirect\\\"\nallow_seamless = false\nrequire_seamless_capability = true\nfallback_to_redirect_when_seamless_unavailable = true\nenable_unsafe_seamless_splice = false\n\n[admin]\nbind = $(TomlQuote \"127.0.0.1:${admin_port}\")\nsecret = \\\"\\\"\nenabled = true\ngranted_permissions = [\\\"*\\\"]\n\n[registry]\nmode = $(TomlQuote \"$mode\")\nproxy_id = $(TomlQuote \"${NP_PROXY_ID:-nimbus-proxy}\")\nurl = $(TomlQuote \"$registry_url\")\nshared_secret = $(TomlQuote \"$remote_secret\")\nembedded_bind = $(TomlQuote \"$embedded_bind\")\nembedded_shared_secret = $(TomlQuote \"$embedded_secret\")\nbackend_stale_seconds = 20\nbackend_drop_seconds = 120\nnonce_window_seconds = 90\nmax_reservation_ttl_seconds = 300\nfail_on_error = true\ntransfer_intent_poll_ms = 1000\nadvertise_on_master_server = false\n\n[whitelist]\nnetwork = ${whitelist}\nservers = $(TomlArray \"$whitelist_ids\")\nfail_open_until_first_sync = false\n\n[logging]\nverbose = ${verbose}\nsniff_frames = false\nlog_traffic_bytes = false\n\n[metrics]\nenabled = true\nbind = $(TomlQuote \"http://127.0.0.1:${metrics_port}\")\npath = \\\"/metrics\\\"\nstatus_api = true\nstatus_api_token = \\\"\\\"\n\n[status]\nenabled = true\nname = $(TomlQuote \"${NP_STATUS_NAME:-Nimbus}\")\nmotd = $(TomlQuote \"${NP_STATUS_MOTD:-Vintage Story proxy}\")\ngame_mode = \\\"survival\\\"\npassword = false\nserver_version = \\\"\\\"\nmax_players = ${max_users}\nquery_timeout_ms = 1500\n\n[plugins]\nenabled = true\ndirectory = \\\"plugins\\\"\ndisabled = []\n\n[persistence]\npersist_drain_flags = true\ndrain_flags_file = \\\"nimbus.drain-state.json\\\"\n\n[advanced]\nconnect_timeout_ms = 5000\nbuffer_size = 16384\n\"\nWriteAtomic \"$target\" \"$content\"\nprintf \u0027wrote %s\\n\u0027 \"$target\"\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Deploy Proxy renderer (Windows)", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/write-proxy-toml.ps1", + "UpdateSourceData": "param([Parameter(Mandatory = $true)][string]$Target)\n\n$ErrorActionPreference = \u0027Stop\u0027\n\nfunction Get-Value([string]$Name, [string]$Default = \u0027\u0027) {\n $value = [Environment]::GetEnvironmentVariable($Name)\n if ($null -eq $value) { return $Default }\n return $value\n}\n\nfunction TomlQuote([string]$Value) {\n if ($null -eq $Value) { $Value = \u0027\u0027 }\n $Value = $Value.Replace(\u0027\\\u0027, \u0027\\\\\u0027).Replace(\u0027\"\u0027, \u0027\\\"\u0027)\n $Value = $Value.Replace(\"`r\", \u0027\\r\u0027).Replace(\"`n\", \u0027\\n\u0027).Replace(\"`t\", \u0027\\t\u0027)\n return \u0027\"\u0027 + $Value + \u0027\"\u0027\n}\n\nfunction ParseBackendMap([string]$Value) {\n $result = [ordered]@{}\n foreach ($raw in $Value.Split(\u0027;\u0027)) {\n $entry = $raw.Trim()\n if ($entry -eq \u0027\u0027) { continue }\n $split = $entry.IndexOf(\u0027=\u0027)\n if ($split -lt 1 -or $split -eq $entry.Length - 1) { throw \"Malformed backend entry \u0027$entry\u0027; expected id=host:port\" }\n $id = $entry.Substring(0, $split).Trim()\n $endpoint = $entry.Substring($split + 1).Trim()\n if ($id -notmatch \u0027^[A-Za-z0-9][A-Za-z0-9_.-]*$\u0027) { throw \"Invalid backend ID \u0027$id\u0027\" }\n if ($result.Contains($id)) { throw \"Duplicate backend ID \u0027$id\u0027\" }\n $match = [regex]::Match($endpoint, \u0027^(\\[[^\\]]+\\]|[^:\\s]+):([0-9]+)$\u0027)\n if (-not $match.Success) { throw \"Invalid backend endpoint \u0027$endpoint\u0027\" }\n $port = 0\n if (-not [int]::TryParse($match.Groups[2].Value, [ref]$port) -or $port -lt 1 -or $port -gt 65535) {\n throw \"Backend port is outside 1-65535 in \u0027$endpoint\u0027\"\n }\n $result[$id] = $endpoint\n }\n if ($result.Count -eq 0) { throw \u0027At least one backend is required\u0027 }\n return $result\n}\n\nfunction ParseIdList([string]$Value, [System.Collections.IDictionary]$Known, [bool]$AllowEmpty = $false) {\n $result = New-Object System.Collections.Generic.List[string]\n foreach ($raw in $Value.Split(\u0027,\u0027)) {\n $id = $raw.Trim()\n if ($id -eq \u0027\u0027) { continue }\n if (-not $Known.Contains($id)) { throw \"Unknown backend ID \u0027$id\u0027\" }\n if (-not $result.Contains($id)) { $result.Add($id) }\n }\n if (-not $AllowEmpty -and $result.Count -eq 0) { throw \u0027At least one backend ID is required\u0027 }\n return @($result)\n}\n\nfunction ReadExistingSecret([string]$Path, [string]$RegistryMode) {\n if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) { return \u0027\u0027 }\n $key = if ($RegistryMode -eq \u0027embedded\u0027) { \u0027embedded_shared_secret\u0027 } else { \u0027shared_secret\u0027 }\n $pattern = \u0027^\\s*\u0027 + [regex]::Escape($key) + \u0027\\s*=\\s*\"([0-9A-Fa-f]+)\"\\s*$\u0027\n foreach ($line in [IO.File]::ReadAllLines($Path)) {\n $match = [regex]::Match($line, $pattern)\n if ($match.Success) { return $match.Groups[1].Value }\n }\n return \u0027\u0027\n}\n\nfunction NewRandomSecret() {\n $bytes = New-Object byte[] 32\n $rng = [Security.Cryptography.RandomNumberGenerator]::Create()\n try { $rng.GetBytes($bytes) } finally { $rng.Dispose() }\n return (($bytes | ForEach-Object { $_.ToString(\u0027x2\u0027) }) -join \u0027\u0027)\n}\n\nfunction ResolveSecret([string]$PanelValue, [string]$ExistingValue, [string]$RegistryMode) {\n $value = $PanelValue.Trim()\n $placeholder = \u0027^(?i)(change-me.*|paste.*secret.*|shared[-_ ]?secret|your[-_ ]?secret|replace[-_ ]?me.*)$\u0027\n if ($value -match $placeholder) { throw \u0027The shared secret is a documented placeholder, not a usable secret\u0027 }\n if ($value -ne \u0027\u0027) { return $value }\n if ($ExistingValue -ne \u0027\u0027) { return $ExistingValue }\n if ($RegistryMode -eq \u0027embedded\u0027) { return NewRandomSecret }\n throw \u0027Remote Registry mode requires an explicit or previously saved shared secret\u0027\n}\n\nfunction ParseBool([string]$Value, [string]$Name) {\n switch ($Value.Trim().ToLowerInvariant()) {\n \u0027true\u0027 { return \u0027true\u0027 }\n \u0027false\u0027 { return \u0027false\u0027 }\n default { throw \"$Name must be true or false\" }\n }\n}\n\nfunction ParsePort([string]$Value, [string]$Name) {\n $port = 0\n if (-not [int]::TryParse($Value, [ref]$port) -or $port -lt 1 -or $port -gt 65535) { throw \"$Name must be from 1 through 65535\" }\n return $port\n}\n\nfunction TomlArray([string[]]$Values) {\n return \u0027[\u0027 + (($Values | ForEach-Object { TomlQuote $_ }) -join \u0027, \u0027) + \u0027]\u0027\n}\n\nfunction WriteAtomic([string]$Path, [string]$Content) {\n $directory = Split-Path -Parent $Path\n if ($directory -and -not (Test-Path -LiteralPath $directory)) { New-Item -ItemType Directory -Path $directory -Force | Out-Null }\n $temporary = Join-Path $directory (\u0027.\u0027 + [IO.Path]::GetFileName($Path) + \u0027.\u0027 + [guid]::NewGuid().ToString(\u0027N\u0027) + \u0027.tmp\u0027)\n try {\n [IO.File]::WriteAllText($temporary, $Content, (New-Object Text.UTF8Encoding $false))\n Move-Item -LiteralPath $temporary -Destination $Path -Force\n }\n finally {\n if (Test-Path -LiteralPath $temporary) { Remove-Item -LiteralPath $temporary -Force }\n }\n}\n\n$bindAddress = Get-Value \u0027NP_BIND_ADDRESS\u0027 \u00270.0.0.0\u0027\n$serverPort = ParsePort (Get-Value \u0027NP_SERVER_PORT\u0027 \u002742420\u0027) \u0027Server port\u0027\n$registryPort = ParsePort (Get-Value \u0027NP_REGISTRY_PORT\u0027 \u00278765\u0027) \u0027Registry port\u0027\n$adminPort = ParsePort (Get-Value \u0027NP_ADMIN_PORT\u0027 \u002742499\u0027) \u0027Admin port\u0027\n$metricsPort = ParsePort (Get-Value \u0027NP_METRICS_PORT\u0027 \u002742500\u0027) \u0027Metrics port\u0027\n$maxPlayers = ParsePort (Get-Value \u0027NP_MAX_USERS\u0027 \u0027100\u0027) \u0027Player limit\u0027\n$backends = ParseBackendMap (Get-Value \u0027NP_SERVERS\u0027 \u0027hub=127.0.0.1:42421\u0027)\n$tryIds = ParseIdList (Get-Value \u0027NP_TRY\u0027 \u0027hub\u0027) $backends\n$whitelistIds = ParseIdList (Get-Value \u0027NP_WHITELIST_SERVERS\u0027 \u0027\u0027) $backends $true\n$mode = (Get-Value \u0027NP_REGISTRY_MODE\u0027 \u0027embedded\u0027).Trim().ToLowerInvariant()\nif (@(\u0027embedded\u0027, \u0027remote\u0027) -notcontains $mode) { throw \u0027Registry mode must be embedded or remote\u0027 }\n$access = (Get-Value \u0027NP_REGISTRY_ACCESS\u0027 \u0027same-host\u0027).Trim().ToLowerInvariant()\nif (@(\u0027same-host\u0027, \u0027other-hosts\u0027) -notcontains $access) { throw \u0027Registry access must be same-host or other-hosts\u0027 }\n$registryUrl = (Get-Value \u0027NP_REGISTRY_URL\u0027 \u0027\u0027).Trim()\nif ($mode -eq \u0027remote\u0027 -and $registryUrl -notmatch \u0027^https?://[^\\s]+$\u0027) { throw \u0027Remote Registry mode requires an HTTP or HTTPS URL\u0027 }\n$existingSecret = ReadExistingSecret $Target $mode\n$secret = ResolveSecret (Get-Value \u0027NP_SHARED_SECRET\u0027 \u0027\u0027) $existingSecret $mode\n$embeddedBindHost = if ($access -eq \u0027same-host\u0027) { \u0027127.0.0.1\u0027 } else { \u00270.0.0.0\u0027 }\n$remoteSecret = if ($mode -eq \u0027remote\u0027) { $secret } else { \u0027\u0027 }\n$embeddedSecret = if ($mode -eq \u0027embedded\u0027) { $secret } else { \u0027\u0027 }\n$embeddedBind = if ($mode -eq \u0027embedded\u0027) { \"http://${embeddedBindHost}:$registryPort\" } else { \u0027\u0027 }\n$whitelistNetwork = ParseBool (Get-Value \u0027NP_WHITELIST_NETWORK\u0027 \u0027false\u0027) \u0027Network whitelist\u0027\n$verbose = ParseBool (Get-Value \u0027NP_VERBOSE\u0027 \u0027false\u0027) \u0027Verbose logging\u0027\n\n$lines = New-Object System.Collections.Generic.List[string]\n$lines.Add(\u0027bind = \u0027 + (TomlQuote \"${bindAddress}:$serverPort\"))\n$lines.Add(\u0027try = \u0027 + (TomlArray $tryIds))\n$lines.Add(\u0027\u0027)\n$lines.Add(\u0027[servers]\u0027)\nforeach ($entry in $backends.GetEnumerator()) { $lines.Add((TomlQuote $entry.Key) + \u0027 = \u0027 + (TomlQuote $entry.Value)) }\n$lines.Add(\u0027\u0027)\n$lines.Add(\u0027[transfers]\u0027)\n$lines.Add(\u0027default_mode = \"redirect\"\u0027)\n$lines.Add(\u0027allow_seamless = false\u0027)\n$lines.Add(\u0027require_seamless_capability = true\u0027)\n$lines.Add(\u0027fallback_to_redirect_when_seamless_unavailable = true\u0027)\n$lines.Add(\u0027enable_unsafe_seamless_splice = false\u0027)\n$lines.Add(\u0027\u0027)\n$lines.Add(\u0027[admin]\u0027)\n$lines.Add(\u0027bind = \u0027 + (TomlQuote \"127.0.0.1:$adminPort\"))\n$lines.Add(\u0027secret = \"\"\u0027)\n$lines.Add(\u0027enabled = true\u0027)\n$lines.Add(\u0027granted_permissions = [\"*\"]\u0027)\n$lines.Add(\u0027\u0027)\n$lines.Add(\u0027[registry]\u0027)\n$lines.Add(\u0027mode = \u0027 + (TomlQuote $mode))\n$lines.Add(\u0027proxy_id = \u0027 + (TomlQuote (Get-Value \u0027NP_PROXY_ID\u0027 \u0027nimbus-proxy\u0027)))\n$lines.Add(\u0027url = \u0027 + (TomlQuote $(if ($mode -eq \u0027remote\u0027) { $registryUrl } else { \u0027\u0027 })))\n$lines.Add(\u0027shared_secret = \u0027 + (TomlQuote $remoteSecret))\n$lines.Add(\u0027embedded_bind = \u0027 + (TomlQuote $embeddedBind))\n$lines.Add(\u0027embedded_shared_secret = \u0027 + (TomlQuote $embeddedSecret))\n$lines.Add(\u0027backend_stale_seconds = 20\u0027)\n$lines.Add(\u0027backend_drop_seconds = 120\u0027)\n$lines.Add(\u0027nonce_window_seconds = 90\u0027)\n$lines.Add(\u0027max_reservation_ttl_seconds = 300\u0027)\n$lines.Add(\u0027fail_on_error = true\u0027)\n$lines.Add(\u0027transfer_intent_poll_ms = 1000\u0027)\n$lines.Add(\u0027advertise_on_master_server = false\u0027)\n$lines.Add(\u0027\u0027)\n$lines.Add(\u0027[whitelist]\u0027)\n$lines.Add(\u0027network = \u0027 + $whitelistNetwork)\n$lines.Add(\u0027servers = \u0027 + (TomlArray $whitelistIds))\n$lines.Add(\u0027fail_open_until_first_sync = false\u0027)\n$lines.Add(\u0027\u0027)\n$lines.Add(\u0027[logging]\u0027)\n$lines.Add(\u0027verbose = \u0027 + $verbose)\n$lines.Add(\u0027sniff_frames = false\u0027)\n$lines.Add(\u0027log_traffic_bytes = false\u0027)\n$lines.Add(\u0027\u0027)\n$lines.Add(\u0027[metrics]\u0027)\n$lines.Add(\u0027enabled = true\u0027)\n$lines.Add(\u0027bind = \u0027 + (TomlQuote \"http://127.0.0.1:$metricsPort\"))\n$lines.Add(\u0027path = \"/metrics\"\u0027)\n$lines.Add(\u0027status_api = true\u0027)\n$lines.Add(\u0027status_api_token = \"\"\u0027)\n$lines.Add(\u0027\u0027)\n$lines.Add(\u0027[status]\u0027)\n$lines.Add(\u0027enabled = true\u0027)\n$lines.Add(\u0027name = \u0027 + (TomlQuote (Get-Value \u0027NP_STATUS_NAME\u0027 \u0027Nimbus\u0027)))\n$lines.Add(\u0027motd = \u0027 + (TomlQuote (Get-Value \u0027NP_STATUS_MOTD\u0027 \u0027Vintage Story proxy\u0027)))\n$lines.Add(\u0027game_mode = \"survival\"\u0027)\n$lines.Add(\u0027password = false\u0027)\n$lines.Add(\u0027server_version = \"\"\u0027)\n$lines.Add(\u0027max_players = \u0027 + $maxPlayers)\n$lines.Add(\u0027query_timeout_ms = 1500\u0027)\n$lines.Add(\u0027\u0027)\n$lines.Add(\u0027[plugins]\u0027)\n$lines.Add(\u0027enabled = true\u0027)\n$lines.Add(\u0027directory = \"plugins\"\u0027)\n$lines.Add(\u0027disabled = []\u0027)\n$lines.Add(\u0027\u0027)\n$lines.Add(\u0027[persistence]\u0027)\n$lines.Add(\u0027persist_drain_flags = true\u0027)\n$lines.Add(\u0027drain_flags_file = \"nimbus.drain-state.json\"\u0027)\n$lines.Add(\u0027\u0027)\n$lines.Add(\u0027[advanced]\u0027)\n$lines.Add(\u0027connect_timeout_ms = 5000\u0027)\n$lines.Add(\u0027buffer_size = 16384\u0027)\n\nWriteAtomic $Target (($lines -join \"`n\") + \"`n\")\nWrite-Output \"wrote $Target\"\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + } +] \ No newline at end of file diff --git a/nimbus-registry.kvp b/nimbus-registry.kvp index c36b7d26a..3e4cb4674 100644 --- a/nimbus-registry.kvp +++ b/nimbus-registry.kvp @@ -1,14 +1,13 @@ -Meta.DisplayName=Nimbus Registry (Vintage Story) -Meta.Description=Standalone Nimbus registry for Vintage Story networks. It is the single source of truth for which backends are alive, slot reservations, transfer intents, bans, the whitelist and API tokens. You only need this instance when you run more than one proxy, or when you want the registry to survive a proxy restart - a single proxy can host the registry itself in embedded mode. +Meta.DisplayName=Nimbus Registry (Optional) +Meta.Description=Optional shared Nimbus control plane for multi-proxy or multi-host networks Meta.OS=Windows, Linux Meta.AarchSupport=None Meta.Arch=x86_64 Meta.Author=HuguesDePayens Meta.URL=https://github.com/StratumServer/Nimbus -Meta.DisplayImageSource=url:https://wiki.vintagestory.at/images/thumb/8/8a/Gamelogo-vintagestory.png/340px-Gamelogo-vintagestory.png Meta.EndpointURIFormat= Meta.ConfigManifest=nimbus-registryconfig.json -Meta.MetaConfigManifest=nimbus-registrymetaconfig.json +Meta.MetaConfigManifest= Meta.ConfigRoot=nimbus-registry.kvp Meta.MinAMPVersion=2.4.6.0 Meta.SpecificDockerImage=cubecoders/ampbase:debian @@ -19,29 +18,28 @@ Meta.Prerequisites=[] Meta.ConfigReleaseState=NotSpecified Meta.NoCommercialUsage=False Meta.ConfigVersion=1 -Meta.AppConfigId=c92f1a35-47b8-4d61-95e0-1f8d6c3b7a20 +Meta.AppConfigId=b0ed14fe-3b73-4044-9339-71bd3df1ced3 Meta.AppIsMultiIPAware=True -Meta.ResourceUsageInfo=1 CPU core and 256MB RAM; the registry only answers small HTTP requests +Meta.ResourceUsageInfo=Optional lightweight HTTP control plane; one Proxy can use its embedded Registry instead Meta.ImportableExtensions=[] App.DisplayName=Nimbus Registry App.RootDir=./nimbus-registry/ App.BaseDirectory=./nimbus-registry/ -App.ExecutableWin=dotnet\dotnet.exe App.ExecutableLinux=dotnet/dotnet +App.ExecutableWin=dotnet\dotnet.exe App.WorkingDir=Nimbus.Registry App.LinuxCommandLineArgs="{{$FullRootDir}}Nimbus.Registry/Nimbus.Registry.dll" "{{$FullRootDir}}Nimbus.Registry/nimbus.registry.toml" App.WindowsCommandLineArgs="{{$FullRootDir}}Nimbus.Registry\Nimbus.Registry.dll" "{{$FullRootDir}}Nimbus.Registry\nimbus.registry.toml" -App.CommandLineArgs={{$PlatformArgs}} {{RegistryExtraArgs}} +App.CommandLineArgs={{$PlatformArgs}} App.UseLinuxIOREDIR=False App.AppSettings={} -App.EnvironmentVariables={"DOTNET_ROOT":"{{$FullRootDir}}dotnet","DOTNET_CLI_TELEMETRY_OPTOUT":"1","DOTNET_NOLOGO":"1","ASPNETCORE_ENVIRONMENT":"Production"} -App.CommandLineParameterFormat=--{0} {1} +App.EnvironmentVariables={"DOTNET_ROOT":"{{$FullRootDir}}dotnet","DOTNET_CLI_TELEMETRY_OPTOUT":"1","DOTNET_NOLOGO":"1"} +App.CommandLineParameterFormat={0} {1} App.CommandLineParameterDelimiter= -App.ExitMethod=SIGTERM -App.ExitMethodWindows=None +App.ExitMethod=OS_CLOSE App.ExitTimeout=30 App.ExitString= -App.ExitFile=lock +App.ExitFile= App.HasWriteableConsole=False App.HasReadableConsole=True App.SupportsLiveSettingsChanges=False @@ -50,8 +48,8 @@ App.ApplicationIPBinding=0.0.0.0 App.Ports=@IncludeJson[nimbus-registryports.json] App.AdminPortRef=RegistryPort App.PrimaryApplicationPortRef=RegistryPort -App.UniversalSleepApplicationUDPPortRef=RegistryPort -App.UniversalSleepSteamQueryPortRef=RegistryPort +App.UniversalSleepApplicationUDPPortRef= +App.UniversalSleepSteamQueryPortRef= App.MaxUsers=0 App.UseRandomAdminPassword=False App.RemoteAdminPassword= @@ -60,7 +58,7 @@ App.AdminLoginTransform=None App.RCONConnectDelaySeconds=5 App.RCONConnectRetrySeconds=5 App.RCONHeartbeatMinutes=0 -App.RCONHeartbeatCommand=ping +App.RCONHeartbeatCommand= App.TelnetLoginFormat={0} App.PreStartStages=@IncludeJson[nimbus-registrystart.json] App.UpdateSources=@IncludeJson[nimbus-registryupdates.json] @@ -69,8 +67,8 @@ App.SteamUpdateAnonymousLogin=True App.SteamForceLoginPrompt=False App.RapidStartup=False App.SmartExcludeSupported=True -App.SmartExcludeExemptions=["*.toml","*.json","*.cfg","*.conf","*.config","*.ini","*.kvp","*.yml","*.yaml"] -App.MonitorChildProcess=False +App.SmartExcludeExemptions=["*.toml","nimbus.bans.json*","nimbus.whitelist.json*","nimbus.tokens.json*"] +App.MonitorChildProcess=True App.MonitorChildProcessWaitMs=100 App.MonitorChildProcessName= App.SupportsUniversalSleep=False diff --git a/nimbus-registryconfig.json b/nimbus-registryconfig.json index 45920f18a..2a908b0f1 100644 --- a/nimbus-registryconfig.json +++ b/nimbus-registryconfig.json @@ -1,582 +1,13 @@ [ - { - "DisplayName": "Let AMP Manage nimbus.registry.toml", - "Category": "Updates", - "Subcategory": "Nimbus Updates:build:-1", - "Description": "When on, AMP rewrites Nimbus.Registry/nimbus.registry.toml from the settings in this panel every time the instance starts. Turn it off to hand-edit that file instead.", - "Keywords": "nimbus,config,manage", - "FieldName": "RegistryWriteConfig", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "RegistryWriteConfig", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Nimbus Version Tag", - "Category": "Updates", - "Subcategory": "Nimbus Updates:build:-1", - "Description": "Pin a specific Nimbus release tag, for example v0.5.0. Leave empty to take the newest release on the channel below. Every part of a Nimbus network - proxy, registry and the server mod on each backend - must run the same Nimbus version, so pin this once you go live and bump all of them together.", - "Keywords": "nimbus,version,tag", - "FieldName": "NimbusVersionTag", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "NimbusVersionTag", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "v0.5.0" - }, - { - "DisplayName": "Nimbus Release Channel", - "Category": "Updates", - "Subcategory": "Nimbus Updates:build:-1", - "Description": "stable takes the newest non prerelease. prerelease also considers releases marked as pre-release, which is only for test networks.", - "Keywords": "nimbus,channel,prerelease", - "FieldName": "NimbusReleaseChannel", - "InputType": "enum", - "IsFlagArgument": false, - "ParamFieldName": "NimbusReleaseChannel", - "IncludeInCommandLine": false, - "DefaultValue": "stable", - "EnumValues": { - "Stable releases only": "stable", - "Include pre-releases": "prerelease" - } - }, - { - "DisplayName": "GitHub Token (optional)", - "Category": "Updates", - "Subcategory": "Nimbus Updates:build:-1", - "Description": "Optional GitHub personal access token used only to raise the API rate limit while looking up releases. Nothing here needs a private repository, so leave it empty unless updates start failing with a rate limit message.", - "Keywords": "github,token,ratelimit", - "FieldName": "NimbusGitHubToken", - "InputType": "password", - "IsFlagArgument": false, - "ParamFieldName": "NimbusGitHubToken", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Components To Install", - "Category": "Updates", - "Subcategory": "Nimbus Updates:build:-1", - "Description": "Which parts of the Nimbus release are unpacked into this instance. The standalone registry is all this instance runs. Choose the second option only if you also want the proxy binaries unpacked here for manual use.", - "Keywords": "nimbus,components", - "FieldName": "NimbusUpdateComponents", - "InputType": "enum", - "IsFlagArgument": false, - "ParamFieldName": "NimbusUpdateComponents", - "IncludeInCommandLine": false, - "DefaultValue": "Nimbus.Registry", - "EnumValues": { - "Registry only": "Nimbus.Registry", - "Registry and proxy": "Nimbus.Registry Nimbus" - } - }, - { - "DisplayName": ".NET SDK Version", - "Category": "Updates", - "Subcategory": "Runtime:memory:-1", - "Description": "Exact .NET SDK version to install, for example 10.0.100. Leave this empty to always take the latest SDK from the channel below, which is what you want unless a specific build broke something.", - "Keywords": "dotnet,sdk,version", - "FieldName": "DotnetSDKVersion", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "DotnetSDKVersion", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "10.0.100" - }, - { - "DisplayName": ".NET Release Channel", - "Category": "Updates", - "Subcategory": "Runtime:memory:-1", - "Description": "The .NET release channel the SDK is fetched from. Nimbus Registry targets .NET 10 and needs the ASP.NET Core runtime, which the SDK includes, so leave this at 10.0 unless Nimbus itself moves to a newer runtime.", - "Keywords": "dotnet,release,channel", - "FieldName": "DotnetRelease", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "DotnetRelease", - "IncludeInCommandLine": false, - "DefaultValue": "10.0", - "EnumValues": {}, - "Placeholder": "10.0" - }, - { - "DisplayName": "Additional Command Line Arguments", - "Category": "Updates", - "Subcategory": "Nimbus Updates:build:-1", - "Description": "Extra arguments appended to the registry command line after the config file path. Normally empty.", - "Keywords": "args,commandline", - "FieldName": "RegistryExtraArgs", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "RegistryExtraArgs", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Registry Bind URL", - "Category": "Nimbus Registry:dns", - "Subcategory": "Registry:dns:1", - "Description": "Base URL the registry listens on. The host part is taken from this field and the port from the Registry Port setting, so http://0.0.0.0 plus port 8765 becomes http://0.0.0.0:8765. A standalone registry only earns its keep when backends are not on the same box, so 0.0.0.0 is the sensible default here, and that makes setting a real shared secret mandatory. (Config file key: bind_url)", - "Keywords": "registrybindscheme", - "FieldName": "RegistryBindScheme", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "RegistryBindScheme", - "IncludeInCommandLine": false, - "DefaultValue": "http://0.0.0.0:8765", - "EnumValues": {}, - "Placeholder": "http://0.0.0.0" - }, - { - "DisplayName": "Shared Secret", - "Category": "Nimbus Registry:dns", - "Subcategory": "Registry:dns:1", - "Description": "HMAC secret every backend and every proxy signs its registry calls with. Leave empty and the registry generates one on first start, then read it out of nimbus.registry.toml and paste the same value into each backend's Nimbus Shared Secret and each proxy's Remote Registry Shared Secret. Never leave it as change-me-and-keep-secret. (Config file key: shared_secret)", - "Keywords": "registrysharedsecret", - "FieldName": "RegistrySharedSecret", - "InputType": "password", - "IsFlagArgument": false, - "ParamFieldName": "RegistrySharedSecret", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Additional Accepted Secrets", - "Category": "Nimbus Registry:dns", - "Subcategory": "Registry:dns:1", - "Description": "Comma separated secrets that are also accepted, used to rotate without downtime: add the new secret here, redeploy every backend and proxy with it, then promote it to Shared Secret and clear this field. (Config file key: accepted_secrets)", - "Keywords": "registryacceptedsecrets", - "FieldName": "RegistryAcceptedSecrets", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "RegistryAcceptedSecrets", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Backend Stale After (seconds)", - "Category": "Nimbus Registry:dns", - "Subcategory": "Registry:dns:1", - "Description": "Seconds without a heartbeat before a backend is reported as stale in the network snapshot. (Config file key: backend_stale_seconds)", - "Keywords": "registrybackendstaleseconds", - "FieldName": "RegistryBackendStaleSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "RegistryBackendStaleSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "20", - "EnumValues": {}, - "MinValue": "1" - }, - { - "DisplayName": "Backend Dropped After (seconds)", - "Category": "Nimbus Registry:dns", - "Subcategory": "Registry:dns:1", - "Description": "Seconds without a heartbeat before a backend is removed from the registry entirely. (Config file key: backend_drop_seconds)", - "Keywords": "registrybackenddropseconds", - "FieldName": "RegistryBackendDropSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "RegistryBackendDropSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "120", - "EnumValues": {}, - "MinValue": "1" - }, - { - "DisplayName": "Nonce Window (seconds)", - "Category": "Nimbus Registry:dns", - "Subcategory": "Registry:dns:1", - "Description": "Replay protection window. Signed requests older than this are refused, so every machine on the network needs its clock inside roughly this margin. (Config file key: nonce_window_seconds)", - "Keywords": "registrynoncewindowseconds", - "FieldName": "RegistryNonceWindowSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "RegistryNonceWindowSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "90", - "EnumValues": {}, - "MinValue": "5" - }, - { - "DisplayName": "Maximum Reservation TTL (seconds)", - "Category": "Nimbus Registry:dns", - "Subcategory": "Registry:dns:1", - "Description": "Reservations requesting a longer TTL than this are refused. 0 removes the ceiling. (Config file key: max_reservation_ttl_seconds)", - "Keywords": "registrymaxreservationttlseconds", - "FieldName": "RegistryMaxReservationTtlSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "RegistryMaxReservationTtlSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "300", - "EnumValues": {}, - "MinValue": "0" - }, - { - "DisplayName": "Log Every Heartbeat", - "Category": "Nimbus Registry:dns", - "Subcategory": "Registry:dns:1", - "Description": "Logs every successful backend heartbeat. Handy while wiring a network up, very noisy once it works. (Config file key: log_heartbeats)", - "Keywords": "registrylogheartbeats", - "FieldName": "RegistryLogHeartbeats", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "RegistryLogHeartbeats", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "State Directory", - "Category": "Nimbus Registry:dns", - "Subcategory": "Registry:dns:1", - "Description": "Where nimbus.bans.json, nimbus.whitelist.json and nimbus.tokens.json are kept so they survive a restart. A relative path resolves against the working directory, which is where nimbus.registry.toml lives. A file the registry cannot parse is renamed with a .bad suffix rather than trusted. (Config file key: state_dir)", - "Keywords": "registrystatedir", - "FieldName": "RegistryStateDir", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "RegistryStateDir", - "IncludeInCommandLine": false, - "DefaultValue": ".", - "EnumValues": {}, - "Placeholder": "." - }, - { - "DisplayName": "Enable API Tokens", - "Category": "Nimbus Registry:dns", - "Subcategory": "API Tokens:key:2", - "Description": "Master switch for scoped bearer tokens used by third party integrations. Off refuses bearer authentication no matter which tokens exist. Nimbus's own components always use HMAC and are unaffected. (Config file key: api_tokens.enabled)", - "Keywords": "registryapitokensenabled", - "FieldName": "RegistryApiTokensEnabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "RegistryApiTokensEnabled", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "API Token Rate Limit (per minute)", - "Category": "Nimbus Registry:dns", - "Subcategory": "API Tokens:key:2", - "Description": "Requests per minute per token. A value of zero or less is a configuration error and falls back to 60. (Config file key: api_tokens.rate_limit_per_minute)", - "Keywords": "registryapitokensratelimitperminute", - "FieldName": "RegistryApiTokensRateLimitPerMinute", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "RegistryApiTokensRateLimitPerMinute", - "IncludeInCommandLine": false, - "DefaultValue": "60", - "EnumValues": {}, - "MinValue": "1" - }, - { - "DisplayName": "Trust X-Forwarded-Proto", - "Category": "Nimbus Registry:dns", - "Subcategory": "API Tokens:key:2", - "Description": "Token authentication is only accepted over loopback or the registry's own TLS listener. Set this true only when a TLS terminating reverse proxy is the sole route to the bind URL, because anything that can reach the bind directly can forge the header. (Config file key: api_tokens.trust_forwarded_proto)", - "Keywords": "registryapitokenstrustforwardedproto", - "FieldName": "RegistryApiTokensTrustForwardedProto", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "RegistryApiTokensTrustForwardedProto", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Advertise Network On Master Server", - "Category": "Nimbus Registry:dns", - "Subcategory": "Master Server Listing:public:3", - "Description": "Registers the whole network as one entry on the public Vintage Story server list. Turn master server advertising off on every backend when you use this, otherwise players see each backend separately. (Config file key: identity.advertise_on_master_server)", - "Keywords": "registryadvertiseonmasterserver", - "FieldName": "RegistryAdvertiseOnMasterServer", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "RegistryAdvertiseOnMasterServer", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Master Server URL", - "Category": "Nimbus Registry:dns", - "Subcategory": "Master Server Listing:public:3", - "Description": "Endpoint the registration is sent to. Change this only when you self host a master server. (Config file key: identity.master_server_url)", - "Keywords": "registrymasterserverurl", - "FieldName": "RegistryMasterServerUrl", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "RegistryMasterServerUrl", - "IncludeInCommandLine": false, - "DefaultValue": "http://masterserver.vintagestory.at/api/v1/servers/", - "EnumValues": {} - }, - { - "DisplayName": "Public Host", - "Category": "Nimbus Registry:dns", - "Subcategory": "Master Server Listing:public:3", - "Description": "Address players connect to, which must be the proxy's reachable hostname or IP, never a backend's. (Config file key: identity.public_host)", - "Keywords": "registrypublichost", - "FieldName": "RegistryPublicHost", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "RegistryPublicHost", - "IncludeInCommandLine": false, - "DefaultValue": "127.0.0.1", - "EnumValues": {}, - "Placeholder": "play.example.com" - }, - { - "DisplayName": "Public Port", - "Category": "Nimbus Registry:dns", - "Subcategory": "Master Server Listing:public:3", - "Description": "Port players connect to on the proxy. (Config file key: identity.public_port)", - "Keywords": "registrypublicport", - "FieldName": "RegistryPublicPort", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "RegistryPublicPort", - "IncludeInCommandLine": false, - "DefaultValue": "42420", - "EnumValues": {}, - "MinValue": "1", - "MaxValue": "65535" - }, - { - "DisplayName": "Network Name", - "Category": "Nimbus Registry:dns", - "Subcategory": "Master Server Listing:public:3", - "Description": "Name shown in the public server list. (Config file key: identity.server_name)", - "Keywords": "registryservername", - "FieldName": "RegistryServerName", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "RegistryServerName", - "IncludeInCommandLine": false, - "DefaultValue": "Nimbus Network", - "EnumValues": {} - }, - { - "DisplayName": "Network Description", - "Category": "Nimbus Registry:dns", - "Subcategory": "Master Server Listing:public:3", - "Description": "Description shown in the public server list. (Config file key: identity.server_description)", - "Keywords": "registryserverdescription", - "FieldName": "RegistryServerDescription", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "RegistryServerDescription", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Website URL", - "Category": "Nimbus Registry:dns", - "Subcategory": "Master Server Listing:public:3", - "Description": "Optional website link shown with the listing. (Config file key: identity.server_url)", - "Keywords": "registryserverurl", - "FieldName": "RegistryServerUrl", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "RegistryServerUrl", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "https://example.com" - }, - { - "DisplayName": "Server Icon", - "Category": "Nimbus Registry:dns", - "Subcategory": "Master Server Listing:public:3", - "Description": "Optional icon published with the listing, in the form the master server expects. (Config file key: identity.server_icon)", - "Keywords": "registryservericon", - "FieldName": "RegistryServerIcon", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "RegistryServerIcon", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Hosting Identifier", - "Category": "Nimbus Registry:dns", - "Subcategory": "Master Server Listing:public:3", - "Description": "Optional game hosting provider identifier. Leave empty for self hosted networks. (Config file key: identity.vh_identifier)", - "Keywords": "registryvhidentifier", - "FieldName": "RegistryVhIdentifier", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "RegistryVhIdentifier", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Reported Game Version", - "Category": "Nimbus Registry:dns", - "Subcategory": "Master Server Listing:public:3", - "Description": "Vintage Story version published with the listing. Set it to the version your Stratum backends run, otherwise clients filter the network out of their list. (Config file key: identity.game_version)", - "Keywords": "registrygameversion", - "FieldName": "RegistryGameVersion", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "RegistryGameVersion", - "IncludeInCommandLine": false, - "DefaultValue": "1.22.2", - "EnumValues": {}, - "Placeholder": "1.22.6" - }, - { - "DisplayName": "Player Limit Override", - "Category": "Nimbus Registry:dns", - "Subcategory": "Master Server Listing:public:3", - "Description": "Player count published for the network. 0 publishes the sum of every live backend's own limit, which is usually right. (Config file key: identity.max_players_override)", - "Keywords": "registrymaxplayersoverride", - "FieldName": "RegistryMaxPlayersOverride", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "RegistryMaxPlayersOverride", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {}, - "MinValue": "0" - }, - { - "DisplayName": "Mod List Source", - "Category": "Nimbus Registry:dns", - "Subcategory": "Master Server Listing:public:3", - "Description": "Which mod list is published: aggregate for the union of every live backend's required client mods, explicit to publish the list below, or backend: to mirror one named backend. (Config file key: identity.mod_source)", - "Keywords": "registrymodsource", - "FieldName": "RegistryModSource", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "RegistryModSource", - "IncludeInCommandLine": false, - "DefaultValue": "aggregate", - "EnumValues": {}, - "Placeholder": "aggregate" - }, - { - "DisplayName": "Explicit Mod List", - "Category": "Nimbus Registry:dns", - "Subcategory": "Master Server Listing:public:3", - "Description": "Used only when Mod List Source is explicit. Comma separated modid=version pairs, for example nimbus=0.5.0,carryon=1.7.0. (Config file key: identity.explicit_mods)", - "Keywords": "registryexplicitmods", - "FieldName": "RegistryExplicitMods", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "RegistryExplicitMods", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "nimbus=0.5.0" - }, - { - "DisplayName": "Report As Whitelisted", - "Category": "Nimbus Registry:dns", - "Subcategory": "Master Server Listing:public:3", - "Description": "Flags the listing as whitelisted so players know they need to be on the list. This is a label only and enforces nothing. (Config file key: identity.whitelisted)", - "Keywords": "registrylistingwhitelisted", - "FieldName": "RegistryListingWhitelisted", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "RegistryListingWhitelisted", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Report As Password Protected", - "Category": "Nimbus Registry:dns", - "Subcategory": "Master Server Listing:public:3", - "Description": "Flags the listing as password protected. A label only; set it if the backends actually require a password. (Config file key: identity.has_password)", - "Keywords": "registrylistinghaspassword", - "FieldName": "RegistryListingHasPassword", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "RegistryListingHasPassword", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Master Server Heartbeat (seconds)", - "Category": "Nimbus Registry:dns", - "Subcategory": "Master Server Listing:public:3", - "Description": "How often the listing is refreshed. Vanilla uses 120 seconds; do not go lower. (Config file key: identity.heartbeat_interval_seconds)", - "Keywords": "registrymasterheartbeatintervalseconds", - "FieldName": "RegistryMasterHeartbeatIntervalSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "RegistryMasterHeartbeatIntervalSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "120", - "EnumValues": {}, - "MinValue": "120" - }, - { - "DisplayName": "Playstyle ID", - "Category": "Nimbus Registry:dns", - "Subcategory": "Master Server Listing:public:3", - "Description": "Playstyle id published with the listing, for example surviveandbuild, wildernesssurvival or creativebuilding. (Config file key: identity.playstyle.id)", - "Keywords": "registryplaystyleid", - "FieldName": "RegistryPlaystyleId", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "RegistryPlaystyleId", - "IncludeInCommandLine": false, - "DefaultValue": "surviveandbuild", - "EnumValues": {}, - "Placeholder": "surviveandbuild" - }, - { - "DisplayName": "Playstyle Language Code", - "Category": "Nimbus Registry:dns", - "Subcategory": "Master Server Listing:public:3", - "Description": "Translation key for the playstyle, normally preset- followed by the playstyle id. (Config file key: identity.playstyle.lang_code)", - "Keywords": "registryplaystylelangcode", - "FieldName": "RegistryPlaystyleLangCode", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "RegistryPlaystyleLangCode", - "IncludeInCommandLine": false, - "DefaultValue": "preset-surviveandbuild", - "EnumValues": {}, - "Placeholder": "preset-surviveandbuild" - } + {"DisplayName":"Registry Port","Category":"Registry:hub","Subcategory":"Network:dns:1","Description":"HTTP port used by Nimbus Proxy and backends.","Keywords":"registry,port","FieldName":"$RegistryPort","InputType":"number","Hidden":true,"ParamFieldName":"RegistryPort","IncludeInCommandLine":false,"DefaultValue":"8765","MinValue":1,"MaxValue":65535,"EnumValues":{}}, + {"DisplayName":"Nimbus Release Tag","Category":"Updates:update","Subcategory":"Version:verified_user:1","Description":"Optional exact Nimbus release tag. Leave blank for the latest stable release.","Keywords":"nimbus,version","FieldName":"NimbusVersionTag","InputType":"text","ParamFieldName":"NimbusVersionTag","IncludeInCommandLine":false,"DefaultValue":"","Placeholder":"v0.5.0","EnumValues":{}}, + {"DisplayName":"Registry Shared Secret","Category":"Registry:hub","Subcategory":"Security:lock:2","Description":"Blank generates a strong secret once and preserves it. Copy the resulting value to Proxy and every backend.","Keywords":"registry,secret","FieldName":"RegistrySharedSecret","InputType":"password","ParamFieldName":"RegistrySharedSecret","IncludeInCommandLine":false,"DefaultValue":"","EnumValues":{}}, + {"DisplayName":"Advertise on Vintage Story Master Server","Category":"Public Listing:public","Subcategory":"Advertising:campaign:1","Description":"Publish the Proxy endpoint on the Vintage Story public server list.","Keywords":"master,server,advertise","FieldName":"RegistryAdvertise","InputType":"checkbox","ParamFieldName":"RegistryAdvertise","IncludeInCommandLine":false,"DefaultValue":"false","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Proxy Public Host","Category":"Public Listing:public","Subcategory":"Identity:badge:2","Description":"Public hostname or IP of Nimbus Proxy, not this Registry HTTP endpoint.","Keywords":"proxy,public,host","FieldName":"RegistryPublicHost","InputType":"text","ParamFieldName":"RegistryPublicHost","IncludeInCommandLine":false,"DefaultValue":"127.0.0.1","Placeholder":"play.example.com","EnumValues":{}}, + {"DisplayName":"Proxy Public Port","Category":"Public Listing:public","Subcategory":"Identity:badge:2","Description":"Public player port of Nimbus Proxy, not the Registry port.","Keywords":"proxy,public,port","FieldName":"RegistryPublicPort","InputType":"number","ParamFieldName":"RegistryPublicPort","IncludeInCommandLine":false,"DefaultValue":"42420","MinValue":1,"MaxValue":65535,"EnumValues":{}}, + {"DisplayName":"Network Name","Category":"Public Listing:public","Subcategory":"Identity:badge:2","Description":"Name shown on the Vintage Story public server list.","Keywords":"server,name","FieldName":"RegistryServerName","InputType":"text","ParamFieldName":"RegistryServerName","IncludeInCommandLine":false,"DefaultValue":"Nimbus Network","EnumValues":{}}, + {"DisplayName":"Network Description","Category":"Public Listing:public","Subcategory":"Identity:badge:2","Description":"Description shown on the Vintage Story public server list.","Keywords":"server,description","FieldName":"RegistryServerDescription","InputType":"text","ParamFieldName":"RegistryServerDescription","IncludeInCommandLine":false,"DefaultValue":"","EnumValues":{}}, + {"DisplayName":"Vintage Story Version","Category":"Public Listing:public","Subcategory":"Compatibility:verified_user:3","Description":"Game version reported publicly. Keep this equal to the Vintage Story version owned by the selected Stratum release.","Keywords":"game,version,stratum","FieldName":"RegistryGameVersion","InputType":"text","ParamFieldName":"RegistryGameVersion","IncludeInCommandLine":false,"Required":true,"DefaultValue":"1.22.6","EnumValues":{}}, + {"DisplayName":"List as Password Protected","Category":"Public Listing:public","Subcategory":"Access:lock:4","Description":"Report that the network requires a player password.","Keywords":"listing,password","FieldName":"RegistryListingHasPassword","InputType":"checkbox","ParamFieldName":"RegistryListingHasPassword","IncludeInCommandLine":false,"DefaultValue":"false","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"List as Whitelisted","Category":"Public Listing:public","Subcategory":"Access:lock:4","Description":"Report that the network uses a whitelist.","Keywords":"listing,whitelist","FieldName":"RegistryListingWhitelisted","InputType":"checkbox","ParamFieldName":"RegistryListingWhitelisted","IncludeInCommandLine":false,"DefaultValue":"false","EnumValues":{"True":"true","False":"false"}} ] diff --git a/nimbus-registryports.json b/nimbus-registryports.json index 4326848ea..12962d2dd 100644 --- a/nimbus-registryports.json +++ b/nimbus-registryports.json @@ -1,9 +1,3 @@ [ - { - "Protocol": "TCP", - "Name": "Registry Port", - "Description": "HTTP port the registry listens on. Must be reachable from every proxy and every backend on the network, and from nowhere else.", - "Port": 8765, - "Ref": "RegistryPort" - } + {"Protocol":"TCP","Name":"Registry Port","Description":"Nimbus Registry HTTP endpoint used by Proxy and backends","Port":8765,"Ref":"RegistryPort"} ] diff --git a/nimbus-registrystart.json b/nimbus-registrystart.json index 4611c2230..ec4a61519 100644 --- a/nimbus-registrystart.json +++ b/nimbus-registrystart.json @@ -1,18 +1,18 @@ [ - { - "UpdateStageName": "Render nimbus.registry.toml", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "Executable", - "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"NR_WRITE='{{RegistryWriteConfig}}' NR_BIND='{{RegistryBindScheme}}:{{$RegistryPort}}' NR_SECRET='{{RegistrySharedSecret}}' NR_ACCEPTED='{{RegistryAcceptedSecrets}}' NR_STALE='{{RegistryBackendStaleSeconds}}' NR_DROP='{{RegistryBackendDropSeconds}}' NR_NONCE='{{RegistryNonceWindowSeconds}}' NR_MAXRESTTL='{{RegistryMaxReservationTtlSeconds}}' NR_LOGHB='{{RegistryLogHeartbeats}}' NR_STATEDIR='{{RegistryStateDir}}' NR_APITOK='{{RegistryApiTokensEnabled}}' NR_APIRATE='{{RegistryApiTokensRateLimitPerMinute}}' NR_APIFWD='{{RegistryApiTokensTrustForwardedProto}}' NR_I_ADVERTISE='{{RegistryAdvertiseOnMasterServer}}' NR_I_MSURL='{{RegistryMasterServerUrl}}' NR_I_HOST='{{RegistryPublicHost}}' NR_I_PORT='{{RegistryPublicPort}}' NR_I_NAME='{{RegistryServerName}}' NR_I_DESC='{{RegistryServerDescription}}' NR_I_URL='{{RegistryServerUrl}}' NR_I_ICON='{{RegistryServerIcon}}' NR_I_VHID='{{RegistryVhIdentifier}}' NR_I_GAMEVER='{{RegistryGameVersion}}' NR_I_MAXPLAYERS='{{RegistryMaxPlayersOverride}}' NR_I_MODSOURCE='{{RegistryModSource}}' NR_I_MODS='{{RegistryExplicitMods}}' NR_I_WHITELISTED='{{RegistryListingWhitelisted}}' NR_I_HASPASSWORD='{{RegistryListingHasPassword}}' NR_I_HB='{{RegistryMasterHeartbeatIntervalSeconds}}' NR_I_PSID='{{RegistryPlaystyleId}}' NR_I_PSLANG='{{RegistryPlaystyleLangCode}}' bash '{{$FullRootDir}}scripts/write-registry-toml.sh' '{{$FullRootDir}}Nimbus.Registry/nimbus.registry.toml'\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Render nimbus.registry.toml", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "Executable", - "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$env:NR_WRITE='{{RegistryWriteConfig}}'; $env:NR_BIND='{{RegistryBindScheme}}:{{$RegistryPort}}'; $env:NR_SECRET='{{RegistrySharedSecret}}'; $env:NR_ACCEPTED='{{RegistryAcceptedSecrets}}'; $env:NR_STALE='{{RegistryBackendStaleSeconds}}'; $env:NR_DROP='{{RegistryBackendDropSeconds}}'; $env:NR_NONCE='{{RegistryNonceWindowSeconds}}'; $env:NR_MAXRESTTL='{{RegistryMaxReservationTtlSeconds}}'; $env:NR_LOGHB='{{RegistryLogHeartbeats}}'; $env:NR_STATEDIR='{{RegistryStateDir}}'; $env:NR_APITOK='{{RegistryApiTokensEnabled}}'; $env:NR_APIRATE='{{RegistryApiTokensRateLimitPerMinute}}'; $env:NR_APIFWD='{{RegistryApiTokensTrustForwardedProto}}'; $env:NR_I_ADVERTISE='{{RegistryAdvertiseOnMasterServer}}'; $env:NR_I_MSURL='{{RegistryMasterServerUrl}}'; $env:NR_I_HOST='{{RegistryPublicHost}}'; $env:NR_I_PORT='{{RegistryPublicPort}}'; $env:NR_I_NAME='{{RegistryServerName}}'; $env:NR_I_DESC='{{RegistryServerDescription}}'; $env:NR_I_URL='{{RegistryServerUrl}}'; $env:NR_I_ICON='{{RegistryServerIcon}}'; $env:NR_I_VHID='{{RegistryVhIdentifier}}'; $env:NR_I_GAMEVER='{{RegistryGameVersion}}'; $env:NR_I_MAXPLAYERS='{{RegistryMaxPlayersOverride}}'; $env:NR_I_MODSOURCE='{{RegistryModSource}}'; $env:NR_I_MODS='{{RegistryExplicitMods}}'; $env:NR_I_WHITELISTED='{{RegistryListingWhitelisted}}'; $env:NR_I_HASPASSWORD='{{RegistryListingHasPassword}}'; $env:NR_I_HB='{{RegistryMasterHeartbeatIntervalSeconds}}'; $env:NR_I_PSID='{{RegistryPlaystyleId}}'; $env:NR_I_PSLANG='{{RegistryPlaystyleLangCode}}';& '{{$FullRootDir}}scripts\\write-registry-toml.ps1' '{{$FullRootDir}}Nimbus.Registry\\nimbus.registry.toml'\"", - "SkipOnFailure": false - } + { + "UpdateStageName":"Render Nimbus Registry configuration", + "UpdateSourcePlatform":"Linux", + "UpdateSource":"Executable", + "UpdateSourceData":"/bin/bash", + "UpdateSourceArgs":"-c \"NR_BIND_ADDRESS='{{$ApplicationIPBinding}}' NR_REGISTRY_PORT='{{$RegistryPort}}' NR_SHARED_SECRET='{{RegistrySharedSecret}}' NR_ADVERTISE='{{RegistryAdvertise}}' NR_PUBLIC_HOST='{{RegistryPublicHost}}' NR_PUBLIC_PORT='{{RegistryPublicPort}}' NR_SERVER_NAME='{{RegistryServerName}}' NR_SERVER_DESCRIPTION='{{RegistryServerDescription}}' NR_GAME_VERSION='{{RegistryGameVersion}}' NR_HAS_PASSWORD='{{RegistryListingHasPassword}}' NR_WHITELISTED='{{RegistryListingWhitelisted}}' bash '{{$FullRootDir}}scripts/write-registry-toml.sh' '{{$FullRootDir}}Nimbus.Registry/nimbus.registry.toml'\"", + "SkipOnFailure":false + }, + { + "UpdateStageName":"Render Nimbus Registry configuration", + "UpdateSourcePlatform":"Windows", + "UpdateSource":"Executable", + "UpdateSourceData":"powershell.exe", + "UpdateSourceArgs":"-NoProfile -ExecutionPolicy Bypass -Command \"$env:NR_BIND_ADDRESS='{{$ApplicationIPBinding}}'; $env:NR_REGISTRY_PORT='{{$RegistryPort}}'; $env:NR_SHARED_SECRET='{{RegistrySharedSecret}}'; $env:NR_ADVERTISE='{{RegistryAdvertise}}'; $env:NR_PUBLIC_HOST='{{RegistryPublicHost}}'; $env:NR_PUBLIC_PORT='{{RegistryPublicPort}}'; $env:NR_SERVER_NAME='{{RegistryServerName}}'; $env:NR_SERVER_DESCRIPTION='{{RegistryServerDescription}}'; $env:NR_GAME_VERSION='{{RegistryGameVersion}}'; $env:NR_HAS_PASSWORD='{{RegistryListingHasPassword}}'; $env:NR_WHITELISTED='{{RegistryListingWhitelisted}}'; & '{{$FullRootDir}}scripts\\write-registry-toml.ps1' '{{$FullRootDir}}Nimbus.Registry\\nimbus.registry.toml'\"", + "SkipOnFailure":false + } ] diff --git a/nimbus-registryupdates.json b/nimbus-registryupdates.json index 2823057af..aedd5990e 100644 --- a/nimbus-registryupdates.json +++ b/nimbus-registryupdates.json @@ -1,109 +1,75 @@ -[ - { - "UpdateStageName": "Create Nimbus.Registry directory", - "UpdateSourcePlatform": "All", - "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullRootDir}}Nimbus.Registry", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Create dotnet directory", - "UpdateSourcePlatform": "All", - "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullRootDir}}dotnet", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Create scripts directory", - "UpdateSourcePlatform": "All", - "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullRootDir}}scripts", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Write Nimbus installer script (Linux)", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}scripts/install-nimbus.sh", - "UpdateSourceData": "#!/usr/bin/env bash\n# Generated by the AMP Nimbus instance template.\n# Resolves a Nimbus release and installs the requested components out of it.\n# The release zip lays out release_full/Nimbus (proxy), release_full/Nimbus.Registry\n# (standalone registry) and release_full/Nimbus.ServerMod (the Vintage Story mod).\nset -euo pipefail\n\nroot=\"${1:?root directory required}\"\ncomponents=\"${2:?component list required}\"\ncd \"$root\"\n\nrepo=\"StratumServer/Nimbus\"\nhdr=(-H \"User-Agent: AMP-Nimbus-Template\" -H \"Accept: application/vnd.github+json\")\nif [ -n \"${GITHUB_TOKEN:-}\" ]; then hdr+=(-H \"Authorization: Bearer ${GITHUB_TOKEN}\"); fi\n\nfor tool in curl unzip jq; do\n command -v \"$tool\" >/dev/null 2>&1 || { echo \"[AMP] $tool is required but not installed\" >&2; exit 1; }\ndone\n\ntag=\"$(printf '%s' \"${NIMBUS_TAG:-}\" | tr -d '[:space:]')\"\nif [ -z \"$tag\" ]; then\n echo \"[AMP] resolving Nimbus release (channel=${NIMBUS_CHANNEL:-stable})\"\n json=\"$(curl -fsSL \"${hdr[@]}\" \"https://api.github.com/repos/${repo}/releases?per_page=100\")\"\n filter='.[] | select(.draft == false)'\n if [ \"${NIMBUS_CHANNEL:-stable}\" != \"prerelease\" ]; then\n filter=\"${filter} | select(.prerelease == false)\"\n fi\n tag=\"$(printf '%s' \"$json\" | jq -r \"[ ${filter} ] | .[0].tag_name // empty\")\"\nfi\n[ -n \"$tag\" ] || { echo \"[AMP] no Nimbus release matched channel=${NIMBUS_CHANNEL:-stable}\" >&2; exit 1; }\ncase \"$tag\" in v*) ;; *) tag=\"v${tag}\";; esac\n\nmarker=\".amp-nimbus-release\"\nif [ -f \"$marker\" ] && [ \"$(cat \"$marker\")\" = \"$tag\" ]; then\n ok=1\n for comp in $components; do\n [ -d \"$comp\" ] || ok=0\n done\n if [ \"$ok\" = \"1\" ]; then\n echo \"[AMP] already on Nimbus ${tag}; nothing to download\"\n exit 0\n fi\nfi\n\nurl=\"https://github.com/${repo}/releases/download/${tag}/Nimbus-${tag}.zip\"\necho \"[AMP] downloading ${url}\"\nrm -rf .nimbus-extract\nmkdir -p .nimbus-extract\ncurl -fL --retry 3 -o nimbus-release.zip \"$url\"\nunzip -qo nimbus-release.zip -d .nimbus-extract\nrm -f nimbus-release.zip\n\nsrc=\".nimbus-extract/release_full\"\n[ -d \"$src\" ] || src=\".nimbus-extract\"\n\nfor comp in $components; do\n if [ ! -d \"$src/$comp\" ]; then\n echo \"[AMP] component $comp is not present in this release\" >&2\n exit 1\n fi\n mkdir -p \"$comp\"\n # Config, state and plugins live in the component directory, so replace program files\n # only and leave everything the operator or Nimbus itself wrote in place.\n find \"$comp\" -maxdepth 1 -type f \\( -name '*.dll' -o -name '*.pdb' -o -name '*.deps.json' \\\n -o -name '*.runtimeconfig.json' -o -name 'web.config' -o -name '*.staticwebassets.endpoints.json' \\) -delete\n cp -RL \"$src/$comp/.\" \"$comp/\"\ndone\n\nif [ -f \"Nimbus/Nimbus.Proxy\" ]; then chmod +x \"Nimbus/Nimbus.Proxy\"; fi\nif [ -f \"Nimbus.Registry/Nimbus.Registry\" ]; then chmod +x \"Nimbus.Registry/Nimbus.Registry\"; fi\nif [ -f \"$src/LICENSE\" ]; then cp -f \"$src/LICENSE\" ./LICENSE; fi\n\nrm -rf .nimbus-extract\nprintf '%s' \"$tag\" > \"$marker\"\necho \"[AMP] installed Nimbus ${tag} (${components}) into ${root}\"\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, - { - "UpdateStageName": "Write Nimbus installer script (Windows)", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}scripts/install-nimbus.ps1", - "UpdateSourceData": "# Generated by the AMP Nimbus instance template.\nparam(\n [Parameter(Mandatory = $true)][string]$Root,\n [Parameter(Mandatory = $true)][string]$Components\n)\n\n$ErrorActionPreference = 'Stop'\n$ProgressPreference = 'SilentlyContinue'\n[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n\n$repo = 'StratumServer/Nimbus'\n$comps = @($Components -split '[,\\s]+' | Where-Object { $_ -ne '' })\n$headers = @{ 'User-Agent' = 'AMP-Nimbus-Template'; 'Accept' = 'application/vnd.github+json' }\nif ($env:GITHUB_TOKEN) { $headers['Authorization'] = \"Bearer $($env:GITHUB_TOKEN)\" }\n\n$tag = if ($env:NIMBUS_TAG) { $env:NIMBUS_TAG.Trim() } else { '' }\nif ($tag -eq '') {\n $channel = if ($env:NIMBUS_CHANNEL) { $env:NIMBUS_CHANNEL } else { 'stable' }\n Write-Host \"[AMP] resolving Nimbus release (channel=$channel)\"\n $releases = Invoke-RestMethod -Headers $headers -Uri \"https://api.github.com/repos/$repo/releases?per_page=100\"\n $candidates = @($releases | Where-Object { -not $_.draft })\n if ($channel -ne 'prerelease') { $candidates = @($candidates | Where-Object { -not $_.prerelease }) }\n if ($candidates.Count -eq 0) { throw \"No Nimbus release matched channel=$channel\" }\n $tag = $candidates[0].tag_name\n}\nif (-not $tag.StartsWith('v')) { $tag = \"v$tag\" }\n\n$marker = Join-Path $Root '.amp-nimbus-release'\nif ((Test-Path $marker) -and ((Get-Content $marker -Raw).Trim() -eq $tag)) {\n $missing = @($comps | Where-Object { -not (Test-Path (Join-Path $Root $_)) })\n if ($missing.Count -eq 0) {\n Write-Host \"[AMP] already on Nimbus $tag; nothing to download\"\n exit 0\n }\n}\n\n$extract = Join-Path $Root '.nimbus-extract'\nif (Test-Path $extract) { Remove-Item $extract -Recurse -Force }\nNew-Item -ItemType Directory -Force -Path $extract | Out-Null\n\n$zip = Join-Path $Root 'nimbus-release.zip'\n$url = \"https://github.com/$repo/releases/download/$tag/Nimbus-$tag.zip\"\nWrite-Host \"[AMP] downloading $url\"\nInvoke-WebRequest -UseBasicParsing -Headers $headers -Uri $url -OutFile $zip\nExpand-Archive -Path $zip -DestinationPath $extract -Force\nRemove-Item $zip -Force\n\n$src = Join-Path $extract 'release_full'\nif (-not (Test-Path $src)) { $src = $extract }\n\n$programPatterns = @('*.dll', '*.pdb', '*.deps.json', '*.runtimeconfig.json', 'web.config', '*.staticwebassets.endpoints.json')\nforeach ($comp in $comps) {\n $from = Join-Path $src $comp\n if (-not (Test-Path $from)) { throw \"Component $comp is not present in this release\" }\n $to = Join-Path $Root $comp\n New-Item -ItemType Directory -Force -Path $to | Out-Null\n # Replace program files only; nimbus.proxy.toml, state files and plugins stay put.\n foreach ($pattern in $programPatterns) {\n Get-ChildItem -LiteralPath $to -Filter $pattern -File -ErrorAction SilentlyContinue | Remove-Item -Force\n }\n Copy-Item -Path (Join-Path $from '*') -Destination $to -Recurse -Force\n}\n\n$license = Join-Path $src 'LICENSE'\nif (Test-Path $license) { Copy-Item -Path $license -Destination (Join-Path $Root 'LICENSE') -Force }\n\nRemove-Item $extract -Recurse -Force\nSet-Content -Path $marker -Value $tag -NoNewline\nWrite-Host \"[AMP] installed Nimbus $tag ($Components) into $Root\"\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, - { - "UpdateStageName": "Write config renderer script (Linux)", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}scripts/write-registry-toml.sh", - "UpdateSourceData": "#!/usr/bin/env bash\n# Renders nimbus.registry.toml from environment variables set by AMP.\n# Generated by the AMP Nimbus instance template; edits here are overwritten on the next update.\nset -uf\n\nOUT=\"${1:-}\"\nif [ -z \"$OUT\" ]; then echo \"usage: $0 \" >&2; exit 1; fi\nif [ \"$(printf '%s' \"${NR_WRITE:-true}\" | tr 'A-Z' 'a-z')\" != \"true\" ]; then\n echo \"AMP management of $(basename \"$OUT\") is disabled, leaving the existing file alone\"\n exit 0\nfi\n\nTMP=\"$OUT.amptmp\"\nmkdir -p \"$(dirname \"$OUT\")\"\n: > \"$TMP\"\n\nesc() { printf '%s' \"${1-}\" | sed -e 's/\\\\/\\\\\\\\/g' -e 's/\"/\\\\\"/g'; }\nbl() { case \"$(printf '%s' \"${1-}\" | tr 'A-Z' 'a-z')\" in true|1|yes|on) printf 'true';; *) printf 'false';; esac }\nnum() { case \"${1-}\" in ''|*[!0-9-]*) printf '%s' \"${2-0}\";; *) printf '%s' \"$1\";; esac }\ntrim() { printf '%s' \"${1-}\" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'; }\nlst() {\n local out=\"\" first=1 x\n local IFS=','\n for x in ${1-}; do\n x=\"$(trim \"$x\")\"\n [ -z \"$x\" ] && continue\n if [ $first -eq 1 ]; then first=0; else out=\"$out, \"; fi\n out=\"$out\\\"$(esc \"$x\")\\\"\"\n done\n printf '[%s]' \"$out\"\n}\nsrv() {\n local x k v\n local IFS=','\n for x in ${1-}; do\n x=\"$(trim \"$x\")\"\n [ -z \"$x\" ] && continue\n case \"$x\" in *=*) ;; *) echo \"skipping malformed servers entry '$x' (expected id=host:port)\" >&2; continue;; esac\n k=\"$(trim \"${x%%=*}\")\"; v=\"$(trim \"${x#*=}\")\"\n if [ -z \"$k\" ] || [ -z \"$v\" ]; then\n echo \"skipping malformed servers entry '$x' (expected id=host:port)\" >&2\n continue\n fi\n printf '\"%s\" = \"%s\"\\n' \"$(esc \"$k\")\" \"$(esc \"$v\")\" >> \"$TMP\"\n done\n}\nfh() {\n local x k v\n local IFS=','\n for x in ${1-}; do\n x=\"$(trim \"$x\")\"\n [ -z \"$x\" ] && continue\n case \"$x\" in *=*) ;; *) echo \"skipping malformed forced_hosts entry '$x' (expected hostname=id1|id2)\" >&2; continue;; esac\n k=\"$(trim \"${x%%=*}\")\"; v=\"$(trim \"${x#*=}\")\"\n [ -z \"$k\" ] && continue\n printf '\"%s\" = %s\\n' \"$(esc \"$k\")\" \"$(lst \"$(printf '%s' \"$v\" | tr '|' ',')\")\" >> \"$TMP\"\n done\n}\nmods() {\n local out=\"\" first=1 x k v\n local IFS=','\n for x in ${1-}; do\n x=\"$(trim \"$x\")\"\n [ -z \"$x\" ] && continue\n case \"$x\" in\n *=*) k=\"$(trim \"${x%%=*}\")\"; v=\"$(trim \"${x#*=}\")\";;\n *) k=\"$x\"; v=\"\";;\n esac\n if [ $first -eq 1 ]; then first=0; else out=\"$out, \"; fi\n out=\"$out{ id = \\\"$(esc \"$k\")\\\", version = \\\"$(esc \"$v\")\\\" }\"\n done\n printf '[%s]' \"$out\"\n}\nkeep_secret() {\n local key=\"$1\" val=\"${2:-}\" f=\"$3\" cur=\"\"\n if [ -n \"$val\" ]; then printf '%s' \"$val\"; return; fi\n if [ -f \"$f\" ]; then\n cur=\"$(sed -n \"s/^[[:space:]]*${key}[[:space:]]*=[[:space:]]*\\\"\\(.*\\)\\\".*/\\1/p\" \"$f\" | head -n 1)\"\n case \"$cur\" in\n \"\"|change-me-and-keep-secret) ;;\n *) printf '%s' \"$cur\"; return;;\n esac\n fi\n echo \"[AMP] no ${key} set, generating a random one; read it out of $(basename \"$f\") and paste it into every backend\" >&2\n head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \\n'\n}\nprintf 'bind_url = \"%s\"\\n' \"$(esc \"${NR_BIND:-http://0.0.0.0:8765}\")\" >> \"$TMP\"\nprintf 'shared_secret = \"%s\"\\n' \"$(esc \"$(keep_secret shared_secret \"${NR_SECRET:-}\" \"$OUT\")\")\" >> \"$TMP\"\nprintf 'accepted_secrets = %s\\n' \"$(lst \"${NR_ACCEPTED:-}\")\" >> \"$TMP\"\nprintf 'backend_stale_seconds = %s\\n' \"$(num \"${NR_STALE:-20}\" 20)\" >> \"$TMP\"\nprintf 'backend_drop_seconds = %s\\n' \"$(num \"${NR_DROP:-120}\" 120)\" >> \"$TMP\"\nprintf 'nonce_window_seconds = %s\\n' \"$(num \"${NR_NONCE:-90}\" 90)\" >> \"$TMP\"\nprintf 'max_reservation_ttl_seconds = %s\\n' \"$(num \"${NR_MAXRESTTL:-300}\" 300)\" >> \"$TMP\"\nprintf 'log_heartbeats = %s\\n' \"$(bl \"${NR_LOGHB:-false}\")\" >> \"$TMP\"\nprintf 'state_dir = \"%s\"\\n' \"$(esc \"${NR_STATEDIR:-.}\")\" >> \"$TMP\"\nprintf '\\n[api_tokens]\\n' >> \"$TMP\"\nprintf 'enabled = %s\\n' \"$(bl \"${NR_APITOK:-false}\")\" >> \"$TMP\"\nprintf 'rate_limit_per_minute = %s\\n' \"$(num \"${NR_APIRATE:-60}\" 60)\" >> \"$TMP\"\nprintf 'trust_forwarded_proto = %s\\n' \"$(bl \"${NR_APIFWD:-false}\")\" >> \"$TMP\"\nprintf '\\n[identity]\\n' >> \"$TMP\"\nprintf 'advertise_on_master_server = %s\\n' \"$(bl \"${NR_I_ADVERTISE:-false}\")\" >> \"$TMP\"\nprintf 'master_server_url = \"%s\"\\n' \"$(esc \"${NR_I_MSURL:-http://masterserver.vintagestory.at/api/v1/servers/}\")\" >> \"$TMP\"\nprintf 'public_host = \"%s\"\\n' \"$(esc \"${NR_I_HOST:-127.0.0.1}\")\" >> \"$TMP\"\nprintf 'public_port = %s\\n' \"$(num \"${NR_I_PORT:-42420}\" 42420)\" >> \"$TMP\"\nprintf 'server_name = \"%s\"\\n' \"$(esc \"${NR_I_NAME:-Nimbus Network}\")\" >> \"$TMP\"\nprintf 'server_description = \"%s\"\\n' \"$(esc \"${NR_I_DESC:-}\")\" >> \"$TMP\"\nprintf 'server_url = \"%s\"\\n' \"$(esc \"${NR_I_URL:-}\")\" >> \"$TMP\"\nprintf 'server_icon = \"%s\"\\n' \"$(esc \"${NR_I_ICON:-}\")\" >> \"$TMP\"\nprintf 'vh_identifier = \"%s\"\\n' \"$(esc \"${NR_I_VHID:-}\")\" >> \"$TMP\"\nprintf 'game_version = \"%s\"\\n' \"$(esc \"${NR_I_GAMEVER:-1.22.2}\")\" >> \"$TMP\"\nprintf 'max_players_override = %s\\n' \"$(num \"${NR_I_MAXPLAYERS:-0}\" 0)\" >> \"$TMP\"\nprintf 'mod_source = \"%s\"\\n' \"$(esc \"${NR_I_MODSOURCE:-aggregate}\")\" >> \"$TMP\"\nprintf 'explicit_mods = %s\\n' \"$(mods \"${NR_I_MODS:-}\")\" >> \"$TMP\"\nprintf 'whitelisted = %s\\n' \"$(bl \"${NR_I_WHITELISTED:-false}\")\" >> \"$TMP\"\nprintf 'has_password = %s\\n' \"$(bl \"${NR_I_HASPASSWORD:-false}\")\" >> \"$TMP\"\nprintf 'heartbeat_interval_seconds = %s\\n' \"$(num \"${NR_I_HB:-120}\" 120)\" >> \"$TMP\"\nprintf '\\n[identity.playstyle]\\n' >> \"$TMP\"\nprintf 'id = \"%s\"\\n' \"$(esc \"${NR_I_PSID:-surviveandbuild}\")\" >> \"$TMP\"\nprintf 'lang_code = \"%s\"\\n' \"$(esc \"${NR_I_PSLANG:-preset-surviveandbuild}\")\" >> \"$TMP\"\nmv -f \"$TMP\" \"$OUT\"\necho \"wrote $OUT\"\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, - { - "UpdateStageName": "Write config renderer script (Windows)", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}scripts/write-registry-toml.ps1", - "UpdateSourceData": "# Renders nimbus.registry.toml from environment variables set by AMP.\n# Generated by the AMP Nimbus instance template; edits here are overwritten on the next update.\nparam([Parameter(Mandatory = $true)][string]$Out)\n$ErrorActionPreference = 'Stop'\n\nfunction D([string]$v, [string]$d) { if ([string]::IsNullOrWhiteSpace($v)) { return $d } return $v }\nfunction Esc([string]$s) { if ($null -eq $s) { return '' } return $s.Replace('\\', '\\\\').Replace('\"', '\\\"') }\nfunction B([string]$s) { if ($null -eq $s) { return 'false' } if (@('true', '1', 'yes', 'on') -contains $s.Trim().ToLowerInvariant()) { return 'true' } return 'false' }\nfunction I([string]$s, [int]$d) { $n = 0; if ([int]::TryParse(($s -replace '\\s', ''), [ref]$n)) { return \"$n\" } return \"$d\" }\nfunction L([string]$s) {\n $parts = @()\n foreach ($x in ($s -split ',')) { $t = $x.Trim(); if ($t -ne '') { $parts += ('\"' + (Esc $t) + '\"') } }\n return '[' + ($parts -join ', ') + ']'\n}\nfunction Pair([string]$x) {\n $i = $x.IndexOf('=')\n if ($i -lt 1) { return $null }\n return @{ Key = $x.Substring(0, $i).Trim(); Value = $x.Substring($i + 1).Trim() }\n}\nfunction SrvLines($list, [string]$s) {\n foreach ($x in ($s -split ',')) {\n $t = $x.Trim(); if ($t -eq '') { continue }\n $p = Pair $t\n if ($null -eq $p -or $p.Key -eq '' -or $p.Value -eq '') { Write-Output \"skipping malformed servers entry '$t' (expected id=host:port)\"; continue }\n $list.Add('\"' + (Esc $p.Key) + '\" = \"' + (Esc $p.Value) + '\"')\n }\n}\nfunction FhLines($list, [string]$s) {\n foreach ($x in ($s -split ',')) {\n $t = $x.Trim(); if ($t -eq '') { continue }\n $p = Pair $t\n if ($null -eq $p -or $p.Key -eq '') { Write-Output \"skipping malformed forced_hosts entry '$t' (expected hostname=id1|id2)\"; continue }\n $list.Add('\"' + (Esc $p.Key) + '\" = ' + (L ($p.Value -replace '\\|', ',')))\n }\n}\nfunction Mods([string]$s) {\n $parts = @()\n foreach ($x in ($s -split ',')) {\n $t = $x.Trim(); if ($t -eq '') { continue }\n $p = Pair $t\n if ($null -eq $p) { $parts += ('{ id = \"' + (Esc $t) + '\", version = \"\" }') }\n else { $parts += ('{ id = \"' + (Esc $p.Key) + '\", version = \"' + (Esc $p.Value) + '\" }') }\n }\n return '[' + ($parts -join ', ') + ']'\n}\nfunction KeepSecret([string]$key, [string]$val, [string]$file) {\n if (-not [string]::IsNullOrWhiteSpace($val)) { return $val }\n if (Test-Path -LiteralPath $file) {\n $pattern = '^\\s*' + [regex]::Escape($key) + '\\s*=\\s*\"(.*)\"'\n $m = Select-String -LiteralPath $file -Pattern $pattern | Select-Object -First 1\n if ($m) {\n $cur = $m.Matches[0].Groups[1].Value\n if ($cur -ne '' -and $cur -ne 'change-me-and-keep-secret') { return $cur }\n }\n }\n Write-Host (\"[AMP] no $key set, generating a random one; read it out of \" + (Split-Path -Leaf $file) + \" and paste it into every backend\")\n $bytes = New-Object byte[] 32\n $rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()\n $rng.GetBytes($bytes)\n return (($bytes | ForEach-Object { $_.ToString('x2') }) -join '')\n}\n\nif ((B (D $env:NR_WRITE 'true')) -ne 'true') {\n Write-Output (\"AMP management of \" + (Split-Path -Leaf $Out) + \" is disabled, leaving the existing file alone\")\n exit 0\n}\n\n$dir = Split-Path -Parent $Out\nif ($dir -and -not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null }\n$L = New-Object System.Collections.Generic.List[string]\n$L.Add('bind_url = \"' + (Esc (D $env:NR_BIND 'http://0.0.0.0:8765')) + '\"')\n$L.Add('shared_secret = \"' + (Esc (KeepSecret 'shared_secret' $env:NR_SECRET $Out)) + '\"')\n$L.Add('accepted_secrets = ' + (L (D $env:NR_ACCEPTED '')))\n$L.Add('backend_stale_seconds = ' + (I (D $env:NR_STALE '20') 20))\n$L.Add('backend_drop_seconds = ' + (I (D $env:NR_DROP '120') 120))\n$L.Add('nonce_window_seconds = ' + (I (D $env:NR_NONCE '90') 90))\n$L.Add('max_reservation_ttl_seconds = ' + (I (D $env:NR_MAXRESTTL '300') 300))\n$L.Add('log_heartbeats = ' + (B (D $env:NR_LOGHB 'false')))\n$L.Add('state_dir = \"' + (Esc (D $env:NR_STATEDIR '.')) + '\"')\n$L.Add('')\n$L.Add('[api_tokens]')\n$L.Add('enabled = ' + (B (D $env:NR_APITOK 'false')))\n$L.Add('rate_limit_per_minute = ' + (I (D $env:NR_APIRATE '60') 60))\n$L.Add('trust_forwarded_proto = ' + (B (D $env:NR_APIFWD 'false')))\n$L.Add('')\n$L.Add('[identity]')\n$L.Add('advertise_on_master_server = ' + (B (D $env:NR_I_ADVERTISE 'false')))\n$L.Add('master_server_url = \"' + (Esc (D $env:NR_I_MSURL 'http://masterserver.vintagestory.at/api/v1/servers/')) + '\"')\n$L.Add('public_host = \"' + (Esc (D $env:NR_I_HOST '127.0.0.1')) + '\"')\n$L.Add('public_port = ' + (I (D $env:NR_I_PORT '42420') 42420))\n$L.Add('server_name = \"' + (Esc (D $env:NR_I_NAME 'Nimbus Network')) + '\"')\n$L.Add('server_description = \"' + (Esc (D $env:NR_I_DESC '')) + '\"')\n$L.Add('server_url = \"' + (Esc (D $env:NR_I_URL '')) + '\"')\n$L.Add('server_icon = \"' + (Esc (D $env:NR_I_ICON '')) + '\"')\n$L.Add('vh_identifier = \"' + (Esc (D $env:NR_I_VHID '')) + '\"')\n$L.Add('game_version = \"' + (Esc (D $env:NR_I_GAMEVER '1.22.2')) + '\"')\n$L.Add('max_players_override = ' + (I (D $env:NR_I_MAXPLAYERS '0') 0))\n$L.Add('mod_source = \"' + (Esc (D $env:NR_I_MODSOURCE 'aggregate')) + '\"')\n$L.Add('explicit_mods = ' + (Mods (D $env:NR_I_MODS '')))\n$L.Add('whitelisted = ' + (B (D $env:NR_I_WHITELISTED 'false')))\n$L.Add('has_password = ' + (B (D $env:NR_I_HASPASSWORD 'false')))\n$L.Add('heartbeat_interval_seconds = ' + (I (D $env:NR_I_HB '120') 120))\n$L.Add('')\n$L.Add('[identity.playstyle]')\n$L.Add('id = \"' + (Esc (D $env:NR_I_PSID 'surviveandbuild')) + '\"')\n$L.Add('lang_code = \"' + (Esc (D $env:NR_I_PSLANG 'preset-surviveandbuild')) + '\"')\n$tmp = \"$Out.amptmp\"\nSet-Content -LiteralPath $tmp -Value $L -Encoding UTF8\nMove-Item -LiteralPath $tmp -Destination $Out -Force\nWrite-Output \"wrote $Out\"\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, - { - "UpdateStageName": ".NET SDK Download", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "Executable", - "UpdateSourceArch": "x86_64", - "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"DotnetVersion=\\\"{{DotnetSDKVersion}}\\\"; cd \\\"{{$FullBaseDir}}\\\" && if [[ -x dotnet/dotnet ]]; then InstalledVersion=$(dotnet/dotnet --version | xargs); else InstalledVersion=\\\"\\\"; fi; if [[ -z \\\"$DotnetVersion\\\" ]]; then DotnetVersion=$(wget -qO- https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json | jq -r \\\".[\\\\\\\"latest-sdk\\\\\\\"]\\\"); fi; if [[ ! \\\"$DotnetVersion\\\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+$ ]]; then echo \\\"Invalid .NET SDK version format specified\\\" && exit 1; elif [[ \\\"$InstalledVersion\\\" == \\\"$DotnetVersion\\\" ]]; then echo \\\".NET SDK v$DotnetVersion already installed. Skipping\\\" && exit 0; else [[ -f dotnet.tar.gz ]] && rm -f dotnet.tar.gz >/dev/null 2>&1; wget -qO dotnet.tar.gz https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-linux-x64.tar.gz || { echo \\\"Download failed from the Microsoft CDN. This is a fault with the CDN, not AMP. Aborting\\\"; exit 1; }; rm -rf dotnet/* >/dev/null 2>&1 && tar -xzf dotnet.tar.gz -C dotnet >/dev/null 2>&1 && rm -f dotnet.tar.gz >/dev/null 2>&1 && echo \\\".NET SDK v$DotnetVersion downloaded\\\"; fi\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": ".NET SDK Download", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "Executable", - "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -Command \"$ProgressPreference='SilentlyContinue'; [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $DotnetVersion='{{DotnetSDKVersion}}'; Set-Location -Path '{{$FullBaseDir}}'; if (Test-Path 'dotnet/dotnet.exe') { $InstalledVersion = (& dotnet/dotnet.exe --version).Trim() } else { $InstalledVersion = '' }; if ( [string]::IsNullOrWhiteSpace($DotnetVersion) ) { $DotnetVersion=(Invoke-RestMethod -UseBasicParsing -Uri https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json).\\\"latest-sdk\\\" }; if ($DotnetVersion -notmatch '^\\d+\\.\\d+\\.\\d+$') { Write-Output \\\"Invalid .NET SDK version format specified\\\"; exit 1 } elseif ( $InstalledVersion -eq $DotnetVersion ) { Write-Output \\\".NET SDK v$DotnetVersion already installed. Skipping\\\"; exit 0 } else { if ( Test-Path dotnet.zip ) { Remove-Item dotnet.zip -Force -ErrorAction SilentlyContinue *> $null }; try { Invoke-WebRequest -UseBasicParsing -Uri https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-win-x64.zip -OutFile dotnet.zip -ErrorAction Stop } catch { Write-Output \\\"Download failed from the Microsoft CDN. This is a fault with the CDN, not AMP. Aborting\\\"; exit 1; }; Remove-Item -Path 'dotnet/*' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive -Path \\\"dotnet.zip\\\" -DestinationPath \\\"dotnet\\\" -Force *> $null; if ( Test-Path dotnet.zip ) { Remove-Item dotnet.zip -Force -ErrorAction SilentlyContinue *> $null }; Write-Output \\\".NET SDK v$DotnetVersion downloaded\\\" }\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Nimbus Download", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "Executable", - "UpdateSourceArch": "x86_64", - "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"NIMBUS_TAG='{{NimbusVersionTag}}' NIMBUS_CHANNEL='{{NimbusReleaseChannel}}' GITHUB_TOKEN='{{NimbusGitHubToken}}' bash '{{$FullRootDir}}scripts/install-nimbus.sh' '{{$FullRootDir}}' '{{NimbusUpdateComponents}}'\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Nimbus Download", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "Executable", - "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$env:NIMBUS_TAG='{{NimbusVersionTag}}'; $env:NIMBUS_CHANNEL='{{NimbusReleaseChannel}}'; $env:GITHUB_TOKEN='{{NimbusGitHubToken}}'; & '{{$FullRootDir}}scripts\\install-nimbus.ps1' '{{$FullRootDir}}' '{{NimbusUpdateComponents}}'\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Render nimbus.registry.toml", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "Executable", - "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"NR_WRITE='{{RegistryWriteConfig}}' NR_BIND='{{RegistryBindScheme}}:{{$RegistryPort}}' NR_SECRET='{{RegistrySharedSecret}}' NR_ACCEPTED='{{RegistryAcceptedSecrets}}' NR_STALE='{{RegistryBackendStaleSeconds}}' NR_DROP='{{RegistryBackendDropSeconds}}' NR_NONCE='{{RegistryNonceWindowSeconds}}' NR_MAXRESTTL='{{RegistryMaxReservationTtlSeconds}}' NR_LOGHB='{{RegistryLogHeartbeats}}' NR_STATEDIR='{{RegistryStateDir}}' NR_APITOK='{{RegistryApiTokensEnabled}}' NR_APIRATE='{{RegistryApiTokensRateLimitPerMinute}}' NR_APIFWD='{{RegistryApiTokensTrustForwardedProto}}' NR_I_ADVERTISE='{{RegistryAdvertiseOnMasterServer}}' NR_I_MSURL='{{RegistryMasterServerUrl}}' NR_I_HOST='{{RegistryPublicHost}}' NR_I_PORT='{{RegistryPublicPort}}' NR_I_NAME='{{RegistryServerName}}' NR_I_DESC='{{RegistryServerDescription}}' NR_I_URL='{{RegistryServerUrl}}' NR_I_ICON='{{RegistryServerIcon}}' NR_I_VHID='{{RegistryVhIdentifier}}' NR_I_GAMEVER='{{RegistryGameVersion}}' NR_I_MAXPLAYERS='{{RegistryMaxPlayersOverride}}' NR_I_MODSOURCE='{{RegistryModSource}}' NR_I_MODS='{{RegistryExplicitMods}}' NR_I_WHITELISTED='{{RegistryListingWhitelisted}}' NR_I_HASPASSWORD='{{RegistryListingHasPassword}}' NR_I_HB='{{RegistryMasterHeartbeatIntervalSeconds}}' NR_I_PSID='{{RegistryPlaystyleId}}' NR_I_PSLANG='{{RegistryPlaystyleLangCode}}' bash '{{$FullRootDir}}scripts/write-registry-toml.sh' '{{$FullRootDir}}Nimbus.Registry/nimbus.registry.toml'\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Render nimbus.registry.toml", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "Executable", - "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$env:NR_WRITE='{{RegistryWriteConfig}}'; $env:NR_BIND='{{RegistryBindScheme}}:{{$RegistryPort}}'; $env:NR_SECRET='{{RegistrySharedSecret}}'; $env:NR_ACCEPTED='{{RegistryAcceptedSecrets}}'; $env:NR_STALE='{{RegistryBackendStaleSeconds}}'; $env:NR_DROP='{{RegistryBackendDropSeconds}}'; $env:NR_NONCE='{{RegistryNonceWindowSeconds}}'; $env:NR_MAXRESTTL='{{RegistryMaxReservationTtlSeconds}}'; $env:NR_LOGHB='{{RegistryLogHeartbeats}}'; $env:NR_STATEDIR='{{RegistryStateDir}}'; $env:NR_APITOK='{{RegistryApiTokensEnabled}}'; $env:NR_APIRATE='{{RegistryApiTokensRateLimitPerMinute}}'; $env:NR_APIFWD='{{RegistryApiTokensTrustForwardedProto}}'; $env:NR_I_ADVERTISE='{{RegistryAdvertiseOnMasterServer}}'; $env:NR_I_MSURL='{{RegistryMasterServerUrl}}'; $env:NR_I_HOST='{{RegistryPublicHost}}'; $env:NR_I_PORT='{{RegistryPublicPort}}'; $env:NR_I_NAME='{{RegistryServerName}}'; $env:NR_I_DESC='{{RegistryServerDescription}}'; $env:NR_I_URL='{{RegistryServerUrl}}'; $env:NR_I_ICON='{{RegistryServerIcon}}'; $env:NR_I_VHID='{{RegistryVhIdentifier}}'; $env:NR_I_GAMEVER='{{RegistryGameVersion}}'; $env:NR_I_MAXPLAYERS='{{RegistryMaxPlayersOverride}}'; $env:NR_I_MODSOURCE='{{RegistryModSource}}'; $env:NR_I_MODS='{{RegistryExplicitMods}}'; $env:NR_I_WHITELISTED='{{RegistryListingWhitelisted}}'; $env:NR_I_HASPASSWORD='{{RegistryListingHasPassword}}'; $env:NR_I_HB='{{RegistryMasterHeartbeatIntervalSeconds}}'; $env:NR_I_PSID='{{RegistryPlaystyleId}}'; $env:NR_I_PSLANG='{{RegistryPlaystyleLangCode}}';& '{{$FullRootDir}}scripts\\write-registry-toml.ps1' '{{$FullRootDir}}Nimbus.Registry\\nimbus.registry.toml'\"", - "SkipOnFailure": false - } -] +[ + { + "UpdateStageName": "Create dotnet directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}dotnet", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create Nimbus Registry directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}Nimbus.Registry", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create scripts directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}scripts", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Install local .NET 10 runtime", + "UpdateSourcePlatform": "Linux", + "UpdateSourceArch": "x86_64", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"set -euo pipefail; root=\u0027{{$FullRootDir}}\u0027; if [ -x \\\"$root/dotnet/dotnet\\\" ] \u0026\u0026 \\\"$root/dotnet/dotnet\\\" --list-runtimes | grep -q \u0027^Microsoft.NETCore.App 10\\.\u0027; then echo \u0027[AMP] .NET 10 runtime already installed\u0027; else tmp=\\\"$(mktemp)\\\"; curl -fsSL https://dot.net/v1/dotnet-install.sh -o \\\"$tmp\\\"; bash \\\"$tmp\\\" --channel 10.0 --runtime dotnet --install-dir \\\"$root/dotnet\\\" --no-path; rm -f \\\"$tmp\\\"; fi\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Install local .NET 10 runtime", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference=\u0027Stop\u0027; $root=\u0027{{$FullRootDir}}\u0027; $dotnet=Join-Path $root \u0027dotnet\\dotnet.exe\u0027; $ready=$false; if (Test-Path -LiteralPath $dotnet) { $ready=[bool]((\u0026 $dotnet --list-runtimes) -match \u0027^Microsoft.NETCore.App 10\\.\u0027) }; if ($ready) { Write-Output \u0027[AMP] .NET 10 runtime already installed\u0027 } else { $script=Join-Path $env:TEMP (\u0027dotnet-install-\u0027+[guid]::NewGuid().ToString(\u0027N\u0027)+\u0027.ps1\u0027); try { Invoke-WebRequest -UseBasicParsing -Uri https://dot.net/v1/dotnet-install.ps1 -OutFile $script; \u0026 $script -Channel 10.0 -Runtime dotnet -InstallDir (Join-Path $root \u0027dotnet\u0027) -NoPath } finally { Remove-Item -LiteralPath $script -Force -ErrorAction SilentlyContinue } }\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Install Nimbus Registry", + "UpdateSourcePlatform": "Linux", + "UpdateSourceArch": "x86_64", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"set -euo pipefail; root=\u0027{{$FullRootDir}}\u0027; tag=\u0027{{NimbusVersionTag}}\u0027; if [ -z \\\"$tag\\\" ]; then tag=\\\"$(curl -fsSL -H \u0027User-Agent: AMP-Clean-Template\u0027 https://api.github.com/repos/StratumServer/Nimbus/releases/latest | jq -r .tag_name)\\\"; fi; case \\\"$tag\\\" in v*) ;; *) tag=\\\"v$tag\\\";; esac; stage=\\\"$root/.amp-registry-stage\\\"; archive=\\\"$root/.amp-registry.zip\\\"; old=\\\"$root/.amp-registry-old\\\"; rm -rf \\\"$stage\\\" \\\"$old\\\"; mkdir -p \\\"$stage\\\"; curl -fL --retry 3 -o \\\"$archive\\\" \\\"https://github.com/StratumServer/Nimbus/releases/download/$tag/Nimbus-$tag.zip\\\"; unzip -q \\\"$archive\\\" -d \\\"$stage\\\"; rm -f \\\"$archive\\\"; fresh_dll=\\\"$(find \\\"$stage\\\" -type f -name Nimbus.Registry.dll -print -quit)\\\"; [ -n \\\"$fresh_dll\\\" ]; fresh=\\\"$(dirname \\\"$fresh_dll\\\")\\\"; if [ -f \\\"$root/Nimbus.Registry/nimbus.registry.toml\\\" ]; then cp \\\"$root/Nimbus.Registry/nimbus.registry.toml\\\" \\\"$fresh/nimbus.registry.toml\\\"; fi; for name in nimbus.bans.json nimbus.whitelist.json nimbus.tokens.json; do for file in \\\"$root/Nimbus.Registry/$name\\\"*; do [ -f \\\"$file\\\" ] \u0026\u0026 cp \\\"$file\\\" \\\"$fresh/\\\"; done; done; if [ -d \\\"$root/Nimbus.Registry\\\" ]; then mv \\\"$root/Nimbus.Registry\\\" \\\"$old\\\"; fi; mv \\\"$fresh\\\" \\\"$root/Nimbus.Registry\\\"; rm -rf \\\"$stage\\\" \\\"$old\\\"; printf \u0027%s\u0027 \\\"$tag\\\" \u003e \\\"$root/Nimbus.Registry/.amp-nimbus-release\\\"\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Install Nimbus Registry", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference=\u0027Stop\u0027; $ProgressPreference=\u0027SilentlyContinue\u0027; $root=\u0027{{$FullRootDir}}\u0027; $tag=\u0027{{NimbusVersionTag}}\u0027.Trim(); $headers=@{\u0027User-Agent\u0027=\u0027AMP-Clean-Template\u0027}; if (-not $tag) { $tag=(Invoke-RestMethod -Headers $headers -Uri https://api.github.com/repos/StratumServer/Nimbus/releases/latest).tag_name }; if (-not $tag.StartsWith(\u0027v\u0027)) { $tag=\u0027v\u0027+$tag }; $stage=Join-Path $root \u0027.amp-registry-stage\u0027; $archive=Join-Path $root \u0027.amp-registry.zip\u0027; $target=Join-Path $root \u0027Nimbus.Registry\u0027; $old=Join-Path $root \u0027.amp-registry-old\u0027; Remove-Item -LiteralPath $stage,$old,$archive -Recurse -Force -ErrorAction SilentlyContinue; New-Item -ItemType Directory -Path $stage | Out-Null; Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri (\u0027https://github.com/StratumServer/Nimbus/releases/download/\u0027+$tag+\u0027/Nimbus-\u0027+$tag+\u0027.zip\u0027) -OutFile $archive; Expand-Archive -LiteralPath $archive -DestinationPath $stage -Force; Remove-Item -LiteralPath $archive -Force; $freshDll=Get-ChildItem -LiteralPath $stage -Filter \u0027Nimbus.Registry.dll\u0027 -File -Recurse | Select-Object -First 1; if ($null -eq $freshDll) { throw \u0027Nimbus archive did not contain Nimbus.Registry.dll\u0027 }; $fresh=$freshDll.Directory.FullName; foreach ($pattern in @(\u0027nimbus.registry.toml\u0027,\u0027nimbus.bans.json*\u0027,\u0027nimbus.whitelist.json*\u0027,\u0027nimbus.tokens.json*\u0027)) { Get-ChildItem -LiteralPath $target -Filter $pattern -File -ErrorAction SilentlyContinue | ForEach-Object { Copy-Item -LiteralPath $_.FullName -Destination $fresh -Force } }; if (Test-Path -LiteralPath $target) { Move-Item -LiteralPath $target -Destination $old }; try { Move-Item -LiteralPath $fresh -Destination $target; Remove-Item -LiteralPath $stage,$old -Recurse -Force -ErrorAction SilentlyContinue } catch { if ((Test-Path -LiteralPath $old) -and -not (Test-Path -LiteralPath $target)) { Move-Item -LiteralPath $old -Destination $target }; throw }; [IO.File]::WriteAllText((Join-Path $target \u0027.amp-nimbus-release\u0027),$tag,(New-Object Text.UTF8Encoding $false))\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Deploy Registry renderer (Linux)", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/write-registry-toml.sh", + "UpdateSourceData": "#!/usr/bin/env bash\nset -euo pipefail\n\ntarget=\"${1:?target path required}\"\n\nTomlQuote() {\n local value=\"${1-}\"\n value=${value//\\/\\\\}; value=${value//\\\"/\\\\\\\"}\n value=${value//$\u0027\\r\u0027/\\\\r}; value=${value//$\u0027\\n\u0027/\\\\n}; value=${value//$\u0027\\t\u0027/\\\\t}\n printf \u0027\"%s\"\u0027 \"$value\"\n}\nReadExistingSecret() { [ -f \"$1\" ] || return 0; sed -n \u0027s/^[[:space:]]*shared_secret[[:space:]]*=[[:space:]]*\"\\([0-9A-Fa-f]*\\)\"[[:space:]]*$/\\1/p\u0027 \"$1\" | head -n 1; }\nNewRandomSecret() { od -An -N32 -tx1 /dev/urandom | tr -d \u0027 \\n\u0027; }\nResolveSecret() {\n local panel=\"$1\" existing=\"$2\" lower\n panel=\"$(printf \u0027%s\u0027 \"$panel\" | sed \u0027s/^[[:space:]]*//;s/[[:space:]]*$//\u0027)\"; lower=\"$(printf \u0027%s\u0027 \"$panel\" | tr \u0027[:upper:]\u0027 \u0027[:lower:]\u0027)\"\n case \"$lower\" in change-me*|paste*secret*|shared-secret|shared_secret|\"shared secret\"|your-secret|your_secret|\"your secret\"|replace-me*) echo \u0027The shared secret is a documented placeholder, not a usable secret\u0027 \u003e\u00262; return 1;; esac\n if [ -n \"$panel\" ]; then printf \u0027%s\u0027 \"$panel\"; elif [ -n \"$existing\" ]; then printf \u0027%s\u0027 \"$existing\"; else NewRandomSecret; fi\n}\nParsePort() { local value=\"$1\" name=\"$2\"; [[ \"$value\" =~ ^[0-9]+$ ]] \u0026\u0026 (( value \u003e= 1 \u0026\u0026 value \u003c= 65535 )) || { echo \"$name must be from 1 through 65535\" \u003e\u00262; return 1; }; printf \u0027%s\u0027 \"$value\"; }\nParseBool() { local value=\"${1,,}\" name=\"$2\"; case \"$value\" in true|false) printf \u0027%s\u0027 \"$value\";; *) echo \"$name must be true or false\" \u003e\u00262; return 1;; esac; }\nWriteAtomic() { local path=\"$1\" content=\"$2\" directory temporary; directory=\"$(dirname \"$path\")\"; mkdir -p \"$directory\"; temporary=\"$directory/.$(basename \"$path\").$$.$RANDOM.tmp\"; trap \u0027rm -f \"$temporary\"\u0027 RETURN; printf \u0027%s\u0027 \"$content\" \u003e \"$temporary\"; mv -f \"$temporary\" \"$path\"; trap - RETURN; }\n\nregistry_port=\"$(ParsePort \"${NR_REGISTRY_PORT:-8765}\" \u0027Registry port\u0027)\"\npublic_port=\"$(ParsePort \"${NR_PUBLIC_PORT:-42420}\" \u0027Proxy public port\u0027)\"\nadvertise=\"$(ParseBool \"${NR_ADVERTISE:-false}\" \u0027Master-server advertising\u0027)\"\nhas_password=\"$(ParseBool \"${NR_HAS_PASSWORD:-false}\" \u0027Password listing flag\u0027)\"\nwhitelisted=\"$(ParseBool \"${NR_WHITELISTED:-false}\" \u0027Whitelist listing flag\u0027)\"\npublic_host=\"${NR_PUBLIC_HOST-}\"; game_version=\"${NR_GAME_VERSION:-1.22.6}\"\nif [ \"$advertise\" = true ]; then [ -n \"$public_host\" ] || { echo \u0027Advertising requires the public hostname or IP of Nimbus Proxy\u0027 \u003e\u00262; exit 1; }; [ -n \"$game_version\" ] || { echo \u0027Advertising requires the Vintage Story game version supported by the selected Stratum release\u0027 \u003e\u00262; exit 1; }; fi\nsecret=\"$(ResolveSecret \"${NR_SHARED_SECRET:-}\" \"$(ReadExistingSecret \"$target\")\")\"\n\ncontent=\"bind_url = $(TomlQuote \"http://${NR_BIND_ADDRESS:-0.0.0.0}:${registry_port}\")\nshared_secret = $(TomlQuote \"$secret\")\naccepted_secrets = []\nbackend_stale_seconds = 20\nbackend_drop_seconds = 120\nnonce_window_seconds = 90\nmax_reservation_ttl_seconds = 300\nlog_heartbeats = false\nstate_dir = \\\".\\\"\n\n[api_tokens]\nenabled = false\nrate_limit_per_minute = 60\ntrust_forwarded_proto = false\n\n[identity]\nadvertise_on_master_server = ${advertise}\nmaster_server_url = \\\"http://masterserver.vintagestory.at/api/v1/servers/\\\"\npublic_host = $(TomlQuote \"$public_host\")\npublic_port = ${public_port}\nserver_name = $(TomlQuote \"${NR_SERVER_NAME:-Nimbus Network}\")\nserver_description = $(TomlQuote \"${NR_SERVER_DESCRIPTION:-}\")\nserver_url = \\\"\\\"\nserver_icon = \\\"\\\"\nvh_identifier = \\\"\\\"\ngame_version = $(TomlQuote \"$game_version\")\nmax_players_override = 0\nmod_source = \\\"aggregate\\\"\nexplicit_mods = []\nwhitelisted = ${whitelisted}\nhas_password = ${has_password}\nheartbeat_interval_seconds = 120\n\n[identity.playstyle]\nid = \\\"surviveandbuild\\\"\nlang_code = \\\"preset-surviveandbuild\\\"\n\"\nWriteAtomic \"$target\" \"$content\"\nprintf \u0027wrote %s\\n\u0027 \"$target\"\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Deploy Registry renderer (Windows)", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}scripts/write-registry-toml.ps1", + "UpdateSourceData": "param([Parameter(Mandatory = $true)][string]$Target)\n\n$ErrorActionPreference = \u0027Stop\u0027\n\nfunction Get-Value([string]$Name, [string]$Default = \u0027\u0027) {\n $value = [Environment]::GetEnvironmentVariable($Name)\n if ($null -eq $value) { return $Default }\n return $value\n}\n\nfunction TomlQuote([string]$Value) {\n if ($null -eq $Value) { $Value = \u0027\u0027 }\n $Value = $Value.Replace(\u0027\\\u0027, \u0027\\\\\u0027).Replace(\u0027\"\u0027, \u0027\\\"\u0027)\n $Value = $Value.Replace(\"`r\", \u0027\\r\u0027).Replace(\"`n\", \u0027\\n\u0027).Replace(\"`t\", \u0027\\t\u0027)\n return \u0027\"\u0027 + $Value + \u0027\"\u0027\n}\n\nfunction ReadExistingSecret([string]$Path) {\n if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) { return \u0027\u0027 }\n foreach ($line in [IO.File]::ReadAllLines($Path)) {\n $match = [regex]::Match($line, \u0027^\\s*shared_secret\\s*=\\s*\"([0-9A-Fa-f]+)\"\\s*$\u0027)\n if ($match.Success) { return $match.Groups[1].Value }\n }\n return \u0027\u0027\n}\n\nfunction NewRandomSecret() {\n $bytes = New-Object byte[] 32\n $rng = [Security.Cryptography.RandomNumberGenerator]::Create()\n try { $rng.GetBytes($bytes) } finally { $rng.Dispose() }\n return (($bytes | ForEach-Object { $_.ToString(\u0027x2\u0027) }) -join \u0027\u0027)\n}\n\nfunction ResolveSecret([string]$PanelValue, [string]$ExistingValue) {\n $value = $PanelValue.Trim()\n $placeholder = \u0027^(?i)(change-me.*|paste.*secret.*|shared[-_ ]?secret|your[-_ ]?secret|replace[-_ ]?me.*)$\u0027\n if ($value -match $placeholder) { throw \u0027The shared secret is a documented placeholder, not a usable secret\u0027 }\n if ($value -ne \u0027\u0027) { return $value }\n if ($ExistingValue -ne \u0027\u0027) { return $ExistingValue }\n return NewRandomSecret\n}\n\nfunction ParseBool([string]$Value, [string]$Name) {\n switch ($Value.Trim().ToLowerInvariant()) {\n \u0027true\u0027 { return \u0027true\u0027 }\n \u0027false\u0027 { return \u0027false\u0027 }\n default { throw \"$Name must be true or false\" }\n }\n}\n\nfunction ParsePort([string]$Value, [string]$Name) {\n $port = 0\n if (-not [int]::TryParse($Value, [ref]$port) -or $port -lt 1 -or $port -gt 65535) { throw \"$Name must be from 1 through 65535\" }\n return $port\n}\n\nfunction WriteAtomic([string]$Path, [string]$Content) {\n $directory = Split-Path -Parent $Path\n if ($directory -and -not (Test-Path -LiteralPath $directory)) { New-Item -ItemType Directory -Path $directory -Force | Out-Null }\n $temporary = Join-Path $directory (\u0027.\u0027 + [IO.Path]::GetFileName($Path) + \u0027.\u0027 + [guid]::NewGuid().ToString(\u0027N\u0027) + \u0027.tmp\u0027)\n try {\n [IO.File]::WriteAllText($temporary, $Content, (New-Object Text.UTF8Encoding $false))\n Move-Item -LiteralPath $temporary -Destination $Path -Force\n }\n finally {\n if (Test-Path -LiteralPath $temporary) { Remove-Item -LiteralPath $temporary -Force }\n }\n}\n\n$bindAddress = Get-Value \u0027NR_BIND_ADDRESS\u0027 \u00270.0.0.0\u0027\n$registryPort = ParsePort (Get-Value \u0027NR_REGISTRY_PORT\u0027 \u00278765\u0027) \u0027Registry port\u0027\n$publicPort = ParsePort (Get-Value \u0027NR_PUBLIC_PORT\u0027 \u002742420\u0027) \u0027Proxy public port\u0027\n$advertise = ParseBool (Get-Value \u0027NR_ADVERTISE\u0027 \u0027false\u0027) \u0027Master-server advertising\u0027\n$hasPassword = ParseBool (Get-Value \u0027NR_HAS_PASSWORD\u0027 \u0027false\u0027) \u0027Password listing flag\u0027\n$whitelisted = ParseBool (Get-Value \u0027NR_WHITELISTED\u0027 \u0027false\u0027) \u0027Whitelist listing flag\u0027\n$publicHost = (Get-Value \u0027NR_PUBLIC_HOST\u0027 \u0027\u0027).Trim()\n$gameVersion = (Get-Value \u0027NR_GAME_VERSION\u0027 \u00271.22.6\u0027).Trim()\nif ($advertise -eq \u0027true\u0027) {\n if ($publicHost -eq \u0027\u0027) { throw \u0027Advertising requires the public hostname or IP of Nimbus Proxy\u0027 }\n if ($gameVersion -eq \u0027\u0027) { throw \u0027Advertising requires the Vintage Story game version supported by the selected Stratum release\u0027 }\n}\n$secret = ResolveSecret (Get-Value \u0027NR_SHARED_SECRET\u0027 \u0027\u0027) (ReadExistingSecret $Target)\n\n$lines = New-Object System.Collections.Generic.List[string]\n$lines.Add(\u0027bind_url = \u0027 + (TomlQuote \"http://${bindAddress}:$registryPort\"))\n$lines.Add(\u0027shared_secret = \u0027 + (TomlQuote $secret))\n$lines.Add(\u0027accepted_secrets = []\u0027)\n$lines.Add(\u0027backend_stale_seconds = 20\u0027)\n$lines.Add(\u0027backend_drop_seconds = 120\u0027)\n$lines.Add(\u0027nonce_window_seconds = 90\u0027)\n$lines.Add(\u0027max_reservation_ttl_seconds = 300\u0027)\n$lines.Add(\u0027log_heartbeats = false\u0027)\n$lines.Add(\u0027state_dir = \".\"\u0027)\n$lines.Add(\u0027\u0027)\n$lines.Add(\u0027[api_tokens]\u0027)\n$lines.Add(\u0027enabled = false\u0027)\n$lines.Add(\u0027rate_limit_per_minute = 60\u0027)\n$lines.Add(\u0027trust_forwarded_proto = false\u0027)\n$lines.Add(\u0027\u0027)\n$lines.Add(\u0027[identity]\u0027)\n$lines.Add(\u0027advertise_on_master_server = \u0027 + $advertise)\n$lines.Add(\u0027master_server_url = \"http://masterserver.vintagestory.at/api/v1/servers/\"\u0027)\n$lines.Add(\u0027public_host = \u0027 + (TomlQuote $publicHost))\n$lines.Add(\u0027public_port = \u0027 + $publicPort)\n$lines.Add(\u0027server_name = \u0027 + (TomlQuote (Get-Value \u0027NR_SERVER_NAME\u0027 \u0027Nimbus Network\u0027)))\n$lines.Add(\u0027server_description = \u0027 + (TomlQuote (Get-Value \u0027NR_SERVER_DESCRIPTION\u0027 \u0027\u0027)))\n$lines.Add(\u0027server_url = \"\"\u0027)\n$lines.Add(\u0027server_icon = \"\"\u0027)\n$lines.Add(\u0027vh_identifier = \"\"\u0027)\n$lines.Add(\u0027game_version = \u0027 + (TomlQuote $gameVersion))\n$lines.Add(\u0027max_players_override = 0\u0027)\n$lines.Add(\u0027mod_source = \"aggregate\"\u0027)\n$lines.Add(\u0027explicit_mods = []\u0027)\n$lines.Add(\u0027whitelisted = \u0027 + $whitelisted)\n$lines.Add(\u0027has_password = \u0027 + $hasPassword)\n$lines.Add(\u0027heartbeat_interval_seconds = 120\u0027)\n$lines.Add(\u0027\u0027)\n$lines.Add(\u0027[identity.playstyle]\u0027)\n$lines.Add(\u0027id = \"surviveandbuild\"\u0027)\n$lines.Add(\u0027lang_code = \"preset-surviveandbuild\"\u0027)\n\nWriteAtomic $Target (($lines -join \"`n\") + \"`n\")\nWrite-Output \"wrote $Target\"\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + } +] \ No newline at end of file diff --git a/vintage-story-stratum.kvp b/vintage-story-stratum.kvp index 86725ad8e..1a3ce3000 100644 --- a/vintage-story-stratum.kvp +++ b/vintage-story-stratum.kvp @@ -1,5 +1,5 @@ -Meta.DisplayName=Vintage Story (Stratum + Nimbus) -Meta.Description=Vintage Story dedicated server running the Stratum performance/hardening fork, with the Nimbus backend mod for multi-server networks. Stratum releases pin the exact Vintage Story version and download the matching vanilla assets automatically. +Meta.DisplayName=Vintage Story (Stratum + Nimbus Backend) +Meta.Description=Vintage Story backend using Stratum and Nimbus.ServerMod. Players connect through Nimbus Proxy. Meta.OS=Windows, Linux Meta.AarchSupport=None Meta.Arch=x86_64 @@ -19,11 +19,11 @@ Meta.Prerequisites=[] Meta.ConfigReleaseState=NotSpecified Meta.NoCommercialUsage=False Meta.ConfigVersion=1 -Meta.AppConfigId=7f3b1c42-5d18-4a6e-9b21-2c7f5ea41d90 +Meta.AppConfigId=ac764031-4749-46d1-b662-d3e9de8d9356 Meta.AppIsMultiIPAware=True -Meta.ResourceUsageInfo=2 CPU cores and 4GB RAM minimum per backend server, 4 cores and 8GB recommended for busy worlds +Meta.ResourceUsageInfo=4 GB RAM minimum; 8 GB recommended for active worlds Meta.ImportableExtensions=[] -App.DisplayName=Vintage Story (Stratum) +App.DisplayName=Vintage Story (Stratum Backend) App.RootDir=./vintage-story/ App.BaseDirectory=./vintage-story/ App.ExecutableWin=server\StratumServer.exe @@ -31,7 +31,7 @@ App.ExecutableLinux=server/StratumServer App.WorkingDir=server App.LinuxCommandLineArgs= App.WindowsCommandLineArgs= -App.CommandLineArgs={{$PlatformArgs}} --port {{$ServerPort}} --dataPath "../data" {{StratumExtraArgs}} {{$FormattedArgs}} +App.CommandLineArgs={{$PlatformArgs}} --port {{$ServerPort}} --dataPath "../data" {{$FormattedArgs}} App.UseLinuxIOREDIR=False App.AppSettings={} App.EnvironmentVariables={"DOTNET_ROOT":"{{$FullRootDir}}dotnet","DOTNET_CLI_TELEMETRY_OPTOUT":"1","DOTNET_NOLOGO":"1"} @@ -51,9 +51,9 @@ App.AdminPortRef=ServerPort App.PrimaryApplicationPortRef=ServerPort App.UniversalSleepApplicationUDPPortRef=ServerPort App.UniversalSleepSteamQueryPortRef=ServerPort -App.MaxUsers=16 +App.MaxUsers={{$MaxUsers}} App.UseRandomAdminPassword=False -App.RemoteAdminPassword=Password123 +App.RemoteAdminPassword= App.AdminMethod=STDIO App.AdminLoginTransform=None App.RCONConnectDelaySeconds=5 @@ -61,7 +61,6 @@ App.RCONConnectRetrySeconds=5 App.RCONHeartbeatMinutes=0 App.RCONHeartbeatCommand=ping App.TelnetLoginFormat={0} -App.PreStartStages=@IncludeJson[vintage-story-stratumstart.json] App.UpdateSources=@IncludeJson[vintage-story-stratumupdates.json] App.Compatibility=None App.SteamUpdateAnonymousLogin=True @@ -76,14 +75,14 @@ App.SupportsUniversalSleep=False App.WakeupMode=Any App.ApplicationReadyMode=RegexMatch App.StripANSIControlCodes=True -Console.FilterMatchRegex=|<\/font> +Console.FilterMatchRegex=^.*(?:|).*$ Console.FilterMatchReplacement= Console.ThrowawayMessageRegex=^(WARNING|ERROR): Shader.+$ -Console.AppReadyRegex=^[\d\.]*\s*[\d:\.]+ \[.*Event\] (?:Dedicated Server|Serveur dédié|Dedizierter Server) now running on Port \d+ and (?:all ips|ip .*)!$ -Console.UserJoinRegex=^[\d\.]*\s*[\d:\.]+ \[.*Event\] (?.+?) [\[\]a-f\d:.]+ joins\.$ -Console.UserLeaveRegex=^[\d\.]*\s*[\d:\.]+ \[.*Event\] Player (?.+?) (left|got removed\. Reason: Server shutting down - Shutdown via server command).*$ -Console.UserChatRegex=^[\d\.]*\s*[\d:\.]+ \[.*Chat\] (?.+?): (?.+?): (?.+)$ -Console.UpdateAvailableRegex=^.*(?:A new server update is available!|UPDATE AVAILABLE: running ).*$ +Console.AppReadyRegex=^[\d.]*\s*[\d:.]+ \[.*Event\] (?:Dedicated Server|Serveur dédié|Dedizierter Server) now running on Port \d+ and (?:all ips|ip .*)!$ +Console.UserJoinRegex=^[\d.]*\s*[\d:.]+ \[.*Event\] (?.+?) [\[\]a-f\d:.]+ joins\.$ +Console.UserLeaveRegex=^[\d.]*\s*[\d:.]+ \[.*Event\] Player (?.+?) (left|got removed\. Reason: Server shutting down - Shutdown via server command).*$ +Console.UserChatRegex=^[\d.]*\s*[\d:.]+ \[.*Chat\] (?.+?): (?.+?): (?.+)$ +Console.UpdateAvailableRegex=^.*(?:Stratum update available:|A new server update is available!|UPDATE AVAILABLE: running ).*$ Console.MetricsRegex= Console.SuppressLogAtStart=False Console.ActivateLogRegex= diff --git a/vintage-story-stratumconfig.json b/vintage-story-stratumconfig.json index ffffec017..3b63b70b4 100644 --- a/vintage-story-stratumconfig.json +++ b/vintage-story-stratumconfig.json @@ -1,9781 +1,26 @@ [ - { - "DisplayName": "Port", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Game port. Managed by AMP - change it under Configuration -> Network, not here.", - "Keywords": "port", - "FieldName": "$ServerPort", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Port", - "IncludeInCommandLine": false, - "DefaultValue": "42420", - "EnumValues": {}, - "Hidden": true - }, - { - "DisplayName": "Server Name", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Server name shown in the server browser and to the Nimbus network.", - "Keywords": "server,name", - "FieldName": "VS_ServerName", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.ServerName", - "IncludeInCommandLine": false, - "DefaultValue": "Vintage Story Server - Powered by AMP", - "EnumValues": {} - }, - { - "DisplayName": "Server Description", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Longer description shown in the server browser. VTML markup is supported.", - "Keywords": "description,motd", - "FieldName": "VS_ServerDescription", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.ServerDescription", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Server URL", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Website shown alongside the server listing.", - "Keywords": "url,website", - "FieldName": "VS_ServerUrl", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.ServerUrl", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Welcome Message", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Message sent when a player joins. {0} is replaced with the player name. Must not be empty on 1.19 and below.", - "Keywords": "welcome,message,motd", - "FieldName": "VS_WelcomeMessage", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.WelcomeMessage", - "IncludeInCommandLine": false, - "DefaultValue": "Welcome, {0}, may you survive well and prosper", - "EnumValues": {} - }, - { - "DisplayName": "Server Password", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Password players must enter. Leave empty for an open server. On a Nimbus network set this on the proxy instead.", - "Keywords": "password", - "FieldName": "VS_Password", - "InputType": "password", - "IsFlagArgument": false, - "ParamFieldName": "$.Password", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Make Server Public", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Publish this server to the public server list. On a Nimbus network leave this OFF for backends and let the proxy or registry advertise the network instead.", - "Keywords": "public,advertise", - "FieldName": "VS_AdvertiseServer", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.AdvertiseServer", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Master Server URL", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Master server used for the public listing. Only change this when self-hosting a master server. Keep the trailing slash.", - "Keywords": "masterserver", - "FieldName": "VS_MasterserverUrl", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.MasterserverUrl", - "IncludeInCommandLine": false, - "DefaultValue": "http://masterserver.vintagestory.at/api/v1/servers/", - "EnumValues": {} - }, - { - "DisplayName": "Mod DB URL", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Mod database used by the server for mod lookups.", - "Keywords": "moddb", - "FieldName": "VS_ModDbUrl", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.ModDbUrl", - "IncludeInCommandLine": false, - "DefaultValue": "https://mods.vintagestory.at/", - "EnumValues": {} - }, - { - "DisplayName": "Compress Packets", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Compress network packets. Leave on unless profiling says otherwise.", - "Keywords": "compress,packets", - "FieldName": "VS_CompressPackets", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.CompressPackets", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enable UPnP", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Ask the router to forward the game port automatically. Leave off on hosted machines.", - "Keywords": "upnp", - "FieldName": "VS_Upnp", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Upnp", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "UPnP Infinite Lifetime", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Request a port mapping with no expiry instead of a renewed lease.", - "Keywords": "upnp,lifetime", - "FieldName": "VS_UpnpInfiniteLifetime", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.UpnpInfiniteLifetime", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Player Limit", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Players:group:2", - "Description": "Maximum number of players allowed on this server.", - "Keywords": "players,limit,slots", - "FieldName": "$MaxUsers", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.MaxClients", - "IncludeInCommandLine": false, - "DefaultValue": "16", - "EnumValues": {}, - "Suffix": "players", - "MinValue": "1" - }, - { - "DisplayName": "Queue Size", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Players:group:2", - "Description": "How many extra players may wait in the connection queue when the server is full. 0 disables the queue.", - "Keywords": "queue", - "FieldName": "VS_MaxClientsInQueue", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.MaxClientsInQueue", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {}, - "Suffix": "players", - "MinValue": "0" - }, - { - "DisplayName": "Whitelist Mode", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Players:group:2", - "Description": "Whitelist behaviour on 1.20+. Default means on for dedicated servers.", - "Keywords": "whitelist", - "FieldName": "VS_WhitelistMode", - "InputType": "enum", - "IsFlagArgument": false, - "ParamFieldName": "$.WhitelistMode", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": { - "0": "Default", - "1": "Off", - "2": "On" - } - }, - { - "DisplayName": "Enable Whitelist (Legacy)", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Players:group:2", - "Description": "Legacy whitelist switch for 1.19 and below. Ignored on 1.20+.", - "Keywords": "whitelist,legacy", - "FieldName": "VS_OnlyWhitelisted", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.OnlyWhitelisted", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Verify Player Auth", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Players:group:2", - "Description": "Require players to be authenticated game owners. Turning this off allows cracked clients.", - "Keywords": "auth,verify", - "FieldName": "VS_VerifyPlayerAuth", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.VerifyPlayerAuth", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Login Flood Protection", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Players:group:2", - "Description": "Rate limit repeated connection attempts from the same address.", - "Keywords": "login,flood", - "FieldName": "VS_LoginFloodProtection", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.LoginFloodProtection", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Temporary IP Block List", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Players:group:2", - "Description": "Temporarily block addresses that trip abuse protection.", - "Keywords": "ip,block", - "FieldName": "VS_TemporaryIpBlockList", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.TemporaryIpBlockList", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Client Connection Timeout", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Players:group:2", - "Description": "Seconds without traffic before a client is dropped.", - "Keywords": "timeout", - "FieldName": "VS_ClientConnectionTimeout", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ClientConnectionTimeout", - "IncludeInCommandLine": false, - "DefaultValue": "150", - "EnumValues": {}, - "Suffix": "seconds", - "MinValue": "10" - }, - { - "DisplayName": "AFK Warn After", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Players:group:2", - "Description": "Warn a player after this many idle seconds. 0 disables AFK warnings.", - "Keywords": "afk,warn", - "FieldName": "VS_WarnClientsAfterAfkSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.WarnClientsAfterAfkSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {}, - "Suffix": "seconds", - "MinValue": "0" - }, - { - "DisplayName": "AFK Kick After", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Players:group:2", - "Description": "Kick a player after this many idle seconds. 0 disables AFK kicking.", - "Keywords": "afk,kick", - "FieldName": "VS_KickClientsAfterAfkSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.KickClientsAfterAfkSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {}, - "Suffix": "seconds", - "MinValue": "0" - }, - { - "DisplayName": "Anti Abuse Level", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Players:group:2", - "Description": "Vanilla abuse protection level. Stratum's own anticheat is configured under the Stratum categories and is far more granular.", - "Keywords": "antiabuse,cheat", - "FieldName": "VS_AntiAbuse", - "InputType": "enum", - "IsFlagArgument": false, - "ParamFieldName": "$.AntiAbuse", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": { - "0": "0 - Off", - "1": "1 - Basic", - "2": "2 - Strict" - } - }, - { - "DisplayName": "Group Chat History Size", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Players:group:2", - "Description": "Number of group chat messages kept in history.", - "Keywords": "chat,group,history", - "FieldName": "VS_GroupChatHistorySize", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.GroupChatHistorySize", - "IncludeInCommandLine": false, - "DefaultValue": "20", - "EnumValues": {}, - "MinValue": "0" - }, - { - "DisplayName": "Max Group Channels Per Player", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Players:group:2", - "Description": "How many chat groups a single player may own.", - "Keywords": "chat,group,channels", - "FieldName": "VS_MaxOwnedGroupChannelsPerUser", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.MaxOwnedGroupChannelsPerUser", - "IncludeInCommandLine": false, - "DefaultValue": "10", - "EnumValues": {}, - "MinValue": "0" - }, - { - "DisplayName": "Allow PvP", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Gameplay:sports_esports:3", - "Description": "Allow players to damage each other.", - "Keywords": "pvp", - "FieldName": "VS_AllowPvP", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.AllowPvP", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Allow Fire Spread", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Gameplay:sports_esports:3", - "Description": "Allow fire to spread to neighbouring blocks.", - "Keywords": "fire", - "FieldName": "VS_AllowFireSpread", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.AllowFireSpread", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Allow Falling Blocks", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Gameplay:sports_esports:3", - "Description": "Allow gravity-affected blocks to fall.", - "Keywords": "gravity,blocks", - "FieldName": "VS_AllowFallingBlocks", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.AllowFallingBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Pass Time When Empty", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Gameplay:sports_esports:3", - "Description": "Keep advancing world time while no players are online.", - "Keywords": "time,empty", - "FieldName": "VS_PassTimeWhenEmpty", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.PassTimeWhenEmpty", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Entity Debug Mode", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Gameplay:sports_esports:3", - "Description": "Send entity debug information to clients.", - "Keywords": "debug,entity", - "FieldName": "VS_EntityDebugMode", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityDebugMode", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Startup Commands", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Gameplay:sports_esports:3", - "Description": "Server commands run on every start, separated by \\n. Example: /time set 8:00\\n/weather clear", - "Keywords": "startup,commands", - "FieldName": "VS_StartupCommands", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.StartupCommands", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Spawn Cap Player Scaling", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Gameplay:sports_esports:3", - "Description": "How much the creature cap grows per additional player.", - "Keywords": "spawn,cap,mobs", - "FieldName": "VS_SpawnCapPlayerScaling", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.SpawnCapPlayerScaling", - "IncludeInCommandLine": false, - "DefaultValue": "0.5", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "World Name", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "World:public:4", - "Description": "Display name of the world save.", - "Keywords": "world,name", - "FieldName": "VS_WorldConfig_WorldName", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.WorldConfig.WorldName", - "IncludeInCommandLine": false, - "DefaultValue": "A new world", - "EnumValues": {} - }, - { - "DisplayName": "Play Style", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "World:public:4", - "Description": "World preset id, applied when the world is first created: surviveandbuild, wildernesssurvival, exploration, homosapiens, creativebuilding.", - "Keywords": "playstyle,preset", - "FieldName": "VS_WorldConfig_PlayStyle", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.WorldConfig.PlayStyle", - "IncludeInCommandLine": false, - "DefaultValue": "surviveandbuild", - "EnumValues": {} - }, - { - "DisplayName": "Play Style Lang Code", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "World:public:4", - "Description": "Language code that belongs to the chosen play style, for example surviveandbuild-bands.", - "Keywords": "playstyle,lang", - "FieldName": "VS_WorldConfig_PlayStyleLangCode", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.WorldConfig.PlayStyleLangCode", - "IncludeInCommandLine": false, - "DefaultValue": "surviveandbuild-bands", - "EnumValues": {} - }, - { - "DisplayName": "World Type", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "World:public:4", - "Description": "standard or superflat. Only used when the world is created.", - "Keywords": "worldtype,superflat", - "FieldName": "VS_WorldConfig_WorldType", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.WorldConfig.WorldType", - "IncludeInCommandLine": false, - "DefaultValue": "standard", - "EnumValues": {} - }, - { - "DisplayName": "World Seed", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "World:public:4", - "Description": "Seed used when the world is created. Empty means random.", - "Keywords": "seed", - "FieldName": "VS_WorldConfig_Seed", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.WorldConfig.Seed", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Allow Creative Mode", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "World:public:4", - "Description": "Allow creative mode in this world.", - "Keywords": "creative", - "FieldName": "VS_WorldConfig_AllowCreativeMode", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.WorldConfig.AllowCreativeMode", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "World Height", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "World:public:4", - "Description": "World height in blocks. Only applied when the world is created.", - "Keywords": "height,mapsize", - "FieldName": "VS_WorldConfig_MapSizeY", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.WorldConfig.MapSizeY", - "IncludeInCommandLine": false, - "DefaultValue": "256", - "EnumValues": {}, - "MinValue": "0" - }, - { - "DisplayName": "World Repair Mode", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "World:public:4", - "Description": "Load the world in repair mode. Diagnostic use only.", - "Keywords": "repair", - "FieldName": "VS_WorldConfig_RepairMode", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.WorldConfig.RepairMode", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Max Chunk Radius", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Performance:speed:5", - "Description": "Server side view distance in chunks. Stratum's adaptive radius controller can override this at runtime.", - "Keywords": "chunks,radius,viewdistance", - "FieldName": "VS_MaxChunkRadius", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.MaxChunkRadius", - "IncludeInCommandLine": false, - "DefaultValue": "12", - "EnumValues": {}, - "Suffix": "chunks", - "MinValue": "1" - }, - { - "DisplayName": "Tick Time", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Performance:speed:5", - "Description": "Target milliseconds per server tick. 33.333332 is 30 ticks per second.", - "Keywords": "tick,tps", - "FieldName": "VS_TickTime", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.TickTime", - "IncludeInCommandLine": false, - "DefaultValue": "33.333332", - "EnumValues": {}, - "Decimal": true, - "Suffix": "ms" - }, - { - "DisplayName": "Block Tick Interval", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Performance:speed:5", - "Description": "Milliseconds between random block tick passes.", - "Keywords": "blocktick", - "FieldName": "VS_BlockTickInterval", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockTickInterval", - "IncludeInCommandLine": false, - "DefaultValue": "300", - "EnumValues": {}, - "Suffix": "ms", - "MinValue": "1" - }, - { - "DisplayName": "Random Block Ticks Per Chunk", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Performance:speed:5", - "Description": "How many random block ticks each chunk gets per pass.", - "Keywords": "blocktick,random", - "FieldName": "VS_RandomBlockTicksPerChunk", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.RandomBlockTicksPerChunk", - "IncludeInCommandLine": false, - "DefaultValue": "16", - "EnumValues": {}, - "MinValue": "0" - }, - { - "DisplayName": "Block Tick Chunk Range", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Performance:speed:5", - "Description": "Radius in chunks around players that receives random block ticks.", - "Keywords": "blocktick,range", - "FieldName": "VS_BlockTickChunkRange", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockTickChunkRange", - "IncludeInCommandLine": false, - "DefaultValue": "5", - "EnumValues": {}, - "Suffix": "chunks", - "MinValue": "0" - }, - { - "DisplayName": "Max Main Thread Block Ticks", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Performance:speed:5", - "Description": "Upper bound of block ticks executed on the main thread per tick.", - "Keywords": "blocktick,mainthread", - "FieldName": "VS_MaxMainThreadBlockTicks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.MaxMainThreadBlockTicks", - "IncludeInCommandLine": false, - "DefaultValue": "10000", - "EnumValues": {}, - "MinValue": "0" - }, - { - "DisplayName": "Corruption Protection", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Reliability:health_and_safety:6", - "Description": "Write extra checksums so corrupt chunks can be detected.", - "Keywords": "corruption", - "FieldName": "VS_CorruptionProtection", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.CorruptionProtection", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Regenerate Corrupt Chunks", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Reliability:health_and_safety:6", - "Description": "Regenerate chunks that fail the corruption check instead of failing the load.", - "Keywords": "corruption,regenerate", - "FieldName": "VS_RegenerateCorruptChunks", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.RegenerateCorruptChunks", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Log Block Break/Place", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Reliability:health_and_safety:6", - "Description": "Log every block break and place. Useful for grief investigations, noisy on busy servers.", - "Keywords": "log,blocks,griefing", - "FieldName": "VS_LogBlockBreakPlace", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.LogBlockBreakPlace", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Split Log After Lines", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Reliability:health_and_safety:6", - "Description": "Start a new log file after this many lines.", - "Keywords": "log,split", - "FieldName": "VS_LogFileSplitAfterLine", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.LogFileSplitAfterLine", - "IncludeInCommandLine": false, - "DefaultValue": "500000", - "EnumValues": {}, - "MinValue": "1000" - }, - { - "DisplayName": "Shut Down Below Disk Space", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Reliability:health_and_safety:6", - "Description": "Shut the server down when free disk space drops below this, protecting the save from a truncated write.", - "Keywords": "disk,space", - "FieldName": "VS_DieBelowDiskSpaceMb", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.DieBelowDiskSpaceMb", - "IncludeInCommandLine": false, - "DefaultValue": "400", - "EnumValues": {}, - "Suffix": "MB", - "MinValue": "0" - }, - { - "DisplayName": "Shut Down Above Memory Usage", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Reliability:health_and_safety:6", - "Description": "Shut the server down when memory use exceeds this value.", - "Keywords": "memory,ram", - "FieldName": "VS_DieAboveMemoryUsageMb", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.DieAboveMemoryUsageMb", - "IncludeInCommandLine": false, - "DefaultValue": "50000", - "EnumValues": {}, - "Suffix": "MB", - "MinValue": "0" - }, - { - "DisplayName": "Shut Down Above Error Count", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Reliability:health_and_safety:6", - "Description": "Shut the server down after this many logged errors.", - "Keywords": "errors", - "FieldName": "VS_DieAboveErrorCount", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.DieAboveErrorCount", - "IncludeInCommandLine": false, - "DefaultValue": "100000", - "EnumValues": {}, - "MinValue": "0" - }, - { - "DisplayName": "Disable Mod Safety Check", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Mods & Advanced:extension:7", - "Description": "Skip the mod sandbox checks. Only for trusted mod sets.", - "Keywords": "mods,safety,sandbox", - "FieldName": "VS_DisableModSafetyCheck", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.DisableModSafetyCheck", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Disable Auto Remap", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Mods & Advanced:extension:7", - "Description": "Disable automatic block id remapping when the mod set changes.", - "Keywords": "mods,remap", - "FieldName": "VS_DisableAutoRemap", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.DisableAutoRemap", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Hosted Mode", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Mods & Advanced:extension:7", - "Description": "Locks down settings a hosting provider controls: max clients, chunk radius, UPnP, tick time and block ticking. Leave off on AMP.", - "Keywords": "hosted", - "FieldName": "VS_HostedMode", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.HostedMode", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Hosted Mode Allow Mods", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Mods & Advanced:extension:7", - "Description": "Allow mods while hosted mode is enabled.", - "Keywords": "hosted,mods", - "FieldName": "VS_HostedModeAllowMods", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.HostedModeAllowMods", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Repair Mode", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Mods & Advanced:extension:7", - "Description": "Start the server in repair mode. Diagnostic use only.", - "Keywords": "repair", - "FieldName": "VS_RepairMode", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.RepairMode", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Analyze Mode", - "Category": "Vintage Story:stadia_controller", - "Subcategory": "Mods & Advanced:extension:7", - "Description": "Start the server in analyze mode. Diagnostic use only.", - "Keywords": "analyze", - "FieldName": "VS_AnalyzeMode", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.AnalyzeMode", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Let AMP Manage nimbus-server.json", - "Category": "Nimbus:cloud", - "Subcategory": "Nimbus Backend:hub:1", - "Description": "When on, AMP rewrites data/ModConfig/nimbus-server.json from the settings below every time the instance starts. Turn it off if you want to hand-edit that file instead; every Nimbus setting in this panel is then ignored.", - "Keywords": "nimbus,config,manage", - "FieldName": "NimbusWriteConfig", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "NimbusWriteConfig", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enable Nimbus Backend Mod", - "Category": "Nimbus:cloud", - "Subcategory": "Nimbus Backend:hub:1", - "Description": "Master switch inside nimbus-server.json. Off means the mod loads but never heartbeats to the registry, so this server is not part of the network.", - "Keywords": "nimbus,enabled", - "FieldName": "NimbusEnabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "NimbusEnabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Server ID", - "Category": "Nimbus:cloud", - "Subcategory": "Nimbus Backend:hub:1", - "Description": "Unique id of this backend on the network, lower case, no spaces, for example hub, creative, mining-1. Players use it as /server , the proxy uses it in its [servers] table, and it must be unique across the whole network.", - "Keywords": "nimbus,serverid,name", - "FieldName": "NimbusServerId", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "NimbusServerId", - "IncludeInCommandLine": false, - "DefaultValue": "hub", - "EnumValues": {}, - "Placeholder": "hub" - }, - { - "DisplayName": "Display Name", - "Category": "Nimbus:cloud", - "Subcategory": "Nimbus Backend:hub:1", - "Description": "Friendly name shown in /servers and in transfer messages.", - "Keywords": "nimbus,displayname", - "FieldName": "NimbusDisplayName", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "NimbusDisplayName", - "IncludeInCommandLine": false, - "DefaultValue": "Hub", - "EnumValues": {} - }, - { - "DisplayName": "Advertised Host", - "Category": "Nimbus:cloud", - "Subcategory": "Nimbus Backend:hub:1", - "Description": "Address the PROXY uses to reach this backend, not the address players use. Use 127.0.0.1 when the proxy runs on the same machine, otherwise the LAN or WAN address of this instance.", - "Keywords": "nimbus,host,publichost", - "FieldName": "NimbusPublicHost", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "NimbusPublicHost", - "IncludeInCommandLine": false, - "DefaultValue": "127.0.0.1", - "EnumValues": {}, - "Placeholder": "127.0.0.1" - }, - { - "DisplayName": "Advertised Port", - "Category": "Nimbus:cloud", - "Subcategory": "Nimbus Backend:hub:1", - "Description": "Port the proxy dials for this backend. 0 means use this instance's own game port, which is almost always what you want.", - "Keywords": "nimbus,port,publicport", - "FieldName": "NimbusPublicPort", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "NimbusPublicPort", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {}, - "MinValue": "0" - }, - { - "DisplayName": "Tags", - "Category": "Nimbus:cloud", - "Subcategory": "Nimbus Backend:hub:1", - "Description": "Comma separated tags published with the heartbeat, for example survival,pvp. Plugins and shortcut logic can select servers by tag.", - "Keywords": "nimbus,tags", - "FieldName": "NimbusTags", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "NimbusTags", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "survival,pvp" - }, - { - "DisplayName": "Registry URL", - "Category": "Nimbus:cloud", - "Subcategory": "Nimbus Backend:hub:1", - "Description": "Base URL of the Nimbus registry. Use the proxy's embedded registry bind (default http://127.0.0.1:8765) or the standalone registry's bind. Must be reachable from this instance.", - "Keywords": "nimbus,registry,url", - "FieldName": "NimbusRegistryUrl", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "NimbusRegistryUrl", - "IncludeInCommandLine": false, - "DefaultValue": "http://127.0.0.1:8765", - "EnumValues": {}, - "Placeholder": "http://127.0.0.1:8765" - }, - { - "DisplayName": "Registry Shared Secret", - "Category": "Nimbus:cloud", - "Subcategory": "Nimbus Backend:hub:1", - "Description": "HMAC secret this backend signs heartbeats with. It must be byte for byte the same value as the registry's shared secret. Never generate it here: copy the one the proxy or registry wrote on its first run.", - "Keywords": "nimbus,secret,hmac", - "FieldName": "NimbusSharedSecret", - "InputType": "password", - "IsFlagArgument": false, - "ParamFieldName": "NimbusSharedSecret", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Heartbeat Interval", - "Category": "Nimbus:cloud", - "Subcategory": "Nimbus Backend:hub:1", - "Description": "Seconds between heartbeats to the registry. Must be well below the registry's stale window.", - "Keywords": "nimbus,heartbeat", - "FieldName": "NimbusHeartbeatIntervalSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "NimbusHeartbeatIntervalSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "5", - "EnumValues": {}, - "Suffix": "seconds", - "MinValue": "1" - }, - { - "DisplayName": "Registry HTTP Timeout", - "Category": "Nimbus:cloud", - "Subcategory": "Nimbus Backend:hub:1", - "Description": "Seconds before a registry call is abandoned.", - "Keywords": "nimbus,timeout", - "FieldName": "NimbusRegistryHttpTimeoutSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "NimbusRegistryHttpTimeoutSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "5", - "EnumValues": {}, - "Suffix": "seconds", - "MinValue": "1" - }, - { - "DisplayName": "Maintenance Mode", - "Category": "Nimbus:cloud", - "Subcategory": "Nimbus Backend:hub:1", - "Description": "Advertise this backend as in maintenance. The proxy keeps it out of the join try-list and out of shortcut targets while players already on it stay.", - "Keywords": "nimbus,maintenance", - "FieldName": "NimbusMaintenance", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "NimbusMaintenance", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Require Proxy Reservation", - "Category": "Nimbus:cloud", - "Subcategory": "Nimbus Backend:hub:1", - "Description": "Only let players in who hold a reservation issued by the proxy. This is what stops players bypassing the proxy by connecting to the backend port directly.", - "Keywords": "nimbus,reservation", - "FieldName": "NimbusReservationRequired", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "NimbusReservationRequired", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Fail Closed On Registry Outage", - "Category": "Nimbus:cloud", - "Subcategory": "Nimbus Backend:hub:1", - "Description": "Off (default) lets players in when the registry cannot be reached, so an outage does not lock everyone out. On kicks them instead, so an outage cannot be used to bypass the proxy.", - "Keywords": "nimbus,failclosed", - "FieldName": "NimbusFailClosedWhenRegistryUnreachable", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "NimbusFailClosedWhenRegistryUnreachable", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Allow /server For Players", - "Category": "Nimbus:cloud", - "Subcategory": "Nimbus Transfers:swap_horiz:2", - "Description": "Let ordinary players run /server and /servers. Turn it off to restrict movement to shortcuts and staff commands.", - "Keywords": "nimbus,server,command", - "FieldName": "NimbusAllowPlayerServerCommand", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "NimbusAllowPlayerServerCommand", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Transfer Mode", - "Category": "Nimbus:cloud", - "Subcategory": "Nimbus Transfers:swap_horiz:2", - "Description": "How this backend hands a player to another server. redirect uses the vanilla redirect packet and needs no client mod. seamless keeps the same TCP connection and requires the proxy to allow seamless transfers.", - "Keywords": "nimbus,transfer,mode", - "FieldName": "NimbusTransferMode", - "InputType": "enum", - "IsFlagArgument": false, - "ParamFieldName": "NimbusTransferMode", - "IncludeInCommandLine": false, - "DefaultValue": "redirect", - "EnumValues": { - "redirect": "Redirect (safe default)", - "seamless": "Seamless (proxy must allow it)" - } - }, - { - "DisplayName": "Seamless Prepare Ack Timeout", - "Category": "Nimbus:cloud", - "Subcategory": "Nimbus Transfers:swap_horiz:2", - "Description": "Seconds to wait for the target server to confirm it is ready during a seamless transfer. Clamped to 1-30.", - "Keywords": "nimbus,seamless,timeout", - "FieldName": "NimbusSeamlessPrepareAckTimeoutSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "NimbusSeamlessPrepareAckTimeoutSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {}, - "Suffix": "seconds", - "MinValue": "1", - "MaxValue": "30" - }, - { - "DisplayName": "Shortcut Commands", - "Category": "Nimbus:cloud", - "Subcategory": "Nimbus Transfers:swap_horiz:2", - "Description": "Named /commands that move a player, semicolon separated. Format: name=target1|target2@privilege. Example: hub=hub;creative=creative|hub;staff=staff@controlserver. Targets are tried in order and the first healthy one that is not this server wins. Privilege defaults to chat.", - "Keywords": "nimbus,shortcuts,commands", - "FieldName": "NimbusShortcutCommands", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "NimbusShortcutCommands", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "hub=hub;creative=creative|hub" - }, - { - "DisplayName": "Stratum Release Channel", - "Category": "Updates", - "Subcategory": "Server Updates:build:-1", - "Description": "Which Stratum releases this instance is allowed to install. Stable only takes tagged releases; Prerelease also accepts -indev builds.", - "Keywords": "stratum,channel,release", - "FieldName": "StratumReleaseChannel", - "InputType": "enum", - "IsFlagArgument": false, - "ParamFieldName": "StratumReleaseChannel", - "IncludeInCommandLine": false, - "DefaultValue": "stable", - "EnumValues": { - "stable": "Stable (default)", - "prerelease": "Prerelease / indev" - } - }, - { - "DisplayName": "Vintage Story Version", - "Category": "Updates", - "Subcategory": "Server Updates:build:-1", - "Description": "The Vintage Story version Stratum must be built against, for example 1.22.6. Empty means the newest version available on the selected channel. Stratum tags are v-stratum., and the matching vanilla assets are downloaded automatically, so this single field is what pins the game version.", - "Keywords": "stratum,version,vintagestory", - "FieldName": "StratumGameVersion", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "StratumGameVersion", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "1.22.6" - }, - { - "DisplayName": "Stratum Release Tag Override", - "Category": "Updates", - "Subcategory": "Server Updates:build:-1", - "Description": "Exact release tag to install, for example v1.22.6-stratum.2. Overrides both the channel and the version field above. Use it to pin or roll back a build.", - "Keywords": "stratum,tag,pin", - "FieldName": "StratumVersionTag", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "StratumVersionTag", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "v1.22.6-stratum.2" - }, - { - "DisplayName": "Re-download Vanilla Assets", - "Category": "Updates", - "Subcategory": "Server Updates:build:-1", - "Description": "Force Stratum to discard its cached vanilla game files and fetch them again on the next update. Use this if an update left the server folder in a broken state.", - "Keywords": "stratum,vanilla,refresh", - "FieldName": "StratumRefreshVanilla", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "StratumRefreshVanilla", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "GitHub Token (optional)", - "Category": "Updates", - "Subcategory": "Server Updates:build:-1", - "Description": "Optional GitHub token used only to raise the API rate limit while resolving release tags. A read-only token is enough and it is never sent anywhere else.", - "Keywords": "github,token,ratelimit", - "FieldName": "StratumGitHubToken", - "InputType": "password", - "IsFlagArgument": false, - "ParamFieldName": "StratumGitHubToken", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Install Nimbus Server Mod", - "Category": "Updates", - "Subcategory": "Nimbus Updates:cloud_download:0", - "Description": "Download Nimbus.ServerMod into data/Mods on every update. Required for this server to join a Nimbus network. Turn it off for a stand-alone Stratum server.", - "Keywords": "nimbus,mod,install", - "FieldName": "NimbusInstall", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "NimbusInstall", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Nimbus Version", - "Category": "Updates", - "Subcategory": "Nimbus Updates:cloud_download:0", - "Description": "Nimbus release to install, for example v0.5.0. Empty means the newest release on the selected channel. The proxy, the registry and every backend mod on a network must run the same Nimbus version.", - "Keywords": "nimbus,version", - "FieldName": "NimbusModVersion", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "NimbusModVersion", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "v0.5.0" - }, - { - "DisplayName": "Nimbus Release Channel", - "Category": "Updates", - "Subcategory": "Nimbus Updates:cloud_download:0", - "Description": "Whether prerelease Nimbus builds are eligible when no explicit version is set.", - "Keywords": "nimbus,channel", - "FieldName": "NimbusReleaseChannel", - "InputType": "enum", - "IsFlagArgument": false, - "ParamFieldName": "NimbusReleaseChannel", - "IncludeInCommandLine": false, - "DefaultValue": "stable", - "EnumValues": { - "stable": "Stable (default)", - "prerelease": "Prerelease" - } - }, - { - "DisplayName": "Dotnet Release Stream", - "Category": "Updates", - "Subcategory": "Server Updates:build:-1", - "Description": "Which .NET SDK stream to install. Vintage Story 1.22 and Nimbus both need 10.0; 1.21 and below need 8.0.", - "Keywords": "dotnet,release", - "FieldName": "DotnetRelease", - "InputType": "enum", - "IsFlagArgument": false, - "ParamFieldName": "DotnetRelease", - "IncludeInCommandLine": false, - "DefaultValue": "10.0", - "EnumValues": { - "10.0": "10.0 (default)", - "8.0": "8.0" - } - }, - { - "DisplayName": "Dotnet Version", - "Category": "Updates", - "Subcategory": "Server Updates:build:-1", - "Description": "Exact .NET SDK version to install. Empty means the newest in the selected stream.", - "Keywords": "dotnet,version", - "FieldName": "DotnetSDKVersion", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "DotnetSDKVersion", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {}, - "Placeholder": "10.0.100" - }, - { - "DisplayName": "Additional Command Line Arguments", - "Category": "Updates", - "Subcategory": "Server Updates:build:-1", - "Description": "Extra arguments appended to the StratumServer command line, for example --tracelog. Leave empty unless you know you need one.", - "Keywords": "args,commandline", - "FieldName": "StratumExtraArgs", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "StratumExtraArgs", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Log Startup Summary", - "Category": "Stratum:filter_alt", - "Subcategory": "Diagnostics:monitor_heart:10", - "Description": "data/stratum.json -> $.Diagnostics.LogStartupSummary", - "Keywords": "diagnostics,logstartupsummary", - "FieldName": "Stratum_main_Diagnostics_LogStartupSummary", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Diagnostics.LogStartupSummary", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Run Startup Preflight", - "Category": "Stratum:filter_alt", - "Subcategory": "Diagnostics:monitor_heart:10", - "Description": "data/stratum.json -> $.Diagnostics.RunStartupPreflight", - "Keywords": "diagnostics,runstartuppreflight", - "FieldName": "Stratum_main_Diagnostics_RunStartupPreflight", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Diagnostics.RunStartupPreflight", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Log Preflight Warnings", - "Category": "Stratum:filter_alt", - "Subcategory": "Diagnostics:monitor_heart:10", - "Description": "data/stratum.json -> $.Diagnostics.LogPreflightWarnings", - "Keywords": "diagnostics,logpreflightwarnings", - "FieldName": "Stratum_main_Diagnostics_LogPreflightWarnings", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Diagnostics.LogPreflightWarnings", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Log Mod Harmony Patches", - "Category": "Stratum:filter_alt", - "Subcategory": "Diagnostics:monitor_heart:10", - "Description": "Logs every mod-owned Harmony patch at startup, grouped by mod. Visibility only, it does not cross-reference Stratum's own source-patched methods -- see StratumHarmonyVisibility. On by default because a mod patch landing on something Stratum reshaped usually goes missing silently rather than erroring, and this log is what makes it traceable. (data/stratum.json -> $.Diagnostics.LogModHarmonyPatches)", - "Keywords": "diagnostics,logmodharmonypatches", - "FieldName": "Stratum_main_Diagnostics_LogModHarmonyPatches", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Diagnostics.LogModHarmonyPatches", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Update Checker:system_update:10", - "Description": "data/stratum.json -> $.UpdateChecker.Enabled", - "Keywords": "updatechecker,enabled", - "FieldName": "Stratum_main_UpdateChecker_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.UpdateChecker.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Check On Startup", - "Category": "Stratum:filter_alt", - "Subcategory": "Update Checker:system_update:10", - "Description": "data/stratum.json -> $.UpdateChecker.CheckOnStartup", - "Keywords": "updatechecker,checkonstartup", - "FieldName": "Stratum_main_UpdateChecker_CheckOnStartup", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.UpdateChecker.CheckOnStartup", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Check Interval Hours", - "Category": "Stratum:filter_alt", - "Subcategory": "Update Checker:system_update:10", - "Description": "data/stratum.json -> $.UpdateChecker.CheckIntervalHours", - "Keywords": "updatechecker,checkintervalhours", - "FieldName": "Stratum_main_UpdateChecker_CheckIntervalHours", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.UpdateChecker.CheckIntervalHours", - "IncludeInCommandLine": false, - "DefaultValue": "12", - "EnumValues": {} - }, - { - "DisplayName": "Notify Staff In Game", - "Category": "Stratum:filter_alt", - "Subcategory": "Update Checker:system_update:10", - "Description": "data/stratum.json -> $.UpdateChecker.NotifyStaffInGame", - "Keywords": "updatechecker,notifystaffingame", - "FieldName": "Stratum_main_UpdateChecker_NotifyStaffInGame", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.UpdateChecker.NotifyStaffInGame", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Latest Release Url", - "Category": "Stratum:filter_alt", - "Subcategory": "Update Checker:system_update:10", - "Description": "data/stratum.json -> $.UpdateChecker.LatestReleaseUrl", - "Keywords": "updatechecker,latestreleaseurl", - "FieldName": "Stratum_main_UpdateChecker_LatestReleaseUrl", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.UpdateChecker.LatestReleaseUrl", - "IncludeInCommandLine": false, - "DefaultValue": "https://api.github.com/repos/StratumServer/Stratum/releases/latest", - "EnumValues": {} - }, - { - "DisplayName": "Timeout Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Update Checker:system_update:10", - "Description": "data/stratum.json -> $.UpdateChecker.TimeoutSeconds", - "Keywords": "updatechecker,timeoutseconds", - "FieldName": "Stratum_main_UpdateChecker_TimeoutSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.UpdateChecker.TimeoutSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "5", - "EnumValues": {} - }, - { - "DisplayName": "Preserve Vanilla Protocol", - "Category": "Stratum:filter_alt", - "Subcategory": "Hardening:shield:10", - "Description": "data/stratum.json -> $.Hardening.PreserveVanillaProtocol", - "Keywords": "hardening,preservevanillaprotocol", - "FieldName": "Stratum_main_Hardening_PreserveVanillaProtocol", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Hardening.PreserveVanillaProtocol", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Packet Monitoring", - "Category": "Stratum:filter_alt", - "Subcategory": "Hardening:shield:10", - "Description": "data/stratum.json -> $.Hardening.PacketMonitoring", - "Keywords": "hardening,packetmonitoring", - "FieldName": "Stratum_main_Hardening_PacketMonitoring", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Hardening.PacketMonitoring", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Block Break Guards", - "Category": "Stratum:filter_alt", - "Subcategory": "Hardening:shield:10", - "Description": "data/stratum.json -> $.Hardening.BlockBreakGuards", - "Keywords": "hardening,blockbreakguards", - "FieldName": "Stratum_main_Hardening_BlockBreakGuards", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Hardening.BlockBreakGuards", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Inventory Guards", - "Category": "Stratum:filter_alt", - "Subcategory": "Hardening:shield:10", - "Description": "data/stratum.json -> $.Hardening.InventoryGuards", - "Keywords": "hardening,inventoryguards", - "FieldName": "Stratum_main_Hardening_InventoryGuards", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Hardening.InventoryGuards", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Entity Guards", - "Category": "Stratum:filter_alt", - "Subcategory": "Hardening:shield:10", - "Description": "data/stratum.json -> $.Hardening.EntityGuards", - "Keywords": "hardening,entityguards", - "FieldName": "Stratum_main_Hardening_EntityGuards", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Hardening.EntityGuards", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Limits:speed:10", - "Description": "data/stratum.json -> $.PacketLimits.Enabled", - "Keywords": "packetlimits,enabled", - "FieldName": "Stratum_main_PacketLimits_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketLimits.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Drop Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Limits:speed:10", - "Description": "data/stratum.json -> $.PacketLimits.DropViolations", - "Keywords": "packetlimits,dropviolations", - "FieldName": "Stratum_main_PacketLimits_DropViolations", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketLimits.DropViolations", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Log Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Limits:speed:10", - "Description": "data/stratum.json -> $.PacketLimits.LogViolations", - "Keywords": "packetlimits,logviolations", - "FieldName": "Stratum_main_PacketLimits_LogViolations", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketLimits.LogViolations", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Kick Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Limits:speed:10", - "Description": "data/stratum.json -> $.PacketLimits.KickViolations", - "Keywords": "packetlimits,kickviolations", - "FieldName": "Stratum_main_PacketLimits_KickViolations", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketLimits.KickViolations", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Kick Invalid Packets", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Limits:speed:10", - "Description": "data/stratum.json -> $.PacketLimits.KickInvalidPackets", - "Keywords": "packetlimits,kickinvalidpackets", - "FieldName": "Stratum_main_PacketLimits_KickInvalidPackets", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketLimits.KickInvalidPackets", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Kick Oversized Custom Packets", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Limits:speed:10", - "Description": "data/stratum.json -> $.PacketLimits.KickOversizedCustomPackets", - "Keywords": "packetlimits,kickoversizedcustompackets", - "FieldName": "Stratum_main_PacketLimits_KickOversizedCustomPackets", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketLimits.KickOversizedCustomPackets", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Monitor Only Sensitive Packets", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Limits:speed:10", - "Description": "data/stratum.json -> $.PacketLimits.MonitorOnlySensitivePackets", - "Keywords": "packetlimits,monitoronlysensitivepackets", - "FieldName": "Stratum_main_PacketLimits_MonitorOnlySensitivePackets", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketLimits.MonitorOnlySensitivePackets", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Kick After Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Limits:speed:10", - "Description": "data/stratum.json -> $.PacketLimits.KickAfterViolations", - "Keywords": "packetlimits,kickafterviolations", - "FieldName": "Stratum_main_PacketLimits_KickAfterViolations", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketLimits.KickAfterViolations", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {} - }, - { - "DisplayName": "Kick Message", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Limits:speed:10", - "Description": "data/stratum.json -> $.PacketLimits.KickMessage", - "Keywords": "packetlimits,kickmessage", - "FieldName": "Stratum_main_PacketLimits_KickMessage", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketLimits.KickMessage", - "IncludeInCommandLine": false, - "DefaultValue": "Disconnected by Stratum packet protection", - "EnumValues": {} - }, - { - "DisplayName": "Window Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Limits:speed:10", - "Description": "data/stratum.json -> $.PacketLimits.WindowSeconds", - "Keywords": "packetlimits,windowseconds", - "FieldName": "Stratum_main_PacketLimits_WindowSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketLimits.WindowSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "5", - "EnumValues": {} - }, - { - "DisplayName": "Default Max Packets", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Limits:speed:10", - "Description": "data/stratum.json -> $.PacketLimits.DefaultMaxPackets", - "Keywords": "packetlimits,defaultmaxpackets", - "FieldName": "Stratum_main_PacketLimits_DefaultMaxPackets", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketLimits.DefaultMaxPackets", - "IncludeInCommandLine": false, - "DefaultValue": "300", - "EnumValues": {} - }, - { - "DisplayName": "Movement Max Packets", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Limits:speed:10", - "Description": "data/stratum.json -> $.PacketLimits.MovementMaxPackets", - "Keywords": "packetlimits,movementmaxpackets", - "FieldName": "Stratum_main_PacketLimits_MovementMaxPackets", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketLimits.MovementMaxPackets", - "IncludeInCommandLine": false, - "DefaultValue": "420", - "EnumValues": {} - }, - { - "DisplayName": "Inventory Max Packets", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Limits:speed:10", - "Description": "data/stratum.json -> $.PacketLimits.InventoryMaxPackets", - "Keywords": "packetlimits,inventorymaxpackets", - "FieldName": "Stratum_main_PacketLimits_InventoryMaxPackets", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketLimits.InventoryMaxPackets", - "IncludeInCommandLine": false, - "DefaultValue": "90", - "EnumValues": {} - }, - { - "DisplayName": "Block Interaction Max Packets", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Limits:speed:10", - "Description": "data/stratum.json -> $.PacketLimits.BlockInteractionMaxPackets", - "Keywords": "packetlimits,blockinteractionmaxpackets", - "FieldName": "Stratum_main_PacketLimits_BlockInteractionMaxPackets", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketLimits.BlockInteractionMaxPackets", - "IncludeInCommandLine": false, - "DefaultValue": "140", - "EnumValues": {} - }, - { - "DisplayName": "Entity Interaction Max Packets", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Limits:speed:10", - "Description": "data/stratum.json -> $.PacketLimits.EntityInteractionMaxPackets", - "Keywords": "packetlimits,entityinteractionmaxpackets", - "FieldName": "Stratum_main_PacketLimits_EntityInteractionMaxPackets", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketLimits.EntityInteractionMaxPackets", - "IncludeInCommandLine": false, - "DefaultValue": "140", - "EnumValues": {} - }, - { - "DisplayName": "Hand Interaction Max Packets", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Limits:speed:10", - "Description": "data/stratum.json -> $.PacketLimits.HandInteractionMaxPackets", - "Keywords": "packetlimits,handinteractionmaxpackets", - "FieldName": "Stratum_main_PacketLimits_HandInteractionMaxPackets", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketLimits.HandInteractionMaxPackets", - "IncludeInCommandLine": false, - "DefaultValue": "90", - "EnumValues": {} - }, - { - "DisplayName": "Custom Packet Max Packets", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Limits:speed:10", - "Description": "data/stratum.json -> $.PacketLimits.CustomPacketMaxPackets", - "Keywords": "packetlimits,custompacketmaxpackets", - "FieldName": "Stratum_main_PacketLimits_CustomPacketMaxPackets", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketLimits.CustomPacketMaxPackets", - "IncludeInCommandLine": false, - "DefaultValue": "120", - "EnumValues": {} - }, - { - "DisplayName": "Custom Packet Max Bytes", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Limits:speed:10", - "Description": "data/stratum.json -> $.PacketLimits.CustomPacketMaxBytes", - "Keywords": "packetlimits,custompacketmaxbytes", - "FieldName": "Stratum_main_PacketLimits_CustomPacketMaxBytes", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketLimits.CustomPacketMaxBytes", - "IncludeInCommandLine": false, - "DefaultValue": "262144", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Back Pressure:compress:10", - "Description": "data/stratum.json -> $.PacketBackPressure.Enabled", - "Keywords": "packetbackpressure,enabled", - "FieldName": "Stratum_main_PacketBackPressure_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketBackPressure.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Max Milliseconds Per Tick", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Back Pressure:compress:10", - "Description": "data/stratum.json -> $.PacketBackPressure.MaxMillisecondsPerTick", - "Keywords": "packetbackpressure,maxmillisecondspertick", - "FieldName": "Stratum_main_PacketBackPressure_MaxMillisecondsPerTick", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketBackPressure.MaxMillisecondsPerTick", - "IncludeInCommandLine": false, - "DefaultValue": "25", - "EnumValues": {} - }, - { - "DisplayName": "Max Packets Per Client Per Tick", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Back Pressure:compress:10", - "Description": "data/stratum.json -> $.PacketBackPressure.MaxPacketsPerClientPerTick", - "Keywords": "packetbackpressure,maxpacketsperclientpertick", - "FieldName": "Stratum_main_PacketBackPressure_MaxPacketsPerClientPerTick", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketBackPressure.MaxPacketsPerClientPerTick", - "IncludeInCommandLine": false, - "DefaultValue": "32", - "EnumValues": {} - }, - { - "DisplayName": "Max Queue Depth Per Client", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Back Pressure:compress:10", - "Description": "data/stratum.json -> $.PacketBackPressure.MaxQueueDepthPerClient", - "Keywords": "packetbackpressure,maxqueuedepthperclient", - "FieldName": "Stratum_main_PacketBackPressure_MaxQueueDepthPerClient", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketBackPressure.MaxQueueDepthPerClient", - "IncludeInCommandLine": false, - "DefaultValue": "2000", - "EnumValues": {} - }, - { - "DisplayName": "Kick On Queue Overflow", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Back Pressure:compress:10", - "Description": "data/stratum.json -> $.PacketBackPressure.KickOnQueueOverflow", - "Keywords": "packetbackpressure,kickonqueueoverflow", - "FieldName": "Stratum_main_PacketBackPressure_KickOnQueueOverflow", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketBackPressure.KickOnQueueOverflow", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Kick Message", - "Category": "Stratum:filter_alt", - "Subcategory": "Packet Back Pressure:compress:10", - "Description": "data/stratum.json -> $.PacketBackPressure.KickMessage", - "Keywords": "packetbackpressure,kickmessage", - "FieldName": "Stratum_main_PacketBackPressure_KickMessage", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.PacketBackPressure.KickMessage", - "IncludeInCommandLine": false, - "DefaultValue": "Disconnected by Stratum packet back-pressure", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Block Break Guards:construction:10", - "Description": "data/stratum.json -> $.BlockBreakGuards.Enabled", - "Keywords": "blockbreakguards,enabled", - "FieldName": "Stratum_main_BlockBreakGuards_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockBreakGuards.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Require Server Selection", - "Category": "Stratum:filter_alt", - "Subcategory": "Block Break Guards:construction:10", - "Description": "data/stratum.json -> $.BlockBreakGuards.RequireServerSelection", - "Keywords": "blockbreakguards,requireserverselection", - "FieldName": "Stratum_main_BlockBreakGuards_RequireServerSelection", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockBreakGuards.RequireServerSelection", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Drop Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Block Break Guards:construction:10", - "Description": "data/stratum.json -> $.BlockBreakGuards.DropViolations", - "Keywords": "blockbreakguards,dropviolations", - "FieldName": "Stratum_main_BlockBreakGuards_DropViolations", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockBreakGuards.DropViolations", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Log Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Block Break Guards:construction:10", - "Description": "data/stratum.json -> $.BlockBreakGuards.LogViolations", - "Keywords": "blockbreakguards,logviolations", - "FieldName": "Stratum_main_BlockBreakGuards_LogViolations", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockBreakGuards.LogViolations", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Required Progress Ratio", - "Category": "Stratum:filter_alt", - "Subcategory": "Block Break Guards:construction:10", - "Description": "data/stratum.json -> $.BlockBreakGuards.RequiredProgressRatio", - "Keywords": "blockbreakguards,requiredprogressratio", - "FieldName": "Stratum_main_BlockBreakGuards_RequiredProgressRatio", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockBreakGuards.RequiredProgressRatio", - "IncludeInCommandLine": false, - "DefaultValue": "0.8", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Grace Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Block Break Guards:construction:10", - "Description": "data/stratum.json -> $.BlockBreakGuards.GraceSeconds", - "Keywords": "blockbreakguards,graceseconds", - "FieldName": "Stratum_main_BlockBreakGuards_GraceSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockBreakGuards.GraceSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0.25", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Minimum Tracked Break Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Block Break Guards:construction:10", - "Description": "data/stratum.json -> $.BlockBreakGuards.MinimumTrackedBreakSeconds", - "Keywords": "blockbreakguards,minimumtrackedbreakseconds", - "FieldName": "Stratum_main_BlockBreakGuards_MinimumTrackedBreakSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockBreakGuards.MinimumTrackedBreakSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0.15", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Partial Progress Retention Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Block Break Guards:construction:10", - "Description": "data/stratum.json -> $.BlockBreakGuards.PartialProgressRetentionSeconds", - "Keywords": "blockbreakguards,partialprogressretentionseconds", - "FieldName": "Stratum_main_BlockBreakGuards_PartialProgressRetentionSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockBreakGuards.PartialProgressRetentionSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Max Remembered Progress Ratio", - "Category": "Stratum:filter_alt", - "Subcategory": "Block Break Guards:construction:10", - "Description": "data/stratum.json -> $.BlockBreakGuards.MaxRememberedProgressRatio", - "Keywords": "blockbreakguards,maxrememberedprogressratio", - "FieldName": "Stratum_main_BlockBreakGuards_MaxRememberedProgressRatio", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockBreakGuards.MaxRememberedProgressRatio", - "IncludeInCommandLine": false, - "DefaultValue": "0.95", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Max Remembered Partial Breaks Per Client", - "Category": "Stratum:filter_alt", - "Subcategory": "Block Break Guards:construction:10", - "Description": "data/stratum.json -> $.BlockBreakGuards.MaxRememberedPartialBreaksPerClient", - "Keywords": "blockbreakguards,maxrememberedpartialbreaksperclient", - "FieldName": "Stratum_main_BlockBreakGuards_MaxRememberedPartialBreaksPerClient", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockBreakGuards.MaxRememberedPartialBreaksPerClient", - "IncludeInCommandLine": false, - "DefaultValue": "24", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Enabled", - "Keywords": "anticheat,enabled", - "FieldName": "Stratum_main_Anticheat_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Staff Alerts", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.StaffAlerts", - "Keywords": "anticheat,staffalerts", - "FieldName": "Stratum_main_Anticheat_StaffAlerts", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.StaffAlerts", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Max Stored Violations Per Player", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MaxStoredViolationsPerPlayer", - "Keywords": "anticheat,maxstoredviolationsperplayer", - "FieldName": "Stratum_main_Anticheat_MaxStoredViolationsPerPlayer", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MaxStoredViolationsPerPlayer", - "IncludeInCommandLine": false, - "DefaultValue": "128", - "EnumValues": {} - }, - { - "DisplayName": "Keep Player Violations Minutes", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.KeepPlayerViolationsMinutes", - "Keywords": "anticheat,keepplayerviolationsminutes", - "FieldName": "Stratum_main_Anticheat_KeepPlayerViolationsMinutes", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.KeepPlayerViolationsMinutes", - "IncludeInCommandLine": false, - "DefaultValue": "60", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Entity Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockEntityOutOfRange.Enabled", - "Keywords": "anticheat,blockentityoutofrange,enabled", - "FieldName": "Stratum_main_Anticheat_BlockEntityOutOfRange_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockEntityOutOfRange.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Alert After Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Entity Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockEntityOutOfRange.AlertAfterViolations", - "Keywords": "anticheat,blockentityoutofrange,alertafterviolations", - "FieldName": "Stratum_main_Anticheat_BlockEntityOutOfRange_AlertAfterViolations", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockEntityOutOfRange.AlertAfterViolations", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {} - }, - { - "DisplayName": "Alert Window Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Entity Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockEntityOutOfRange.AlertWindowSeconds", - "Keywords": "anticheat,blockentityoutofrange,alertwindowseconds", - "FieldName": "Stratum_main_Anticheat_BlockEntityOutOfRange_AlertWindowSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockEntityOutOfRange.AlertWindowSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "10", - "EnumValues": {} - }, - { - "DisplayName": "Repeat Alert Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Entity Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockEntityOutOfRange.RepeatAlertSeconds", - "Keywords": "anticheat,blockentityoutofrange,repeatalertseconds", - "FieldName": "Stratum_main_Anticheat_BlockEntityOutOfRange_RepeatAlertSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockEntityOutOfRange.RepeatAlertSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "20", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Interaction Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockInteractionOutOfRange.Enabled", - "Keywords": "anticheat,blockinteractionoutofrange,enabled", - "FieldName": "Stratum_main_Anticheat_BlockInteractionOutOfRange_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockInteractionOutOfRange.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Alert After Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Interaction Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockInteractionOutOfRange.AlertAfterViolations", - "Keywords": "anticheat,blockinteractionoutofrange,alertafterviolations", - "FieldName": "Stratum_main_Anticheat_BlockInteractionOutOfRange_AlertAfterViolations", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockInteractionOutOfRange.AlertAfterViolations", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {} - }, - { - "DisplayName": "Alert Window Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Interaction Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockInteractionOutOfRange.AlertWindowSeconds", - "Keywords": "anticheat,blockinteractionoutofrange,alertwindowseconds", - "FieldName": "Stratum_main_Anticheat_BlockInteractionOutOfRange_AlertWindowSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockInteractionOutOfRange.AlertWindowSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "10", - "EnumValues": {} - }, - { - "DisplayName": "Repeat Alert Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Interaction Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockInteractionOutOfRange.RepeatAlertSeconds", - "Keywords": "anticheat,blockinteractionoutofrange,repeatalertseconds", - "FieldName": "Stratum_main_Anticheat_BlockInteractionOutOfRange_RepeatAlertSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockInteractionOutOfRange.RepeatAlertSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "20", - "EnumValues": {} - }, - { - "DisplayName": "Range Slack", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Interaction Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockInteractionOutOfRange.RangeSlack", - "Keywords": "anticheat,blockinteractionoutofrange,rangeslack", - "FieldName": "Stratum_main_Anticheat_BlockInteractionOutOfRange_RangeSlack", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockInteractionOutOfRange.RangeSlack", - "IncludeInCommandLine": false, - "DefaultValue": "0.75", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Kick Confirmed Cheats", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Interaction Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockInteractionOutOfRange.KickConfirmedCheats", - "Keywords": "anticheat,blockinteractionoutofrange,kickconfirmedcheats", - "FieldName": "Stratum_main_Anticheat_BlockInteractionOutOfRange_KickConfirmedCheats", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockInteractionOutOfRange.KickConfirmedCheats", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Kick After Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Interaction Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockInteractionOutOfRange.KickAfterViolations", - "Keywords": "anticheat,blockinteractionoutofrange,kickafterviolations", - "FieldName": "Stratum_main_Anticheat_BlockInteractionOutOfRange_KickAfterViolations", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockInteractionOutOfRange.KickAfterViolations", - "IncludeInCommandLine": false, - "DefaultValue": "3", - "EnumValues": {} - }, - { - "DisplayName": "Kick Message", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Interaction Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockInteractionOutOfRange.KickMessage", - "Keywords": "anticheat,blockinteractionoutofrange,kickmessage", - "FieldName": "Stratum_main_Anticheat_BlockInteractionOutOfRange_KickMessage", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockInteractionOutOfRange.KickMessage", - "IncludeInCommandLine": false, - "DefaultValue": "Disconnected by Stratum block reach protection", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Entity Interaction Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.EntityInteractionOutOfRange.Enabled", - "Keywords": "anticheat,entityinteractionoutofrange,enabled", - "FieldName": "Stratum_main_Anticheat_EntityInteractionOutOfRange_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.EntityInteractionOutOfRange.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Alert After Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Entity Interaction Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.EntityInteractionOutOfRange.AlertAfterViolations", - "Keywords": "anticheat,entityinteractionoutofrange,alertafterviolations", - "FieldName": "Stratum_main_Anticheat_EntityInteractionOutOfRange_AlertAfterViolations", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.EntityInteractionOutOfRange.AlertAfterViolations", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {} - }, - { - "DisplayName": "Alert Window Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Entity Interaction Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.EntityInteractionOutOfRange.AlertWindowSeconds", - "Keywords": "anticheat,entityinteractionoutofrange,alertwindowseconds", - "FieldName": "Stratum_main_Anticheat_EntityInteractionOutOfRange_AlertWindowSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.EntityInteractionOutOfRange.AlertWindowSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "10", - "EnumValues": {} - }, - { - "DisplayName": "Repeat Alert Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Entity Interaction Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.EntityInteractionOutOfRange.RepeatAlertSeconds", - "Keywords": "anticheat,entityinteractionoutofrange,repeatalertseconds", - "FieldName": "Stratum_main_Anticheat_EntityInteractionOutOfRange_RepeatAlertSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.EntityInteractionOutOfRange.RepeatAlertSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "20", - "EnumValues": {} - }, - { - "DisplayName": "Range Slack", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Entity Interaction Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.EntityInteractionOutOfRange.RangeSlack", - "Keywords": "anticheat,entityinteractionoutofrange,rangeslack", - "FieldName": "Stratum_main_Anticheat_EntityInteractionOutOfRange_RangeSlack", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.EntityInteractionOutOfRange.RangeSlack", - "IncludeInCommandLine": false, - "DefaultValue": "1.0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Kick Confirmed Cheats", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Entity Interaction Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.EntityInteractionOutOfRange.KickConfirmedCheats", - "Keywords": "anticheat,entityinteractionoutofrange,kickconfirmedcheats", - "FieldName": "Stratum_main_Anticheat_EntityInteractionOutOfRange_KickConfirmedCheats", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.EntityInteractionOutOfRange.KickConfirmedCheats", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Kick After Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Entity Interaction Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.EntityInteractionOutOfRange.KickAfterViolations", - "Keywords": "anticheat,entityinteractionoutofrange,kickafterviolations", - "FieldName": "Stratum_main_Anticheat_EntityInteractionOutOfRange_KickAfterViolations", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.EntityInteractionOutOfRange.KickAfterViolations", - "IncludeInCommandLine": false, - "DefaultValue": "3", - "EnumValues": {} - }, - { - "DisplayName": "Kick Message", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Entity Interaction Out Of Range:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.EntityInteractionOutOfRange.KickMessage", - "Keywords": "anticheat,entityinteractionoutofrange,kickmessage", - "FieldName": "Stratum_main_Anticheat_EntityInteractionOutOfRange_KickMessage", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.EntityInteractionOutOfRange.KickMessage", - "IncludeInCommandLine": false, - "DefaultValue": "Disconnected by Stratum entity reach protection", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Break Progress:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockBreakProgress.Enabled", - "Keywords": "anticheat,blockbreakprogress,enabled", - "FieldName": "Stratum_main_Anticheat_BlockBreakProgress_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockBreakProgress.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Alert After Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Break Progress:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockBreakProgress.AlertAfterViolations", - "Keywords": "anticheat,blockbreakprogress,alertafterviolations", - "FieldName": "Stratum_main_Anticheat_BlockBreakProgress_AlertAfterViolations", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockBreakProgress.AlertAfterViolations", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {} - }, - { - "DisplayName": "Alert Window Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Break Progress:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockBreakProgress.AlertWindowSeconds", - "Keywords": "anticheat,blockbreakprogress,alertwindowseconds", - "FieldName": "Stratum_main_Anticheat_BlockBreakProgress_AlertWindowSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockBreakProgress.AlertWindowSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "10", - "EnumValues": {} - }, - { - "DisplayName": "Repeat Alert Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Break Progress:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockBreakProgress.RepeatAlertSeconds", - "Keywords": "anticheat,blockbreakprogress,repeatalertseconds", - "FieldName": "Stratum_main_Anticheat_BlockBreakProgress_RepeatAlertSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockBreakProgress.RepeatAlertSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "20", - "EnumValues": {} - }, - { - "DisplayName": "Kick Confirmed Cheats", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Break Progress:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockBreakProgress.KickConfirmedCheats", - "Keywords": "anticheat,blockbreakprogress,kickconfirmedcheats", - "FieldName": "Stratum_main_Anticheat_BlockBreakProgress_KickConfirmedCheats", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockBreakProgress.KickConfirmedCheats", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Kick After Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Break Progress:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockBreakProgress.KickAfterViolations", - "Keywords": "anticheat,blockbreakprogress,kickafterviolations", - "FieldName": "Stratum_main_Anticheat_BlockBreakProgress_KickAfterViolations", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockBreakProgress.KickAfterViolations", - "IncludeInCommandLine": false, - "DefaultValue": "3", - "EnumValues": {} - }, - { - "DisplayName": "Kick Message", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Block Break Progress:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.BlockBreakProgress.KickMessage", - "Keywords": "anticheat,blockbreakprogress,kickmessage", - "FieldName": "Stratum_main_Anticheat_BlockBreakProgress_KickMessage", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.BlockBreakProgress.KickMessage", - "IncludeInCommandLine": false, - "DefaultValue": "Disconnected by Stratum block break protection", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.Enabled", - "Keywords": "anticheat,movement,enabled", - "FieldName": "Stratum_main_Anticheat_Movement_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Alert After Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.AlertAfterViolations", - "Keywords": "anticheat,movement,alertafterviolations", - "FieldName": "Stratum_main_Anticheat_Movement_AlertAfterViolations", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.AlertAfterViolations", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {} - }, - { - "DisplayName": "Alert Window Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.AlertWindowSeconds", - "Keywords": "anticheat,movement,alertwindowseconds", - "FieldName": "Stratum_main_Anticheat_Movement_AlertWindowSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.AlertWindowSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "10", - "EnumValues": {} - }, - { - "DisplayName": "Repeat Alert Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.RepeatAlertSeconds", - "Keywords": "anticheat,movement,repeatalertseconds", - "FieldName": "Stratum_main_Anticheat_Movement_RepeatAlertSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.RepeatAlertSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "20", - "EnumValues": {} - }, - { - "DisplayName": "Use Stat Based Speed Limits", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.UseStatBasedSpeedLimits", - "Keywords": "anticheat,movement,usestatbasedspeedlimits", - "FieldName": "Stratum_main_Anticheat_Movement_UseStatBasedSpeedLimits", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.UseStatBasedSpeedLimits", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Horizontal Speed Multiplier", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.HorizontalSpeedMultiplier", - "Keywords": "anticheat,movement,horizontalspeedmultiplier", - "FieldName": "Stratum_main_Anticheat_Movement_HorizontalSpeedMultiplier", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.HorizontalSpeedMultiplier", - "IncludeInCommandLine": false, - "DefaultValue": "3.0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Airborne Horizontal Multiplier", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.AirborneHorizontalMultiplier", - "Keywords": "anticheat,movement,airbornehorizontalmultiplier", - "FieldName": "Stratum_main_Anticheat_Movement_AirborneHorizontalMultiplier", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.AirborneHorizontalMultiplier", - "IncludeInCommandLine": false, - "DefaultValue": "1.75", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Minimum Horizontal Blocks Per Second", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.MinimumHorizontalBlocksPerSecond", - "Keywords": "anticheat,movement,minimumhorizontalblockspersecond", - "FieldName": "Stratum_main_Anticheat_Movement_MinimumHorizontalBlocksPerSecond", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.MinimumHorizontalBlocksPerSecond", - "IncludeInCommandLine": false, - "DefaultValue": "8.0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Position Version Accept Distance", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.PositionVersionAcceptDistance", - "Keywords": "anticheat,movement,positionversionacceptdistance", - "FieldName": "Stratum_main_Anticheat_Movement_PositionVersionAcceptDistance", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.PositionVersionAcceptDistance", - "IncludeInCommandLine": false, - "DefaultValue": "4.0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Max Horizontal Blocks Per Second", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "Fallback cap when stat-based speed limits are disabled, and hard ceiling when they are on. (data/stratum.json -> $.Anticheat.Movement.MaxHorizontalBlocksPerSecond)", - "Keywords": "anticheat,movement,maxhorizontalblockspersecond", - "FieldName": "Stratum_main_Anticheat_Movement_MaxHorizontalBlocksPerSecond", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.MaxHorizontalBlocksPerSecond", - "IncludeInCommandLine": false, - "DefaultValue": "36", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Max Vertical Up Blocks Per Second", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.MaxVerticalUpBlocksPerSecond", - "Keywords": "anticheat,movement,maxverticalupblockspersecond", - "FieldName": "Stratum_main_Anticheat_Movement_MaxVerticalUpBlocksPerSecond", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.MaxVerticalUpBlocksPerSecond", - "IncludeInCommandLine": false, - "DefaultValue": "18", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Cumulative Speed Multiplier", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.CumulativeSpeedMultiplier", - "Keywords": "anticheat,movement,cumulativespeedmultiplier", - "FieldName": "Stratum_main_Anticheat_Movement_CumulativeSpeedMultiplier", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.CumulativeSpeedMultiplier", - "IncludeInCommandLine": false, - "DefaultValue": "2.5", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Max Cumulative Blocks Per Second", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "Hard ceiling for repeated smaller teleports that stay under the per-packet cap. (data/stratum.json -> $.Anticheat.Movement.MaxCumulativeBlocksPerSecond)", - "Keywords": "anticheat,movement,maxcumulativeblockspersecond", - "FieldName": "Stratum_main_Anticheat_Movement_MaxCumulativeBlocksPerSecond", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.MaxCumulativeBlocksPerSecond", - "IncludeInCommandLine": false, - "DefaultValue": "64", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Slack Blocks", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.SlackBlocks", - "Keywords": "anticheat,movement,slackblocks", - "FieldName": "Stratum_main_Anticheat_Movement_SlackBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.SlackBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "2.5", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Mount Max Horizontal Blocks Per Second", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.MountMaxHorizontalBlocksPerSecond", - "Keywords": "anticheat,movement,mountmaxhorizontalblockspersecond", - "FieldName": "Stratum_main_Anticheat_Movement_MountMaxHorizontalBlocksPerSecond", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.MountMaxHorizontalBlocksPerSecond", - "IncludeInCommandLine": false, - "DefaultValue": "96", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Mount Max Vertical Up Blocks Per Second", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.MountMaxVerticalUpBlocksPerSecond", - "Keywords": "anticheat,movement,mountmaxverticalupblockspersecond", - "FieldName": "Stratum_main_Anticheat_Movement_MountMaxVerticalUpBlocksPerSecond", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.MountMaxVerticalUpBlocksPerSecond", - "IncludeInCommandLine": false, - "DefaultValue": "36", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Mount Max Cumulative Blocks Per Second", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.MountMaxCumulativeBlocksPerSecond", - "Keywords": "anticheat,movement,mountmaxcumulativeblockspersecond", - "FieldName": "Stratum_main_Anticheat_Movement_MountMaxCumulativeBlocksPerSecond", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.MountMaxCumulativeBlocksPerSecond", - "IncludeInCommandLine": false, - "DefaultValue": "160", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Mount Slack Blocks", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.MountSlackBlocks", - "Keywords": "anticheat,movement,mountslackblocks", - "FieldName": "Stratum_main_Anticheat_Movement_MountSlackBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.MountSlackBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Kick Confirmed Cheats", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.KickConfirmedCheats", - "Keywords": "anticheat,movement,kickconfirmedcheats", - "FieldName": "Stratum_main_Anticheat_Movement_KickConfirmedCheats", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.KickConfirmedCheats", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Kick After Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.KickAfterViolations", - "Keywords": "anticheat,movement,kickafterviolations", - "FieldName": "Stratum_main_Anticheat_Movement_KickAfterViolations", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.KickAfterViolations", - "IncludeInCommandLine": false, - "DefaultValue": "10", - "EnumValues": {} - }, - { - "DisplayName": "Kick Message", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.KickMessage", - "Keywords": "anticheat,movement,kickmessage", - "FieldName": "Stratum_main_Anticheat_Movement_KickMessage", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.KickMessage", - "IncludeInCommandLine": false, - "DefaultValue": "Disconnected by Stratum movement protection", - "EnumValues": {} - }, - { - "DisplayName": "Detect Flight", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "Handles slow hover and air-walk cases that never trip the speed caps. (data/stratum.json -> $.Anticheat.Movement.DetectFlight)", - "Keywords": "anticheat,movement,detectflight", - "FieldName": "Stratum_main_Anticheat_Movement_DetectFlight", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.DetectFlight", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Detect Water Walk", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.DetectWaterWalk", - "Keywords": "anticheat,movement,detectwaterwalk", - "FieldName": "Stratum_main_Anticheat_Movement_DetectWaterWalk", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.DetectWaterWalk", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Water Walk Consecutive Ticks", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.WaterWalkConsecutiveTicks", - "Keywords": "anticheat,movement,waterwalkconsecutiveticks", - "FieldName": "Stratum_main_Anticheat_Movement_WaterWalkConsecutiveTicks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.WaterWalkConsecutiveTicks", - "IncludeInCommandLine": false, - "DefaultValue": "3", - "EnumValues": {} - }, - { - "DisplayName": "Water Walk Entry Grace Ms", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.WaterWalkEntryGraceMs", - "Keywords": "anticheat,movement,waterwalkentrygracems", - "FieldName": "Stratum_main_Anticheat_Movement_WaterWalkEntryGraceMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.WaterWalkEntryGraceMs", - "IncludeInCommandLine": false, - "DefaultValue": "900", - "EnumValues": {} - }, - { - "DisplayName": "Ground Contact Tolerance", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.GroundContactTolerance", - "Keywords": "anticheat,movement,groundcontacttolerance", - "FieldName": "Stratum_main_Anticheat_Movement_GroundContactTolerance", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.GroundContactTolerance", - "IncludeInCommandLine": false, - "DefaultValue": "0.04", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Flight Ground Scan Depth", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "Extra cells below the real ground contact check. Keep this low unless testing proves otherwise. (data/stratum.json -> $.Anticheat.Movement.FlightGroundScanDepth)", - "Keywords": "anticheat,movement,flightgroundscandepth", - "FieldName": "Stratum_main_Anticheat_Movement_FlightGroundScanDepth", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.FlightGroundScanDepth", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Flight Min Airborne Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.FlightMinAirborneSeconds", - "Keywords": "anticheat,movement,flightminairborneseconds", - "FieldName": "Stratum_main_Anticheat_Movement_FlightMinAirborneSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.FlightMinAirborneSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "1.75", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Flight Required Descent Blocks", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.FlightRequiredDescentBlocks", - "Keywords": "anticheat,movement,flightrequireddescentblocks", - "FieldName": "Stratum_main_Anticheat_Movement_FlightRequiredDescentBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.FlightRequiredDescentBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "0.35", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Detect Noclip", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "Chest-only by design. Feet collide with too many normal partial blocks. (data/stratum.json -> $.Anticheat.Movement.DetectNoclip)", - "Keywords": "anticheat,movement,detectnoclip", - "FieldName": "Stratum_main_Anticheat_Movement_DetectNoclip", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.DetectNoclip", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Noclip Consecutive Ticks", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Movement.NoclipConsecutiveTicks", - "Keywords": "anticheat,movement,noclipconsecutiveticks", - "FieldName": "Stratum_main_Anticheat_Movement_NoclipConsecutiveTicks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Movement.NoclipConsecutiveTicks", - "IncludeInCommandLine": false, - "DefaultValue": "3", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Combat:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Combat.Enabled", - "Keywords": "anticheat,combat,enabled", - "FieldName": "Stratum_main_Anticheat_Combat_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Combat.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Alert After Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Combat:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Combat.AlertAfterViolations", - "Keywords": "anticheat,combat,alertafterviolations", - "FieldName": "Stratum_main_Anticheat_Combat_AlertAfterViolations", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Combat.AlertAfterViolations", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {} - }, - { - "DisplayName": "Alert Window Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Combat:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Combat.AlertWindowSeconds", - "Keywords": "anticheat,combat,alertwindowseconds", - "FieldName": "Stratum_main_Anticheat_Combat_AlertWindowSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Combat.AlertWindowSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "10", - "EnumValues": {} - }, - { - "DisplayName": "Repeat Alert Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Combat:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Combat.RepeatAlertSeconds", - "Keywords": "anticheat,combat,repeatalertseconds", - "FieldName": "Stratum_main_Anticheat_Combat_RepeatAlertSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Combat.RepeatAlertSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "20", - "EnumValues": {} - }, - { - "DisplayName": "Detect Multi Target", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Combat:gpp_maybe:10", - "Description": "Attacking several distinct entities in a tiny window is physically impossible with a real client (one target per swing, one crosshair). This is the highest-confidence signal here. (data/stratum.json -> $.Anticheat.Combat.DetectMultiTarget)", - "Keywords": "anticheat,combat,detectmultitarget", - "FieldName": "Stratum_main_Anticheat_Combat_DetectMultiTarget", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Combat.DetectMultiTarget", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Multi Target Window Ms", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Combat:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Combat.MultiTargetWindowMs", - "Keywords": "anticheat,combat,multitargetwindowms", - "FieldName": "Stratum_main_Anticheat_Combat_MultiTargetWindowMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Combat.MultiTargetWindowMs", - "IncludeInCommandLine": false, - "DefaultValue": "400", - "EnumValues": {} - }, - { - "DisplayName": "Multi Target Threshold", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Combat:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Combat.MultiTargetThreshold", - "Keywords": "anticheat,combat,multitargetthreshold", - "FieldName": "Stratum_main_Anticheat_Combat_MultiTargetThreshold", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Combat.MultiTargetThreshold", - "IncludeInCommandLine": false, - "DefaultValue": "3", - "EnumValues": {} - }, - { - "DisplayName": "Detect Aim Cone", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Combat:gpp_maybe:10", - "Description": "Flags an attack whose target sits outside the player's aim cone. Kept generous so ordinary aiming plus lag never trips it; the point is to catch hits landed on entities beside or behind the player, which only an aura does. (data/stratum.json -> $.Anticheat.Combat.DetectAimCone)", - "Keywords": "anticheat,combat,detectaimcone", - "FieldName": "Stratum_main_Anticheat_Combat_DetectAimCone", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Combat.DetectAimCone", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Max Attack Angle Degrees", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Combat:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Combat.MaxAttackAngleDegrees", - "Keywords": "anticheat,combat,maxattackangledegrees", - "FieldName": "Stratum_main_Anticheat_Combat_MaxAttackAngleDegrees", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Combat.MaxAttackAngleDegrees", - "IncludeInCommandLine": false, - "DefaultValue": "75.0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Min Angle Check Distance", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Combat:gpp_maybe:10", - "Description": "Skip the cone test when the target is basically touching the player, where the geometry of a large hitbox makes the angle meaningless. (data/stratum.json -> $.Anticheat.Combat.MinAngleCheckDistance)", - "Keywords": "anticheat,combat,minanglecheckdistance", - "FieldName": "Stratum_main_Anticheat_Combat_MinAngleCheckDistance", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Combat.MinAngleCheckDistance", - "IncludeInCommandLine": false, - "DefaultValue": "1.5", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Kick Confirmed Cheats", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Combat:gpp_maybe:10", - "Description": "Combat heuristics start as monitor-only. Turn this on once a server has watched the /stratum ac combat data and is comfortable the false-positive rate is zero. (data/stratum.json -> $.Anticheat.Combat.KickConfirmedCheats)", - "Keywords": "anticheat,combat,kickconfirmedcheats", - "FieldName": "Stratum_main_Anticheat_Combat_KickConfirmedCheats", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Combat.KickConfirmedCheats", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Kick After Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Combat:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Combat.KickAfterViolations", - "Keywords": "anticheat,combat,kickafterviolations", - "FieldName": "Stratum_main_Anticheat_Combat_KickAfterViolations", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Combat.KickAfterViolations", - "IncludeInCommandLine": false, - "DefaultValue": "12", - "EnumValues": {} - }, - { - "DisplayName": "Kick Message", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Combat:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.Combat.KickMessage", - "Keywords": "anticheat,combat,kickmessage", - "FieldName": "Stratum_main_Anticheat_Combat_KickMessage", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Combat.KickMessage", - "IncludeInCommandLine": false, - "DefaultValue": "Disconnected by Stratum combat protection", - "EnumValues": {} - }, - { - "DisplayName": "Cancel Flagged Hits", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Combat:gpp_maybe:10", - "Description": "When on, a flagged hit is dropped instead of applied. Off by default so v1 never changes the outcome of any hit; a real client can't trigger these checks anyway. (data/stratum.json -> $.Anticheat.Combat.CancelFlaggedHits)", - "Keywords": "anticheat,combat,cancelflaggedhits", - "FieldName": "Stratum_main_Anticheat_Combat_CancelFlaggedHits", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.Combat.CancelFlaggedHits", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > No Fall:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.NoFall.Enabled", - "Keywords": "anticheat,nofall,enabled", - "FieldName": "Stratum_main_Anticheat_NoFall_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.NoFall.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Alert After Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > No Fall:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.NoFall.AlertAfterViolations", - "Keywords": "anticheat,nofall,alertafterviolations", - "FieldName": "Stratum_main_Anticheat_NoFall_AlertAfterViolations", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.NoFall.AlertAfterViolations", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {} - }, - { - "DisplayName": "Alert Window Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > No Fall:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.NoFall.AlertWindowSeconds", - "Keywords": "anticheat,nofall,alertwindowseconds", - "FieldName": "Stratum_main_Anticheat_NoFall_AlertWindowSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.NoFall.AlertWindowSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "10", - "EnumValues": {} - }, - { - "DisplayName": "Repeat Alert Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > No Fall:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.NoFall.RepeatAlertSeconds", - "Keywords": "anticheat,nofall,repeatalertseconds", - "FieldName": "Stratum_main_Anticheat_NoFall_RepeatAlertSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.NoFall.RepeatAlertSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "20", - "EnumValues": {} - }, - { - "DisplayName": "Min Fall Blocks", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > No Fall:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.NoFall.MinFallBlocks", - "Keywords": "anticheat,nofall,minfallblocks", - "FieldName": "Stratum_main_Anticheat_NoFall_MinFallBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.NoFall.MinFallBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "5.0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Min Descent Speed", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > No Fall:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.NoFall.MinDescentSpeed", - "Keywords": "anticheat,nofall,mindescentspeed", - "FieldName": "Stratum_main_Anticheat_NoFall_MinDescentSpeed", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.NoFall.MinDescentSpeed", - "IncludeInCommandLine": false, - "DefaultValue": "4.0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Kick Confirmed Cheats", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > No Fall:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.NoFall.KickConfirmedCheats", - "Keywords": "anticheat,nofall,kickconfirmedcheats", - "FieldName": "Stratum_main_Anticheat_NoFall_KickConfirmedCheats", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.NoFall.KickConfirmedCheats", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Kick After Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > No Fall:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.NoFall.KickAfterViolations", - "Keywords": "anticheat,nofall,kickafterviolations", - "FieldName": "Stratum_main_Anticheat_NoFall_KickAfterViolations", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.NoFall.KickAfterViolations", - "IncludeInCommandLine": false, - "DefaultValue": "10", - "EnumValues": {} - }, - { - "DisplayName": "Kick Message", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > No Fall:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.NoFall.KickMessage", - "Keywords": "anticheat,nofall,kickmessage", - "FieldName": "Stratum_main_Anticheat_NoFall_KickMessage", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.NoFall.KickMessage", - "IncludeInCommandLine": false, - "DefaultValue": "Disconnected by Stratum no-fall protection", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MultiBreak.Enabled", - "Keywords": "anticheat,multibreak,enabled", - "FieldName": "Stratum_main_Anticheat_MultiBreak_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MultiBreak.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Alert After Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MultiBreak.AlertAfterViolations", - "Keywords": "anticheat,multibreak,alertafterviolations", - "FieldName": "Stratum_main_Anticheat_MultiBreak_AlertAfterViolations", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MultiBreak.AlertAfterViolations", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {} - }, - { - "DisplayName": "Alert Window Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MultiBreak.AlertWindowSeconds", - "Keywords": "anticheat,multibreak,alertwindowseconds", - "FieldName": "Stratum_main_Anticheat_MultiBreak_AlertWindowSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MultiBreak.AlertWindowSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "10", - "EnumValues": {} - }, - { - "DisplayName": "Repeat Alert Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MultiBreak.RepeatAlertSeconds", - "Keywords": "anticheat,multibreak,repeatalertseconds", - "FieldName": "Stratum_main_Anticheat_MultiBreak_RepeatAlertSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MultiBreak.RepeatAlertSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "20", - "EnumValues": {} - }, - { - "DisplayName": "Window Ms", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MultiBreak.WindowMs", - "Keywords": "anticheat,multibreak,windowms", - "FieldName": "Stratum_main_Anticheat_MultiBreak_WindowMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MultiBreak.WindowMs", - "IncludeInCommandLine": false, - "DefaultValue": "300", - "EnumValues": {} - }, - { - "DisplayName": "Max Breaks In Window", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MultiBreak.MaxBreaksInWindow", - "Keywords": "anticheat,multibreak,maxbreaksinwindow", - "FieldName": "Stratum_main_Anticheat_MultiBreak_MaxBreaksInWindow", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MultiBreak.MaxBreaksInWindow", - "IncludeInCommandLine": false, - "DefaultValue": "6", - "EnumValues": {} - }, - { - "DisplayName": "Max Tracked Breaks", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", - "Description": "Cap on tracked positions per player so a huge radius nuke can't grow memory (data/stratum.json -> $.Anticheat.MultiBreak.MaxTrackedBreaks)", - "Keywords": "anticheat,multibreak,maxtrackedbreaks", - "FieldName": "Stratum_main_Anticheat_MultiBreak_MaxTrackedBreaks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MultiBreak.MaxTrackedBreaks", - "IncludeInCommandLine": false, - "DefaultValue": "128", - "EnumValues": {} - }, - { - "DisplayName": "Kick Confirmed Cheats", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", - "Description": "Off by default: monitor-only (data/stratum.json -> $.Anticheat.MultiBreak.KickConfirmedCheats)", - "Keywords": "anticheat,multibreak,kickconfirmedcheats", - "FieldName": "Stratum_main_Anticheat_MultiBreak_KickConfirmedCheats", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MultiBreak.KickConfirmedCheats", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Kick After Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MultiBreak.KickAfterViolations", - "Keywords": "anticheat,multibreak,kickafterviolations", - "FieldName": "Stratum_main_Anticheat_MultiBreak_KickAfterViolations", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MultiBreak.KickAfterViolations", - "IncludeInCommandLine": false, - "DefaultValue": "4", - "EnumValues": {} - }, - { - "DisplayName": "Kick Message", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MultiBreak.KickMessage", - "Keywords": "anticheat,multibreak,kickmessage", - "FieldName": "Stratum_main_Anticheat_MultiBreak_KickMessage", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MultiBreak.KickMessage", - "IncludeInCommandLine": false, - "DefaultValue": "Disconnected by Stratum multi-break protection", - "EnumValues": {} - }, - { - "DisplayName": "Kick On Fingerprint", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Multi Break:gpp_maybe:10", - "Description": "when every hit lands dead-centre (0.5,0.5,0.5) can't come from a real raytrace, which always strikes a block surface. Combined with the superhuman burst rate this is near-zero false-positive, so such a burst may kick immediately even while KickConfirmedCheats stays off. (data/stratum.json -> $.Anticheat.MultiBreak.KickOnFingerprint)", - "Keywords": "anticheat,multibreak,kickonfingerprint", - "FieldName": "Stratum_main_Anticheat_MultiBreak_KickOnFingerprint", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MultiBreak.KickOnFingerprint", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.Enabled", - "Keywords": "anticheat,movementauthority,enabled", - "FieldName": "Stratum_main_Anticheat_MovementAuthority_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MovementAuthority.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Alert After Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.AlertAfterViolations", - "Keywords": "anticheat,movementauthority,alertafterviolations", - "FieldName": "Stratum_main_Anticheat_MovementAuthority_AlertAfterViolations", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MovementAuthority.AlertAfterViolations", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {} - }, - { - "DisplayName": "Alert Window Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.AlertWindowSeconds", - "Keywords": "anticheat,movementauthority,alertwindowseconds", - "FieldName": "Stratum_main_Anticheat_MovementAuthority_AlertWindowSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MovementAuthority.AlertWindowSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "10", - "EnumValues": {} - }, - { - "DisplayName": "Repeat Alert Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.RepeatAlertSeconds", - "Keywords": "anticheat,movementauthority,repeatalertseconds", - "FieldName": "Stratum_main_Anticheat_MovementAuthority_RepeatAlertSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MovementAuthority.RepeatAlertSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "20", - "EnumValues": {} - }, - { - "DisplayName": "Detect Step Height", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.DetectStepHeight", - "Keywords": "anticheat,movementauthority,detectstepheight", - "FieldName": "Stratum_main_Anticheat_MovementAuthority_DetectStepHeight", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MovementAuthority.DetectStepHeight", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Max Step Height Blocks", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.MaxStepHeightBlocks", - "Keywords": "anticheat,movementauthority,maxstepheightblocks", - "FieldName": "Stratum_main_Anticheat_MovementAuthority_MaxStepHeightBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MovementAuthority.MaxStepHeightBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "1.3", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Step Max Horizontal Blocks", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.StepMaxHorizontalBlocks", - "Keywords": "anticheat,movementauthority,stepmaxhorizontalblocks", - "FieldName": "Stratum_main_Anticheat_MovementAuthority_StepMaxHorizontalBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MovementAuthority.StepMaxHorizontalBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "1.5", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Detect Acceleration", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.DetectAcceleration", - "Keywords": "anticheat,movementauthority,detectacceleration", - "FieldName": "Stratum_main_Anticheat_MovementAuthority_DetectAcceleration", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MovementAuthority.DetectAcceleration", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Max Speed Jump Blocks Per Second", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.MaxSpeedJumpBlocksPerSecond", - "Keywords": "anticheat,movementauthority,maxspeedjumpblockspersecond", - "FieldName": "Stratum_main_Anticheat_MovementAuthority_MaxSpeedJumpBlocksPerSecond", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MovementAuthority.MaxSpeedJumpBlocksPerSecond", - "IncludeInCommandLine": false, - "DefaultValue": "16.0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Min Flagged Speed", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.MinFlaggedSpeed", - "Keywords": "anticheat,movementauthority,minflaggedspeed", - "FieldName": "Stratum_main_Anticheat_MovementAuthority_MinFlaggedSpeed", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MovementAuthority.MinFlaggedSpeed", - "IncludeInCommandLine": false, - "DefaultValue": "12.0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Kick Confirmed Cheats", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.KickConfirmedCheats", - "Keywords": "anticheat,movementauthority,kickconfirmedcheats", - "FieldName": "Stratum_main_Anticheat_MovementAuthority_KickConfirmedCheats", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MovementAuthority.KickConfirmedCheats", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Kick After Violations", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.KickAfterViolations", - "Keywords": "anticheat,movementauthority,kickafterviolations", - "FieldName": "Stratum_main_Anticheat_MovementAuthority_KickAfterViolations", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MovementAuthority.KickAfterViolations", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {} - }, - { - "DisplayName": "Kick Message", - "Category": "Stratum:filter_alt", - "Subcategory": "Anticheat > Movement Authority:gpp_maybe:10", - "Description": "data/stratum.json -> $.Anticheat.MovementAuthority.KickMessage", - "Keywords": "anticheat,movementauthority,kickmessage", - "FieldName": "Stratum_main_Anticheat_MovementAuthority_KickMessage", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Anticheat.MovementAuthority.KickMessage", - "IncludeInCommandLine": false, - "DefaultValue": "Disconnected by Stratum movement protection", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Client Mod Policy:extension:10", - "Description": "data/stratum.json -> $.ClientModPolicy.Enabled", - "Keywords": "clientmodpolicy,enabled", - "FieldName": "Stratum_main_ClientModPolicy_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ClientModPolicy.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Strict Whitelist", - "Category": "Stratum:filter_alt", - "Subcategory": "Client Mod Policy:extension:10", - "Description": "data/stratum.json -> $.ClientModPolicy.StrictWhitelist", - "Keywords": "clientmodpolicy,strictwhitelist", - "FieldName": "Stratum_main_ClientModPolicy_StrictWhitelist", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ClientModPolicy.StrictWhitelist", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Include Server Universal Mods", - "Category": "Stratum:filter_alt", - "Subcategory": "Client Mod Policy:extension:10", - "Description": "data/stratum.json -> $.ClientModPolicy.IncludeServerUniversalMods", - "Keywords": "clientmodpolicy,includeserveruniversalmods", - "FieldName": "Stratum_main_ClientModPolicy_IncludeServerUniversalMods", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ClientModPolicy.IncludeServerUniversalMods", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Log Policy On Startup", - "Category": "Stratum:filter_alt", - "Subcategory": "Client Mod Policy:extension:10", - "Description": "data/stratum.json -> $.ClientModPolicy.LogPolicyOnStartup", - "Keywords": "clientmodpolicy,logpolicyonstartup", - "FieldName": "Stratum_main_ClientModPolicy_LogPolicyOnStartup", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ClientModPolicy.LogPolicyOnStartup", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Split Terrain Pass", - "Category": "Stratum:filter_alt", - "Subcategory": "Worldgen:public:10", - "Description": "Runs the Terrain pass as two sub-stages so two threads can share it. Off gives the stock single-stage pass. See StratumWorldgenCompat. (data/stratum.json -> $.Worldgen.SplitTerrainPass)", - "Keywords": "worldgen,splitterrainpass", - "FieldName": "Stratum_main_Worldgen_SplitTerrainPass", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Worldgen.SplitTerrainPass", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Auto Disable Split For Mods", - "Category": "Stratum:filter_alt", - "Subcategory": "Worldgen:public:10", - "Description": "Drops back to the vanilla single-stage pass when a mod registers a handler there or patches a generator inside it. Leave on unless you have checked this server's mods. (data/stratum.json -> $.Worldgen.AutoDisableSplitForMods)", - "Keywords": "worldgen,autodisablesplitformods", - "FieldName": "Stratum_main_Worldgen_AutoDisableSplitForMods", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Worldgen.AutoDisableSplitForMods", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Chat:chat:10", - "Description": "data/stratum.json -> $.Chat.Enabled", - "Keywords": "chat,enabled", - "FieldName": "Stratum_main_Chat_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Chat.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Linkify Urls", - "Category": "Stratum:filter_alt", - "Subcategory": "Chat:chat:10", - "Description": "data/stratum.json -> $.Chat.LinkifyUrls", - "Keywords": "chat,linkifyurls", - "FieldName": "Stratum_main_Chat_LinkifyUrls", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Chat.LinkifyUrls", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Show Joins", - "Category": "Stratum:filter_alt", - "Subcategory": "Chat > Connection Messages:chat:10", - "Description": "data/stratum.json -> $.Chat.ConnectionMessages.ShowJoins", - "Keywords": "chat,connectionmessages,showjoins", - "FieldName": "Stratum_main_Chat_ConnectionMessages_ShowJoins", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Chat.ConnectionMessages.ShowJoins", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Show Leaves", - "Category": "Stratum:filter_alt", - "Subcategory": "Chat > Connection Messages:chat:10", - "Description": "data/stratum.json -> $.Chat.ConnectionMessages.ShowLeaves", - "Keywords": "chat,connectionmessages,showleaves", - "FieldName": "Stratum_main_Chat_ConnectionMessages_ShowLeaves", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Chat.ConnectionMessages.ShowLeaves", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Show Disconnects", - "Category": "Stratum:filter_alt", - "Subcategory": "Chat > Connection Messages:chat:10", - "Description": "data/stratum.json -> $.Chat.ConnectionMessages.ShowDisconnects", - "Keywords": "chat,connectionmessages,showdisconnects", - "FieldName": "Stratum_main_Chat_ConnectionMessages_ShowDisconnects", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Chat.ConnectionMessages.ShowDisconnects", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Chat > Rate Limit:chat:10", - "Description": "data/stratum.json -> $.Chat.RateLimit.Enabled", - "Keywords": "chat,ratelimit,enabled", - "FieldName": "Stratum_main_Chat_RateLimit_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Chat.RateLimit.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Minimum Interval Ms", - "Category": "Stratum:filter_alt", - "Subcategory": "Chat > Rate Limit:chat:10", - "Description": "data/stratum.json -> $.Chat.RateLimit.MinimumIntervalMs", - "Keywords": "chat,ratelimit,minimumintervalms", - "FieldName": "Stratum_main_Chat_RateLimit_MinimumIntervalMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Chat.RateLimit.MinimumIntervalMs", - "IncludeInCommandLine": false, - "DefaultValue": "750", - "EnumValues": {} - }, - { - "DisplayName": "Drop Duplicates", - "Category": "Stratum:filter_alt", - "Subcategory": "Chat > Rate Limit:chat:10", - "Description": "data/stratum.json -> $.Chat.RateLimit.DropDuplicates", - "Keywords": "chat,ratelimit,dropduplicates", - "FieldName": "Stratum_main_Chat_RateLimit_DropDuplicates", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Chat.RateLimit.DropDuplicates", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Duplicate Window Ms", - "Category": "Stratum:filter_alt", - "Subcategory": "Chat > Rate Limit:chat:10", - "Description": "data/stratum.json -> $.Chat.RateLimit.DuplicateWindowMs", - "Keywords": "chat,ratelimit,duplicatewindowms", - "FieldName": "Stratum_main_Chat_RateLimit_DuplicateWindowMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Chat.RateLimit.DuplicateWindowMs", - "IncludeInCommandLine": false, - "DefaultValue": "3000", - "EnumValues": {} - }, - { - "DisplayName": "Exempt Commands", - "Category": "Stratum:filter_alt", - "Subcategory": "Chat > Rate Limit:chat:10", - "Description": "data/stratum.json -> $.Chat.RateLimit.ExemptCommands", - "Keywords": "chat,ratelimit,exemptcommands", - "FieldName": "Stratum_main_Chat_RateLimit_ExemptCommands", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Chat.RateLimit.ExemptCommands", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Appearance > Theme:palette:10", - "Description": "data/stratum.json -> $.Appearance.Theme.Enabled", - "Keywords": "appearance,theme,enabled", - "FieldName": "Stratum_main_Appearance_Theme_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Appearance.Theme.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Style Disconnect Screens", - "Category": "Stratum:filter_alt", - "Subcategory": "Appearance > Theme:palette:10", - "Description": "data/stratum.json -> $.Appearance.Theme.StyleDisconnectScreens", - "Keywords": "appearance,theme,styledisconnectscreens", - "FieldName": "Stratum_main_Appearance_Theme_StyleDisconnectScreens", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Appearance.Theme.StyleDisconnectScreens", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Style Join Leave Messages", - "Category": "Stratum:filter_alt", - "Subcategory": "Appearance > Theme:palette:10", - "Description": "data/stratum.json -> $.Appearance.Theme.StyleJoinLeaveMessages", - "Keywords": "appearance,theme,stylejoinleavemessages", - "FieldName": "Stratum_main_Appearance_Theme_StyleJoinLeaveMessages", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Appearance.Theme.StyleJoinLeaveMessages", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Style Welcome Messages", - "Category": "Stratum:filter_alt", - "Subcategory": "Appearance > Theme:palette:10", - "Description": "data/stratum.json -> $.Appearance.Theme.StyleWelcomeMessages", - "Keywords": "appearance,theme,stylewelcomemessages", - "FieldName": "Stratum_main_Appearance_Theme_StyleWelcomeMessages", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Appearance.Theme.StyleWelcomeMessages", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Brand Name", - "Category": "Stratum:filter_alt", - "Subcategory": "Appearance > Theme:palette:10", - "Description": "data/stratum.json -> $.Appearance.Theme.BrandName", - "Keywords": "appearance,theme,brandname", - "FieldName": "Stratum_main_Appearance_Theme_BrandName", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Appearance.Theme.BrandName", - "IncludeInCommandLine": false, - "DefaultValue": "Stratum", - "EnumValues": {} - }, - { - "DisplayName": "Accent Color", - "Category": "Stratum:filter_alt", - "Subcategory": "Appearance > Theme:palette:10", - "Description": "data/stratum.json -> $.Appearance.Theme.AccentColor", - "Keywords": "appearance,theme,accentcolor", - "FieldName": "Stratum_main_Appearance_Theme_AccentColor", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Appearance.Theme.AccentColor", - "IncludeInCommandLine": false, - "DefaultValue": "#8bd5ff", - "EnumValues": {} - }, - { - "DisplayName": "Good Color", - "Category": "Stratum:filter_alt", - "Subcategory": "Appearance > Theme:palette:10", - "Description": "data/stratum.json -> $.Appearance.Theme.GoodColor", - "Keywords": "appearance,theme,goodcolor", - "FieldName": "Stratum_main_Appearance_Theme_GoodColor", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Appearance.Theme.GoodColor", - "IncludeInCommandLine": false, - "DefaultValue": "#9bd77e", - "EnumValues": {} - }, - { - "DisplayName": "Warn Color", - "Category": "Stratum:filter_alt", - "Subcategory": "Appearance > Theme:palette:10", - "Description": "data/stratum.json -> $.Appearance.Theme.WarnColor", - "Keywords": "appearance,theme,warncolor", - "FieldName": "Stratum_main_Appearance_Theme_WarnColor", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Appearance.Theme.WarnColor", - "IncludeInCommandLine": false, - "DefaultValue": "#e6c15f", - "EnumValues": {} - }, - { - "DisplayName": "Bad Color", - "Category": "Stratum:filter_alt", - "Subcategory": "Appearance > Theme:palette:10", - "Description": "data/stratum.json -> $.Appearance.Theme.BadColor", - "Keywords": "appearance,theme,badcolor", - "FieldName": "Stratum_main_Appearance_Theme_BadColor", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Appearance.Theme.BadColor", - "IncludeInCommandLine": false, - "DefaultValue": "#e47d68", - "EnumValues": {} - }, - { - "DisplayName": "Muted Color", - "Category": "Stratum:filter_alt", - "Subcategory": "Appearance > Theme:palette:10", - "Description": "data/stratum.json -> $.Appearance.Theme.MutedColor", - "Keywords": "appearance,theme,mutedcolor", - "FieldName": "Stratum_main_Appearance_Theme_MutedColor", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Appearance.Theme.MutedColor", - "IncludeInCommandLine": false, - "DefaultValue": "#9aa8b5", - "EnumValues": {} - }, - { - "DisplayName": "Label Color", - "Category": "Stratum:filter_alt", - "Subcategory": "Appearance > Theme:palette:10", - "Description": "data/stratum.json -> $.Appearance.Theme.LabelColor", - "Keywords": "appearance,theme,labelcolor", - "FieldName": "Stratum_main_Appearance_Theme_LabelColor", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Appearance.Theme.LabelColor", - "IncludeInCommandLine": false, - "DefaultValue": "#c9d6e2", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Appearance > Role Prefixes:palette:10", - "Description": "data/stratum.json -> $.Appearance.RolePrefixes.Enabled", - "Keywords": "appearance,roleprefixes,enabled", - "FieldName": "Stratum_main_Appearance_RolePrefixes_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Appearance.RolePrefixes.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Format", - "Category": "Stratum:filter_alt", - "Subcategory": "Appearance > Role Prefixes:palette:10", - "Description": "data/stratum.json -> $.Appearance.RolePrefixes.Format", - "Keywords": "appearance,roleprefixes,format", - "FieldName": "Stratum_main_Appearance_RolePrefixes_Format", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Appearance.RolePrefixes.Format", - "IncludeInCommandLine": false, - "DefaultValue": "[{tag}]", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Appearance > Nametags:palette:10", - "Description": "data/stratum.json -> $.Appearance.Nametags.Enabled", - "Keywords": "appearance,nametags,enabled", - "FieldName": "Stratum_main_Appearance_Nametags_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Appearance.Nametags.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Apply Role Prefix", - "Category": "Stratum:filter_alt", - "Subcategory": "Appearance > Nametags:palette:10", - "Description": "data/stratum.json -> $.Appearance.Nametags.ApplyRolePrefix", - "Keywords": "appearance,nametags,applyroleprefix", - "FieldName": "Stratum_main_Appearance_Nametags_ApplyRolePrefix", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Appearance.Nametags.ApplyRolePrefix", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Prefix Format", - "Category": "Stratum:filter_alt", - "Subcategory": "Appearance > Nametags:palette:10", - "Description": "data/stratum.json -> $.Appearance.Nametags.PrefixFormat", - "Keywords": "appearance,nametags,prefixformat", - "FieldName": "Stratum_main_Appearance_Nametags_PrefixFormat", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Appearance.Nametags.PrefixFormat", - "IncludeInCommandLine": false, - "DefaultValue": "[{tag}] ", - "EnumValues": {} - }, - { - "DisplayName": "Only Inject If No Existing Entitlement", - "Category": "Stratum:filter_alt", - "Subcategory": "Appearance > Nametags:palette:10", - "Description": "data/stratum.json -> $.Appearance.Nametags.OnlyInjectIfNoExistingEntitlement", - "Keywords": "appearance,nametags,onlyinjectifnoexistingentitlement", - "FieldName": "Stratum_main_Appearance_Nametags_OnlyInjectIfNoExistingEntitlement", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Appearance.Nametags.OnlyInjectIfNoExistingEntitlement", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Rules", - "Category": "Stratum:filter_alt", - "Subcategory": "Server Info:info:10", - "Description": "data/stratum.json -> $.ServerInfo.Rules", - "Keywords": "serverinfo,rules", - "FieldName": "Stratum_main_ServerInfo_Rules", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.ServerInfo.Rules", - "IncludeInCommandLine": false, - "DefaultValue": "Rules: be respectful, no griefing, no cheating, no harassment, and do not abuse exploits.", - "EnumValues": {} - }, - { - "DisplayName": "Discord Url", - "Category": "Stratum:filter_alt", - "Subcategory": "Server Info:info:10", - "Description": "data/stratum.json -> $.ServerInfo.DiscordUrl", - "Keywords": "serverinfo,discordurl", - "FieldName": "Stratum_main_ServerInfo_DiscordUrl", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.ServerInfo.DiscordUrl", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Website Url", - "Category": "Stratum:filter_alt", - "Subcategory": "Server Info:info:10", - "Description": "data/stratum.json -> $.ServerInfo.WebsiteUrl", - "Keywords": "serverinfo,websiteurl", - "FieldName": "Stratum_main_ServerInfo_WebsiteUrl", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.ServerInfo.WebsiteUrl", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Motd", - "Category": "Stratum:filter_alt", - "Subcategory": "Server Info:info:10", - "Description": "data/stratum.json -> $.ServerInfo.Motd", - "Keywords": "serverinfo,motd", - "FieldName": "Stratum_main_ServerInfo_Motd", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.ServerInfo.Motd", - "IncludeInCommandLine": false, - "DefaultValue": "Welcome to this Stratum server.", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Crowd Spawn:groups:10", - "Description": "data/stratum.json -> $.CrowdSpawn.Enabled", - "Keywords": "crowdspawn,enabled", - "FieldName": "Stratum_main_CrowdSpawn_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.CrowdSpawn.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Minimum Nearby Players", - "Category": "Stratum:filter_alt", - "Subcategory": "Crowd Spawn:groups:10", - "Description": "data/stratum.json -> $.CrowdSpawn.MinimumNearbyPlayers", - "Keywords": "crowdspawn,minimumnearbyplayers", - "FieldName": "Stratum_main_CrowdSpawn_MinimumNearbyPlayers", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.CrowdSpawn.MinimumNearbyPlayers", - "IncludeInCommandLine": false, - "DefaultValue": "24", - "EnumValues": {} - }, - { - "DisplayName": "Detection Radius Blocks", - "Category": "Stratum:filter_alt", - "Subcategory": "Crowd Spawn:groups:10", - "Description": "data/stratum.json -> $.CrowdSpawn.DetectionRadiusBlocks", - "Keywords": "crowdspawn,detectionradiusblocks", - "FieldName": "Stratum_main_CrowdSpawn_DetectionRadiusBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.CrowdSpawn.DetectionRadiusBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "48", - "EnumValues": {} - }, - { - "DisplayName": "Spread Radius Blocks", - "Category": "Stratum:filter_alt", - "Subcategory": "Crowd Spawn:groups:10", - "Description": "data/stratum.json -> $.CrowdSpawn.SpreadRadiusBlocks", - "Keywords": "crowdspawn,spreadradiusblocks", - "FieldName": "Stratum_main_CrowdSpawn_SpreadRadiusBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.CrowdSpawn.SpreadRadiusBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "64", - "EnumValues": {} - }, - { - "DisplayName": "Safe Position Tries", - "Category": "Stratum:filter_alt", - "Subcategory": "Crowd Spawn:groups:10", - "Description": "data/stratum.json -> $.CrowdSpawn.SafePositionTries", - "Keywords": "crowdspawn,safepositiontries", - "FieldName": "Stratum_main_CrowdSpawn_SafePositionTries", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.CrowdSpawn.SafePositionTries", - "IncludeInCommandLine": false, - "DefaultValue": "15", - "EnumValues": {} - }, - { - "DisplayName": "Include Returning Players", - "Category": "Stratum:filter_alt", - "Subcategory": "Crowd Spawn:groups:10", - "Description": "data/stratum.json -> $.CrowdSpawn.IncludeReturningPlayers", - "Keywords": "crowdspawn,includereturningplayers", - "FieldName": "Stratum_main_CrowdSpawn_IncludeReturningPlayers", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.CrowdSpawn.IncludeReturningPlayers", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Allow Unauthenticated Clients", - "Category": "Stratum:filter_alt", - "Subcategory": "Load Testing:science:10", - "Description": "data/stratum.json -> $.LoadTesting.AllowUnauthenticatedClients", - "Keywords": "loadtesting,allowunauthenticatedclients", - "FieldName": "Stratum_main_LoadTesting_AllowUnauthenticatedClients", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.LoadTesting.AllowUnauthenticatedClients", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Required Player Name Prefix", - "Category": "Stratum:filter_alt", - "Subcategory": "Load Testing:science:10", - "Description": "data/stratum.json -> $.LoadTesting.RequiredPlayerNamePrefix", - "Keywords": "loadtesting,requiredplayernameprefix", - "FieldName": "Stratum_main_LoadTesting_RequiredPlayerNamePrefix", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.LoadTesting.RequiredPlayerNamePrefix", - "IncludeInCommandLine": false, - "DefaultValue": "StratumBot", - "EnumValues": {} - }, - { - "DisplayName": "Required Player Uid Prefix", - "Category": "Stratum:filter_alt", - "Subcategory": "Load Testing:science:10", - "Description": "data/stratum.json -> $.LoadTesting.RequiredPlayerUidPrefix", - "Keywords": "loadtesting,requiredplayeruidprefix", - "FieldName": "Stratum_main_LoadTesting_RequiredPlayerUidPrefix", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.LoadTesting.RequiredPlayerUidPrefix", - "IncludeInCommandLine": false, - "DefaultValue": "stratum-loadtest-", - "EnumValues": {} - }, - { - "DisplayName": "Log Accepted Clients", - "Category": "Stratum:filter_alt", - "Subcategory": "Load Testing:science:10", - "Description": "data/stratum.json -> $.LoadTesting.LogAcceptedClients", - "Keywords": "loadtesting,logacceptedclients", - "FieldName": "Stratum_main_LoadTesting_LogAcceptedClients", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.LoadTesting.LogAcceptedClients", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Login Protection:login:10", - "Description": "/ Enable join/spawn damage immunity. (data/stratum.json -> $.LoginProtection.Enabled)", - "Keywords": "loginprotection,enabled", - "FieldName": "Stratum_main_LoginProtection_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.LoginProtection.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Protection Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Login Protection:login:10", - "Description": "/ How long the player is invulnerable after joining the world, in seconds. (data/stratum.json -> $.LoginProtection.ProtectionSeconds)", - "Keywords": "loginprotection,protectionseconds", - "FieldName": "Stratum_main_LoginProtection_ProtectionSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.LoginProtection.ProtectionSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "5", - "EnumValues": {} - }, - { - "DisplayName": "Cancel On Horizontal Move", - "Category": "Stratum:filter_alt", - "Subcategory": "Login Protection:login:10", - "Description": "/ End protection as soon as the player moves horizontally past . (data/stratum.json -> $.LoginProtection.CancelOnHorizontalMove)", - "Keywords": "loginprotection,cancelonhorizontalmove", - "FieldName": "Stratum_main_LoginProtection_CancelOnHorizontalMove", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.LoginProtection.CancelOnHorizontalMove", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Move Threshold Blocks", - "Category": "Stratum:filter_alt", - "Subcategory": "Login Protection:login:10", - "Description": "/ How far (in blocks) a player must move horizontally from their join position to end protection. (data/stratum.json -> $.LoginProtection.MoveThresholdBlocks)", - "Keywords": "loginprotection,movethresholdblocks", - "FieldName": "Stratum_main_LoginProtection_MoveThresholdBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.LoginProtection.MoveThresholdBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "0.5", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Cancel In Fire Or Lava", - "Category": "Stratum:filter_alt", - "Subcategory": "Login Protection:login:10", - "Description": "/ If true, protection ends immediately when the player is on fire or standing in lava. (data/stratum.json -> $.LoginProtection.CancelInFireOrLava)", - "Keywords": "loginprotection,cancelinfireorlava", - "FieldName": "Stratum_main_LoginProtection_CancelInFireOrLava", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.LoginProtection.CancelInFireOrLava", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Announce On Start", - "Category": "Stratum:filter_alt", - "Subcategory": "Login Protection:login:10", - "Description": "/ If true, send the player a chat message when protection starts. (data/stratum.json -> $.LoginProtection.AnnounceOnStart)", - "Keywords": "loginprotection,announceonstart", - "FieldName": "Stratum_main_LoginProtection_AnnounceOnStart", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.LoginProtection.AnnounceOnStart", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Announce On End", - "Category": "Stratum:filter_alt", - "Subcategory": "Login Protection:login:10", - "Description": "/ If true, send the player a chat message when protection ends. (data/stratum.json -> $.LoginProtection.AnnounceOnEnd)", - "Keywords": "loginprotection,announceonend", - "FieldName": "Stratum_main_LoginProtection_AnnounceOnEnd", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.LoginProtection.AnnounceOnEnd", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Start Message", - "Category": "Stratum:filter_alt", - "Subcategory": "Login Protection:login:10", - "Description": "/ Message sent when protection starts. {0} = seconds. (data/stratum.json -> $.LoginProtection.StartMessage)", - "Keywords": "loginprotection,startmessage", - "FieldName": "Stratum_main_LoginProtection_StartMessage", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.LoginProtection.StartMessage", - "IncludeInCommandLine": false, - "DefaultValue": "You are protected from damage for {0} seconds. Move to cancel.", - "EnumValues": {} - }, - { - "DisplayName": "End Message", - "Category": "Stratum:filter_alt", - "Subcategory": "Login Protection:login:10", - "Description": "/ Message sent when protection ends. (data/stratum.json -> $.LoginProtection.EndMessage)", - "Keywords": "loginprotection,endmessage", - "FieldName": "Stratum_main_LoginProtection_EndMessage", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.LoginProtection.EndMessage", - "IncludeInCommandLine": false, - "DefaultValue": "Login protection ended.", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Player Privacy:visibility_off:10", - "Description": "/ Enable the player-privacy disclosure hook. Disabled by default \\u2014 opt-in. (data/stratum.json -> $.PlayerPrivacy.Enabled)", - "Keywords": "playerprivacy,enabled", - "FieldName": "Stratum_main_PlayerPrivacy_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.PlayerPrivacy.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Hide Map Pins", - "Category": "Stratum:filter_alt", - "Subcategory": "Player Privacy:visibility_off:10", - "Description": "/ Hide player pins on the world map from other players (other than staff / group, per settings). (data/stratum.json -> $.PlayerPrivacy.HideMapPins)", - "Keywords": "playerprivacy,hidemappins", - "FieldName": "Stratum_main_PlayerPrivacy_HideMapPins", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.PlayerPrivacy.HideMapPins", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Allow Group Map Visibility", - "Category": "Stratum:filter_alt", - "Subcategory": "Player Privacy:visibility_off:10", - "Description": "/ Players in the same player-group can still see each other on the map. (data/stratum.json -> $.PlayerPrivacy.AllowGroupMapVisibility)", - "Keywords": "playerprivacy,allowgroupmapvisibility", - "FieldName": "Stratum_main_PlayerPrivacy_AllowGroupMapVisibility", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.PlayerPrivacy.AllowGroupMapVisibility", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Player Privacy > Staff Override:visibility_off:10", - "Description": "data/stratum.json -> $.PlayerPrivacy.StaffOverride.Enabled", - "Keywords": "playerprivacy,staffoverride,enabled", - "FieldName": "Stratum_main_PlayerPrivacy_StaffOverride_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.PlayerPrivacy.StaffOverride.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum:filter_alt", - "Subcategory": "Player Privacy > Staff Override:visibility_off:10", - "Description": "data/stratum.json -> $.PlayerPrivacy.StaffOverride.Privilege", - "Keywords": "playerprivacy,staffoverride,privilege", - "FieldName": "Stratum_main_PlayerPrivacy_StaffOverride_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.PlayerPrivacy.StaffOverride.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Player Privacy > Staff Override:visibility_off:10", - "Description": "data/stratum.json -> $.PlayerPrivacy.StaffOverride.CooldownSeconds", - "Keywords": "playerprivacy,staffoverride,cooldownseconds", - "FieldName": "Stratum_main_PlayerPrivacy_StaffOverride_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.PlayerPrivacy.StaffOverride.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum:filter_alt", - "Subcategory": "Player Privacy > Staff Override:visibility_off:10", - "Description": "data/stratum.json -> $.PlayerPrivacy.StaffOverride.CooldownBypassForStaff", - "Keywords": "playerprivacy,staffoverride,cooldownbypassforstaff", - "FieldName": "Stratum_main_PlayerPrivacy_StaffOverride_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.PlayerPrivacy.StaffOverride.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Show Staff Pins To All", - "Category": "Stratum:filter_alt", - "Subcategory": "Player Privacy:visibility_off:10", - "Description": "/ If true, staff with the override are also visible to everyone (their own pin is shown). If false, staff are hidden like other players. (data/stratum.json -> $.PlayerPrivacy.ShowStaffPinsToAll)", - "Keywords": "playerprivacy,showstaffpinstoall", - "FieldName": "Stratum_main_PlayerPrivacy_ShowStaffPinsToAll", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.PlayerPrivacy.ShowStaffPinsToAll", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Coordinate Snap Blocks", - "Category": "Stratum:filter_alt", - "Subcategory": "Player Privacy:visibility_off:10", - "Description": "/ / Snap broadcast pin coordinates to a grid of this many blocks for non-staff, non-group receivers. / 0 = exact. Use e.g. 32 to round nearest 32-block bucket so a hostile client can't deduce / exact location even from a sneaked-in receiver. Only applies when HideMapPins is false (i.e., / when pins are being sent at all). / (data/stratum.json -> $.PlayerPrivacy.CoordinateSnapBlocks)", - "Keywords": "playerprivacy,coordinatesnapblocks", - "FieldName": "Stratum_main_PlayerPrivacy_CoordinateSnapBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.PlayerPrivacy.CoordinateSnapBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Max Broadcast Distance Blocks", - "Category": "Stratum:filter_alt", - "Subcategory": "Player Privacy:visibility_off:10", - "Description": "/ / If \\u22650, overrides the world's mapPlayerRenderDistance at startup so map pins are / only sent within this many blocks. -1 = leave worldconfig alone. / (data/stratum.json -> $.PlayerPrivacy.MaxBroadcastDistanceBlocks)", - "Keywords": "playerprivacy,maxbroadcastdistanceblocks", - "FieldName": "Stratum_main_PlayerPrivacy_MaxBroadcastDistanceBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.PlayerPrivacy.MaxBroadcastDistanceBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "-1", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Backup:backup:10", - "Description": "data/stratum.json -> $.Backup.Enabled", - "Keywords": "backup,enabled", - "FieldName": "Stratum_main_Backup_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Backup.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Interval Minutes", - "Category": "Stratum:filter_alt", - "Subcategory": "Backup:backup:10", - "Description": "data/stratum.json -> $.Backup.IntervalMinutes", - "Keywords": "backup,intervalminutes", - "FieldName": "Stratum_main_Backup_IntervalMinutes", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Backup.IntervalMinutes", - "IncludeInCommandLine": false, - "DefaultValue": "360", - "EnumValues": {} - }, - { - "DisplayName": "Retain Count", - "Category": "Stratum:filter_alt", - "Subcategory": "Backup:backup:10", - "Description": "data/stratum.json -> $.Backup.RetainCount", - "Keywords": "backup,retaincount", - "FieldName": "Stratum_main_Backup_RetainCount", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Backup.RetainCount", - "IncludeInCommandLine": false, - "DefaultValue": "5", - "EnumValues": {} - }, - { - "DisplayName": "Log Backups", - "Category": "Stratum:filter_alt", - "Subcategory": "Backup:backup:10", - "Description": "data/stratum.json -> $.Backup.LogBackups", - "Keywords": "backup,logbackups", - "FieldName": "Stratum_main_Backup_LogBackups", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Backup.LogBackups", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Announcements:campaign:10", - "Description": "data/stratum.json -> $.Announcements.Enabled", - "Keywords": "announcements,enabled", - "FieldName": "Stratum_main_Announcements_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Announcements.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Interval Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Announcements:campaign:10", - "Description": "Seconds between broadcasts. (data/stratum.json -> $.Announcements.IntervalSeconds)", - "Keywords": "announcements,intervalseconds", - "FieldName": "Stratum_main_Announcements_IntervalSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Announcements.IntervalSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "300", - "EnumValues": {} - }, - { - "DisplayName": "Prefix", - "Category": "Stratum:filter_alt", - "Subcategory": "Announcements:campaign:10", - "Description": "Prepended to every message. Default matches /announce orange bold styling. (data/stratum.json -> $.Announcements.Prefix)", - "Keywords": "announcements,prefix", - "FieldName": "Stratum_main_Announcements_Prefix", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Announcements.Prefix", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Suffix", - "Category": "Stratum:filter_alt", - "Subcategory": "Announcements:campaign:10", - "Description": "Appended to every message. Closes the Prefix tags. (data/stratum.json -> $.Announcements.Suffix)", - "Keywords": "announcements,suffix", - "FieldName": "Stratum_main_Announcements_Suffix", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Announcements.Suffix", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Random Order", - "Category": "Stratum:filter_alt", - "Subcategory": "Announcements:campaign:10", - "Description": "If true, pick a random message each time instead of sequential rotation. (data/stratum.json -> $.Announcements.RandomOrder)", - "Keywords": "announcements,randomorder", - "FieldName": "Stratum_main_Announcements_RandomOrder", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Announcements.RandomOrder", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum:filter_alt", - "Subcategory": "Server Stats:insights:10", - "Description": "data/stratum.json -> $.ServerStats.Enabled", - "Keywords": "serverstats,enabled", - "FieldName": "Stratum_main_ServerStats_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ServerStats.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Report Url", - "Category": "Stratum:filter_alt", - "Subcategory": "Server Stats:insights:10", - "Description": "Central endpoint that receives the report (HTTP POST, application/json). Point this at your aggregator. Leave empty to keep reporting off even when Enabled is true. (data/stratum.json -> $.ServerStats.ReportUrl)", - "Keywords": "serverstats,reporturl", - "FieldName": "Stratum_main_ServerStats_ReportUrl", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.ServerStats.ReportUrl", - "IncludeInCommandLine": false, - "DefaultValue": "https://my.stratumvs.dev/stratum-stats.php", - "EnumValues": {} - }, - { - "DisplayName": "Interval Minutes", - "Category": "Stratum:filter_alt", - "Subcategory": "Server Stats:insights:10", - "Description": "data/stratum.json -> $.ServerStats.IntervalMinutes", - "Keywords": "serverstats,intervalminutes", - "FieldName": "Stratum_main_ServerStats_IntervalMinutes", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ServerStats.IntervalMinutes", - "IncludeInCommandLine": false, - "DefaultValue": "30", - "EnumValues": {} - }, - { - "DisplayName": "Timeout Seconds", - "Category": "Stratum:filter_alt", - "Subcategory": "Server Stats:insights:10", - "Description": "data/stratum.json -> $.ServerStats.TimeoutSeconds", - "Keywords": "serverstats,timeoutseconds", - "FieldName": "Stratum_main_ServerStats_TimeoutSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ServerStats.TimeoutSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "10", - "EnumValues": {} - }, - { - "DisplayName": "Server Id", - "Category": "Stratum:filter_alt", - "Subcategory": "Server Stats:insights:10", - "Description": "Random, anonymous, per-install id. Generated once on first run and kept so restarts are not counted as new servers. Delete it to reset this server's identity. (data/stratum.json -> $.ServerStats.ServerId)", - "Keywords": "serverstats,serverid", - "FieldName": "Stratum_main_ServerStats_ServerId", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.ServerStats.ServerId", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "General:terminal:20", - "Description": "data/stratum-commands.json -> $.Enabled", - "Keywords": "enabled", - "FieldName": "Stratum_cmd_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Spawn:terminal:20", - "Description": "data/stratum-commands.json -> $.Spawn.Enabled", - "Keywords": "spawn,enabled", - "FieldName": "Stratum_cmd_Spawn_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Spawn.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Spawn:terminal:20", - "Description": "data/stratum-commands.json -> $.Spawn.Privilege", - "Keywords": "spawn,privilege", - "FieldName": "Stratum_cmd_Spawn_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Spawn.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Spawn:terminal:20", - "Description": "data/stratum-commands.json -> $.Spawn.CooldownSeconds", - "Keywords": "spawn,cooldownseconds", - "FieldName": "Stratum_cmd_Spawn_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Spawn.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Spawn:terminal:20", - "Description": "data/stratum-commands.json -> $.Spawn.CooldownBypassForStaff", - "Keywords": "spawn,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_Spawn_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Spawn.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Set Spawn:terminal:20", - "Description": "data/stratum-commands.json -> $.SetSpawn.Enabled", - "Keywords": "setspawn,enabled", - "FieldName": "Stratum_cmd_SetSpawn_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.SetSpawn.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Set Spawn:terminal:20", - "Description": "data/stratum-commands.json -> $.SetSpawn.Privilege", - "Keywords": "setspawn,privilege", - "FieldName": "Stratum_cmd_SetSpawn_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.SetSpawn.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Set Spawn:terminal:20", - "Description": "data/stratum-commands.json -> $.SetSpawn.CooldownSeconds", - "Keywords": "setspawn,cooldownseconds", - "FieldName": "Stratum_cmd_SetSpawn_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.SetSpawn.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Set Spawn:terminal:20", - "Description": "data/stratum-commands.json -> $.SetSpawn.CooldownBypassForStaff", - "Keywords": "setspawn,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_SetSpawn_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.SetSpawn.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Teleport Requests > Request:terminal:20", - "Description": "data/stratum-commands.json -> $.TeleportRequests.Request.Enabled", - "Keywords": "teleportrequests,request,enabled", - "FieldName": "Stratum_cmd_TeleportRequests_Request_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.TeleportRequests.Request.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Teleport Requests > Request:terminal:20", - "Description": "data/stratum-commands.json -> $.TeleportRequests.Request.Privilege", - "Keywords": "teleportrequests,request,privilege", - "FieldName": "Stratum_cmd_TeleportRequests_Request_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.TeleportRequests.Request.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Teleport Requests > Request:terminal:20", - "Description": "data/stratum-commands.json -> $.TeleportRequests.Request.CooldownSeconds", - "Keywords": "teleportrequests,request,cooldownseconds", - "FieldName": "Stratum_cmd_TeleportRequests_Request_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.TeleportRequests.Request.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Teleport Requests > Request:terminal:20", - "Description": "data/stratum-commands.json -> $.TeleportRequests.Request.CooldownBypassForStaff", - "Keywords": "teleportrequests,request,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_TeleportRequests_Request_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.TeleportRequests.Request.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Teleport Requests > Here:terminal:20", - "Description": "data/stratum-commands.json -> $.TeleportRequests.Here.Enabled", - "Keywords": "teleportrequests,here,enabled", - "FieldName": "Stratum_cmd_TeleportRequests_Here_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.TeleportRequests.Here.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Teleport Requests > Here:terminal:20", - "Description": "data/stratum-commands.json -> $.TeleportRequests.Here.Privilege", - "Keywords": "teleportrequests,here,privilege", - "FieldName": "Stratum_cmd_TeleportRequests_Here_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.TeleportRequests.Here.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Teleport Requests > Here:terminal:20", - "Description": "data/stratum-commands.json -> $.TeleportRequests.Here.CooldownSeconds", - "Keywords": "teleportrequests,here,cooldownseconds", - "FieldName": "Stratum_cmd_TeleportRequests_Here_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.TeleportRequests.Here.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Teleport Requests > Here:terminal:20", - "Description": "data/stratum-commands.json -> $.TeleportRequests.Here.CooldownBypassForStaff", - "Keywords": "teleportrequests,here,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_TeleportRequests_Here_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.TeleportRequests.Here.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Allow Tpa Here", - "Category": "Stratum Commands:terminal", - "Subcategory": "Teleport Requests:terminal:20", - "Description": "data/stratum-commands.json -> $.TeleportRequests.AllowTpaHere", - "Keywords": "teleportrequests,allowtpahere", - "FieldName": "Stratum_cmd_TeleportRequests_AllowTpaHere", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.TeleportRequests.AllowTpaHere", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Timeout Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Teleport Requests:terminal:20", - "Description": "data/stratum-commands.json -> $.TeleportRequests.TimeoutSeconds", - "Keywords": "teleportrequests,timeoutseconds", - "FieldName": "Stratum_cmd_TeleportRequests_TimeoutSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.TeleportRequests.TimeoutSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "60", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Teleport Requests:terminal:20", - "Description": "data/stratum-commands.json -> $.TeleportRequests.CooldownSeconds", - "Keywords": "teleportrequests,cooldownseconds", - "FieldName": "Stratum_cmd_TeleportRequests_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.TeleportRequests.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "15", - "EnumValues": {} - }, - { - "DisplayName": "Warmup Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Teleport Requests:terminal:20", - "Description": "data/stratum-commands.json -> $.TeleportRequests.WarmupSeconds", - "Keywords": "teleportrequests,warmupseconds", - "FieldName": "Stratum_cmd_TeleportRequests_WarmupSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.TeleportRequests.WarmupSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "5", - "EnumValues": {} - }, - { - "DisplayName": "Teleport Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Teleport Requests:terminal:20", - "Description": "data/stratum-commands.json -> $.TeleportRequests.TeleportCooldownSeconds", - "Keywords": "teleportrequests,teleportcooldownseconds", - "FieldName": "Stratum_cmd_TeleportRequests_TeleportCooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.TeleportRequests.TeleportCooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "30", - "EnumValues": {} - }, - { - "DisplayName": "Cancel Move Distance Blocks", - "Category": "Stratum Commands:terminal", - "Subcategory": "Teleport Requests:terminal:20", - "Description": "data/stratum-commands.json -> $.TeleportRequests.CancelMoveDistanceBlocks", - "Keywords": "teleportrequests,cancelmovedistanceblocks", - "FieldName": "Stratum_cmd_TeleportRequests_CancelMoveDistanceBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.TeleportRequests.CancelMoveDistanceBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "0.35", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Cancel On Move", - "Category": "Stratum Commands:terminal", - "Subcategory": "Teleport Requests:terminal:20", - "Description": "data/stratum-commands.json -> $.TeleportRequests.CancelOnMove", - "Keywords": "teleportrequests,cancelonmove", - "FieldName": "Stratum_cmd_TeleportRequests_CancelOnMove", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.TeleportRequests.CancelOnMove", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Cancel On Damage", - "Category": "Stratum Commands:terminal", - "Subcategory": "Teleport Requests:terminal:20", - "Description": "data/stratum-commands.json -> $.TeleportRequests.CancelOnDamage", - "Keywords": "teleportrequests,cancelondamage", - "FieldName": "Stratum_cmd_TeleportRequests_CancelOnDamage", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.TeleportRequests.CancelOnDamage", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Bypass Warmup For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Teleport Requests:terminal:20", - "Description": "data/stratum-commands.json -> $.TeleportRequests.BypassWarmupForStaff", - "Keywords": "teleportrequests,bypasswarmupforstaff", - "FieldName": "Stratum_cmd_TeleportRequests_BypassWarmupForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.TeleportRequests.BypassWarmupForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Homes > Home:terminal:20", - "Description": "data/stratum-commands.json -> $.Homes.Home.Enabled", - "Keywords": "homes,home,enabled", - "FieldName": "Stratum_cmd_Homes_Home_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Homes.Home.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Homes > Home:terminal:20", - "Description": "data/stratum-commands.json -> $.Homes.Home.Privilege", - "Keywords": "homes,home,privilege", - "FieldName": "Stratum_cmd_Homes_Home_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Homes.Home.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Homes > Home:terminal:20", - "Description": "data/stratum-commands.json -> $.Homes.Home.CooldownSeconds", - "Keywords": "homes,home,cooldownseconds", - "FieldName": "Stratum_cmd_Homes_Home_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Homes.Home.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Homes > Home:terminal:20", - "Description": "data/stratum-commands.json -> $.Homes.Home.CooldownBypassForStaff", - "Keywords": "homes,home,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_Homes_Home_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Homes.Home.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Homes > Set Home:terminal:20", - "Description": "data/stratum-commands.json -> $.Homes.SetHome.Enabled", - "Keywords": "homes,sethome,enabled", - "FieldName": "Stratum_cmd_Homes_SetHome_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Homes.SetHome.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Homes > Set Home:terminal:20", - "Description": "data/stratum-commands.json -> $.Homes.SetHome.Privilege", - "Keywords": "homes,sethome,privilege", - "FieldName": "Stratum_cmd_Homes_SetHome_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Homes.SetHome.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Homes > Set Home:terminal:20", - "Description": "data/stratum-commands.json -> $.Homes.SetHome.CooldownSeconds", - "Keywords": "homes,sethome,cooldownseconds", - "FieldName": "Stratum_cmd_Homes_SetHome_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Homes.SetHome.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Homes > Set Home:terminal:20", - "Description": "data/stratum-commands.json -> $.Homes.SetHome.CooldownBypassForStaff", - "Keywords": "homes,sethome,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_Homes_SetHome_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Homes.SetHome.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Homes > Delete Home:terminal:20", - "Description": "data/stratum-commands.json -> $.Homes.DeleteHome.Enabled", - "Keywords": "homes,deletehome,enabled", - "FieldName": "Stratum_cmd_Homes_DeleteHome_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Homes.DeleteHome.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Homes > Delete Home:terminal:20", - "Description": "data/stratum-commands.json -> $.Homes.DeleteHome.Privilege", - "Keywords": "homes,deletehome,privilege", - "FieldName": "Stratum_cmd_Homes_DeleteHome_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Homes.DeleteHome.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Homes > Delete Home:terminal:20", - "Description": "data/stratum-commands.json -> $.Homes.DeleteHome.CooldownSeconds", - "Keywords": "homes,deletehome,cooldownseconds", - "FieldName": "Stratum_cmd_Homes_DeleteHome_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Homes.DeleteHome.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Homes > Delete Home:terminal:20", - "Description": "data/stratum-commands.json -> $.Homes.DeleteHome.CooldownBypassForStaff", - "Keywords": "homes,deletehome,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_Homes_DeleteHome_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Homes.DeleteHome.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Default Max Homes", - "Category": "Stratum Commands:terminal", - "Subcategory": "Homes:terminal:20", - "Description": "data/stratum-commands.json -> $.Homes.DefaultMaxHomes", - "Keywords": "homes,defaultmaxhomes", - "FieldName": "Stratum_cmd_Homes_DefaultMaxHomes", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Homes.DefaultMaxHomes", - "IncludeInCommandLine": false, - "DefaultValue": "3", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Seen:terminal:20", - "Description": "data/stratum-commands.json -> $.Seen.Enabled", - "Keywords": "seen,enabled", - "FieldName": "Stratum_cmd_Seen_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Seen.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Seen:terminal:20", - "Description": "data/stratum-commands.json -> $.Seen.Privilege", - "Keywords": "seen,privilege", - "FieldName": "Stratum_cmd_Seen_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Seen.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Seen:terminal:20", - "Description": "data/stratum-commands.json -> $.Seen.CooldownSeconds", - "Keywords": "seen,cooldownseconds", - "FieldName": "Stratum_cmd_Seen_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Seen.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Seen:terminal:20", - "Description": "data/stratum-commands.json -> $.Seen.CooldownBypassForStaff", - "Keywords": "seen,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_Seen_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Seen.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Whois:terminal:20", - "Description": "data/stratum-commands.json -> $.Whois.Enabled", - "Keywords": "whois,enabled", - "FieldName": "Stratum_cmd_Whois_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Whois.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Whois:terminal:20", - "Description": "data/stratum-commands.json -> $.Whois.Privilege", - "Keywords": "whois,privilege", - "FieldName": "Stratum_cmd_Whois_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Whois.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Whois:terminal:20", - "Description": "data/stratum-commands.json -> $.Whois.CooldownSeconds", - "Keywords": "whois,cooldownseconds", - "FieldName": "Stratum_cmd_Whois_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Whois.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Whois:terminal:20", - "Description": "data/stratum-commands.json -> $.Whois.CooldownBypassForStaff", - "Keywords": "whois,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_Whois_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Whois.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Near:terminal:20", - "Description": "data/stratum-commands.json -> $.Near.Enabled", - "Keywords": "near,enabled", - "FieldName": "Stratum_cmd_Near_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Near.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Near:terminal:20", - "Description": "data/stratum-commands.json -> $.Near.Privilege", - "Keywords": "near,privilege", - "FieldName": "Stratum_cmd_Near_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Near.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Near:terminal:20", - "Description": "data/stratum-commands.json -> $.Near.CooldownSeconds", - "Keywords": "near,cooldownseconds", - "FieldName": "Stratum_cmd_Near_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Near.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Near:terminal:20", - "Description": "data/stratum-commands.json -> $.Near.CooldownBypassForStaff", - "Keywords": "near,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_Near_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Near.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Back:terminal:20", - "Description": "data/stratum-commands.json -> $.Back.Enabled", - "Keywords": "back,enabled", - "FieldName": "Stratum_cmd_Back_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Back.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Back:terminal:20", - "Description": "data/stratum-commands.json -> $.Back.Privilege", - "Keywords": "back,privilege", - "FieldName": "Stratum_cmd_Back_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Back.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Back:terminal:20", - "Description": "data/stratum-commands.json -> $.Back.CooldownSeconds", - "Keywords": "back,cooldownseconds", - "FieldName": "Stratum_cmd_Back_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Back.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Back:terminal:20", - "Description": "data/stratum-commands.json -> $.Back.CooldownBypassForStaff", - "Keywords": "back,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_Back_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Back.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Message:terminal:20", - "Description": "data/stratum-commands.json -> $.Message.Enabled", - "Keywords": "message,enabled", - "FieldName": "Stratum_cmd_Message_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Message.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Message:terminal:20", - "Description": "data/stratum-commands.json -> $.Message.Privilege", - "Keywords": "message,privilege", - "FieldName": "Stratum_cmd_Message_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Message.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Message:terminal:20", - "Description": "data/stratum-commands.json -> $.Message.CooldownSeconds", - "Keywords": "message,cooldownseconds", - "FieldName": "Stratum_cmd_Message_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Message.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Message:terminal:20", - "Description": "data/stratum-commands.json -> $.Message.CooldownBypassForStaff", - "Keywords": "message,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_Message_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Message.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Staff Chat:terminal:20", - "Description": "data/stratum-commands.json -> $.StaffChat.Enabled", - "Keywords": "staffchat,enabled", - "FieldName": "Stratum_cmd_StaffChat_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.StaffChat.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Staff Chat:terminal:20", - "Description": "data/stratum-commands.json -> $.StaffChat.Privilege", - "Keywords": "staffchat,privilege", - "FieldName": "Stratum_cmd_StaffChat_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.StaffChat.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Staff Chat:terminal:20", - "Description": "data/stratum-commands.json -> $.StaffChat.CooldownSeconds", - "Keywords": "staffchat,cooldownseconds", - "FieldName": "Stratum_cmd_StaffChat_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.StaffChat.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Staff Chat:terminal:20", - "Description": "data/stratum-commands.json -> $.StaffChat.CooldownBypassForStaff", - "Keywords": "staffchat,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_StaffChat_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.StaffChat.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Chat Control:terminal:20", - "Description": "data/stratum-commands.json -> $.ChatControl.Enabled", - "Keywords": "chatcontrol,enabled", - "FieldName": "Stratum_cmd_ChatControl_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ChatControl.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Chat Control:terminal:20", - "Description": "data/stratum-commands.json -> $.ChatControl.Privilege", - "Keywords": "chatcontrol,privilege", - "FieldName": "Stratum_cmd_ChatControl_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.ChatControl.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Chat Control:terminal:20", - "Description": "data/stratum-commands.json -> $.ChatControl.CooldownSeconds", - "Keywords": "chatcontrol,cooldownseconds", - "FieldName": "Stratum_cmd_ChatControl_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChatControl.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Chat Control:terminal:20", - "Description": "data/stratum-commands.json -> $.ChatControl.CooldownBypassForStaff", - "Keywords": "chatcontrol,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_ChatControl_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ChatControl.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Staff Broadcast:terminal:20", - "Description": "data/stratum-commands.json -> $.StaffBroadcast.Enabled", - "Keywords": "staffbroadcast,enabled", - "FieldName": "Stratum_cmd_StaffBroadcast_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.StaffBroadcast.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Staff Broadcast:terminal:20", - "Description": "data/stratum-commands.json -> $.StaffBroadcast.Privilege", - "Keywords": "staffbroadcast,privilege", - "FieldName": "Stratum_cmd_StaffBroadcast_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.StaffBroadcast.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Staff Broadcast:terminal:20", - "Description": "data/stratum-commands.json -> $.StaffBroadcast.CooldownSeconds", - "Keywords": "staffbroadcast,cooldownseconds", - "FieldName": "Stratum_cmd_StaffBroadcast_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.StaffBroadcast.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Staff Broadcast:terminal:20", - "Description": "data/stratum-commands.json -> $.StaffBroadcast.CooldownBypassForStaff", - "Keywords": "staffbroadcast,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_StaffBroadcast_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.StaffBroadcast.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Info Commands:terminal:20", - "Description": "data/stratum-commands.json -> $.InfoCommands.Enabled", - "Keywords": "infocommands,enabled", - "FieldName": "Stratum_cmd_InfoCommands_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.InfoCommands.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Info Commands:terminal:20", - "Description": "data/stratum-commands.json -> $.InfoCommands.Privilege", - "Keywords": "infocommands,privilege", - "FieldName": "Stratum_cmd_InfoCommands_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.InfoCommands.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Info Commands:terminal:20", - "Description": "data/stratum-commands.json -> $.InfoCommands.CooldownSeconds", - "Keywords": "infocommands,cooldownseconds", - "FieldName": "Stratum_cmd_InfoCommands_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.InfoCommands.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Info Commands:terminal:20", - "Description": "data/stratum-commands.json -> $.InfoCommands.CooldownBypassForStaff", - "Keywords": "infocommands,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_InfoCommands_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.InfoCommands.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Vanish:terminal:20", - "Description": "data/stratum-commands.json -> $.Vanish.Enabled", - "Keywords": "vanish,enabled", - "FieldName": "Stratum_cmd_Vanish_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Vanish.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Vanish:terminal:20", - "Description": "data/stratum-commands.json -> $.Vanish.Privilege", - "Keywords": "vanish,privilege", - "FieldName": "Stratum_cmd_Vanish_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Vanish.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Vanish:terminal:20", - "Description": "data/stratum-commands.json -> $.Vanish.CooldownSeconds", - "Keywords": "vanish,cooldownseconds", - "FieldName": "Stratum_cmd_Vanish_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Vanish.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Vanish:terminal:20", - "Description": "data/stratum-commands.json -> $.Vanish.CooldownBypassForStaff", - "Keywords": "vanish,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_Vanish_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Vanish.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Pvp:terminal:20", - "Description": "data/stratum-commands.json -> $.Pvp.Enabled", - "Keywords": "pvp,enabled", - "FieldName": "Stratum_cmd_Pvp_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Pvp.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Pvp:terminal:20", - "Description": "data/stratum-commands.json -> $.Pvp.Privilege", - "Keywords": "pvp,privilege", - "FieldName": "Stratum_cmd_Pvp_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Pvp.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Pvp:terminal:20", - "Description": "data/stratum-commands.json -> $.Pvp.CooldownSeconds", - "Keywords": "pvp,cooldownseconds", - "FieldName": "Stratum_cmd_Pvp_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Pvp.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Pvp:terminal:20", - "Description": "data/stratum-commands.json -> $.Pvp.CooldownBypassForStaff", - "Keywords": "pvp,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_Pvp_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Pvp.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Vanish Reminder Interval Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "General:terminal:20", - "Description": "data/stratum-commands.json -> $.VanishReminderIntervalSeconds", - "Keywords": "vanishreminderintervalseconds", - "FieldName": "Stratum_cmd_VanishReminderIntervalSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.VanishReminderIntervalSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "4", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Freeze:terminal:20", - "Description": "data/stratum-commands.json -> $.Freeze.Enabled", - "Keywords": "freeze,enabled", - "FieldName": "Stratum_cmd_Freeze_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Freeze.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Freeze:terminal:20", - "Description": "data/stratum-commands.json -> $.Freeze.Privilege", - "Keywords": "freeze,privilege", - "FieldName": "Stratum_cmd_Freeze_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Freeze.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Freeze:terminal:20", - "Description": "data/stratum-commands.json -> $.Freeze.CooldownSeconds", - "Keywords": "freeze,cooldownseconds", - "FieldName": "Stratum_cmd_Freeze_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Freeze.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Freeze:terminal:20", - "Description": "data/stratum-commands.json -> $.Freeze.CooldownBypassForStaff", - "Keywords": "freeze,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_Freeze_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Freeze.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Revive:terminal:20", - "Description": "data/stratum-commands.json -> $.Revive.Enabled", - "Keywords": "revive,enabled", - "FieldName": "Stratum_cmd_Revive_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Revive.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Revive:terminal:20", - "Description": "data/stratum-commands.json -> $.Revive.Privilege", - "Keywords": "revive,privilege", - "FieldName": "Stratum_cmd_Revive_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Revive.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Revive:terminal:20", - "Description": "data/stratum-commands.json -> $.Revive.CooldownSeconds", - "Keywords": "revive,cooldownseconds", - "FieldName": "Stratum_cmd_Revive_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Revive.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Revive:terminal:20", - "Description": "data/stratum-commands.json -> $.Revive.CooldownBypassForStaff", - "Keywords": "revive,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_Revive_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Revive.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Jail:terminal:20", - "Description": "data/stratum-commands.json -> $.Jail.Enabled", - "Keywords": "jail,enabled", - "FieldName": "Stratum_cmd_Jail_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Jail.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Jail:terminal:20", - "Description": "data/stratum-commands.json -> $.Jail.Privilege", - "Keywords": "jail,privilege", - "FieldName": "Stratum_cmd_Jail_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Jail.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Jail:terminal:20", - "Description": "data/stratum-commands.json -> $.Jail.CooldownSeconds", - "Keywords": "jail,cooldownseconds", - "FieldName": "Stratum_cmd_Jail_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Jail.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Jail:terminal:20", - "Description": "data/stratum-commands.json -> $.Jail.CooldownBypassForStaff", - "Keywords": "jail,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_Jail_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Jail.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Warn:terminal:20", - "Description": "data/stratum-commands.json -> $.Warn.Enabled", - "Keywords": "warn,enabled", - "FieldName": "Stratum_cmd_Warn_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Warn.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Warn:terminal:20", - "Description": "data/stratum-commands.json -> $.Warn.Privilege", - "Keywords": "warn,privilege", - "FieldName": "Stratum_cmd_Warn_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Warn.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Warn:terminal:20", - "Description": "data/stratum-commands.json -> $.Warn.CooldownSeconds", - "Keywords": "warn,cooldownseconds", - "FieldName": "Stratum_cmd_Warn_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Warn.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Warn:terminal:20", - "Description": "data/stratum-commands.json -> $.Warn.CooldownBypassForStaff", - "Keywords": "warn,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_Warn_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Warn.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Mute:terminal:20", - "Description": "data/stratum-commands.json -> $.Mute.Enabled", - "Keywords": "mute,enabled", - "FieldName": "Stratum_cmd_Mute_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Mute.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Mute:terminal:20", - "Description": "data/stratum-commands.json -> $.Mute.Privilege", - "Keywords": "mute,privilege", - "FieldName": "Stratum_cmd_Mute_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Mute.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Mute:terminal:20", - "Description": "data/stratum-commands.json -> $.Mute.CooldownSeconds", - "Keywords": "mute,cooldownseconds", - "FieldName": "Stratum_cmd_Mute_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Mute.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Mute:terminal:20", - "Description": "data/stratum-commands.json -> $.Mute.CooldownBypassForStaff", - "Keywords": "mute,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_Mute_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Mute.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Notes:terminal:20", - "Description": "data/stratum-commands.json -> $.Notes.Enabled", - "Keywords": "notes,enabled", - "FieldName": "Stratum_cmd_Notes_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Notes.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Notes:terminal:20", - "Description": "data/stratum-commands.json -> $.Notes.Privilege", - "Keywords": "notes,privilege", - "FieldName": "Stratum_cmd_Notes_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Notes.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Notes:terminal:20", - "Description": "data/stratum-commands.json -> $.Notes.CooldownSeconds", - "Keywords": "notes,cooldownseconds", - "FieldName": "Stratum_cmd_Notes_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Notes.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Notes:terminal:20", - "Description": "data/stratum-commands.json -> $.Notes.CooldownBypassForStaff", - "Keywords": "notes,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_Notes_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Notes.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Report:terminal:20", - "Description": "data/stratum-commands.json -> $.Report.Enabled", - "Keywords": "report,enabled", - "FieldName": "Stratum_cmd_Report_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Report.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Report:terminal:20", - "Description": "data/stratum-commands.json -> $.Report.Privilege", - "Keywords": "report,privilege", - "FieldName": "Stratum_cmd_Report_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.Report.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Report:terminal:20", - "Description": "data/stratum-commands.json -> $.Report.CooldownSeconds", - "Keywords": "report,cooldownseconds", - "FieldName": "Stratum_cmd_Report_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Report.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Report:terminal:20", - "Description": "data/stratum-commands.json -> $.Report.CooldownBypassForStaff", - "Keywords": "report,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_Report_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Report.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Commands:terminal", - "Subcategory": "Report Manage:terminal:20", - "Description": "data/stratum-commands.json -> $.ReportManage.Enabled", - "Keywords": "reportmanage,enabled", - "FieldName": "Stratum_cmd_ReportManage_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ReportManage.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Privilege", - "Category": "Stratum Commands:terminal", - "Subcategory": "Report Manage:terminal:20", - "Description": "data/stratum-commands.json -> $.ReportManage.Privilege", - "Keywords": "reportmanage,privilege", - "FieldName": "Stratum_cmd_ReportManage_Privilege", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.ReportManage.Privilege", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "Report Manage:terminal:20", - "Description": "data/stratum-commands.json -> $.ReportManage.CooldownSeconds", - "Keywords": "reportmanage,cooldownseconds", - "FieldName": "Stratum_cmd_ReportManage_CooldownSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ReportManage.CooldownSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Cooldown Bypass For Staff", - "Category": "Stratum Commands:terminal", - "Subcategory": "Report Manage:terminal:20", - "Description": "data/stratum-commands.json -> $.ReportManage.CooldownBypassForStaff", - "Keywords": "reportmanage,cooldownbypassforstaff", - "FieldName": "Stratum_cmd_ReportManage_CooldownBypassForStaff", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ReportManage.CooldownBypassForStaff", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Near Default Radius Blocks", - "Category": "Stratum Commands:terminal", - "Subcategory": "General:terminal:20", - "Description": "data/stratum-commands.json -> $.NearDefaultRadiusBlocks", - "Keywords": "neardefaultradiusblocks", - "FieldName": "Stratum_cmd_NearDefaultRadiusBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.NearDefaultRadiusBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "128", - "EnumValues": {} - }, - { - "DisplayName": "Near Max Radius Blocks", - "Category": "Stratum Commands:terminal", - "Subcategory": "General:terminal:20", - "Description": "data/stratum-commands.json -> $.NearMaxRadiusBlocks", - "Keywords": "nearmaxradiusblocks", - "FieldName": "Stratum_cmd_NearMaxRadiusBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.NearMaxRadiusBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "512", - "EnumValues": {} - }, - { - "DisplayName": "Slowmode Max Seconds", - "Category": "Stratum Commands:terminal", - "Subcategory": "General:terminal:20", - "Description": "data/stratum-commands.json -> $.SlowmodeMaxSeconds", - "Keywords": "slowmodemaxseconds", - "FieldName": "Stratum_cmd_SlowmodeMaxSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.SlowmodeMaxSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "3600", - "EnumValues": {} - }, - { - "DisplayName": "Clear Chat Lines", - "Category": "Stratum Commands:terminal", - "Subcategory": "General:terminal:20", - "Description": "data/stratum-commands.json -> $.ClearChatLines", - "Keywords": "clearchatlines", - "FieldName": "Stratum_cmd_ClearChatLines", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ClearChatLines", - "IncludeInCommandLine": false, - "DefaultValue": "80", - "EnumValues": {} - }, - { - "DisplayName": "Set", - "Category": "Stratum Commands:terminal", - "Subcategory": "Jail Settings > Location:terminal:20", - "Description": "data/stratum-commands.json -> $.JailSettings.Location.Set", - "Keywords": "jailsettings,location,set", - "FieldName": "Stratum_cmd_JailSettings_Location_Set", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.JailSettings.Location.Set", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "X", - "Category": "Stratum Commands:terminal", - "Subcategory": "Jail Settings > Location:terminal:20", - "Description": "data/stratum-commands.json -> $.JailSettings.Location.X", - "Keywords": "jailsettings,location,x", - "FieldName": "Stratum_cmd_JailSettings_Location_X", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.JailSettings.Location.X", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Y", - "Category": "Stratum Commands:terminal", - "Subcategory": "Jail Settings > Location:terminal:20", - "Description": "data/stratum-commands.json -> $.JailSettings.Location.Y", - "Keywords": "jailsettings,location,y", - "FieldName": "Stratum_cmd_JailSettings_Location_Y", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.JailSettings.Location.Y", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Z", - "Category": "Stratum Commands:terminal", - "Subcategory": "Jail Settings > Location:terminal:20", - "Description": "data/stratum-commands.json -> $.JailSettings.Location.Z", - "Keywords": "jailsettings,location,z", - "FieldName": "Stratum_cmd_JailSettings_Location_Z", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.JailSettings.Location.Z", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Dimension", - "Category": "Stratum Commands:terminal", - "Subcategory": "Jail Settings > Location:terminal:20", - "Description": "data/stratum-commands.json -> $.JailSettings.Location.Dimension", - "Keywords": "jailsettings,location,dimension", - "FieldName": "Stratum_cmd_JailSettings_Location_Dimension", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.JailSettings.Location.Dimension", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Yaw", - "Category": "Stratum Commands:terminal", - "Subcategory": "Jail Settings > Location:terminal:20", - "Description": "data/stratum-commands.json -> $.JailSettings.Location.Yaw", - "Keywords": "jailsettings,location,yaw", - "FieldName": "Stratum_cmd_JailSettings_Location_Yaw", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.JailSettings.Location.Yaw", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Pitch", - "Category": "Stratum Commands:terminal", - "Subcategory": "Jail Settings > Location:terminal:20", - "Description": "data/stratum-commands.json -> $.JailSettings.Location.Pitch", - "Keywords": "jailsettings,location,pitch", - "FieldName": "Stratum_cmd_JailSettings_Location_Pitch", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.JailSettings.Location.Pitch", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Max Distance Blocks", - "Category": "Stratum Commands:terminal", - "Subcategory": "Jail Settings:terminal:20", - "Description": "data/stratum-commands.json -> $.JailSettings.MaxDistanceBlocks", - "Keywords": "jailsettings,maxdistanceblocks", - "FieldName": "Stratum_cmd_JailSettings_MaxDistanceBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.JailSettings.MaxDistanceBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "6", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Return On Unjail", - "Category": "Stratum Commands:terminal", - "Subcategory": "Jail Settings:terminal:20", - "Description": "data/stratum-commands.json -> $.JailSettings.ReturnOnUnjail", - "Keywords": "jailsettings,returnonunjail", - "FieldName": "Stratum_cmd_JailSettings_ReturnOnUnjail", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.JailSettings.ReturnOnUnjail", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.Enabled", - "Keywords": "chunksending,enabled", - "FieldName": "Stratum_perf_ChunkSending_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Max Chunks Per Server Tick", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.MaxChunksPerServerTick", - "Keywords": "chunksending,maxchunksperservertick", - "FieldName": "Stratum_perf_ChunkSending_MaxChunksPerServerTick", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.MaxChunksPerServerTick", - "IncludeInCommandLine": false, - "DefaultValue": "384", - "EnumValues": {} - }, - { - "DisplayName": "Max Chunks Per Client Tick", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.MaxChunksPerClientTick", - "Keywords": "chunksending,maxchunksperclienttick", - "FieldName": "Stratum_perf_ChunkSending_MaxChunksPerClientTick", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.MaxChunksPerClientTick", - "IncludeInCommandLine": false, - "DefaultValue": "64", - "EnumValues": {} - }, - { - "DisplayName": "Include Local Clients", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.IncludeLocalClients", - "Keywords": "chunksending,includelocalclients", - "FieldName": "Stratum_perf_ChunkSending_IncludeLocalClients", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.IncludeLocalClients", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Adaptive Under Overload", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.AdaptiveUnderOverload", - "Keywords": "chunksending,adaptiveunderoverload", - "FieldName": "Stratum_perf_ChunkSending_AdaptiveUnderOverload", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.AdaptiveUnderOverload", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Overload Tick Ms", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.OverloadTickMs", - "Keywords": "chunksending,overloadtickms", - "FieldName": "Stratum_perf_ChunkSending_OverloadTickMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.OverloadTickMs", - "IncludeInCommandLine": false, - "DefaultValue": "45", - "EnumValues": {} - }, - { - "DisplayName": "Overload Scale", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.OverloadScale", - "Keywords": "chunksending,overloadscale", - "FieldName": "Stratum_perf_ChunkSending_OverloadScale", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.OverloadScale", - "IncludeInCommandLine": false, - "DefaultValue": "0.5", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Overload Floor Server Tick", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.OverloadFloorServerTick", - "Keywords": "chunksending,overloadfloorservertick", - "FieldName": "Stratum_perf_ChunkSending_OverloadFloorServerTick", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.OverloadFloorServerTick", - "IncludeInCommandLine": false, - "DefaultValue": "64", - "EnumValues": {} - }, - { - "DisplayName": "Overload Floor Client Tick", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.OverloadFloorClientTick", - "Keywords": "chunksending,overloadfloorclienttick", - "FieldName": "Stratum_perf_ChunkSending_OverloadFloorClientTick", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.OverloadFloorClientTick", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {} - }, - { - "DisplayName": "Fair Scheduling Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.FairSchedulingEnabled", - "Keywords": "chunksending,fairschedulingenabled", - "FieldName": "Stratum_perf_ChunkSending_FairSchedulingEnabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.FairSchedulingEnabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Fair Window Milliseconds", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.FairWindowMilliseconds", - "Keywords": "chunksending,fairwindowmilliseconds", - "FieldName": "Stratum_perf_ChunkSending_FairWindowMilliseconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.FairWindowMilliseconds", - "IncludeInCommandLine": false, - "DefaultValue": "5000", - "EnumValues": {} - }, - { - "DisplayName": "Near Ring Radius Chunks", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.NearRingRadiusChunks", - "Keywords": "chunksending,nearringradiuschunks", - "FieldName": "Stratum_perf_ChunkSending_NearRingRadiusChunks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.NearRingRadiusChunks", - "IncludeInCommandLine": false, - "DefaultValue": "2", - "EnumValues": {} - }, - { - "DisplayName": "Outbound Pressure Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.OutboundPressureEnabled", - "Keywords": "chunksending,outboundpressureenabled", - "FieldName": "Stratum_perf_ChunkSending_OutboundPressureEnabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.OutboundPressureEnabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Outbound Pressure Pending Sends Soft Limit", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.OutboundPressurePendingSendsSoftLimit", - "Keywords": "chunksending,outboundpressurependingsendssoftlimit", - "FieldName": "Stratum_perf_ChunkSending_OutboundPressurePendingSendsSoftLimit", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.OutboundPressurePendingSendsSoftLimit", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {} - }, - { - "DisplayName": "Outbound Pressure Pending Sends Hard Limit", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.OutboundPressurePendingSendsHardLimit", - "Keywords": "chunksending,outboundpressurependingsendshardlimit", - "FieldName": "Stratum_perf_ChunkSending_OutboundPressurePendingSendsHardLimit", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.OutboundPressurePendingSendsHardLimit", - "IncludeInCommandLine": false, - "DefaultValue": "32", - "EnumValues": {} - }, - { - "DisplayName": "Outbound Pressure Pending Bytes Soft Limit", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.OutboundPressurePendingBytesSoftLimit", - "Keywords": "chunksending,outboundpressurependingbytessoftlimit", - "FieldName": "Stratum_perf_ChunkSending_OutboundPressurePendingBytesSoftLimit", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.OutboundPressurePendingBytesSoftLimit", - "IncludeInCommandLine": false, - "DefaultValue": "262144", - "EnumValues": {} - }, - { - "DisplayName": "Outbound Pressure Pending Bytes Hard Limit", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.OutboundPressurePendingBytesHardLimit", - "Keywords": "chunksending,outboundpressurependingbyteshardlimit", - "FieldName": "Stratum_perf_ChunkSending_OutboundPressurePendingBytesHardLimit", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.OutboundPressurePendingBytesHardLimit", - "IncludeInCommandLine": false, - "DefaultValue": "1048576", - "EnumValues": {} - }, - { - "DisplayName": "Outbound Pressure Scale", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.OutboundPressureScale", - "Keywords": "chunksending,outboundpressurescale", - "FieldName": "Stratum_perf_ChunkSending_OutboundPressureScale", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.OutboundPressureScale", - "IncludeInCommandLine": false, - "DefaultValue": "0.5", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Outbound Pressure Minimum Client Budget", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Sending:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkSending.OutboundPressureMinimumClientBudget", - "Keywords": "chunksending,outboundpressureminimumclientbudget", - "FieldName": "Stratum_perf_ChunkSending_OutboundPressureMinimumClientBudget", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkSending.OutboundPressureMinimumClientBudget", - "IncludeInCommandLine": false, - "DefaultValue": "2", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Generation:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkGeneration.Enabled", - "Keywords": "chunkgeneration,enabled", - "FieldName": "Stratum_perf_ChunkGeneration_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkGeneration.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Max Column Requests Per Server Tick", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Generation:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkGeneration.MaxColumnRequestsPerServerTick", - "Keywords": "chunkgeneration,maxcolumnrequestsperservertick", - "FieldName": "Stratum_perf_ChunkGeneration_MaxColumnRequestsPerServerTick", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkGeneration.MaxColumnRequestsPerServerTick", - "IncludeInCommandLine": false, - "DefaultValue": "32", - "EnumValues": {} - }, - { - "DisplayName": "Max Column Requests Per Client Tick", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Generation:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkGeneration.MaxColumnRequestsPerClientTick", - "Keywords": "chunkgeneration,maxcolumnrequestsperclienttick", - "FieldName": "Stratum_perf_ChunkGeneration_MaxColumnRequestsPerClientTick", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkGeneration.MaxColumnRequestsPerClientTick", - "IncludeInCommandLine": false, - "DefaultValue": "4", - "EnumValues": {} - }, - { - "DisplayName": "Include Local Clients", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Generation:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkGeneration.IncludeLocalClients", - "Keywords": "chunkgeneration,includelocalclients", - "FieldName": "Stratum_perf_ChunkGeneration_IncludeLocalClients", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkGeneration.IncludeLocalClients", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Adaptive Under Overload", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Generation:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkGeneration.AdaptiveUnderOverload", - "Keywords": "chunkgeneration,adaptiveunderoverload", - "FieldName": "Stratum_perf_ChunkGeneration_AdaptiveUnderOverload", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkGeneration.AdaptiveUnderOverload", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Overload Tick Ms", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Generation:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkGeneration.OverloadTickMs", - "Keywords": "chunkgeneration,overloadtickms", - "FieldName": "Stratum_perf_ChunkGeneration_OverloadTickMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkGeneration.OverloadTickMs", - "IncludeInCommandLine": false, - "DefaultValue": "45", - "EnumValues": {} - }, - { - "DisplayName": "Overload Scale", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Generation:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkGeneration.OverloadScale", - "Keywords": "chunkgeneration,overloadscale", - "FieldName": "Stratum_perf_ChunkGeneration_OverloadScale", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkGeneration.OverloadScale", - "IncludeInCommandLine": false, - "DefaultValue": "0.5", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Overload Floor Server Tick", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Generation:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkGeneration.OverloadFloorServerTick", - "Keywords": "chunkgeneration,overloadfloorservertick", - "FieldName": "Stratum_perf_ChunkGeneration_OverloadFloorServerTick", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkGeneration.OverloadFloorServerTick", - "IncludeInCommandLine": false, - "DefaultValue": "4", - "EnumValues": {} - }, - { - "DisplayName": "Overload Floor Client Tick", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Generation:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkGeneration.OverloadFloorClientTick", - "Keywords": "chunkgeneration,overloadfloorclienttick", - "FieldName": "Stratum_perf_ChunkGeneration_OverloadFloorClientTick", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkGeneration.OverloadFloorClientTick", - "IncludeInCommandLine": false, - "DefaultValue": "1", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Request Management:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.Enabled", - "Keywords": "chunkrequestmanagement,enabled", - "FieldName": "Stratum_perf_ChunkRequestManagement_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkRequestManagement.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Cancel Stale Pending Requests", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Request Management:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.CancelStalePendingRequests", - "Keywords": "chunkrequestmanagement,cancelstalependingrequests", - "FieldName": "Stratum_perf_ChunkRequestManagement_CancelStalePendingRequests", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkRequestManagement.CancelStalePendingRequests", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Minimum Pending Age Seconds", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Request Management:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.MinimumPendingAgeSeconds", - "Keywords": "chunkrequestmanagement,minimumpendingageseconds", - "FieldName": "Stratum_perf_ChunkRequestManagement_MinimumPendingAgeSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkRequestManagement.MinimumPendingAgeSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "3", - "EnumValues": {} - }, - { - "DisplayName": "Max Distance Beyond View Chunks", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Request Management:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.MaxDistanceBeyondViewChunks", - "Keywords": "chunkrequestmanagement,maxdistancebeyondviewchunks", - "FieldName": "Stratum_perf_ChunkRequestManagement_MaxDistanceBeyondViewChunks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkRequestManagement.MaxDistanceBeyondViewChunks", - "IncludeInCommandLine": false, - "DefaultValue": "2", - "EnumValues": {} - }, - { - "DisplayName": "Cleanup Interval Milliseconds", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Request Management:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.CleanupIntervalMilliseconds", - "Keywords": "chunkrequestmanagement,cleanupintervalmilliseconds", - "FieldName": "Stratum_perf_ChunkRequestManagement_CleanupIntervalMilliseconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkRequestManagement.CleanupIntervalMilliseconds", - "IncludeInCommandLine": false, - "DefaultValue": "1000", - "EnumValues": {} - }, - { - "DisplayName": "Max Tracked Requests Per Cleanup", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Request Management:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.MaxTrackedRequestsPerCleanup", - "Keywords": "chunkrequestmanagement,maxtrackedrequestspercleanup", - "FieldName": "Stratum_perf_ChunkRequestManagement_MaxTrackedRequestsPerCleanup", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkRequestManagement.MaxTrackedRequestsPerCleanup", - "IncludeInCommandLine": false, - "DefaultValue": "512", - "EnumValues": {} - }, - { - "DisplayName": "Max Cancelled Requests Per Cleanup", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Request Management:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.MaxCancelledRequestsPerCleanup", - "Keywords": "chunkrequestmanagement,maxcancelledrequestspercleanup", - "FieldName": "Stratum_perf_ChunkRequestManagement_MaxCancelledRequestsPerCleanup", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkRequestManagement.MaxCancelledRequestsPerCleanup", - "IncludeInCommandLine": false, - "DefaultValue": "128", - "EnumValues": {} - }, - { - "DisplayName": "Prioritize Moving Direction", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Request Management:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.PrioritizeMovingDirection", - "Keywords": "chunkrequestmanagement,prioritizemovingdirection", - "FieldName": "Stratum_perf_ChunkRequestManagement_PrioritizeMovingDirection", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkRequestManagement.PrioritizeMovingDirection", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Forward Prediction Blocks", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Request Management:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.ForwardPredictionBlocks", - "Keywords": "chunkrequestmanagement,forwardpredictionblocks", - "FieldName": "Stratum_perf_ChunkRequestManagement_ForwardPredictionBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkRequestManagement.ForwardPredictionBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "48", - "EnumValues": {} - }, - { - "DisplayName": "Minimum Movement Speed", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Request Management:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkRequestManagement.MinimumMovementSpeed", - "Keywords": "chunkrequestmanagement,minimummovementspeed", - "FieldName": "Stratum_perf_ChunkRequestManagement_MinimumMovementSpeed", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkRequestManagement.MinimumMovementSpeed", - "IncludeInCommandLine": false, - "DefaultValue": "0.05", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Pregen:speed:30", - "Description": "data/stratum-performance.json -> $.Pregen.Enabled", - "Keywords": "pregen,enabled", - "FieldName": "Stratum_perf_Pregen_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Pregen.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Max Columns Per Second", - "Category": "Stratum Performance:speed", - "Subcategory": "Pregen:speed:30", - "Description": "data/stratum-performance.json -> $.Pregen.MaxColumnsPerSecond", - "Keywords": "pregen,maxcolumnspersecond", - "FieldName": "Stratum_perf_Pregen_MaxColumnsPerSecond", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Pregen.MaxColumnsPerSecond", - "IncludeInCommandLine": false, - "DefaultValue": "500", - "EnumValues": {} - }, - { - "DisplayName": "Max Scans Per Second", - "Category": "Stratum Performance:speed", - "Subcategory": "Pregen:speed:30", - "Description": "data/stratum-performance.json -> $.Pregen.MaxScansPerSecond", - "Keywords": "pregen,maxscanspersecond", - "FieldName": "Stratum_perf_Pregen_MaxScansPerSecond", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Pregen.MaxScansPerSecond", - "IncludeInCommandLine": false, - "DefaultValue": "4096", - "EnumValues": {} - }, - { - "DisplayName": "Max Pending Column Queue", - "Category": "Stratum Performance:speed", - "Subcategory": "Pregen:speed:30", - "Description": "data/stratum-performance.json -> $.Pregen.MaxPendingColumnQueue", - "Keywords": "pregen,maxpendingcolumnqueue", - "FieldName": "Stratum_perf_Pregen_MaxPendingColumnQueue", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Pregen.MaxPendingColumnQueue", - "IncludeInCommandLine": false, - "DefaultValue": "500", - "EnumValues": {} - }, - { - "DisplayName": "Max Worker Column Queue", - "Category": "Stratum Performance:speed", - "Subcategory": "Pregen:speed:30", - "Description": "data/stratum-performance.json -> $.Pregen.MaxWorkerColumnQueue", - "Keywords": "pregen,maxworkercolumnqueue", - "FieldName": "Stratum_perf_Pregen_MaxWorkerColumnQueue", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Pregen.MaxWorkerColumnQueue", - "IncludeInCommandLine": false, - "DefaultValue": "1000", - "EnumValues": {} - }, - { - "DisplayName": "Max Loaded Chunk Columns", - "Category": "Stratum Performance:speed", - "Subcategory": "Pregen:speed:30", - "Description": "data/stratum-performance.json -> $.Pregen.MaxLoadedChunkColumns", - "Keywords": "pregen,maxloadedchunkcolumns", - "FieldName": "Stratum_perf_Pregen_MaxLoadedChunkColumns", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Pregen.MaxLoadedChunkColumns", - "IncludeInCommandLine": false, - "DefaultValue": "4096", - "EnumValues": {} - }, - { - "DisplayName": "Max Radius Chunks", - "Category": "Stratum Performance:speed", - "Subcategory": "Pregen:speed:30", - "Description": "data/stratum-performance.json -> $.Pregen.MaxRadiusChunks", - "Keywords": "pregen,maxradiuschunks", - "FieldName": "Stratum_perf_Pregen_MaxRadiusChunks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Pregen.MaxRadiusChunks", - "IncludeInCommandLine": false, - "DefaultValue": "1000", - "EnumValues": {} - }, - { - "DisplayName": "Max Area Columns", - "Category": "Stratum Performance:speed", - "Subcategory": "Pregen:speed:30", - "Description": "data/stratum-performance.json -> $.Pregen.MaxAreaColumns", - "Keywords": "pregen,maxareacolumns", - "FieldName": "Stratum_perf_Pregen_MaxAreaColumns", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Pregen.MaxAreaColumns", - "IncludeInCommandLine": false, - "DefaultValue": "1000000", - "EnumValues": {} - }, - { - "DisplayName": "Pause When Players Online", - "Category": "Stratum Performance:speed", - "Subcategory": "Pregen:speed:30", - "Description": "data/stratum-performance.json -> $.Pregen.PauseWhenPlayersOnline", - "Keywords": "pregen,pausewhenplayersonline", - "FieldName": "Stratum_perf_Pregen_PauseWhenPlayersOnline", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Pregen.PauseWhenPlayersOnline", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Pause Below Tps", - "Category": "Stratum Performance:speed", - "Subcategory": "Pregen:speed:30", - "Description": "data/stratum-performance.json -> $.Pregen.PauseBelowTps", - "Keywords": "pregen,pausebelowtps", - "FieldName": "Stratum_perf_Pregen_PauseBelowTps", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Pregen.PauseBelowTps", - "IncludeInCommandLine": false, - "DefaultValue": "15.0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Progress Log Interval Seconds", - "Category": "Stratum Performance:speed", - "Subcategory": "Pregen:speed:30", - "Description": "data/stratum-performance.json -> $.Pregen.ProgressLogIntervalSeconds", - "Keywords": "pregen,progresslogintervalseconds", - "FieldName": "Stratum_perf_Pregen_ProgressLogIntervalSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Pregen.ProgressLogIntervalSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "60", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Simulation Distance:speed:30", - "Description": "data/stratum-performance.json -> $.SimulationDistance.Enabled", - "Keywords": "simulationdistance,enabled", - "FieldName": "Stratum_perf_SimulationDistance_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.SimulationDistance.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Limit Random Ticks", - "Category": "Stratum Performance:speed", - "Subcategory": "Simulation Distance:speed:30", - "Description": "data/stratum-performance.json -> $.SimulationDistance.LimitRandomTicks", - "Keywords": "simulationdistance,limitrandomticks", - "FieldName": "Stratum_perf_SimulationDistance_LimitRandomTicks", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.SimulationDistance.LimitRandomTicks", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Random Tick Distance Blocks", - "Category": "Stratum Performance:speed", - "Subcategory": "Simulation Distance:speed:30", - "Description": "data/stratum-performance.json -> $.SimulationDistance.RandomTickDistanceBlocks", - "Keywords": "simulationdistance,randomtickdistanceblocks", - "FieldName": "Stratum_perf_SimulationDistance_RandomTickDistanceBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.SimulationDistance.RandomTickDistanceBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "96", - "EnumValues": {} - }, - { - "DisplayName": "Limit Block Game Tick Listeners", - "Category": "Stratum Performance:speed", - "Subcategory": "Simulation Distance:speed:30", - "Description": "data/stratum-performance.json -> $.SimulationDistance.LimitBlockGameTickListeners", - "Keywords": "simulationdistance,limitblockgameticklisteners", - "FieldName": "Stratum_perf_SimulationDistance_LimitBlockGameTickListeners", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.SimulationDistance.LimitBlockGameTickListeners", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Block Game Tick Listener Distance Blocks", - "Category": "Stratum Performance:speed", - "Subcategory": "Simulation Distance:speed:30", - "Description": "data/stratum-performance.json -> $.SimulationDistance.BlockGameTickListenerDistanceBlocks", - "Keywords": "simulationdistance,blockgameticklistenerdistanceblocks", - "FieldName": "Stratum_perf_SimulationDistance_BlockGameTickListenerDistanceBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.SimulationDistance.BlockGameTickListenerDistanceBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "128", - "EnumValues": {} - }, - { - "DisplayName": "Tick Force Loaded Block Listeners", - "Category": "Stratum Performance:speed", - "Subcategory": "Simulation Distance:speed:30", - "Description": "data/stratum-performance.json -> $.SimulationDistance.TickForceLoadedBlockListeners", - "Keywords": "simulationdistance,tickforceloadedblocklisteners", - "FieldName": "Stratum_perf_SimulationDistance_TickForceLoadedBlockListeners", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.SimulationDistance.TickForceLoadedBlockListeners", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Physics:speed:30", - "Description": "data/stratum-performance.json -> $.Physics.Enabled", - "Keywords": "physics,enabled", - "FieldName": "Stratum_perf_Physics_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Physics.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Max Catch Up Ticks Per Server Tick", - "Category": "Stratum Performance:speed", - "Subcategory": "Physics:speed:30", - "Description": "Max physics steps consolidated into a single server tick (catchup). Vanilla used 3, which works fine on a CPU-bound server where every tick is already busy. With Stratum's EAR freeing headroom, the server accumulates spare time during idle ticks and would otherwise dump 2-3 physics steps on the next tick (visible as 15-30ms spikes in an otherwise 4ms average). (data/stratum-performance.json -> $.Physics.MaxCatchUpTicksPerServerTick)", - "Keywords": "physics,maxcatchupticksperservertick", - "FieldName": "Stratum_perf_Physics_MaxCatchUpTicksPerServerTick", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Physics.MaxCatchUpTicksPerServerTick", - "IncludeInCommandLine": false, - "DefaultValue": "2", - "EnumValues": {} - }, - { - "DisplayName": "Overloaded Max Catch Up Ticks Per Server Tick", - "Category": "Stratum Performance:speed", - "Subcategory": "Physics:speed:30", - "Description": "data/stratum-performance.json -> $.Physics.OverloadedMaxCatchUpTicksPerServerTick", - "Keywords": "physics,overloadedmaxcatchupticksperservertick", - "FieldName": "Stratum_perf_Physics_OverloadedMaxCatchUpTicksPerServerTick", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Physics.OverloadedMaxCatchUpTicksPerServerTick", - "IncludeInCommandLine": false, - "DefaultValue": "1", - "EnumValues": {} - }, - { - "DisplayName": "Minimum State Update Interval Ms", - "Category": "Stratum Performance:speed", - "Subcategory": "Physics:speed:30", - "Description": "data/stratum-performance.json -> $.Physics.MinimumStateUpdateIntervalMs", - "Keywords": "physics,minimumstateupdateintervalms", - "FieldName": "Stratum_perf_Physics_MinimumStateUpdateIntervalMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Physics.MinimumStateUpdateIntervalMs", - "IncludeInCommandLine": false, - "DefaultValue": "500", - "EnumValues": {} - }, - { - "DisplayName": "Overloaded State Update Interval Ms", - "Category": "Stratum Performance:speed", - "Subcategory": "Physics:speed:30", - "Description": "data/stratum-performance.json -> $.Physics.OverloadedStateUpdateIntervalMs", - "Keywords": "physics,overloadedstateupdateintervalms", - "FieldName": "Stratum_perf_Physics_OverloadedStateUpdateIntervalMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Physics.OverloadedStateUpdateIntervalMs", - "IncludeInCommandLine": false, - "DefaultValue": "1500", - "EnumValues": {} - }, - { - "DisplayName": "Overloaded Tick Threshold Ms", - "Category": "Stratum Performance:speed", - "Subcategory": "Physics:speed:30", - "Description": "data/stratum-performance.json -> $.Physics.OverloadedTickThresholdMs", - "Keywords": "physics,overloadedtickthresholdms", - "FieldName": "Stratum_perf_Physics_OverloadedTickThresholdMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Physics.OverloadedTickThresholdMs", - "IncludeInCommandLine": false, - "DefaultValue": "60", - "EnumValues": {} - }, - { - "DisplayName": "Parallel Threshold", - "Category": "Stratum Performance:speed", - "Subcategory": "Physics:speed:30", - "Description": "Tickables count threshold to switch from single-thread to parallel physics (vanilla = 800). Lowering this makes parallel physics kick in earlier on busy servers. 32 means: as soon as there are more than ~4 tickables per available physics thread, run in parallel. (data/stratum-performance.json -> $.Physics.ParallelThreshold)", - "Keywords": "physics,parallelthreshold", - "FieldName": "Stratum_perf_Physics_ParallelThreshold", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Physics.ParallelThreshold", - "IncludeInCommandLine": false, - "DefaultValue": "32", - "EnumValues": {} - }, - { - "DisplayName": "Max Threads Override", - "Category": "Stratum Performance:speed", - "Subcategory": "Physics:speed:30", - "Description": "Override for the MagicNum.MaxPhysicsThreads ceiling. 0 = use vanilla MagicNum value. Effective threads are still clamped to [1, 8] internally. (data/stratum-performance.json -> $.Physics.MaxThreadsOverride)", - "Keywords": "physics,maxthreadsoverride", - "FieldName": "Stratum_perf_Physics_MaxThreadsOverride", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Physics.MaxThreadsOverride", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Even Thread Partition", - "Category": "Stratum Performance:speed", - "Subcategory": "Physics:speed:30", - "Description": "When true, evenly split tickables across all physics threads instead of vanilla's \"thread 1 gets the first 480 + a share\" partition (which overloads thread 1). (data/stratum-performance.json -> $.Physics.EvenThreadPartition)", - "Keywords": "physics,eventhreadpartition", - "FieldName": "Stratum_perf_Physics_EvenThreadPartition", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Physics.EvenThreadPartition", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Activation Range Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Physics:speed:30", - "Description": "Stratum: Paper-style Entity Activation Range for PhysicsManager. Far-tracked entities (IsTracked == 1, >50 blocks from any player) tick threadsafe behaviors and OnPhysicsTick at reduced frequency, interleaved deterministically by EntityId so the cost spreads evenly across physics steps. (data/stratum-performance.json -> $.Physics.ActivationRangeEnabled)", - "Keywords": "physics,activationrangeenabled", - "FieldName": "Stratum_perf_Physics_ActivationRangeEnabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Physics.ActivationRangeEnabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Far Tracked Tick Stride", - "Category": "Stratum Performance:speed", - "Subcategory": "Physics:speed:30", - "Description": "Frame stride for entities in the MID band (NearActivationRadiusBlocks .. MidActivationRadiusBlocks). 2 = half-rate (~15Hz instead of 30Hz). Was the old \"far-tracked\" stride when EAR keyed off the binary IsTracked field; now drives the configurable distance band. (data/stratum-performance.json -> $.Physics.FarTrackedTickStride)", - "Keywords": "physics,fartrackedtickstride", - "FieldName": "Stratum_perf_Physics_FarTrackedTickStride", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Physics.FarTrackedTickStride", - "IncludeInCommandLine": false, - "DefaultValue": "2", - "EnumValues": {} - }, - { - "DisplayName": "Untracked Behavior Tick Stride", - "Category": "Stratum Performance:speed", - "Subcategory": "Physics:speed:30", - "Description": "Frame stride for OnGameTick behaviors of untracked entities (IsTracked == 0). These entities are skipped for OnPhysicsTick already, but vanilla still runs all threadsafe behaviors every physics step. 4 = quarter-rate. 1 disables throttling. (data/stratum-performance.json -> $.Physics.UntrackedBehaviorTickStride)", - "Keywords": "physics,untrackedbehaviortickstride", - "FieldName": "Stratum_perf_Physics_UntrackedBehaviorTickStride", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Physics.UntrackedBehaviorTickStride", - "IncludeInCommandLine": false, - "DefaultValue": "4", - "EnumValues": {} - }, - { - "DisplayName": "Near Activation Radius Blocks", - "Category": "Stratum Performance:speed", - "Subcategory": "Physics:speed:30", - "Description": "Distance bands for EAR (Paper-style activation range). Uses Entity.NearestPlayerDistance directly instead of the binary IsTracked field, so EAR provides benefit even on solo/low-pop servers where vanilla's hardcoded 50-block IsTracked boundary engulfs all entities. (data/stratum-performance.json -> $.Physics.NearActivationRadiusBlocks)", - "Keywords": "physics,nearactivationradiusblocks", - "FieldName": "Stratum_perf_Physics_NearActivationRadiusBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Physics.NearActivationRadiusBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "24", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Mid Activation Radius Blocks", - "Category": "Stratum Performance:speed", - "Subcategory": "Physics:speed:30", - "Description": "data/stratum-performance.json -> $.Physics.MidActivationRadiusBlocks", - "Keywords": "physics,midactivationradiusblocks", - "FieldName": "Stratum_perf_Physics_MidActivationRadiusBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Physics.MidActivationRadiusBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "60", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Far Band Tick Stride", - "Category": "Stratum Performance:speed", - "Subcategory": "Physics:speed:30", - "Description": "Stride for entities beyond MidActivationRadiusBlocks but still tracked (IsTracked > 0). (data/stratum-performance.json -> $.Physics.FarBandTickStride)", - "Keywords": "physics,farbandtickstride", - "FieldName": "Stratum_perf_Physics_FarBandTickStride", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Physics.FarBandTickStride", - "IncludeInCommandLine": false, - "DefaultValue": "3", - "EnumValues": {} - }, - { - "DisplayName": "Max Activations Per Tick", - "Category": "Stratum Performance:speed", - "Subcategory": "Physics:speed:30", - "Description": "Max entities to dequeue from the toAdd queue per tick. Prevents spikes when multiple chunks load simultaneously and dump 50-100 new physics tickables in one frame. Deferred entities stay in the queue and drain on subsequent ticks. 0 = no limit. (data/stratum-performance.json -> $.Physics.MaxActivationsPerTick)", - "Keywords": "physics,maxactivationspertick", - "FieldName": "Stratum_perf_Physics_MaxActivationsPerTick", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Physics.MaxActivationsPerTick", - "IncludeInCommandLine": false, - "DefaultValue": "50", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "data/stratum-performance.json -> $.EntityTicking.Enabled", - "Keywords": "entityticking,enabled", - "FieldName": "Stratum_perf_EntityTicking_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Near Distance Blocks", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "Near zone: entities within this distance of any player tick every server tick. (data/stratum-performance.json -> $.EntityTicking.NearDistanceBlocks)", - "Keywords": "entityticking,neardistanceblocks", - "FieldName": "Stratum_perf_EntityTicking_NearDistanceBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.NearDistanceBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "32", - "EnumValues": {} - }, - { - "DisplayName": "Mid Distance Blocks", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "Mid zone: entities within this distance tick every Nth tick. (data/stratum-performance.json -> $.EntityTicking.MidDistanceBlocks)", - "Keywords": "entityticking,middistanceblocks", - "FieldName": "Stratum_perf_EntityTicking_MidDistanceBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.MidDistanceBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "64", - "EnumValues": {} - }, - { - "DisplayName": "Mid Tick Interval", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "data/stratum-performance.json -> $.EntityTicking.MidTickInterval", - "Keywords": "entityticking,midtickinterval", - "FieldName": "Stratum_perf_EntityTicking_MidTickInterval", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.MidTickInterval", - "IncludeInCommandLine": false, - "DefaultValue": "2", - "EnumValues": {} - }, - { - "DisplayName": "Far Entity Distance Blocks", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "Far zone: entities within this distance tick every Nth tick. (data/stratum-performance.json -> $.EntityTicking.FarEntityDistanceBlocks)", - "Keywords": "entityticking,farentitydistanceblocks", - "FieldName": "Stratum_perf_EntityTicking_FarEntityDistanceBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.FarEntityDistanceBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "96", - "EnumValues": {} - }, - { - "DisplayName": "Far Entity Tick Interval", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "data/stratum-performance.json -> $.EntityTicking.FarEntityTickInterval", - "Keywords": "entityticking,farentitytickinterval", - "FieldName": "Stratum_perf_EntityTicking_FarEntityTickInterval", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.FarEntityTickInterval", - "IncludeInCommandLine": false, - "DefaultValue": "5", - "EnumValues": {} - }, - { - "DisplayName": "Very Far Tick Interval", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "Very-far zone: entities beyond Far tick every Nth tick. 1 = same as no throttle. (data/stratum-performance.json -> $.EntityTicking.VeryFarTickInterval)", - "Keywords": "entityticking,veryfartickinterval", - "FieldName": "Stratum_perf_EntityTicking_VeryFarTickInterval", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.VeryFarTickInterval", - "IncludeInCommandLine": false, - "DefaultValue": "10", - "EnumValues": {} - }, - { - "DisplayName": "Throttle Creatures", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "data/stratum-performance.json -> $.EntityTicking.ThrottleCreatures", - "Keywords": "entityticking,throttlecreatures", - "FieldName": "Stratum_perf_EntityTicking_ThrottleCreatures", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.ThrottleCreatures", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Throttle Inanimate", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "data/stratum-performance.json -> $.EntityTicking.ThrottleInanimate", - "Keywords": "entityticking,throttleinanimate", - "FieldName": "Stratum_perf_EntityTicking_ThrottleInanimate", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.ThrottleInanimate", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Skip Moving Entities", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "data/stratum-performance.json -> $.EntityTicking.SkipMovingEntities", - "Keywords": "entityticking,skipmovingentities", - "FieldName": "Stratum_perf_EntityTicking_SkipMovingEntities", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.SkipMovingEntities", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Moving Entity Speed Threshold", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "data/stratum-performance.json -> $.EntityTicking.MovingEntitySpeedThreshold", - "Keywords": "entityticking,movingentityspeedthreshold", - "FieldName": "Stratum_perf_EntityTicking_MovingEntitySpeedThreshold", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.MovingEntitySpeedThreshold", - "IncludeInCommandLine": false, - "DefaultValue": "0.01", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Max Creature Ticks Per Tick", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "Hard cap on creature entities ticked per server tick (round-robin fairness via accumulated dt). 0 = unlimited. Recommended ~ (target tick ms) * (ticks-per-ms creature budget). (data/stratum-performance.json -> $.EntityTicking.MaxCreatureTicksPerTick)", - "Keywords": "entityticking,maxcreaturetickspertick", - "FieldName": "Stratum_perf_EntityTicking_MaxCreatureTicksPerTick", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.MaxCreatureTicksPerTick", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Ambient Fauna Tier Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "Paper-style ambient fauna tier. Entities whose code path matches one of these prefixes get an extra stride multiplier on top of the distance-band tickInterval. Ambient creatures (fish, butterflies, bees, hens etc.) are background mood and don't need 30Hz AI even when a player is nearby. Lazy-resolved per-entity and cached. (data/stratum-performance.json -> $.EntityTicking.AmbientFaunaTierEnabled)", - "Keywords": "entityticking,ambientfaunatierenabled", - "FieldName": "Stratum_perf_EntityTicking_AmbientFaunaTierEnabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.AmbientFaunaTierEnabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Ambient Fauna Tick Multiplier", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "data/stratum-performance.json -> $.EntityTicking.AmbientFaunaTickMultiplier", - "Keywords": "entityticking,ambientfaunatickmultiplier", - "FieldName": "Stratum_perf_EntityTicking_AmbientFaunaTickMultiplier", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.AmbientFaunaTickMultiplier", - "IncludeInCommandLine": false, - "DefaultValue": "2", - "EnumValues": {} - }, - { - "DisplayName": "Hard Despawn Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "Paper-style hard despawn: creatures that have been beyond HardDespawnDistanceBlocks from every player for HardDespawnGracePeriodSeconds get unloaded. Off by default. Enable only on long-running worlds where stray mobs accumulate in old chunks. (data/stratum-performance.json -> $.EntityTicking.HardDespawnEnabled)", - "Keywords": "entityticking,harddespawnenabled", - "FieldName": "Stratum_perf_EntityTicking_HardDespawnEnabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.HardDespawnEnabled", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Hard Despawn Distance Blocks", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "data/stratum-performance.json -> $.EntityTicking.HardDespawnDistanceBlocks", - "Keywords": "entityticking,harddespawndistanceblocks", - "FieldName": "Stratum_perf_EntityTicking_HardDespawnDistanceBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.HardDespawnDistanceBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "128", - "EnumValues": {} - }, - { - "DisplayName": "Hard Despawn Grace Period Seconds", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "data/stratum-performance.json -> $.EntityTicking.HardDespawnGracePeriodSeconds", - "Keywords": "entityticking,harddespawngraceperiodseconds", - "FieldName": "Stratum_perf_EntityTicking_HardDespawnGracePeriodSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.HardDespawnGracePeriodSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "30", - "EnumValues": {} - }, - { - "DisplayName": "Hard Despawn Exempt If Named", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "Skip entities whose nametag attribute has been set (Name Tag item, custom-named mobs). (data/stratum-performance.json -> $.EntityTicking.HardDespawnExemptIfNamed)", - "Keywords": "entityticking,harddespawnexemptifnamed", - "FieldName": "Stratum_perf_EntityTicking_HardDespawnExemptIfNamed", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.HardDespawnExemptIfNamed", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Entity Caps Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "Stratum per-chunk-column entity caps. Periodically scans loaded entities and culls the oldest excess in any column that exceeds the cap. Creatures honor the same exempt prefixes and named-entity rule as hard despawn so livestock & tames aren't culled. Item entities (ground drops) ignore those exemptions; uncollected loot is fair game. (data/stratum-performance.json -> $.EntityTicking.EntityCapsEnabled)", - "Keywords": "entityticking,entitycapsenabled", - "FieldName": "Stratum_perf_EntityTicking_EntityCapsEnabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.EntityCapsEnabled", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Entity Caps Enforcement Interval Seconds", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "data/stratum-performance.json -> $.EntityTicking.EntityCapsEnforcementIntervalSeconds", - "Keywords": "entityticking,entitycapsenforcementintervalseconds", - "FieldName": "Stratum_perf_EntityTicking_EntityCapsEnforcementIntervalSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.EntityCapsEnforcementIntervalSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "10", - "EnumValues": {} - }, - { - "DisplayName": "Max Creatures Per Chunk Column", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "data/stratum-performance.json -> $.EntityTicking.MaxCreaturesPerChunkColumn", - "Keywords": "entityticking,maxcreaturesperchunkcolumn", - "FieldName": "Stratum_perf_EntityTicking_MaxCreaturesPerChunkColumn", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.MaxCreaturesPerChunkColumn", - "IncludeInCommandLine": false, - "DefaultValue": "32", - "EnumValues": {} - }, - { - "DisplayName": "Max Item Entities Per Chunk Column", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Ticking:speed:30", - "Description": "data/stratum-performance.json -> $.EntityTicking.MaxItemEntitiesPerChunkColumn", - "Keywords": "entityticking,maxitementitiesperchunkcolumn", - "FieldName": "Stratum_perf_EntityTicking_MaxItemEntitiesPerChunkColumn", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityTicking.MaxItemEntitiesPerChunkColumn", - "IncludeInCommandLine": false, - "DefaultValue": "64", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Io:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkIo.Enabled", - "Keywords": "chunkio,enabled", - "FieldName": "Stratum_perf_ChunkIo_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkIo.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Worker Threads", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Io:speed:30", - "Description": "Worker connections in the pool. Each is a fully-prepared read-only SqliteConnection; cost is one OS file handle + a few KB per connection. Useful range is 2-8; saturating SSDs usually happens around 4. (data/stratum-performance.json -> $.ChunkIo.WorkerThreads)", - "Keywords": "chunkio,workerthreads", - "FieldName": "Stratum_perf_ChunkIo_WorkerThreads", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkIo.WorkerThreads", - "IncludeInCommandLine": false, - "DefaultValue": "4", - "EnumValues": {} - }, - { - "DisplayName": "Min Chunk Y Levels For Parallel", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Io:speed:30", - "Description": "Threshold below which the parallel read path is bypassed (small columns aren't worth the dispatch overhead). (data/stratum-performance.json -> $.ChunkIo.MinChunkYLevelsForParallel)", - "Keywords": "chunkio,minchunkylevelsforparallel", - "FieldName": "Stratum_perf_ChunkIo_MinChunkYLevelsForParallel", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkIo.MinChunkYLevelsForParallel", - "IncludeInCommandLine": false, - "DefaultValue": "4", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Priority:speed:30", - "Description": "data/stratum-performance.json -> $.ChunkPriority.Enabled", - "Keywords": "chunkpriority,enabled", - "FieldName": "Stratum_perf_ChunkPriority_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkPriority.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Max Sorted Per Tick", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Priority:speed:30", - "Description": "Cap on requests pulled into the sort window each chunk-thread iteration. Keeps the sort cost bounded regardless of queue size. (data/stratum-performance.json -> $.ChunkPriority.MaxSortedPerTick)", - "Keywords": "chunkpriority,maxsortedpertick", - "FieldName": "Stratum_perf_ChunkPriority_MaxSortedPerTick", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkPriority.MaxSortedPerTick", - "IncludeInCommandLine": false, - "DefaultValue": "64", - "EnumValues": {} - }, - { - "DisplayName": "Prediction Seconds", - "Category": "Stratum Performance:speed", - "Subcategory": "Chunk Priority:speed:30", - "Description": "Forward-predict each player's chunk position by this many seconds based on .Motion so chunks ahead of motion are loaded earlier than chunks behind. 0 disables prediction. (data/stratum-performance.json -> $.ChunkPriority.PredictionSeconds)", - "Keywords": "chunkpriority,predictionseconds", - "FieldName": "Stratum_perf_ChunkPriority_PredictionSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ChunkPriority.PredictionSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "1.5", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Auto Save:speed:30", - "Description": "data/stratum-performance.json -> $.AutoSave.Enabled", - "Keywords": "autosave,enabled", - "FieldName": "Stratum_perf_AutoSave_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.AutoSave.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Delay During Chunk Pressure", - "Category": "Stratum Performance:speed", - "Subcategory": "Auto Save:speed:30", - "Description": "data/stratum-performance.json -> $.AutoSave.DelayDuringChunkPressure", - "Keywords": "autosave,delayduringchunkpressure", - "FieldName": "Stratum_perf_AutoSave_DelayDuringChunkPressure", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.AutoSave.DelayDuringChunkPressure", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Incremental Dirty Flush", - "Category": "Stratum Performance:speed", - "Subcategory": "Auto Save:speed:30", - "Description": "data/stratum-performance.json -> $.AutoSave.IncrementalDirtyFlush", - "Keywords": "autosave,incrementaldirtyflush", - "FieldName": "Stratum_perf_AutoSave_IncrementalDirtyFlush", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.AutoSave.IncrementalDirtyFlush", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Max Pending Chunk Columns", - "Category": "Stratum Performance:speed", - "Subcategory": "Auto Save:speed:30", - "Description": "data/stratum-performance.json -> $.AutoSave.MaxPendingChunkColumns", - "Keywords": "autosave,maxpendingchunkcolumns", - "FieldName": "Stratum_perf_AutoSave_MaxPendingChunkColumns", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.AutoSave.MaxPendingChunkColumns", - "IncludeInCommandLine": false, - "DefaultValue": "256", - "EnumValues": {} - }, - { - "DisplayName": "Max Worker Chunk Columns", - "Category": "Stratum Performance:speed", - "Subcategory": "Auto Save:speed:30", - "Description": "data/stratum-performance.json -> $.AutoSave.MaxWorkerChunkColumns", - "Keywords": "autosave,maxworkerchunkcolumns", - "FieldName": "Stratum_perf_AutoSave_MaxWorkerChunkColumns", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.AutoSave.MaxWorkerChunkColumns", - "IncludeInCommandLine": false, - "DefaultValue": "512", - "EnumValues": {} - }, - { - "DisplayName": "Max Delay Seconds", - "Category": "Stratum Performance:speed", - "Subcategory": "Auto Save:speed:30", - "Description": "data/stratum-performance.json -> $.AutoSave.MaxDelaySeconds", - "Keywords": "autosave,maxdelayseconds", - "FieldName": "Stratum_perf_AutoSave_MaxDelaySeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.AutoSave.MaxDelaySeconds", - "IncludeInCommandLine": false, - "DefaultValue": "120", - "EnumValues": {} - }, - { - "DisplayName": "Incremental Flush Interval Seconds", - "Category": "Stratum Performance:speed", - "Subcategory": "Auto Save:speed:30", - "Description": "data/stratum-performance.json -> $.AutoSave.IncrementalFlushIntervalSeconds", - "Keywords": "autosave,incrementalflushintervalseconds", - "FieldName": "Stratum_perf_AutoSave_IncrementalFlushIntervalSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.AutoSave.IncrementalFlushIntervalSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "10", - "EnumValues": {} - }, - { - "DisplayName": "Max Loaded Chunks Per Flush", - "Category": "Stratum Performance:speed", - "Subcategory": "Auto Save:speed:30", - "Description": "data/stratum-performance.json -> $.AutoSave.MaxLoadedChunksPerFlush", - "Keywords": "autosave,maxloadedchunksperflush", - "FieldName": "Stratum_perf_AutoSave_MaxLoadedChunksPerFlush", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.AutoSave.MaxLoadedChunksPerFlush", - "IncludeInCommandLine": false, - "DefaultValue": "256", - "EnumValues": {} - }, - { - "DisplayName": "Max Map Chunks Per Flush", - "Category": "Stratum Performance:speed", - "Subcategory": "Auto Save:speed:30", - "Description": "data/stratum-performance.json -> $.AutoSave.MaxMapChunksPerFlush", - "Keywords": "autosave,maxmapchunksperflush", - "FieldName": "Stratum_perf_AutoSave_MaxMapChunksPerFlush", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.AutoSave.MaxMapChunksPerFlush", - "IncludeInCommandLine": false, - "DefaultValue": "128", - "EnumValues": {} - }, - { - "DisplayName": "Max Loaded Chunk Scans Per Flush", - "Category": "Stratum Performance:speed", - "Subcategory": "Auto Save:speed:30", - "Description": "data/stratum-performance.json -> $.AutoSave.MaxLoadedChunkScansPerFlush", - "Keywords": "autosave,maxloadedchunkscansperflush", - "FieldName": "Stratum_perf_AutoSave_MaxLoadedChunkScansPerFlush", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.AutoSave.MaxLoadedChunkScansPerFlush", - "IncludeInCommandLine": false, - "DefaultValue": "4096", - "EnumValues": {} - }, - { - "DisplayName": "Max Map Chunk Scans Per Flush", - "Category": "Stratum Performance:speed", - "Subcategory": "Auto Save:speed:30", - "Description": "data/stratum-performance.json -> $.AutoSave.MaxMapChunkScansPerFlush", - "Keywords": "autosave,maxmapchunkscansperflush", - "FieldName": "Stratum_perf_AutoSave_MaxMapChunkScansPerFlush", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.AutoSave.MaxMapChunkScansPerFlush", - "IncludeInCommandLine": false, - "DefaultValue": "2048", - "EnumValues": {} - }, - { - "DisplayName": "Save Scan Refresh Seconds", - "Category": "Stratum Performance:speed", - "Subcategory": "Auto Save:speed:30", - "Description": "data/stratum-performance.json -> $.AutoSave.SaveScanRefreshSeconds", - "Keywords": "autosave,savescanrefreshseconds", - "FieldName": "Stratum_perf_AutoSave_SaveScanRefreshSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.AutoSave.SaveScanRefreshSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "30", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Block Ticks:speed:30", - "Description": "data/stratum-performance.json -> $.BlockTicks.Enabled", - "Keywords": "blockticks,enabled", - "FieldName": "Stratum_perf_BlockTicks_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockTicks.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Max Chunks Per Pass", - "Category": "Stratum Performance:speed", - "Subcategory": "Block Ticks:speed:30", - "Description": "data/stratum-performance.json -> $.BlockTicks.MaxChunksPerPass", - "Keywords": "blockticks,maxchunksperpass", - "FieldName": "Stratum_perf_BlockTicks_MaxChunksPerPass", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockTicks.MaxChunksPerPass", - "IncludeInCommandLine": false, - "DefaultValue": "512", - "EnumValues": {} - }, - { - "DisplayName": "Max Random Ticks Per Chunk", - "Category": "Stratum Performance:speed", - "Subcategory": "Block Ticks:speed:30", - "Description": "data/stratum-performance.json -> $.BlockTicks.MaxRandomTicksPerChunk", - "Keywords": "blockticks,maxrandomticksperchunk", - "FieldName": "Stratum_perf_BlockTicks_MaxRandomTicksPerChunk", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockTicks.MaxRandomTicksPerChunk", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {} - }, - { - "DisplayName": "Max Main Thread Block Ticks Per Pass", - "Category": "Stratum Performance:speed", - "Subcategory": "Block Ticks:speed:30", - "Description": "data/stratum-performance.json -> $.BlockTicks.MaxMainThreadBlockTicksPerPass", - "Keywords": "blockticks,maxmainthreadblockticksperpass", - "FieldName": "Stratum_perf_BlockTicks_MaxMainThreadBlockTicksPerPass", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockTicks.MaxMainThreadBlockTicksPerPass", - "IncludeInCommandLine": false, - "DefaultValue": "5000", - "EnumValues": {} - }, - { - "DisplayName": "Random Tick Slice Count", - "Category": "Stratum Performance:speed", - "Subcategory": "Block Ticks:speed:30", - "Description": "Spread the random tick pass across N smaller slices instead of one burst. Each slice runs at BlockTickInterval/SliceCount ms and processes 1/SliceCount of the chunk set. Same aggregate rate per chunk, removes the periodic sawtooth spike. 1 = vanilla batch. (data/stratum-performance.json -> $.BlockTicks.RandomTickSliceCount)", - "Keywords": "blockticks,randomtickslicecount", - "FieldName": "Stratum_perf_BlockTicks_RandomTickSliceCount", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockTicks.RandomTickSliceCount", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {} - }, - { - "DisplayName": "Adaptive Under Overload", - "Category": "Stratum Performance:speed", - "Subcategory": "Block Ticks:speed:30", - "Description": "Self-tuning under load: when the recent average server tick exceeds OverloadTickMs the per-chunk random-tick budget is scaled down (multiplied by OverloadScale, then floored at OverloadFloor). Lets crops/fluids/fire tick at full rate when the server has headroom and dial back automatically when it doesn't, instead of needing a manual config bump under load. (data/stratum-performance.json -> $.BlockTicks.AdaptiveUnderOverload)", - "Keywords": "blockticks,adaptiveunderoverload", - "FieldName": "Stratum_perf_BlockTicks_AdaptiveUnderOverload", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockTicks.AdaptiveUnderOverload", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Overload Tick Ms", - "Category": "Stratum Performance:speed", - "Subcategory": "Block Ticks:speed:30", - "Description": "data/stratum-performance.json -> $.BlockTicks.OverloadTickMs", - "Keywords": "blockticks,overloadtickms", - "FieldName": "Stratum_perf_BlockTicks_OverloadTickMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockTicks.OverloadTickMs", - "IncludeInCommandLine": false, - "DefaultValue": "45", - "EnumValues": {} - }, - { - "DisplayName": "Overload Scale", - "Category": "Stratum Performance:speed", - "Subcategory": "Block Ticks:speed:30", - "Description": "data/stratum-performance.json -> $.BlockTicks.OverloadScale", - "Keywords": "blockticks,overloadscale", - "FieldName": "Stratum_perf_BlockTicks_OverloadScale", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockTicks.OverloadScale", - "IncludeInCommandLine": false, - "DefaultValue": "0.5", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Overload Floor", - "Category": "Stratum Performance:speed", - "Subcategory": "Block Ticks:speed:30", - "Description": "data/stratum-performance.json -> $.BlockTicks.OverloadFloor", - "Keywords": "blockticks,overloadfloor", - "FieldName": "Stratum_perf_BlockTicks_OverloadFloor", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockTicks.OverloadFloor", - "IncludeInCommandLine": false, - "DefaultValue": "2", - "EnumValues": {} - }, - { - "DisplayName": "Enabled On Startup", - "Category": "Stratum Performance:speed", - "Subcategory": "Timings:speed:30", - "Description": "data/stratum-performance.json -> $.Timings.EnabledOnStartup", - "Keywords": "timings,enabledonstartup", - "FieldName": "Stratum_perf_Timings_EnabledOnStartup", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Timings.EnabledOnStartup", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Report Top Entries", - "Category": "Stratum Performance:speed", - "Subcategory": "Timings:speed:30", - "Description": "data/stratum-performance.json -> $.Timings.ReportTopEntries", - "Keywords": "timings,reporttopentries", - "FieldName": "Stratum_perf_Timings_ReportTopEntries", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Timings.ReportTopEntries", - "IncludeInCommandLine": false, - "DefaultValue": "30", - "EnumValues": {} - }, - { - "DisplayName": "Slow Sample Threshold Ms", - "Category": "Stratum Performance:speed", - "Subcategory": "Timings:speed:30", - "Description": "data/stratum-performance.json -> $.Timings.SlowSampleThresholdMs", - "Keywords": "timings,slowsamplethresholdms", - "FieldName": "Stratum_perf_Timings_SlowSampleThresholdMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Timings.SlowSampleThresholdMs", - "IncludeInCommandLine": false, - "DefaultValue": "50", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Async", - "Category": "Stratum Performance:speed", - "Subcategory": "Pathfinding:speed:30", - "Description": "Move pathfinding tasks off the main thread onto a dedicated worker pool. (data/stratum-performance.json -> $.Pathfinding.Async)", - "Keywords": "pathfinding,async", - "FieldName": "Stratum_perf_Pathfinding_Async", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Pathfinding.Async", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Worker Threads", - "Category": "Stratum Performance:speed", - "Subcategory": "Pathfinding:speed:30", - "Description": "Worker thread count for async pathfinding. 0 = auto (max(2, Environment.ProcessorCount / 2)). (data/stratum-performance.json -> $.Pathfinding.WorkerThreads)", - "Keywords": "pathfinding,workerthreads", - "FieldName": "Stratum_perf_Pathfinding_WorkerThreads", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Pathfinding.WorkerThreads", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Max Queued", - "Category": "Stratum Performance:speed", - "Subcategory": "Pathfinding:speed:30", - "Description": "Max queued pathfind requests before stale or oldest queued work is dropped. 0 = unbounded. (data/stratum-performance.json -> $.Pathfinding.MaxQueued)", - "Keywords": "pathfinding,maxqueued", - "FieldName": "Stratum_perf_Pathfinding_MaxQueued", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Pathfinding.MaxQueued", - "IncludeInCommandLine": false, - "DefaultValue": "512", - "EnumValues": {} - }, - { - "DisplayName": "Max Task Age Ms", - "Category": "Stratum Performance:speed", - "Subcategory": "Pathfinding:speed:30", - "Description": "Queued async path requests older than this are considered stale and can be discarded before useful work is dropped. 0 = never stale by age. (data/stratum-performance.json -> $.Pathfinding.MaxTaskAgeMs)", - "Keywords": "pathfinding,maxtaskagems", - "FieldName": "Stratum_perf_Pathfinding_MaxTaskAgeMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Pathfinding.MaxTaskAgeMs", - "IncludeInCommandLine": false, - "DefaultValue": "2000", - "EnumValues": {} - }, - { - "DisplayName": "Priority Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Pathfinding:speed:30", - "Description": "Reorders queued work near players first once the queue is backed up. (data/stratum-performance.json -> $.Pathfinding.PriorityEnabled)", - "Keywords": "pathfinding,priorityenabled", - "FieldName": "Stratum_perf_Pathfinding_PriorityEnabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Pathfinding.PriorityEnabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Priority Queue Threshold", - "Category": "Stratum Performance:speed", - "Subcategory": "Pathfinding:speed:30", - "Description": "Queue depth that enables priority sorting and pressure-only far task drops. (data/stratum-performance.json -> $.Pathfinding.PriorityQueueThreshold)", - "Keywords": "pathfinding,priorityqueuethreshold", - "FieldName": "Stratum_perf_Pathfinding_PriorityQueueThreshold", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Pathfinding.PriorityQueueThreshold", - "IncludeInCommandLine": false, - "DefaultValue": "64", - "EnumValues": {} - }, - { - "DisplayName": "Far Task Distance Blocks", - "Category": "Stratum Performance:speed", - "Subcategory": "Pathfinding:speed:30", - "Description": "Queued tasks whose owner is farther than this from all players can be dropped under queue pressure. 0 disables distance-based dropping. (data/stratum-performance.json -> $.Pathfinding.FarTaskDistanceBlocks)", - "Keywords": "pathfinding,fartaskdistanceblocks", - "FieldName": "Stratum_perf_Pathfinding_FarTaskDistanceBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Pathfinding.FarTaskDistanceBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "160", - "EnumValues": {} - }, - { - "DisplayName": "Drop Far Tasks Under Pressure", - "Category": "Stratum Performance:speed", - "Subcategory": "Pathfinding:speed:30", - "Description": "data/stratum-performance.json -> $.Pathfinding.DropFarTasksUnderPressure", - "Keywords": "pathfinding,dropfartasksunderpressure", - "FieldName": "Stratum_perf_Pathfinding_DropFarTasksUnderPressure", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Pathfinding.DropFarTasksUnderPressure", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Failure Cooldown After Failures", - "Category": "Stratum Performance:speed", - "Subcategory": "Pathfinding:speed:30", - "Description": "A short per-traverser cooldown after repeated no-path results. Keeps mobs from burning worker time on the same impossible goal every tick. (data/stratum-performance.json -> $.Pathfinding.FailureCooldownAfterFailures)", - "Keywords": "pathfinding,failurecooldownafterfailures", - "FieldName": "Stratum_perf_Pathfinding_FailureCooldownAfterFailures", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Pathfinding.FailureCooldownAfterFailures", - "IncludeInCommandLine": false, - "DefaultValue": "3", - "EnumValues": {} - }, - { - "DisplayName": "Failure Cooldown Ms", - "Category": "Stratum Performance:speed", - "Subcategory": "Pathfinding:speed:30", - "Description": "data/stratum-performance.json -> $.Pathfinding.FailureCooldownMs", - "Keywords": "pathfinding,failurecooldownms", - "FieldName": "Stratum_perf_Pathfinding_FailureCooldownMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Pathfinding.FailureCooldownMs", - "IncludeInCommandLine": false, - "DefaultValue": "1500", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Region Ticking:speed:30", - "Description": "Folia-style regionized entity ticking. Splits LoadedEntities into spatial regions (region size in chunks) and ticks each region on a worker thread in parallel. Behaviors that throw repeatedly get runtime-blocked via FallbackAfterExceptions. Disabled by default: entity behaviors from mods may not be thread-safe. Enable after validating your mod set under load. Unsafe behaviors self-quarantine to serial. (data/stratum-performance.json -> $.RegionTicking.Enabled)", - "Keywords": "regionticking,enabled", - "FieldName": "Stratum_perf_RegionTicking_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.RegionTicking.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Region Size Chunks", - "Category": "Stratum Performance:speed", - "Subcategory": "Region Ticking:speed:30", - "Description": "Region size in chunks (e.g. 8 = 8x8 chunk regions = 256x256 blocks). (data/stratum-performance.json -> $.RegionTicking.RegionSizeChunks)", - "Keywords": "regionticking,regionsizechunks", - "FieldName": "Stratum_perf_RegionTicking_RegionSizeChunks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.RegionTicking.RegionSizeChunks", - "IncludeInCommandLine": false, - "DefaultValue": "8", - "EnumValues": {} - }, - { - "DisplayName": "Worker Threads", - "Category": "Stratum Performance:speed", - "Subcategory": "Region Ticking:speed:30", - "Description": "Worker thread count. 0 = auto (max(1, Environment.ProcessorCount - 2)). (data/stratum-performance.json -> $.RegionTicking.WorkerThreads)", - "Keywords": "regionticking,workerthreads", - "FieldName": "Stratum_perf_RegionTicking_WorkerThreads", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.RegionTicking.WorkerThreads", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Min Entities Per Region", - "Category": "Stratum Performance:speed", - "Subcategory": "Region Ticking:speed:30", - "Description": "Min entities required in a region to consider parallel ticking (small regions stay on main thread). (data/stratum-performance.json -> $.RegionTicking.MinEntitiesPerRegion)", - "Keywords": "regionticking,minentitiesperregion", - "FieldName": "Stratum_perf_RegionTicking_MinEntitiesPerRegion", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.RegionTicking.MinEntitiesPerRegion", - "IncludeInCommandLine": false, - "DefaultValue": "16", - "EnumValues": {} - }, - { - "DisplayName": "Entity Filter Mode", - "Category": "Stratum Performance:speed", - "Subcategory": "Region Ticking:speed:30", - "Description": "Entity filter mode. Controls which entities tick in parallel worker threads vs main thread. \"all\" = current behavior (all non-players go parallel). \"denylist\" = entities matching BlockedEntityCodePrefixes or BlockedEntityClasses tick on main thread. \"allowlist\" = only entities matching AllowedEntityCodePrefixes go parallel, everything else stays serial. (data/stratum-performance.json -> $.RegionTicking.EntityFilterMode)", - "Keywords": "regionticking,entityfiltermode", - "FieldName": "Stratum_perf_RegionTicking_EntityFilterMode", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.RegionTicking.EntityFilterMode", - "IncludeInCommandLine": false, - "DefaultValue": "all", - "EnumValues": {} - }, - { - "DisplayName": "Fallback After Exceptions", - "Category": "Stratum Performance:speed", - "Subcategory": "Region Ticking:speed:30", - "Description": "Automatic fallback: max exceptions a single entity type (Properties.Class) can throw within FallbackWindowSeconds before it gets runtime-blocked from parallel ticking. 0 = disabled (no automatic fallback). (data/stratum-performance.json -> $.RegionTicking.FallbackAfterExceptions)", - "Keywords": "regionticking,fallbackafterexceptions", - "FieldName": "Stratum_perf_RegionTicking_FallbackAfterExceptions", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.RegionTicking.FallbackAfterExceptions", - "IncludeInCommandLine": false, - "DefaultValue": "5", - "EnumValues": {} - }, - { - "DisplayName": "Fallback Window Seconds", - "Category": "Stratum Performance:speed", - "Subcategory": "Region Ticking:speed:30", - "Description": "Time window in seconds for counting exceptions per entity type. (data/stratum-performance.json -> $.RegionTicking.FallbackWindowSeconds)", - "Keywords": "regionticking,fallbackwindowseconds", - "FieldName": "Stratum_perf_RegionTicking_FallbackWindowSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.RegionTicking.FallbackWindowSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "60", - "EnumValues": {} - }, - { - "DisplayName": "Persist Fallback Until Restart", - "Category": "Stratum Performance:speed", - "Subcategory": "Region Ticking:speed:30", - "Description": "When true, the runtime-blocked set persists until server restart. When false (default), /stratum reload clears the blocked set. (data/stratum-performance.json -> $.RegionTicking.PersistFallbackUntilRestart)", - "Keywords": "regionticking,persistfallbackuntilrestart", - "FieldName": "Stratum_perf_RegionTicking_PersistFallbackUntilRestart", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.RegionTicking.PersistFallbackUntilRestart", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Body Temperature:speed:30", - "Description": "When enabled, vanilla bodytemperature accumulator thresholds are replaced with the values below + per-entity jitter (so 150 players don't all run the expensive RoomRegistry + climate sampling on the same tick). (data/stratum-performance.json -> $.BodyTemperature.Enabled)", - "Keywords": "bodytemperature,enabled", - "FieldName": "Stratum_perf_BodyTemperature_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.BodyTemperature.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Update Interval Seconds", - "Category": "Stratum Performance:speed", - "Subcategory": "Body Temperature:speed:30", - "Description": "How often per player to run the main ambient-temp/wetness update (vanilla = 2s). (data/stratum-performance.json -> $.BodyTemperature.UpdateIntervalSeconds)", - "Keywords": "bodytemperature,updateintervalseconds", - "FieldName": "Stratum_perf_BodyTemperature_UpdateIntervalSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BodyTemperature.UpdateIntervalSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "3", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Heat Source Interval Seconds", - "Category": "Stratum Performance:speed", - "Subcategory": "Body Temperature:speed:30", - "Description": "How often to recompute heat-source strength (the RoomRegistry flood-fill, vanilla = 5s). (data/stratum-performance.json -> $.BodyTemperature.HeatSourceIntervalSeconds)", - "Keywords": "bodytemperature,heatsourceintervalseconds", - "FieldName": "Stratum_perf_BodyTemperature_HeatSourceIntervalSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BodyTemperature.HeatSourceIntervalSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "15", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Freezing Anim Interval Seconds", - "Category": "Stratum Performance:speed", - "Subcategory": "Body Temperature:speed:30", - "Description": "How often to refresh the freezing visual state (vanilla = 1s). (data/stratum-performance.json -> $.BodyTemperature.FreezingAnimIntervalSeconds)", - "Keywords": "bodytemperature,freezinganimintervalseconds", - "FieldName": "Stratum_perf_BodyTemperature_FreezingAnimIntervalSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BodyTemperature.FreezingAnimIntervalSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "2", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Damage Check Interval Seconds", - "Category": "Stratum Performance:speed", - "Subcategory": "Body Temperature:speed:30", - "Description": "How often to do the frost-damage check (vanilla = 10s). (data/stratum-performance.json -> $.BodyTemperature.DamageCheckIntervalSeconds)", - "Keywords": "bodytemperature,damagecheckintervalseconds", - "FieldName": "Stratum_perf_BodyTemperature_DamageCheckIntervalSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BodyTemperature.DamageCheckIntervalSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "12", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Jitter Percent", - "Category": "Stratum Performance:speed", - "Subcategory": "Body Temperature:speed:30", - "Description": "Per-entity random jitter applied to each interval (0..1 = +/- this fraction). 0.25 means a 5s interval ends up between 3.75s and 6.25s per entity. (data/stratum-performance.json -> $.BodyTemperature.JitterPercent)", - "Keywords": "bodytemperature,jitterpercent", - "FieldName": "Stratum_perf_BodyTemperature_JitterPercent", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BodyTemperature.JitterPercent", - "IncludeInCommandLine": false, - "DefaultValue": "0.25", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Event Tick:speed:30", - "Description": "data/stratum-performance.json -> $.EventTick.Enabled", - "Keywords": "eventtick,enabled", - "FieldName": "Stratum_perf_EventTick_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.EventTick.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Record Subsection Timings", - "Category": "Stratum Performance:speed", - "Subcategory": "Event Tick:speed:30", - "Description": "When true, records per-subsection timings for server.eventTick into PerformanceStats: eventTick.gtEntity, eventTick.gtBlock, eventTick.dcEntity, eventTick.dcBlock. (data/stratum-performance.json -> $.EventTick.RecordSubsectionTimings)", - "Keywords": "eventtick,recordsubsectiontimings", - "FieldName": "Stratum_perf_EventTick_RecordSubsectionTimings", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.EventTick.RecordSubsectionTimings", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Slow Block Listener Threshold Ms", - "Category": "Stratum Performance:speed", - "Subcategory": "Event Tick:speed:30", - "Description": "When a single block-listener tick exceeds this many milliseconds, record its profiler name for diagnosis. 0 disables. (data/stratum-performance.json -> $.EventTick.SlowBlockListenerThresholdMs)", - "Keywords": "eventtick,slowblocklistenerthresholdms", - "FieldName": "Stratum_perf_EventTick_SlowBlockListenerThresholdMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EventTick.SlowBlockListenerThresholdMs", - "IncludeInCommandLine": false, - "DefaultValue": "5", - "EnumValues": {} - }, - { - "DisplayName": "Slow Entity Listener Threshold Ms", - "Category": "Stratum Performance:speed", - "Subcategory": "Event Tick:speed:30", - "Description": "When a single entity-listener tick exceeds this many milliseconds, record its profiler name. 0 disables. Note: 'entity listeners' here = RegisterGameTickListener handlers (not entity OnGameTick). (data/stratum-performance.json -> $.EventTick.SlowEntityListenerThresholdMs)", - "Keywords": "eventtick,slowentitylistenerthresholdms", - "FieldName": "Stratum_perf_EventTick_SlowEntityListenerThresholdMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EventTick.SlowEntityListenerThresholdMs", - "IncludeInCommandLine": false, - "DefaultValue": "5", - "EnumValues": {} - }, - { - "DisplayName": "Adaptive Throttle When Overloaded", - "Category": "Stratum Performance:speed", - "Subcategory": "Event Tick:speed:30", - "Description": "Paper-style adaptive throttle: when the previous server tick exceeded the overloaded threshold, stretch the effective interval of non-critical entity listeners by this factor. 1 disables. Critical listeners (interval <= AdaptiveCriticalIntervalMs) are never throttled so packet, physics, and netcode listeners always fire on time. (data/stratum-performance.json -> $.EventTick.AdaptiveThrottleWhenOverloaded)", - "Keywords": "eventtick,adaptivethrottlewhenoverloaded", - "FieldName": "Stratum_perf_EventTick_AdaptiveThrottleWhenOverloaded", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.EventTick.AdaptiveThrottleWhenOverloaded", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Adaptive Overloaded Multiplier", - "Category": "Stratum Performance:speed", - "Subcategory": "Event Tick:speed:30", - "Description": "data/stratum-performance.json -> $.EventTick.AdaptiveOverloadedMultiplier", - "Keywords": "eventtick,adaptiveoverloadedmultiplier", - "FieldName": "Stratum_perf_EventTick_AdaptiveOverloadedMultiplier", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EventTick.AdaptiveOverloadedMultiplier", - "IncludeInCommandLine": false, - "DefaultValue": "2", - "EnumValues": {} - }, - { - "DisplayName": "Adaptive Critical Interval Ms", - "Category": "Stratum Performance:speed", - "Subcategory": "Event Tick:speed:30", - "Description": "Listeners whose configured interval is <= this many ms are exempt from adaptive throttling. (data/stratum-performance.json -> $.EventTick.AdaptiveCriticalIntervalMs)", - "Keywords": "eventtick,adaptivecriticalintervalms", - "FieldName": "Stratum_perf_EventTick_AdaptiveCriticalIntervalMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EventTick.AdaptiveCriticalIntervalMs", - "IncludeInCommandLine": false, - "DefaultValue": "50", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Collisions:speed:30", - "Description": "data/stratum-performance.json -> $.EntityCollisions.Enabled", - "Keywords": "entitycollisions,enabled", - "FieldName": "Stratum_perf_EntityCollisions_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityCollisions.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Max Collisions Per Entity", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Collisions:speed:30", - "Description": "0 disables the cap. Paper default is 8; we use 12 to be more permissive of pushing. (data/stratum-performance.json -> $.EntityCollisions.MaxCollisionsPerEntity)", - "Keywords": "entitycollisions,maxcollisionsperentity", - "FieldName": "Stratum_perf_EntityCollisions_MaxCollisionsPerEntity", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityCollisions.MaxCollisionsPerEntity", - "IncludeInCommandLine": false, - "DefaultValue": "12", - "EnumValues": {} - }, - { - "DisplayName": "Distance Gate Blocks", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Collisions:speed:30", - "Description": "Distance gate for RepulseAgents (non-player creatures skip entirely beyond this range). (data/stratum-performance.json -> $.EntityCollisions.DistanceGateBlocks)", - "Keywords": "entitycollisions,distancegateblocks", - "FieldName": "Stratum_perf_EntityCollisions_DistanceGateBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityCollisions.DistanceGateBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "24", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Near Band Blocks", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Collisions:speed:30", - "Description": "data/stratum-performance.json -> $.EntityCollisions.NearBandBlocks", - "Keywords": "entitycollisions,nearbandblocks", - "FieldName": "Stratum_perf_EntityCollisions_NearBandBlocks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityCollisions.NearBandBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "12", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Far Band Skip Ticks", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Collisions:speed:30", - "Description": "data/stratum-performance.json -> $.EntityCollisions.FarBandSkipTicks", - "Keywords": "entitycollisions,farbandskipticks", - "FieldName": "Stratum_perf_EntityCollisions_FarBandSkipTicks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityCollisions.FarBandSkipTicks", - "IncludeInCommandLine": false, - "DefaultValue": "4", - "EnumValues": {} - }, - { - "DisplayName": "Collect Stride Interval", - "Category": "Stratum Performance:speed", - "Subcategory": "Entity Collisions:speed:30", - "Description": "CollectEntities scan stride. Only run the spatial query every N ticks per entity, phase-offset by EntityId. Reduces allocations from GetEntitiesAround. 1 = every tick. (data/stratum-performance.json -> $.EntityCollisions.CollectStrideInterval)", - "Keywords": "entitycollisions,collectstrideinterval", - "FieldName": "Stratum_perf_EntityCollisions_CollectStrideInterval", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.EntityCollisions.CollectStrideInterval", - "IncludeInCommandLine": false, - "DefaultValue": "3", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Block Entity Init:speed:30", - "Description": "data/stratum-performance.json -> $.BlockEntityInit.Enabled", - "Keywords": "blockentityinit,enabled", - "FieldName": "Stratum_perf_BlockEntityInit_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockEntityInit.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Max Stagger Ms", - "Category": "Stratum Performance:speed", - "Subcategory": "Block Entity Init:speed:30", - "Description": "Max stagger window in ms. The actual offset for a given BE is (Pos.HashCode % min(MaxStaggerMs, millisecondInterval)). 0 disables. 250ms = up to ~7 ticks of stagger at 30Hz. (data/stratum-performance.json -> $.BlockEntityInit.MaxStaggerMs)", - "Keywords": "blockentityinit,maxstaggerms", - "FieldName": "Stratum_perf_BlockEntityInit_MaxStaggerMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.BlockEntityInit.MaxStaggerMs", - "IncludeInCommandLine": false, - "DefaultValue": "250", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Timer Resolution:speed:30", - "Description": "data/stratum-performance.json -> $.TimerResolution.Enabled", - "Keywords": "timerresolution,enabled", - "FieldName": "Stratum_perf_TimerResolution_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.TimerResolution.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Period Ms", - "Category": "Stratum Performance:speed", - "Subcategory": "Timer Resolution:speed:30", - "Description": "Requested timer period in ms. 1 = highest practical resolution. Range 1-15. (data/stratum-performance.json -> $.TimerResolution.PeriodMs)", - "Keywords": "timerresolution,periodms", - "FieldName": "Stratum_perf_TimerResolution_PeriodMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.TimerResolution.PeriodMs", - "IncludeInCommandLine": false, - "DefaultValue": "1", - "EnumValues": {} - }, - { - "DisplayName": "Cache Startup Packets", - "Category": "Stratum Performance:speed", - "Subcategory": "Join:speed:30", - "Description": "data/stratum-performance.json -> $.Join.CacheStartupPackets", - "Keywords": "join,cachestartuppackets", - "FieldName": "Stratum_perf_Join_CacheStartupPackets", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Join.CacheStartupPackets", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Max Queue Admissions Per Pass", - "Category": "Stratum Performance:speed", - "Subcategory": "Join:speed:30", - "Description": "Limits how many queued players are admitted in one queue pass. 0 = vanilla behavior. (data/stratum-performance.json -> $.Join.MaxQueueAdmissionsPerPass)", - "Keywords": "join,maxqueueadmissionsperpass", - "FieldName": "Stratum_perf_Join_MaxQueueAdmissionsPerPass", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Join.MaxQueueAdmissionsPerPass", - "IncludeInCommandLine": false, - "DefaultValue": "2", - "EnumValues": {} - }, - { - "DisplayName": "Max Joins Per Tick", - "Category": "Stratum Performance:speed", - "Subcategory": "Join:speed:30", - "Description": "Limits how many RequestJoin packets (Id 11) are processed per tick. Deferred joins drain on subsequent ticks. Keeps the main thread responsive during join storms. 0 = no limit (vanilla behavior). (data/stratum-performance.json -> $.Join.MaxJoinsPerTick)", - "Keywords": "join,maxjoinspertick", - "FieldName": "Stratum_perf_Join_MaxJoinsPerTick", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Join.MaxJoinsPerTick", - "IncludeInCommandLine": false, - "DefaultValue": "3", - "EnumValues": {} - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Adaptive Radius:speed:30", - "Description": "data/stratum-performance.json -> $.AdaptiveRadius.Enabled", - "Keywords": "adaptiveradius,enabled", - "FieldName": "Stratum_perf_AdaptiveRadius_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.AdaptiveRadius.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Smoothing Alpha", - "Category": "Stratum Performance:speed", - "Subcategory": "Adaptive Radius:speed:30", - "Description": "data/stratum-performance.json -> $.AdaptiveRadius.SmoothingAlpha", - "Keywords": "adaptiveradius,smoothingalpha", - "FieldName": "Stratum_perf_AdaptiveRadius_SmoothingAlpha", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.AdaptiveRadius.SmoothingAlpha", - "IncludeInCommandLine": false, - "DefaultValue": "0.15", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Decrease Mspt Threshold", - "Category": "Stratum Performance:speed", - "Subcategory": "Adaptive Radius:speed:30", - "Description": "data/stratum-performance.json -> $.AdaptiveRadius.DecreaseMsptThreshold", - "Keywords": "adaptiveradius,decreasemsptthreshold", - "FieldName": "Stratum_perf_AdaptiveRadius_DecreaseMsptThreshold", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.AdaptiveRadius.DecreaseMsptThreshold", - "IncludeInCommandLine": false, - "DefaultValue": "45.0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Increase Mspt Threshold", - "Category": "Stratum Performance:speed", - "Subcategory": "Adaptive Radius:speed:30", - "Description": "data/stratum-performance.json -> $.AdaptiveRadius.IncreaseMsptThreshold", - "Keywords": "adaptiveradius,increasemsptthreshold", - "FieldName": "Stratum_perf_AdaptiveRadius_IncreaseMsptThreshold", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.AdaptiveRadius.IncreaseMsptThreshold", - "IncludeInCommandLine": false, - "DefaultValue": "35.0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Overload Drop Threshold Ms", - "Category": "Stratum Performance:speed", - "Subcategory": "Adaptive Radius:speed:30", - "Description": "Instant radius drop when a single tick exceeds this value (ms). (data/stratum-performance.json -> $.AdaptiveRadius.OverloadDropThresholdMs)", - "Keywords": "adaptiveradius,overloaddropthresholdms", - "FieldName": "Stratum_perf_AdaptiveRadius_OverloadDropThresholdMs", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.AdaptiveRadius.OverloadDropThresholdMs", - "IncludeInCommandLine": false, - "DefaultValue": "500.0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Floor Chunks", - "Category": "Stratum Performance:speed", - "Subcategory": "Adaptive Radius:speed:30", - "Description": "data/stratum-performance.json -> $.AdaptiveRadius.FloorChunks", - "Keywords": "adaptiveradius,floorchunks", - "FieldName": "Stratum_perf_AdaptiveRadius_FloorChunks", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.AdaptiveRadius.FloorChunks", - "IncludeInCommandLine": false, - "DefaultValue": "4", - "EnumValues": {} - }, - { - "DisplayName": "Adjustment Interval Seconds", - "Category": "Stratum Performance:speed", - "Subcategory": "Adaptive Radius:speed:30", - "Description": "data/stratum-performance.json -> $.AdaptiveRadius.AdjustmentIntervalSeconds", - "Keywords": "adaptiveradius,adjustmentintervalseconds", - "FieldName": "Stratum_perf_AdaptiveRadius_AdjustmentIntervalSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.AdaptiveRadius.AdjustmentIntervalSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "2.0", - "EnumValues": {}, - "Decimal": true - }, - { - "DisplayName": "Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Item Cleanup:speed:30", - "Description": "data/stratum-performance.json -> $.ItemCleanup.Enabled", - "Keywords": "itemcleanup,enabled", - "FieldName": "Stratum_perf_ItemCleanup_Enabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.ItemCleanup.Enabled", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Interval Seconds", - "Category": "Stratum Performance:speed", - "Subcategory": "Item Cleanup:speed:30", - "Description": "data/stratum-performance.json -> $.ItemCleanup.IntervalSeconds", - "Keywords": "itemcleanup,intervalseconds", - "FieldName": "Stratum_perf_ItemCleanup_IntervalSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ItemCleanup.IntervalSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "60", - "EnumValues": {} - }, - { - "DisplayName": "Minimum Entity Age Seconds", - "Category": "Stratum Performance:speed", - "Subcategory": "Item Cleanup:speed:30", - "Description": "data/stratum-performance.json -> $.ItemCleanup.MinimumEntityAgeSeconds", - "Keywords": "itemcleanup,minimumentityageseconds", - "FieldName": "Stratum_perf_ItemCleanup_MinimumEntityAgeSeconds", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.ItemCleanup.MinimumEntityAgeSeconds", - "IncludeInCommandLine": false, - "DefaultValue": "10", - "EnumValues": {} - }, - { - "DisplayName": "Cleanup Warning Message", - "Category": "Stratum Performance:speed", - "Subcategory": "Item Cleanup:speed:30", - "Description": "data/stratum-performance.json -> $.ItemCleanup.CleanupWarningMessage", - "Keywords": "itemcleanup,cleanupwarningmessage", - "FieldName": "Stratum_perf_ItemCleanup_CleanupWarningMessage", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.ItemCleanup.CleanupWarningMessage", - "IncludeInCommandLine": false, - "DefaultValue": "Cleaning up dropped items in {0} seconds.", - "EnumValues": {} - }, - { - "DisplayName": "Cleanup Starting Message", - "Category": "Stratum Performance:speed", - "Subcategory": "Item Cleanup:speed:30", - "Description": "data/stratum-performance.json -> $.ItemCleanup.CleanupStartingMessage", - "Keywords": "itemcleanup,cleanupstartingmessage", - "FieldName": "Stratum_perf_ItemCleanup_CleanupStartingMessage", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.ItemCleanup.CleanupStartingMessage", - "IncludeInCommandLine": false, - "DefaultValue": "Cleaning up dropped items...", - "EnumValues": {} - }, - { - "DisplayName": "Cleanup Done Message", - "Category": "Stratum Performance:speed", - "Subcategory": "Item Cleanup:speed:30", - "Description": "data/stratum-performance.json -> $.ItemCleanup.CleanupDoneMessage", - "Keywords": "itemcleanup,cleanupdonemessage", - "FieldName": "Stratum_perf_ItemCleanup_CleanupDoneMessage", - "InputType": "text", - "IsFlagArgument": false, - "ParamFieldName": "$.ItemCleanup.CleanupDoneMessage", - "IncludeInCommandLine": false, - "DefaultValue": "Cleaned up {0} items.", - "EnumValues": {} - }, - { - "DisplayName": "Send Queue Enabled", - "Category": "Stratum Performance:speed", - "Subcategory": "Network:speed:30", - "Description": "Off by default. The queue removes the packet reordering bug from the old StratumNetworkFlush (disabled after client crashes, see PR #138), but it is new code on the hottest path in the server. Soak on a community server before flipping the shipped default. (data/stratum-performance.json -> $.Network.SendQueueEnabled)", - "Keywords": "network,sendqueueenabled", - "FieldName": "Stratum_perf_Network_SendQueueEnabled", - "InputType": "checkbox", - "IsFlagArgument": false, - "ParamFieldName": "$.Network.SendQueueEnabled", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Large Threshold Bytes", - "Category": "Stratum Performance:speed", - "Subcategory": "Network:speed:30", - "Description": "Packets at or above this size skip coalescing and go out alone. Matches the TCP MTU assumption the old flush buffer used. (data/stratum-performance.json -> $.Network.LargeThresholdBytes)", - "Keywords": "network,largethresholdbytes", - "FieldName": "Stratum_perf_Network_LargeThresholdBytes", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Network.LargeThresholdBytes", - "IncludeInCommandLine": false, - "DefaultValue": "1400", - "EnumValues": {} - }, - { - "DisplayName": "Coalesce Limit Bytes", - "Category": "Stratum Performance:speed", - "Subcategory": "Network:speed:30", - "Description": "Upper bound on one coalesced send. Caps the reusable drain buffer and how much data a single SendAsync call carries. (data/stratum-performance.json -> $.Network.CoalesceLimitBytes)", - "Keywords": "network,coalescelimitbytes", - "FieldName": "Stratum_perf_Network_CoalesceLimitBytes", - "InputType": "number", - "IsFlagArgument": false, - "ParamFieldName": "$.Network.CoalesceLimitBytes", - "IncludeInCommandLine": false, - "DefaultValue": "65536", - "EnumValues": {} - } + {"DisplayName":"Server Port","Category":"Vintage Story:stadia_controller","Subcategory":"Network:dns:1","Description":"Private game port used by Nimbus Proxy.","Keywords":"port,backend","FieldName":"$ServerPort","InputType":"number","Hidden":true,"ParamFieldName":"$.Port","IncludeInCommandLine":false,"DefaultValue":"42420","MinValue":1,"MaxValue":65535,"EnumValues":{}}, + {"DisplayName":"Player Limit","Category":"Vintage Story:stadia_controller","Subcategory":"Players:group:2","Description":"Maximum simultaneous players on this backend.","Keywords":"players,limit","FieldName":"$MaxUsers","InputType":"number","ParamFieldName":"$.MaxClients","IncludeInCommandLine":false,"DefaultValue":"16","MinValue":1,"MaxValue":1000,"EnumValues":{}}, + {"DisplayName":"Server Name","Category":"Vintage Story:stadia_controller","Subcategory":"Identity:badge:1","Description":"Name shown by the Vintage Story server.","Keywords":"server,name","FieldName":"VS_ServerName","InputType":"text","ParamFieldName":"$.ServerName","IncludeInCommandLine":false,"DefaultValue":"Vintage Story Server","EnumValues":{}}, + {"DisplayName":"Server Description","Category":"Vintage Story:stadia_controller","Subcategory":"Identity:badge:1","Description":"Short description shown to players.","Keywords":"server,description","FieldName":"VS_ServerDescription","InputType":"text","ParamFieldName":"$.ServerDescription","IncludeInCommandLine":false,"DefaultValue":"","EnumValues":{}}, + {"DisplayName":"Welcome Message","Category":"Vintage Story:stadia_controller","Subcategory":"Identity:badge:1","Description":"Message shown after a player joins.","Keywords":"welcome,message","FieldName":"VS_WelcomeMessage","InputType":"text","ParamFieldName":"$.WelcomeMessage","IncludeInCommandLine":false,"DefaultValue":"Welcome, {0}, may you survive well and prosper","EnumValues":{}}, + {"DisplayName":"Server Password","Category":"Vintage Story:stadia_controller","Subcategory":"Access:lock:3","Description":"Optional password required to join. Leave blank for none.","Keywords":"password,access","FieldName":"VS_Password","InputType":"password","ParamFieldName":"$.Password","IncludeInCommandLine":false,"DefaultValue":"","EnumValues":{}}, + {"DisplayName":"Whitelist Mode","Category":"Vintage Story:stadia_controller","Subcategory":"Access:lock:3","Description":"Default follows Vintage Story dedicated-server policy.","Keywords":"whitelist,access","FieldName":"VS_WhitelistMode","InputType":"enum","ParamFieldName":"$.WhitelistMode","IncludeInCommandLine":false,"DefaultValue":"0","EnumValues":{"0":"Default (on for dedicated servers)","1":"Off","2":"On"}}, + {"DisplayName":"Allow PvP","Category":"Vintage Story:stadia_controller","Subcategory":"Rules:gavel:4","Description":"Allow players to damage other players.","Keywords":"pvp,rules","FieldName":"VS_AllowPvP","InputType":"checkbox","ParamFieldName":"$.AllowPvP","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Allow Fire Spread","Category":"Vintage Story:stadia_controller","Subcategory":"Rules:gavel:4","Description":"Allow fire to spread between blocks.","Keywords":"fire,spread","FieldName":"VS_AllowFireSpread","InputType":"checkbox","ParamFieldName":"$.AllowFireSpread","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Pass Time When Empty","Category":"Vintage Story:stadia_controller","Subcategory":"Rules:gavel:4","Description":"Advance world time while no players are online.","Keywords":"time,empty","FieldName":"VS_PassTimeWhenEmpty","InputType":"checkbox","ParamFieldName":"$.PassTimeWhenEmpty","IncludeInCommandLine":false,"DefaultValue":"false","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"World Name","Category":"World:public","Subcategory":"Creation:terrain:1","Description":"Name for a newly created world.","Keywords":"world,name","FieldName":"VS_WorldName","InputType":"text","ParamFieldName":"$.WorldConfig.WorldName","IncludeInCommandLine":false,"DefaultValue":"A new world","EnumValues":{}}, + {"DisplayName":"World Seed","Category":"World:public","Subcategory":"Creation:terrain:1","Description":"Optional seed for a newly created world. Leave blank for random.","Keywords":"world,seed","FieldName":"VS_WorldSeed","InputType":"text","ParamFieldName":"$.WorldConfig.Seed","IncludeInCommandLine":false,"DefaultValue":"","EnumValues":{}}, + {"DisplayName":"Play Style","Category":"World:public","Subcategory":"Creation:terrain:1","Description":"Play style used when the world is first created.","Keywords":"world,playstyle","FieldName":"VS_PlayStyle","InputType":"enum","ParamFieldName":"$.WorldConfig.PlayStyle","IncludeInCommandLine":false,"DefaultValue":"surviveandbuild","EnumValues":{"surviveandbuild":"Survive and Build","exploration":"Exploration","wildernesssurvival":"Wilderness Survival","creativebuilding":"Creative Building"}}, + {"DisplayName":"Nimbus Server ID","Category":"Nimbus Backend:share","Subcategory":"Connection:dns:1","Description":"Unique ID that must exactly match this backend's key in the Proxy Backend Servers map.","Keywords":"nimbus,id","FieldName":"NimbusServerId","InputType":"text","ParamFieldName":"$.ServerId","IncludeInCommandLine":false,"Required":true,"DefaultValue":"","Placeholder":"hub","EnumValues":{}}, + {"DisplayName":"Nimbus Display Name","Category":"Nimbus Backend:share","Subcategory":"Connection:dns:1","Description":"Friendly name for this backend.","Keywords":"nimbus,name","FieldName":"NimbusDisplayName","InputType":"text","ParamFieldName":"$.DisplayName","IncludeInCommandLine":false,"DefaultValue":"","Placeholder":"Hub","EnumValues":{}}, + {"DisplayName":"Proxy Public Host","Category":"Nimbus Backend:share","Subcategory":"Connection:dns:1","Description":"Public hostname or IP players use for Nimbus Proxy, not this private backend.","Keywords":"proxy,host","FieldName":"NimbusPublicHost","InputType":"text","ParamFieldName":"$.PublicHost","IncludeInCommandLine":false,"Required":true,"DefaultValue":"","Placeholder":"play.example.com","EnumValues":{}}, + {"DisplayName":"Proxy Public Port","Category":"Nimbus Backend:share","Subcategory":"Connection:dns:1","Description":"Public player port of Nimbus Proxy.","Keywords":"proxy,port","FieldName":"NimbusPublicPort","InputType":"number","ParamFieldName":"$.PublicPort","IncludeInCommandLine":false,"DefaultValue":"42420","MinValue":1,"MaxValue":65535,"EnumValues":{}}, + {"DisplayName":"Nimbus Registry URL","Category":"Nimbus Backend:share","Subcategory":"Registry:hub:2","Description":"HTTP URL reachable from this backend for the Proxy's embedded Registry or the optional standalone Registry.","Keywords":"registry,url","FieldName":"NimbusRegistryUrl","InputType":"text","ParamFieldName":"$.RegistryUrl","IncludeInCommandLine":false,"Required":true,"DefaultValue":"","Placeholder":"http://proxy-host:8765","EnumValues":{}}, + {"DisplayName":"Nimbus Shared Secret","Category":"Nimbus Backend:share","Subcategory":"Registry:hub:2","Description":"Copy the generated shared secret from the Proxy or standalone Registry. Backends never generate it.","Keywords":"registry,secret","FieldName":"NimbusSharedSecret","InputType":"password","ParamFieldName":"$.SharedSecret","IncludeInCommandLine":false,"Required":true,"DefaultValue":"","EnumValues":{}}, + {"DisplayName":"Maintenance Mode","Category":"Nimbus Backend:share","Subcategory":"Routing:swap_horiz:3","Description":"Keep this backend online but remove it from normal routing.","Keywords":"maintenance,routing","FieldName":"NimbusMaintenance","InputType":"checkbox","ParamFieldName":"$.Maintenance","IncludeInCommandLine":false,"DefaultValue":"false","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Allow Player Server Command","Category":"Nimbus Backend:share","Subcategory":"Routing:swap_horiz:3","Description":"Allow players to use Nimbus server-switch commands.","Keywords":"server,command","FieldName":"NimbusAllowPlayerServerCommand","InputType":"checkbox","ParamFieldName":"$.AllowPlayerServerCommand","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Anonymous Stratum Statistics","Category":"Stratum:security","Subcategory":"Privacy:visibility:1","Description":"Send Stratum's anonymous version and player-count statistics.","Keywords":"stratum,statistics","FieldName":"StratumServerStats","InputType":"checkbox","ParamFieldName":"$.ServerStats.Enabled","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Stratum Release Tag","Category":"Updates:update","Subcategory":"Version:verified_user:1","Description":"Optional exact Stratum release tag. Leave blank for the latest stable release; the release selects the compatible Vintage Story version.","Keywords":"stratum,version","FieldName":"StratumVersionTag","InputType":"text","ParamFieldName":"StratumVersionTag","IncludeInCommandLine":false,"DefaultValue":"","Placeholder":"v1.22.6-stratum.2","EnumValues":{}}, + {"DisplayName":"Nimbus Release Tag","Category":"Updates:update","Subcategory":"Version:verified_user:1","Description":"Optional exact Nimbus release tag. Leave blank for the latest stable release.","Keywords":"nimbus,version","FieldName":"NimbusVersionTag","InputType":"text","ParamFieldName":"NimbusVersionTag","IncludeInCommandLine":false,"DefaultValue":"","Placeholder":"v0.5.0","EnumValues":{}} ] diff --git a/vintage-story-stratummetaconfig.json b/vintage-story-stratummetaconfig.json index be40a6ee2..df80c95c2 100644 --- a/vintage-story-stratummetaconfig.json +++ b/vintage-story-stratummetaconfig.json @@ -1,22 +1,5 @@ [ - { - "ConfigFile": "data/serverconfig.json", - "AutoMap": true, - "ConfigType": "json" - }, - { - "ConfigFile": "data/stratum.json", - "AutoMap": true, - "ConfigType": "json" - }, - { - "ConfigFile": "data/stratum-commands.json", - "AutoMap": true, - "ConfigType": "json" - }, - { - "ConfigFile": "data/stratum-performance.json", - "AutoMap": true, - "ConfigType": "json" - } + {"ConfigFile":"data/serverconfig.json","AutoMap":true,"ConfigType":"json"}, + {"ConfigFile":"data/stratum.json","AutoMap":true,"ConfigType":"json"}, + {"ConfigFile":"data/ModConfig/nimbus-server.json","AutoMap":true,"ConfigType":"json"} ] diff --git a/vintage-story-stratumports.json b/vintage-story-stratumports.json index a9f7d0f4b..0a83adc08 100644 --- a/vintage-story-stratumports.json +++ b/vintage-story-stratumports.json @@ -1,9 +1,9 @@ [ - { - "Protocol": "Both", - "Name": "Server Port", - "Description": "Vintage Story game traffic. On a Nimbus network this is the port the PROXY dials, not the port players use - keep it unique per backend instance and do not expose it publicly.", - "Port": 42420, - "Ref": "ServerPort" - } + { + "Protocol": "Both", + "Name": "Server Port", + "Description": "Private game port used by Nimbus Proxy to reach this backend", + "Port": 42420, + "Ref": "ServerPort" + } ] diff --git a/vintage-story-stratumupdates.json b/vintage-story-stratumupdates.json index 9f95adcc8..a09f94288 100644 --- a/vintage-story-stratumupdates.json +++ b/vintage-story-stratumupdates.json @@ -1,247 +1,110 @@ [ - { - "UpdateStageName": "Create server directory", - "UpdateSourcePlatform": "All", - "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullRootDir}}server", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Create dotnet directory", - "UpdateSourcePlatform": "All", - "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullRootDir}}dotnet", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Create data directory", - "UpdateSourcePlatform": "All", - "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullRootDir}}data", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Create Mods directory", - "UpdateSourcePlatform": "All", - "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullRootDir}}data/Mods", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Create ModConfig directory", - "UpdateSourcePlatform": "All", - "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullRootDir}}data/ModConfig", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Create scripts directory", - "UpdateSourcePlatform": "All", - "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullRootDir}}scripts", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Write Stratum installer script (Linux)", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}scripts/install-stratum.sh", - "UpdateSourceData": "#!/usr/bin/env bash\n# Generated by the AMP \"Vintage Story (Stratum + Nimbus)\" template.\n# Resolves and installs a Stratum release. The release tag pins the Vintage Story\n# version (tags look like v1.22.6-stratum.2); Stratum then downloads the matching\n# vanilla server assets itself on the next start or during the prepare stage.\nset -euo pipefail\n\nroot=\"${1:?root directory required}\"\ncd \"$root\"\nmkdir -p server\n\nrepo=\"StratumServer/Stratum\"\nrid=\"linux-x64\"\nhdr=(-H \"User-Agent: AMP-Stratum-Template\" -H \"Accept: application/vnd.github+json\")\nif [ -n \"${GITHUB_TOKEN:-}\" ]; then hdr+=(-H \"Authorization: Bearer ${GITHUB_TOKEN}\"); fi\n\nfor tool in curl unzip jq; do\n command -v \"$tool\" >/dev/null 2>&1 || { echo \"[AMP] $tool is required but not installed\" >&2; exit 1; }\ndone\n\ntag=\"$(printf '%s' \"${STRATUM_TAG:-}\" | tr -d '[:space:]')\"\nif [ -z \"$tag\" ]; then\n echo \"[AMP] resolving Stratum release (channel=${STRATUM_CHANNEL:-stable} gameVersion=${STRATUM_GAMEVER:-latest})\"\n json=\"$(curl -fsSL \"${hdr[@]}\" \"https://api.github.com/repos/${repo}/releases?per_page=100\")\"\n filter='.[] | select(.draft == false)'\n if [ \"${STRATUM_CHANNEL:-stable}\" != \"prerelease\" ]; then\n filter=\"${filter} | select(.prerelease == false)\"\n fi\n if [ -n \"${STRATUM_GAMEVER:-}\" ]; then\n filter=\"${filter} | select(.tag_name | startswith(\\\"v${STRATUM_GAMEVER}-stratum.\\\"))\"\n fi\n tag=\"$(printf '%s' \"$json\" | jq -r \"[ ${filter} ] | .[0].tag_name // empty\")\"\nfi\n\nif [ -z \"$tag\" ]; then\n echo \"[AMP] no Stratum release matched channel=${STRATUM_CHANNEL:-stable} gameVersion=${STRATUM_GAMEVER:-}\" >&2\n exit 1\nfi\n\nversion=\"${tag#v}\"\ngamever=\"${version%%-stratum.*}\"\nasset=\"stratum-${version}-${rid}.zip\"\nmarker=\"server/.amp-stratum-release\"\n\necho \"[AMP] Stratum ${version} selected (Vintage Story ${gamever})\"\n\nif [ -f \"$marker\" ] && [ \"$(cat \"$marker\")\" = \"$tag\" ] && [ -x server/StratumServer ]; then\n echo \"[AMP] already on ${tag}; nothing to download\"\n exit 0\nfi\n\nurl=\"https://github.com/${repo}/releases/download/${tag}/${asset}\"\necho \"[AMP] downloading ${url}\"\ncurl -fL --retry 3 -o stratum-release.zip \"$url\"\nunzip -qo stratum-release.zip -d server\nrm -f stratum-release.zip\nchmod +x server/StratumServer\nprintf '%s' \"$tag\" > \"$marker\"\nprintf '%s' \"$gamever\" > server/.amp-stratum-gameversion\necho \"[AMP] installed Stratum ${tag} into ${root}server\"\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, - { - "UpdateStageName": "Write Stratum installer script (Windows)", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}scripts/install-stratum.ps1", - "UpdateSourceData": "# Generated by the AMP \"Vintage Story (Stratum + Nimbus)\" template.\nparam([Parameter(Mandatory = $true)][string]$Root)\n\n$ErrorActionPreference = 'Stop'\n$ProgressPreference = 'SilentlyContinue'\n[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n\n$repo = 'StratumServer/Stratum'\n$rid = 'win-x64'\n$serverDir = Join-Path $Root 'server'\nNew-Item -ItemType Directory -Force -Path $serverDir | Out-Null\n\n$headers = @{ 'User-Agent' = 'AMP-Stratum-Template'; 'Accept' = 'application/vnd.github+json' }\nif ($env:GITHUB_TOKEN) { $headers['Authorization'] = \"Bearer $($env:GITHUB_TOKEN)\" }\n\nif ($env:STRATUM_TAG) { $tag = $env:STRATUM_TAG.Trim() } else { $tag = '' }\n\nif ($tag -eq '') {\n $channel = if ($env:STRATUM_CHANNEL) { $env:STRATUM_CHANNEL } else { 'stable' }\n $gameVer = if ($env:STRATUM_GAMEVER) { $env:STRATUM_GAMEVER.Trim() } else { '' }\n Write-Host \"[AMP] resolving Stratum release (channel=$channel gameVersion=$(if ($gameVer) { $gameVer } else { 'latest' }))\"\n $releases = Invoke-RestMethod -Headers $headers -Uri \"https://api.github.com/repos/$repo/releases?per_page=100\"\n $candidates = @($releases | Where-Object { -not $_.draft })\n if ($channel -ne 'prerelease') { $candidates = @($candidates | Where-Object { -not $_.prerelease }) }\n if ($gameVer -ne '') { $candidates = @($candidates | Where-Object { $_.tag_name.StartsWith(\"v$gameVer-stratum.\") }) }\n if ($candidates.Count -eq 0) { throw \"No Stratum release matched channel=$channel gameVersion=$gameVer\" }\n $tag = $candidates[0].tag_name\n}\n\n$version = $tag.TrimStart('v')\n$gamever = ($version -split '-stratum\\.')[0]\n$asset = \"stratum-$version-$rid.zip\"\n$marker = Join-Path $serverDir '.amp-stratum-release'\n\nWrite-Host \"[AMP] Stratum $version selected (Vintage Story $gamever)\"\n\nif ((Test-Path $marker) -and ((Get-Content $marker -Raw).Trim() -eq $tag) -and (Test-Path (Join-Path $serverDir 'StratumServer.exe'))) {\n Write-Host \"[AMP] already on $tag; nothing to download\"\n exit 0\n}\n\n$zip = Join-Path $Root 'stratum-release.zip'\n$url = \"https://github.com/$repo/releases/download/$tag/$asset\"\nWrite-Host \"[AMP] downloading $url\"\nInvoke-WebRequest -UseBasicParsing -Uri $url -OutFile $zip\nExpand-Archive -Path $zip -DestinationPath $serverDir -Force\nRemove-Item $zip -Force\nSet-Content -Path $marker -Value $tag -NoNewline\nSet-Content -Path (Join-Path $serverDir '.amp-stratum-gameversion') -Value $gamever -NoNewline\nWrite-Host \"[AMP] installed Stratum $tag into $serverDir\"\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, - { - "UpdateStageName": "Write Nimbus mod installer script (Linux)", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}scripts/install-nimbus-mod.sh", - "UpdateSourceData": "#!/usr/bin/env bash\n# Generated by the AMP \"Vintage Story (Stratum + Nimbus)\" template.\n# Installs Nimbus.ServerMod into data/Mods so this backend can join a Nimbus network.\nset -euo pipefail\n\nroot=\"${1:?root directory required}\"\ncd \"$root\"\n\nistrue() { [ \"$(printf '%s' \"${1:-}\" | tr '[:upper:]' '[:lower:]')\" = \"true\" ]; }\nif ! istrue \"${NIMBUS_INSTALL:-true}\"; then\n echo \"[AMP] Nimbus server mod installation is disabled\"\n exit 0\nfi\n\nrepo=\"StratumServer/Nimbus\"\nhdr=(-H \"User-Agent: AMP-Stratum-Template\" -H \"Accept: application/vnd.github+json\")\nif [ -n \"${GITHUB_TOKEN:-}\" ]; then hdr+=(-H \"Authorization: Bearer ${GITHUB_TOKEN}\"); fi\n\nfor tool in curl unzip jq; do\n command -v \"$tool\" >/dev/null 2>&1 || { echo \"[AMP] $tool is required but not installed\" >&2; exit 1; }\ndone\n\ntag=\"$(printf '%s' \"${NIMBUS_MOD_VERSION:-}\" | tr -d '[:space:]')\"\nif [ -z \"$tag\" ]; then\n json=\"$(curl -fsSL \"${hdr[@]}\" \"https://api.github.com/repos/${repo}/releases?per_page=100\")\"\n filter='.[] | select(.draft == false)'\n if [ \"${NIMBUS_CHANNEL:-stable}\" != \"prerelease\" ]; then\n filter=\"${filter} | select(.prerelease == false)\"\n fi\n tag=\"$(printf '%s' \"$json\" | jq -r \"[ ${filter} ] | .[0].tag_name // empty\")\"\nfi\n[ -n \"$tag\" ] || { echo \"[AMP] no Nimbus release found\" >&2; exit 1; }\ncase \"$tag\" in v*) ;; *) tag=\"v${tag}\";; esac\n\nmkdir -p data/Mods data/ModConfig\nmarker=\"data/Mods/Nimbus.ServerMod/.amp-nimbus-release\"\nif [ -f \"$marker\" ] && [ \"$(cat \"$marker\")\" = \"$tag\" ]; then\n echo \"[AMP] Nimbus server mod already on ${tag}\"\n exit 0\nfi\n\nurl=\"https://github.com/${repo}/releases/download/${tag}/Nimbus.ServerMod-${tag}.zip\"\necho \"[AMP] downloading ${url}\"\ncurl -fL --retry 3 -o nimbus-mod.zip \"$url\"\nrm -rf data/Mods/Nimbus.ServerMod\nmkdir -p data/Mods/Nimbus.ServerMod\nunzip -qo nimbus-mod.zip -d data/Mods/Nimbus.ServerMod\nrm -f nimbus-mod.zip\nprintf '%s' \"$tag\" > \"$marker\"\necho \"[AMP] installed Nimbus server mod ${tag} into ${root}data/Mods/Nimbus.ServerMod\"\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, - { - "UpdateStageName": "Write Nimbus mod installer script (Windows)", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}scripts/install-nimbus-mod.ps1", - "UpdateSourceData": "# Generated by the AMP \"Vintage Story (Stratum + Nimbus)\" template.\nparam([Parameter(Mandatory = $true)][string]$Root)\n\n$ErrorActionPreference = 'Stop'\n$ProgressPreference = 'SilentlyContinue'\n[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n\nif ($env:NIMBUS_INSTALL -and $env:NIMBUS_INSTALL.Trim().ToLowerInvariant() -ne 'true') {\n Write-Host '[AMP] Nimbus server mod installation is disabled'\n exit 0\n}\n\n$repo = 'StratumServer/Nimbus'\n$headers = @{ 'User-Agent' = 'AMP-Stratum-Template'; 'Accept' = 'application/vnd.github+json' }\nif ($env:GITHUB_TOKEN) { $headers['Authorization'] = \"Bearer $($env:GITHUB_TOKEN)\" }\n\n$tag = if ($env:NIMBUS_MOD_VERSION) { $env:NIMBUS_MOD_VERSION.Trim() } else { '' }\nif ($tag -eq '') {\n $channel = if ($env:NIMBUS_CHANNEL) { $env:NIMBUS_CHANNEL } else { 'stable' }\n $releases = Invoke-RestMethod -Headers $headers -Uri \"https://api.github.com/repos/$repo/releases?per_page=100\"\n $candidates = @($releases | Where-Object { -not $_.draft })\n if ($channel -ne 'prerelease') { $candidates = @($candidates | Where-Object { -not $_.prerelease }) }\n if ($candidates.Count -eq 0) { throw 'No Nimbus release found' }\n $tag = $candidates[0].tag_name\n}\nif (-not $tag.StartsWith('v')) { $tag = \"v$tag\" }\n\n$modDir = Join-Path $Root 'data\\Mods\\Nimbus.ServerMod'\nNew-Item -ItemType Directory -Force -Path (Join-Path $Root 'data\\ModConfig') | Out-Null\n$marker = Join-Path $modDir '.amp-nimbus-release'\nif ((Test-Path $marker) -and ((Get-Content $marker -Raw).Trim() -eq $tag)) {\n Write-Host \"[AMP] Nimbus server mod already on $tag\"\n exit 0\n}\n\n$zip = Join-Path $Root 'nimbus-mod.zip'\n$url = \"https://github.com/$repo/releases/download/$tag/Nimbus.ServerMod-$tag.zip\"\nWrite-Host \"[AMP] downloading $url\"\nInvoke-WebRequest -UseBasicParsing -Uri $url -OutFile $zip\nif (Test-Path $modDir) { Remove-Item $modDir -Recurse -Force }\nNew-Item -ItemType Directory -Force -Path $modDir | Out-Null\nExpand-Archive -Path $zip -DestinationPath $modDir -Force\nRemove-Item $zip -Force\nSet-Content -Path $marker -Value $tag -NoNewline\nWrite-Host \"[AMP] installed Nimbus server mod $tag into $modDir\"\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, - { - "UpdateStageName": "Write savegame path repair script (Linux)", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}scripts/fix-serverconfig.sh", - "UpdateSourceData": "#!/usr/bin/env bash\n# Generated by the AMP \"Vintage Story (Stratum + Nimbus)\" template.\n# Repairs WorldConfig.SaveFileLocation in data/serverconfig.json before every start.\n# Vintage Story stores an absolute path to the .vcdbs world file in that key and never\n# recalculates it, so an empty, missing or stale value makes the server abort with\n# \"Unable to open or create savegame\". This script puts a valid path back without\n# touching or reformatting any other part of the file.\nset -euo pipefail\n\ndata=\"${1:?data directory required}\"\ndata=\"${data%/}\"\ncfg=\"$data/serverconfig.json\"\n\n[ -f \"$cfg\" ] || exit 0\n\nsaves=\"$data/Saves\"\ndesired=\"$saves/default.vcdbs\"\nif [ -d \"$saves\" ] && [ ! -f \"$desired\" ]; then\n found=\"\"\n count=0\n for f in \"$saves\"/*.vcdbs; do\n [ -f \"$f\" ] || continue\n found=\"$f\"\n count=$((count + 1))\n done\n if [ \"$count\" = \"1\" ]; then\n desired=\"$found\"\n fi\nfi\n\nneed=0\nif ! grep -q '\"SaveFileLocation\"' \"$cfg\"; then\n need=2\nelse\n cur=$(sed -n 's|.*\"SaveFileLocation\"[[:space:]]*:[[:space:]]*\"\\(.*\\)\".*|\\1|p' \"$cfg\" | head -n 1)\n if [ -z \"$cur\" ]; then\n need=1\n elif [ ! -d \"$(dirname \"$cur\")\" ]; then\n echo \"[AMP] serverconfig.json points at $cur but that folder does not exist on this system\"\n need=1\n fi\nfi\n\nif [ \"$need\" = \"0\" ]; then\n exit 0\nfi\n\nmkdir -p \"$saves\"\nesc=$(printf '%s' \"$desired\" | sed -e 's/[\\\\&|]/\\\\&/g')\n\nif [ \"$need\" = \"1\" ]; then\n sed -i \"s|\\\"SaveFileLocation\\\"[[:space:]]*:[[:space:]]*\\\"[^\\\"]*\\\"|\\\"SaveFileLocation\\\": \\\"$esc\\\"|\" \"$cfg\"\nelif grep -q '\"WorldConfig\"' \"$cfg\"; then\n sed -i \"s|\\\"WorldConfig\\\"[[:space:]]*:[[:space:]]*{|&\\\"SaveFileLocation\\\": \\\"$esc\\\",|\" \"$cfg\"\nelse\n echo \"[AMP] WARNING: no WorldConfig section in $cfg, cannot repair the save file location\" >&2\n exit 0\nfi\n\necho \"[AMP] repaired SaveFileLocation in serverconfig.json -> $desired\"\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, - { - "UpdateStageName": "Write savegame path repair script (Windows)", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}scripts/fix-serverconfig.ps1", - "UpdateSourceData": "# Generated by the AMP \"Vintage Story (Stratum + Nimbus)\" template.\n# Repairs WorldConfig.SaveFileLocation in data\\serverconfig.json before every start.\n# Vintage Story stores an absolute path to the .vcdbs world file in that key and never\n# recalculates it, so an empty, missing or stale value makes the server abort with\n# \"Unable to open or create savegame\". This script puts a valid path back without\n# touching or reformatting any other part of the file.\nparam([Parameter(Mandatory = $true)][string]$DataDir)\n\n$ErrorActionPreference = 'Stop'\n\n$DataDir = $DataDir.TrimEnd('\\', '/')\n$cfg = Join-Path $DataDir 'serverconfig.json'\nif (-not (Test-Path -LiteralPath $cfg)) { exit 0 }\n\n$saves = Join-Path $DataDir 'Saves'\n$desired = Join-Path $saves 'default.vcdbs'\nif ((Test-Path -LiteralPath $saves) -and -not (Test-Path -LiteralPath $desired)) {\n $found = @(Get-ChildItem -LiteralPath $saves -Filter '*.vcdbs' -File -ErrorAction SilentlyContinue)\n if ($found.Count -eq 1) { $desired = $found[0].FullName }\n}\n\n$text = [IO.File]::ReadAllText($cfg)\n$rx = '\"SaveFileLocation\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.)*)\"'\n$m = [regex]::Match($text, $rx)\n\n$need = 0\nif (-not $m.Success) {\n $need = 2\n}\nelse {\n $cur = $m.Groups[1].Value -replace '\\\\\\\\', '\\'\n if ([string]::IsNullOrWhiteSpace($cur)) {\n $need = 1\n }\n else {\n $parent = Split-Path -Path $cur -Parent\n if ([string]::IsNullOrWhiteSpace($parent) -or -not (Test-Path -LiteralPath $parent)) {\n Write-Output \"[AMP] serverconfig.json points at $cur but that folder does not exist on this system\"\n $need = 1\n }\n }\n}\n\nif ($need -eq 0) { exit 0 }\n\nNew-Item -ItemType Directory -Path $saves -Force | Out-Null\n$bs = [string][char]92\n$dl = [string][char]36\n$esc = $desired.Replace($bs, $bs + $bs)\n$rep = $esc.Replace($dl, $dl + $dl)\n\nif ($need -eq 1) {\n $text = [regex]::new($rx).Replace($text, ('\"SaveFileLocation\": \"' + $rep + '\"'), 1)\n}\nelseif ($text -match '\"WorldConfig\"\\s*:\\s*\\{') {\n $text = [regex]::new('\"WorldConfig\"\\s*:\\s*\\{').Replace($text, ('$0\"SaveFileLocation\": \"' + $rep + '\",'), 1)\n}\nelse {\n Write-Warning \"[AMP] no WorldConfig section in $cfg, cannot repair the save file location\"\n exit 0\n}\n\n[IO.File]::WriteAllText($cfg, $text, (New-Object Text.UTF8Encoding $false))\nWrite-Output \"[AMP] repaired SaveFileLocation in serverconfig.json -> $desired\"\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, - { - "UpdateStageName": "Write Nimbus backend config script (Linux)", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}scripts/write-nimbus-server.sh", - "UpdateSourceData": "#!/usr/bin/env bash\n# Generated by the AMP \"Vintage Story (Stratum + Nimbus)\" template.\n# Renders data/ModConfig/nimbus-server.json from the instance settings before every start.\n# Do not edit: it is overwritten on every update. Set \"Let AMP Manage nimbus-server.json\"\n# to false if you would rather hand-edit the JSON.\nset -euo pipefail\n\ntarget=\"${1:?target path required}\"\nmkdir -p \"$(dirname \"$target\")\"\n\nistrue() { [ \"$(printf '%s' \"${1:-}\" | tr '[:upper:]' '[:lower:]')\" = \"true\" ]; }\n\nif ! istrue \"${NIMBUS_WRITE_CONFIG:-true}\"; then\n echo \"[AMP] Nimbus config management is off; leaving $target as it is\"\n exit 0\nfi\n\nif ! command -v jq >/dev/null 2>&1; then\n echo \"[AMP] jq is required to render $target but was not found on this system\" >&2\n exit 1\nfi\n\nport=\"${NIMBUS_PUBLIC_PORT:-0}\"\ncase \"$port\" in ''|0|*[!0-9]*) port=\"${NIMBUS_FALLBACK_PORT:-42420}\";; esac\nhost=\"${NIMBUS_PUBLIC_HOST:-}\"\n[ -n \"$host\" ] || host=\"127.0.0.1\"\n\nbool() { if istrue \"${1:-}\"; then printf 'true'; else printf 'false'; fi; }\n\njq -n \\\n --arg enabled \"$(bool \"${NIMBUS_ENABLED:-true}\")\" \\\n --arg id \"${NIMBUS_SERVER_ID:-}\" \\\n --arg dname \"${NIMBUS_DISPLAY_NAME:-}\" \\\n --arg host \"$host\" \\\n --arg port \"$port\" \\\n --arg tags \"${NIMBUS_TAGS:-}\" \\\n --arg regurl \"${NIMBUS_REGISTRY_URL:-}\" \\\n --arg secret \"${NIMBUS_SHARED_SECRET:-}\" \\\n --arg hb \"${NIMBUS_HEARTBEAT:-5}\" \\\n --arg httpto \"${NIMBUS_HTTP_TIMEOUT:-5}\" \\\n --arg maint \"$(bool \"${NIMBUS_MAINTENANCE:-false}\")\" \\\n --arg resv \"$(bool \"${NIMBUS_RESERVATION_REQUIRED:-true}\")\" \\\n --arg failclosed \"$(bool \"${NIMBUS_FAIL_CLOSED:-false}\")\" \\\n --arg allowcmd \"$(bool \"${NIMBUS_ALLOW_SERVER_COMMAND:-true}\")\" \\\n --arg tmode \"${NIMBUS_TRANSFER_MODE:-redirect}\" \\\n --arg sack \"${NIMBUS_SEAMLESS_ACK:-8}\" \\\n --arg shortcuts \"${NIMBUS_SHORTCUTS:-}\" \\\n '{\n Enabled: ($enabled == \"true\"),\n ServerId: $id,\n DisplayName: $dname,\n PublicHost: $host,\n PublicPort: ($port | tonumber),\n Tags: ($tags | split(\",\") | map(gsub(\"^\\\\s+|\\\\s+$\"; \"\")) | map(select(length > 0))),\n RegistryUrl: $regurl,\n SharedSecret: $secret,\n HeartbeatIntervalSeconds: ($hb | tonumber),\n RegistryHttpTimeoutSeconds: ($httpto | tonumber),\n Maintenance: ($maint == \"true\"),\n ReservationRequired: ($resv == \"true\"),\n FailClosedWhenRegistryUnreachable: ($failclosed == \"true\"),\n AllowPlayerServerCommand: ($allowcmd == \"true\"),\n TransferMode: $tmode,\n SeamlessPrepareAckTimeoutSeconds: ($sack | tonumber),\n ShortcutCommands: ($shortcuts | split(\";\") | map(select(length > 0)) | map(\n (split(\"@\")) as $parts |\n (($parts[0]) | split(\"=\")) as $kv |\n {\n Name: ($kv[0] | gsub(\"^\\\\s+|\\\\s+$\"; \"\") | ltrimstr(\"/\")),\n Targets: ((($kv[1]) // \"\") | split(\"|\") | map(gsub(\"^\\\\s+|\\\\s+$\"; \"\")) | map(select(length > 0))),\n Privilege: ((($parts[1]) // \"chat\") | gsub(\"^\\\\s+|\\\\s+$\"; \"\")),\n Description: \"\"\n }) | map(select((.Name | length) > 0 and (.Targets | length) > 0)))\n }' > \"$target.amptmp\"\n\nmv \"$target.amptmp\" \"$target\"\necho \"[AMP] wrote $target serverId=${NIMBUS_SERVER_ID:-} advertised=${host}:${port} registry=${NIMBUS_REGISTRY_URL:-} transferMode=${NIMBUS_TRANSFER_MODE:-redirect}\"\nif [ -z \"${NIMBUS_SHARED_SECRET:-}\" ]; then\n echo \"[AMP] WARNING: no registry shared secret is set, so heartbeats will be rejected. Copy the secret from the proxy or registry into this instance's Nimbus settings.\"\nfi\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, - { - "UpdateStageName": "Write Nimbus backend config script (Windows)", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}scripts/write-nimbus-server.ps1", - "UpdateSourceData": "# Generated by the AMP \"Vintage Story (Stratum + Nimbus)\" template.\n# Renders data\\ModConfig\\nimbus-server.json from the instance settings before every start.\nparam([Parameter(Mandatory = $true)][string]$Target)\n\n$ErrorActionPreference = 'Stop'\n\nfunction Get-Env([string]$name, [string]$fallback = '') {\n $v = [Environment]::GetEnvironmentVariable($name)\n if ([string]::IsNullOrWhiteSpace($v)) { return $fallback }\n return $v\n}\nfunction Get-Bool([string]$name, [bool]$fallback) {\n $v = Get-Env $name ''\n if ($v -eq '') { return $fallback }\n return ($v.Trim().ToLowerInvariant() -eq 'true')\n}\nfunction Split-List([string]$value, [string]$sep) {\n if ([string]::IsNullOrWhiteSpace($value)) { return @() }\n return @($value.Split($sep) | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne '' })\n}\n\nif (-not (Get-Bool 'NIMBUS_WRITE_CONFIG' $true)) {\n Write-Host \"[AMP] Nimbus config management is off; leaving $Target as it is\"\n exit 0\n}\n\n$dir = Split-Path -Parent $Target\nif ($dir -and -not (Test-Path $dir)) { New-Item -ItemType Directory -Force -Path $dir | Out-Null }\n\n$port = 0\n[void][int]::TryParse((Get-Env 'NIMBUS_PUBLIC_PORT' '0'), [ref]$port)\nif ($port -le 0) { [void][int]::TryParse((Get-Env 'NIMBUS_FALLBACK_PORT' '42420'), [ref]$port) }\nif ($port -le 0) { $port = 42420 }\n\n$host_ = Get-Env 'NIMBUS_PUBLIC_HOST' '127.0.0.1'\n\n$shortcuts = @()\nforeach ($raw in (Split-List (Get-Env 'NIMBUS_SHORTCUTS' '') ';')) {\n $privilege = 'chat'\n $body = $raw\n $at = $raw.LastIndexOf('@')\n if ($at -ge 0) {\n $body = $raw.Substring(0, $at)\n $privilege = $raw.Substring($at + 1).Trim()\n if ($privilege -eq '') { $privilege = 'chat' }\n }\n $kv = $body.Split('=', 2)\n $name = $kv[0].Trim().TrimStart('/')\n $targets = @()\n if ($kv.Length -gt 1) { $targets = Split-List $kv[1] '|' }\n if ($name -ne '' -and $targets.Count -gt 0) {\n $shortcuts += [ordered]@{ Name = $name; Targets = $targets; Privilege = $privilege; Description = '' }\n }\n}\n\n# Windows PowerShell 5.1 turns single element arrays into scalars when it converts to\n# JSON, which would produce \"Targets\": \"hub\" instead of a list, so the JSON is written by\n# hand here. Keep it that way.\nfunction Esc([string]$s) {\n if ($null -eq $s) { return '\"\"' }\n $s = $s.Replace('\\', '\\\\').Replace('\"', '\\\"').Replace(\"`r\", '\\r').Replace(\"`n\", '\\n').Replace(\"`t\", '\\t')\n return '\"' + $s + '\"'\n}\nfunction JList($items) {\n if (-not $items -or @($items).Count -eq 0) { return '[]' }\n return '[' + ((@($items) | ForEach-Object { Esc $_ }) -join ', ') + ']'\n}\nfunction JBool([bool]$b) { if ($b) { return 'true' } else { return 'false' } }\n\n$serverId = Get-Env 'NIMBUS_SERVER_ID' ''\n$registryUrl = Get-Env 'NIMBUS_REGISTRY_URL' ''\n$transferMode = Get-Env 'NIMBUS_TRANSFER_MODE' 'redirect'\n$secret = Get-Env 'NIMBUS_SHARED_SECRET' ''\n\n$sc = @()\nforeach ($s in $shortcuts) {\n $sc += @\"\n {\n \"Name\": $(Esc $s.Name),\n \"Targets\": $(JList $s.Targets),\n \"Privilege\": $(Esc $s.Privilege),\n \"Description\": \"\"\n }\n\"@\n}\n\n$json = @\"\n{\n \"Enabled\": $(JBool (Get-Bool 'NIMBUS_ENABLED' $true)),\n \"ServerId\": $(Esc $serverId),\n \"DisplayName\": $(Esc (Get-Env 'NIMBUS_DISPLAY_NAME' '')),\n \"PublicHost\": $(Esc $host_),\n \"PublicPort\": $port,\n \"Tags\": $(JList (Split-List (Get-Env 'NIMBUS_TAGS' '') ',')),\n \"RegistryUrl\": $(Esc $registryUrl),\n \"SharedSecret\": $(Esc $secret),\n \"HeartbeatIntervalSeconds\": $([int](Get-Env 'NIMBUS_HEARTBEAT' '5')),\n \"RegistryHttpTimeoutSeconds\": $([int](Get-Env 'NIMBUS_HTTP_TIMEOUT' '5')),\n \"Maintenance\": $(JBool (Get-Bool 'NIMBUS_MAINTENANCE' $false)),\n \"ReservationRequired\": $(JBool (Get-Bool 'NIMBUS_RESERVATION_REQUIRED' $true)),\n \"FailClosedWhenRegistryUnreachable\": $(JBool (Get-Bool 'NIMBUS_FAIL_CLOSED' $false)),\n \"AllowPlayerServerCommand\": $(JBool (Get-Bool 'NIMBUS_ALLOW_SERVER_COMMAND' $true)),\n \"TransferMode\": $(Esc $transferMode),\n \"SeamlessPrepareAckTimeoutSeconds\": $([int](Get-Env 'NIMBUS_SEAMLESS_ACK' '8')),\n \"ShortcutCommands\": [\n$($sc -join \",`r`n\")\n ]\n}\n\"@\n\n[IO.File]::WriteAllText($Target, $json, (New-Object Text.UTF8Encoding($false)))\nWrite-Host (\"[AMP] wrote {0} serverId={1} advertised={2}:{3} registry={4} transferMode={5}\" -f $Target, $serverId, $host_, $port, $registryUrl, $transferMode)\nif ([string]::IsNullOrWhiteSpace($secret)) {\n Write-Host \"[AMP] WARNING: no registry shared secret is set, so heartbeats will be rejected. Copy the secret from the proxy or registry into this instance's Nimbus settings.\"\n}\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, - { - "UpdateStageName": ".NET SDK Download", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "Executable", - "UpdateSourceArch": "x86_64", - "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"DotnetVersion=\\\"{{DotnetSDKVersion}}\\\"; cd \\\"{{$FullBaseDir}}\\\" && if [[ -x dotnet/dotnet ]]; then InstalledVersion=$(dotnet/dotnet --version | xargs); else InstalledVersion=\\\"\\\"; fi; if [[ -z \\\"$DotnetVersion\\\" ]]; then DotnetVersion=$(wget -qO- https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json | jq -r \\\".[\\\\\\\"latest-sdk\\\\\\\"]\\\"); fi; if [[ ! \\\"$DotnetVersion\\\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+$ ]]; then echo \\\"Invalid .NET SDK version format specified\\\" && exit 1; elif [[ \\\"$InstalledVersion\\\" == \\\"$DotnetVersion\\\" ]]; then echo \\\".NET SDK v$DotnetVersion already installed. Skipping\\\" && exit 0; else [[ -f dotnet.tar.gz ]] && rm -f dotnet.tar.gz >/dev/null 2>&1; wget -qO dotnet.tar.gz https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-linux-x64.tar.gz || { echo \\\"Download failed from the Microsoft CDN. This is a fault with the CDN, not AMP. Aborting\\\"; exit 1; }; rm -rf dotnet/* >/dev/null 2>&1 && tar -xzf dotnet.tar.gz -C dotnet >/dev/null 2>&1 && rm -f dotnet.tar.gz >/dev/null 2>&1 && echo \\\".NET SDK v$DotnetVersion downloaded\\\"; fi\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": ".NET SDK Download", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "Executable", - "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -Command \"$ProgressPreference='SilentlyContinue'; [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $DotnetVersion='{{DotnetSDKVersion}}'; Set-Location -Path '{{$FullBaseDir}}'; if (Test-Path 'dotnet/dotnet.exe') { $InstalledVersion = (& dotnet/dotnet.exe --version).Trim() } else { $InstalledVersion = '' }; if ( [string]::IsNullOrWhiteSpace($DotnetVersion) ) { $DotnetVersion=(Invoke-RestMethod -UseBasicParsing -Uri https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json).\\\"latest-sdk\\\" }; if ($DotnetVersion -notmatch '^\\d+\\.\\d+\\.\\d+$') { Write-Output \\\"Invalid .NET SDK version format specified\\\"; exit 1 } elseif ( $InstalledVersion -eq $DotnetVersion ) { Write-Output \\\".NET SDK v$DotnetVersion already installed. Skipping\\\"; exit 0 } else { if ( Test-Path dotnet.zip ) { Remove-Item dotnet.zip -Force -ErrorAction SilentlyContinue *> $null }; try { Invoke-WebRequest -UseBasicParsing -Uri https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-win-x64.zip -OutFile dotnet.zip -ErrorAction Stop } catch { Write-Output \\\"Download failed from the Microsoft CDN. This is a fault with the CDN, not AMP. Aborting\\\"; exit 1; }; Remove-Item -Path 'dotnet/*' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive -Path \\\"dotnet.zip\\\" -DestinationPath \\\"dotnet\\\" -Force *> $null; if ( Test-Path dotnet.zip ) { Remove-Item dotnet.zip -Force -ErrorAction SilentlyContinue *> $null }; Write-Output \\\".NET SDK v$DotnetVersion downloaded\\\" }\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Stratum Server Download", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "Executable", - "UpdateSourceArch": "x86_64", - "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"STRATUM_TAG='{{StratumVersionTag}}' STRATUM_CHANNEL='{{StratumReleaseChannel}}' STRATUM_GAMEVER='{{StratumGameVersion}}' GITHUB_TOKEN='{{StratumGitHubToken}}' bash '{{$FullRootDir}}scripts/install-stratum.sh' '{{$FullRootDir}}'\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Stratum Server Download", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "Executable", - "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$env:STRATUM_TAG='{{StratumVersionTag}}'; $env:STRATUM_CHANNEL='{{StratumReleaseChannel}}'; $env:STRATUM_GAMEVER='{{StratumGameVersion}}'; $env:GITHUB_TOKEN='{{StratumGitHubToken}}'; & '{{$FullRootDir}}scripts\\install-stratum.ps1' '{{$FullRootDir}}'\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Bootstrap Vintage Story Assets", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "Executable", - "UpdateSourceArch": "x86_64", - "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"export DOTNET_ROOT='{{$FullRootDir}}dotnet'; cd '{{$FullRootDir}}server' && ./StratumServer --stratum-prepare-only --stratum-no-banner --dataPath '{{$FullRootDir}}data'\"", - "UpdateSourceConditionSetting": "StratumRefreshVanilla", - "UpdateSourceConditionValue": "false", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Bootstrap Vintage Story Assets (forced refresh)", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "Executable", - "UpdateSourceArch": "x86_64", - "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"export DOTNET_ROOT='{{$FullRootDir}}dotnet'; cd '{{$FullRootDir}}server' && ./StratumServer --stratum-prepare-only --stratum-refresh --stratum-no-banner --dataPath '{{$FullRootDir}}data'\"", - "UpdateSourceConditionSetting": "StratumRefreshVanilla", - "UpdateSourceConditionValue": "true", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Bootstrap Vintage Story Assets", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "Executable", - "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -Command \"$env:DOTNET_ROOT='{{$FullRootDir}}dotnet'; Set-Location '{{$FullRootDir}}server'; & '.\\StratumServer.exe' --stratum-prepare-only --stratum-no-banner --dataPath '{{$FullRootDir}}data'\"", - "UpdateSourceConditionSetting": "StratumRefreshVanilla", - "UpdateSourceConditionValue": "false", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Bootstrap Vintage Story Assets (forced refresh)", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "Executable", - "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -Command \"$env:DOTNET_ROOT='{{$FullRootDir}}dotnet'; Set-Location '{{$FullRootDir}}server'; & '.\\StratumServer.exe' --stratum-prepare-only --stratum-refresh --stratum-no-banner --dataPath '{{$FullRootDir}}data'\"", - "UpdateSourceConditionSetting": "StratumRefreshVanilla", - "UpdateSourceConditionValue": "true", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Nimbus Server Mod Download", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "Executable", - "UpdateSourceArch": "x86_64", - "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"NIMBUS_INSTALL='{{NimbusInstall}}' NIMBUS_MOD_VERSION='{{NimbusModVersion}}' NIMBUS_CHANNEL='{{NimbusReleaseChannel}}' GITHUB_TOKEN='{{StratumGitHubToken}}' bash '{{$FullRootDir}}scripts/install-nimbus-mod.sh' '{{$FullRootDir}}'\"", - "UpdateSourceConditionSetting": "NimbusInstall", - "UpdateSourceConditionValue": "true", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Nimbus Server Mod Download", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "Executable", - "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$env:NIMBUS_INSTALL='{{NimbusInstall}}'; $env:NIMBUS_MOD_VERSION='{{NimbusModVersion}}'; $env:NIMBUS_CHANNEL='{{NimbusReleaseChannel}}'; $env:GITHUB_TOKEN='{{StratumGitHubToken}}'; & '{{$FullRootDir}}scripts\\install-nimbus-mod.ps1' '{{$FullRootDir}}'\"", - "UpdateSourceConditionSetting": "NimbusInstall", - "UpdateSourceConditionValue": "true", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Repair savegame path", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "Executable", - "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"bash '{{$FullRootDir}}scripts/fix-serverconfig.sh' '{{$FullRootDir}}data'\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Repair savegame path", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "Executable", - "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"& '{{$FullRootDir}}scripts\\fix-serverconfig.ps1' '{{$FullRootDir}}data'\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Start Server", - "UpdateSourcePlatform": "All", - "UpdateSource": "StartApplication", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Wait For Server Start", - "UpdateSourcePlatform": "All", - "UpdateSource": "WaitForStartupComplete", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Stop Server", - "UpdateSourcePlatform": "All", - "UpdateSource": "ShutdownApplication", - "SkipOnFailure": false - } + {"UpdateStageName":"Create server directory","UpdateSourcePlatform":"All","UpdateSource":"CreateDirectory","UpdateSourceArgs":"{{$FullRootDir}}server","SkipOnFailure":false}, + {"UpdateStageName":"Create data directory","UpdateSourcePlatform":"All","UpdateSource":"CreateDirectory","UpdateSourceArgs":"{{$FullRootDir}}data","SkipOnFailure":false}, + {"UpdateStageName":"Create Mods directory","UpdateSourcePlatform":"All","UpdateSource":"CreateDirectory","UpdateSourceArgs":"{{$FullRootDir}}data/Mods","SkipOnFailure":false}, + {"UpdateStageName":"Create ModConfig directory","UpdateSourcePlatform":"All","UpdateSource":"CreateDirectory","UpdateSourceArgs":"{{$FullRootDir}}data/ModConfig","SkipOnFailure":false}, + {"UpdateStageName":"Create dotnet directory","UpdateSourcePlatform":"All","UpdateSource":"CreateDirectory","UpdateSourceArgs":"{{$FullRootDir}}dotnet","SkipOnFailure":false}, + { + "UpdateStageName":"Install local .NET 10 runtime", + "UpdateSourcePlatform":"Linux", + "UpdateSourceArch":"x86_64", + "UpdateSource":"Executable", + "UpdateSourceData":"/bin/bash", + "UpdateSourceArgs":"-c \"set -euo pipefail; root='{{$FullRootDir}}'; if [ -x \\\"$root/dotnet/dotnet\\\" ] && \\\"$root/dotnet/dotnet\\\" --list-runtimes | grep -q '^Microsoft.NETCore.App 10\\.'; then echo '[AMP] .NET 10 runtime already installed'; else tmp=\\\"$(mktemp)\\\"; curl -fsSL https://dot.net/v1/dotnet-install.sh -o \\\"$tmp\\\"; bash \\\"$tmp\\\" --channel 10.0 --runtime dotnet --install-dir \\\"$root/dotnet\\\" --no-path; rm -f \\\"$tmp\\\"; fi\"", + "SkipOnFailure":false + }, + { + "UpdateStageName":"Install local .NET 10 runtime", + "UpdateSourcePlatform":"Windows", + "UpdateSource":"Executable", + "UpdateSourceData":"powershell.exe", + "UpdateSourceArgs":"-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference='Stop'; $root='{{$FullRootDir}}'; $dotnet=Join-Path $root 'dotnet\\dotnet.exe'; $ready=$false; if (Test-Path -LiteralPath $dotnet) { $ready=[bool]((& $dotnet --list-runtimes) -match '^Microsoft.NETCore.App 10\\.') }; if ($ready) { Write-Output '[AMP] .NET 10 runtime already installed' } else { $script=Join-Path $env:TEMP ('dotnet-install-'+[guid]::NewGuid().ToString('N')+'.ps1'); try { Invoke-WebRequest -UseBasicParsing -Uri https://dot.net/v1/dotnet-install.ps1 -OutFile $script; & $script -Channel 10.0 -Runtime dotnet -InstallDir (Join-Path $root 'dotnet') -NoPath } finally { Remove-Item -LiteralPath $script -Force -ErrorAction SilentlyContinue } }\"", + "SkipOnFailure":false + }, + { + "UpdateStageName":"Install Stratum release", + "UpdateSourcePlatform":"Linux", + "UpdateSourceArch":"x86_64", + "UpdateSource":"Executable", + "UpdateSourceData":"/bin/bash", + "UpdateSourceArgs":"-c \"set -euo pipefail; root='{{$FullRootDir}}'; tag='{{StratumVersionTag}}'; if [ -z \\\"$tag\\\" ]; then tag=\\\"$(curl -fsSL -H 'User-Agent: AMP-Clean-Template' https://api.github.com/repos/StratumServer/Stratum/releases/latest | jq -r .tag_name)\\\"; fi; case \\\"$tag\\\" in v*) ;; *) tag=\\\"v$tag\\\";; esac; version=\\\"${tag#v}\\\"; asset=\\\"stratum-${version}-linux-x64.zip\\\"; stage=\\\"$root/.amp-stratum-stage\\\"; archive=\\\"$root/.amp-stratum.zip\\\"; rm -rf \\\"$stage\\\"; mkdir -p \\\"$stage\\\"; curl -fL --retry 3 -o \\\"$archive\\\" \\\"https://github.com/StratumServer/Stratum/releases/download/$tag/$asset\\\"; unzip -q \\\"$archive\\\" -d \\\"$stage\\\"; rm -f \\\"$archive\\\"; test -x \\\"$stage/StratumServer\\\" || chmod +x \\\"$stage/StratumServer\\\"; test -x \\\"$stage/StratumServer\\\"; old=\\\"$root/.amp-stratum-old\\\"; rm -rf \\\"$old\\\"; if [ -d \\\"$root/server\\\" ]; then mv \\\"$root/server\\\" \\\"$old\\\"; fi; mv \\\"$stage\\\" \\\"$root/server\\\"; rm -rf \\\"$old\\\"; printf '%s' \\\"$tag\\\" > \\\"$root/server/.amp-stratum-release\\\"\"", + "SkipOnFailure":false + }, + { + "UpdateStageName":"Install Stratum release", + "UpdateSourcePlatform":"Windows", + "UpdateSource":"Executable", + "UpdateSourceData":"powershell.exe", + "UpdateSourceArgs":"-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference='Stop'; $ProgressPreference='SilentlyContinue'; $root='{{$FullRootDir}}'; $tag='{{StratumVersionTag}}'.Trim(); $headers=@{'User-Agent'='AMP-Clean-Template'}; if (-not $tag) { $tag=(Invoke-RestMethod -Headers $headers -Uri https://api.github.com/repos/StratumServer/Stratum/releases/latest).tag_name }; if (-not $tag.StartsWith('v')) { $tag='v'+$tag }; $version=$tag.TrimStart('v'); $asset='stratum-'+$version+'-win-x64.zip'; $stage=Join-Path $root '.amp-stratum-stage'; $archive=Join-Path $root '.amp-stratum.zip'; $server=Join-Path $root 'server'; $old=Join-Path $root '.amp-stratum-old'; Remove-Item -LiteralPath $stage,$old,$archive -Recurse -Force -ErrorAction SilentlyContinue; New-Item -ItemType Directory -Path $stage | Out-Null; Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri ('https://github.com/StratumServer/Stratum/releases/download/'+$tag+'/'+$asset) -OutFile $archive; Expand-Archive -LiteralPath $archive -DestinationPath $stage -Force; Remove-Item -LiteralPath $archive -Force; if (-not (Test-Path -LiteralPath (Join-Path $stage 'StratumServer.exe'))) { throw 'Stratum archive did not contain StratumServer.exe' }; if (Test-Path -LiteralPath $server) { Move-Item -LiteralPath $server -Destination $old }; try { Move-Item -LiteralPath $stage -Destination $server; Remove-Item -LiteralPath $old -Recurse -Force -ErrorAction SilentlyContinue } catch { if ((Test-Path -LiteralPath $old) -and -not (Test-Path -LiteralPath $server)) { Move-Item -LiteralPath $old -Destination $server }; throw }; [IO.File]::WriteAllText((Join-Path $server '.amp-stratum-release'),$tag,(New-Object Text.UTF8Encoding $false))\"", + "SkipOnFailure":false + }, + { + "UpdateStageName":"Prepare compatible Vintage Story server assets", + "UpdateSourcePlatform":"Linux", + "UpdateSourceArch":"x86_64", + "UpdateSource":"Executable", + "UpdateSourceData":"/bin/bash", + "UpdateSourceArgs":"-c \"set -euo pipefail; export DOTNET_ROOT='{{$FullRootDir}}dotnet'; cd '{{$FullRootDir}}server'; ./StratumServer --stratum-prepare-only --stratum-no-banner --dataPath '../data'\"", + "SkipOnFailure":false + }, + { + "UpdateStageName":"Prepare compatible Vintage Story server assets", + "UpdateSourcePlatform":"Windows", + "UpdateSource":"Executable", + "UpdateSourceData":"powershell.exe", + "UpdateSourceArgs":"-NoProfile -Command \"$env:DOTNET_ROOT='{{$FullRootDir}}dotnet'; Set-Location '{{$FullRootDir}}server'; & '.\\StratumServer.exe' --stratum-prepare-only --stratum-no-banner --dataPath '../data'; exit $LASTEXITCODE\"", + "SkipOnFailure":false + }, + { + "UpdateStageName":"Generate official Vintage Story configuration when missing", + "UpdateSourcePlatform":"Linux", + "UpdateSourceArch":"x86_64", + "UpdateSource":"Executable", + "UpdateSourceData":"/bin/bash", + "UpdateSourceArgs":"-c \"set -euo pipefail; if [ ! -f '{{$FullRootDir}}data/serverconfig.json' ]; then export DOTNET_ROOT='{{$FullRootDir}}dotnet'; cd '{{$FullRootDir}}server'; ./StratumServer --genconfig --dataPath '../data'; fi\"", + "SkipOnFailure":false + }, + { + "UpdateStageName":"Generate official Vintage Story configuration when missing", + "UpdateSourcePlatform":"Windows", + "UpdateSource":"Executable", + "UpdateSourceData":"powershell.exe", + "UpdateSourceArgs":"-NoProfile -Command \"$cfg='{{$FullRootDir}}data\\serverconfig.json'; if (-not (Test-Path -LiteralPath $cfg)) { $env:DOTNET_ROOT='{{$FullRootDir}}dotnet'; Set-Location '{{$FullRootDir}}server'; & '.\\StratumServer.exe' --genconfig --dataPath '../data'; exit $LASTEXITCODE }\"", + "SkipOnFailure":false + }, + { + "UpdateStageName":"Seed Stratum configuration when missing", + "UpdateSourcePlatform":"All", + "UpdateSource":"CreateFile", + "UpdateSourceArgs":"{{$FullRootDir}}data/stratum.json", + "UpdateSourceData":"{\n \"ServerStats\": {\n \"Enabled\": true\n }\n}\n", + "OverwriteExistingFiles":false, + "SkipOnFailure":false + }, + { + "UpdateStageName":"Seed Nimbus backend configuration when missing", + "UpdateSourcePlatform":"All", + "UpdateSource":"CreateFile", + "UpdateSourceArgs":"{{$FullRootDir}}data/ModConfig/nimbus-server.json", + "UpdateSourceData":"{\n \"Enabled\": true,\n \"ServerId\": \"\",\n \"DisplayName\": \"\",\n \"PublicHost\": \"\",\n \"PublicPort\": 42420,\n \"RegistryUrl\": \"\",\n \"SharedSecret\": \"\",\n \"HeartbeatIntervalSeconds\": 5,\n \"RegistryHttpTimeoutSeconds\": 5,\n \"Maintenance\": false,\n \"ReservationRequired\": true,\n \"FailClosedWhenRegistryUnreachable\": false,\n \"AllowPlayerServerCommand\": true,\n \"TransferMode\": \"redirect\",\n \"SeamlessPrepareAckTimeoutSeconds\": 8,\n \"ShortcutCommands\": [],\n \"Tags\": []\n}\n", + "OverwriteExistingFiles":false, + "SkipOnFailure":false + }, + { + "UpdateStageName":"Install Nimbus ServerMod", + "UpdateSourcePlatform":"Linux", + "UpdateSourceArch":"x86_64", + "UpdateSource":"Executable", + "UpdateSourceData":"/bin/bash", + "UpdateSourceArgs":"-c \"set -euo pipefail; root='{{$FullRootDir}}'; tag='{{NimbusVersionTag}}'; if [ -z \\\"$tag\\\" ]; then tag=\\\"$(curl -fsSL -H 'User-Agent: AMP-Clean-Template' https://api.github.com/repos/StratumServer/Nimbus/releases/latest | jq -r .tag_name)\\\"; fi; case \\\"$tag\\\" in v*) ;; *) tag=\\\"v$tag\\\";; esac; stage=\\\"$root/.amp-nimbus-mod-stage\\\"; archive=\\\"$root/.amp-nimbus-mod.zip\\\"; target=\\\"$root/data/Mods/Nimbus.ServerMod\\\"; rm -rf \\\"$stage\\\"; mkdir -p \\\"$stage\\\"; curl -fL --retry 3 -o \\\"$archive\\\" \\\"https://github.com/StratumServer/Nimbus/releases/download/$tag/Nimbus.ServerMod-$tag.zip\\\"; unzip -q \\\"$archive\\\" -d \\\"$stage\\\"; rm -f \\\"$archive\\\"; find \\\"$stage\\\" -type f | grep -q .; old=\\\"$root/.amp-nimbus-mod-old\\\"; rm -rf \\\"$old\\\"; if [ -d \\\"$target\\\" ]; then mv \\\"$target\\\" \\\"$old\\\"; fi; mv \\\"$stage\\\" \\\"$target\\\"; rm -rf \\\"$old\\\"; printf '%s' \\\"$tag\\\" > \\\"$target/.amp-nimbus-release\\\"\"", + "SkipOnFailure":false + }, + { + "UpdateStageName":"Install Nimbus ServerMod", + "UpdateSourcePlatform":"Windows", + "UpdateSource":"Executable", + "UpdateSourceData":"powershell.exe", + "UpdateSourceArgs":"-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference='Stop'; $ProgressPreference='SilentlyContinue'; $root='{{$FullRootDir}}'; $tag='{{NimbusVersionTag}}'.Trim(); $headers=@{'User-Agent'='AMP-Clean-Template'}; if (-not $tag) { $tag=(Invoke-RestMethod -Headers $headers -Uri https://api.github.com/repos/StratumServer/Nimbus/releases/latest).tag_name }; if (-not $tag.StartsWith('v')) { $tag='v'+$tag }; $stage=Join-Path $root '.amp-nimbus-mod-stage'; $archive=Join-Path $root '.amp-nimbus-mod.zip'; $target=Join-Path $root 'data\\Mods\\Nimbus.ServerMod'; $old=Join-Path $root '.amp-nimbus-mod-old'; Remove-Item -LiteralPath $stage,$old,$archive -Recurse -Force -ErrorAction SilentlyContinue; New-Item -ItemType Directory -Path $stage | Out-Null; Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri ('https://github.com/StratumServer/Nimbus/releases/download/'+$tag+'/Nimbus.ServerMod-'+$tag+'.zip') -OutFile $archive; Expand-Archive -LiteralPath $archive -DestinationPath $stage -Force; Remove-Item -LiteralPath $archive -Force; if (-not (Get-ChildItem -LiteralPath $stage -File -Recurse | Select-Object -First 1)) { throw 'Nimbus ServerMod archive was empty' }; if (Test-Path -LiteralPath $target) { Move-Item -LiteralPath $target -Destination $old }; try { Move-Item -LiteralPath $stage -Destination $target; Remove-Item -LiteralPath $old -Recurse -Force -ErrorAction SilentlyContinue } catch { if ((Test-Path -LiteralPath $old) -and -not (Test-Path -LiteralPath $target)) { Move-Item -LiteralPath $old -Destination $target }; throw }; [IO.File]::WriteAllText((Join-Path $target '.amp-nimbus-release'),$tag,(New-Object Text.UTF8Encoding $false))\"", + "SkipOnFailure":false + } ] From 5173ae5af3f3be14f8e553886ddeac2945525fa5 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Tue, 11 Aug 2026 17:36:42 -0500 Subject: [PATCH 19/50] Delete nimbus-proxystart.json --- nimbus-proxystart.json | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 nimbus-proxystart.json diff --git a/nimbus-proxystart.json b/nimbus-proxystart.json deleted file mode 100644 index 578909085..000000000 --- a/nimbus-proxystart.json +++ /dev/null @@ -1,18 +0,0 @@ -[ - { - "UpdateStageName":"Render Nimbus Proxy configuration", - "UpdateSourcePlatform":"Linux", - "UpdateSource":"Executable", - "UpdateSourceData":"/bin/bash", - "UpdateSourceArgs":"-c \"NP_BIND_ADDRESS='{{$ApplicationIPBinding}}' NP_SERVER_PORT='{{$ServerPort}}' NP_REGISTRY_PORT='{{$RegistryPort}}' NP_ADMIN_PORT='{{$AdminPort}}' NP_METRICS_PORT='{{$MetricsPort}}' NP_SERVERS='{{ProxyServers}}' NP_TRY='{{ProxyTryList}}' NP_REGISTRY_MODE='{{ProxyRegistryMode}}' NP_REGISTRY_ACCESS='{{ProxyRegistryAccess}}' NP_REGISTRY_URL='{{ProxyRegistryUrl}}' NP_SHARED_SECRET='{{ProxySharedSecret}}' NP_PROXY_ID='{{ProxyId}}' NP_STATUS_NAME='{{ProxyStatusName}}' NP_STATUS_MOTD='{{ProxyStatusMotd}}' NP_MAX_USERS='{{$MaxUsers}}' NP_WHITELIST_NETWORK='{{ProxyWhitelistNetwork}}' NP_WHITELIST_SERVERS='{{ProxyWhitelistServers}}' NP_VERBOSE='{{ProxyVerboseLogging}}' bash '{{$FullRootDir}}scripts/write-proxy-toml.sh' '{{$FullRootDir}}Nimbus/nimbus.proxy.toml'\"", - "SkipOnFailure":false - }, - { - "UpdateStageName":"Render Nimbus Proxy configuration", - "UpdateSourcePlatform":"Windows", - "UpdateSource":"Executable", - "UpdateSourceData":"powershell.exe", - "UpdateSourceArgs":"-NoProfile -ExecutionPolicy Bypass -Command \"$env:NP_BIND_ADDRESS='{{$ApplicationIPBinding}}'; $env:NP_SERVER_PORT='{{$ServerPort}}'; $env:NP_REGISTRY_PORT='{{$RegistryPort}}'; $env:NP_ADMIN_PORT='{{$AdminPort}}'; $env:NP_METRICS_PORT='{{$MetricsPort}}'; $env:NP_SERVERS='{{ProxyServers}}'; $env:NP_TRY='{{ProxyTryList}}'; $env:NP_REGISTRY_MODE='{{ProxyRegistryMode}}'; $env:NP_REGISTRY_ACCESS='{{ProxyRegistryAccess}}'; $env:NP_REGISTRY_URL='{{ProxyRegistryUrl}}'; $env:NP_SHARED_SECRET='{{ProxySharedSecret}}'; $env:NP_PROXY_ID='{{ProxyId}}'; $env:NP_STATUS_NAME='{{ProxyStatusName}}'; $env:NP_STATUS_MOTD='{{ProxyStatusMotd}}'; $env:NP_MAX_USERS='{{$MaxUsers}}'; $env:NP_WHITELIST_NETWORK='{{ProxyWhitelistNetwork}}'; $env:NP_WHITELIST_SERVERS='{{ProxyWhitelistServers}}'; $env:NP_VERBOSE='{{ProxyVerboseLogging}}'; & '{{$FullRootDir}}scripts\\write-proxy-toml.ps1' '{{$FullRootDir}}Nimbus\\nimbus.proxy.toml'\"", - "SkipOnFailure":false - } -] From 9e520cdd95436e0f2b94f2cc6f6b528c2f702740 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Tue, 11 Aug 2026 17:37:31 -0500 Subject: [PATCH 20/50] Add files via upload --- nimbus-proxystart.json | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 nimbus-proxystart.json diff --git a/nimbus-proxystart.json b/nimbus-proxystart.json new file mode 100644 index 000000000..578909085 --- /dev/null +++ b/nimbus-proxystart.json @@ -0,0 +1,18 @@ +[ + { + "UpdateStageName":"Render Nimbus Proxy configuration", + "UpdateSourcePlatform":"Linux", + "UpdateSource":"Executable", + "UpdateSourceData":"/bin/bash", + "UpdateSourceArgs":"-c \"NP_BIND_ADDRESS='{{$ApplicationIPBinding}}' NP_SERVER_PORT='{{$ServerPort}}' NP_REGISTRY_PORT='{{$RegistryPort}}' NP_ADMIN_PORT='{{$AdminPort}}' NP_METRICS_PORT='{{$MetricsPort}}' NP_SERVERS='{{ProxyServers}}' NP_TRY='{{ProxyTryList}}' NP_REGISTRY_MODE='{{ProxyRegistryMode}}' NP_REGISTRY_ACCESS='{{ProxyRegistryAccess}}' NP_REGISTRY_URL='{{ProxyRegistryUrl}}' NP_SHARED_SECRET='{{ProxySharedSecret}}' NP_PROXY_ID='{{ProxyId}}' NP_STATUS_NAME='{{ProxyStatusName}}' NP_STATUS_MOTD='{{ProxyStatusMotd}}' NP_MAX_USERS='{{$MaxUsers}}' NP_WHITELIST_NETWORK='{{ProxyWhitelistNetwork}}' NP_WHITELIST_SERVERS='{{ProxyWhitelistServers}}' NP_VERBOSE='{{ProxyVerboseLogging}}' bash '{{$FullRootDir}}scripts/write-proxy-toml.sh' '{{$FullRootDir}}Nimbus/nimbus.proxy.toml'\"", + "SkipOnFailure":false + }, + { + "UpdateStageName":"Render Nimbus Proxy configuration", + "UpdateSourcePlatform":"Windows", + "UpdateSource":"Executable", + "UpdateSourceData":"powershell.exe", + "UpdateSourceArgs":"-NoProfile -ExecutionPolicy Bypass -Command \"$env:NP_BIND_ADDRESS='{{$ApplicationIPBinding}}'; $env:NP_SERVER_PORT='{{$ServerPort}}'; $env:NP_REGISTRY_PORT='{{$RegistryPort}}'; $env:NP_ADMIN_PORT='{{$AdminPort}}'; $env:NP_METRICS_PORT='{{$MetricsPort}}'; $env:NP_SERVERS='{{ProxyServers}}'; $env:NP_TRY='{{ProxyTryList}}'; $env:NP_REGISTRY_MODE='{{ProxyRegistryMode}}'; $env:NP_REGISTRY_ACCESS='{{ProxyRegistryAccess}}'; $env:NP_REGISTRY_URL='{{ProxyRegistryUrl}}'; $env:NP_SHARED_SECRET='{{ProxySharedSecret}}'; $env:NP_PROXY_ID='{{ProxyId}}'; $env:NP_STATUS_NAME='{{ProxyStatusName}}'; $env:NP_STATUS_MOTD='{{ProxyStatusMotd}}'; $env:NP_MAX_USERS='{{$MaxUsers}}'; $env:NP_WHITELIST_NETWORK='{{ProxyWhitelistNetwork}}'; $env:NP_WHITELIST_SERVERS='{{ProxyWhitelistServers}}'; $env:NP_VERBOSE='{{ProxyVerboseLogging}}'; & '{{$FullRootDir}}scripts\\write-proxy-toml.ps1' '{{$FullRootDir}}Nimbus\\nimbus.proxy.toml'\"", + "SkipOnFailure":false + } +] From ef762e57ccd24d41b5cfd93a3af4a972144ef0c7 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Tue, 11 Aug 2026 17:39:39 -0500 Subject: [PATCH 21/50] Delete nimbus-proxymetaconfig.json --- nimbus-proxymetaconfig.json | 1 - 1 file changed, 1 deletion(-) delete mode 100644 nimbus-proxymetaconfig.json diff --git a/nimbus-proxymetaconfig.json b/nimbus-proxymetaconfig.json deleted file mode 100644 index fe51488c7..000000000 --- a/nimbus-proxymetaconfig.json +++ /dev/null @@ -1 +0,0 @@ -[] From 77aaf403b49b7424a9b08404084970e40655954a Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Tue, 11 Aug 2026 17:39:58 -0500 Subject: [PATCH 22/50] Delete nimbus-registrymetaconfig.json --- nimbus-registrymetaconfig.json | 1 - 1 file changed, 1 deletion(-) delete mode 100644 nimbus-registrymetaconfig.json diff --git a/nimbus-registrymetaconfig.json b/nimbus-registrymetaconfig.json deleted file mode 100644 index fe51488c7..000000000 --- a/nimbus-registrymetaconfig.json +++ /dev/null @@ -1 +0,0 @@ -[] From 4b121ecbe5b9e85100dbbb9af93c5f33053852e9 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Tue, 11 Aug 2026 17:42:52 -0500 Subject: [PATCH 23/50] Delete vintage-story-stratumstart.json --- vintage-story-stratumstart.json | 38 --------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 vintage-story-stratumstart.json diff --git a/vintage-story-stratumstart.json b/vintage-story-stratumstart.json deleted file mode 100644 index 9933d496f..000000000 --- a/vintage-story-stratumstart.json +++ /dev/null @@ -1,38 +0,0 @@ -[ - { - "UpdateStageName": "Repair savegame path", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "Executable", - "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"bash '{{$FullRootDir}}scripts/fix-serverconfig.sh' '{{$FullRootDir}}data'\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Repair savegame path", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "Executable", - "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"& '{{$FullRootDir}}scripts\\fix-serverconfig.ps1' '{{$FullRootDir}}data'\"", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Render Nimbus backend config", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "Executable", - "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"NIMBUS_WRITE_CONFIG='{{NimbusWriteConfig}}' NIMBUS_ENABLED='{{NimbusEnabled}}' NIMBUS_SERVER_ID='{{NimbusServerId}}' NIMBUS_DISPLAY_NAME='{{NimbusDisplayName}}' NIMBUS_PUBLIC_HOST='{{NimbusPublicHost}}' NIMBUS_PUBLIC_PORT='{{NimbusPublicPort}}' NIMBUS_FALLBACK_PORT='{{$ServerPort}}' NIMBUS_TAGS='{{NimbusTags}}' NIMBUS_REGISTRY_URL='{{NimbusRegistryUrl}}' NIMBUS_SHARED_SECRET='{{NimbusSharedSecret}}' NIMBUS_HEARTBEAT='{{NimbusHeartbeatIntervalSeconds}}' NIMBUS_HTTP_TIMEOUT='{{NimbusRegistryHttpTimeoutSeconds}}' NIMBUS_MAINTENANCE='{{NimbusMaintenance}}' NIMBUS_RESERVATION_REQUIRED='{{NimbusReservationRequired}}' NIMBUS_FAIL_CLOSED='{{NimbusFailClosedWhenRegistryUnreachable}}' NIMBUS_ALLOW_SERVER_COMMAND='{{NimbusAllowPlayerServerCommand}}' NIMBUS_TRANSFER_MODE='{{NimbusTransferMode}}' NIMBUS_SEAMLESS_ACK='{{NimbusSeamlessPrepareAckTimeoutSeconds}}' NIMBUS_SHORTCUTS='{{NimbusShortcutCommands}}' bash '{{$FullRootDir}}scripts/write-nimbus-server.sh' '{{$FullRootDir}}data/ModConfig/nimbus-server.json'\"", - "UpdateSourceConditionSetting": "NimbusInstall", - "UpdateSourceConditionValue": "true", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Render Nimbus backend config", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "Executable", - "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$env:NIMBUS_WRITE_CONFIG='{{NimbusWriteConfig}}'; $env:NIMBUS_ENABLED='{{NimbusEnabled}}'; $env:NIMBUS_SERVER_ID='{{NimbusServerId}}'; $env:NIMBUS_DISPLAY_NAME='{{NimbusDisplayName}}'; $env:NIMBUS_PUBLIC_HOST='{{NimbusPublicHost}}'; $env:NIMBUS_PUBLIC_PORT='{{NimbusPublicPort}}'; $env:NIMBUS_FALLBACK_PORT='{{$ServerPort}}'; $env:NIMBUS_TAGS='{{NimbusTags}}'; $env:NIMBUS_REGISTRY_URL='{{NimbusRegistryUrl}}'; $env:NIMBUS_SHARED_SECRET='{{NimbusSharedSecret}}'; $env:NIMBUS_HEARTBEAT='{{NimbusHeartbeatIntervalSeconds}}'; $env:NIMBUS_HTTP_TIMEOUT='{{NimbusRegistryHttpTimeoutSeconds}}'; $env:NIMBUS_MAINTENANCE='{{NimbusMaintenance}}'; $env:NIMBUS_RESERVATION_REQUIRED='{{NimbusReservationRequired}}'; $env:NIMBUS_FAIL_CLOSED='{{NimbusFailClosedWhenRegistryUnreachable}}'; $env:NIMBUS_ALLOW_SERVER_COMMAND='{{NimbusAllowPlayerServerCommand}}'; $env:NIMBUS_TRANSFER_MODE='{{NimbusTransferMode}}'; $env:NIMBUS_SEAMLESS_ACK='{{NimbusSeamlessPrepareAckTimeoutSeconds}}'; $env:NIMBUS_SHORTCUTS='{{NimbusShortcutCommands}}'; & '{{$FullRootDir}}scripts\\write-nimbus-server.ps1' '{{$FullRootDir}}data\\ModConfig\\nimbus-server.json'\"", - "UpdateSourceConditionSetting": "NimbusInstall", - "UpdateSourceConditionValue": "true", - "SkipOnFailure": false - } -] From ba070c0b2470b590c461eda80fc7dccdb45cb8c0 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Tue, 11 Aug 2026 18:32:40 -0500 Subject: [PATCH 24/50] Add files via upload --- nimbus-proxy.kvp | 1 + nimbus-registry.kvp | 1 + vintage-story-stratumconfig.json | 72 ++++++++++++++++++++++++++++++-- 3 files changed, 70 insertions(+), 4 deletions(-) diff --git a/nimbus-proxy.kvp b/nimbus-proxy.kvp index 311b4a72a..bf0af64f1 100644 --- a/nimbus-proxy.kvp +++ b/nimbus-proxy.kvp @@ -5,6 +5,7 @@ Meta.AarchSupport=None Meta.Arch=x86_64 Meta.Author=HuguesDePayens Meta.URL=https://github.com/StratumServer/Nimbus +Meta.DisplayImageSource=url:https://wiki.vintagestory.at/images/thumb/8/8a/Gamelogo-vintagestory.png/340px-Gamelogo-vintagestory.png Meta.EndpointURIFormat= Meta.ConfigManifest=nimbus-proxyconfig.json Meta.MetaConfigManifest= diff --git a/nimbus-registry.kvp b/nimbus-registry.kvp index 3e4cb4674..370ff935e 100644 --- a/nimbus-registry.kvp +++ b/nimbus-registry.kvp @@ -5,6 +5,7 @@ Meta.AarchSupport=None Meta.Arch=x86_64 Meta.Author=HuguesDePayens Meta.URL=https://github.com/StratumServer/Nimbus +Meta.DisplayImageSource=url:https://wiki.vintagestory.at/images/thumb/8/8a/Gamelogo-vintagestory.png/340px-Gamelogo-vintagestory.png Meta.EndpointURIFormat= Meta.ConfigManifest=nimbus-registryconfig.json Meta.MetaConfigManifest= diff --git a/vintage-story-stratumconfig.json b/vintage-story-stratumconfig.json index 3b63b70b4..05640da9f 100644 --- a/vintage-story-stratumconfig.json +++ b/vintage-story-stratumconfig.json @@ -7,11 +7,75 @@ {"DisplayName":"Server Password","Category":"Vintage Story:stadia_controller","Subcategory":"Access:lock:3","Description":"Optional password required to join. Leave blank for none.","Keywords":"password,access","FieldName":"VS_Password","InputType":"password","ParamFieldName":"$.Password","IncludeInCommandLine":false,"DefaultValue":"","EnumValues":{}}, {"DisplayName":"Whitelist Mode","Category":"Vintage Story:stadia_controller","Subcategory":"Access:lock:3","Description":"Default follows Vintage Story dedicated-server policy.","Keywords":"whitelist,access","FieldName":"VS_WhitelistMode","InputType":"enum","ParamFieldName":"$.WhitelistMode","IncludeInCommandLine":false,"DefaultValue":"0","EnumValues":{"0":"Default (on for dedicated servers)","1":"Off","2":"On"}}, {"DisplayName":"Allow PvP","Category":"Vintage Story:stadia_controller","Subcategory":"Rules:gavel:4","Description":"Allow players to damage other players.","Keywords":"pvp,rules","FieldName":"VS_AllowPvP","InputType":"checkbox","ParamFieldName":"$.AllowPvP","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Allow Fire Spread","Category":"Vintage Story:stadia_controller","Subcategory":"Rules:gavel:4","Description":"Allow fire to spread between blocks.","Keywords":"fire,spread","FieldName":"VS_AllowFireSpread","InputType":"checkbox","ParamFieldName":"$.AllowFireSpread","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Allow Fire Spread","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"Allow fire to spread between flammable blocks.","Keywords":"world,fire,spread","FieldName":"VS_AllowFireSpread","InputType":"checkbox","ParamFieldName":"$.AllowFireSpread","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, {"DisplayName":"Pass Time When Empty","Category":"Vintage Story:stadia_controller","Subcategory":"Rules:gavel:4","Description":"Advance world time while no players are online.","Keywords":"time,empty","FieldName":"VS_PassTimeWhenEmpty","InputType":"checkbox","ParamFieldName":"$.PassTimeWhenEmpty","IncludeInCommandLine":false,"DefaultValue":"false","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"World Name","Category":"World:public","Subcategory":"Creation:terrain:1","Description":"Name for a newly created world.","Keywords":"world,name","FieldName":"VS_WorldName","InputType":"text","ParamFieldName":"$.WorldConfig.WorldName","IncludeInCommandLine":false,"DefaultValue":"A new world","EnumValues":{}}, - {"DisplayName":"World Seed","Category":"World:public","Subcategory":"Creation:terrain:1","Description":"Optional seed for a newly created world. Leave blank for random.","Keywords":"world,seed","FieldName":"VS_WorldSeed","InputType":"text","ParamFieldName":"$.WorldConfig.Seed","IncludeInCommandLine":false,"DefaultValue":"","EnumValues":{}}, - {"DisplayName":"Play Style","Category":"World:public","Subcategory":"Creation:terrain:1","Description":"Play style used when the world is first created.","Keywords":"world,playstyle","FieldName":"VS_PlayStyle","InputType":"enum","ParamFieldName":"$.WorldConfig.PlayStyle","IncludeInCommandLine":false,"DefaultValue":"surviveandbuild","EnumValues":{"surviveandbuild":"Survive and Build","exploration":"Exploration","wildernesssurvival":"Wilderness Survival","creativebuilding":"Creative Building"}}, + {"DisplayName":"World Name","Category":"World:public","Subcategory":"Identity and Preset:language:1","Description":"Name for a newly created world. Most settings here only apply before the first save is generated.","Keywords":"world,name,setup","FieldName":"VS_WorldName","InputType":"text","ParamFieldName":"$.WorldConfig.WorldName","IncludeInCommandLine":false,"DefaultValue":"A new world","EnumValues":{}}, + {"DisplayName":"World Seed","Category":"World:public","Subcategory":"Identity and Preset:language:1","Description":"Optional seed for a newly created world. Leave blank for random.","Keywords":"world,seed,setup","FieldName":"VS_WorldSeed","InputType":"text","ParamFieldName":"$.WorldConfig.Seed","IncludeInCommandLine":false,"DefaultValue":"","EnumValues":{}}, + {"DisplayName":"Base Play Style","Category":"World:public","Subcategory":"Identity and Preset:language:1","Description":"Base preset. Every other visible World Setup value is an explicit override.","Keywords":"world,playstyle,setup","FieldName":"VS_PlayStyle","InputType":"enum","ParamFieldName":"$.WorldConfig.PlayStyle","IncludeInCommandLine":false,"DefaultValue":"surviveandbuild","EnumValues":{"surviveandbuild":"Standard (Survive and Build)","exploration":"Exploration","wildernesssurvival":"Wilderness Survival","creativebuilding":"Creative Building"}}, + {"DisplayName":"World Height","Category":"World:public","Subcategory":"Identity and Preset:language:1","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_WorldHeight","InputType":"enum","ParamFieldName":"$.WorldConfig.MapSizeY","IncludeInCommandLine":false,"DefaultValue":"256","EnumValues":{"128":"128 blocks","192":"192 blocks","256":"256 blocks (Standard)","384":"384 blocks","512":"512 blocks"}}, + {"DisplayName":"Allow Falling Blocks","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_AllowFallingBlocks","InputType":"checkbox","ParamFieldName":"$.AllowFallingBlocks","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Game Mode","Category":"World:public","Subcategory":"Player Spawn and Death:favorite:2","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_GameMode","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.gameMode","IncludeInCommandLine":false,"DefaultValue":"survival","EnumValues":{"survival":"Survival","creative":"Creative"}}, + {"DisplayName":"Player Lives","Category":"World:public","Subcategory":"Player Spawn and Death:favorite:2","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_PlayerLives","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.playerlives","IncludeInCommandLine":false,"DefaultValue":"-1","EnumValues":{"1":"1 life","2":"2 lives","3":"3 lives","4":"4 lives","5":"5 lives","10":"10 lives","20":"20 lives","-1":"Infinite"}}, + {"DisplayName":"Starting Climate","Category":"World:public","Subcategory":"Player Spawn and Death:favorite:2","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_StartingClimate","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.startingClimate","IncludeInCommandLine":false,"DefaultValue":"temperate","EnumValues":{"hot":"Hot","warm":"Warm","temperate":"Temperate","cool":"Cool","icy":"Icy"}}, + {"DisplayName":"Random Respawn Radius","Category":"World:public","Subcategory":"Player Spawn and Death:favorite:2","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_SpawnRadius","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.spawnRadius","IncludeInCommandLine":false,"DefaultValue":"50","EnumValues":{"0":"0 blocks","25":"25 blocks","50":"50 blocks","100":"100 blocks","250":"250 blocks","500":"500 blocks","1000":"1,000 blocks","2500":"2,500 blocks","5000":"5,000 blocks","10000":"10,000 blocks"}}, + {"DisplayName":"Grace Timer","Category":"World:public","Subcategory":"Player Spawn and Death:favorite:2","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_GraceTimer","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.graceTimer","IncludeInCommandLine":false,"DefaultValue":"0","EnumValues":{"0":"None","1":"1 day","2":"2 days","3":"3 days","4":"4 days","5":"5 days","10":"10 days"}}, + {"DisplayName":"Death Punishment","Category":"World:public","Subcategory":"Player Spawn and Death:favorite:2","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_DeathPunishment","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.deathPunishment","IncludeInCommandLine":false,"DefaultValue":"drop","EnumValues":{"drop":"Drop inventory contents","keep":"Keep inventory contents"}}, + {"DisplayName":"Dropped-on-Death Item Timer","Category":"World:public","Subcategory":"Player Spawn and Death:favorite:2","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_DroppedItemsTimer","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.droppedItemsTimer","IncludeInCommandLine":false,"DefaultValue":"600","EnumValues":{"300":"5 minutes","600":"10 minutes","1200":"20 minutes","1800":"30 minutes","3600":"60 minutes"}}, + {"DisplayName":"Seasons","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_Seasons","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.seasons","IncludeInCommandLine":false,"DefaultValue":"enabled","EnumValues":{"enabled":"Enabled","spring":"Always spring","summer":"Always summer","fall":"Always fall","winter":"Always winter"}}, + {"DisplayName":"Days per Month","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_DaysPerMonth","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.daysPerMonth","IncludeInCommandLine":false,"DefaultValue":"9","EnumValues":{"3":"3 days","6":"6 days","9":"9 days (Standard)","12":"12 days","20":"20 days","30":"30 days"}}, + {"DisplayName":"True Winters","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_HarshWinters","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.harshWinters","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Block Gravity","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_BlockGravity","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.blockGravity","IncludeInCommandLine":false,"DefaultValue":"sandgravel","EnumValues":{"sandgravel":"Sand and gravel","sandgravelsoil":"Sand, gravel, and soil"}}, + {"DisplayName":"Cave-ins","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_CaveIns","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.caveIns","IncludeInCommandLine":false,"DefaultValue":"off","EnumValues":{"off":"Disabled","on":"Enabled"}}, + {"DisplayName":"Fire from Lightning","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_LightningFires","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.lightningFires","IncludeInCommandLine":false,"DefaultValue":"false","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Allow Underground Farming","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_AllowUndergroundFarming","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.allowUndergroundFarming","IncludeInCommandLine":false,"DefaultValue":"false","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Prevent Liquid Source Transport","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_NoLiquidSourceTransport","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.noLiquidSourceTransport","IncludeInCommandLine":false,"DefaultValue":"false","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Player Health Points","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_PlayerHealthPoints","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.playerHealthPoints","IncludeInCommandLine":false,"DefaultValue":"15","EnumValues":{"5":"5 hp","10":"10 hp","15":"15 hp (Standard)","20":"20 hp","25":"25 hp","30":"30 hp"}}, + {"DisplayName":"Health Regeneration Rate","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_PlayerHealthRegenSpeed","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.playerHealthRegenSpeed","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal (100%)","2":"200%","3":"300%","0.25":"25%","0.5":"50%","0.75":"75%","1.5":"150%"}}, + {"DisplayName":"Hunger Rate","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_PlayerHungerSpeed","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.playerHungerSpeed","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal (100%)","2":"200%","3":"300%","0.25":"25%","0.5":"50%","0.75":"75%","1.5":"150%"}}, + {"DisplayName":"Lung Capacity","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_LungCapacity","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.lungCapacity","IncludeInCommandLine":false,"DefaultValue":"40000","EnumValues":{"10000":"10 seconds","20000":"20 seconds","30000":"30 seconds","40000":"40 seconds (Standard)","60000":"60 seconds","120000":"2 minutes","3600000":"1 hour"}}, + {"DisplayName":"Body Temperature Hardiness","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_BodyTemperatureResistance","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.bodyTemperatureResistance","IncludeInCommandLine":false,"DefaultValue":"0","EnumValues":{"0":"0 °C (Standard)","10":"10 °C","20":"20 °C","-40":"-40 °C","-30":"-30 °C","-20":"-20 °C","-10":"-10 °C"}}, + {"DisplayName":"Walk Speed","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_PlayerMoveSpeed","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.playerMoveSpeed","IncludeInCommandLine":false,"DefaultValue":"1.5","EnumValues":{"1":"Reduced","2":"Fast","3":"Very fast","0.5":"Slow","1.5":"Normal"}}, + {"DisplayName":"Creature Hostility","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_CreatureHostility","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.creatureHostility","IncludeInCommandLine":false,"DefaultValue":"aggressive","EnumValues":{"aggressive":"Aggressive","passive":"Passive","off":"Off"}}, + {"DisplayName":"Creature Strength","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_CreatureStrength","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.creatureStrength","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal (100%)","2":"200%","3":"300%","0.25":"25%","0.5":"50%","0.75":"75%","1.5":"150%"}}, + {"DisplayName":"Creature Swim Speed","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_CreatureSwimSpeed","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.creatureSwimSpeed","IncludeInCommandLine":false,"DefaultValue":"2","EnumValues":{"1":"100%","2":"200% (Standard)","3":"300%","0.5":"50%","1.5":"150%","2.5":"250%"}}, + {"DisplayName":"Food Spoilage Rate","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_FoodSpoilSpeed","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.foodSpoilSpeed","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal (100%)","2":"200%","3":"300%","0.25":"25%","0.5":"50%","0.75":"75%","1.5":"150%"}}, + {"DisplayName":"Tree Sapling Growth Time","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_SaplingGrowthRate","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.saplingGrowthRate","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal (100%)","2":"200%","3":"300%","0.25":"25%","0.5":"50%","0.75":"75%","1.5":"150%"}}, + {"DisplayName":"Tool Durability","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_ToolDurability","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.toolDurability","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal (100%)","2":"200%","3":"300%","0.25":"25%","0.5":"50%","0.75":"75%","1.5":"150%"}}, + {"DisplayName":"Tool Mining Speed","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_ToolMiningSpeed","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.toolMiningSpeed","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal (100%)","2":"200%","3":"300%","0.25":"25%","0.5":"50%","0.75":"75%","1.5":"150%"}}, + {"DisplayName":"Prospecting Pick Node Radius","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_PropickNodeSearchRadius","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.propickNodeSearchRadius","IncludeInCommandLine":false,"DefaultValue":"6","EnumValues":{"0":"Disabled","2":"2 blocks","4":"4 blocks","6":"6 blocks (Standard)","8":"8 blocks"}}, + {"DisplayName":"Microblock Chiseling","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_MicroblockChiseling","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.microblockChiseling","IncludeInCommandLine":false,"DefaultValue":"stonewood","EnumValues":{"off":"Off","stonewood":"Stone, wood, and bricks","all":"Most cubic blocks"}}, + {"DisplayName":"Coordinate Overlay","Category":"World:public","Subcategory":"Map and Navigation:map:4","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_AllowCoordinateHud","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.allowCoordinateHud","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"World Map","Category":"World:public","Subcategory":"Map and Navigation:map:4","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_AllowMap","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.allowMap","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Color-accurate World Map","Category":"World:public","Subcategory":"Map and Navigation:map:4","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_ColorAccurateWorldmap","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.colorAccurateWorldmap","IncludeInCommandLine":false,"DefaultValue":"false","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Lore Content","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_LoreContent","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.loreContent","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Clutter Obtainable","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_ClutterObtainable","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.clutterObtainable","IncludeInCommandLine":false,"DefaultValue":"ifrepaired","EnumValues":{"ifrepaired":"Only after repair with glue","yes":"Yes, without repair","no":"No"}}, + {"DisplayName":"Temporal Stability","Category":"World:public","Subcategory":"Temporal Stability:storm:5","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_TemporalStability","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.temporalStability","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Temporal Storms","Category":"World:public","Subcategory":"Temporal Stability:storm:5","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_TemporalStorms","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.temporalStorms","IncludeInCommandLine":false,"DefaultValue":"sometimes","EnumValues":{"off":"Off","veryrare":"Very rare","rare":"Rare","sometimes":"Sometimes (Standard)","often":"Often","veryoften":"Very often"}}, + {"DisplayName":"Temporal Storm Length","Category":"World:public","Subcategory":"Temporal Stability:storm:5","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_TempstormDurationMul","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.tempstormDurationMul","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal (100%)","2":"200%","3":"300%","0.25":"25%","0.5":"50%","0.75":"75%","1.5":"150%"}}, + {"DisplayName":"Temporal Rifts","Category":"World:public","Subcategory":"Temporal Stability:storm:5","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_TemporalRifts","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.temporalRifts","IncludeInCommandLine":false,"DefaultValue":"visible","EnumValues":{"off":"Off","invisible":"Invisible","visible":"Visible"}}, + {"DisplayName":"Temporal Gear Respawn Uses","Category":"World:public","Subcategory":"Temporal Stability:storm:5","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_TemporalGearRespawnUses","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.temporalGearRespawnUses","IncludeInCommandLine":false,"DefaultValue":"20","EnumValues":{"1":"1 use","5":"5 uses","10":"10 uses","20":"20 uses (Standard)","50":"50 uses","100":"100 uses","-1":"Infinite"}}, + {"DisplayName":"Sleeping During Temporal Storms","Category":"World:public","Subcategory":"Temporal Stability:storm:5","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_TemporalStormSleeping","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.temporalStormSleeping","IncludeInCommandLine":false,"DefaultValue":"0","EnumValues":{"0":"Disallowed","1":"Allowed"}}, + {"DisplayName":"Climate Distribution","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_WorldClimate","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.worldClimate","IncludeInCommandLine":false,"DefaultValue":"realistic","EnumValues":{"realistic":"Realistic","patchy":"Patchy"}}, + {"DisplayName":"Landcover","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_Landcover","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.landcover","IncludeInCommandLine":false,"DefaultValue":"0.975","EnumValues":{"1":"100%","0.1":"10%","0.25":"25%","0.5":"50%","0.7":"70%","0.9":"90%","0.975":"97.5% (Standard)"}}, + {"DisplayName":"Landcover Scale","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_OceanScale","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.oceanscale","IncludeInCommandLine":false,"DefaultValue":"5","EnumValues":{"1":"100%","2":"200%","5":"500% (Standard)","0.1":"10%","0.25":"25%","0.5":"50%"}}, + {"DisplayName":"Upheaval Rate","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_UpheavelCommonness","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.upheavelCommonness","IncludeInCommandLine":false,"DefaultValue":"0.3","EnumValues":{"0":"0%","1":"100%","0.1":"10%","0.2":"20%","0.3":"30% (Standard)","0.4":"40%","0.5":"50%","0.6":"60%"}}, + {"DisplayName":"Geologic Activity","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_GeologicActivity","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.geologicActivity","IncludeInCommandLine":false,"DefaultValue":"0.05","EnumValues":{"0":"None","0.025":"Very rare","0.05":"Rare (Standard)","0.1":"Uncommon","0.2":"Common","0.4":"Very common"}}, + {"DisplayName":"Landform Scale","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_LandformScale","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.landformScale","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"100% (Standard)","2":"200%","3":"300%","0.2":"20%","0.5":"50%","1.5":"150%"}}, + {"DisplayName":"World Width","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_WorldWidth","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.worldWidth","IncludeInCommandLine":false,"DefaultValue":"1024000","EnumValues":{"32768":"32k blocks","102400":"100k blocks","256000":"250k blocks","512000":"500k blocks","1024000":"1M blocks (Standard)","2048000":"2M blocks","4096000":"4M blocks","8192000":"8M blocks"}}, + {"DisplayName":"World Length","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_WorldLength","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.worldLength","IncludeInCommandLine":false,"DefaultValue":"1024000","EnumValues":{"32768":"32k blocks","102400":"100k blocks","256000":"250k blocks","512000":"500k blocks","1024000":"1M blocks (Standard)","2048000":"2M blocks","4096000":"4M blocks","8192000":"8M blocks"}}, + {"DisplayName":"World Edge","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_WorldEdge","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.worldEdge","IncludeInCommandLine":false,"DefaultValue":"traversable","EnumValues":{"traversable":"Traversable (can fall down)","blocked":"Blocked"}}, + {"DisplayName":"Polar-Equator Distance","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_PolarEquatorDistance","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.polarEquatorDistance","IncludeInCommandLine":false,"DefaultValue":"100000","EnumValues":{"5000":"5k blocks","10000":"10k blocks","15000":"15k blocks","25000":"25k blocks","50000":"50k blocks","100000":"100k blocks (Standard)","200000":"200k blocks","400000":"400k blocks","800000":"800k blocks"}}, + {"DisplayName":"Story Structure Distance","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_StoryStructuresDistScaling","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.storyStructuresDistScaling","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"100% (Standard)","2":"200%","3":"300%","0.15":"15%","0.25":"25%","0.5":"50%","0.75":"75%","1.5":"150%"}}, + {"DisplayName":"Global Temperature","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_GlobalTemperature","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.globalTemperature","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal","2":"Hot","3":"Very hot","5":"Extreme heat","0.1":"Very cold","0.5":"Cold","1.5":"Warm"}}, + {"DisplayName":"Global Precipitation","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_GlobalPrecipitation","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.globalPrecipitation","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal","2":"Very wet","3":"Extremely wet","5":"Maximum","0.1":"Very dry","0.5":"Dry","1.5":"Wet"}}, + {"DisplayName":"Forestation & Shrubs","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_GlobalForestation","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.globalForestation","IncludeInCommandLine":false,"DefaultValue":"0","EnumValues":{"0":"Normal","1":"Full coverage","-1":"None","-0.5":"Sparse","0.5":"Dense"}}, + {"DisplayName":"Global Deposit Spawn Rate","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_GlobalDepositSpawnRate","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.globalDepositSpawnRate","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"100% (Standard)","2":"200%","3":"300%","0.2":"20%","0.5":"50%","0.75":"75%","1.5":"150%"}}, + {"DisplayName":"Surface Copper Frequency","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_SurfaceCopperDeposits","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.surfaceCopperDeposits","IncludeInCommandLine":false,"DefaultValue":"0.12","EnumValues":{"0":"None","0.007":"Extremely rare","0.04":"Very rare","0.08":"Rare","0.12":"Standard","0.2":"Common","0.4":"Very common"}}, + {"DisplayName":"Surface Tin Frequency","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_SurfaceTinDeposits","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.surfaceTinDeposits","IncludeInCommandLine":false,"DefaultValue":"0.007","EnumValues":{"0":"None","0.003":"Extremely rare","0.007":"Standard","0.02":"Rare","0.05":"Uncommon","0.1":"Common"}}, + {"DisplayName":"Snow and Ice","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_SnowAccum","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.snowAccum","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Land Claiming","Category":"World:public","Subcategory":"Multiplayer:groups:7","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_AllowLandClaiming","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.allowLandClaiming","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Class-exclusive Recipes","Category":"World:public","Subcategory":"Multiplayer:groups:7","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_ClassExclusiveRecipes","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.classExclusiveRecipes","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, + {"DisplayName":"Auction House","Category":"World:public","Subcategory":"Multiplayer:groups:7","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_AuctionHouse","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.auctionHouse","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, {"DisplayName":"Nimbus Server ID","Category":"Nimbus Backend:share","Subcategory":"Connection:dns:1","Description":"Unique ID that must exactly match this backend's key in the Proxy Backend Servers map.","Keywords":"nimbus,id","FieldName":"NimbusServerId","InputType":"text","ParamFieldName":"$.ServerId","IncludeInCommandLine":false,"Required":true,"DefaultValue":"","Placeholder":"hub","EnumValues":{}}, {"DisplayName":"Nimbus Display Name","Category":"Nimbus Backend:share","Subcategory":"Connection:dns:1","Description":"Friendly name for this backend.","Keywords":"nimbus,name","FieldName":"NimbusDisplayName","InputType":"text","ParamFieldName":"$.DisplayName","IncludeInCommandLine":false,"DefaultValue":"","Placeholder":"Hub","EnumValues":{}}, {"DisplayName":"Proxy Public Host","Category":"Nimbus Backend:share","Subcategory":"Connection:dns:1","Description":"Public hostname or IP players use for Nimbus Proxy, not this private backend.","Keywords":"proxy,host","FieldName":"NimbusPublicHost","InputType":"text","ParamFieldName":"$.PublicHost","IncludeInCommandLine":false,"Required":true,"DefaultValue":"","Placeholder":"play.example.com","EnumValues":{}}, From 8e67f93f9ac114ea1a7ebd65068714c034a0e553 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Tue, 11 Aug 2026 18:43:29 -0500 Subject: [PATCH 25/50] Add files via upload --- vintage-story-stratumconfig.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vintage-story-stratumconfig.json b/vintage-story-stratumconfig.json index 05640da9f..9079b31ae 100644 --- a/vintage-story-stratumconfig.json +++ b/vintage-story-stratumconfig.json @@ -12,7 +12,7 @@ {"DisplayName":"World Name","Category":"World:public","Subcategory":"Identity and Preset:language:1","Description":"Name for a newly created world. Most settings here only apply before the first save is generated.","Keywords":"world,name,setup","FieldName":"VS_WorldName","InputType":"text","ParamFieldName":"$.WorldConfig.WorldName","IncludeInCommandLine":false,"DefaultValue":"A new world","EnumValues":{}}, {"DisplayName":"World Seed","Category":"World:public","Subcategory":"Identity and Preset:language:1","Description":"Optional seed for a newly created world. Leave blank for random.","Keywords":"world,seed,setup","FieldName":"VS_WorldSeed","InputType":"text","ParamFieldName":"$.WorldConfig.Seed","IncludeInCommandLine":false,"DefaultValue":"","EnumValues":{}}, {"DisplayName":"Base Play Style","Category":"World:public","Subcategory":"Identity and Preset:language:1","Description":"Base preset. Every other visible World Setup value is an explicit override.","Keywords":"world,playstyle,setup","FieldName":"VS_PlayStyle","InputType":"enum","ParamFieldName":"$.WorldConfig.PlayStyle","IncludeInCommandLine":false,"DefaultValue":"surviveandbuild","EnumValues":{"surviveandbuild":"Standard (Survive and Build)","exploration":"Exploration","wildernesssurvival":"Wilderness Survival","creativebuilding":"Creative Building"}}, - {"DisplayName":"World Height","Category":"World:public","Subcategory":"Identity and Preset:language:1","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_WorldHeight","InputType":"enum","ParamFieldName":"$.WorldConfig.MapSizeY","IncludeInCommandLine":false,"DefaultValue":"256","EnumValues":{"128":"128 blocks","192":"192 blocks","256":"256 blocks (Standard)","384":"384 blocks","512":"512 blocks"}}, + {"DisplayName":"World Height","Category":"World:public","Subcategory":"Identity and Preset:language:1","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_WorldHeight","InputType":"enum","ParamFieldName":"$.WorldConfig.MapSizeY","IncludeInCommandLine":false,"DefaultValue":"256","EnumValues":{"128":"128 blocks","192":"192 blocks","256":"256 blocks (Standard)","384":"384 blocks","448":"448 blocks","512":"512 blocks"}}, {"DisplayName":"Allow Falling Blocks","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_AllowFallingBlocks","InputType":"checkbox","ParamFieldName":"$.AllowFallingBlocks","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, {"DisplayName":"Game Mode","Category":"World:public","Subcategory":"Player Spawn and Death:favorite:2","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_GameMode","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.gameMode","IncludeInCommandLine":false,"DefaultValue":"survival","EnumValues":{"survival":"Survival","creative":"Creative"}}, {"DisplayName":"Player Lives","Category":"World:public","Subcategory":"Player Spawn and Death:favorite:2","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_PlayerLives","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.playerlives","IncludeInCommandLine":false,"DefaultValue":"-1","EnumValues":{"1":"1 life","2":"2 lives","3":"3 lives","4":"4 lives","5":"5 lives","10":"10 lives","20":"20 lives","-1":"Infinite"}}, From c77a5695297edd6b965e0a1fc905eac02939f568 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Tue, 11 Aug 2026 18:50:34 -0500 Subject: [PATCH 26/50] Add files via upload --- nimbus-proxyupdates.json | 6 +++--- nimbus-registryupdates.json | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/nimbus-proxyupdates.json b/nimbus-proxyupdates.json index cc0cb149f..c31412784 100644 --- a/nimbus-proxyupdates.json +++ b/nimbus-proxyupdates.json @@ -26,7 +26,7 @@ "UpdateSourceArch": "x86_64", "UpdateSource": "Executable", "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"set -euo pipefail; root=\u0027{{$FullRootDir}}\u0027; if [ -x \\\"$root/dotnet/dotnet\\\" ] \u0026\u0026 \\\"$root/dotnet/dotnet\\\" --list-runtimes | grep -q \u0027^Microsoft.NETCore.App 10\\.\u0027; then echo \u0027[AMP] .NET 10 runtime already installed\u0027; else tmp=\\\"$(mktemp)\\\"; curl -fsSL https://dot.net/v1/dotnet-install.sh -o \\\"$tmp\\\"; bash \\\"$tmp\\\" --channel 10.0 --runtime dotnet --install-dir \\\"$root/dotnet\\\" --no-path; rm -f \\\"$tmp\\\"; fi\"", + "UpdateSourceArgs": "-c \"set -euo pipefail; root=\u0027{{$FullRootDir}}\u0027; if [ -x \\\"$root/dotnet/dotnet\\\" ] \u0026\u0026 \\\"$root/dotnet/dotnet\\\" --list-runtimes | grep -q \u0027^Microsoft.AspNetCore.App 10\\.\u0027; then echo \u0027[AMP] .NET 10 ASP.NET Core runtime already installed\u0027; else tmp=\\\"$(mktemp)\\\"; curl -fsSL https://dot.net/v1/dotnet-install.sh -o \\\"$tmp\\\"; bash \\\"$tmp\\\" --channel 10.0 --runtime aspnetcore --install-dir \\\"$root/dotnet\\\" --no-path; rm -f \\\"$tmp\\\"; fi\"", "SkipOnFailure": false }, { @@ -34,7 +34,7 @@ "UpdateSourcePlatform": "Windows", "UpdateSource": "Executable", "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference=\u0027Stop\u0027; $root=\u0027{{$FullRootDir}}\u0027; $dotnet=Join-Path $root \u0027dotnet\\dotnet.exe\u0027; $ready=$false; if (Test-Path -LiteralPath $dotnet) { $ready=[bool]((\u0026 $dotnet --list-runtimes) -match \u0027^Microsoft.NETCore.App 10\\.\u0027) }; if ($ready) { Write-Output \u0027[AMP] .NET 10 runtime already installed\u0027 } else { $script=Join-Path $env:TEMP (\u0027dotnet-install-\u0027+[guid]::NewGuid().ToString(\u0027N\u0027)+\u0027.ps1\u0027); try { Invoke-WebRequest -UseBasicParsing -Uri https://dot.net/v1/dotnet-install.ps1 -OutFile $script; \u0026 $script -Channel 10.0 -Runtime dotnet -InstallDir (Join-Path $root \u0027dotnet\u0027) -NoPath } finally { Remove-Item -LiteralPath $script -Force -ErrorAction SilentlyContinue } }\"", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference=\u0027Stop\u0027; $root=\u0027{{$FullRootDir}}\u0027; $dotnet=Join-Path $root \u0027dotnet\\dotnet.exe\u0027; $ready=$false; if (Test-Path -LiteralPath $dotnet) { $ready=[bool]((\u0026 $dotnet --list-runtimes) -match \u0027^Microsoft.AspNetCore.App 10\\.\u0027) }; if ($ready) { Write-Output \u0027[AMP] .NET 10 ASP.NET Core runtime already installed\u0027 } else { $script=Join-Path $env:TEMP (\u0027dotnet-install-\u0027+[guid]::NewGuid().ToString(\u0027N\u0027)+\u0027.ps1\u0027); try { Invoke-WebRequest -UseBasicParsing -Uri https://dot.net/v1/dotnet-install.ps1 -OutFile $script; \u0026 $script -Channel 10.0 -Runtime aspnetcore -InstallDir (Join-Path $root \u0027dotnet\u0027) -NoPath } finally { Remove-Item -LiteralPath $script -Force -ErrorAction SilentlyContinue } }\"", "SkipOnFailure": false }, { @@ -72,4 +72,4 @@ "OverwriteExistingFiles": true, "SkipOnFailure": false } -] \ No newline at end of file +] diff --git a/nimbus-registryupdates.json b/nimbus-registryupdates.json index aedd5990e..e2db834a7 100644 --- a/nimbus-registryupdates.json +++ b/nimbus-registryupdates.json @@ -26,7 +26,7 @@ "UpdateSourceArch": "x86_64", "UpdateSource": "Executable", "UpdateSourceData": "/bin/bash", - "UpdateSourceArgs": "-c \"set -euo pipefail; root=\u0027{{$FullRootDir}}\u0027; if [ -x \\\"$root/dotnet/dotnet\\\" ] \u0026\u0026 \\\"$root/dotnet/dotnet\\\" --list-runtimes | grep -q \u0027^Microsoft.NETCore.App 10\\.\u0027; then echo \u0027[AMP] .NET 10 runtime already installed\u0027; else tmp=\\\"$(mktemp)\\\"; curl -fsSL https://dot.net/v1/dotnet-install.sh -o \\\"$tmp\\\"; bash \\\"$tmp\\\" --channel 10.0 --runtime dotnet --install-dir \\\"$root/dotnet\\\" --no-path; rm -f \\\"$tmp\\\"; fi\"", + "UpdateSourceArgs": "-c \"set -euo pipefail; root=\u0027{{$FullRootDir}}\u0027; if [ -x \\\"$root/dotnet/dotnet\\\" ] \u0026\u0026 \\\"$root/dotnet/dotnet\\\" --list-runtimes | grep -q \u0027^Microsoft.AspNetCore.App 10\\.\u0027; then echo \u0027[AMP] .NET 10 ASP.NET Core runtime already installed\u0027; else tmp=\\\"$(mktemp)\\\"; curl -fsSL https://dot.net/v1/dotnet-install.sh -o \\\"$tmp\\\"; bash \\\"$tmp\\\" --channel 10.0 --runtime aspnetcore --install-dir \\\"$root/dotnet\\\" --no-path; rm -f \\\"$tmp\\\"; fi\"", "SkipOnFailure": false }, { @@ -34,7 +34,7 @@ "UpdateSourcePlatform": "Windows", "UpdateSource": "Executable", "UpdateSourceData": "powershell.exe", - "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference=\u0027Stop\u0027; $root=\u0027{{$FullRootDir}}\u0027; $dotnet=Join-Path $root \u0027dotnet\\dotnet.exe\u0027; $ready=$false; if (Test-Path -LiteralPath $dotnet) { $ready=[bool]((\u0026 $dotnet --list-runtimes) -match \u0027^Microsoft.NETCore.App 10\\.\u0027) }; if ($ready) { Write-Output \u0027[AMP] .NET 10 runtime already installed\u0027 } else { $script=Join-Path $env:TEMP (\u0027dotnet-install-\u0027+[guid]::NewGuid().ToString(\u0027N\u0027)+\u0027.ps1\u0027); try { Invoke-WebRequest -UseBasicParsing -Uri https://dot.net/v1/dotnet-install.ps1 -OutFile $script; \u0026 $script -Channel 10.0 -Runtime dotnet -InstallDir (Join-Path $root \u0027dotnet\u0027) -NoPath } finally { Remove-Item -LiteralPath $script -Force -ErrorAction SilentlyContinue } }\"", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference=\u0027Stop\u0027; $root=\u0027{{$FullRootDir}}\u0027; $dotnet=Join-Path $root \u0027dotnet\\dotnet.exe\u0027; $ready=$false; if (Test-Path -LiteralPath $dotnet) { $ready=[bool]((\u0026 $dotnet --list-runtimes) -match \u0027^Microsoft.AspNetCore.App 10\\.\u0027) }; if ($ready) { Write-Output \u0027[AMP] .NET 10 ASP.NET Core runtime already installed\u0027 } else { $script=Join-Path $env:TEMP (\u0027dotnet-install-\u0027+[guid]::NewGuid().ToString(\u0027N\u0027)+\u0027.ps1\u0027); try { Invoke-WebRequest -UseBasicParsing -Uri https://dot.net/v1/dotnet-install.ps1 -OutFile $script; \u0026 $script -Channel 10.0 -Runtime aspnetcore -InstallDir (Join-Path $root \u0027dotnet\u0027) -NoPath } finally { Remove-Item -LiteralPath $script -Force -ErrorAction SilentlyContinue } }\"", "SkipOnFailure": false }, { @@ -72,4 +72,4 @@ "OverwriteExistingFiles": true, "SkipOnFailure": false } -] \ No newline at end of file +] From 2239e7c14a51da3d11af4c69cd757e9302f09e06 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Wed, 12 Aug 2026 18:29:15 -0500 Subject: [PATCH 27/50] Add files via upload --- vintage-story-stratum.kvp | 1 + vintage-story-stratumconfig.json | 1706 ++++++++++++++++++++++++-- vintage-story-stratummetaconfig.json | 1 + vintage-story-stratumstart.json | 18 + vintage-story-stratumupdates.json | 292 +++-- 5 files changed, 1820 insertions(+), 198 deletions(-) create mode 100644 vintage-story-stratumstart.json diff --git a/vintage-story-stratum.kvp b/vintage-story-stratum.kvp index 1a3ce3000..8eb7d1d48 100644 --- a/vintage-story-stratum.kvp +++ b/vintage-story-stratum.kvp @@ -62,6 +62,7 @@ App.RCONHeartbeatMinutes=0 App.RCONHeartbeatCommand=ping App.TelnetLoginFormat={0} App.UpdateSources=@IncludeJson[vintage-story-stratumupdates.json] +App.PreStartStages=@IncludeJson[vintage-story-stratumstart.json] App.Compatibility=None App.SteamUpdateAnonymousLogin=True App.SteamForceLoginPrompt=False diff --git a/vintage-story-stratumconfig.json b/vintage-story-stratumconfig.json index 9079b31ae..4aca067d4 100644 --- a/vintage-story-stratumconfig.json +++ b/vintage-story-stratumconfig.json @@ -1,90 +1,1618 @@ -[ - {"DisplayName":"Server Port","Category":"Vintage Story:stadia_controller","Subcategory":"Network:dns:1","Description":"Private game port used by Nimbus Proxy.","Keywords":"port,backend","FieldName":"$ServerPort","InputType":"number","Hidden":true,"ParamFieldName":"$.Port","IncludeInCommandLine":false,"DefaultValue":"42420","MinValue":1,"MaxValue":65535,"EnumValues":{}}, - {"DisplayName":"Player Limit","Category":"Vintage Story:stadia_controller","Subcategory":"Players:group:2","Description":"Maximum simultaneous players on this backend.","Keywords":"players,limit","FieldName":"$MaxUsers","InputType":"number","ParamFieldName":"$.MaxClients","IncludeInCommandLine":false,"DefaultValue":"16","MinValue":1,"MaxValue":1000,"EnumValues":{}}, - {"DisplayName":"Server Name","Category":"Vintage Story:stadia_controller","Subcategory":"Identity:badge:1","Description":"Name shown by the Vintage Story server.","Keywords":"server,name","FieldName":"VS_ServerName","InputType":"text","ParamFieldName":"$.ServerName","IncludeInCommandLine":false,"DefaultValue":"Vintage Story Server","EnumValues":{}}, - {"DisplayName":"Server Description","Category":"Vintage Story:stadia_controller","Subcategory":"Identity:badge:1","Description":"Short description shown to players.","Keywords":"server,description","FieldName":"VS_ServerDescription","InputType":"text","ParamFieldName":"$.ServerDescription","IncludeInCommandLine":false,"DefaultValue":"","EnumValues":{}}, - {"DisplayName":"Welcome Message","Category":"Vintage Story:stadia_controller","Subcategory":"Identity:badge:1","Description":"Message shown after a player joins.","Keywords":"welcome,message","FieldName":"VS_WelcomeMessage","InputType":"text","ParamFieldName":"$.WelcomeMessage","IncludeInCommandLine":false,"DefaultValue":"Welcome, {0}, may you survive well and prosper","EnumValues":{}}, - {"DisplayName":"Server Password","Category":"Vintage Story:stadia_controller","Subcategory":"Access:lock:3","Description":"Optional password required to join. Leave blank for none.","Keywords":"password,access","FieldName":"VS_Password","InputType":"password","ParamFieldName":"$.Password","IncludeInCommandLine":false,"DefaultValue":"","EnumValues":{}}, - {"DisplayName":"Whitelist Mode","Category":"Vintage Story:stadia_controller","Subcategory":"Access:lock:3","Description":"Default follows Vintage Story dedicated-server policy.","Keywords":"whitelist,access","FieldName":"VS_WhitelistMode","InputType":"enum","ParamFieldName":"$.WhitelistMode","IncludeInCommandLine":false,"DefaultValue":"0","EnumValues":{"0":"Default (on for dedicated servers)","1":"Off","2":"On"}}, - {"DisplayName":"Allow PvP","Category":"Vintage Story:stadia_controller","Subcategory":"Rules:gavel:4","Description":"Allow players to damage other players.","Keywords":"pvp,rules","FieldName":"VS_AllowPvP","InputType":"checkbox","ParamFieldName":"$.AllowPvP","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Allow Fire Spread","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"Allow fire to spread between flammable blocks.","Keywords":"world,fire,spread","FieldName":"VS_AllowFireSpread","InputType":"checkbox","ParamFieldName":"$.AllowFireSpread","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Pass Time When Empty","Category":"Vintage Story:stadia_controller","Subcategory":"Rules:gavel:4","Description":"Advance world time while no players are online.","Keywords":"time,empty","FieldName":"VS_PassTimeWhenEmpty","InputType":"checkbox","ParamFieldName":"$.PassTimeWhenEmpty","IncludeInCommandLine":false,"DefaultValue":"false","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"World Name","Category":"World:public","Subcategory":"Identity and Preset:language:1","Description":"Name for a newly created world. Most settings here only apply before the first save is generated.","Keywords":"world,name,setup","FieldName":"VS_WorldName","InputType":"text","ParamFieldName":"$.WorldConfig.WorldName","IncludeInCommandLine":false,"DefaultValue":"A new world","EnumValues":{}}, - {"DisplayName":"World Seed","Category":"World:public","Subcategory":"Identity and Preset:language:1","Description":"Optional seed for a newly created world. Leave blank for random.","Keywords":"world,seed,setup","FieldName":"VS_WorldSeed","InputType":"text","ParamFieldName":"$.WorldConfig.Seed","IncludeInCommandLine":false,"DefaultValue":"","EnumValues":{}}, - {"DisplayName":"Base Play Style","Category":"World:public","Subcategory":"Identity and Preset:language:1","Description":"Base preset. Every other visible World Setup value is an explicit override.","Keywords":"world,playstyle,setup","FieldName":"VS_PlayStyle","InputType":"enum","ParamFieldName":"$.WorldConfig.PlayStyle","IncludeInCommandLine":false,"DefaultValue":"surviveandbuild","EnumValues":{"surviveandbuild":"Standard (Survive and Build)","exploration":"Exploration","wildernesssurvival":"Wilderness Survival","creativebuilding":"Creative Building"}}, - {"DisplayName":"World Height","Category":"World:public","Subcategory":"Identity and Preset:language:1","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_WorldHeight","InputType":"enum","ParamFieldName":"$.WorldConfig.MapSizeY","IncludeInCommandLine":false,"DefaultValue":"256","EnumValues":{"128":"128 blocks","192":"192 blocks","256":"256 blocks (Standard)","384":"384 blocks","448":"448 blocks","512":"512 blocks"}}, - {"DisplayName":"Allow Falling Blocks","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_AllowFallingBlocks","InputType":"checkbox","ParamFieldName":"$.AllowFallingBlocks","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Game Mode","Category":"World:public","Subcategory":"Player Spawn and Death:favorite:2","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_GameMode","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.gameMode","IncludeInCommandLine":false,"DefaultValue":"survival","EnumValues":{"survival":"Survival","creative":"Creative"}}, - {"DisplayName":"Player Lives","Category":"World:public","Subcategory":"Player Spawn and Death:favorite:2","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_PlayerLives","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.playerlives","IncludeInCommandLine":false,"DefaultValue":"-1","EnumValues":{"1":"1 life","2":"2 lives","3":"3 lives","4":"4 lives","5":"5 lives","10":"10 lives","20":"20 lives","-1":"Infinite"}}, - {"DisplayName":"Starting Climate","Category":"World:public","Subcategory":"Player Spawn and Death:favorite:2","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_StartingClimate","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.startingClimate","IncludeInCommandLine":false,"DefaultValue":"temperate","EnumValues":{"hot":"Hot","warm":"Warm","temperate":"Temperate","cool":"Cool","icy":"Icy"}}, - {"DisplayName":"Random Respawn Radius","Category":"World:public","Subcategory":"Player Spawn and Death:favorite:2","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_SpawnRadius","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.spawnRadius","IncludeInCommandLine":false,"DefaultValue":"50","EnumValues":{"0":"0 blocks","25":"25 blocks","50":"50 blocks","100":"100 blocks","250":"250 blocks","500":"500 blocks","1000":"1,000 blocks","2500":"2,500 blocks","5000":"5,000 blocks","10000":"10,000 blocks"}}, - {"DisplayName":"Grace Timer","Category":"World:public","Subcategory":"Player Spawn and Death:favorite:2","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_GraceTimer","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.graceTimer","IncludeInCommandLine":false,"DefaultValue":"0","EnumValues":{"0":"None","1":"1 day","2":"2 days","3":"3 days","4":"4 days","5":"5 days","10":"10 days"}}, - {"DisplayName":"Death Punishment","Category":"World:public","Subcategory":"Player Spawn and Death:favorite:2","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_DeathPunishment","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.deathPunishment","IncludeInCommandLine":false,"DefaultValue":"drop","EnumValues":{"drop":"Drop inventory contents","keep":"Keep inventory contents"}}, - {"DisplayName":"Dropped-on-Death Item Timer","Category":"World:public","Subcategory":"Player Spawn and Death:favorite:2","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_DroppedItemsTimer","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.droppedItemsTimer","IncludeInCommandLine":false,"DefaultValue":"600","EnumValues":{"300":"5 minutes","600":"10 minutes","1200":"20 minutes","1800":"30 minutes","3600":"60 minutes"}}, - {"DisplayName":"Seasons","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_Seasons","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.seasons","IncludeInCommandLine":false,"DefaultValue":"enabled","EnumValues":{"enabled":"Enabled","spring":"Always spring","summer":"Always summer","fall":"Always fall","winter":"Always winter"}}, - {"DisplayName":"Days per Month","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_DaysPerMonth","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.daysPerMonth","IncludeInCommandLine":false,"DefaultValue":"9","EnumValues":{"3":"3 days","6":"6 days","9":"9 days (Standard)","12":"12 days","20":"20 days","30":"30 days"}}, - {"DisplayName":"True Winters","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_HarshWinters","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.harshWinters","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Block Gravity","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_BlockGravity","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.blockGravity","IncludeInCommandLine":false,"DefaultValue":"sandgravel","EnumValues":{"sandgravel":"Sand and gravel","sandgravelsoil":"Sand, gravel, and soil"}}, - {"DisplayName":"Cave-ins","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_CaveIns","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.caveIns","IncludeInCommandLine":false,"DefaultValue":"off","EnumValues":{"off":"Disabled","on":"Enabled"}}, - {"DisplayName":"Fire from Lightning","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_LightningFires","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.lightningFires","IncludeInCommandLine":false,"DefaultValue":"false","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Allow Underground Farming","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_AllowUndergroundFarming","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.allowUndergroundFarming","IncludeInCommandLine":false,"DefaultValue":"false","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Prevent Liquid Source Transport","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_NoLiquidSourceTransport","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.noLiquidSourceTransport","IncludeInCommandLine":false,"DefaultValue":"false","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Player Health Points","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_PlayerHealthPoints","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.playerHealthPoints","IncludeInCommandLine":false,"DefaultValue":"15","EnumValues":{"5":"5 hp","10":"10 hp","15":"15 hp (Standard)","20":"20 hp","25":"25 hp","30":"30 hp"}}, - {"DisplayName":"Health Regeneration Rate","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_PlayerHealthRegenSpeed","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.playerHealthRegenSpeed","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal (100%)","2":"200%","3":"300%","0.25":"25%","0.5":"50%","0.75":"75%","1.5":"150%"}}, - {"DisplayName":"Hunger Rate","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_PlayerHungerSpeed","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.playerHungerSpeed","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal (100%)","2":"200%","3":"300%","0.25":"25%","0.5":"50%","0.75":"75%","1.5":"150%"}}, - {"DisplayName":"Lung Capacity","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_LungCapacity","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.lungCapacity","IncludeInCommandLine":false,"DefaultValue":"40000","EnumValues":{"10000":"10 seconds","20000":"20 seconds","30000":"30 seconds","40000":"40 seconds (Standard)","60000":"60 seconds","120000":"2 minutes","3600000":"1 hour"}}, - {"DisplayName":"Body Temperature Hardiness","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_BodyTemperatureResistance","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.bodyTemperatureResistance","IncludeInCommandLine":false,"DefaultValue":"0","EnumValues":{"0":"0 °C (Standard)","10":"10 °C","20":"20 °C","-40":"-40 °C","-30":"-30 °C","-20":"-20 °C","-10":"-10 °C"}}, - {"DisplayName":"Walk Speed","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_PlayerMoveSpeed","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.playerMoveSpeed","IncludeInCommandLine":false,"DefaultValue":"1.5","EnumValues":{"1":"Reduced","2":"Fast","3":"Very fast","0.5":"Slow","1.5":"Normal"}}, - {"DisplayName":"Creature Hostility","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_CreatureHostility","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.creatureHostility","IncludeInCommandLine":false,"DefaultValue":"aggressive","EnumValues":{"aggressive":"Aggressive","passive":"Passive","off":"Off"}}, - {"DisplayName":"Creature Strength","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_CreatureStrength","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.creatureStrength","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal (100%)","2":"200%","3":"300%","0.25":"25%","0.5":"50%","0.75":"75%","1.5":"150%"}}, - {"DisplayName":"Creature Swim Speed","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_CreatureSwimSpeed","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.creatureSwimSpeed","IncludeInCommandLine":false,"DefaultValue":"2","EnumValues":{"1":"100%","2":"200% (Standard)","3":"300%","0.5":"50%","1.5":"150%","2.5":"250%"}}, - {"DisplayName":"Food Spoilage Rate","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_FoodSpoilSpeed","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.foodSpoilSpeed","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal (100%)","2":"200%","3":"300%","0.25":"25%","0.5":"50%","0.75":"75%","1.5":"150%"}}, - {"DisplayName":"Tree Sapling Growth Time","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_SaplingGrowthRate","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.saplingGrowthRate","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal (100%)","2":"200%","3":"300%","0.25":"25%","0.5":"50%","0.75":"75%","1.5":"150%"}}, - {"DisplayName":"Tool Durability","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_ToolDurability","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.toolDurability","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal (100%)","2":"200%","3":"300%","0.25":"25%","0.5":"50%","0.75":"75%","1.5":"150%"}}, - {"DisplayName":"Tool Mining Speed","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_ToolMiningSpeed","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.toolMiningSpeed","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal (100%)","2":"200%","3":"300%","0.25":"25%","0.5":"50%","0.75":"75%","1.5":"150%"}}, - {"DisplayName":"Prospecting Pick Node Radius","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_PropickNodeSearchRadius","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.propickNodeSearchRadius","IncludeInCommandLine":false,"DefaultValue":"6","EnumValues":{"0":"Disabled","2":"2 blocks","4":"4 blocks","6":"6 blocks (Standard)","8":"8 blocks"}}, - {"DisplayName":"Microblock Chiseling","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_MicroblockChiseling","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.microblockChiseling","IncludeInCommandLine":false,"DefaultValue":"stonewood","EnumValues":{"off":"Off","stonewood":"Stone, wood, and bricks","all":"Most cubic blocks"}}, - {"DisplayName":"Coordinate Overlay","Category":"World:public","Subcategory":"Map and Navigation:map:4","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_AllowCoordinateHud","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.allowCoordinateHud","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"World Map","Category":"World:public","Subcategory":"Map and Navigation:map:4","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_AllowMap","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.allowMap","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Color-accurate World Map","Category":"World:public","Subcategory":"Map and Navigation:map:4","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_ColorAccurateWorldmap","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.colorAccurateWorldmap","IncludeInCommandLine":false,"DefaultValue":"false","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Lore Content","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_LoreContent","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.loreContent","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Clutter Obtainable","Category":"World:public","Subcategory":"Survival Challenges:local_fire_department:3","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_ClutterObtainable","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.clutterObtainable","IncludeInCommandLine":false,"DefaultValue":"ifrepaired","EnumValues":{"ifrepaired":"Only after repair with glue","yes":"Yes, without repair","no":"No"}}, - {"DisplayName":"Temporal Stability","Category":"World:public","Subcategory":"Temporal Stability:storm:5","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_TemporalStability","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.temporalStability","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Temporal Storms","Category":"World:public","Subcategory":"Temporal Stability:storm:5","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_TemporalStorms","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.temporalStorms","IncludeInCommandLine":false,"DefaultValue":"sometimes","EnumValues":{"off":"Off","veryrare":"Very rare","rare":"Rare","sometimes":"Sometimes (Standard)","often":"Often","veryoften":"Very often"}}, - {"DisplayName":"Temporal Storm Length","Category":"World:public","Subcategory":"Temporal Stability:storm:5","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_TempstormDurationMul","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.tempstormDurationMul","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal (100%)","2":"200%","3":"300%","0.25":"25%","0.5":"50%","0.75":"75%","1.5":"150%"}}, - {"DisplayName":"Temporal Rifts","Category":"World:public","Subcategory":"Temporal Stability:storm:5","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_TemporalRifts","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.temporalRifts","IncludeInCommandLine":false,"DefaultValue":"visible","EnumValues":{"off":"Off","invisible":"Invisible","visible":"Visible"}}, - {"DisplayName":"Temporal Gear Respawn Uses","Category":"World:public","Subcategory":"Temporal Stability:storm:5","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_TemporalGearRespawnUses","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.temporalGearRespawnUses","IncludeInCommandLine":false,"DefaultValue":"20","EnumValues":{"1":"1 use","5":"5 uses","10":"10 uses","20":"20 uses (Standard)","50":"50 uses","100":"100 uses","-1":"Infinite"}}, - {"DisplayName":"Sleeping During Temporal Storms","Category":"World:public","Subcategory":"Temporal Stability:storm:5","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_TemporalStormSleeping","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.temporalStormSleeping","IncludeInCommandLine":false,"DefaultValue":"0","EnumValues":{"0":"Disallowed","1":"Allowed"}}, - {"DisplayName":"Climate Distribution","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_WorldClimate","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.worldClimate","IncludeInCommandLine":false,"DefaultValue":"realistic","EnumValues":{"realistic":"Realistic","patchy":"Patchy"}}, - {"DisplayName":"Landcover","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_Landcover","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.landcover","IncludeInCommandLine":false,"DefaultValue":"0.975","EnumValues":{"1":"100%","0.1":"10%","0.25":"25%","0.5":"50%","0.7":"70%","0.9":"90%","0.975":"97.5% (Standard)"}}, - {"DisplayName":"Landcover Scale","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_OceanScale","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.oceanscale","IncludeInCommandLine":false,"DefaultValue":"5","EnumValues":{"1":"100%","2":"200%","5":"500% (Standard)","0.1":"10%","0.25":"25%","0.5":"50%"}}, - {"DisplayName":"Upheaval Rate","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_UpheavelCommonness","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.upheavelCommonness","IncludeInCommandLine":false,"DefaultValue":"0.3","EnumValues":{"0":"0%","1":"100%","0.1":"10%","0.2":"20%","0.3":"30% (Standard)","0.4":"40%","0.5":"50%","0.6":"60%"}}, - {"DisplayName":"Geologic Activity","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_GeologicActivity","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.geologicActivity","IncludeInCommandLine":false,"DefaultValue":"0.05","EnumValues":{"0":"None","0.025":"Very rare","0.05":"Rare (Standard)","0.1":"Uncommon","0.2":"Common","0.4":"Very common"}}, - {"DisplayName":"Landform Scale","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_LandformScale","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.landformScale","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"100% (Standard)","2":"200%","3":"300%","0.2":"20%","0.5":"50%","1.5":"150%"}}, - {"DisplayName":"World Width","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_WorldWidth","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.worldWidth","IncludeInCommandLine":false,"DefaultValue":"1024000","EnumValues":{"32768":"32k blocks","102400":"100k blocks","256000":"250k blocks","512000":"500k blocks","1024000":"1M blocks (Standard)","2048000":"2M blocks","4096000":"4M blocks","8192000":"8M blocks"}}, - {"DisplayName":"World Length","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_WorldLength","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.worldLength","IncludeInCommandLine":false,"DefaultValue":"1024000","EnumValues":{"32768":"32k blocks","102400":"100k blocks","256000":"250k blocks","512000":"500k blocks","1024000":"1M blocks (Standard)","2048000":"2M blocks","4096000":"4M blocks","8192000":"8M blocks"}}, - {"DisplayName":"World Edge","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_WorldEdge","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.worldEdge","IncludeInCommandLine":false,"DefaultValue":"traversable","EnumValues":{"traversable":"Traversable (can fall down)","blocked":"Blocked"}}, - {"DisplayName":"Polar-Equator Distance","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_PolarEquatorDistance","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.polarEquatorDistance","IncludeInCommandLine":false,"DefaultValue":"100000","EnumValues":{"5000":"5k blocks","10000":"10k blocks","15000":"15k blocks","25000":"25k blocks","50000":"50k blocks","100000":"100k blocks (Standard)","200000":"200k blocks","400000":"400k blocks","800000":"800k blocks"}}, - {"DisplayName":"Story Structure Distance","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_StoryStructuresDistScaling","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.storyStructuresDistScaling","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"100% (Standard)","2":"200%","3":"300%","0.15":"15%","0.25":"25%","0.5":"50%","0.75":"75%","1.5":"150%"}}, - {"DisplayName":"Global Temperature","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_GlobalTemperature","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.globalTemperature","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal","2":"Hot","3":"Very hot","5":"Extreme heat","0.1":"Very cold","0.5":"Cold","1.5":"Warm"}}, - {"DisplayName":"Global Precipitation","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_GlobalPrecipitation","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.globalPrecipitation","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"Normal","2":"Very wet","3":"Extremely wet","5":"Maximum","0.1":"Very dry","0.5":"Dry","1.5":"Wet"}}, - {"DisplayName":"Forestation & Shrubs","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_GlobalForestation","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.globalForestation","IncludeInCommandLine":false,"DefaultValue":"0","EnumValues":{"0":"Normal","1":"Full coverage","-1":"None","-0.5":"Sparse","0.5":"Dense"}}, - {"DisplayName":"Global Deposit Spawn Rate","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_GlobalDepositSpawnRate","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.globalDepositSpawnRate","IncludeInCommandLine":false,"DefaultValue":"1","EnumValues":{"1":"100% (Standard)","2":"200%","3":"300%","0.2":"20%","0.5":"50%","0.75":"75%","1.5":"150%"}}, - {"DisplayName":"Surface Copper Frequency","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_SurfaceCopperDeposits","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.surfaceCopperDeposits","IncludeInCommandLine":false,"DefaultValue":"0.12","EnumValues":{"0":"None","0.007":"Extremely rare","0.04":"Very rare","0.08":"Rare","0.12":"Standard","0.2":"Common","0.4":"Very common"}}, - {"DisplayName":"Surface Tin Frequency","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_SurfaceTinDeposits","InputType":"enum","ParamFieldName":"$.WorldConfig.WorldConfiguration.surfaceTinDeposits","IncludeInCommandLine":false,"DefaultValue":"0.007","EnumValues":{"0":"None","0.003":"Extremely rare","0.007":"Standard","0.02":"Rare","0.05":"Uncommon","0.1":"Common"}}, - {"DisplayName":"Snow and Ice","Category":"World:public","Subcategory":"World Generation:terrain:6","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_SnowAccum","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.snowAccum","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Land Claiming","Category":"World:public","Subcategory":"Multiplayer:groups:7","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_AllowLandClaiming","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.allowLandClaiming","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Class-exclusive Recipes","Category":"World:public","Subcategory":"Multiplayer:groups:7","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_ClassExclusiveRecipes","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.classExclusiveRecipes","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Auction House","Category":"World:public","Subcategory":"Multiplayer:groups:7","Description":"New-world setting. Uses Vintage Story's documented configuration value.","Keywords":"world,setup","FieldName":"VS_AuctionHouse","InputType":"checkbox","ParamFieldName":"$.WorldConfig.WorldConfiguration.auctionHouse","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Nimbus Server ID","Category":"Nimbus Backend:share","Subcategory":"Connection:dns:1","Description":"Unique ID that must exactly match this backend's key in the Proxy Backend Servers map.","Keywords":"nimbus,id","FieldName":"NimbusServerId","InputType":"text","ParamFieldName":"$.ServerId","IncludeInCommandLine":false,"Required":true,"DefaultValue":"","Placeholder":"hub","EnumValues":{}}, - {"DisplayName":"Nimbus Display Name","Category":"Nimbus Backend:share","Subcategory":"Connection:dns:1","Description":"Friendly name for this backend.","Keywords":"nimbus,name","FieldName":"NimbusDisplayName","InputType":"text","ParamFieldName":"$.DisplayName","IncludeInCommandLine":false,"DefaultValue":"","Placeholder":"Hub","EnumValues":{}}, - {"DisplayName":"Proxy Public Host","Category":"Nimbus Backend:share","Subcategory":"Connection:dns:1","Description":"Public hostname or IP players use for Nimbus Proxy, not this private backend.","Keywords":"proxy,host","FieldName":"NimbusPublicHost","InputType":"text","ParamFieldName":"$.PublicHost","IncludeInCommandLine":false,"Required":true,"DefaultValue":"","Placeholder":"play.example.com","EnumValues":{}}, - {"DisplayName":"Proxy Public Port","Category":"Nimbus Backend:share","Subcategory":"Connection:dns:1","Description":"Public player port of Nimbus Proxy.","Keywords":"proxy,port","FieldName":"NimbusPublicPort","InputType":"number","ParamFieldName":"$.PublicPort","IncludeInCommandLine":false,"DefaultValue":"42420","MinValue":1,"MaxValue":65535,"EnumValues":{}}, - {"DisplayName":"Nimbus Registry URL","Category":"Nimbus Backend:share","Subcategory":"Registry:hub:2","Description":"HTTP URL reachable from this backend for the Proxy's embedded Registry or the optional standalone Registry.","Keywords":"registry,url","FieldName":"NimbusRegistryUrl","InputType":"text","ParamFieldName":"$.RegistryUrl","IncludeInCommandLine":false,"Required":true,"DefaultValue":"","Placeholder":"http://proxy-host:8765","EnumValues":{}}, - {"DisplayName":"Nimbus Shared Secret","Category":"Nimbus Backend:share","Subcategory":"Registry:hub:2","Description":"Copy the generated shared secret from the Proxy or standalone Registry. Backends never generate it.","Keywords":"registry,secret","FieldName":"NimbusSharedSecret","InputType":"password","ParamFieldName":"$.SharedSecret","IncludeInCommandLine":false,"Required":true,"DefaultValue":"","EnumValues":{}}, - {"DisplayName":"Maintenance Mode","Category":"Nimbus Backend:share","Subcategory":"Routing:swap_horiz:3","Description":"Keep this backend online but remove it from normal routing.","Keywords":"maintenance,routing","FieldName":"NimbusMaintenance","InputType":"checkbox","ParamFieldName":"$.Maintenance","IncludeInCommandLine":false,"DefaultValue":"false","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Allow Player Server Command","Category":"Nimbus Backend:share","Subcategory":"Routing:swap_horiz:3","Description":"Allow players to use Nimbus server-switch commands.","Keywords":"server,command","FieldName":"NimbusAllowPlayerServerCommand","InputType":"checkbox","ParamFieldName":"$.AllowPlayerServerCommand","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Anonymous Stratum Statistics","Category":"Stratum:security","Subcategory":"Privacy:visibility:1","Description":"Send Stratum's anonymous version and player-count statistics.","Keywords":"stratum,statistics","FieldName":"StratumServerStats","InputType":"checkbox","ParamFieldName":"$.ServerStats.Enabled","IncludeInCommandLine":false,"DefaultValue":"true","EnumValues":{"True":"true","False":"false"}}, - {"DisplayName":"Stratum Release Tag","Category":"Updates:update","Subcategory":"Version:verified_user:1","Description":"Optional exact Stratum release tag. Leave blank for the latest stable release; the release selects the compatible Vintage Story version.","Keywords":"stratum,version","FieldName":"StratumVersionTag","InputType":"text","ParamFieldName":"StratumVersionTag","IncludeInCommandLine":false,"DefaultValue":"","Placeholder":"v1.22.6-stratum.2","EnumValues":{}}, - {"DisplayName":"Nimbus Release Tag","Category":"Updates:update","Subcategory":"Version:verified_user:1","Description":"Optional exact Nimbus release tag. Leave blank for the latest stable release.","Keywords":"nimbus,version","FieldName":"NimbusVersionTag","InputType":"text","ParamFieldName":"NimbusVersionTag","IncludeInCommandLine":false,"DefaultValue":"","Placeholder":"v0.5.0","EnumValues":{}} +[ + { + "DisplayName": "Server Port", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Network:dns:1", + "Description": "Private game port used by Nimbus Proxy.", + "Keywords": "port,backend", + "FieldName": "$ServerPort", + "InputType": "number", + "Hidden": true, + "ParamFieldName": "$.Port", + "IncludeInCommandLine": false, + "DefaultValue": "42420", + "MinValue": 1, + "MaxValue": 65535, + "EnumValues": { + + } + }, + { + "DisplayName": "Player Limit", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Players:group:2", + "Description": "Maximum simultaneous players on this backend.", + "Keywords": "players,limit", + "FieldName": "$MaxUsers", + "InputType": "number", + "ParamFieldName": "$.MaxClients", + "IncludeInCommandLine": false, + "DefaultValue": "16", + "MinValue": 1, + "MaxValue": 1000, + "EnumValues": { + + } + }, + { + "DisplayName": "Server Name", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Identity:badge:1", + "Description": "Name shown by the Vintage Story server.", + "Keywords": "server,name", + "FieldName": "VS_ServerName", + "InputType": "text", + "ParamFieldName": "$.ServerName", + "IncludeInCommandLine": false, + "DefaultValue": "Vintage Story Server", + "EnumValues": { + + } + }, + { + "DisplayName": "Server Description", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Identity:badge:1", + "Description": "Short description shown to players.", + "Keywords": "server,description", + "FieldName": "VS_ServerDescription", + "InputType": "text", + "ParamFieldName": "$.ServerDescription", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": { + + } + }, + { + "DisplayName": "Welcome Message", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Identity:badge:1", + "Description": "Message shown after a player joins.", + "Keywords": "welcome,message", + "FieldName": "VS_WelcomeMessage", + "InputType": "text", + "ParamFieldName": "$.WelcomeMessage", + "IncludeInCommandLine": false, + "DefaultValue": "Welcome, {0}, may you survive well and prosper", + "EnumValues": { + + } + }, + { + "DisplayName": "Server Password", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Access:lock:3", + "Description": "Optional password required to join. Leave blank for none.", + "Keywords": "password,access", + "FieldName": "VS_Password", + "InputType": "password", + "ParamFieldName": "$.Password", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": { + + } + }, + { + "DisplayName": "Whitelist Mode", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Access:lock:3", + "Description": "Default follows Vintage Story dedicated-server policy.", + "Keywords": "whitelist,access", + "FieldName": "VS_WhitelistMode", + "InputType": "enum", + "ParamFieldName": "$.WhitelistMode", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": { + "0": "Default (on for dedicated servers)", + "1": "Off", + "2": "On" + } + }, + { + "DisplayName": "Allow PvP", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Rules:gavel:4", + "Description": "Allow players to damage other players.", + "Keywords": "pvp,rules", + "FieldName": "VS_AllowPvP", + "InputType": "checkbox", + "ParamFieldName": "$.AllowPvP", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Allow Fire Spread", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied at every server start. Allow fire to spread between flammable blocks.", + "Keywords": "world,fire,spread", + "FieldName": "VS_AllowFireSpread", + "InputType": "checkbox", + "ParamFieldName": "$.Server.AllowFireSpread", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Pass Time When Empty", + "Category": "Vintage Story:stadia_controller", + "Subcategory": "Rules:gavel:4", + "Description": "Advance world time while no players are online.", + "Keywords": "time,empty", + "FieldName": "VS_PassTimeWhenEmpty", + "InputType": "checkbox", + "ParamFieldName": "$.PassTimeWhenEmpty", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Apply World Settings to Existing Save", + "Category": "World:public", + "Subcategory": "Identity and Preset:language:1", + "Description": "Opt in to restart-based overrides for an existing save. Creation-only identity, seed, play style, height, dimensions, climate, and grace timer are never changed. World-generation changes affect only unexplored chunks and may create seams.", + "Keywords": "world,existing,override,restart,enforce", + "FieldName": "VS_ApplyWorldSettingsToExisting", + "InputType": "checkbox", + "ParamFieldName": "$.ApplyToExistingWorld", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "World Name", + "Category": "World:public", + "Subcategory": "Identity and Preset:language:1", + "Description": "New worlds only. Name for a newly created world. Most settings here only apply before the first save is generated.", + "Keywords": "world,name,setup", + "FieldName": "VS_WorldName", + "InputType": "text", + "ParamFieldName": "$.Creation.WorldName", + "IncludeInCommandLine": false, + "DefaultValue": "A new world", + "EnumValues": { + + } + }, + { + "DisplayName": "World Seed", + "Category": "World:public", + "Subcategory": "Identity and Preset:language:1", + "Description": "New worlds only. Optional seed for a newly created world. Leave blank for random.", + "Keywords": "world,seed,setup", + "FieldName": "VS_WorldSeed", + "InputType": "text", + "ParamFieldName": "$.Creation.Seed", + "IncludeInCommandLine": false, + "DefaultValue": "", + "EnumValues": { + + } + }, + { + "DisplayName": "Base Play Style", + "Category": "World:public", + "Subcategory": "Identity and Preset:language:1", + "Description": "New worlds only. Base preset. Every other visible World Setup value is an explicit override.", + "Keywords": "world,playstyle,setup", + "FieldName": "VS_PlayStyle", + "InputType": "enum", + "ParamFieldName": "$.Creation.PlayStyle", + "IncludeInCommandLine": false, + "DefaultValue": "surviveandbuild", + "EnumValues": { + "surviveandbuild": "Standard (Survive and Build)", + "exploration": "Exploration", + "wildernesssurvival": "Wilderness Survival", + "creativebuilding": "Creative Building" + } + }, + { + "DisplayName": "World Height", + "Category": "World:public", + "Subcategory": "Identity and Preset:language:1", + "Description": "New worlds only. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_WorldHeight", + "InputType": "enum", + "ParamFieldName": "$.Creation.MapSizeY", + "IncludeInCommandLine": false, + "DefaultValue": "256", + "EnumValues": { + "128": "128 blocks", + "192": "192 blocks", + "256": "256 blocks (Standard)", + "384": "384 blocks", + "448": "448 blocks", + "512": "512 blocks" + } + }, + { + "DisplayName": "Allow Falling Blocks", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied at every server start. Allow gravity-affected blocks to fall.", + "Keywords": "world,setup", + "FieldName": "VS_AllowFallingBlocks", + "InputType": "checkbox", + "ParamFieldName": "$.Server.AllowFallingBlocks", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Game Mode", + "Category": "World:public", + "Subcategory": "Player Spawn and Death:favorite:2", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_GameMode", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.gameMode", + "IncludeInCommandLine": false, + "DefaultValue": "survival", + "EnumValues": { + "survival": "Survival", + "creative": "Creative" + } + }, + { + "DisplayName": "Player Lives", + "Category": "World:public", + "Subcategory": "Player Spawn and Death:favorite:2", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_PlayerLives", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.playerlives", + "IncludeInCommandLine": false, + "DefaultValue": "-1", + "EnumValues": { + "1": "1 life", + "2": "2 lives", + "3": "3 lives", + "4": "4 lives", + "5": "5 lives", + "10": "10 lives", + "20": "20 lives", + "-1": "Infinite" + } + }, + { + "DisplayName": "Starting Climate", + "Category": "World:public", + "Subcategory": "Player Spawn and Death:favorite:2", + "Description": "New worlds only. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_StartingClimate", + "InputType": "enum", + "ParamFieldName": "$.CreationOnlyWorldConfiguration.startingClimate", + "IncludeInCommandLine": false, + "DefaultValue": "temperate", + "EnumValues": { + "hot": "Hot", + "warm": "Warm", + "temperate": "Temperate", + "cool": "Cool", + "icy": "Icy" + } + }, + { + "DisplayName": "Random Respawn Radius", + "Category": "World:public", + "Subcategory": "Player Spawn and Death:favorite:2", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_SpawnRadius", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.spawnRadius", + "IncludeInCommandLine": false, + "DefaultValue": "50", + "EnumValues": { + "0": "0 blocks", + "25": "25 blocks", + "50": "50 blocks", + "100": "100 blocks", + "250": "250 blocks", + "500": "500 blocks", + "1000": "1,000 blocks", + "2500": "2,500 blocks", + "5000": "5,000 blocks", + "10000": "10,000 blocks" + } + }, + { + "DisplayName": "Grace Timer", + "Category": "World:public", + "Subcategory": "Player Spawn and Death:favorite:2", + "Description": "New worlds only. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_GraceTimer", + "InputType": "enum", + "ParamFieldName": "$.CreationOnlyWorldConfiguration.graceTimer", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": { + "0": "None", + "1": "1 day", + "2": "2 days", + "3": "3 days", + "4": "4 days", + "5": "5 days", + "10": "10 days" + } + }, + { + "DisplayName": "Death Punishment", + "Category": "World:public", + "Subcategory": "Player Spawn and Death:favorite:2", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_DeathPunishment", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.deathPunishment", + "IncludeInCommandLine": false, + "DefaultValue": "drop", + "EnumValues": { + "drop": "Drop inventory contents", + "keep": "Keep inventory contents" + } + }, + { + "DisplayName": "Dropped-on-Death Item Timer", + "Category": "World:public", + "Subcategory": "Player Spawn and Death:favorite:2", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_DroppedItemsTimer", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.droppedItemsTimer", + "IncludeInCommandLine": false, + "DefaultValue": "600", + "EnumValues": { + "300": "5 minutes", + "600": "10 minutes", + "1200": "20 minutes", + "1800": "30 minutes", + "3600": "60 minutes" + } + }, + { + "DisplayName": "Seasons", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_Seasons", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.seasons", + "IncludeInCommandLine": false, + "DefaultValue": "enabled", + "EnumValues": { + "enabled": "Enabled", + "spring": "Always spring", + "summer": "Always summer", + "fall": "Always fall", + "winter": "Always winter" + } + }, + { + "DisplayName": "Days per Month", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_DaysPerMonth", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.daysPerMonth", + "IncludeInCommandLine": false, + "DefaultValue": "9", + "EnumValues": { + "3": "3 days", + "6": "6 days", + "9": "9 days (Standard)", + "12": "12 days", + "20": "20 days", + "30": "30 days" + } + }, + { + "DisplayName": "True Winters", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_HarshWinters", + "InputType": "checkbox", + "ParamFieldName": "$.ExistingWorld.harshWinters", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Block Gravity", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_BlockGravity", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.blockGravity", + "IncludeInCommandLine": false, + "DefaultValue": "sandgravel", + "EnumValues": { + "sandgravel": "Sand and gravel", + "sandgravelsoil": "Sand, gravel, and soil" + } + }, + { + "DisplayName": "Cave-ins", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_CaveIns", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.caveIns", + "IncludeInCommandLine": false, + "DefaultValue": "off", + "EnumValues": { + "off": "Disabled", + "on": "Enabled" + } + }, + { + "DisplayName": "Fire from Lightning", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_LightningFires", + "InputType": "checkbox", + "ParamFieldName": "$.ExistingWorld.lightningFires", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Allow Underground Farming", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_AllowUndergroundFarming", + "InputType": "checkbox", + "ParamFieldName": "$.ExistingWorld.allowUndergroundFarming", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Prevent Liquid Source Transport", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_NoLiquidSourceTransport", + "InputType": "checkbox", + "ParamFieldName": "$.ExistingWorld.noLiquidSourceTransport", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Player Health Points", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_PlayerHealthPoints", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.playerHealthPoints", + "IncludeInCommandLine": false, + "DefaultValue": "15", + "EnumValues": { + "5": "5 hp", + "10": "10 hp", + "15": "15 hp (Standard)", + "20": "20 hp", + "25": "25 hp", + "30": "30 hp" + } + }, + { + "DisplayName": "Health Regeneration Rate", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_PlayerHealthRegenSpeed", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.playerHealthRegenSpeed", + "IncludeInCommandLine": false, + "DefaultValue": "1", + "EnumValues": { + "1": "Normal (100%)", + "2": "200%", + "3": "300%", + "0.25": "25%", + "0.5": "50%", + "0.75": "75%", + "1.5": "150%" + } + }, + { + "DisplayName": "Hunger Rate", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_PlayerHungerSpeed", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.playerHungerSpeed", + "IncludeInCommandLine": false, + "DefaultValue": "1", + "EnumValues": { + "1": "Normal (100%)", + "2": "200%", + "3": "300%", + "0.25": "25%", + "0.5": "50%", + "0.75": "75%", + "1.5": "150%" + } + }, + { + "DisplayName": "Lung Capacity", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_LungCapacity", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.lungCapacity", + "IncludeInCommandLine": false, + "DefaultValue": "40000", + "EnumValues": { + "10000": "10 seconds", + "20000": "20 seconds", + "30000": "30 seconds", + "40000": "40 seconds (Standard)", + "60000": "60 seconds", + "120000": "2 minutes", + "3600000": "1 hour" + } + }, + { + "DisplayName": "Body Temperature Hardiness", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_BodyTemperatureResistance", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.bodyTemperatureResistance", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": { + "0": "0 °C (Standard)", + "10": "10 °C", + "20": "20 °C", + "-40": "-40 °C", + "-30": "-30 °C", + "-20": "-20 °C", + "-10": "-10 °C" + } + }, + { + "DisplayName": "Walk Speed", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_PlayerMoveSpeed", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.playerMoveSpeed", + "IncludeInCommandLine": false, + "DefaultValue": "1.5", + "EnumValues": { + "1": "Reduced", + "2": "Fast", + "3": "Very fast", + "0.5": "Slow", + "1.5": "Normal" + } + }, + { + "DisplayName": "Creature Hostility", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_CreatureHostility", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.creatureHostility", + "IncludeInCommandLine": false, + "DefaultValue": "aggressive", + "EnumValues": { + "aggressive": "Aggressive", + "passive": "Passive", + "off": "Off" + } + }, + { + "DisplayName": "Creature Strength", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_CreatureStrength", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.creatureStrength", + "IncludeInCommandLine": false, + "DefaultValue": "1", + "EnumValues": { + "1": "Normal (100%)", + "2": "200%", + "3": "300%", + "0.25": "25%", + "0.5": "50%", + "0.75": "75%", + "1.5": "150%" + } + }, + { + "DisplayName": "Creature Swim Speed", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_CreatureSwimSpeed", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.creatureSwimSpeed", + "IncludeInCommandLine": false, + "DefaultValue": "2", + "EnumValues": { + "1": "100%", + "2": "200% (Standard)", + "3": "300%", + "0.5": "50%", + "1.5": "150%", + "2.5": "250%" + } + }, + { + "DisplayName": "Food Spoilage Rate", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_FoodSpoilSpeed", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.foodSpoilSpeed", + "IncludeInCommandLine": false, + "DefaultValue": "1", + "EnumValues": { + "1": "Normal (100%)", + "2": "200%", + "3": "300%", + "0.25": "25%", + "0.5": "50%", + "0.75": "75%", + "1.5": "150%" + } + }, + { + "DisplayName": "Tree Sapling Growth Time", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_SaplingGrowthRate", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.saplingGrowthRate", + "IncludeInCommandLine": false, + "DefaultValue": "1", + "EnumValues": { + "1": "Normal (100%)", + "2": "200%", + "3": "300%", + "0.25": "25%", + "0.5": "50%", + "0.75": "75%", + "1.5": "150%" + } + }, + { + "DisplayName": "Tool Durability", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_ToolDurability", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.toolDurability", + "IncludeInCommandLine": false, + "DefaultValue": "1", + "EnumValues": { + "1": "Normal (100%)", + "2": "200%", + "3": "300%", + "0.25": "25%", + "0.5": "50%", + "0.75": "75%", + "1.5": "150%" + } + }, + { + "DisplayName": "Tool Mining Speed", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_ToolMiningSpeed", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.toolMiningSpeed", + "IncludeInCommandLine": false, + "DefaultValue": "1", + "EnumValues": { + "1": "Normal (100%)", + "2": "200%", + "3": "300%", + "0.25": "25%", + "0.5": "50%", + "0.75": "75%", + "1.5": "150%" + } + }, + { + "DisplayName": "Prospecting Pick Node Radius", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_PropickNodeSearchRadius", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.propickNodeSearchRadius", + "IncludeInCommandLine": false, + "DefaultValue": "6", + "EnumValues": { + "0": "Disabled", + "2": "2 blocks", + "4": "4 blocks", + "6": "6 blocks (Standard)", + "8": "8 blocks" + } + }, + { + "DisplayName": "Microblock Chiseling", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_MicroblockChiseling", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.microblockChiseling", + "IncludeInCommandLine": false, + "DefaultValue": "stonewood", + "EnumValues": { + "off": "Off", + "stonewood": "Stone, wood, and bricks", + "all": "Most cubic blocks" + } + }, + { + "DisplayName": "Coordinate Overlay", + "Category": "World:public", + "Subcategory": "Map and Navigation:map:4", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_AllowCoordinateHud", + "InputType": "checkbox", + "ParamFieldName": "$.ExistingWorld.allowCoordinateHud", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "World Map", + "Category": "World:public", + "Subcategory": "Map and Navigation:map:4", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_AllowMap", + "InputType": "checkbox", + "ParamFieldName": "$.ExistingWorld.allowMap", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Color-accurate World Map", + "Category": "World:public", + "Subcategory": "Map and Navigation:map:4", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_ColorAccurateWorldmap", + "InputType": "checkbox", + "ParamFieldName": "$.ExistingWorld.colorAccurateWorldmap", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Lore Content", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_LoreContent", + "InputType": "checkbox", + "ParamFieldName": "$.ExistingWorld.loreContent", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Clutter Obtainable", + "Category": "World:public", + "Subcategory": "Survival Challenges:local_fire_department:3", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_ClutterObtainable", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.clutterObtainable", + "IncludeInCommandLine": false, + "DefaultValue": "ifrepaired", + "EnumValues": { + "ifrepaired": "Only after repair with glue", + "yes": "Yes, without repair", + "no": "No" + } + }, + { + "DisplayName": "Temporal Stability", + "Category": "World:public", + "Subcategory": "Temporal Stability:storm:5", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_TemporalStability", + "InputType": "checkbox", + "ParamFieldName": "$.ExistingWorld.temporalStability", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Temporal Storms", + "Category": "World:public", + "Subcategory": "Temporal Stability:storm:5", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_TemporalStorms", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.temporalStorms", + "IncludeInCommandLine": false, + "DefaultValue": "sometimes", + "EnumValues": { + "off": "Off", + "veryrare": "Very rare", + "rare": "Rare", + "sometimes": "Sometimes (Standard)", + "often": "Often", + "veryoften": "Very often" + } + }, + { + "DisplayName": "Temporal Storm Length", + "Category": "World:public", + "Subcategory": "Temporal Stability:storm:5", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_TempstormDurationMul", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.tempstormDurationMul", + "IncludeInCommandLine": false, + "DefaultValue": "1", + "EnumValues": { + "1": "Normal (100%)", + "2": "200%", + "3": "300%", + "0.25": "25%", + "0.5": "50%", + "0.75": "75%", + "1.5": "150%" + } + }, + { + "DisplayName": "Temporal Rifts", + "Category": "World:public", + "Subcategory": "Temporal Stability:storm:5", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_TemporalRifts", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.temporalRifts", + "IncludeInCommandLine": false, + "DefaultValue": "visible", + "EnumValues": { + "off": "Off", + "invisible": "Invisible", + "visible": "Visible" + } + }, + { + "DisplayName": "Temporal Gear Respawn Uses", + "Category": "World:public", + "Subcategory": "Temporal Stability:storm:5", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_TemporalGearRespawnUses", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.temporalGearRespawnUses", + "IncludeInCommandLine": false, + "DefaultValue": "20", + "EnumValues": { + "1": "1 use", + "5": "5 uses", + "10": "10 uses", + "20": "20 uses (Standard)", + "50": "50 uses", + "100": "100 uses", + "-1": "Infinite" + } + }, + { + "DisplayName": "Sleeping During Temporal Storms", + "Category": "World:public", + "Subcategory": "Temporal Stability:storm:5", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_TemporalStormSleeping", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorld.temporalStormSleeping", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": { + "0": "Disallowed", + "1": "Allowed" + } + }, + { + "DisplayName": "Climate Distribution", + "Category": "World:public", + "Subcategory": "World Generation:terrain:6", + "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_WorldClimate", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorldgen.worldClimate", + "IncludeInCommandLine": false, + "DefaultValue": "realistic", + "EnumValues": { + "realistic": "Realistic", + "patchy": "Patchy" + } + }, + { + "DisplayName": "Landcover", + "Category": "World:public", + "Subcategory": "World Generation:terrain:6", + "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_Landcover", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorldgen.landcover", + "IncludeInCommandLine": false, + "DefaultValue": "0.975", + "EnumValues": { + "1": "100%", + "0.1": "10%", + "0.25": "25%", + "0.5": "50%", + "0.7": "70%", + "0.9": "90%", + "0.975": "97.5% (Standard)" + } + }, + { + "DisplayName": "Landcover Scale", + "Category": "World:public", + "Subcategory": "World Generation:terrain:6", + "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_OceanScale", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorldgen.oceanscale", + "IncludeInCommandLine": false, + "DefaultValue": "5", + "EnumValues": { + "1": "100%", + "2": "200%", + "5": "500% (Standard)", + "0.1": "10%", + "0.25": "25%", + "0.5": "50%" + } + }, + { + "DisplayName": "Upheaval Rate", + "Category": "World:public", + "Subcategory": "World Generation:terrain:6", + "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_UpheavelCommonness", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorldgen.upheavelCommonness", + "IncludeInCommandLine": false, + "DefaultValue": "0.3", + "EnumValues": { + "0": "0%", + "1": "100%", + "0.1": "10%", + "0.2": "20%", + "0.3": "30% (Standard)", + "0.4": "40%", + "0.5": "50%", + "0.6": "60%" + } + }, + { + "DisplayName": "Geologic Activity", + "Category": "World:public", + "Subcategory": "World Generation:terrain:6", + "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_GeologicActivity", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorldgen.geologicActivity", + "IncludeInCommandLine": false, + "DefaultValue": "0.05", + "EnumValues": { + "0": "None", + "0.025": "Very rare", + "0.05": "Rare (Standard)", + "0.1": "Uncommon", + "0.2": "Common", + "0.4": "Very common" + } + }, + { + "DisplayName": "Landform Scale", + "Category": "World:public", + "Subcategory": "World Generation:terrain:6", + "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_LandformScale", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorldgen.landformScale", + "IncludeInCommandLine": false, + "DefaultValue": "1", + "EnumValues": { + "1": "100% (Standard)", + "2": "200%", + "3": "300%", + "0.2": "20%", + "0.5": "50%", + "1.5": "150%" + } + }, + { + "DisplayName": "World Width", + "Category": "World:public", + "Subcategory": "World Generation:terrain:6", + "Description": "New worlds only. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_WorldWidth", + "InputType": "enum", + "ParamFieldName": "$.CreationOnlyWorldConfiguration.worldWidth", + "IncludeInCommandLine": false, + "DefaultValue": "1024000", + "EnumValues": { + "32768": "32k blocks", + "102400": "100k blocks", + "256000": "250k blocks", + "512000": "500k blocks", + "1024000": "1M blocks (Standard)", + "2048000": "2M blocks", + "4096000": "4M blocks", + "8192000": "8M blocks" + } + }, + { + "DisplayName": "World Length", + "Category": "World:public", + "Subcategory": "World Generation:terrain:6", + "Description": "New worlds only. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_WorldLength", + "InputType": "enum", + "ParamFieldName": "$.CreationOnlyWorldConfiguration.worldLength", + "IncludeInCommandLine": false, + "DefaultValue": "1024000", + "EnumValues": { + "32768": "32k blocks", + "102400": "100k blocks", + "256000": "250k blocks", + "512000": "500k blocks", + "1024000": "1M blocks (Standard)", + "2048000": "2M blocks", + "4096000": "4M blocks", + "8192000": "8M blocks" + } + }, + { + "DisplayName": "World Edge", + "Category": "World:public", + "Subcategory": "World Generation:terrain:6", + "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_WorldEdge", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorldgen.worldEdge", + "IncludeInCommandLine": false, + "DefaultValue": "traversable", + "EnumValues": { + "traversable": "Traversable (can fall down)", + "blocked": "Blocked" + } + }, + { + "DisplayName": "Polar-Equator Distance", + "Category": "World:public", + "Subcategory": "World Generation:terrain:6", + "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_PolarEquatorDistance", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorldgen.polarEquatorDistance", + "IncludeInCommandLine": false, + "DefaultValue": "100000", + "EnumValues": { + "5000": "5k blocks", + "10000": "10k blocks", + "15000": "15k blocks", + "25000": "25k blocks", + "50000": "50k blocks", + "100000": "100k blocks (Standard)", + "200000": "200k blocks", + "400000": "400k blocks", + "800000": "800k blocks" + } + }, + { + "DisplayName": "Story Structure Distance", + "Category": "World:public", + "Subcategory": "World Generation:terrain:6", + "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_StoryStructuresDistScaling", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorldgen.storyStructuresDistScaling", + "IncludeInCommandLine": false, + "DefaultValue": "1", + "EnumValues": { + "1": "100% (Standard)", + "2": "200%", + "3": "300%", + "0.15": "15%", + "0.25": "25%", + "0.5": "50%", + "0.75": "75%", + "1.5": "150%" + } + }, + { + "DisplayName": "Global Temperature", + "Category": "World:public", + "Subcategory": "World Generation:terrain:6", + "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_GlobalTemperature", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorldgen.globalTemperature", + "IncludeInCommandLine": false, + "DefaultValue": "1", + "EnumValues": { + "1": "Normal", + "2": "Hot", + "3": "Very hot", + "5": "Extreme heat", + "0.1": "Very cold", + "0.5": "Cold", + "1.5": "Warm" + } + }, + { + "DisplayName": "Global Precipitation", + "Category": "World:public", + "Subcategory": "World Generation:terrain:6", + "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_GlobalPrecipitation", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorldgen.globalPrecipitation", + "IncludeInCommandLine": false, + "DefaultValue": "1", + "EnumValues": { + "1": "Normal", + "2": "Very wet", + "3": "Extremely wet", + "5": "Maximum", + "0.1": "Very dry", + "0.5": "Dry", + "1.5": "Wet" + } + }, + { + "DisplayName": "Forestation \u0026 Shrubs", + "Category": "World:public", + "Subcategory": "World Generation:terrain:6", + "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_GlobalForestation", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorldgen.globalForestation", + "IncludeInCommandLine": false, + "DefaultValue": "0", + "EnumValues": { + "0": "Normal", + "1": "Full coverage", + "-1": "None", + "-0.5": "Sparse", + "0.5": "Dense" + } + }, + { + "DisplayName": "Global Deposit Spawn Rate", + "Category": "World:public", + "Subcategory": "World Generation:terrain:6", + "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_GlobalDepositSpawnRate", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorldgen.globalDepositSpawnRate", + "IncludeInCommandLine": false, + "DefaultValue": "1", + "EnumValues": { + "1": "100% (Standard)", + "2": "200%", + "3": "300%", + "0.2": "20%", + "0.5": "50%", + "0.75": "75%", + "1.5": "150%" + } + }, + { + "DisplayName": "Surface Copper Frequency", + "Category": "World:public", + "Subcategory": "World Generation:terrain:6", + "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_SurfaceCopperDeposits", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorldgen.surfaceCopperDeposits", + "IncludeInCommandLine": false, + "DefaultValue": "0.12", + "EnumValues": { + "0": "None", + "0.007": "Extremely rare", + "0.04": "Very rare", + "0.08": "Rare", + "0.12": "Standard", + "0.2": "Common", + "0.4": "Very common" + } + }, + { + "DisplayName": "Surface Tin Frequency", + "Category": "World:public", + "Subcategory": "World Generation:terrain:6", + "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_SurfaceTinDeposits", + "InputType": "enum", + "ParamFieldName": "$.ExistingWorldgen.surfaceTinDeposits", + "IncludeInCommandLine": false, + "DefaultValue": "0.007", + "EnumValues": { + "0": "None", + "0.003": "Extremely rare", + "0.007": "Standard", + "0.02": "Rare", + "0.05": "Uncommon", + "0.1": "Common" + } + }, + { + "DisplayName": "Snow and Ice", + "Category": "World:public", + "Subcategory": "World Generation:terrain:6", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_SnowAccum", + "InputType": "checkbox", + "ParamFieldName": "$.ExistingWorld.snowAccum", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Land Claiming", + "Category": "World:public", + "Subcategory": "Multiplayer:groups:7", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_AllowLandClaiming", + "InputType": "checkbox", + "ParamFieldName": "$.ExistingWorld.allowLandClaiming", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Class-exclusive Recipes", + "Category": "World:public", + "Subcategory": "Multiplayer:groups:7", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_ClassExclusiveRecipes", + "InputType": "checkbox", + "ParamFieldName": "$.ExistingWorld.classExclusiveRecipes", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Auction House", + "Category": "World:public", + "Subcategory": "Multiplayer:groups:7", + "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", + "Keywords": "world,setup", + "FieldName": "VS_AuctionHouse", + "InputType": "checkbox", + "ParamFieldName": "$.ExistingWorld.auctionHouse", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Nimbus Server ID", + "Category": "Nimbus Backend:share", + "Subcategory": "Connection:dns:1", + "Description": "Unique ID that must exactly match this backend\u0027s key in the Proxy Backend Servers map.", + "Keywords": "nimbus,id", + "FieldName": "NimbusServerId", + "InputType": "text", + "ParamFieldName": "$.ServerId", + "IncludeInCommandLine": false, + "Required": true, + "DefaultValue": "", + "Placeholder": "hub", + "EnumValues": { + + } + }, + { + "DisplayName": "Nimbus Display Name", + "Category": "Nimbus Backend:share", + "Subcategory": "Connection:dns:1", + "Description": "Friendly name for this backend.", + "Keywords": "nimbus,name", + "FieldName": "NimbusDisplayName", + "InputType": "text", + "ParamFieldName": "$.DisplayName", + "IncludeInCommandLine": false, + "DefaultValue": "", + "Placeholder": "Hub", + "EnumValues": { + + } + }, + { + "DisplayName": "Proxy Public Host", + "Category": "Nimbus Backend:share", + "Subcategory": "Connection:dns:1", + "Description": "Public hostname or IP players use for Nimbus Proxy, not this private backend.", + "Keywords": "proxy,host", + "FieldName": "NimbusPublicHost", + "InputType": "text", + "ParamFieldName": "$.PublicHost", + "IncludeInCommandLine": false, + "Required": true, + "DefaultValue": "", + "Placeholder": "play.example.com", + "EnumValues": { + + } + }, + { + "DisplayName": "Proxy Public Port", + "Category": "Nimbus Backend:share", + "Subcategory": "Connection:dns:1", + "Description": "Public player port of Nimbus Proxy.", + "Keywords": "proxy,port", + "FieldName": "NimbusPublicPort", + "InputType": "number", + "ParamFieldName": "$.PublicPort", + "IncludeInCommandLine": false, + "DefaultValue": "42420", + "MinValue": 1, + "MaxValue": 65535, + "EnumValues": { + + } + }, + { + "DisplayName": "Nimbus Registry URL", + "Category": "Nimbus Backend:share", + "Subcategory": "Registry:hub:2", + "Description": "HTTP URL reachable from this backend for the Proxy\u0027s embedded Registry or the optional standalone Registry.", + "Keywords": "registry,url", + "FieldName": "NimbusRegistryUrl", + "InputType": "text", + "ParamFieldName": "$.RegistryUrl", + "IncludeInCommandLine": false, + "Required": true, + "DefaultValue": "", + "Placeholder": "http://proxy-host:8765", + "EnumValues": { + + } + }, + { + "DisplayName": "Nimbus Shared Secret", + "Category": "Nimbus Backend:share", + "Subcategory": "Registry:hub:2", + "Description": "Copy the generated shared secret from the Proxy or standalone Registry. Backends never generate it.", + "Keywords": "registry,secret", + "FieldName": "NimbusSharedSecret", + "InputType": "password", + "ParamFieldName": "$.SharedSecret", + "IncludeInCommandLine": false, + "Required": true, + "DefaultValue": "", + "EnumValues": { + + } + }, + { + "DisplayName": "Maintenance Mode", + "Category": "Nimbus Backend:share", + "Subcategory": "Routing:swap_horiz:3", + "Description": "Keep this backend online but remove it from normal routing.", + "Keywords": "maintenance,routing", + "FieldName": "NimbusMaintenance", + "InputType": "checkbox", + "ParamFieldName": "$.Maintenance", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Allow Player Server Command", + "Category": "Nimbus Backend:share", + "Subcategory": "Routing:swap_horiz:3", + "Description": "Allow players to use Nimbus server-switch commands.", + "Keywords": "server,command", + "FieldName": "NimbusAllowPlayerServerCommand", + "InputType": "checkbox", + "ParamFieldName": "$.AllowPlayerServerCommand", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Anonymous Stratum Statistics", + "Category": "Stratum:security", + "Subcategory": "Privacy:visibility:1", + "Description": "Send Stratum\u0027s anonymous version and player-count statistics.", + "Keywords": "stratum,statistics", + "FieldName": "StratumServerStats", + "InputType": "checkbox", + "ParamFieldName": "$.ServerStats.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "true", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Stratum Release Tag", + "Category": "Updates:update", + "Subcategory": "Version:verified_user:1", + "Description": "Optional exact Stratum release tag. Leave blank for the latest stable release; the release selects the compatible Vintage Story version.", + "Keywords": "stratum,version", + "FieldName": "StratumVersionTag", + "InputType": "text", + "ParamFieldName": "StratumVersionTag", + "IncludeInCommandLine": false, + "DefaultValue": "", + "Placeholder": "v1.22.6-stratum.2", + "EnumValues": { + + } + }, + { + "DisplayName": "Nimbus Release Tag", + "Category": "Updates:update", + "Subcategory": "Version:verified_user:1", + "Description": "Optional exact Nimbus release tag. Leave blank for the latest stable release.", + "Keywords": "nimbus,version", + "FieldName": "NimbusVersionTag", + "InputType": "text", + "ParamFieldName": "NimbusVersionTag", + "IncludeInCommandLine": false, + "DefaultValue": "", + "Placeholder": "v0.5.0", + "EnumValues": { + + } + } ] diff --git a/vintage-story-stratummetaconfig.json b/vintage-story-stratummetaconfig.json index df80c95c2..2aae28417 100644 --- a/vintage-story-stratummetaconfig.json +++ b/vintage-story-stratummetaconfig.json @@ -1,5 +1,6 @@ [ {"ConfigFile":"data/serverconfig.json","AutoMap":true,"ConfigType":"json"}, + {"ConfigFile":"data/amp-world-settings.json","AutoMap":true,"ConfigType":"json"}, {"ConfigFile":"data/stratum.json","AutoMap":true,"ConfigType":"json"}, {"ConfigFile":"data/ModConfig/nimbus-server.json","AutoMap":true,"ConfigType":"json"} ] diff --git a/vintage-story-stratumstart.json b/vintage-story-stratumstart.json new file mode 100644 index 000000000..6ed40608f --- /dev/null +++ b/vintage-story-stratumstart.json @@ -0,0 +1,18 @@ +[ + { + "UpdateStageName":"Apply AMP world settings", + "UpdateSourcePlatform":"Linux", + "UpdateSource":"Executable", + "UpdateSourceData":"/bin/sh", + "UpdateSourceArgs":"\"{{$FullRootDir}}tools/apply-world-settings.sh\" \"{{$FullRootDir}}\"", + "SkipOnFailure":false + }, + { + "UpdateStageName":"Apply AMP world settings", + "UpdateSourcePlatform":"Windows", + "UpdateSource":"Executable", + "UpdateSourceData":"powershell.exe", + "UpdateSourceArgs":"-NoProfile -ExecutionPolicy Bypass -File \"{{$FullRootDir}}tools\\apply-world-settings.ps1\" -Root \"{{$FullRootDir}}\"", + "SkipOnFailure":false + } +] diff --git a/vintage-story-stratumupdates.json b/vintage-story-stratumupdates.json index a09f94288..15c094339 100644 --- a/vintage-story-stratumupdates.json +++ b/vintage-story-stratumupdates.json @@ -1,110 +1,184 @@ -[ - {"UpdateStageName":"Create server directory","UpdateSourcePlatform":"All","UpdateSource":"CreateDirectory","UpdateSourceArgs":"{{$FullRootDir}}server","SkipOnFailure":false}, - {"UpdateStageName":"Create data directory","UpdateSourcePlatform":"All","UpdateSource":"CreateDirectory","UpdateSourceArgs":"{{$FullRootDir}}data","SkipOnFailure":false}, - {"UpdateStageName":"Create Mods directory","UpdateSourcePlatform":"All","UpdateSource":"CreateDirectory","UpdateSourceArgs":"{{$FullRootDir}}data/Mods","SkipOnFailure":false}, - {"UpdateStageName":"Create ModConfig directory","UpdateSourcePlatform":"All","UpdateSource":"CreateDirectory","UpdateSourceArgs":"{{$FullRootDir}}data/ModConfig","SkipOnFailure":false}, - {"UpdateStageName":"Create dotnet directory","UpdateSourcePlatform":"All","UpdateSource":"CreateDirectory","UpdateSourceArgs":"{{$FullRootDir}}dotnet","SkipOnFailure":false}, - { - "UpdateStageName":"Install local .NET 10 runtime", - "UpdateSourcePlatform":"Linux", - "UpdateSourceArch":"x86_64", - "UpdateSource":"Executable", - "UpdateSourceData":"/bin/bash", - "UpdateSourceArgs":"-c \"set -euo pipefail; root='{{$FullRootDir}}'; if [ -x \\\"$root/dotnet/dotnet\\\" ] && \\\"$root/dotnet/dotnet\\\" --list-runtimes | grep -q '^Microsoft.NETCore.App 10\\.'; then echo '[AMP] .NET 10 runtime already installed'; else tmp=\\\"$(mktemp)\\\"; curl -fsSL https://dot.net/v1/dotnet-install.sh -o \\\"$tmp\\\"; bash \\\"$tmp\\\" --channel 10.0 --runtime dotnet --install-dir \\\"$root/dotnet\\\" --no-path; rm -f \\\"$tmp\\\"; fi\"", - "SkipOnFailure":false - }, - { - "UpdateStageName":"Install local .NET 10 runtime", - "UpdateSourcePlatform":"Windows", - "UpdateSource":"Executable", - "UpdateSourceData":"powershell.exe", - "UpdateSourceArgs":"-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference='Stop'; $root='{{$FullRootDir}}'; $dotnet=Join-Path $root 'dotnet\\dotnet.exe'; $ready=$false; if (Test-Path -LiteralPath $dotnet) { $ready=[bool]((& $dotnet --list-runtimes) -match '^Microsoft.NETCore.App 10\\.') }; if ($ready) { Write-Output '[AMP] .NET 10 runtime already installed' } else { $script=Join-Path $env:TEMP ('dotnet-install-'+[guid]::NewGuid().ToString('N')+'.ps1'); try { Invoke-WebRequest -UseBasicParsing -Uri https://dot.net/v1/dotnet-install.ps1 -OutFile $script; & $script -Channel 10.0 -Runtime dotnet -InstallDir (Join-Path $root 'dotnet') -NoPath } finally { Remove-Item -LiteralPath $script -Force -ErrorAction SilentlyContinue } }\"", - "SkipOnFailure":false - }, - { - "UpdateStageName":"Install Stratum release", - "UpdateSourcePlatform":"Linux", - "UpdateSourceArch":"x86_64", - "UpdateSource":"Executable", - "UpdateSourceData":"/bin/bash", - "UpdateSourceArgs":"-c \"set -euo pipefail; root='{{$FullRootDir}}'; tag='{{StratumVersionTag}}'; if [ -z \\\"$tag\\\" ]; then tag=\\\"$(curl -fsSL -H 'User-Agent: AMP-Clean-Template' https://api.github.com/repos/StratumServer/Stratum/releases/latest | jq -r .tag_name)\\\"; fi; case \\\"$tag\\\" in v*) ;; *) tag=\\\"v$tag\\\";; esac; version=\\\"${tag#v}\\\"; asset=\\\"stratum-${version}-linux-x64.zip\\\"; stage=\\\"$root/.amp-stratum-stage\\\"; archive=\\\"$root/.amp-stratum.zip\\\"; rm -rf \\\"$stage\\\"; mkdir -p \\\"$stage\\\"; curl -fL --retry 3 -o \\\"$archive\\\" \\\"https://github.com/StratumServer/Stratum/releases/download/$tag/$asset\\\"; unzip -q \\\"$archive\\\" -d \\\"$stage\\\"; rm -f \\\"$archive\\\"; test -x \\\"$stage/StratumServer\\\" || chmod +x \\\"$stage/StratumServer\\\"; test -x \\\"$stage/StratumServer\\\"; old=\\\"$root/.amp-stratum-old\\\"; rm -rf \\\"$old\\\"; if [ -d \\\"$root/server\\\" ]; then mv \\\"$root/server\\\" \\\"$old\\\"; fi; mv \\\"$stage\\\" \\\"$root/server\\\"; rm -rf \\\"$old\\\"; printf '%s' \\\"$tag\\\" > \\\"$root/server/.amp-stratum-release\\\"\"", - "SkipOnFailure":false - }, - { - "UpdateStageName":"Install Stratum release", - "UpdateSourcePlatform":"Windows", - "UpdateSource":"Executable", - "UpdateSourceData":"powershell.exe", - "UpdateSourceArgs":"-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference='Stop'; $ProgressPreference='SilentlyContinue'; $root='{{$FullRootDir}}'; $tag='{{StratumVersionTag}}'.Trim(); $headers=@{'User-Agent'='AMP-Clean-Template'}; if (-not $tag) { $tag=(Invoke-RestMethod -Headers $headers -Uri https://api.github.com/repos/StratumServer/Stratum/releases/latest).tag_name }; if (-not $tag.StartsWith('v')) { $tag='v'+$tag }; $version=$tag.TrimStart('v'); $asset='stratum-'+$version+'-win-x64.zip'; $stage=Join-Path $root '.amp-stratum-stage'; $archive=Join-Path $root '.amp-stratum.zip'; $server=Join-Path $root 'server'; $old=Join-Path $root '.amp-stratum-old'; Remove-Item -LiteralPath $stage,$old,$archive -Recurse -Force -ErrorAction SilentlyContinue; New-Item -ItemType Directory -Path $stage | Out-Null; Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri ('https://github.com/StratumServer/Stratum/releases/download/'+$tag+'/'+$asset) -OutFile $archive; Expand-Archive -LiteralPath $archive -DestinationPath $stage -Force; Remove-Item -LiteralPath $archive -Force; if (-not (Test-Path -LiteralPath (Join-Path $stage 'StratumServer.exe'))) { throw 'Stratum archive did not contain StratumServer.exe' }; if (Test-Path -LiteralPath $server) { Move-Item -LiteralPath $server -Destination $old }; try { Move-Item -LiteralPath $stage -Destination $server; Remove-Item -LiteralPath $old -Recurse -Force -ErrorAction SilentlyContinue } catch { if ((Test-Path -LiteralPath $old) -and -not (Test-Path -LiteralPath $server)) { Move-Item -LiteralPath $old -Destination $server }; throw }; [IO.File]::WriteAllText((Join-Path $server '.amp-stratum-release'),$tag,(New-Object Text.UTF8Encoding $false))\"", - "SkipOnFailure":false - }, - { - "UpdateStageName":"Prepare compatible Vintage Story server assets", - "UpdateSourcePlatform":"Linux", - "UpdateSourceArch":"x86_64", - "UpdateSource":"Executable", - "UpdateSourceData":"/bin/bash", - "UpdateSourceArgs":"-c \"set -euo pipefail; export DOTNET_ROOT='{{$FullRootDir}}dotnet'; cd '{{$FullRootDir}}server'; ./StratumServer --stratum-prepare-only --stratum-no-banner --dataPath '../data'\"", - "SkipOnFailure":false - }, - { - "UpdateStageName":"Prepare compatible Vintage Story server assets", - "UpdateSourcePlatform":"Windows", - "UpdateSource":"Executable", - "UpdateSourceData":"powershell.exe", - "UpdateSourceArgs":"-NoProfile -Command \"$env:DOTNET_ROOT='{{$FullRootDir}}dotnet'; Set-Location '{{$FullRootDir}}server'; & '.\\StratumServer.exe' --stratum-prepare-only --stratum-no-banner --dataPath '../data'; exit $LASTEXITCODE\"", - "SkipOnFailure":false - }, - { - "UpdateStageName":"Generate official Vintage Story configuration when missing", - "UpdateSourcePlatform":"Linux", - "UpdateSourceArch":"x86_64", - "UpdateSource":"Executable", - "UpdateSourceData":"/bin/bash", - "UpdateSourceArgs":"-c \"set -euo pipefail; if [ ! -f '{{$FullRootDir}}data/serverconfig.json' ]; then export DOTNET_ROOT='{{$FullRootDir}}dotnet'; cd '{{$FullRootDir}}server'; ./StratumServer --genconfig --dataPath '../data'; fi\"", - "SkipOnFailure":false - }, - { - "UpdateStageName":"Generate official Vintage Story configuration when missing", - "UpdateSourcePlatform":"Windows", - "UpdateSource":"Executable", - "UpdateSourceData":"powershell.exe", - "UpdateSourceArgs":"-NoProfile -Command \"$cfg='{{$FullRootDir}}data\\serverconfig.json'; if (-not (Test-Path -LiteralPath $cfg)) { $env:DOTNET_ROOT='{{$FullRootDir}}dotnet'; Set-Location '{{$FullRootDir}}server'; & '.\\StratumServer.exe' --genconfig --dataPath '../data'; exit $LASTEXITCODE }\"", - "SkipOnFailure":false - }, - { - "UpdateStageName":"Seed Stratum configuration when missing", - "UpdateSourcePlatform":"All", - "UpdateSource":"CreateFile", - "UpdateSourceArgs":"{{$FullRootDir}}data/stratum.json", - "UpdateSourceData":"{\n \"ServerStats\": {\n \"Enabled\": true\n }\n}\n", - "OverwriteExistingFiles":false, - "SkipOnFailure":false - }, - { - "UpdateStageName":"Seed Nimbus backend configuration when missing", - "UpdateSourcePlatform":"All", - "UpdateSource":"CreateFile", - "UpdateSourceArgs":"{{$FullRootDir}}data/ModConfig/nimbus-server.json", - "UpdateSourceData":"{\n \"Enabled\": true,\n \"ServerId\": \"\",\n \"DisplayName\": \"\",\n \"PublicHost\": \"\",\n \"PublicPort\": 42420,\n \"RegistryUrl\": \"\",\n \"SharedSecret\": \"\",\n \"HeartbeatIntervalSeconds\": 5,\n \"RegistryHttpTimeoutSeconds\": 5,\n \"Maintenance\": false,\n \"ReservationRequired\": true,\n \"FailClosedWhenRegistryUnreachable\": false,\n \"AllowPlayerServerCommand\": true,\n \"TransferMode\": \"redirect\",\n \"SeamlessPrepareAckTimeoutSeconds\": 8,\n \"ShortcutCommands\": [],\n \"Tags\": []\n}\n", - "OverwriteExistingFiles":false, - "SkipOnFailure":false - }, - { - "UpdateStageName":"Install Nimbus ServerMod", - "UpdateSourcePlatform":"Linux", - "UpdateSourceArch":"x86_64", - "UpdateSource":"Executable", - "UpdateSourceData":"/bin/bash", - "UpdateSourceArgs":"-c \"set -euo pipefail; root='{{$FullRootDir}}'; tag='{{NimbusVersionTag}}'; if [ -z \\\"$tag\\\" ]; then tag=\\\"$(curl -fsSL -H 'User-Agent: AMP-Clean-Template' https://api.github.com/repos/StratumServer/Nimbus/releases/latest | jq -r .tag_name)\\\"; fi; case \\\"$tag\\\" in v*) ;; *) tag=\\\"v$tag\\\";; esac; stage=\\\"$root/.amp-nimbus-mod-stage\\\"; archive=\\\"$root/.amp-nimbus-mod.zip\\\"; target=\\\"$root/data/Mods/Nimbus.ServerMod\\\"; rm -rf \\\"$stage\\\"; mkdir -p \\\"$stage\\\"; curl -fL --retry 3 -o \\\"$archive\\\" \\\"https://github.com/StratumServer/Nimbus/releases/download/$tag/Nimbus.ServerMod-$tag.zip\\\"; unzip -q \\\"$archive\\\" -d \\\"$stage\\\"; rm -f \\\"$archive\\\"; find \\\"$stage\\\" -type f | grep -q .; old=\\\"$root/.amp-nimbus-mod-old\\\"; rm -rf \\\"$old\\\"; if [ -d \\\"$target\\\" ]; then mv \\\"$target\\\" \\\"$old\\\"; fi; mv \\\"$stage\\\" \\\"$target\\\"; rm -rf \\\"$old\\\"; printf '%s' \\\"$tag\\\" > \\\"$target/.amp-nimbus-release\\\"\"", - "SkipOnFailure":false - }, - { - "UpdateStageName":"Install Nimbus ServerMod", - "UpdateSourcePlatform":"Windows", - "UpdateSource":"Executable", - "UpdateSourceData":"powershell.exe", - "UpdateSourceArgs":"-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference='Stop'; $ProgressPreference='SilentlyContinue'; $root='{{$FullRootDir}}'; $tag='{{NimbusVersionTag}}'.Trim(); $headers=@{'User-Agent'='AMP-Clean-Template'}; if (-not $tag) { $tag=(Invoke-RestMethod -Headers $headers -Uri https://api.github.com/repos/StratumServer/Nimbus/releases/latest).tag_name }; if (-not $tag.StartsWith('v')) { $tag='v'+$tag }; $stage=Join-Path $root '.amp-nimbus-mod-stage'; $archive=Join-Path $root '.amp-nimbus-mod.zip'; $target=Join-Path $root 'data\\Mods\\Nimbus.ServerMod'; $old=Join-Path $root '.amp-nimbus-mod-old'; Remove-Item -LiteralPath $stage,$old,$archive -Recurse -Force -ErrorAction SilentlyContinue; New-Item -ItemType Directory -Path $stage | Out-Null; Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri ('https://github.com/StratumServer/Nimbus/releases/download/'+$tag+'/Nimbus.ServerMod-'+$tag+'.zip') -OutFile $archive; Expand-Archive -LiteralPath $archive -DestinationPath $stage -Force; Remove-Item -LiteralPath $archive -Force; if (-not (Get-ChildItem -LiteralPath $stage -File -Recurse | Select-Object -First 1)) { throw 'Nimbus ServerMod archive was empty' }; if (Test-Path -LiteralPath $target) { Move-Item -LiteralPath $target -Destination $old }; try { Move-Item -LiteralPath $stage -Destination $target; Remove-Item -LiteralPath $old -Recurse -Force -ErrorAction SilentlyContinue } catch { if ((Test-Path -LiteralPath $old) -and -not (Test-Path -LiteralPath $target)) { Move-Item -LiteralPath $old -Destination $target }; throw }; [IO.File]::WriteAllText((Join-Path $target '.amp-nimbus-release'),$tag,(New-Object Text.UTF8Encoding $false))\"", - "SkipOnFailure":false - } +[ + { + "UpdateStageName": "Create server directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}server", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create data directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}data", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create tools directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}tools", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create Mods directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}data/Mods", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create ModConfig directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}data/ModConfig", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create dotnet directory", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullRootDir}}dotnet", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Install local .NET 10 runtime", + "UpdateSourcePlatform": "Linux", + "UpdateSourceArch": "x86_64", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"set -euo pipefail; root=\u0027{{$FullRootDir}}\u0027; if [ -x \\\"$root/dotnet/dotnet\\\" ] \u0026\u0026 \\\"$root/dotnet/dotnet\\\" --list-runtimes | grep -q \u0027^Microsoft.NETCore.App 10\\.\u0027; then echo \u0027[AMP] .NET 10 runtime already installed\u0027; else tmp=\\\"$(mktemp)\\\"; curl -fsSL https://dot.net/v1/dotnet-install.sh -o \\\"$tmp\\\"; bash \\\"$tmp\\\" --channel 10.0 --runtime dotnet --install-dir \\\"$root/dotnet\\\" --no-path; rm -f \\\"$tmp\\\"; fi\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Install local .NET 10 runtime", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference=\u0027Stop\u0027; $root=\u0027{{$FullRootDir}}\u0027; $dotnet=Join-Path $root \u0027dotnet\\dotnet.exe\u0027; $ready=$false; if (Test-Path -LiteralPath $dotnet) { $ready=[bool]((\u0026 $dotnet --list-runtimes) -match \u0027^Microsoft.NETCore.App 10\\.\u0027) }; if ($ready) { Write-Output \u0027[AMP] .NET 10 runtime already installed\u0027 } else { $script=Join-Path $env:TEMP (\u0027dotnet-install-\u0027+[guid]::NewGuid().ToString(\u0027N\u0027)+\u0027.ps1\u0027); try { Invoke-WebRequest -UseBasicParsing -Uri https://dot.net/v1/dotnet-install.ps1 -OutFile $script; \u0026 $script -Channel 10.0 -Runtime dotnet -InstallDir (Join-Path $root \u0027dotnet\u0027) -NoPath } finally { Remove-Item -LiteralPath $script -Force -ErrorAction SilentlyContinue } }\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Install Stratum release", + "UpdateSourcePlatform": "Linux", + "UpdateSourceArch": "x86_64", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"set -euo pipefail; root=\u0027{{$FullRootDir}}\u0027; tag=\u0027{{StratumVersionTag}}\u0027; if [ -z \\\"$tag\\\" ]; then tag=\\\"$(curl -fsSL -H \u0027User-Agent: AMP-Clean-Template\u0027 https://api.github.com/repos/StratumServer/Stratum/releases/latest | jq -r .tag_name)\\\"; fi; case \\\"$tag\\\" in v*) ;; *) tag=\\\"v$tag\\\";; esac; version=\\\"${tag#v}\\\"; asset=\\\"stratum-${version}-linux-x64.zip\\\"; stage=\\\"$root/.amp-stratum-stage\\\"; archive=\\\"$root/.amp-stratum.zip\\\"; rm -rf \\\"$stage\\\"; mkdir -p \\\"$stage\\\"; curl -fL --retry 3 -o \\\"$archive\\\" \\\"https://github.com/StratumServer/Stratum/releases/download/$tag/$asset\\\"; unzip -q \\\"$archive\\\" -d \\\"$stage\\\"; rm -f \\\"$archive\\\"; test -x \\\"$stage/StratumServer\\\" || chmod +x \\\"$stage/StratumServer\\\"; test -x \\\"$stage/StratumServer\\\"; old=\\\"$root/.amp-stratum-old\\\"; rm -rf \\\"$old\\\"; if [ -d \\\"$root/server\\\" ]; then mv \\\"$root/server\\\" \\\"$old\\\"; fi; mv \\\"$stage\\\" \\\"$root/server\\\"; rm -rf \\\"$old\\\"; printf \u0027%s\u0027 \\\"$tag\\\" \u003e \\\"$root/server/.amp-stratum-release\\\"\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Install Stratum release", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference=\u0027Stop\u0027; $ProgressPreference=\u0027SilentlyContinue\u0027; $root=\u0027{{$FullRootDir}}\u0027; $tag=\u0027{{StratumVersionTag}}\u0027.Trim(); $headers=@{\u0027User-Agent\u0027=\u0027AMP-Clean-Template\u0027}; if (-not $tag) { $tag=(Invoke-RestMethod -Headers $headers -Uri https://api.github.com/repos/StratumServer/Stratum/releases/latest).tag_name }; if (-not $tag.StartsWith(\u0027v\u0027)) { $tag=\u0027v\u0027+$tag }; $version=$tag.TrimStart(\u0027v\u0027); $asset=\u0027stratum-\u0027+$version+\u0027-win-x64.zip\u0027; $stage=Join-Path $root \u0027.amp-stratum-stage\u0027; $archive=Join-Path $root \u0027.amp-stratum.zip\u0027; $server=Join-Path $root \u0027server\u0027; $old=Join-Path $root \u0027.amp-stratum-old\u0027; Remove-Item -LiteralPath $stage,$old,$archive -Recurse -Force -ErrorAction SilentlyContinue; New-Item -ItemType Directory -Path $stage | Out-Null; Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri (\u0027https://github.com/StratumServer/Stratum/releases/download/\u0027+$tag+\u0027/\u0027+$asset) -OutFile $archive; Expand-Archive -LiteralPath $archive -DestinationPath $stage -Force; Remove-Item -LiteralPath $archive -Force; if (-not (Test-Path -LiteralPath (Join-Path $stage \u0027StratumServer.exe\u0027))) { throw \u0027Stratum archive did not contain StratumServer.exe\u0027 }; if (Test-Path -LiteralPath $server) { Move-Item -LiteralPath $server -Destination $old }; try { Move-Item -LiteralPath $stage -Destination $server; Remove-Item -LiteralPath $old -Recurse -Force -ErrorAction SilentlyContinue } catch { if ((Test-Path -LiteralPath $old) -and -not (Test-Path -LiteralPath $server)) { Move-Item -LiteralPath $old -Destination $server }; throw }; [IO.File]::WriteAllText((Join-Path $server \u0027.amp-stratum-release\u0027),$tag,(New-Object Text.UTF8Encoding $false))\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Prepare compatible Vintage Story server assets", + "UpdateSourcePlatform": "Linux", + "UpdateSourceArch": "x86_64", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"set -euo pipefail; export DOTNET_ROOT=\u0027{{$FullRootDir}}dotnet\u0027; cd \u0027{{$FullRootDir}}server\u0027; ./StratumServer --stratum-prepare-only --stratum-no-banner --dataPath \u0027../data\u0027\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Prepare compatible Vintage Story server assets", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -Command \"$env:DOTNET_ROOT=\u0027{{$FullRootDir}}dotnet\u0027; Set-Location \u0027{{$FullRootDir}}server\u0027; \u0026 \u0027.\\StratumServer.exe\u0027 --stratum-prepare-only --stratum-no-banner --dataPath \u0027../data\u0027; exit $LASTEXITCODE\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Generate official Vintage Story configuration when missing", + "UpdateSourcePlatform": "Linux", + "UpdateSourceArch": "x86_64", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"set -euo pipefail; if [ ! -f \u0027{{$FullRootDir}}data/serverconfig.json\u0027 ]; then export DOTNET_ROOT=\u0027{{$FullRootDir}}dotnet\u0027; cd \u0027{{$FullRootDir}}server\u0027; ./StratumServer --genconfig --dataPath \u0027../data\u0027; fi\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Generate official Vintage Story configuration when missing", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -Command \"$cfg=\u0027{{$FullRootDir}}data\\serverconfig.json\u0027; if (-not (Test-Path -LiteralPath $cfg)) { $env:DOTNET_ROOT=\u0027{{$FullRootDir}}dotnet\u0027; Set-Location \u0027{{$FullRootDir}}server\u0027; \u0026 \u0027.\\StratumServer.exe\u0027 --genconfig --dataPath \u0027../data\u0027; exit $LASTEXITCODE }\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Seed Stratum configuration when missing", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}data/stratum.json", + "UpdateSourceData": "{\n \"ServerStats\": {\n \"Enabled\": true\n }\n}\n", + "OverwriteExistingFiles": false, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Seed Nimbus backend configuration when missing", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}data/ModConfig/nimbus-server.json", + "UpdateSourceData": "{\n \"Enabled\": true,\n \"ServerId\": \"\",\n \"DisplayName\": \"\",\n \"PublicHost\": \"\",\n \"PublicPort\": 42420,\n \"RegistryUrl\": \"\",\n \"SharedSecret\": \"\",\n \"HeartbeatIntervalSeconds\": 5,\n \"RegistryHttpTimeoutSeconds\": 5,\n \"Maintenance\": false,\n \"ReservationRequired\": true,\n \"FailClosedWhenRegistryUnreachable\": false,\n \"AllowPlayerServerCommand\": true,\n \"TransferMode\": \"redirect\",\n \"SeamlessPrepareAckTimeoutSeconds\": 8,\n \"ShortcutCommands\": [],\n \"Tags\": []\n}\n", + "OverwriteExistingFiles": false, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Deploy AMP world settings contract", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}data/amp-world-settings-contract.json", + "UpdateSourceData": "[\r\n {\r\n \"Group\": \"Server\",\r\n \"Key\": \"AllowFireSpread\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"server\",\r\n \"CreationPath\": \"AllowFireSpread\",\r\n \"Command\": \"allowfirespread\"\r\n },\r\n {\r\n \"Group\": \"Creation\",\r\n \"Key\": \"WorldName\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"new-only\",\r\n \"CreationPath\": \"WorldConfig.WorldName\",\r\n \"Command\": null,\r\n \"MaxLength\": 128\r\n },\r\n {\r\n \"Group\": \"Creation\",\r\n \"Key\": \"Seed\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"new-only\",\r\n \"CreationPath\": \"WorldConfig.Seed\",\r\n \"Command\": null,\r\n \"MaxLength\": 256\r\n },\r\n {\r\n \"Group\": \"Creation\",\r\n \"Key\": \"PlayStyle\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"new-only\",\r\n \"CreationPath\": \"WorldConfig.PlayStyle\",\r\n \"Command\": null,\r\n \"Allowed\": [\r\n \"surviveandbuild\",\r\n \"exploration\",\r\n \"wildernesssurvival\",\r\n \"creativebuilding\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"Creation\",\r\n \"Key\": \"MapSizeY\",\r\n \"Type\": \"integer\",\r\n \"Lifecycle\": \"new-only\",\r\n \"CreationPath\": \"WorldConfig.MapSizeY\",\r\n \"Command\": null,\r\n \"Allowed\": [\r\n 128,\r\n 192,\r\n 256,\r\n 384,\r\n 448,\r\n 512\r\n ]\r\n },\r\n {\r\n \"Group\": \"Server\",\r\n \"Key\": \"AllowFallingBlocks\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"server\",\r\n \"CreationPath\": \"AllowFallingBlocks\",\r\n \"Command\": \"allowfallingblocks\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"gameMode\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.gameMode\",\r\n \"Command\": \"gameMode\",\r\n \"Allowed\": [\r\n \"survival\",\r\n \"creative\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"playerlives\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.playerlives\",\r\n \"Command\": \"playerlives\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"4\",\r\n \"5\",\r\n \"10\",\r\n \"20\",\r\n \"-1\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"CreationOnlyWorldConfiguration\",\r\n \"Key\": \"startingClimate\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"new-only\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.startingClimate\",\r\n \"Command\": null,\r\n \"Allowed\": [\r\n \"hot\",\r\n \"warm\",\r\n \"temperate\",\r\n \"cool\",\r\n \"icy\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"spawnRadius\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.spawnRadius\",\r\n \"Command\": \"spawnRadius\",\r\n \"Allowed\": [\r\n \"0\",\r\n \"25\",\r\n \"50\",\r\n \"100\",\r\n \"250\",\r\n \"500\",\r\n \"1000\",\r\n \"2500\",\r\n \"5000\",\r\n \"10000\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"CreationOnlyWorldConfiguration\",\r\n \"Key\": \"graceTimer\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"new-only\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.graceTimer\",\r\n \"Command\": null,\r\n \"Allowed\": [\r\n \"0\",\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"4\",\r\n \"5\",\r\n \"10\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"deathPunishment\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.deathPunishment\",\r\n \"Command\": \"deathPunishment\",\r\n \"Allowed\": [\r\n \"drop\",\r\n \"keep\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"droppedItemsTimer\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.droppedItemsTimer\",\r\n \"Command\": \"droppedItemsTimer\",\r\n \"Allowed\": [\r\n \"300\",\r\n \"600\",\r\n \"1200\",\r\n \"1800\",\r\n \"3600\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"seasons\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.seasons\",\r\n \"Command\": \"seasons\",\r\n \"Allowed\": [\r\n \"enabled\",\r\n \"spring\",\r\n \"summer\",\r\n \"fall\",\r\n \"winter\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"daysPerMonth\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.daysPerMonth\",\r\n \"Command\": \"daysPerMonth\",\r\n \"Allowed\": [\r\n \"3\",\r\n \"6\",\r\n \"9\",\r\n \"12\",\r\n \"20\",\r\n \"30\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"harshWinters\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.harshWinters\",\r\n \"Command\": \"harshWinters\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"blockGravity\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.blockGravity\",\r\n \"Command\": \"blockGravity\",\r\n \"Allowed\": [\r\n \"sandgravel\",\r\n \"sandgravelsoil\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"caveIns\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.caveIns\",\r\n \"Command\": \"caveIns\",\r\n \"Allowed\": [\r\n \"off\",\r\n \"on\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"lightningFires\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.lightningFires\",\r\n \"Command\": \"lightningFires\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"allowUndergroundFarming\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.allowUndergroundFarming\",\r\n \"Command\": \"allowUndergroundFarming\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"noLiquidSourceTransport\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.noLiquidSourceTransport\",\r\n \"Command\": \"noLiquidSourceTransport\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"playerHealthPoints\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.playerHealthPoints\",\r\n \"Command\": \"playerHealthPoints\",\r\n \"Allowed\": [\r\n \"5\",\r\n \"10\",\r\n \"15\",\r\n \"20\",\r\n \"25\",\r\n \"30\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"playerHealthRegenSpeed\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.playerHealthRegenSpeed\",\r\n \"Command\": \"playerHealthRegenSpeed\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"playerHungerSpeed\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.playerHungerSpeed\",\r\n \"Command\": \"playerHungerSpeed\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"lungCapacity\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.lungCapacity\",\r\n \"Command\": \"lungCapacity\",\r\n \"Allowed\": [\r\n \"10000\",\r\n \"20000\",\r\n \"30000\",\r\n \"40000\",\r\n \"60000\",\r\n \"120000\",\r\n \"3600000\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"bodyTemperatureResistance\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.bodyTemperatureResistance\",\r\n \"Command\": \"bodyTemperatureResistance\",\r\n \"Allowed\": [\r\n \"0\",\r\n \"10\",\r\n \"20\",\r\n \"-40\",\r\n \"-30\",\r\n \"-20\",\r\n \"-10\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"playerMoveSpeed\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.playerMoveSpeed\",\r\n \"Command\": \"playerMoveSpeed\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.5\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"creatureHostility\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.creatureHostility\",\r\n \"Command\": \"creatureHostility\",\r\n \"Allowed\": [\r\n \"aggressive\",\r\n \"passive\",\r\n \"off\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"creatureStrength\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.creatureStrength\",\r\n \"Command\": \"creatureStrength\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"creatureSwimSpeed\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.creatureSwimSpeed\",\r\n \"Command\": \"creatureSwimSpeed\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.5\",\r\n \"1.5\",\r\n \"2.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"foodSpoilSpeed\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.foodSpoilSpeed\",\r\n \"Command\": \"foodSpoilSpeed\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"saplingGrowthRate\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.saplingGrowthRate\",\r\n \"Command\": \"saplingGrowthRate\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"toolDurability\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.toolDurability\",\r\n \"Command\": \"toolDurability\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"toolMiningSpeed\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.toolMiningSpeed\",\r\n \"Command\": \"toolMiningSpeed\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"propickNodeSearchRadius\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.propickNodeSearchRadius\",\r\n \"Command\": \"propickNodeSearchRadius\",\r\n \"Allowed\": [\r\n \"0\",\r\n \"2\",\r\n \"4\",\r\n \"6\",\r\n \"8\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"microblockChiseling\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.microblockChiseling\",\r\n \"Command\": \"microblockChiseling\",\r\n \"Allowed\": [\r\n \"off\",\r\n \"stonewood\",\r\n \"all\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"allowCoordinateHud\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.allowCoordinateHud\",\r\n \"Command\": \"allowCoordinateHud\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"allowMap\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.allowMap\",\r\n \"Command\": \"allowMap\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"colorAccurateWorldmap\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.colorAccurateWorldmap\",\r\n \"Command\": \"colorAccurateWorldmap\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"loreContent\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.loreContent\",\r\n \"Command\": \"loreContent\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"clutterObtainable\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.clutterObtainable\",\r\n \"Command\": \"clutterObtainable\",\r\n \"Allowed\": [\r\n \"ifrepaired\",\r\n \"yes\",\r\n \"no\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"temporalStability\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.temporalStability\",\r\n \"Command\": \"temporalStability\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"temporalStorms\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.temporalStorms\",\r\n \"Command\": \"temporalStorms\",\r\n \"Allowed\": [\r\n \"off\",\r\n \"veryrare\",\r\n \"rare\",\r\n \"sometimes\",\r\n \"often\",\r\n \"veryoften\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"tempstormDurationMul\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.tempstormDurationMul\",\r\n \"Command\": \"tempstormDurationMul\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"temporalRifts\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.temporalRifts\",\r\n \"Command\": \"temporalRifts\",\r\n \"Allowed\": [\r\n \"off\",\r\n \"invisible\",\r\n \"visible\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"temporalGearRespawnUses\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.temporalGearRespawnUses\",\r\n \"Command\": \"temporalGearRespawnUses\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"5\",\r\n \"10\",\r\n \"20\",\r\n \"50\",\r\n \"100\",\r\n \"-1\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"temporalStormSleeping\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.temporalStormSleeping\",\r\n \"Command\": \"temporalStormSleeping\",\r\n \"Allowed\": [\r\n \"0\",\r\n \"1\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"worldClimate\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.worldClimate\",\r\n \"Command\": \"worldClimate\",\r\n \"Allowed\": [\r\n \"realistic\",\r\n \"patchy\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"landcover\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.landcover\",\r\n \"Command\": \"landcover\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"0.1\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.7\",\r\n \"0.9\",\r\n \"0.975\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"oceanscale\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.oceanscale\",\r\n \"Command\": \"oceanscale\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"5\",\r\n \"0.1\",\r\n \"0.25\",\r\n \"0.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"upheavelCommonness\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.upheavelCommonness\",\r\n \"Command\": \"upheavelCommonness\",\r\n \"Allowed\": [\r\n \"0\",\r\n \"1\",\r\n \"0.1\",\r\n \"0.2\",\r\n \"0.3\",\r\n \"0.4\",\r\n \"0.5\",\r\n \"0.6\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"geologicActivity\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.geologicActivity\",\r\n \"Command\": \"geologicActivity\",\r\n \"Allowed\": [\r\n \"0\",\r\n \"0.025\",\r\n \"0.05\",\r\n \"0.1\",\r\n \"0.2\",\r\n \"0.4\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"landformScale\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.landformScale\",\r\n \"Command\": \"landformScale\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.2\",\r\n \"0.5\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"CreationOnlyWorldConfiguration\",\r\n \"Key\": \"worldWidth\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"new-only\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.worldWidth\",\r\n \"Command\": null,\r\n \"Allowed\": [\r\n \"32768\",\r\n \"102400\",\r\n \"256000\",\r\n \"512000\",\r\n \"1024000\",\r\n \"2048000\",\r\n \"4096000\",\r\n \"8192000\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"CreationOnlyWorldConfiguration\",\r\n \"Key\": \"worldLength\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"new-only\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.worldLength\",\r\n \"Command\": null,\r\n \"Allowed\": [\r\n \"32768\",\r\n \"102400\",\r\n \"256000\",\r\n \"512000\",\r\n \"1024000\",\r\n \"2048000\",\r\n \"4096000\",\r\n \"8192000\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"worldEdge\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.worldEdge\",\r\n \"Command\": \"worldEdge\",\r\n \"Allowed\": [\r\n \"traversable\",\r\n \"blocked\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"polarEquatorDistance\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.polarEquatorDistance\",\r\n \"Command\": \"polarEquatorDistance\",\r\n \"Allowed\": [\r\n \"5000\",\r\n \"10000\",\r\n \"15000\",\r\n \"25000\",\r\n \"50000\",\r\n \"100000\",\r\n \"200000\",\r\n \"400000\",\r\n \"800000\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"storyStructuresDistScaling\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.storyStructuresDistScaling\",\r\n \"Command\": \"storyStructuresDistScaling\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.15\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"globalTemperature\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.globalTemperature\",\r\n \"Command\": \"globalTemperature\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"5\",\r\n \"0.1\",\r\n \"0.5\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"globalPrecipitation\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.globalPrecipitation\",\r\n \"Command\": \"globalPrecipitation\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"5\",\r\n \"0.1\",\r\n \"0.5\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"globalForestation\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.globalForestation\",\r\n \"Command\": \"globalForestation\",\r\n \"Allowed\": [\r\n \"0\",\r\n \"1\",\r\n \"-1\",\r\n \"-0.5\",\r\n \"0.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"globalDepositSpawnRate\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.globalDepositSpawnRate\",\r\n \"Command\": \"globalDepositSpawnRate\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.2\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"surfaceCopperDeposits\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.surfaceCopperDeposits\",\r\n \"Command\": \"surfaceCopperDeposits\",\r\n \"Allowed\": [\r\n \"0\",\r\n \"0.007\",\r\n \"0.04\",\r\n \"0.08\",\r\n \"0.12\",\r\n \"0.2\",\r\n \"0.4\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"surfaceTinDeposits\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.surfaceTinDeposits\",\r\n \"Command\": \"surfaceTinDeposits\",\r\n \"Allowed\": [\r\n \"0\",\r\n \"0.003\",\r\n \"0.007\",\r\n \"0.02\",\r\n \"0.05\",\r\n \"0.1\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"snowAccum\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.snowAccum\",\r\n \"Command\": \"snowAccum\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"allowLandClaiming\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.allowLandClaiming\",\r\n \"Command\": \"allowLandClaiming\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"classExclusiveRecipes\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.classExclusiveRecipes\",\r\n \"Command\": \"classExclusiveRecipes\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"auctionHouse\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.auctionHouse\",\r\n \"Command\": \"auctionHouse\"\r\n }\r\n]\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Seed AMP world settings when missing", + "UpdateSourcePlatform": "All", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}data/amp-world-settings.json", + "UpdateSourceData": "{\n \"SchemaVersion\": 1,\n \"ApplyToExistingWorld\": false,\n \"Creation\": {\n \"WorldName\": \"A new world\",\n \"Seed\": \"\",\n \"PlayStyle\": \"surviveandbuild\",\n \"MapSizeY\": 256\n },\n \"CreationOnlyWorldConfiguration\": {\n \"startingClimate\": \"temperate\",\n \"graceTimer\": \"0\",\n \"worldWidth\": \"1024000\",\n \"worldLength\": \"1024000\"\n },\n \"ExistingWorld\": {\n \"gameMode\": \"survival\",\n \"playerlives\": \"-1\",\n \"spawnRadius\": \"50\",\n \"deathPunishment\": \"drop\",\n \"droppedItemsTimer\": \"600\",\n \"seasons\": \"enabled\",\n \"daysPerMonth\": \"9\",\n \"harshWinters\": true,\n \"blockGravity\": \"sandgravel\",\n \"caveIns\": \"off\",\n \"lightningFires\": false,\n \"allowUndergroundFarming\": false,\n \"noLiquidSourceTransport\": false,\n \"playerHealthPoints\": \"15\",\n \"playerHealthRegenSpeed\": \"1\",\n \"playerHungerSpeed\": \"1\",\n \"lungCapacity\": \"40000\",\n \"bodyTemperatureResistance\": \"0\",\n \"playerMoveSpeed\": \"1.5\",\n \"creatureHostility\": \"aggressive\",\n \"creatureStrength\": \"1\",\n \"creatureSwimSpeed\": \"2\",\n \"foodSpoilSpeed\": \"1\",\n \"saplingGrowthRate\": \"1\",\n \"toolDurability\": \"1\",\n \"toolMiningSpeed\": \"1\",\n \"propickNodeSearchRadius\": \"6\",\n \"microblockChiseling\": \"stonewood\",\n \"allowCoordinateHud\": true,\n \"allowMap\": true,\n \"colorAccurateWorldmap\": false,\n \"loreContent\": true,\n \"clutterObtainable\": \"ifrepaired\",\n \"temporalStability\": true,\n \"temporalStorms\": \"sometimes\",\n \"tempstormDurationMul\": \"1\",\n \"temporalRifts\": \"visible\",\n \"temporalGearRespawnUses\": \"20\",\n \"temporalStormSleeping\": \"0\",\n \"snowAccum\": true,\n \"allowLandClaiming\": true,\n \"classExclusiveRecipes\": true,\n \"auctionHouse\": true\n },\n \"ExistingWorldgen\": {\n \"worldClimate\": \"realistic\",\n \"landcover\": \"0.975\",\n \"oceanscale\": \"5\",\n \"upheavelCommonness\": \"0.3\",\n \"geologicActivity\": \"0.05\",\n \"landformScale\": \"1\",\n \"worldEdge\": \"traversable\",\n \"polarEquatorDistance\": \"100000\",\n \"storyStructuresDistScaling\": \"1\",\n \"globalTemperature\": \"1\",\n \"globalPrecipitation\": \"1\",\n \"globalForestation\": \"0\",\n \"globalDepositSpawnRate\": \"1\",\n \"surfaceCopperDeposits\": \"0.12\",\n \"surfaceTinDeposits\": \"0.007\"\n },\n \"Server\": {\n \"AllowFireSpread\": true,\n \"AllowFallingBlocks\": true\n }\n}\n", + "OverwriteExistingFiles": false, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Deploy AMP world settings renderer (Linux)", + "UpdateSourcePlatform": "Linux", + "UpdateSourceArch": "x86_64", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}tools/apply-world-settings.sh", + "UpdateSourceData": "#!/bin/sh\nset -eu\n\nfail() {\n printf \u0027%s\\n\u0027 \"[AMP World] ERROR: $*\" \u003e\u00262\n exit 1\n}\n\n[ \"$#\" -eq 1 ] || fail \u0027usage: apply-world-settings.sh INSTANCE_ROOT\u0027\ncommand -v jq \u003e/dev/null 2\u003e\u00261 || fail \u0027jq is required\u0027\ncommand -v realpath \u003e/dev/null 2\u003e\u00261 || fail \u0027realpath is required\u0027\n\nroot=$(realpath -m \"$1\")\ndata=\"$root/data\"\nmanaged=\"$data/amp-world-settings.json\"\ncontract=\"$data/amp-world-settings-contract.json\"\nconfig=\"$data/serverconfig.json\"\nstate=\"$data/amp-world-settings-state.json\"\nbackup=\"$data/serverconfig.json.amp-world-backup\"\n\n[ -f \"$managed\" ] || fail \"AMP world settings do not exist: $managed\"\n[ -f \"$contract\" ] || fail \"AMP world settings contract does not exist: $contract\"\n[ -f \"$config\" ] || fail \"Vintage Story serverconfig does not exist: $config\"\n\njq -e empty \"$managed\" \u003e/dev/null 2\u003e\u00261 || fail \u0027AMP world settings are not valid JSON\u0027\njq -e empty \"$contract\" \u003e/dev/null 2\u003e\u00261 || fail \u0027AMP world settings contract is not valid JSON\u0027\njq -e empty \"$config\" \u003e/dev/null 2\u003e\u00261 || fail \u0027Vintage Story serverconfig is not valid JSON\u0027\n\njq -e --slurpfile c \"$contract\" \u0027\n . as $m |\n ($m.SchemaVersion == 1) and\n (($m.ApplyToExistingWorld | type) == \"boolean\") and\n (($c[0] | type) == \"array\") and (($c[0] | length) == 68) and\n all($c[0][];\n . as $e |\n ($m | has($e.Group)) and ($m[$e.Group] | has($e.Key)) and\n ($m[$e.Group][$e.Key] as $v |\n (($e.Type == \"string\" and ($v | type) == \"string\") or\n ($e.Type == \"boolean\" and ($v | type) == \"boolean\") or\n ($e.Type == \"integer\" and ($v | type) == \"number\" and ($v | floor) == $v) or\n ($e.Type == \"number\" and ($v | type) == \"number\")) and\n (($e | has(\"Allowed\") | not) or (($e.Allowed | index($v)) != null)) and\n (($e | has(\"MaxLength\") | not) or (($v | length) \u003c= $e.MaxLength))))\n\u0027 \"$managed\" \u003e/dev/null 2\u003e\u00261 || fail \u0027managed settings failed schema, type, or allowed-value validation\u0027\n\nsave_location=$(jq -er \u0027.WorldConfig.SaveFileLocation | select(type == \"string\" and length \u003e 0)\u0027 \"$config\") || fail \u0027WorldConfig.SaveFileLocation is blank or missing\u0027\nserver_root=$(realpath -m \"$root/server\")\ndata_root=$(realpath -m \"$data\")\ncase \"$save_location\" in\n /*) save_path=$(realpath -m \"$save_location\") ;;\n *)\n save_path=$(realpath -m \"$server_root/$save_location\")\n case \"$save_path\" in\n \"$data_root\"/*) ;;\n *) fail \"relative SaveFileLocation escapes the instance data directory: $save_location\" ;;\n esac\n ;;\nesac\n\nif [ -f \"$save_path\" ]; then existing=true; else existing=false; fi\nenforce=$(jq -r \u0027.ApplyToExistingWorld\u0027 \"$managed\")\n\nrendered=$(mktemp \"$data/.serverconfig.json.tmp.XXXXXX\")\nnext_rendered=$(mktemp \"$data/.serverconfig.json.next.XXXXXX\")\nprevious_commands=$(mktemp \"$data/.amp-world-previous.XXXXXX\")\nmanaged_commands=$(mktemp \"$data/.amp-world-commands.XXXXXX\")\nstate_temp=$(mktemp \"$data/.amp-world-state.XXXXXX\")\ncleanup() {\n rm -f \"$rendered\" \"$next_rendered\" \"$previous_commands\" \"$managed_commands\" \"$state_temp\"\n}\ntrap cleanup EXIT HUP INT TERM\n\njq -S --slurpfile m \"$managed\" --slurpfile c \"$contract\" \u0027\n reduce ($c[0][] | select(.Group == \"Server\")) as $e\n (. ; setpath(($e.CreationPath | split(\".\")); $m[0][$e.Group][$e.Key]))\n\u0027 \"$config\" \u003e \"$rendered\" || fail \u0027could not render server settings\u0027\n\nif [ \"$existing\" = false ]; then\n jq -S --slurpfile m \"$managed\" --slurpfile c \"$contract\" \u0027\n .WorldConfig.WorldConfiguration = {} |\n reduce ($c[0][] | select(.Group != \"Server\")) as $e\n (. ; setpath(\n ($e.CreationPath | split(\".\"));\n (if $e.Group == \"Creation\" and $e.Key == \"Seed\" and $m[0][$e.Group][$e.Key] == \"\"\n then null else $m[0][$e.Group][$e.Key] end)\n ))\n \u0027 \"$rendered\" \u003e \"$next_rendered\" || fail \u0027could not render new-world settings\u0027\n mv -f \"$next_rendered\" \"$rendered\"\n printf \u0027[]\\n\u0027 \u003e \"$managed_commands\"\nelse\n if [ -f \"$state\" ]; then\n if jq -e \u0027.SchemaVersion == 1 and (.ManagedCommands | type) == \"array\" and all(.ManagedCommands[]; type == \"string\")\u0027 \"$state\" \u003e/dev/null 2\u003e\u00261; then\n jq -c \u0027.ManagedCommands\u0027 \"$state\" \u003e \"$previous_commands\"\n else\n printf \u0027%s\\n\u0027 \u0027[AMP World] WARNING: state file invalid; preserving all existing startup commands\u0027 \u003e\u00262\n printf \u0027[]\\n\u0027 \u003e \"$previous_commands\"\n fi\n else\n printf \u0027[]\\n\u0027 \u003e \"$previous_commands\"\n fi\n\n if [ \"$enforce\" = true ]; then\n jq -c -n --slurpfile m \"$managed\" --slurpfile c \"$contract\" \u0027\n [$c[0][] | select(.Lifecycle == \"restart\" or .Lifecycle == \"unexplored\" or .Lifecycle == \"server\") |\n . as $e | ($m[0][$e.Group][$e.Key] | tostring) as $value |\n (if $e.Lifecycle == \"server\" then \"/serverconfig \" else \"/worldconfig \" end) + $e.Command + \" \" + $value]\n \u0027 \u003e \"$managed_commands\" || fail \u0027could not generate managed startup commands\u0027\n else\n printf \u0027[]\\n\u0027 \u003e \"$managed_commands\"\n fi\n\n jq -S --slurpfile old \"$previous_commands\" --slurpfile managed \"$managed_commands\" \u0027\n ((.StartupCommands // \"\") | split(\"\\n\") | map(sub(\"\\r$\"; \"\")) |\n map(select(length \u003e 0)) | map(. as $line | select(($old[0] | index($line)) == null))) as $custom |\n .StartupCommands = (($custom + $managed[0]) | join(\"\\n\"))\n \u0027 \"$rendered\" \u003e \"$next_rendered\" || fail \u0027could not reconcile startup commands\u0027\n mv -f \"$next_rendered\" \"$rendered\"\n jq -S -n --slurpfile commands \"$managed_commands\" \u0027{SchemaVersion:1, ManagedCommands:$commands[0]}\u0027 \u003e \"$state_temp\" || fail \u0027could not render managed state\u0027\nfi\n\njq -e empty \"$rendered\" \u003e/dev/null 2\u003e\u00261 || fail \u0027rendered serverconfig failed JSON validation\u0027\nif [ \"$existing\" = true ]; then jq -e empty \"$state_temp\" \u003e/dev/null 2\u003e\u00261 || fail \u0027rendered state failed JSON validation\u0027; fi\n\nchanged=false\nif ! cmp -s \"$rendered\" \"$config\"; then\n cp -p \"$config\" \"$backup\" || fail \u0027could not create serverconfig.json.amp-world-backup\u0027\n mv -f \"$rendered\" \"$config\" || fail \u0027could not atomically replace serverconfig.json\u0027\n changed=true\nfi\n\nif [ \"$existing\" = true ]; then\n if [ ! -f \"$state\" ] || ! cmp -s \"$state_temp\" \"$state\"; then\n if ! mv -f \"$state_temp\" \"$state\"; then\n if [ \"$changed\" = true ] \u0026\u0026 [ -f \"$backup\" ]; then\n rollback=$(mktemp \"$data/.serverconfig.rollback.XXXXXX\")\n cp -p \"$backup\" \"$rollback\" \u0026\u0026 mv -f \"$rollback\" \"$config\"\n fi\n fail \u0027could not atomically replace AMP world settings state\u0027\n fi\n fi\nfi\n\ncommand_count=$(jq -r \u0027length\u0027 \"$managed_commands\")\nif [ \"$existing\" = true ]; then creation_count=0; mode=existing; else creation_count=68; mode=new; fi\nprintf \u0027%s\\n\u0027 \"[AMP World] save=$mode enforcement=$enforce creation-values=$creation_count managed-commands=$command_count\"\nif [ \"$existing\" = true ] \u0026\u0026 [ \"$enforce\" = true ]; then\n printf \u0027%s\\n\u0027 \u0027[AMP World] WARNING: world-generation overrides affect only unexplored chunks and may create visible terrain borders\u0027 \u003e\u00262\nfi\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Deploy AMP world settings renderer (Windows)", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "CreateFile", + "UpdateSourceArgs": "{{$FullRootDir}}tools/apply-world-settings.ps1", + "UpdateSourceData": "[CmdletBinding()]\nparam(\n [Parameter(Mandatory=$true)]\n [string]$Root\n)\n\n$ErrorActionPreference = \u0027Stop\u0027\n\nfunction Read-JsonFile([string]$Path, [string]$Label) {\n if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) { throw \"$Label does not exist: $Path\" }\n try { return (Get-Content -Raw -LiteralPath $Path | ConvertFrom-Json) }\n catch { throw \"$Label is not valid JSON: $($_.Exception.Message)\" }\n}\n\nfunction Get-PropertyValue([object]$Object, [string]$Name) {\n if ($null -eq $Object) { throw \"Missing object containing \u0027$Name\u0027\" }\n $property = $Object.PSObject.Properties[$Name]\n if ($null -eq $property) { throw \"Missing required managed setting \u0027$Name\u0027\" }\n return $property.Value\n}\n\nfunction Test-ExactAllowed([object]$Value, [object[]]$Allowed) {\n foreach ($candidate in $Allowed) {\n if ($Value -is [string] -and $candidate -is [string]) {\n if ($Value -ceq $candidate) { return $true }\n }\n elseif ($Value -eq $candidate) { return $true }\n }\n return $false\n}\n\nfunction Assert-ContractValue([object]$Value, [object]$Entry) {\n $validType = switch ([string]$Entry.Type) {\n \u0027string\u0027 { $Value -is [string] }\n \u0027boolean\u0027 { $Value -is [bool] }\n \u0027integer\u0027 { $Value -is [int] -or $Value -is [long] }\n \u0027number\u0027 { $Value -is [int] -or $Value -is [long] -or $Value -is [double] -or $Value -is [decimal] }\n default { $false }\n }\n if (-not $validType) { throw \"$($Entry.Group).$($Entry.Key) must be $($Entry.Type)\" }\n\n $allowedProperty = $Entry.PSObject.Properties[\u0027Allowed\u0027]\n if ($null -ne $allowedProperty -and -not (Test-ExactAllowed $Value @($allowedProperty.Value))) {\n throw \"$($Entry.Group).$($Entry.Key) has unsupported value \u0027$Value\u0027\"\n }\n $maxLengthProperty = $Entry.PSObject.Properties[\u0027MaxLength\u0027]\n if ($null -ne $maxLengthProperty -and ([string]$Value).Length -gt [int]$maxLengthProperty.Value) {\n throw \"$($Entry.Group).$($Entry.Key) exceeds $($maxLengthProperty.Value) characters\"\n }\n}\n\nfunction Set-JsonPath([object]$Object, [string]$DotPath, [object]$Value) {\n $segments = @($DotPath -split \u0027\\.\u0027)\n $cursor = $Object\n for ($index = 0; $index -lt $segments.Count - 1; $index++) {\n $segment = $segments[$index]\n $property = $cursor.PSObject.Properties[$segment]\n if ($null -eq $property -or $null -eq $property.Value) {\n $child = [pscustomobject]@{}\n if ($null -eq $property) { $cursor | Add-Member -NotePropertyName $segment -NotePropertyValue $child }\n else { $property.Value = $child }\n $cursor = $child\n }\n else { $cursor = $property.Value }\n }\n $leaf = $segments[-1]\n $leafProperty = $cursor.PSObject.Properties[$leaf]\n if ($null -eq $leafProperty) { $cursor | Add-Member -NotePropertyName $leaf -NotePropertyValue $Value }\n else { $leafProperty.Value = $Value }\n}\n\nfunction Resolve-EffectiveSavePath([string]$RootPath, [string]$ConfiguredPath) {\n if ([string]::IsNullOrWhiteSpace($ConfiguredPath)) { throw \u0027WorldConfig.SaveFileLocation is blank\u0027 }\n if ([IO.Path]::IsPathRooted($ConfiguredPath)) { return [IO.Path]::GetFullPath($ConfiguredPath) }\n $serverRoot = [IO.Path]::GetFullPath((Join-Path $RootPath \u0027server\u0027))\n $resolved = [IO.Path]::GetFullPath((Join-Path $serverRoot $ConfiguredPath))\n $dataRoot = [IO.Path]::GetFullPath((Join-Path $RootPath \u0027data\u0027)).TrimEnd(\u0027\\\u0027,\u0027/\u0027) + [IO.Path]::DirectorySeparatorChar\n if (-not $resolved.StartsWith($dataRoot, [StringComparison]::OrdinalIgnoreCase)) {\n throw \"Relative SaveFileLocation escapes the instance data directory: $ConfiguredPath\"\n }\n return $resolved\n}\n\nfunction ConvertTo-CommandValue([object]$Value) {\n if ($Value -is [bool]) { return $Value.ToString().ToLowerInvariant() }\n if ($Value -is [IFormattable]) { return $Value.ToString($null, [Globalization.CultureInfo]::InvariantCulture) }\n return [string]$Value\n}\n\nfunction ConvertTo-StableJson([object]$Value) {\n return (($Value | ConvertTo-Json -Depth 40) + \"`n\")\n}\n\nfunction Write-ValidatedTemp([string]$Destination, [string]$Text) {\n $directory = Split-Path -Parent $Destination\n $temporary = Join-Path $directory (\u0027.\u0027 + [IO.Path]::GetFileName($Destination) + \u0027.tmp-\u0027 + [guid]::NewGuid().ToString(\u0027N\u0027))\n [IO.File]::WriteAllText($temporary, $Text, (New-Object Text.UTF8Encoding $false))\n try { Get-Content -Raw -LiteralPath $temporary | ConvertFrom-Json | Out-Null }\n catch { Remove-Item -LiteralPath $temporary -Force -ErrorAction SilentlyContinue; throw \"Rendered JSON validation failed for $Destination\" }\n return $temporary\n}\n\nfunction Replace-File([string]$Temporary, [string]$Destination, [string]$Backup = \u0027\u0027) {\n if (Test-Path -LiteralPath $Destination -PathType Leaf) {\n if ([string]::IsNullOrEmpty($Backup)) {\n $discardBackup = Join-Path ([IO.Path]::GetDirectoryName($Destination)) (\u0027.amp-world-discard-\u0027 + [guid]::NewGuid().ToString(\u0027N\u0027))\n try { [IO.File]::Replace($Temporary, $Destination, $discardBackup, $true) }\n finally { Remove-Item -LiteralPath $discardBackup -Force -ErrorAction SilentlyContinue }\n }\n else {\n [IO.File]::Replace($Temporary, $Destination, $Backup, $true)\n }\n }\n else { [IO.File]::Move($Temporary, $Destination) }\n}\n\nfunction Read-ManagedState([string]$Path) {\n if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) {\n return [pscustomobject]@{ Valid=$false; Commands=@(); Reason=\u0027missing\u0027 }\n }\n try {\n $value = Get-Content -Raw -LiteralPath $Path | ConvertFrom-Json\n if ($value.SchemaVersion -ne 1 -or $null -eq $value.PSObject.Properties[\u0027ManagedCommands\u0027]) { throw \u0027unsupported state shape\u0027 }\n $commands = @($value.ManagedCommands)\n foreach ($command in $commands) { if (-not ($command -is [string])) { throw \u0027ManagedCommands must contain strings\u0027 } }\n return [pscustomobject]@{ Valid=$true; Commands=$commands; Reason=\u0027\u0027 }\n }\n catch { return [pscustomobject]@{ Valid=$false; Commands=@(); Reason=\u0027invalid\u0027 } }\n}\n\n$rootPath = [IO.Path]::GetFullPath($Root)\n$dataPath = Join-Path $rootPath \u0027data\u0027\n$managedPath = Join-Path $dataPath \u0027amp-world-settings.json\u0027\n$contractPath = Join-Path $dataPath \u0027amp-world-settings-contract.json\u0027\n$serverConfigPath = Join-Path $dataPath \u0027serverconfig.json\u0027\n$statePath = Join-Path $dataPath \u0027amp-world-settings-state.json\u0027\n$backupPath = Join-Path $dataPath \u0027serverconfig.json.amp-world-backup\u0027\n\ntry {\n $managed = Read-JsonFile $managedPath \u0027AMP world settings\u0027\n $contract = Read-JsonFile $contractPath \u0027AMP world settings contract\u0027\n $serverConfig = Read-JsonFile $serverConfigPath \u0027Vintage Story serverconfig\u0027\n if ($managed.SchemaVersion -ne 1) { throw \"Unsupported AMP world settings schema version \u0027$($managed.SchemaVersion)\u0027\" }\n if (-not ($managed.ApplyToExistingWorld -is [bool])) { throw \u0027ApplyToExistingWorld must be boolean\u0027 }\n if ($contract.Count -ne 68) { throw \"World settings contract must contain 68 entries, found $($contract.Count)\" }\n\n $values = [ordered]@{}\n foreach ($entry in $contract) {\n $group = Get-PropertyValue $managed ([string]$entry.Group)\n $value = Get-PropertyValue $group ([string]$entry.Key)\n Assert-ContractValue $value $entry\n $values[\"$($entry.Group).$($entry.Key)\"] = $value\n }\n\n $worldConfig = Get-PropertyValue $serverConfig \u0027WorldConfig\u0027\n $saveLocation = [string](Get-PropertyValue $worldConfig \u0027SaveFileLocation\u0027)\n $savePath = Resolve-EffectiveSavePath $rootPath $saveLocation\n $existing = Test-Path -LiteralPath $savePath -PathType Leaf\n $managedCommands = @()\n $stateOutput = $null\n\n foreach ($entry in $contract | Where-Object { $_.Group -eq \u0027Server\u0027 }) {\n Set-JsonPath $serverConfig ([string]$entry.CreationPath) $values[\"$($entry.Group).$($entry.Key)\"]\n }\n\n if (-not $existing) {\n Set-JsonPath $serverConfig \u0027WorldConfig.WorldConfiguration\u0027 ([pscustomobject]@{})\n foreach ($entry in $contract | Where-Object { $_.Group -ne \u0027Server\u0027 }) {\n $value = $values[\"$($entry.Group).$($entry.Key)\"]\n if ($entry.Group -eq \u0027Creation\u0027 -and $entry.Key -eq \u0027Seed\u0027 -and [string]::IsNullOrEmpty([string]$value)) { $value = $null }\n Set-JsonPath $serverConfig ([string]$entry.CreationPath) $value\n }\n }\n else {\n $state = Read-ManagedState $statePath\n $startupProperty = $serverConfig.PSObject.Properties[\u0027StartupCommands\u0027]\n $startupText = if ($null -eq $startupProperty -or $null -eq $startupProperty.Value) { \u0027\u0027 } else { [string]$startupProperty.Value }\n $lines = @($startupText -split \"`r?`n\" | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })\n if ($state.Valid) {\n $lines = @($lines | Where-Object { $line = $_; -not @($state.Commands | Where-Object { $_ -ceq $line }).Count })\n }\n elseif ($state.Reason -eq \u0027invalid\u0027) { Write-Warning \u0027[AMP World] state file invalid; preserving all existing startup commands\u0027 }\n\n if ($managed.ApplyToExistingWorld) {\n foreach ($entry in $contract | Where-Object { $_.Lifecycle -in @(\u0027restart\u0027,\u0027unexplored\u0027,\u0027server\u0027) }) {\n $value = ConvertTo-CommandValue $values[\"$($entry.Group).$($entry.Key)\"]\n if ($entry.Lifecycle -eq \u0027server\u0027) { $managedCommands += \"/serverconfig $($entry.Command) $value\" }\n else { $managedCommands += \"/worldconfig $($entry.Command) $value\" }\n }\n }\n $combined = @($lines) + @($managedCommands)\n if ($null -eq $startupProperty) { $serverConfig | Add-Member -NotePropertyName StartupCommands -NotePropertyValue ($combined -join \"`n\") }\n else { $startupProperty.Value = ($combined -join \"`n\") }\n $stateOutput = [ordered]@{ SchemaVersion=1; ManagedCommands=@($managedCommands) }\n }\n\n $serverText = ConvertTo-StableJson $serverConfig\n $currentText = [IO.File]::ReadAllText($serverConfigPath)\n $serverChanged = $currentText -cne $serverText\n $serverTemp = if ($serverChanged) { Write-ValidatedTemp $serverConfigPath $serverText } else { $null }\n $stateTemp = $null\n $stateChanged = $false\n if ($existing) {\n $stateText = ConvertTo-StableJson $stateOutput\n $stateChanged = -not (Test-Path -LiteralPath $statePath) -or ([IO.File]::ReadAllText($statePath) -cne $stateText)\n if ($stateChanged) { $stateTemp = Write-ValidatedTemp $statePath $stateText }\n }\n\n try {\n if ($serverChanged) { Replace-File $serverTemp $serverConfigPath $backupPath; $serverTemp = $null }\n if ($stateChanged) { Replace-File $stateTemp $statePath; $stateTemp = $null }\n }\n catch {\n if ($serverChanged -and (Test-Path -LiteralPath $backupPath -PathType Leaf)) {\n $rollback = Join-Path $dataPath (\u0027.serverconfig.rollback-\u0027 + [guid]::NewGuid().ToString(\u0027N\u0027))\n [IO.File]::Copy($backupPath, $rollback, $true)\n Replace-File $rollback $serverConfigPath\n }\n throw\n }\n finally {\n if ($serverTemp) { Remove-Item -LiteralPath $serverTemp -Force -ErrorAction SilentlyContinue }\n if ($stateTemp) { Remove-Item -LiteralPath $stateTemp -Force -ErrorAction SilentlyContinue }\n }\n\n $mode = if ($existing) { \u0027existing\u0027 } else { \u0027new\u0027 }\n $enforcement = $managed.ApplyToExistingWorld.ToString().ToLowerInvariant()\n Write-Output \"[AMP World] save=$mode enforcement=$enforcement creation-values=$(if ($existing) { 0 } else { 68 }) managed-commands=$($managedCommands.Count)\"\n if ($existing -and $managed.ApplyToExistingWorld -and @($contract | Where-Object Lifecycle -eq \u0027unexplored\u0027).Count -gt 0) {\n Write-Warning \u0027[AMP World] world-generation overrides affect only unexplored chunks and may create visible terrain borders\u0027\n }\n}\ncatch {\n [Console]::Error.WriteLine(\"[AMP World] ERROR: $($_.Exception.Message)\")\n exit 1\n}\n", + "OverwriteExistingFiles": true, + "SkipOnFailure": false + }, + { + "UpdateStageName": "Install Nimbus ServerMod", + "UpdateSourcePlatform": "Linux", + "UpdateSourceArch": "x86_64", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"set -euo pipefail; root=\u0027{{$FullRootDir}}\u0027; tag=\u0027{{NimbusVersionTag}}\u0027; if [ -z \\\"$tag\\\" ]; then tag=\\\"$(curl -fsSL -H \u0027User-Agent: AMP-Clean-Template\u0027 https://api.github.com/repos/StratumServer/Nimbus/releases/latest | jq -r .tag_name)\\\"; fi; case \\\"$tag\\\" in v*) ;; *) tag=\\\"v$tag\\\";; esac; stage=\\\"$root/.amp-nimbus-mod-stage\\\"; archive=\\\"$root/.amp-nimbus-mod.zip\\\"; target=\\\"$root/data/Mods/Nimbus.ServerMod\\\"; rm -rf \\\"$stage\\\"; mkdir -p \\\"$stage\\\"; curl -fL --retry 3 -o \\\"$archive\\\" \\\"https://github.com/StratumServer/Nimbus/releases/download/$tag/Nimbus.ServerMod-$tag.zip\\\"; unzip -q \\\"$archive\\\" -d \\\"$stage\\\"; rm -f \\\"$archive\\\"; find \\\"$stage\\\" -type f | grep -q .; old=\\\"$root/.amp-nimbus-mod-old\\\"; rm -rf \\\"$old\\\"; if [ -d \\\"$target\\\" ]; then mv \\\"$target\\\" \\\"$old\\\"; fi; mv \\\"$stage\\\" \\\"$target\\\"; rm -rf \\\"$old\\\"; printf \u0027%s\u0027 \\\"$tag\\\" \u003e \\\"$target/.amp-nimbus-release\\\"\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Install Nimbus ServerMod", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference=\u0027Stop\u0027; $ProgressPreference=\u0027SilentlyContinue\u0027; $root=\u0027{{$FullRootDir}}\u0027; $tag=\u0027{{NimbusVersionTag}}\u0027.Trim(); $headers=@{\u0027User-Agent\u0027=\u0027AMP-Clean-Template\u0027}; if (-not $tag) { $tag=(Invoke-RestMethod -Headers $headers -Uri https://api.github.com/repos/StratumServer/Nimbus/releases/latest).tag_name }; if (-not $tag.StartsWith(\u0027v\u0027)) { $tag=\u0027v\u0027+$tag }; $stage=Join-Path $root \u0027.amp-nimbus-mod-stage\u0027; $archive=Join-Path $root \u0027.amp-nimbus-mod.zip\u0027; $target=Join-Path $root \u0027data\\Mods\\Nimbus.ServerMod\u0027; $old=Join-Path $root \u0027.amp-nimbus-mod-old\u0027; Remove-Item -LiteralPath $stage,$old,$archive -Recurse -Force -ErrorAction SilentlyContinue; New-Item -ItemType Directory -Path $stage | Out-Null; Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri (\u0027https://github.com/StratumServer/Nimbus/releases/download/\u0027+$tag+\u0027/Nimbus.ServerMod-\u0027+$tag+\u0027.zip\u0027) -OutFile $archive; Expand-Archive -LiteralPath $archive -DestinationPath $stage -Force; Remove-Item -LiteralPath $archive -Force; if (-not (Get-ChildItem -LiteralPath $stage -File -Recurse | Select-Object -First 1)) { throw \u0027Nimbus ServerMod archive was empty\u0027 }; if (Test-Path -LiteralPath $target) { Move-Item -LiteralPath $target -Destination $old }; try { Move-Item -LiteralPath $stage -Destination $target; Remove-Item -LiteralPath $old -Recurse -Force -ErrorAction SilentlyContinue } catch { if ((Test-Path -LiteralPath $old) -and -not (Test-Path -LiteralPath $target)) { Move-Item -LiteralPath $old -Destination $target }; throw }; [IO.File]::WriteAllText((Join-Path $target \u0027.amp-nimbus-release\u0027),$tag,(New-Object Text.UTF8Encoding $false))\"", + "SkipOnFailure": false + } ] From b35feae81ec03d7b8bdb701293d21682035515d9 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Wed, 12 Aug 2026 19:10:14 -0500 Subject: [PATCH 28/50] Add files via upload --- vintage-story-stratum.kvp | 2 +- vintage-story-stratumupdates.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vintage-story-stratum.kvp b/vintage-story-stratum.kvp index 8eb7d1d48..1501c8444 100644 --- a/vintage-story-stratum.kvp +++ b/vintage-story-stratum.kvp @@ -18,7 +18,7 @@ Meta.ExtraContainerPackages=["jq","unzip","curl","ca-certificates"] Meta.Prerequisites=[] Meta.ConfigReleaseState=NotSpecified Meta.NoCommercialUsage=False -Meta.ConfigVersion=1 +Meta.ConfigVersion=2 Meta.AppConfigId=ac764031-4749-46d1-b662-d3e9de8d9356 Meta.AppIsMultiIPAware=True Meta.ResourceUsageInfo=4 GB RAM minimum; 8 GB recommended for active worlds diff --git a/vintage-story-stratumupdates.json b/vintage-story-stratumupdates.json index 15c094339..55694a910 100644 --- a/vintage-story-stratumupdates.json +++ b/vintage-story-stratumupdates.json @@ -151,7 +151,7 @@ "UpdateSourceArch": "x86_64", "UpdateSource": "CreateFile", "UpdateSourceArgs": "{{$FullRootDir}}tools/apply-world-settings.sh", - "UpdateSourceData": "#!/bin/sh\nset -eu\n\nfail() {\n printf \u0027%s\\n\u0027 \"[AMP World] ERROR: $*\" \u003e\u00262\n exit 1\n}\n\n[ \"$#\" -eq 1 ] || fail \u0027usage: apply-world-settings.sh INSTANCE_ROOT\u0027\ncommand -v jq \u003e/dev/null 2\u003e\u00261 || fail \u0027jq is required\u0027\ncommand -v realpath \u003e/dev/null 2\u003e\u00261 || fail \u0027realpath is required\u0027\n\nroot=$(realpath -m \"$1\")\ndata=\"$root/data\"\nmanaged=\"$data/amp-world-settings.json\"\ncontract=\"$data/amp-world-settings-contract.json\"\nconfig=\"$data/serverconfig.json\"\nstate=\"$data/amp-world-settings-state.json\"\nbackup=\"$data/serverconfig.json.amp-world-backup\"\n\n[ -f \"$managed\" ] || fail \"AMP world settings do not exist: $managed\"\n[ -f \"$contract\" ] || fail \"AMP world settings contract does not exist: $contract\"\n[ -f \"$config\" ] || fail \"Vintage Story serverconfig does not exist: $config\"\n\njq -e empty \"$managed\" \u003e/dev/null 2\u003e\u00261 || fail \u0027AMP world settings are not valid JSON\u0027\njq -e empty \"$contract\" \u003e/dev/null 2\u003e\u00261 || fail \u0027AMP world settings contract is not valid JSON\u0027\njq -e empty \"$config\" \u003e/dev/null 2\u003e\u00261 || fail \u0027Vintage Story serverconfig is not valid JSON\u0027\n\njq -e --slurpfile c \"$contract\" \u0027\n . as $m |\n ($m.SchemaVersion == 1) and\n (($m.ApplyToExistingWorld | type) == \"boolean\") and\n (($c[0] | type) == \"array\") and (($c[0] | length) == 68) and\n all($c[0][];\n . as $e |\n ($m | has($e.Group)) and ($m[$e.Group] | has($e.Key)) and\n ($m[$e.Group][$e.Key] as $v |\n (($e.Type == \"string\" and ($v | type) == \"string\") or\n ($e.Type == \"boolean\" and ($v | type) == \"boolean\") or\n ($e.Type == \"integer\" and ($v | type) == \"number\" and ($v | floor) == $v) or\n ($e.Type == \"number\" and ($v | type) == \"number\")) and\n (($e | has(\"Allowed\") | not) or (($e.Allowed | index($v)) != null)) and\n (($e | has(\"MaxLength\") | not) or (($v | length) \u003c= $e.MaxLength))))\n\u0027 \"$managed\" \u003e/dev/null 2\u003e\u00261 || fail \u0027managed settings failed schema, type, or allowed-value validation\u0027\n\nsave_location=$(jq -er \u0027.WorldConfig.SaveFileLocation | select(type == \"string\" and length \u003e 0)\u0027 \"$config\") || fail \u0027WorldConfig.SaveFileLocation is blank or missing\u0027\nserver_root=$(realpath -m \"$root/server\")\ndata_root=$(realpath -m \"$data\")\ncase \"$save_location\" in\n /*) save_path=$(realpath -m \"$save_location\") ;;\n *)\n save_path=$(realpath -m \"$server_root/$save_location\")\n case \"$save_path\" in\n \"$data_root\"/*) ;;\n *) fail \"relative SaveFileLocation escapes the instance data directory: $save_location\" ;;\n esac\n ;;\nesac\n\nif [ -f \"$save_path\" ]; then existing=true; else existing=false; fi\nenforce=$(jq -r \u0027.ApplyToExistingWorld\u0027 \"$managed\")\n\nrendered=$(mktemp \"$data/.serverconfig.json.tmp.XXXXXX\")\nnext_rendered=$(mktemp \"$data/.serverconfig.json.next.XXXXXX\")\nprevious_commands=$(mktemp \"$data/.amp-world-previous.XXXXXX\")\nmanaged_commands=$(mktemp \"$data/.amp-world-commands.XXXXXX\")\nstate_temp=$(mktemp \"$data/.amp-world-state.XXXXXX\")\ncleanup() {\n rm -f \"$rendered\" \"$next_rendered\" \"$previous_commands\" \"$managed_commands\" \"$state_temp\"\n}\ntrap cleanup EXIT HUP INT TERM\n\njq -S --slurpfile m \"$managed\" --slurpfile c \"$contract\" \u0027\n reduce ($c[0][] | select(.Group == \"Server\")) as $e\n (. ; setpath(($e.CreationPath | split(\".\")); $m[0][$e.Group][$e.Key]))\n\u0027 \"$config\" \u003e \"$rendered\" || fail \u0027could not render server settings\u0027\n\nif [ \"$existing\" = false ]; then\n jq -S --slurpfile m \"$managed\" --slurpfile c \"$contract\" \u0027\n .WorldConfig.WorldConfiguration = {} |\n reduce ($c[0][] | select(.Group != \"Server\")) as $e\n (. ; setpath(\n ($e.CreationPath | split(\".\"));\n (if $e.Group == \"Creation\" and $e.Key == \"Seed\" and $m[0][$e.Group][$e.Key] == \"\"\n then null else $m[0][$e.Group][$e.Key] end)\n ))\n \u0027 \"$rendered\" \u003e \"$next_rendered\" || fail \u0027could not render new-world settings\u0027\n mv -f \"$next_rendered\" \"$rendered\"\n printf \u0027[]\\n\u0027 \u003e \"$managed_commands\"\nelse\n if [ -f \"$state\" ]; then\n if jq -e \u0027.SchemaVersion == 1 and (.ManagedCommands | type) == \"array\" and all(.ManagedCommands[]; type == \"string\")\u0027 \"$state\" \u003e/dev/null 2\u003e\u00261; then\n jq -c \u0027.ManagedCommands\u0027 \"$state\" \u003e \"$previous_commands\"\n else\n printf \u0027%s\\n\u0027 \u0027[AMP World] WARNING: state file invalid; preserving all existing startup commands\u0027 \u003e\u00262\n printf \u0027[]\\n\u0027 \u003e \"$previous_commands\"\n fi\n else\n printf \u0027[]\\n\u0027 \u003e \"$previous_commands\"\n fi\n\n if [ \"$enforce\" = true ]; then\n jq -c -n --slurpfile m \"$managed\" --slurpfile c \"$contract\" \u0027\n [$c[0][] | select(.Lifecycle == \"restart\" or .Lifecycle == \"unexplored\" or .Lifecycle == \"server\") |\n . as $e | ($m[0][$e.Group][$e.Key] | tostring) as $value |\n (if $e.Lifecycle == \"server\" then \"/serverconfig \" else \"/worldconfig \" end) + $e.Command + \" \" + $value]\n \u0027 \u003e \"$managed_commands\" || fail \u0027could not generate managed startup commands\u0027\n else\n printf \u0027[]\\n\u0027 \u003e \"$managed_commands\"\n fi\n\n jq -S --slurpfile old \"$previous_commands\" --slurpfile managed \"$managed_commands\" \u0027\n ((.StartupCommands // \"\") | split(\"\\n\") | map(sub(\"\\r$\"; \"\")) |\n map(select(length \u003e 0)) | map(. as $line | select(($old[0] | index($line)) == null))) as $custom |\n .StartupCommands = (($custom + $managed[0]) | join(\"\\n\"))\n \u0027 \"$rendered\" \u003e \"$next_rendered\" || fail \u0027could not reconcile startup commands\u0027\n mv -f \"$next_rendered\" \"$rendered\"\n jq -S -n --slurpfile commands \"$managed_commands\" \u0027{SchemaVersion:1, ManagedCommands:$commands[0]}\u0027 \u003e \"$state_temp\" || fail \u0027could not render managed state\u0027\nfi\n\njq -e empty \"$rendered\" \u003e/dev/null 2\u003e\u00261 || fail \u0027rendered serverconfig failed JSON validation\u0027\nif [ \"$existing\" = true ]; then jq -e empty \"$state_temp\" \u003e/dev/null 2\u003e\u00261 || fail \u0027rendered state failed JSON validation\u0027; fi\n\nchanged=false\nif ! cmp -s \"$rendered\" \"$config\"; then\n cp -p \"$config\" \"$backup\" || fail \u0027could not create serverconfig.json.amp-world-backup\u0027\n mv -f \"$rendered\" \"$config\" || fail \u0027could not atomically replace serverconfig.json\u0027\n changed=true\nfi\n\nif [ \"$existing\" = true ]; then\n if [ ! -f \"$state\" ] || ! cmp -s \"$state_temp\" \"$state\"; then\n if ! mv -f \"$state_temp\" \"$state\"; then\n if [ \"$changed\" = true ] \u0026\u0026 [ -f \"$backup\" ]; then\n rollback=$(mktemp \"$data/.serverconfig.rollback.XXXXXX\")\n cp -p \"$backup\" \"$rollback\" \u0026\u0026 mv -f \"$rollback\" \"$config\"\n fi\n fail \u0027could not atomically replace AMP world settings state\u0027\n fi\n fi\nfi\n\ncommand_count=$(jq -r \u0027length\u0027 \"$managed_commands\")\nif [ \"$existing\" = true ]; then creation_count=0; mode=existing; else creation_count=68; mode=new; fi\nprintf \u0027%s\\n\u0027 \"[AMP World] save=$mode enforcement=$enforce creation-values=$creation_count managed-commands=$command_count\"\nif [ \"$existing\" = true ] \u0026\u0026 [ \"$enforce\" = true ]; then\n printf \u0027%s\\n\u0027 \u0027[AMP World] WARNING: world-generation overrides affect only unexplored chunks and may create visible terrain borders\u0027 \u003e\u00262\nfi\n", + "UpdateSourceData": "#!/bin/sh\nset -eu\n\nfail() {\n printf \u0027%s\\n\u0027 \"[AMP World] ERROR: $*\" \u003e\u00262\n exit 1\n}\n\n[ \"$#\" -eq 1 ] || fail \u0027usage: apply-world-settings.sh INSTANCE_ROOT\u0027\ncommand -v jq \u003e/dev/null 2\u003e\u00261 || fail \u0027jq is required\u0027\ncommand -v realpath \u003e/dev/null 2\u003e\u00261 || fail \u0027realpath is required\u0027\n\nroot=$(realpath -m \"$1\")\ndata=\"$root/data\"\nmanaged=\"$data/amp-world-settings.json\"\ncontract=\"$data/amp-world-settings-contract.json\"\nconfig=\"$data/serverconfig.json\"\nstate=\"$data/amp-world-settings-state.json\"\nbackup=\"$data/serverconfig.json.amp-world-backup\"\n\n[ -f \"$managed\" ] || fail \"AMP world settings do not exist: $managed\"\n[ -f \"$contract\" ] || fail \"AMP world settings contract does not exist: $contract\"\n[ -f \"$config\" ] || fail \"Vintage Story serverconfig does not exist: $config\"\n\njq empty \"$managed\" \u003e/dev/null 2\u003e\u00261 || fail \u0027AMP world settings are not valid JSON\u0027\njq empty \"$contract\" \u003e/dev/null 2\u003e\u00261 || fail \u0027AMP world settings contract is not valid JSON\u0027\njq empty \"$config\" \u003e/dev/null 2\u003e\u00261 || fail \u0027Vintage Story serverconfig is not valid JSON\u0027\n\njq -e --slurpfile c \"$contract\" \u0027\n . as $m |\n ($m.SchemaVersion == 1) and\n (($m.ApplyToExistingWorld | type) == \"boolean\") and\n (($c[0] | type) == \"array\") and (($c[0] | length) == 68) and\n all($c[0][];\n . as $e |\n ($m | has($e.Group)) and ($m[$e.Group] | has($e.Key)) and\n ($m[$e.Group][$e.Key] as $v |\n (($e.Type == \"string\" and ($v | type) == \"string\") or\n ($e.Type == \"boolean\" and ($v | type) == \"boolean\") or\n ($e.Type == \"integer\" and ($v | type) == \"number\" and ($v | floor) == $v) or\n ($e.Type == \"number\" and ($v | type) == \"number\")) and\n (($e | has(\"Allowed\") | not) or (($e.Allowed | index($v)) != null)) and\n (($e | has(\"MaxLength\") | not) or (($v | length) \u003c= $e.MaxLength))))\n\u0027 \"$managed\" \u003e/dev/null 2\u003e\u00261 || fail \u0027managed settings failed schema, type, or allowed-value validation\u0027\n\nsave_location=$(jq -er \u0027.WorldConfig.SaveFileLocation | select(type == \"string\" and length \u003e 0)\u0027 \"$config\") || fail \u0027WorldConfig.SaveFileLocation is blank or missing\u0027\nserver_root=$(realpath -m \"$root/server\")\ndata_root=$(realpath -m \"$data\")\ncase \"$save_location\" in\n /*) save_path=$(realpath -m \"$save_location\") ;;\n *)\n save_path=$(realpath -m \"$server_root/$save_location\")\n case \"$save_path\" in\n \"$data_root\"/*) ;;\n *) fail \"relative SaveFileLocation escapes the instance data directory: $save_location\" ;;\n esac\n ;;\nesac\n\nif [ -f \"$save_path\" ]; then existing=true; else existing=false; fi\nenforce=$(jq -r \u0027.ApplyToExistingWorld\u0027 \"$managed\")\n\nrendered=$(mktemp \"$data/.serverconfig.json.tmp.XXXXXX\")\nnext_rendered=$(mktemp \"$data/.serverconfig.json.next.XXXXXX\")\nprevious_commands=$(mktemp \"$data/.amp-world-previous.XXXXXX\")\nmanaged_commands=$(mktemp \"$data/.amp-world-commands.XXXXXX\")\nstate_temp=$(mktemp \"$data/.amp-world-state.XXXXXX\")\ncleanup() {\n rm -f \"$rendered\" \"$next_rendered\" \"$previous_commands\" \"$managed_commands\" \"$state_temp\"\n}\ntrap cleanup EXIT HUP INT TERM\n\njq -S --slurpfile m \"$managed\" --slurpfile c \"$contract\" \u0027\n reduce ($c[0][] | select(.Group == \"Server\")) as $e\n (. ; setpath(($e.CreationPath | split(\".\")); $m[0][$e.Group][$e.Key]))\n\u0027 \"$config\" \u003e \"$rendered\" || fail \u0027could not render server settings\u0027\n\nif [ \"$existing\" = false ]; then\n jq -S --slurpfile m \"$managed\" --slurpfile c \"$contract\" \u0027\n .WorldConfig.WorldConfiguration = {} |\n reduce ($c[0][] | select(.Group != \"Server\")) as $e\n (. ; setpath(\n ($e.CreationPath | split(\".\"));\n (if $e.Group == \"Creation\" and $e.Key == \"Seed\" and $m[0][$e.Group][$e.Key] == \"\"\n then null else $m[0][$e.Group][$e.Key] end)\n ))\n \u0027 \"$rendered\" \u003e \"$next_rendered\" || fail \u0027could not render new-world settings\u0027\n mv -f \"$next_rendered\" \"$rendered\"\n printf \u0027[]\\n\u0027 \u003e \"$managed_commands\"\nelse\n if [ -f \"$state\" ]; then\n if jq -e \u0027.SchemaVersion == 1 and (.ManagedCommands | type) == \"array\" and all(.ManagedCommands[]; type == \"string\")\u0027 \"$state\" \u003e/dev/null 2\u003e\u00261; then\n jq -c \u0027.ManagedCommands\u0027 \"$state\" \u003e \"$previous_commands\"\n else\n printf \u0027%s\\n\u0027 \u0027[AMP World] WARNING: state file invalid; preserving all existing startup commands\u0027 \u003e\u00262\n printf \u0027[]\\n\u0027 \u003e \"$previous_commands\"\n fi\n else\n printf \u0027[]\\n\u0027 \u003e \"$previous_commands\"\n fi\n\n if [ \"$enforce\" = true ]; then\n jq -c -n --slurpfile m \"$managed\" --slurpfile c \"$contract\" \u0027\n [$c[0][] | select(.Lifecycle == \"restart\" or .Lifecycle == \"unexplored\" or .Lifecycle == \"server\") |\n . as $e | ($m[0][$e.Group][$e.Key] | tostring) as $value |\n (if $e.Lifecycle == \"server\" then \"/serverconfig \" else \"/worldconfig \" end) + $e.Command + \" \" + $value]\n \u0027 \u003e \"$managed_commands\" || fail \u0027could not generate managed startup commands\u0027\n else\n printf \u0027[]\\n\u0027 \u003e \"$managed_commands\"\n fi\n\n jq -S --slurpfile old \"$previous_commands\" --slurpfile managed \"$managed_commands\" \u0027\n ((.StartupCommands // \"\") | split(\"\\n\") | map(sub(\"\\r$\"; \"\")) |\n map(select(length \u003e 0)) | map(. as $line | select(($old[0] | index($line)) == null))) as $custom |\n .StartupCommands = (($custom + $managed[0]) | join(\"\\n\"))\n \u0027 \"$rendered\" \u003e \"$next_rendered\" || fail \u0027could not reconcile startup commands\u0027\n mv -f \"$next_rendered\" \"$rendered\"\n jq -S -n --slurpfile commands \"$managed_commands\" \u0027{SchemaVersion:1, ManagedCommands:$commands[0]}\u0027 \u003e \"$state_temp\" || fail \u0027could not render managed state\u0027\nfi\n\njq empty \"$rendered\" \u003e/dev/null 2\u003e\u00261 || fail \u0027rendered serverconfig failed JSON validation\u0027\nif [ \"$existing\" = true ]; then jq empty \"$state_temp\" \u003e/dev/null 2\u003e\u00261 || fail \u0027rendered state failed JSON validation\u0027; fi\n\nchanged=false\nif ! cmp -s \"$rendered\" \"$config\"; then\n cp -p \"$config\" \"$backup\" || fail \u0027could not create serverconfig.json.amp-world-backup\u0027\n mv -f \"$rendered\" \"$config\" || fail \u0027could not atomically replace serverconfig.json\u0027\n changed=true\nfi\n\nif [ \"$existing\" = true ]; then\n if [ ! -f \"$state\" ] || ! cmp -s \"$state_temp\" \"$state\"; then\n if ! mv -f \"$state_temp\" \"$state\"; then\n if [ \"$changed\" = true ] \u0026\u0026 [ -f \"$backup\" ]; then\n rollback=$(mktemp \"$data/.serverconfig.rollback.XXXXXX\")\n cp -p \"$backup\" \"$rollback\" \u0026\u0026 mv -f \"$rollback\" \"$config\"\n fi\n fail \u0027could not atomically replace AMP world settings state\u0027\n fi\n fi\nfi\n\ncommand_count=$(jq -r \u0027length\u0027 \"$managed_commands\")\nif [ \"$existing\" = true ]; then creation_count=0; mode=existing; else creation_count=68; mode=new; fi\nprintf \u0027%s\\n\u0027 \"[AMP World] save=$mode enforcement=$enforce creation-values=$creation_count managed-commands=$command_count\"\nif [ \"$existing\" = true ] \u0026\u0026 [ \"$enforce\" = true ]; then\n printf \u0027%s\\n\u0027 \u0027[AMP World] WARNING: world-generation overrides affect only unexplored chunks and may create visible terrain borders\u0027 \u003e\u00262\nfi\n", "OverwriteExistingFiles": true, "SkipOnFailure": false }, From 10e69f0bd9ecad7aad3bdd1bc2b62b919f127d9c Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Wed, 12 Aug 2026 19:43:28 -0500 Subject: [PATCH 29/50] Add files via upload --- vintage-story-stratum.kvp | 2 +- vintage-story-stratumconfig.json | 1292 -------------------------- vintage-story-stratummetaconfig.json | 1 - vintage-story-stratumstart.json | 19 +- vintage-story-stratumupdates.json | 37 - 5 files changed, 2 insertions(+), 1349 deletions(-) diff --git a/vintage-story-stratum.kvp b/vintage-story-stratum.kvp index 1501c8444..fab63aa28 100644 --- a/vintage-story-stratum.kvp +++ b/vintage-story-stratum.kvp @@ -18,7 +18,7 @@ Meta.ExtraContainerPackages=["jq","unzip","curl","ca-certificates"] Meta.Prerequisites=[] Meta.ConfigReleaseState=NotSpecified Meta.NoCommercialUsage=False -Meta.ConfigVersion=2 +Meta.ConfigVersion=3 Meta.AppConfigId=ac764031-4749-46d1-b662-d3e9de8d9356 Meta.AppIsMultiIPAware=True Meta.ResourceUsageInfo=4 GB RAM minimum; 8 GB recommended for active worlds diff --git a/vintage-story-stratumconfig.json b/vintage-story-stratumconfig.json index 4aca067d4..7dc9d8a65 100644 --- a/vintage-story-stratumconfig.json +++ b/vintage-story-stratumconfig.json @@ -127,22 +127,6 @@ "False": "false" } }, - { - "DisplayName": "Allow Fire Spread", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied at every server start. Allow fire to spread between flammable blocks.", - "Keywords": "world,fire,spread", - "FieldName": "VS_AllowFireSpread", - "InputType": "checkbox", - "ParamFieldName": "$.Server.AllowFireSpread", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, { "DisplayName": "Pass Time When Empty", "Category": "Vintage Story:stadia_controller", @@ -159,1282 +143,6 @@ "False": "false" } }, - { - "DisplayName": "Apply World Settings to Existing Save", - "Category": "World:public", - "Subcategory": "Identity and Preset:language:1", - "Description": "Opt in to restart-based overrides for an existing save. Creation-only identity, seed, play style, height, dimensions, climate, and grace timer are never changed. World-generation changes affect only unexplored chunks and may create seams.", - "Keywords": "world,existing,override,restart,enforce", - "FieldName": "VS_ApplyWorldSettingsToExisting", - "InputType": "checkbox", - "ParamFieldName": "$.ApplyToExistingWorld", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "World Name", - "Category": "World:public", - "Subcategory": "Identity and Preset:language:1", - "Description": "New worlds only. Name for a newly created world. Most settings here only apply before the first save is generated.", - "Keywords": "world,name,setup", - "FieldName": "VS_WorldName", - "InputType": "text", - "ParamFieldName": "$.Creation.WorldName", - "IncludeInCommandLine": false, - "DefaultValue": "A new world", - "EnumValues": { - - } - }, - { - "DisplayName": "World Seed", - "Category": "World:public", - "Subcategory": "Identity and Preset:language:1", - "Description": "New worlds only. Optional seed for a newly created world. Leave blank for random.", - "Keywords": "world,seed,setup", - "FieldName": "VS_WorldSeed", - "InputType": "text", - "ParamFieldName": "$.Creation.Seed", - "IncludeInCommandLine": false, - "DefaultValue": "", - "EnumValues": { - - } - }, - { - "DisplayName": "Base Play Style", - "Category": "World:public", - "Subcategory": "Identity and Preset:language:1", - "Description": "New worlds only. Base preset. Every other visible World Setup value is an explicit override.", - "Keywords": "world,playstyle,setup", - "FieldName": "VS_PlayStyle", - "InputType": "enum", - "ParamFieldName": "$.Creation.PlayStyle", - "IncludeInCommandLine": false, - "DefaultValue": "surviveandbuild", - "EnumValues": { - "surviveandbuild": "Standard (Survive and Build)", - "exploration": "Exploration", - "wildernesssurvival": "Wilderness Survival", - "creativebuilding": "Creative Building" - } - }, - { - "DisplayName": "World Height", - "Category": "World:public", - "Subcategory": "Identity and Preset:language:1", - "Description": "New worlds only. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_WorldHeight", - "InputType": "enum", - "ParamFieldName": "$.Creation.MapSizeY", - "IncludeInCommandLine": false, - "DefaultValue": "256", - "EnumValues": { - "128": "128 blocks", - "192": "192 blocks", - "256": "256 blocks (Standard)", - "384": "384 blocks", - "448": "448 blocks", - "512": "512 blocks" - } - }, - { - "DisplayName": "Allow Falling Blocks", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied at every server start. Allow gravity-affected blocks to fall.", - "Keywords": "world,setup", - "FieldName": "VS_AllowFallingBlocks", - "InputType": "checkbox", - "ParamFieldName": "$.Server.AllowFallingBlocks", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Game Mode", - "Category": "World:public", - "Subcategory": "Player Spawn and Death:favorite:2", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_GameMode", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.gameMode", - "IncludeInCommandLine": false, - "DefaultValue": "survival", - "EnumValues": { - "survival": "Survival", - "creative": "Creative" - } - }, - { - "DisplayName": "Player Lives", - "Category": "World:public", - "Subcategory": "Player Spawn and Death:favorite:2", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_PlayerLives", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.playerlives", - "IncludeInCommandLine": false, - "DefaultValue": "-1", - "EnumValues": { - "1": "1 life", - "2": "2 lives", - "3": "3 lives", - "4": "4 lives", - "5": "5 lives", - "10": "10 lives", - "20": "20 lives", - "-1": "Infinite" - } - }, - { - "DisplayName": "Starting Climate", - "Category": "World:public", - "Subcategory": "Player Spawn and Death:favorite:2", - "Description": "New worlds only. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_StartingClimate", - "InputType": "enum", - "ParamFieldName": "$.CreationOnlyWorldConfiguration.startingClimate", - "IncludeInCommandLine": false, - "DefaultValue": "temperate", - "EnumValues": { - "hot": "Hot", - "warm": "Warm", - "temperate": "Temperate", - "cool": "Cool", - "icy": "Icy" - } - }, - { - "DisplayName": "Random Respawn Radius", - "Category": "World:public", - "Subcategory": "Player Spawn and Death:favorite:2", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_SpawnRadius", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.spawnRadius", - "IncludeInCommandLine": false, - "DefaultValue": "50", - "EnumValues": { - "0": "0 blocks", - "25": "25 blocks", - "50": "50 blocks", - "100": "100 blocks", - "250": "250 blocks", - "500": "500 blocks", - "1000": "1,000 blocks", - "2500": "2,500 blocks", - "5000": "5,000 blocks", - "10000": "10,000 blocks" - } - }, - { - "DisplayName": "Grace Timer", - "Category": "World:public", - "Subcategory": "Player Spawn and Death:favorite:2", - "Description": "New worlds only. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_GraceTimer", - "InputType": "enum", - "ParamFieldName": "$.CreationOnlyWorldConfiguration.graceTimer", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": { - "0": "None", - "1": "1 day", - "2": "2 days", - "3": "3 days", - "4": "4 days", - "5": "5 days", - "10": "10 days" - } - }, - { - "DisplayName": "Death Punishment", - "Category": "World:public", - "Subcategory": "Player Spawn and Death:favorite:2", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_DeathPunishment", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.deathPunishment", - "IncludeInCommandLine": false, - "DefaultValue": "drop", - "EnumValues": { - "drop": "Drop inventory contents", - "keep": "Keep inventory contents" - } - }, - { - "DisplayName": "Dropped-on-Death Item Timer", - "Category": "World:public", - "Subcategory": "Player Spawn and Death:favorite:2", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_DroppedItemsTimer", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.droppedItemsTimer", - "IncludeInCommandLine": false, - "DefaultValue": "600", - "EnumValues": { - "300": "5 minutes", - "600": "10 minutes", - "1200": "20 minutes", - "1800": "30 minutes", - "3600": "60 minutes" - } - }, - { - "DisplayName": "Seasons", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_Seasons", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.seasons", - "IncludeInCommandLine": false, - "DefaultValue": "enabled", - "EnumValues": { - "enabled": "Enabled", - "spring": "Always spring", - "summer": "Always summer", - "fall": "Always fall", - "winter": "Always winter" - } - }, - { - "DisplayName": "Days per Month", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_DaysPerMonth", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.daysPerMonth", - "IncludeInCommandLine": false, - "DefaultValue": "9", - "EnumValues": { - "3": "3 days", - "6": "6 days", - "9": "9 days (Standard)", - "12": "12 days", - "20": "20 days", - "30": "30 days" - } - }, - { - "DisplayName": "True Winters", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_HarshWinters", - "InputType": "checkbox", - "ParamFieldName": "$.ExistingWorld.harshWinters", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Block Gravity", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_BlockGravity", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.blockGravity", - "IncludeInCommandLine": false, - "DefaultValue": "sandgravel", - "EnumValues": { - "sandgravel": "Sand and gravel", - "sandgravelsoil": "Sand, gravel, and soil" - } - }, - { - "DisplayName": "Cave-ins", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_CaveIns", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.caveIns", - "IncludeInCommandLine": false, - "DefaultValue": "off", - "EnumValues": { - "off": "Disabled", - "on": "Enabled" - } - }, - { - "DisplayName": "Fire from Lightning", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_LightningFires", - "InputType": "checkbox", - "ParamFieldName": "$.ExistingWorld.lightningFires", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Allow Underground Farming", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_AllowUndergroundFarming", - "InputType": "checkbox", - "ParamFieldName": "$.ExistingWorld.allowUndergroundFarming", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Prevent Liquid Source Transport", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_NoLiquidSourceTransport", - "InputType": "checkbox", - "ParamFieldName": "$.ExistingWorld.noLiquidSourceTransport", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Player Health Points", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_PlayerHealthPoints", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.playerHealthPoints", - "IncludeInCommandLine": false, - "DefaultValue": "15", - "EnumValues": { - "5": "5 hp", - "10": "10 hp", - "15": "15 hp (Standard)", - "20": "20 hp", - "25": "25 hp", - "30": "30 hp" - } - }, - { - "DisplayName": "Health Regeneration Rate", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_PlayerHealthRegenSpeed", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.playerHealthRegenSpeed", - "IncludeInCommandLine": false, - "DefaultValue": "1", - "EnumValues": { - "1": "Normal (100%)", - "2": "200%", - "3": "300%", - "0.25": "25%", - "0.5": "50%", - "0.75": "75%", - "1.5": "150%" - } - }, - { - "DisplayName": "Hunger Rate", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_PlayerHungerSpeed", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.playerHungerSpeed", - "IncludeInCommandLine": false, - "DefaultValue": "1", - "EnumValues": { - "1": "Normal (100%)", - "2": "200%", - "3": "300%", - "0.25": "25%", - "0.5": "50%", - "0.75": "75%", - "1.5": "150%" - } - }, - { - "DisplayName": "Lung Capacity", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_LungCapacity", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.lungCapacity", - "IncludeInCommandLine": false, - "DefaultValue": "40000", - "EnumValues": { - "10000": "10 seconds", - "20000": "20 seconds", - "30000": "30 seconds", - "40000": "40 seconds (Standard)", - "60000": "60 seconds", - "120000": "2 minutes", - "3600000": "1 hour" - } - }, - { - "DisplayName": "Body Temperature Hardiness", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_BodyTemperatureResistance", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.bodyTemperatureResistance", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": { - "0": "0 °C (Standard)", - "10": "10 °C", - "20": "20 °C", - "-40": "-40 °C", - "-30": "-30 °C", - "-20": "-20 °C", - "-10": "-10 °C" - } - }, - { - "DisplayName": "Walk Speed", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_PlayerMoveSpeed", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.playerMoveSpeed", - "IncludeInCommandLine": false, - "DefaultValue": "1.5", - "EnumValues": { - "1": "Reduced", - "2": "Fast", - "3": "Very fast", - "0.5": "Slow", - "1.5": "Normal" - } - }, - { - "DisplayName": "Creature Hostility", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_CreatureHostility", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.creatureHostility", - "IncludeInCommandLine": false, - "DefaultValue": "aggressive", - "EnumValues": { - "aggressive": "Aggressive", - "passive": "Passive", - "off": "Off" - } - }, - { - "DisplayName": "Creature Strength", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_CreatureStrength", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.creatureStrength", - "IncludeInCommandLine": false, - "DefaultValue": "1", - "EnumValues": { - "1": "Normal (100%)", - "2": "200%", - "3": "300%", - "0.25": "25%", - "0.5": "50%", - "0.75": "75%", - "1.5": "150%" - } - }, - { - "DisplayName": "Creature Swim Speed", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_CreatureSwimSpeed", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.creatureSwimSpeed", - "IncludeInCommandLine": false, - "DefaultValue": "2", - "EnumValues": { - "1": "100%", - "2": "200% (Standard)", - "3": "300%", - "0.5": "50%", - "1.5": "150%", - "2.5": "250%" - } - }, - { - "DisplayName": "Food Spoilage Rate", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_FoodSpoilSpeed", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.foodSpoilSpeed", - "IncludeInCommandLine": false, - "DefaultValue": "1", - "EnumValues": { - "1": "Normal (100%)", - "2": "200%", - "3": "300%", - "0.25": "25%", - "0.5": "50%", - "0.75": "75%", - "1.5": "150%" - } - }, - { - "DisplayName": "Tree Sapling Growth Time", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_SaplingGrowthRate", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.saplingGrowthRate", - "IncludeInCommandLine": false, - "DefaultValue": "1", - "EnumValues": { - "1": "Normal (100%)", - "2": "200%", - "3": "300%", - "0.25": "25%", - "0.5": "50%", - "0.75": "75%", - "1.5": "150%" - } - }, - { - "DisplayName": "Tool Durability", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_ToolDurability", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.toolDurability", - "IncludeInCommandLine": false, - "DefaultValue": "1", - "EnumValues": { - "1": "Normal (100%)", - "2": "200%", - "3": "300%", - "0.25": "25%", - "0.5": "50%", - "0.75": "75%", - "1.5": "150%" - } - }, - { - "DisplayName": "Tool Mining Speed", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_ToolMiningSpeed", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.toolMiningSpeed", - "IncludeInCommandLine": false, - "DefaultValue": "1", - "EnumValues": { - "1": "Normal (100%)", - "2": "200%", - "3": "300%", - "0.25": "25%", - "0.5": "50%", - "0.75": "75%", - "1.5": "150%" - } - }, - { - "DisplayName": "Prospecting Pick Node Radius", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_PropickNodeSearchRadius", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.propickNodeSearchRadius", - "IncludeInCommandLine": false, - "DefaultValue": "6", - "EnumValues": { - "0": "Disabled", - "2": "2 blocks", - "4": "4 blocks", - "6": "6 blocks (Standard)", - "8": "8 blocks" - } - }, - { - "DisplayName": "Microblock Chiseling", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_MicroblockChiseling", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.microblockChiseling", - "IncludeInCommandLine": false, - "DefaultValue": "stonewood", - "EnumValues": { - "off": "Off", - "stonewood": "Stone, wood, and bricks", - "all": "Most cubic blocks" - } - }, - { - "DisplayName": "Coordinate Overlay", - "Category": "World:public", - "Subcategory": "Map and Navigation:map:4", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_AllowCoordinateHud", - "InputType": "checkbox", - "ParamFieldName": "$.ExistingWorld.allowCoordinateHud", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "World Map", - "Category": "World:public", - "Subcategory": "Map and Navigation:map:4", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_AllowMap", - "InputType": "checkbox", - "ParamFieldName": "$.ExistingWorld.allowMap", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Color-accurate World Map", - "Category": "World:public", - "Subcategory": "Map and Navigation:map:4", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_ColorAccurateWorldmap", - "InputType": "checkbox", - "ParamFieldName": "$.ExistingWorld.colorAccurateWorldmap", - "IncludeInCommandLine": false, - "DefaultValue": "false", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Lore Content", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_LoreContent", - "InputType": "checkbox", - "ParamFieldName": "$.ExistingWorld.loreContent", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Clutter Obtainable", - "Category": "World:public", - "Subcategory": "Survival Challenges:local_fire_department:3", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_ClutterObtainable", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.clutterObtainable", - "IncludeInCommandLine": false, - "DefaultValue": "ifrepaired", - "EnumValues": { - "ifrepaired": "Only after repair with glue", - "yes": "Yes, without repair", - "no": "No" - } - }, - { - "DisplayName": "Temporal Stability", - "Category": "World:public", - "Subcategory": "Temporal Stability:storm:5", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_TemporalStability", - "InputType": "checkbox", - "ParamFieldName": "$.ExistingWorld.temporalStability", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Temporal Storms", - "Category": "World:public", - "Subcategory": "Temporal Stability:storm:5", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_TemporalStorms", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.temporalStorms", - "IncludeInCommandLine": false, - "DefaultValue": "sometimes", - "EnumValues": { - "off": "Off", - "veryrare": "Very rare", - "rare": "Rare", - "sometimes": "Sometimes (Standard)", - "often": "Often", - "veryoften": "Very often" - } - }, - { - "DisplayName": "Temporal Storm Length", - "Category": "World:public", - "Subcategory": "Temporal Stability:storm:5", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_TempstormDurationMul", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.tempstormDurationMul", - "IncludeInCommandLine": false, - "DefaultValue": "1", - "EnumValues": { - "1": "Normal (100%)", - "2": "200%", - "3": "300%", - "0.25": "25%", - "0.5": "50%", - "0.75": "75%", - "1.5": "150%" - } - }, - { - "DisplayName": "Temporal Rifts", - "Category": "World:public", - "Subcategory": "Temporal Stability:storm:5", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_TemporalRifts", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.temporalRifts", - "IncludeInCommandLine": false, - "DefaultValue": "visible", - "EnumValues": { - "off": "Off", - "invisible": "Invisible", - "visible": "Visible" - } - }, - { - "DisplayName": "Temporal Gear Respawn Uses", - "Category": "World:public", - "Subcategory": "Temporal Stability:storm:5", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_TemporalGearRespawnUses", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.temporalGearRespawnUses", - "IncludeInCommandLine": false, - "DefaultValue": "20", - "EnumValues": { - "1": "1 use", - "5": "5 uses", - "10": "10 uses", - "20": "20 uses (Standard)", - "50": "50 uses", - "100": "100 uses", - "-1": "Infinite" - } - }, - { - "DisplayName": "Sleeping During Temporal Storms", - "Category": "World:public", - "Subcategory": "Temporal Stability:storm:5", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_TemporalStormSleeping", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorld.temporalStormSleeping", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": { - "0": "Disallowed", - "1": "Allowed" - } - }, - { - "DisplayName": "Climate Distribution", - "Category": "World:public", - "Subcategory": "World Generation:terrain:6", - "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_WorldClimate", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorldgen.worldClimate", - "IncludeInCommandLine": false, - "DefaultValue": "realistic", - "EnumValues": { - "realistic": "Realistic", - "patchy": "Patchy" - } - }, - { - "DisplayName": "Landcover", - "Category": "World:public", - "Subcategory": "World Generation:terrain:6", - "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_Landcover", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorldgen.landcover", - "IncludeInCommandLine": false, - "DefaultValue": "0.975", - "EnumValues": { - "1": "100%", - "0.1": "10%", - "0.25": "25%", - "0.5": "50%", - "0.7": "70%", - "0.9": "90%", - "0.975": "97.5% (Standard)" - } - }, - { - "DisplayName": "Landcover Scale", - "Category": "World:public", - "Subcategory": "World Generation:terrain:6", - "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_OceanScale", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorldgen.oceanscale", - "IncludeInCommandLine": false, - "DefaultValue": "5", - "EnumValues": { - "1": "100%", - "2": "200%", - "5": "500% (Standard)", - "0.1": "10%", - "0.25": "25%", - "0.5": "50%" - } - }, - { - "DisplayName": "Upheaval Rate", - "Category": "World:public", - "Subcategory": "World Generation:terrain:6", - "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_UpheavelCommonness", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorldgen.upheavelCommonness", - "IncludeInCommandLine": false, - "DefaultValue": "0.3", - "EnumValues": { - "0": "0%", - "1": "100%", - "0.1": "10%", - "0.2": "20%", - "0.3": "30% (Standard)", - "0.4": "40%", - "0.5": "50%", - "0.6": "60%" - } - }, - { - "DisplayName": "Geologic Activity", - "Category": "World:public", - "Subcategory": "World Generation:terrain:6", - "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_GeologicActivity", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorldgen.geologicActivity", - "IncludeInCommandLine": false, - "DefaultValue": "0.05", - "EnumValues": { - "0": "None", - "0.025": "Very rare", - "0.05": "Rare (Standard)", - "0.1": "Uncommon", - "0.2": "Common", - "0.4": "Very common" - } - }, - { - "DisplayName": "Landform Scale", - "Category": "World:public", - "Subcategory": "World Generation:terrain:6", - "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_LandformScale", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorldgen.landformScale", - "IncludeInCommandLine": false, - "DefaultValue": "1", - "EnumValues": { - "1": "100% (Standard)", - "2": "200%", - "3": "300%", - "0.2": "20%", - "0.5": "50%", - "1.5": "150%" - } - }, - { - "DisplayName": "World Width", - "Category": "World:public", - "Subcategory": "World Generation:terrain:6", - "Description": "New worlds only. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_WorldWidth", - "InputType": "enum", - "ParamFieldName": "$.CreationOnlyWorldConfiguration.worldWidth", - "IncludeInCommandLine": false, - "DefaultValue": "1024000", - "EnumValues": { - "32768": "32k blocks", - "102400": "100k blocks", - "256000": "250k blocks", - "512000": "500k blocks", - "1024000": "1M blocks (Standard)", - "2048000": "2M blocks", - "4096000": "4M blocks", - "8192000": "8M blocks" - } - }, - { - "DisplayName": "World Length", - "Category": "World:public", - "Subcategory": "World Generation:terrain:6", - "Description": "New worlds only. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_WorldLength", - "InputType": "enum", - "ParamFieldName": "$.CreationOnlyWorldConfiguration.worldLength", - "IncludeInCommandLine": false, - "DefaultValue": "1024000", - "EnumValues": { - "32768": "32k blocks", - "102400": "100k blocks", - "256000": "250k blocks", - "512000": "500k blocks", - "1024000": "1M blocks (Standard)", - "2048000": "2M blocks", - "4096000": "4M blocks", - "8192000": "8M blocks" - } - }, - { - "DisplayName": "World Edge", - "Category": "World:public", - "Subcategory": "World Generation:terrain:6", - "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_WorldEdge", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorldgen.worldEdge", - "IncludeInCommandLine": false, - "DefaultValue": "traversable", - "EnumValues": { - "traversable": "Traversable (can fall down)", - "blocked": "Blocked" - } - }, - { - "DisplayName": "Polar-Equator Distance", - "Category": "World:public", - "Subcategory": "World Generation:terrain:6", - "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_PolarEquatorDistance", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorldgen.polarEquatorDistance", - "IncludeInCommandLine": false, - "DefaultValue": "100000", - "EnumValues": { - "5000": "5k blocks", - "10000": "10k blocks", - "15000": "15k blocks", - "25000": "25k blocks", - "50000": "50k blocks", - "100000": "100k blocks (Standard)", - "200000": "200k blocks", - "400000": "400k blocks", - "800000": "800k blocks" - } - }, - { - "DisplayName": "Story Structure Distance", - "Category": "World:public", - "Subcategory": "World Generation:terrain:6", - "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_StoryStructuresDistScaling", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorldgen.storyStructuresDistScaling", - "IncludeInCommandLine": false, - "DefaultValue": "1", - "EnumValues": { - "1": "100% (Standard)", - "2": "200%", - "3": "300%", - "0.15": "15%", - "0.25": "25%", - "0.5": "50%", - "0.75": "75%", - "1.5": "150%" - } - }, - { - "DisplayName": "Global Temperature", - "Category": "World:public", - "Subcategory": "World Generation:terrain:6", - "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_GlobalTemperature", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorldgen.globalTemperature", - "IncludeInCommandLine": false, - "DefaultValue": "1", - "EnumValues": { - "1": "Normal", - "2": "Hot", - "3": "Very hot", - "5": "Extreme heat", - "0.1": "Very cold", - "0.5": "Cold", - "1.5": "Warm" - } - }, - { - "DisplayName": "Global Precipitation", - "Category": "World:public", - "Subcategory": "World Generation:terrain:6", - "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_GlobalPrecipitation", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorldgen.globalPrecipitation", - "IncludeInCommandLine": false, - "DefaultValue": "1", - "EnumValues": { - "1": "Normal", - "2": "Very wet", - "3": "Extremely wet", - "5": "Maximum", - "0.1": "Very dry", - "0.5": "Dry", - "1.5": "Wet" - } - }, - { - "DisplayName": "Forestation \u0026 Shrubs", - "Category": "World:public", - "Subcategory": "World Generation:terrain:6", - "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_GlobalForestation", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorldgen.globalForestation", - "IncludeInCommandLine": false, - "DefaultValue": "0", - "EnumValues": { - "0": "Normal", - "1": "Full coverage", - "-1": "None", - "-0.5": "Sparse", - "0.5": "Dense" - } - }, - { - "DisplayName": "Global Deposit Spawn Rate", - "Category": "World:public", - "Subcategory": "World Generation:terrain:6", - "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_GlobalDepositSpawnRate", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorldgen.globalDepositSpawnRate", - "IncludeInCommandLine": false, - "DefaultValue": "1", - "EnumValues": { - "1": "100% (Standard)", - "2": "200%", - "3": "300%", - "0.2": "20%", - "0.5": "50%", - "0.75": "75%", - "1.5": "150%" - } - }, - { - "DisplayName": "Surface Copper Frequency", - "Category": "World:public", - "Subcategory": "World Generation:terrain:6", - "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_SurfaceCopperDeposits", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorldgen.surfaceCopperDeposits", - "IncludeInCommandLine": false, - "DefaultValue": "0.12", - "EnumValues": { - "0": "None", - "0.007": "Extremely rare", - "0.04": "Very rare", - "0.08": "Rare", - "0.12": "Standard", - "0.2": "Common", - "0.4": "Very common" - } - }, - { - "DisplayName": "Surface Tin Frequency", - "Category": "World:public", - "Subcategory": "World Generation:terrain:6", - "Description": "Applied to new worlds. With existing-world enforcement enabled, this affects unexplored chunks and can create terrain seams. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_SurfaceTinDeposits", - "InputType": "enum", - "ParamFieldName": "$.ExistingWorldgen.surfaceTinDeposits", - "IncludeInCommandLine": false, - "DefaultValue": "0.007", - "EnumValues": { - "0": "None", - "0.003": "Extremely rare", - "0.007": "Standard", - "0.02": "Rare", - "0.05": "Uncommon", - "0.1": "Common" - } - }, - { - "DisplayName": "Snow and Ice", - "Category": "World:public", - "Subcategory": "World Generation:terrain:6", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_SnowAccum", - "InputType": "checkbox", - "ParamFieldName": "$.ExistingWorld.snowAccum", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Land Claiming", - "Category": "World:public", - "Subcategory": "Multiplayer:groups:7", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_AllowLandClaiming", - "InputType": "checkbox", - "ParamFieldName": "$.ExistingWorld.allowLandClaiming", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Class-exclusive Recipes", - "Category": "World:public", - "Subcategory": "Multiplayer:groups:7", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_ClassExclusiveRecipes", - "InputType": "checkbox", - "ParamFieldName": "$.ExistingWorld.classExclusiveRecipes", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, - { - "DisplayName": "Auction House", - "Category": "World:public", - "Subcategory": "Multiplayer:groups:7", - "Description": "Applied to new worlds. Enable existing-world enforcement to apply it again at each restart. New-world setting. Uses Vintage Story\u0027s documented configuration value.", - "Keywords": "world,setup", - "FieldName": "VS_AuctionHouse", - "InputType": "checkbox", - "ParamFieldName": "$.ExistingWorld.auctionHouse", - "IncludeInCommandLine": false, - "DefaultValue": "true", - "EnumValues": { - "True": "true", - "False": "false" - } - }, { "DisplayName": "Nimbus Server ID", "Category": "Nimbus Backend:share", diff --git a/vintage-story-stratummetaconfig.json b/vintage-story-stratummetaconfig.json index 2aae28417..df80c95c2 100644 --- a/vintage-story-stratummetaconfig.json +++ b/vintage-story-stratummetaconfig.json @@ -1,6 +1,5 @@ [ {"ConfigFile":"data/serverconfig.json","AutoMap":true,"ConfigType":"json"}, - {"ConfigFile":"data/amp-world-settings.json","AutoMap":true,"ConfigType":"json"}, {"ConfigFile":"data/stratum.json","AutoMap":true,"ConfigType":"json"}, {"ConfigFile":"data/ModConfig/nimbus-server.json","AutoMap":true,"ConfigType":"json"} ] diff --git a/vintage-story-stratumstart.json b/vintage-story-stratumstart.json index 6ed40608f..fe51488c7 100644 --- a/vintage-story-stratumstart.json +++ b/vintage-story-stratumstart.json @@ -1,18 +1 @@ -[ - { - "UpdateStageName":"Apply AMP world settings", - "UpdateSourcePlatform":"Linux", - "UpdateSource":"Executable", - "UpdateSourceData":"/bin/sh", - "UpdateSourceArgs":"\"{{$FullRootDir}}tools/apply-world-settings.sh\" \"{{$FullRootDir}}\"", - "SkipOnFailure":false - }, - { - "UpdateStageName":"Apply AMP world settings", - "UpdateSourcePlatform":"Windows", - "UpdateSource":"Executable", - "UpdateSourceData":"powershell.exe", - "UpdateSourceArgs":"-NoProfile -ExecutionPolicy Bypass -File \"{{$FullRootDir}}tools\\apply-world-settings.ps1\" -Root \"{{$FullRootDir}}\"", - "SkipOnFailure":false - } -] +[] diff --git a/vintage-story-stratumupdates.json b/vintage-story-stratumupdates.json index 55694a910..2ad2e664d 100644 --- a/vintage-story-stratumupdates.json +++ b/vintage-story-stratumupdates.json @@ -127,43 +127,6 @@ "OverwriteExistingFiles": false, "SkipOnFailure": false }, - { - "UpdateStageName": "Deploy AMP world settings contract", - "UpdateSourcePlatform": "All", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}data/amp-world-settings-contract.json", - "UpdateSourceData": "[\r\n {\r\n \"Group\": \"Server\",\r\n \"Key\": \"AllowFireSpread\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"server\",\r\n \"CreationPath\": \"AllowFireSpread\",\r\n \"Command\": \"allowfirespread\"\r\n },\r\n {\r\n \"Group\": \"Creation\",\r\n \"Key\": \"WorldName\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"new-only\",\r\n \"CreationPath\": \"WorldConfig.WorldName\",\r\n \"Command\": null,\r\n \"MaxLength\": 128\r\n },\r\n {\r\n \"Group\": \"Creation\",\r\n \"Key\": \"Seed\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"new-only\",\r\n \"CreationPath\": \"WorldConfig.Seed\",\r\n \"Command\": null,\r\n \"MaxLength\": 256\r\n },\r\n {\r\n \"Group\": \"Creation\",\r\n \"Key\": \"PlayStyle\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"new-only\",\r\n \"CreationPath\": \"WorldConfig.PlayStyle\",\r\n \"Command\": null,\r\n \"Allowed\": [\r\n \"surviveandbuild\",\r\n \"exploration\",\r\n \"wildernesssurvival\",\r\n \"creativebuilding\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"Creation\",\r\n \"Key\": \"MapSizeY\",\r\n \"Type\": \"integer\",\r\n \"Lifecycle\": \"new-only\",\r\n \"CreationPath\": \"WorldConfig.MapSizeY\",\r\n \"Command\": null,\r\n \"Allowed\": [\r\n 128,\r\n 192,\r\n 256,\r\n 384,\r\n 448,\r\n 512\r\n ]\r\n },\r\n {\r\n \"Group\": \"Server\",\r\n \"Key\": \"AllowFallingBlocks\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"server\",\r\n \"CreationPath\": \"AllowFallingBlocks\",\r\n \"Command\": \"allowfallingblocks\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"gameMode\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.gameMode\",\r\n \"Command\": \"gameMode\",\r\n \"Allowed\": [\r\n \"survival\",\r\n \"creative\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"playerlives\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.playerlives\",\r\n \"Command\": \"playerlives\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"4\",\r\n \"5\",\r\n \"10\",\r\n \"20\",\r\n \"-1\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"CreationOnlyWorldConfiguration\",\r\n \"Key\": \"startingClimate\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"new-only\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.startingClimate\",\r\n \"Command\": null,\r\n \"Allowed\": [\r\n \"hot\",\r\n \"warm\",\r\n \"temperate\",\r\n \"cool\",\r\n \"icy\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"spawnRadius\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.spawnRadius\",\r\n \"Command\": \"spawnRadius\",\r\n \"Allowed\": [\r\n \"0\",\r\n \"25\",\r\n \"50\",\r\n \"100\",\r\n \"250\",\r\n \"500\",\r\n \"1000\",\r\n \"2500\",\r\n \"5000\",\r\n \"10000\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"CreationOnlyWorldConfiguration\",\r\n \"Key\": \"graceTimer\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"new-only\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.graceTimer\",\r\n \"Command\": null,\r\n \"Allowed\": [\r\n \"0\",\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"4\",\r\n \"5\",\r\n \"10\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"deathPunishment\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.deathPunishment\",\r\n \"Command\": \"deathPunishment\",\r\n \"Allowed\": [\r\n \"drop\",\r\n \"keep\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"droppedItemsTimer\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.droppedItemsTimer\",\r\n \"Command\": \"droppedItemsTimer\",\r\n \"Allowed\": [\r\n \"300\",\r\n \"600\",\r\n \"1200\",\r\n \"1800\",\r\n \"3600\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"seasons\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.seasons\",\r\n \"Command\": \"seasons\",\r\n \"Allowed\": [\r\n \"enabled\",\r\n \"spring\",\r\n \"summer\",\r\n \"fall\",\r\n \"winter\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"daysPerMonth\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.daysPerMonth\",\r\n \"Command\": \"daysPerMonth\",\r\n \"Allowed\": [\r\n \"3\",\r\n \"6\",\r\n \"9\",\r\n \"12\",\r\n \"20\",\r\n \"30\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"harshWinters\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.harshWinters\",\r\n \"Command\": \"harshWinters\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"blockGravity\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.blockGravity\",\r\n \"Command\": \"blockGravity\",\r\n \"Allowed\": [\r\n \"sandgravel\",\r\n \"sandgravelsoil\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"caveIns\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.caveIns\",\r\n \"Command\": \"caveIns\",\r\n \"Allowed\": [\r\n \"off\",\r\n \"on\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"lightningFires\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.lightningFires\",\r\n \"Command\": \"lightningFires\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"allowUndergroundFarming\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.allowUndergroundFarming\",\r\n \"Command\": \"allowUndergroundFarming\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"noLiquidSourceTransport\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.noLiquidSourceTransport\",\r\n \"Command\": \"noLiquidSourceTransport\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"playerHealthPoints\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.playerHealthPoints\",\r\n \"Command\": \"playerHealthPoints\",\r\n \"Allowed\": [\r\n \"5\",\r\n \"10\",\r\n \"15\",\r\n \"20\",\r\n \"25\",\r\n \"30\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"playerHealthRegenSpeed\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.playerHealthRegenSpeed\",\r\n \"Command\": \"playerHealthRegenSpeed\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"playerHungerSpeed\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.playerHungerSpeed\",\r\n \"Command\": \"playerHungerSpeed\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"lungCapacity\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.lungCapacity\",\r\n \"Command\": \"lungCapacity\",\r\n \"Allowed\": [\r\n \"10000\",\r\n \"20000\",\r\n \"30000\",\r\n \"40000\",\r\n \"60000\",\r\n \"120000\",\r\n \"3600000\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"bodyTemperatureResistance\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.bodyTemperatureResistance\",\r\n \"Command\": \"bodyTemperatureResistance\",\r\n \"Allowed\": [\r\n \"0\",\r\n \"10\",\r\n \"20\",\r\n \"-40\",\r\n \"-30\",\r\n \"-20\",\r\n \"-10\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"playerMoveSpeed\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.playerMoveSpeed\",\r\n \"Command\": \"playerMoveSpeed\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.5\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"creatureHostility\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.creatureHostility\",\r\n \"Command\": \"creatureHostility\",\r\n \"Allowed\": [\r\n \"aggressive\",\r\n \"passive\",\r\n \"off\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"creatureStrength\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.creatureStrength\",\r\n \"Command\": \"creatureStrength\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"creatureSwimSpeed\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.creatureSwimSpeed\",\r\n \"Command\": \"creatureSwimSpeed\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.5\",\r\n \"1.5\",\r\n \"2.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"foodSpoilSpeed\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.foodSpoilSpeed\",\r\n \"Command\": \"foodSpoilSpeed\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"saplingGrowthRate\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.saplingGrowthRate\",\r\n \"Command\": \"saplingGrowthRate\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"toolDurability\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.toolDurability\",\r\n \"Command\": \"toolDurability\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"toolMiningSpeed\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.toolMiningSpeed\",\r\n \"Command\": \"toolMiningSpeed\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"propickNodeSearchRadius\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.propickNodeSearchRadius\",\r\n \"Command\": \"propickNodeSearchRadius\",\r\n \"Allowed\": [\r\n \"0\",\r\n \"2\",\r\n \"4\",\r\n \"6\",\r\n \"8\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"microblockChiseling\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.microblockChiseling\",\r\n \"Command\": \"microblockChiseling\",\r\n \"Allowed\": [\r\n \"off\",\r\n \"stonewood\",\r\n \"all\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"allowCoordinateHud\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.allowCoordinateHud\",\r\n \"Command\": \"allowCoordinateHud\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"allowMap\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.allowMap\",\r\n \"Command\": \"allowMap\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"colorAccurateWorldmap\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.colorAccurateWorldmap\",\r\n \"Command\": \"colorAccurateWorldmap\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"loreContent\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.loreContent\",\r\n \"Command\": \"loreContent\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"clutterObtainable\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.clutterObtainable\",\r\n \"Command\": \"clutterObtainable\",\r\n \"Allowed\": [\r\n \"ifrepaired\",\r\n \"yes\",\r\n \"no\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"temporalStability\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.temporalStability\",\r\n \"Command\": \"temporalStability\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"temporalStorms\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.temporalStorms\",\r\n \"Command\": \"temporalStorms\",\r\n \"Allowed\": [\r\n \"off\",\r\n \"veryrare\",\r\n \"rare\",\r\n \"sometimes\",\r\n \"often\",\r\n \"veryoften\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"tempstormDurationMul\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.tempstormDurationMul\",\r\n \"Command\": \"tempstormDurationMul\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"temporalRifts\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.temporalRifts\",\r\n \"Command\": \"temporalRifts\",\r\n \"Allowed\": [\r\n \"off\",\r\n \"invisible\",\r\n \"visible\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"temporalGearRespawnUses\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.temporalGearRespawnUses\",\r\n \"Command\": \"temporalGearRespawnUses\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"5\",\r\n \"10\",\r\n \"20\",\r\n \"50\",\r\n \"100\",\r\n \"-1\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"temporalStormSleeping\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.temporalStormSleeping\",\r\n \"Command\": \"temporalStormSleeping\",\r\n \"Allowed\": [\r\n \"0\",\r\n \"1\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"worldClimate\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.worldClimate\",\r\n \"Command\": \"worldClimate\",\r\n \"Allowed\": [\r\n \"realistic\",\r\n \"patchy\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"landcover\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.landcover\",\r\n \"Command\": \"landcover\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"0.1\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.7\",\r\n \"0.9\",\r\n \"0.975\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"oceanscale\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.oceanscale\",\r\n \"Command\": \"oceanscale\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"5\",\r\n \"0.1\",\r\n \"0.25\",\r\n \"0.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"upheavelCommonness\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.upheavelCommonness\",\r\n \"Command\": \"upheavelCommonness\",\r\n \"Allowed\": [\r\n \"0\",\r\n \"1\",\r\n \"0.1\",\r\n \"0.2\",\r\n \"0.3\",\r\n \"0.4\",\r\n \"0.5\",\r\n \"0.6\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"geologicActivity\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.geologicActivity\",\r\n \"Command\": \"geologicActivity\",\r\n \"Allowed\": [\r\n \"0\",\r\n \"0.025\",\r\n \"0.05\",\r\n \"0.1\",\r\n \"0.2\",\r\n \"0.4\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"landformScale\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.landformScale\",\r\n \"Command\": \"landformScale\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.2\",\r\n \"0.5\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"CreationOnlyWorldConfiguration\",\r\n \"Key\": \"worldWidth\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"new-only\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.worldWidth\",\r\n \"Command\": null,\r\n \"Allowed\": [\r\n \"32768\",\r\n \"102400\",\r\n \"256000\",\r\n \"512000\",\r\n \"1024000\",\r\n \"2048000\",\r\n \"4096000\",\r\n \"8192000\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"CreationOnlyWorldConfiguration\",\r\n \"Key\": \"worldLength\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"new-only\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.worldLength\",\r\n \"Command\": null,\r\n \"Allowed\": [\r\n \"32768\",\r\n \"102400\",\r\n \"256000\",\r\n \"512000\",\r\n \"1024000\",\r\n \"2048000\",\r\n \"4096000\",\r\n \"8192000\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"worldEdge\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.worldEdge\",\r\n \"Command\": \"worldEdge\",\r\n \"Allowed\": [\r\n \"traversable\",\r\n \"blocked\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"polarEquatorDistance\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.polarEquatorDistance\",\r\n \"Command\": \"polarEquatorDistance\",\r\n \"Allowed\": [\r\n \"5000\",\r\n \"10000\",\r\n \"15000\",\r\n \"25000\",\r\n \"50000\",\r\n \"100000\",\r\n \"200000\",\r\n \"400000\",\r\n \"800000\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"storyStructuresDistScaling\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.storyStructuresDistScaling\",\r\n \"Command\": \"storyStructuresDistScaling\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.15\",\r\n \"0.25\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"globalTemperature\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.globalTemperature\",\r\n \"Command\": \"globalTemperature\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"5\",\r\n \"0.1\",\r\n \"0.5\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"globalPrecipitation\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.globalPrecipitation\",\r\n \"Command\": \"globalPrecipitation\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"5\",\r\n \"0.1\",\r\n \"0.5\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"globalForestation\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.globalForestation\",\r\n \"Command\": \"globalForestation\",\r\n \"Allowed\": [\r\n \"0\",\r\n \"1\",\r\n \"-1\",\r\n \"-0.5\",\r\n \"0.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"globalDepositSpawnRate\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.globalDepositSpawnRate\",\r\n \"Command\": \"globalDepositSpawnRate\",\r\n \"Allowed\": [\r\n \"1\",\r\n \"2\",\r\n \"3\",\r\n \"0.2\",\r\n \"0.5\",\r\n \"0.75\",\r\n \"1.5\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"surfaceCopperDeposits\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.surfaceCopperDeposits\",\r\n \"Command\": \"surfaceCopperDeposits\",\r\n \"Allowed\": [\r\n \"0\",\r\n \"0.007\",\r\n \"0.04\",\r\n \"0.08\",\r\n \"0.12\",\r\n \"0.2\",\r\n \"0.4\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorldgen\",\r\n \"Key\": \"surfaceTinDeposits\",\r\n \"Type\": \"string\",\r\n \"Lifecycle\": \"unexplored\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.surfaceTinDeposits\",\r\n \"Command\": \"surfaceTinDeposits\",\r\n \"Allowed\": [\r\n \"0\",\r\n \"0.003\",\r\n \"0.007\",\r\n \"0.02\",\r\n \"0.05\",\r\n \"0.1\"\r\n ]\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"snowAccum\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.snowAccum\",\r\n \"Command\": \"snowAccum\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"allowLandClaiming\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.allowLandClaiming\",\r\n \"Command\": \"allowLandClaiming\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"classExclusiveRecipes\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.classExclusiveRecipes\",\r\n \"Command\": \"classExclusiveRecipes\"\r\n },\r\n {\r\n \"Group\": \"ExistingWorld\",\r\n \"Key\": \"auctionHouse\",\r\n \"Type\": \"boolean\",\r\n \"Lifecycle\": \"restart\",\r\n \"CreationPath\": \"WorldConfig.WorldConfiguration.auctionHouse\",\r\n \"Command\": \"auctionHouse\"\r\n }\r\n]\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, - { - "UpdateStageName": "Seed AMP world settings when missing", - "UpdateSourcePlatform": "All", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}data/amp-world-settings.json", - "UpdateSourceData": "{\n \"SchemaVersion\": 1,\n \"ApplyToExistingWorld\": false,\n \"Creation\": {\n \"WorldName\": \"A new world\",\n \"Seed\": \"\",\n \"PlayStyle\": \"surviveandbuild\",\n \"MapSizeY\": 256\n },\n \"CreationOnlyWorldConfiguration\": {\n \"startingClimate\": \"temperate\",\n \"graceTimer\": \"0\",\n \"worldWidth\": \"1024000\",\n \"worldLength\": \"1024000\"\n },\n \"ExistingWorld\": {\n \"gameMode\": \"survival\",\n \"playerlives\": \"-1\",\n \"spawnRadius\": \"50\",\n \"deathPunishment\": \"drop\",\n \"droppedItemsTimer\": \"600\",\n \"seasons\": \"enabled\",\n \"daysPerMonth\": \"9\",\n \"harshWinters\": true,\n \"blockGravity\": \"sandgravel\",\n \"caveIns\": \"off\",\n \"lightningFires\": false,\n \"allowUndergroundFarming\": false,\n \"noLiquidSourceTransport\": false,\n \"playerHealthPoints\": \"15\",\n \"playerHealthRegenSpeed\": \"1\",\n \"playerHungerSpeed\": \"1\",\n \"lungCapacity\": \"40000\",\n \"bodyTemperatureResistance\": \"0\",\n \"playerMoveSpeed\": \"1.5\",\n \"creatureHostility\": \"aggressive\",\n \"creatureStrength\": \"1\",\n \"creatureSwimSpeed\": \"2\",\n \"foodSpoilSpeed\": \"1\",\n \"saplingGrowthRate\": \"1\",\n \"toolDurability\": \"1\",\n \"toolMiningSpeed\": \"1\",\n \"propickNodeSearchRadius\": \"6\",\n \"microblockChiseling\": \"stonewood\",\n \"allowCoordinateHud\": true,\n \"allowMap\": true,\n \"colorAccurateWorldmap\": false,\n \"loreContent\": true,\n \"clutterObtainable\": \"ifrepaired\",\n \"temporalStability\": true,\n \"temporalStorms\": \"sometimes\",\n \"tempstormDurationMul\": \"1\",\n \"temporalRifts\": \"visible\",\n \"temporalGearRespawnUses\": \"20\",\n \"temporalStormSleeping\": \"0\",\n \"snowAccum\": true,\n \"allowLandClaiming\": true,\n \"classExclusiveRecipes\": true,\n \"auctionHouse\": true\n },\n \"ExistingWorldgen\": {\n \"worldClimate\": \"realistic\",\n \"landcover\": \"0.975\",\n \"oceanscale\": \"5\",\n \"upheavelCommonness\": \"0.3\",\n \"geologicActivity\": \"0.05\",\n \"landformScale\": \"1\",\n \"worldEdge\": \"traversable\",\n \"polarEquatorDistance\": \"100000\",\n \"storyStructuresDistScaling\": \"1\",\n \"globalTemperature\": \"1\",\n \"globalPrecipitation\": \"1\",\n \"globalForestation\": \"0\",\n \"globalDepositSpawnRate\": \"1\",\n \"surfaceCopperDeposits\": \"0.12\",\n \"surfaceTinDeposits\": \"0.007\"\n },\n \"Server\": {\n \"AllowFireSpread\": true,\n \"AllowFallingBlocks\": true\n }\n}\n", - "OverwriteExistingFiles": false, - "SkipOnFailure": false - }, - { - "UpdateStageName": "Deploy AMP world settings renderer (Linux)", - "UpdateSourcePlatform": "Linux", - "UpdateSourceArch": "x86_64", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}tools/apply-world-settings.sh", - "UpdateSourceData": "#!/bin/sh\nset -eu\n\nfail() {\n printf \u0027%s\\n\u0027 \"[AMP World] ERROR: $*\" \u003e\u00262\n exit 1\n}\n\n[ \"$#\" -eq 1 ] || fail \u0027usage: apply-world-settings.sh INSTANCE_ROOT\u0027\ncommand -v jq \u003e/dev/null 2\u003e\u00261 || fail \u0027jq is required\u0027\ncommand -v realpath \u003e/dev/null 2\u003e\u00261 || fail \u0027realpath is required\u0027\n\nroot=$(realpath -m \"$1\")\ndata=\"$root/data\"\nmanaged=\"$data/amp-world-settings.json\"\ncontract=\"$data/amp-world-settings-contract.json\"\nconfig=\"$data/serverconfig.json\"\nstate=\"$data/amp-world-settings-state.json\"\nbackup=\"$data/serverconfig.json.amp-world-backup\"\n\n[ -f \"$managed\" ] || fail \"AMP world settings do not exist: $managed\"\n[ -f \"$contract\" ] || fail \"AMP world settings contract does not exist: $contract\"\n[ -f \"$config\" ] || fail \"Vintage Story serverconfig does not exist: $config\"\n\njq empty \"$managed\" \u003e/dev/null 2\u003e\u00261 || fail \u0027AMP world settings are not valid JSON\u0027\njq empty \"$contract\" \u003e/dev/null 2\u003e\u00261 || fail \u0027AMP world settings contract is not valid JSON\u0027\njq empty \"$config\" \u003e/dev/null 2\u003e\u00261 || fail \u0027Vintage Story serverconfig is not valid JSON\u0027\n\njq -e --slurpfile c \"$contract\" \u0027\n . as $m |\n ($m.SchemaVersion == 1) and\n (($m.ApplyToExistingWorld | type) == \"boolean\") and\n (($c[0] | type) == \"array\") and (($c[0] | length) == 68) and\n all($c[0][];\n . as $e |\n ($m | has($e.Group)) and ($m[$e.Group] | has($e.Key)) and\n ($m[$e.Group][$e.Key] as $v |\n (($e.Type == \"string\" and ($v | type) == \"string\") or\n ($e.Type == \"boolean\" and ($v | type) == \"boolean\") or\n ($e.Type == \"integer\" and ($v | type) == \"number\" and ($v | floor) == $v) or\n ($e.Type == \"number\" and ($v | type) == \"number\")) and\n (($e | has(\"Allowed\") | not) or (($e.Allowed | index($v)) != null)) and\n (($e | has(\"MaxLength\") | not) or (($v | length) \u003c= $e.MaxLength))))\n\u0027 \"$managed\" \u003e/dev/null 2\u003e\u00261 || fail \u0027managed settings failed schema, type, or allowed-value validation\u0027\n\nsave_location=$(jq -er \u0027.WorldConfig.SaveFileLocation | select(type == \"string\" and length \u003e 0)\u0027 \"$config\") || fail \u0027WorldConfig.SaveFileLocation is blank or missing\u0027\nserver_root=$(realpath -m \"$root/server\")\ndata_root=$(realpath -m \"$data\")\ncase \"$save_location\" in\n /*) save_path=$(realpath -m \"$save_location\") ;;\n *)\n save_path=$(realpath -m \"$server_root/$save_location\")\n case \"$save_path\" in\n \"$data_root\"/*) ;;\n *) fail \"relative SaveFileLocation escapes the instance data directory: $save_location\" ;;\n esac\n ;;\nesac\n\nif [ -f \"$save_path\" ]; then existing=true; else existing=false; fi\nenforce=$(jq -r \u0027.ApplyToExistingWorld\u0027 \"$managed\")\n\nrendered=$(mktemp \"$data/.serverconfig.json.tmp.XXXXXX\")\nnext_rendered=$(mktemp \"$data/.serverconfig.json.next.XXXXXX\")\nprevious_commands=$(mktemp \"$data/.amp-world-previous.XXXXXX\")\nmanaged_commands=$(mktemp \"$data/.amp-world-commands.XXXXXX\")\nstate_temp=$(mktemp \"$data/.amp-world-state.XXXXXX\")\ncleanup() {\n rm -f \"$rendered\" \"$next_rendered\" \"$previous_commands\" \"$managed_commands\" \"$state_temp\"\n}\ntrap cleanup EXIT HUP INT TERM\n\njq -S --slurpfile m \"$managed\" --slurpfile c \"$contract\" \u0027\n reduce ($c[0][] | select(.Group == \"Server\")) as $e\n (. ; setpath(($e.CreationPath | split(\".\")); $m[0][$e.Group][$e.Key]))\n\u0027 \"$config\" \u003e \"$rendered\" || fail \u0027could not render server settings\u0027\n\nif [ \"$existing\" = false ]; then\n jq -S --slurpfile m \"$managed\" --slurpfile c \"$contract\" \u0027\n .WorldConfig.WorldConfiguration = {} |\n reduce ($c[0][] | select(.Group != \"Server\")) as $e\n (. ; setpath(\n ($e.CreationPath | split(\".\"));\n (if $e.Group == \"Creation\" and $e.Key == \"Seed\" and $m[0][$e.Group][$e.Key] == \"\"\n then null else $m[0][$e.Group][$e.Key] end)\n ))\n \u0027 \"$rendered\" \u003e \"$next_rendered\" || fail \u0027could not render new-world settings\u0027\n mv -f \"$next_rendered\" \"$rendered\"\n printf \u0027[]\\n\u0027 \u003e \"$managed_commands\"\nelse\n if [ -f \"$state\" ]; then\n if jq -e \u0027.SchemaVersion == 1 and (.ManagedCommands | type) == \"array\" and all(.ManagedCommands[]; type == \"string\")\u0027 \"$state\" \u003e/dev/null 2\u003e\u00261; then\n jq -c \u0027.ManagedCommands\u0027 \"$state\" \u003e \"$previous_commands\"\n else\n printf \u0027%s\\n\u0027 \u0027[AMP World] WARNING: state file invalid; preserving all existing startup commands\u0027 \u003e\u00262\n printf \u0027[]\\n\u0027 \u003e \"$previous_commands\"\n fi\n else\n printf \u0027[]\\n\u0027 \u003e \"$previous_commands\"\n fi\n\n if [ \"$enforce\" = true ]; then\n jq -c -n --slurpfile m \"$managed\" --slurpfile c \"$contract\" \u0027\n [$c[0][] | select(.Lifecycle == \"restart\" or .Lifecycle == \"unexplored\" or .Lifecycle == \"server\") |\n . as $e | ($m[0][$e.Group][$e.Key] | tostring) as $value |\n (if $e.Lifecycle == \"server\" then \"/serverconfig \" else \"/worldconfig \" end) + $e.Command + \" \" + $value]\n \u0027 \u003e \"$managed_commands\" || fail \u0027could not generate managed startup commands\u0027\n else\n printf \u0027[]\\n\u0027 \u003e \"$managed_commands\"\n fi\n\n jq -S --slurpfile old \"$previous_commands\" --slurpfile managed \"$managed_commands\" \u0027\n ((.StartupCommands // \"\") | split(\"\\n\") | map(sub(\"\\r$\"; \"\")) |\n map(select(length \u003e 0)) | map(. as $line | select(($old[0] | index($line)) == null))) as $custom |\n .StartupCommands = (($custom + $managed[0]) | join(\"\\n\"))\n \u0027 \"$rendered\" \u003e \"$next_rendered\" || fail \u0027could not reconcile startup commands\u0027\n mv -f \"$next_rendered\" \"$rendered\"\n jq -S -n --slurpfile commands \"$managed_commands\" \u0027{SchemaVersion:1, ManagedCommands:$commands[0]}\u0027 \u003e \"$state_temp\" || fail \u0027could not render managed state\u0027\nfi\n\njq empty \"$rendered\" \u003e/dev/null 2\u003e\u00261 || fail \u0027rendered serverconfig failed JSON validation\u0027\nif [ \"$existing\" = true ]; then jq empty \"$state_temp\" \u003e/dev/null 2\u003e\u00261 || fail \u0027rendered state failed JSON validation\u0027; fi\n\nchanged=false\nif ! cmp -s \"$rendered\" \"$config\"; then\n cp -p \"$config\" \"$backup\" || fail \u0027could not create serverconfig.json.amp-world-backup\u0027\n mv -f \"$rendered\" \"$config\" || fail \u0027could not atomically replace serverconfig.json\u0027\n changed=true\nfi\n\nif [ \"$existing\" = true ]; then\n if [ ! -f \"$state\" ] || ! cmp -s \"$state_temp\" \"$state\"; then\n if ! mv -f \"$state_temp\" \"$state\"; then\n if [ \"$changed\" = true ] \u0026\u0026 [ -f \"$backup\" ]; then\n rollback=$(mktemp \"$data/.serverconfig.rollback.XXXXXX\")\n cp -p \"$backup\" \"$rollback\" \u0026\u0026 mv -f \"$rollback\" \"$config\"\n fi\n fail \u0027could not atomically replace AMP world settings state\u0027\n fi\n fi\nfi\n\ncommand_count=$(jq -r \u0027length\u0027 \"$managed_commands\")\nif [ \"$existing\" = true ]; then creation_count=0; mode=existing; else creation_count=68; mode=new; fi\nprintf \u0027%s\\n\u0027 \"[AMP World] save=$mode enforcement=$enforce creation-values=$creation_count managed-commands=$command_count\"\nif [ \"$existing\" = true ] \u0026\u0026 [ \"$enforce\" = true ]; then\n printf \u0027%s\\n\u0027 \u0027[AMP World] WARNING: world-generation overrides affect only unexplored chunks and may create visible terrain borders\u0027 \u003e\u00262\nfi\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, - { - "UpdateStageName": "Deploy AMP world settings renderer (Windows)", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "CreateFile", - "UpdateSourceArgs": "{{$FullRootDir}}tools/apply-world-settings.ps1", - "UpdateSourceData": "[CmdletBinding()]\nparam(\n [Parameter(Mandatory=$true)]\n [string]$Root\n)\n\n$ErrorActionPreference = \u0027Stop\u0027\n\nfunction Read-JsonFile([string]$Path, [string]$Label) {\n if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) { throw \"$Label does not exist: $Path\" }\n try { return (Get-Content -Raw -LiteralPath $Path | ConvertFrom-Json) }\n catch { throw \"$Label is not valid JSON: $($_.Exception.Message)\" }\n}\n\nfunction Get-PropertyValue([object]$Object, [string]$Name) {\n if ($null -eq $Object) { throw \"Missing object containing \u0027$Name\u0027\" }\n $property = $Object.PSObject.Properties[$Name]\n if ($null -eq $property) { throw \"Missing required managed setting \u0027$Name\u0027\" }\n return $property.Value\n}\n\nfunction Test-ExactAllowed([object]$Value, [object[]]$Allowed) {\n foreach ($candidate in $Allowed) {\n if ($Value -is [string] -and $candidate -is [string]) {\n if ($Value -ceq $candidate) { return $true }\n }\n elseif ($Value -eq $candidate) { return $true }\n }\n return $false\n}\n\nfunction Assert-ContractValue([object]$Value, [object]$Entry) {\n $validType = switch ([string]$Entry.Type) {\n \u0027string\u0027 { $Value -is [string] }\n \u0027boolean\u0027 { $Value -is [bool] }\n \u0027integer\u0027 { $Value -is [int] -or $Value -is [long] }\n \u0027number\u0027 { $Value -is [int] -or $Value -is [long] -or $Value -is [double] -or $Value -is [decimal] }\n default { $false }\n }\n if (-not $validType) { throw \"$($Entry.Group).$($Entry.Key) must be $($Entry.Type)\" }\n\n $allowedProperty = $Entry.PSObject.Properties[\u0027Allowed\u0027]\n if ($null -ne $allowedProperty -and -not (Test-ExactAllowed $Value @($allowedProperty.Value))) {\n throw \"$($Entry.Group).$($Entry.Key) has unsupported value \u0027$Value\u0027\"\n }\n $maxLengthProperty = $Entry.PSObject.Properties[\u0027MaxLength\u0027]\n if ($null -ne $maxLengthProperty -and ([string]$Value).Length -gt [int]$maxLengthProperty.Value) {\n throw \"$($Entry.Group).$($Entry.Key) exceeds $($maxLengthProperty.Value) characters\"\n }\n}\n\nfunction Set-JsonPath([object]$Object, [string]$DotPath, [object]$Value) {\n $segments = @($DotPath -split \u0027\\.\u0027)\n $cursor = $Object\n for ($index = 0; $index -lt $segments.Count - 1; $index++) {\n $segment = $segments[$index]\n $property = $cursor.PSObject.Properties[$segment]\n if ($null -eq $property -or $null -eq $property.Value) {\n $child = [pscustomobject]@{}\n if ($null -eq $property) { $cursor | Add-Member -NotePropertyName $segment -NotePropertyValue $child }\n else { $property.Value = $child }\n $cursor = $child\n }\n else { $cursor = $property.Value }\n }\n $leaf = $segments[-1]\n $leafProperty = $cursor.PSObject.Properties[$leaf]\n if ($null -eq $leafProperty) { $cursor | Add-Member -NotePropertyName $leaf -NotePropertyValue $Value }\n else { $leafProperty.Value = $Value }\n}\n\nfunction Resolve-EffectiveSavePath([string]$RootPath, [string]$ConfiguredPath) {\n if ([string]::IsNullOrWhiteSpace($ConfiguredPath)) { throw \u0027WorldConfig.SaveFileLocation is blank\u0027 }\n if ([IO.Path]::IsPathRooted($ConfiguredPath)) { return [IO.Path]::GetFullPath($ConfiguredPath) }\n $serverRoot = [IO.Path]::GetFullPath((Join-Path $RootPath \u0027server\u0027))\n $resolved = [IO.Path]::GetFullPath((Join-Path $serverRoot $ConfiguredPath))\n $dataRoot = [IO.Path]::GetFullPath((Join-Path $RootPath \u0027data\u0027)).TrimEnd(\u0027\\\u0027,\u0027/\u0027) + [IO.Path]::DirectorySeparatorChar\n if (-not $resolved.StartsWith($dataRoot, [StringComparison]::OrdinalIgnoreCase)) {\n throw \"Relative SaveFileLocation escapes the instance data directory: $ConfiguredPath\"\n }\n return $resolved\n}\n\nfunction ConvertTo-CommandValue([object]$Value) {\n if ($Value -is [bool]) { return $Value.ToString().ToLowerInvariant() }\n if ($Value -is [IFormattable]) { return $Value.ToString($null, [Globalization.CultureInfo]::InvariantCulture) }\n return [string]$Value\n}\n\nfunction ConvertTo-StableJson([object]$Value) {\n return (($Value | ConvertTo-Json -Depth 40) + \"`n\")\n}\n\nfunction Write-ValidatedTemp([string]$Destination, [string]$Text) {\n $directory = Split-Path -Parent $Destination\n $temporary = Join-Path $directory (\u0027.\u0027 + [IO.Path]::GetFileName($Destination) + \u0027.tmp-\u0027 + [guid]::NewGuid().ToString(\u0027N\u0027))\n [IO.File]::WriteAllText($temporary, $Text, (New-Object Text.UTF8Encoding $false))\n try { Get-Content -Raw -LiteralPath $temporary | ConvertFrom-Json | Out-Null }\n catch { Remove-Item -LiteralPath $temporary -Force -ErrorAction SilentlyContinue; throw \"Rendered JSON validation failed for $Destination\" }\n return $temporary\n}\n\nfunction Replace-File([string]$Temporary, [string]$Destination, [string]$Backup = \u0027\u0027) {\n if (Test-Path -LiteralPath $Destination -PathType Leaf) {\n if ([string]::IsNullOrEmpty($Backup)) {\n $discardBackup = Join-Path ([IO.Path]::GetDirectoryName($Destination)) (\u0027.amp-world-discard-\u0027 + [guid]::NewGuid().ToString(\u0027N\u0027))\n try { [IO.File]::Replace($Temporary, $Destination, $discardBackup, $true) }\n finally { Remove-Item -LiteralPath $discardBackup -Force -ErrorAction SilentlyContinue }\n }\n else {\n [IO.File]::Replace($Temporary, $Destination, $Backup, $true)\n }\n }\n else { [IO.File]::Move($Temporary, $Destination) }\n}\n\nfunction Read-ManagedState([string]$Path) {\n if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) {\n return [pscustomobject]@{ Valid=$false; Commands=@(); Reason=\u0027missing\u0027 }\n }\n try {\n $value = Get-Content -Raw -LiteralPath $Path | ConvertFrom-Json\n if ($value.SchemaVersion -ne 1 -or $null -eq $value.PSObject.Properties[\u0027ManagedCommands\u0027]) { throw \u0027unsupported state shape\u0027 }\n $commands = @($value.ManagedCommands)\n foreach ($command in $commands) { if (-not ($command -is [string])) { throw \u0027ManagedCommands must contain strings\u0027 } }\n return [pscustomobject]@{ Valid=$true; Commands=$commands; Reason=\u0027\u0027 }\n }\n catch { return [pscustomobject]@{ Valid=$false; Commands=@(); Reason=\u0027invalid\u0027 } }\n}\n\n$rootPath = [IO.Path]::GetFullPath($Root)\n$dataPath = Join-Path $rootPath \u0027data\u0027\n$managedPath = Join-Path $dataPath \u0027amp-world-settings.json\u0027\n$contractPath = Join-Path $dataPath \u0027amp-world-settings-contract.json\u0027\n$serverConfigPath = Join-Path $dataPath \u0027serverconfig.json\u0027\n$statePath = Join-Path $dataPath \u0027amp-world-settings-state.json\u0027\n$backupPath = Join-Path $dataPath \u0027serverconfig.json.amp-world-backup\u0027\n\ntry {\n $managed = Read-JsonFile $managedPath \u0027AMP world settings\u0027\n $contract = Read-JsonFile $contractPath \u0027AMP world settings contract\u0027\n $serverConfig = Read-JsonFile $serverConfigPath \u0027Vintage Story serverconfig\u0027\n if ($managed.SchemaVersion -ne 1) { throw \"Unsupported AMP world settings schema version \u0027$($managed.SchemaVersion)\u0027\" }\n if (-not ($managed.ApplyToExistingWorld -is [bool])) { throw \u0027ApplyToExistingWorld must be boolean\u0027 }\n if ($contract.Count -ne 68) { throw \"World settings contract must contain 68 entries, found $($contract.Count)\" }\n\n $values = [ordered]@{}\n foreach ($entry in $contract) {\n $group = Get-PropertyValue $managed ([string]$entry.Group)\n $value = Get-PropertyValue $group ([string]$entry.Key)\n Assert-ContractValue $value $entry\n $values[\"$($entry.Group).$($entry.Key)\"] = $value\n }\n\n $worldConfig = Get-PropertyValue $serverConfig \u0027WorldConfig\u0027\n $saveLocation = [string](Get-PropertyValue $worldConfig \u0027SaveFileLocation\u0027)\n $savePath = Resolve-EffectiveSavePath $rootPath $saveLocation\n $existing = Test-Path -LiteralPath $savePath -PathType Leaf\n $managedCommands = @()\n $stateOutput = $null\n\n foreach ($entry in $contract | Where-Object { $_.Group -eq \u0027Server\u0027 }) {\n Set-JsonPath $serverConfig ([string]$entry.CreationPath) $values[\"$($entry.Group).$($entry.Key)\"]\n }\n\n if (-not $existing) {\n Set-JsonPath $serverConfig \u0027WorldConfig.WorldConfiguration\u0027 ([pscustomobject]@{})\n foreach ($entry in $contract | Where-Object { $_.Group -ne \u0027Server\u0027 }) {\n $value = $values[\"$($entry.Group).$($entry.Key)\"]\n if ($entry.Group -eq \u0027Creation\u0027 -and $entry.Key -eq \u0027Seed\u0027 -and [string]::IsNullOrEmpty([string]$value)) { $value = $null }\n Set-JsonPath $serverConfig ([string]$entry.CreationPath) $value\n }\n }\n else {\n $state = Read-ManagedState $statePath\n $startupProperty = $serverConfig.PSObject.Properties[\u0027StartupCommands\u0027]\n $startupText = if ($null -eq $startupProperty -or $null -eq $startupProperty.Value) { \u0027\u0027 } else { [string]$startupProperty.Value }\n $lines = @($startupText -split \"`r?`n\" | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })\n if ($state.Valid) {\n $lines = @($lines | Where-Object { $line = $_; -not @($state.Commands | Where-Object { $_ -ceq $line }).Count })\n }\n elseif ($state.Reason -eq \u0027invalid\u0027) { Write-Warning \u0027[AMP World] state file invalid; preserving all existing startup commands\u0027 }\n\n if ($managed.ApplyToExistingWorld) {\n foreach ($entry in $contract | Where-Object { $_.Lifecycle -in @(\u0027restart\u0027,\u0027unexplored\u0027,\u0027server\u0027) }) {\n $value = ConvertTo-CommandValue $values[\"$($entry.Group).$($entry.Key)\"]\n if ($entry.Lifecycle -eq \u0027server\u0027) { $managedCommands += \"/serverconfig $($entry.Command) $value\" }\n else { $managedCommands += \"/worldconfig $($entry.Command) $value\" }\n }\n }\n $combined = @($lines) + @($managedCommands)\n if ($null -eq $startupProperty) { $serverConfig | Add-Member -NotePropertyName StartupCommands -NotePropertyValue ($combined -join \"`n\") }\n else { $startupProperty.Value = ($combined -join \"`n\") }\n $stateOutput = [ordered]@{ SchemaVersion=1; ManagedCommands=@($managedCommands) }\n }\n\n $serverText = ConvertTo-StableJson $serverConfig\n $currentText = [IO.File]::ReadAllText($serverConfigPath)\n $serverChanged = $currentText -cne $serverText\n $serverTemp = if ($serverChanged) { Write-ValidatedTemp $serverConfigPath $serverText } else { $null }\n $stateTemp = $null\n $stateChanged = $false\n if ($existing) {\n $stateText = ConvertTo-StableJson $stateOutput\n $stateChanged = -not (Test-Path -LiteralPath $statePath) -or ([IO.File]::ReadAllText($statePath) -cne $stateText)\n if ($stateChanged) { $stateTemp = Write-ValidatedTemp $statePath $stateText }\n }\n\n try {\n if ($serverChanged) { Replace-File $serverTemp $serverConfigPath $backupPath; $serverTemp = $null }\n if ($stateChanged) { Replace-File $stateTemp $statePath; $stateTemp = $null }\n }\n catch {\n if ($serverChanged -and (Test-Path -LiteralPath $backupPath -PathType Leaf)) {\n $rollback = Join-Path $dataPath (\u0027.serverconfig.rollback-\u0027 + [guid]::NewGuid().ToString(\u0027N\u0027))\n [IO.File]::Copy($backupPath, $rollback, $true)\n Replace-File $rollback $serverConfigPath\n }\n throw\n }\n finally {\n if ($serverTemp) { Remove-Item -LiteralPath $serverTemp -Force -ErrorAction SilentlyContinue }\n if ($stateTemp) { Remove-Item -LiteralPath $stateTemp -Force -ErrorAction SilentlyContinue }\n }\n\n $mode = if ($existing) { \u0027existing\u0027 } else { \u0027new\u0027 }\n $enforcement = $managed.ApplyToExistingWorld.ToString().ToLowerInvariant()\n Write-Output \"[AMP World] save=$mode enforcement=$enforcement creation-values=$(if ($existing) { 0 } else { 68 }) managed-commands=$($managedCommands.Count)\"\n if ($existing -and $managed.ApplyToExistingWorld -and @($contract | Where-Object Lifecycle -eq \u0027unexplored\u0027).Count -gt 0) {\n Write-Warning \u0027[AMP World] world-generation overrides affect only unexplored chunks and may create visible terrain borders\u0027\n }\n}\ncatch {\n [Console]::Error.WriteLine(\"[AMP World] ERROR: $($_.Exception.Message)\")\n exit 1\n}\n", - "OverwriteExistingFiles": true, - "SkipOnFailure": false - }, { "UpdateStageName": "Install Nimbus ServerMod", "UpdateSourcePlatform": "Linux", From abc90d351164e770fd39bd29715fe016dc629357 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Thu, 13 Aug 2026 11:06:22 -0500 Subject: [PATCH 30/50] Delete stratum-nimbus.kvp --- stratum-nimbus.kvp | 89 ---------------------------------------------- 1 file changed, 89 deletions(-) delete mode 100644 stratum-nimbus.kvp diff --git a/stratum-nimbus.kvp b/stratum-nimbus.kvp deleted file mode 100644 index d3efa5afe..000000000 --- a/stratum-nimbus.kvp +++ /dev/null @@ -1,89 +0,0 @@ -Meta.DisplayName=Vintage Story Stratum + Nimbus Backend -Meta.Description=Stratum-powered Vintage Story server with Nimbus.ServerMod for multi-server networks -Meta.OS=Windows, Linux -Meta.AarchSupport=Native -Meta.Arch=x86_64 -Meta.Author=StratumServer -Meta.URL=https://github.com/StratumServer/Stratum -Meta.DisplayImageSource=url:https://wiki.vintagestory.at/images/thumb/8/8a/Gamelogo-vintagestory.png/340px-Gamelogo-vintagestory.png -Meta.EndpointURIFormat= -Meta.ConfigManifest=stratum-nimbusconfig.json -Meta.MetaConfigManifest=stratum-nimbusmetaconfig.json -Meta.ConfigRoot=stratum-nimbus.kvp -Meta.MinAMPVersion=2.4.6.0 -Meta.SpecificDockerImage=cubecoders/ampbase:debian -Meta.DockerRequired=False -Meta.ContainerPolicy=Supported -Meta.Prerequisites=[] -Meta.ConfigReleaseState=NotSpecified -Meta.NoCommercialUsage=True -Meta.ConfigVersion=1 -Meta.AppConfigId=e7e85f22-3665-43a1-ada6-c7e7e4eecb1f -App.DisplayName=Vintage Story Stratum + Nimbus -App.RootDir=./stratum-nimbus/ -App.BaseDirectory=./stratum-nimbus/ -App.ExecutableWin=server\StratumServer.exe -App.ExecutableLinux=server/StratumServer -App.WorkingDir=server -App.LinuxCommandLineArgs= -App.WindowsCommandLineArgs= -App.CommandLineArgs=--port {{$ServerPort}} --dataPath "../data" {{$FormattedArgs}} -App.UseLinuxIOREDIR=False -App.AppSettings={} -App.EnvironmentVariables={"DOTNET_ROOT":"{{$FullBaseDir}}dotnet"} -App.CommandLineParameterFormat=--{0} {1} -App.CommandLineParameterDelimiter= -App.ExitMethod=String -App.ExitTimeout=30 -App.ExitString=/stop -App.ExitFile=lock -App.HasWriteableConsole=True -App.HasReadableConsole=True -App.SupportsLiveSettingsChanges=False -App.LiveSettingChangeCommandFormat=set {0} "{1}" -App.ApplicationIPBinding=0.0.0.0 -App.Ports=@IncludeJson[stratum-nimbusports.json] -App.AdminPortRef=ServerPort -App.PrimaryApplicationPortRef=ServerPort -App.UniversalSleepApplicationUDPPortRef=ServerPort -App.UniversalSleepSteamQueryPortRef=ServerPort -App.MaxUsers={{$MaxUsers}} -App.UseRandomAdminPassword=False -App.RemoteAdminPassword= -App.AdminMethod=STDIO -App.AdminLoginTransform=None -App.RCONConnectDelaySeconds=5 -App.RCONConnectRetrySeconds=5 -App.RCONHeartbeatMinutes=0 -App.RCONHeartbeatCommand=ping -App.TelnetLoginFormat={0} -App.UpdateSources=@IncludeJson[stratum-nimbusupdates.json] -App.Compatibility=None -App.SteamUpdateAnonymousLogin=True -App.SteamForceLoginPrompt=False -App.RapidStartup=False -App.SmartExcludeExemptions=["*.cfg","*.conf","*.config","*.ini","*.json","*.xml","*.properties","*.kvp","*.yml","*.yaml","*.toml","*.lua","*.vcdbs"] -App.MonitorChildProcess=True -App.MonitorChildProcessWaitMs=100 -App.MonitorChildProcessName= -App.SupportsUniversalSleep=False -App.WakeupMode=Any -App.ApplicationReadyMode=RegexMatch -Console.FilterMatchRegex=|<\/font> -Console.FilterMatchReplacement= -Console.ThrowawayMessageRegex=^(WARNING|ERROR): Shader.+$ -Console.AppReadyRegex=^[\d\.]*\s*[\d:\.]+ \[.*Event\] (?:Dedicated Server|Serveur dédié|Dedizierter Server) now running on Port \d+ and (?:all ips|ip .*)!$ -Console.UserJoinRegex=^[\d\.]*\s*[\d:\.]+ \[.*Event\] (?.+?) [\[\]a-f\d:.]+ joins\.$ -Console.UserLeaveRegex=^[\d\.]*\s*[\d:\.]+ \[.*Event\] Player (?.+?) (left|got removed\. Reason: Server shutting down - Shutdown via server command).*$ -Console.UserChatRegex=^[\d\.]*\s*[\d:\.]+ \[.*Chat\] (?.+?): (?.+?):<\/strong> (?.+)$ -Console.UpdateAvailableRegex=^.*Stratum update available:.*$ -Console.MetricsRegex= -Console.SuppressLogAtStart=False -Console.ActivateLogRegex= -Console.UserActions={} -Limits.SleepMode=True -Limits.SleepOnStart=False -Limits.SleepDelayMinutes=5 -Limits.DozeDelay=2 -Limits.AutoRetryCount=2 -Limits.SleepStartThresholdSeconds=25 From 0921acd2dbf99a7cccd68443e82d629b3d8d35d2 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Thu, 13 Aug 2026 11:06:40 -0500 Subject: [PATCH 31/50] Delete stratum-nimbusports.json --- stratum-nimbusports.json | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 stratum-nimbusports.json diff --git a/stratum-nimbusports.json b/stratum-nimbusports.json deleted file mode 100644 index f87761f76..000000000 --- a/stratum-nimbusports.json +++ /dev/null @@ -1,9 +0,0 @@ -[ - { - "Protocol": "Both", - "Name": "Backend Server Port", - "Description": "Private game port used by the Nimbus proxy to reach this backend", - "Port": 42421, - "Ref": "ServerPort" - } -] From 7ec300fb13dc87ec84885b36bc71d04958c63b1e Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Thu, 13 Aug 2026 11:06:58 -0500 Subject: [PATCH 32/50] Delete stratum-nimbusconfig.json --- stratum-nimbusconfig.json | 45 --------------------------------------- 1 file changed, 45 deletions(-) delete mode 100644 stratum-nimbusconfig.json diff --git a/stratum-nimbusconfig.json b/stratum-nimbusconfig.json deleted file mode 100644 index ed3516a6d..000000000 --- a/stratum-nimbusconfig.json +++ /dev/null @@ -1,45 +0,0 @@ -[ - { "DisplayName": "Backend Port", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Private backend port reached by Nimbus", "Keywords": "port,backend", "FieldName": "$ServerPort", "InputType": "number", "Hidden": true, "ParamFieldName": "$.Port", "IncludeInCommandLine": false, "EnumValues": {} }, - { "DisplayName": "Make Backend Public", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Normally disabled because players should connect through the Nimbus proxy", "Keywords": "public,advertise", "FieldName": "AdvertiseServer", "InputType": "checkbox", "ParamFieldName": "$.AdvertiseServer", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Server Name", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Name of this backend server", "Keywords": "server,name", "FieldName": "ServerName", "InputType": "text", "ParamFieldName": "$.ServerName", "IncludeInCommandLine": false, "DefaultValue": "Stratum Nimbus Backend", "EnumValues": {} }, - { "DisplayName": "Welcome Message", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Welcome message shown when a player joins", "Keywords": "welcome,message", "FieldName": "WelcomeMessage", "InputType": "text", "ParamFieldName": "$.WelcomeMessage", "IncludeInCommandLine": false, "DefaultValue": "Welcome, {0}, may you survive well and prosper", "EnumValues": {} }, - { "DisplayName": "Player Limit", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Maximum simultaneous players on this backend", "Keywords": "players,limit", "FieldName": "$MaxUsers", "InputType": "number", "ParamFieldName": "$.MaxClients", "IncludeInCommandLine": false, "DefaultValue": "16", "MinValue": "1", "EnumValues": {} }, - { "DisplayName": "Whitelist Mode", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Vintage Story whitelist mode", "Keywords": "whitelist", "FieldName": "WhitelistMode", "InputType": "enum", "ParamFieldName": "$.WhitelistMode", "IncludeInCommandLine": false, "DefaultValue": "0", "EnumValues": { "0": "Default", "1": "Off", "2": "On" } }, - { "DisplayName": "Allow PvP", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Allow players to damage other players", "Keywords": "pvp", "FieldName": "AllowPvP", "InputType": "checkbox", "ParamFieldName": "$.AllowPvP", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Enable UPnP", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Normally disabled for a private Nimbus backend", "Keywords": "upnp", "FieldName": "Upnp", "InputType": "checkbox", "ParamFieldName": "$.Upnp", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Vintage Story Version", "Category": "Updates", "Subcategory": "Compatibility:verified_user:-1", "Description": "Required Vintage Story base version. AMP only selects Stratum and Nimbus releases that declare this exact game version", "Keywords": "vintage,story,version", "FieldName": "ServerVersion", "InputType": "text", "ParamFieldName": "ServerVersion", "IncludeInCommandLine": false, "Required": true, "DefaultValue": "1.22.6", "Placeholder": "1.22.6", "EnumValues": {} }, - { "DisplayName": "Stratum Version", "Category": "Updates", "Subcategory": "Compatibility:verified_user:-1", "Description": "Optional exact Stratum release tag. Empty selects the highest stable Stratum revision for the configured Vintage Story version", "Keywords": "stratum,version,release", "FieldName": "StratumVersion", "InputType": "text", "ParamFieldName": "StratumVersion", "IncludeInCommandLine": false, "DefaultValue": "", "Placeholder": "v1.22.6-stratum.2", "EnumValues": {} }, - { "DisplayName": "Nimbus Version", "Category": "Updates", "Subcategory": "Compatibility:verified_user:-1", "Description": "Optional exact Nimbus release tag. Empty selects the newest stable release whose tagged README declares the configured Vintage Story version", "Keywords": "nimbus,version,release", "FieldName": "NimbusVersion", "InputType": "text", "ParamFieldName": "NimbusVersion", "IncludeInCommandLine": false, "DefaultValue": "", "Placeholder": "v0.5.0", "EnumValues": {} }, - { "DisplayName": ".NET Release Stream", "Category": "Updates", "Subcategory": "Runtime:memory:-1", "Description": ".NET SDK release stream required by current Stratum and Nimbus releases", "Keywords": "dotnet,sdk,runtime", "FieldName": "DotnetRelease", "InputType": "enum", "ParamFieldName": "DotnetRelease", "IncludeInCommandLine": false, "DefaultValue": "10.0", "EnumValues": { "10.0": "10.0" } }, - { "DisplayName": ".NET SDK Version", "Category": "Updates", "Subcategory": "Runtime:memory:-1", "Description": "Optional exact SDK version. Empty installs the newest SDK in the selected stream", "Keywords": "dotnet,sdk,version", "FieldName": "DotnetSDKVersion", "InputType": "text", "ParamFieldName": "DotnetSDKVersion", "IncludeInCommandLine": false, "DefaultValue": "", "Placeholder": "10.0.100", "EnumValues": {} }, - { "DisplayName": "Enable Nimbus", "Category": "Nimbus Backend:share", "Subcategory": "Network:dns:1", "Description": "Enable Nimbus.ServerMod on this backend", "Keywords": "nimbus,enable", "FieldName": "NimbusEnabled", "InputType": "checkbox", "ParamFieldName": "$.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Nimbus Server ID", "Category": "Nimbus Backend:share", "Subcategory": "Network:dns:1", "Description": "Unique backend ID matching a key in the proxy Backend Servers setting", "Keywords": "nimbus,server,id", "FieldName": "NimbusServerId", "InputType": "text", "ParamFieldName": "$.ServerId", "IncludeInCommandLine": false, "Required": true, "DefaultValue": "backend-1", "EnumValues": {} }, - { "DisplayName": "Nimbus Display Name", "Category": "Nimbus Backend:share", "Subcategory": "Network:dns:1", "Description": "Human-readable backend name", "Keywords": "nimbus,display,name", "FieldName": "NimbusDisplayName", "InputType": "text", "ParamFieldName": "$.DisplayName", "IncludeInCommandLine": false, "DefaultValue": "Backend 1", "EnumValues": {} }, - { "DisplayName": "Nimbus Public Host", "Category": "Nimbus Backend:share", "Subcategory": "Network:dns:1", "Description": "Host address the proxy network uses to reach this backend", "Keywords": "nimbus,host,address", "FieldName": "NimbusPublicHost", "InputType": "text", "ParamFieldName": "$.PublicHost", "IncludeInCommandLine": false, "Required": true, "DefaultValue": "127.0.0.1", "EnumValues": {} }, - { "DisplayName": "Nimbus Public Port", "Category": "Nimbus Backend:share", "Subcategory": "Network:dns:1", "Description": "Port the proxy network uses to reach this backend", "Keywords": "nimbus,port", "FieldName": "NimbusPublicPort", "InputType": "number", "ParamFieldName": "$.PublicPort", "IncludeInCommandLine": false, "DefaultValue": "42421", "MinValue": "1", "MaxValue": "65535", "EnumValues": {} }, - { "DisplayName": "Nimbus Registry URL", "Category": "Nimbus Backend:share", "Subcategory": "Registry:dns:2", "Description": "Reachable HTTP URL of the proxy's embedded registry", "Keywords": "nimbus,registry,url", "FieldName": "NimbusRegistryUrl", "InputType": "text", "ParamFieldName": "$.RegistryUrl", "IncludeInCommandLine": false, "Required": true, "DefaultValue": "http://127.0.0.1:8765", "EnumValues": {} }, - { "DisplayName": "Nimbus Shared Secret", "Category": "Nimbus Backend:share", "Subcategory": "Registry:dns:2", "Description": "Copy registry.embedded_shared_secret from the proxy's nimbus.proxy.toml. Every backend must use the exact same value", "Keywords": "nimbus,secret,hmac", "FieldName": "NimbusSharedSecret", "InputType": "password", "ParamFieldName": "$.SharedSecret", "IncludeInCommandLine": false, "Required": true, "DefaultValue": "PASTE-THE-SECRET-FROM-nimbus.proxy.toml", "EnumValues": {} }, - { "DisplayName": "Maintenance Mode", "Category": "Nimbus Backend:share", "Subcategory": "Routing:swap_horiz:3", "Description": "Remove this backend from routing while keeping it online", "Keywords": "maintenance,routing", "FieldName": "NimbusMaintenance", "InputType": "checkbox", "ParamFieldName": "$.Maintenance", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Require Proxy Reservation", "Category": "Nimbus Backend:share", "Subcategory": "Routing:swap_horiz:3", "Description": "Reject direct joins that did not receive a Nimbus proxy reservation", "Keywords": "reservation,proxy", "FieldName": "NimbusReservationRequired", "InputType": "checkbox", "ParamFieldName": "$.ReservationRequired", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Fail Closed When Registry Is Unreachable", "Category": "Nimbus Backend:share", "Subcategory": "Routing:swap_horiz:3", "Description": "Reject joins during registry outages instead of failing open", "Keywords": "registry,fail,closed", "FieldName": "NimbusFailClosed", "InputType": "checkbox", "ParamFieldName": "$.FailClosedWhenRegistryUnreachable", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Allow Player Server Command", "Category": "Nimbus Backend:share", "Subcategory": "Transfers:swap_horiz:4", "Description": "Allow players to use /server and /join", "Keywords": "player,server,command", "FieldName": "NimbusAllowPlayerServerCommand", "InputType": "checkbox", "ParamFieldName": "$.AllowPlayerServerCommand", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Transfer Mode", "Category": "Nimbus Backend:share", "Subcategory": "Transfers:swap_horiz:4", "Description": "Redirect is the supported production transfer mode", "Keywords": "transfer,redirect", "FieldName": "NimbusTransferMode", "InputType": "enum", "ParamFieldName": "$.TransferMode", "IncludeInCommandLine": false, "DefaultValue": "redirect", "EnumValues": { "redirect": "Redirect" } }, - { "DisplayName": "Stratum Update Checks", "Category": "Stratum:security", "Subcategory": "Updates:update:1", "Description": "Let Stratum notify staff about matching updates in game", "Keywords": "stratum,update,check", "FieldName": "StratumUpdateChecks", "InputType": "checkbox", "ParamFieldName": "$.UpdateChecker.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Anonymous Stratum Statistics", "Category": "Stratum:security", "Subcategory": "Privacy:visibility:2", "Description": "Send anonymous Stratum version and player-count statistics", "Keywords": "statistics,privacy", "FieldName": "StratumServerStats", "InputType": "checkbox", "ParamFieldName": "$.ServerStats.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Preserve Vanilla Protocol", "Category": "Stratum:security", "Subcategory": "Compatibility:verified_user:3", "Description": "Keep Stratum compatible with the vanilla network protocol", "Keywords": "protocol,compatibility", "FieldName": "StratumPreserveProtocol", "InputType": "checkbox", "ParamFieldName": "$.Hardening.PreserveVanillaProtocol", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Packet Limits", "Category": "Stratum:security", "Subcategory": "Hardening:shield:4", "Description": "Enable per-client packet rate and size limits", "Keywords": "packet,limits,hardening", "FieldName": "StratumPacketLimits", "InputType": "checkbox", "ParamFieldName": "$.PacketLimits.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Log Packet Violations", "Category": "Stratum:security", "Subcategory": "Hardening:shield:4", "Description": "Log packet-limit violations", "Keywords": "packet,log,violation", "FieldName": "StratumLogPacketViolations", "InputType": "checkbox", "ParamFieldName": "$.PacketLimits.LogViolations", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Packet Violations Before Kick", "Category": "Stratum:security", "Subcategory": "Hardening:shield:4", "Description": "Number of packet violations in the window before disconnecting a client", "Keywords": "packet,kick,violations", "FieldName": "StratumPacketKickThreshold", "InputType": "number", "ParamFieldName": "$.PacketLimits.KickAfterViolations", "IncludeInCommandLine": false, "DefaultValue": "8", "MinValue": "0", "EnumValues": {} }, - { "DisplayName": "Packet Back-Pressure", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Cap main-thread packet drain work per tick", "Keywords": "packet,backpressure,performance", "FieldName": "StratumPacketBackPressure", "InputType": "checkbox", "ParamFieldName": "$.PacketBackPressure.Enabled", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Strict Client Mod Whitelist", "Category": "Stratum:security", "Subcategory": "Hardening:shield:4", "Description": "Only permit client mods included by Stratum's client mod policy", "Keywords": "client,mod,whitelist", "FieldName": "StratumStrictClientMods", "InputType": "checkbox", "ParamFieldName": "$.ClientModPolicy.StrictWhitelist", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Split Terrain Pass", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Run terrain generation as two stages; automatic compatibility fallback remains enabled", "Keywords": "worldgen,terrain,performance", "FieldName": "StratumSplitTerrain", "InputType": "checkbox", "ParamFieldName": "$.Worldgen.SplitTerrainPass", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Login Protection", "Category": "Stratum:security", "Subcategory": "Hardening:shield:4", "Description": "Temporarily protect players from damage after joining", "Keywords": "login,protection", "FieldName": "StratumLoginProtection", "InputType": "checkbox", "ParamFieldName": "$.LoginProtection.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Player Privacy", "Category": "Stratum:security", "Subcategory": "Privacy:visibility:2", "Description": "Enable Stratum map-pin and coordinate privacy controls", "Keywords": "player,privacy,map", "FieldName": "StratumPlayerPrivacy", "InputType": "checkbox", "ParamFieldName": "$.PlayerPrivacy.Enabled", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Stratum Backups", "Category": "Stratum:security", "Subcategory": "Backups:save:6", "Description": "Enable Stratum's scheduled backup system", "Keywords": "backup,save", "FieldName": "StratumBackups", "InputType": "checkbox", "ParamFieldName": "$.Backup.Enabled", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Chunk Sending Optimizations", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Enable Stratum chunk-send scheduling and overload controls", "Keywords": "chunks,sending,performance", "FieldName": "StratumChunkSending", "InputType": "checkbox", "ParamFieldName": "$.ChunkSending.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Chunk Generation Optimizations", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Enable Stratum chunk-generation request limits", "Keywords": "chunks,generation,performance", "FieldName": "StratumChunkGeneration", "InputType": "checkbox", "ParamFieldName": "$.ChunkGeneration.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Entity Ticking Optimizations", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Enable distance-aware entity ticking", "Keywords": "entity,ticking,performance", "FieldName": "StratumEntityTicking", "InputType": "checkbox", "ParamFieldName": "$.EntityTicking.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Autosave Smoothing", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Enable incremental autosave and chunk-pressure delays", "Keywords": "autosave,performance", "FieldName": "StratumAutosave", "InputType": "checkbox", "ParamFieldName": "$.AutoSave.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Block Tick Smoothing", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Enable caps and smoothing for block tick work", "Keywords": "block,tick,performance", "FieldName": "StratumBlockTicks", "InputType": "checkbox", "ParamFieldName": "$.BlockTicks.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Windows Timer Resolution", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Request high-resolution Windows timers; ignored on Linux", "Keywords": "windows,timer,performance", "FieldName": "StratumTimerResolution", "InputType": "checkbox", "ParamFieldName": "$.TimerResolution.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } } -] From e1e621c484e81fa93de8f99645b0ba6c7e0fac7d Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Thu, 13 Aug 2026 11:07:11 -0500 Subject: [PATCH 33/50] Delete stratum-nimbusupdates.json --- stratum-nimbusupdates.json | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 stratum-nimbusupdates.json diff --git a/stratum-nimbusupdates.json b/stratum-nimbusupdates.json deleted file mode 100644 index 836501be3..000000000 --- a/stratum-nimbusupdates.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { "UpdateStageName": "Server Directory Creation", "UpdateSourcePlatform": "All", "UpdateSource": "CreateDirectory", "UpdateSourceArgs": "{{$FullBaseDir}}server", "SkipOnFailure": false }, - { "UpdateStageName": "Data Directory Creation", "UpdateSourcePlatform": "All", "UpdateSource": "CreateDirectory", "UpdateSourceArgs": "{{$FullBaseDir}}data", "SkipOnFailure": false }, - { "UpdateStageName": "Mods Directory Creation", "UpdateSourcePlatform": "All", "UpdateSource": "CreateDirectory", "UpdateSourceArgs": "{{$FullBaseDir}}data/Mods", "SkipOnFailure": false }, - { "UpdateStageName": "Dotnet Directory Creation", "UpdateSourcePlatform": "All", "UpdateSource": "CreateDirectory", "UpdateSourceArgs": "{{$FullBaseDir}}dotnet", "SkipOnFailure": false }, - { "UpdateStageName": ".NET SDK Download", "UpdateSourcePlatform": "Linux", "UpdateSourceArch": "x86_64", "UpdateSource": "Executable", "UpdateSourceData": "/bin/bash", "UpdateSourceArgs": "-c \"DotnetVersion=\\\"{{DotnetSDKVersion}}\\\"; cd \\\"{{$FullBaseDir}}\\\" && if [[ -x dotnet/dotnet ]]; then InstalledVersion=$(dotnet/dotnet --version | xargs); else InstalledVersion=\\\"\\\"; fi; if [[ -z \\\"$DotnetVersion\\\" ]]; then DotnetVersion=$(wget -qO- https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json | jq -r \\\".[\\\\\\\"latest-sdk\\\\\\\"]\\\"); fi; if [[ ! \\\"$DotnetVersion\\\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+$ ]]; then echo \\\"Invalid .NET SDK version format specified\\\" && exit 1; elif [[ \\\"$InstalledVersion\\\" == \\\"$DotnetVersion\\\" ]]; then echo \\\".NET SDK v$DotnetVersion already installed. Skipping\\\" && exit 0; else rm -f dotnet.tar.gz; wget -qO dotnet.tar.gz https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-linux-x64.tar.gz || { echo \\\".NET SDK download failed\\\"; exit 1; }; rm -rf dotnet/* && tar -xzf dotnet.tar.gz -C dotnet && rm -f dotnet.tar.gz && echo \\\".NET SDK v$DotnetVersion downloaded\\\"; fi\"", "SkipOnFailure": false }, - { "UpdateStageName": ".NET SDK Download", "UpdateSourcePlatform": "Windows", "UpdateSource": "Executable", "UpdateSourceData": "powershell.exe", "UpdateSourceArgs": "-NoProfile -Command \"$ProgressPreference='SilentlyContinue'; [Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $DotnetVersion='{{DotnetSDKVersion}}'; Set-Location '{{$FullBaseDir}}'; if (Test-Path 'dotnet/dotnet.exe') { $InstalledVersion=(& dotnet/dotnet.exe --version).Trim() } else { $InstalledVersion='' }; if ([string]::IsNullOrWhiteSpace($DotnetVersion)) { $DotnetVersion=(Invoke-RestMethod -UseBasicParsing 'https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json').'latest-sdk' }; if ($DotnetVersion -notmatch '^\\d+\\.\\d+\\.\\d+$') { throw 'Invalid .NET SDK version format specified' }; if ($InstalledVersion -eq $DotnetVersion) { Write-Output \\\".NET SDK v$DotnetVersion already installed. Skipping\\\"; exit 0 }; Invoke-WebRequest -UseBasicParsing -Uri \\\"https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-win-x64.zip\\\" -OutFile dotnet.zip -ErrorAction Stop; Remove-Item 'dotnet/*' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive dotnet.zip dotnet -Force; Remove-Item dotnet.zip -Force; Write-Output \\\".NET SDK v$DotnetVersion downloaded\\\"\"", "SkipOnFailure": false }, - { "UpdateStageName": "Stratum Download", "UpdateSourcePlatform": "Windows", "UpdateSource": "Executable", "UpdateSourceData": "powershell.exe", "UpdateSourceArgs": "-NoProfile -Command \"$ErrorActionPreference='Stop'; $ProgressPreference='SilentlyContinue'; $game='{{ServerVersion}}'.Trim(); if ($game -notmatch '^\\d+\\.\\d+\\.\\d+(-rc\\.\\d+|-pre\\.\\d+)?$') { throw 'Invalid Vintage Story version' }; $requested='{{StratumVersion}}'.Trim(); if ($requested -and -not $requested.StartsWith('v')) { $requested='v'+$requested }; $releases=Invoke-RestMethod -UseBasicParsing 'https://api.github.com/repos/StratumServer/Stratum/releases?per_page=100'; if ($requested) { if ($requested -notmatch ('^v'+[regex]::Escape($game)+'-stratum\\.[0-9]+(?:\\.[0-9]+)*(?:-[0-9A-Za-z.-]+)?$')) { throw 'The requested Stratum tag does not match the configured Vintage Story version' }; $selected=$releases | Where-Object { $_.tag_name -eq $requested -and -not $_.draft } | Select-Object -First 1 } else { $pattern='^v'+[regex]::Escape($game)+'-stratum\\.([0-9]+(?:\\.[0-9]+)*)\\z'; $selected=$releases | Where-Object { -not $_.draft -and -not $_.prerelease -and $_.tag_name -match $pattern } | Sort-Object { [datetimeoffset]$_.published_at } -Descending | Select-Object -First 1 }; if (-not $selected) { throw \\\"No stable Stratum release was found for Vintage Story $game\\\" }; $version=$selected.tag_name.Substring(1); $assetName=\\\"stratum-$version-win-x64.zip\\\"; $asset=$selected.assets | Where-Object { $_.name -eq $assetName } | Select-Object -First 1; if (-not $asset -or $asset.browser_download_url -notmatch '^https://') { throw \\\"Release asset $assetName was not found\\\" }; Invoke-WebRequest -UseBasicParsing -Uri $asset.browser_download_url -OutFile '{{$FullBaseDir}}stratum.zip'; Remove-Item '{{$FullBaseDir}}stratum-temp' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive '{{$FullBaseDir}}stratum.zip' '{{$FullBaseDir}}stratum-temp' -Force; if (-not (Test-Path '{{$FullBaseDir}}stratum-temp/StratumServer.exe')) { throw 'StratumServer.exe was not found in the release' }; Copy-Item '{{$FullBaseDir}}stratum-temp/*' '{{$FullBaseDir}}server' -Recurse -Force; [IO.File]::WriteAllText('{{$FullBaseDir}}.stratum-version',$selected.tag_name); Remove-Item '{{$FullBaseDir}}stratum-temp','{{$FullBaseDir}}stratum.zip' -Recurse -Force; Write-Output (\\\"Stratum $($selected.tag_name) installed for Vintage Story $game\\\")\"", "SkipOnFailure": false }, - { "UpdateStageName": "Stratum Download", "UpdateSourcePlatform": "Linux", "UpdateSourceArch": "x86_64", "UpdateSource": "Executable", "UpdateSourceData": "/bin/bash", "UpdateSourceArgs": "-c \"set -euo pipefail; game='{{ServerVersion}}'; requested='{{StratumVersion}}'; [[ \\\"$game\\\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+(-rc\\.[0-9]+|-pre\\.[0-9]+)?$ ]] || { echo 'Invalid Vintage Story version'; exit 1; }; [[ -z \\\"$requested\\\" || \\\"$requested\\\" == v* ]] || requested=\\\"v$requested\\\"; releases='{{$FullBaseDir}}stratum-releases.json'; wget -qO \\\"$releases\\\" 'https://api.github.com/repos/StratumServer/Stratum/releases?per_page=100'; escaped_game=${game//./\\.}; if [[ -n \\\"$requested\\\" ]]; then [[ \\\"$requested\\\" =~ ^v${escaped_game}-stratum\\.[0-9]+(\\.[0-9]+)*(-[0-9A-Za-z.-]+)?$ ]] || { echo 'The requested Stratum tag does not match the configured Vintage Story version'; exit 1; }; selected=$(jq -r --arg tag \\\"$requested\\\" '.[] | select(.tag_name==$tag and (.draft|not)) | .tag_name' \\\"$releases\\\" | head -1); else selected=$(jq -r '.[] | select((.draft|not) and (.prerelease|not)) | .tag_name' \\\"$releases\\\" | grep -E \\\"^v${escaped_game}-stratum\\\\.[0-9]+(\\\\.[0-9]+)*$\\\" | sort -V | tail -1); fi; [[ -n \\\"$selected\\\" ]] || { echo \\\"No stable Stratum release was found for Vintage Story $game\\\"; exit 1; }; version=${selected#v}; asset=\\\"stratum-$version-linux-x64.zip\\\"; url=$(jq -r --arg tag \\\"$selected\\\" --arg asset \\\"$asset\\\" '.[] | select(.tag_name==$tag) | .assets[] | select(.name==$asset) | .browser_download_url' \\\"$releases\\\" | head -1); [[ \\\"$url\\\" == https://* ]] || { echo \\\"Release asset $asset was not found\\\"; exit 1; }; wget -qO '{{$FullBaseDir}}stratum.zip' \\\"$url\\\"; rm -rf '{{$FullBaseDir}}stratum-temp'; mkdir -p '{{$FullBaseDir}}stratum-temp'; unzip -qo '{{$FullBaseDir}}stratum.zip' -d '{{$FullBaseDir}}stratum-temp'; [[ -f '{{$FullBaseDir}}stratum-temp/StratumServer' ]] || { echo 'StratumServer was not found in the release'; exit 1; }; cp -rf '{{$FullBaseDir}}stratum-temp/.' '{{$FullBaseDir}}server/'; chmod +x '{{$FullBaseDir}}server/StratumServer'; printf '%s' \\\"$selected\\\" > '{{$FullBaseDir}}.stratum-version'; rm -rf '{{$FullBaseDir}}stratum-temp' '{{$FullBaseDir}}stratum.zip' \\\"$releases\\\"; echo \\\"Stratum $selected installed for Vintage Story $game\\\"\"", "SkipOnFailure": false }, - { "UpdateStageName": "Nimbus Server Mod Download", "UpdateSourcePlatform": "Windows", "UpdateSource": "Executable", "UpdateSourceData": "powershell.exe", "UpdateSourceArgs": "-NoProfile -Command \"$ErrorActionPreference='Stop'; $ProgressPreference='SilentlyContinue'; $game='{{ServerVersion}}'.Trim(); $requested='{{NimbusVersion}}'.Trim(); if ($requested -and -not $requested.StartsWith('v')) { $requested='v'+$requested }; $releases=Invoke-RestMethod -UseBasicParsing 'https://api.github.com/repos/StratumServer/Nimbus/releases?per_page=100'; if ($requested) { $candidates=@($releases | Where-Object { $_.tag_name -eq $requested -and -not $_.draft }) } else { $candidates=@($releases | Where-Object { -not $_.draft -and -not $_.prerelease }) }; $selected=$null; foreach ($release in $candidates) { try { $readme=Invoke-WebRequest -UseBasicParsing -Uri ('https://raw.githubusercontent.com/StratumServer/Nimbus/'+$release.tag_name+'/README.md') | Select-Object -ExpandProperty Content } catch { continue }; $match=[regex]::Match($readme,'Built and tested against Vintage Story\\s+([0-9]+\\.[0-9]+\\.[0-9]+(?:-rc\\.[0-9]+|-pre\\.[0-9]+)?)',[Text.RegularExpressions.RegexOptions]::IgnoreCase); if ($match.Success -and $match.Groups[1].Value -eq $game) { $selected=$release; break } }; if (-not $selected) { throw \\\"No Nimbus release declares compatibility with Vintage Story $game\\\" }; $assetName='Nimbus.ServerMod-'+$selected.tag_name+'.zip'; $asset=$selected.assets | Where-Object { $_.name -eq $assetName } | Select-Object -First 1; if (-not $asset -or $asset.browser_download_url -notmatch '^https://') { throw \\\"Release asset $assetName was not found\\\" }; Invoke-WebRequest -UseBasicParsing -Uri $asset.browser_download_url -OutFile '{{$FullBaseDir}}nimbus-mod.zip'; Remove-Item '{{$FullBaseDir}}nimbus-mod-temp' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive '{{$FullBaseDir}}nimbus-mod.zip' '{{$FullBaseDir}}nimbus-mod-temp' -Force; if (-not (Test-Path '{{$FullBaseDir}}nimbus-mod-temp/modinfo.json')) { throw 'Nimbus ServerMod modinfo.json was not found in the release' }; Remove-Item '{{$FullBaseDir}}data/Mods/Nimbus.ServerMod' -Recurse -Force -ErrorAction SilentlyContinue; New-Item -ItemType Directory '{{$FullBaseDir}}data/Mods/Nimbus.ServerMod' -Force | Out-Null; Copy-Item '{{$FullBaseDir}}nimbus-mod-temp/*' '{{$FullBaseDir}}data/Mods/Nimbus.ServerMod' -Recurse -Force; [IO.File]::WriteAllText('{{$FullBaseDir}}.nimbus-version',$selected.tag_name); Remove-Item '{{$FullBaseDir}}nimbus-mod-temp','{{$FullBaseDir}}nimbus-mod.zip' -Recurse -Force; Write-Output (\\\"Nimbus ServerMod $($selected.tag_name) installed for Vintage Story $game\\\")\"", "SkipOnFailure": false }, - { "UpdateStageName": "Nimbus Server Mod Download", "UpdateSourcePlatform": "Linux", "UpdateSourceArch": "x86_64", "UpdateSource": "Executable", "UpdateSourceData": "/bin/bash", "UpdateSourceArgs": "-c \"set -euo pipefail; game='{{ServerVersion}}'; requested='{{NimbusVersion}}'; [[ -z \\\"$requested\\\" || \\\"$requested\\\" == v* ]] || requested=\\\"v$requested\\\"; releases='{{$FullBaseDir}}nimbus-releases.json'; wget -qO \\\"$releases\\\" 'https://api.github.com/repos/StratumServer/Nimbus/releases?per_page=100'; if [[ -n \\\"$requested\\\" ]]; then tags=\\\"$requested\\\"; else tags=$(jq -r '.[] | select((.draft|not) and (.prerelease|not)) | .tag_name' \\\"$releases\\\"); fi; selected=''; while IFS= read -r tag; do [[ -n \\\"$tag\\\" ]] || continue; readme=$(wget -qO- \\\"https://raw.githubusercontent.com/StratumServer/Nimbus/$tag/README.md\\\" || true); compatible=$(printf '%s' \\\"$readme\\\" | grep -Eio 'Built and tested against Vintage Story[[:space:]]+[0-9]+\\.[0-9]+\\.[0-9]+(-rc\\.[0-9]+|-pre\\.[0-9]+)?' | head -1 | awk '{print $7}'); if [[ \\\"$compatible\\\" == \\\"$game\\\" ]]; then selected=\\\"$tag\\\"; break; fi; done <<< \\\"$tags\\\"; [[ -n \\\"$selected\\\" ]] || { echo \\\"No Nimbus release declares compatibility with Vintage Story $game\\\"; exit 1; }; asset=\\\"Nimbus.ServerMod-$selected.zip\\\"; url=$(jq -r --arg tag \\\"$selected\\\" --arg asset \\\"$asset\\\" '.[] | select(.tag_name==$tag) | .assets[] | select(.name==$asset) | .browser_download_url' \\\"$releases\\\" | head -1); [[ \\\"$url\\\" == https://* ]] || { echo \\\"Release asset $asset was not found\\\"; exit 1; }; wget -qO '{{$FullBaseDir}}nimbus-mod.zip' \\\"$url\\\"; rm -rf '{{$FullBaseDir}}nimbus-mod-temp'; mkdir -p '{{$FullBaseDir}}nimbus-mod-temp'; unzip -qo '{{$FullBaseDir}}nimbus-mod.zip' -d '{{$FullBaseDir}}nimbus-mod-temp'; [[ -f '{{$FullBaseDir}}nimbus-mod-temp/modinfo.json' ]] || { echo 'Nimbus ServerMod modinfo.json was not found in the release'; exit 1; }; rm -rf '{{$FullBaseDir}}data/Mods/Nimbus.ServerMod'; mkdir -p '{{$FullBaseDir}}data/Mods/Nimbus.ServerMod'; cp -rf '{{$FullBaseDir}}nimbus-mod-temp/.' '{{$FullBaseDir}}data/Mods/Nimbus.ServerMod/'; printf '%s' \\\"$selected\\\" > '{{$FullBaseDir}}.nimbus-version'; rm -rf '{{$FullBaseDir}}nimbus-mod-temp' '{{$FullBaseDir}}nimbus-mod.zip' \\\"$releases\\\"; echo \\\"Nimbus ServerMod $selected installed for Vintage Story $game\\\"\"", "SkipOnFailure": false }, - { "UpdateStageName": "Start Server", "UpdateSourcePlatform": "All", "UpdateSource": "StartApplication", "SkipOnFailure": false }, - { "UpdateStageName": "Wait For Server Start", "UpdateSourcePlatform": "All", "UpdateSource": "WaitForStartupComplete", "SkipOnFailure": false }, - { "UpdateStageName": "Stop Server", "UpdateSourcePlatform": "All", "UpdateSource": "ShutdownApplication", "SkipOnFailure": false } -] From ed75cf53728f90beddff77257f339ab156446b8f Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Thu, 13 Aug 2026 11:07:24 -0500 Subject: [PATCH 34/50] Delete stratum-nimbusmetaconfig.json --- stratum-nimbusmetaconfig.json | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 stratum-nimbusmetaconfig.json diff --git a/stratum-nimbusmetaconfig.json b/stratum-nimbusmetaconfig.json deleted file mode 100644 index 576fdc6f7..000000000 --- a/stratum-nimbusmetaconfig.json +++ /dev/null @@ -1,27 +0,0 @@ -[ - { - "ConfigFile": "data/serverconfig.json", - "AutoMap": true, - "ConfigType": "json" - }, - { - "ConfigFile": "data/ModConfig/nimbus-server.json", - "AutoMap": true, - "ConfigType": "json" - }, - { - "ConfigFile": "data/ModConfig/stratum.json", - "AutoMap": true, - "ConfigType": "json" - }, - { - "ConfigFile": "data/ModConfig/stratum-commands.json", - "AutoMap": true, - "ConfigType": "json" - }, - { - "ConfigFile": "data/ModConfig/stratum-performance.json", - "AutoMap": true, - "ConfigType": "json" - } -] From 5cde06c26e8de0c727086687d010b643be4ccce4 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Thu, 13 Aug 2026 11:17:44 -0500 Subject: [PATCH 35/50] Delete stratum-nimbus.kvp --- stratum-nimbus.kvp | 89 ---------------------------------------------- 1 file changed, 89 deletions(-) delete mode 100644 stratum-nimbus.kvp diff --git a/stratum-nimbus.kvp b/stratum-nimbus.kvp deleted file mode 100644 index 6b5d043f9..000000000 --- a/stratum-nimbus.kvp +++ /dev/null @@ -1,89 +0,0 @@ -Meta.DisplayName=Vintage Story Stratum + Nimbus Backend -Meta.Description=Stratum-powered Vintage Story server with Nimbus.ServerMod for multi-server networks -Meta.OS=Windows, Linux -Meta.AarchSupport=Native -Meta.Arch=x86_64 -Meta.Author=HuguesDePayens -Meta.URL=https://github.com/StratumServer/Stratum -Meta.DisplayImageSource=url:https://wiki.vintagestory.at/images/thumb/8/8a/Gamelogo-vintagestory.png/340px-Gamelogo-vintagestory.png -Meta.EndpointURIFormat= -Meta.ConfigManifest=stratum-nimbusconfig.json -Meta.MetaConfigManifest=stratum-nimbusmetaconfig.json -Meta.ConfigRoot=stratum-nimbus.kvp -Meta.MinAMPVersion=2.4.6.0 -Meta.SpecificDockerImage=cubecoders/ampbase:debian -Meta.DockerRequired=False -Meta.ContainerPolicy=Supported -Meta.Prerequisites=[] -Meta.ConfigReleaseState=NotSpecified -Meta.NoCommercialUsage=True -Meta.ConfigVersion=1 -Meta.AppConfigId=e7e85f22-3665-43a1-ada6-c7e7e4eecb1f -App.DisplayName=Vintage Story Stratum + Nimbus -App.RootDir=./stratum-nimbus/ -App.BaseDirectory=./stratum-nimbus/ -App.ExecutableWin=server\StratumServer.exe -App.ExecutableLinux=server/StratumServer -App.WorkingDir=server -App.LinuxCommandLineArgs= -App.WindowsCommandLineArgs= -App.CommandLineArgs=--port {{$ServerPort}} --dataPath "../data" {{$FormattedArgs}} -App.UseLinuxIOREDIR=False -App.AppSettings={} -App.EnvironmentVariables={"DOTNET_ROOT":"{{$FullBaseDir}}dotnet"} -App.CommandLineParameterFormat=--{0} {1} -App.CommandLineParameterDelimiter= -App.ExitMethod=String -App.ExitTimeout=30 -App.ExitString=/stop -App.ExitFile=lock -App.HasWriteableConsole=True -App.HasReadableConsole=True -App.SupportsLiveSettingsChanges=False -App.LiveSettingChangeCommandFormat=set {0} "{1}" -App.ApplicationIPBinding=0.0.0.0 -App.Ports=@IncludeJson[stratum-nimbusports.json] -App.AdminPortRef=ServerPort -App.PrimaryApplicationPortRef=ServerPort -App.UniversalSleepApplicationUDPPortRef=ServerPort -App.UniversalSleepSteamQueryPortRef=ServerPort -App.MaxUsers={{$MaxUsers}} -App.UseRandomAdminPassword=False -App.RemoteAdminPassword= -App.AdminMethod=STDIO -App.AdminLoginTransform=None -App.RCONConnectDelaySeconds=5 -App.RCONConnectRetrySeconds=5 -App.RCONHeartbeatMinutes=0 -App.RCONHeartbeatCommand=ping -App.TelnetLoginFormat={0} -App.UpdateSources=@IncludeJson[stratum-nimbusupdates.json] -App.Compatibility=None -App.SteamUpdateAnonymousLogin=True -App.SteamForceLoginPrompt=False -App.RapidStartup=False -App.SmartExcludeExemptions=["*.cfg","*.conf","*.config","*.ini","*.json","*.xml","*.properties","*.kvp","*.yml","*.yaml","*.toml","*.lua","*.vcdbs"] -App.MonitorChildProcess=True -App.MonitorChildProcessWaitMs=100 -App.MonitorChildProcessName= -App.SupportsUniversalSleep=False -App.WakeupMode=Any -App.ApplicationReadyMode=RegexMatch -Console.FilterMatchRegex=|<\/font> -Console.FilterMatchReplacement= -Console.ThrowawayMessageRegex=^(WARNING|ERROR): Shader.+$ -Console.AppReadyRegex=^[\d\.]*\s*[\d:\.]+ \[.*Event\] (?:Dedicated Server|Serveur dédié|Dedizierter Server) now running on Port \d+ and (?:all ips|ip .*)!$ -Console.UserJoinRegex=^[\d\.]*\s*[\d:\.]+ \[.*Event\] (?.+?) [\[\]a-f\d:.]+ joins\.$ -Console.UserLeaveRegex=^[\d\.]*\s*[\d:\.]+ \[.*Event\] Player (?.+?) (left|got removed\. Reason: Server shutting down - Shutdown via server command).*$ -Console.UserChatRegex=^[\d\.]*\s*[\d:\.]+ \[.*Chat\] (?.+?): (?.+?):<\/strong> (?.+)$ -Console.UpdateAvailableRegex=^.*Stratum update available:.*$ -Console.MetricsRegex= -Console.SuppressLogAtStart=False -Console.ActivateLogRegex= -Console.UserActions={} -Limits.SleepMode=True -Limits.SleepOnStart=False -Limits.SleepDelayMinutes=5 -Limits.DozeDelay=2 -Limits.AutoRetryCount=2 -Limits.SleepStartThresholdSeconds=25 From 2bd38c239664264f179765826bcdb159ba4a0f6f Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Thu, 13 Aug 2026 11:17:59 -0500 Subject: [PATCH 36/50] Delete stratum-nimbusports.json --- stratum-nimbusports.json | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 stratum-nimbusports.json diff --git a/stratum-nimbusports.json b/stratum-nimbusports.json deleted file mode 100644 index f87761f76..000000000 --- a/stratum-nimbusports.json +++ /dev/null @@ -1,9 +0,0 @@ -[ - { - "Protocol": "Both", - "Name": "Backend Server Port", - "Description": "Private game port used by the Nimbus proxy to reach this backend", - "Port": 42421, - "Ref": "ServerPort" - } -] From 0b58b9ade201b14e3236cc2dcc26364da0761599 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Thu, 13 Aug 2026 11:21:34 -0500 Subject: [PATCH 37/50] Delete stratum-nimbusconfig.json --- stratum-nimbusconfig.json | 45 --------------------------------------- 1 file changed, 45 deletions(-) delete mode 100644 stratum-nimbusconfig.json diff --git a/stratum-nimbusconfig.json b/stratum-nimbusconfig.json deleted file mode 100644 index ed3516a6d..000000000 --- a/stratum-nimbusconfig.json +++ /dev/null @@ -1,45 +0,0 @@ -[ - { "DisplayName": "Backend Port", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Private backend port reached by Nimbus", "Keywords": "port,backend", "FieldName": "$ServerPort", "InputType": "number", "Hidden": true, "ParamFieldName": "$.Port", "IncludeInCommandLine": false, "EnumValues": {} }, - { "DisplayName": "Make Backend Public", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Normally disabled because players should connect through the Nimbus proxy", "Keywords": "public,advertise", "FieldName": "AdvertiseServer", "InputType": "checkbox", "ParamFieldName": "$.AdvertiseServer", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Server Name", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Name of this backend server", "Keywords": "server,name", "FieldName": "ServerName", "InputType": "text", "ParamFieldName": "$.ServerName", "IncludeInCommandLine": false, "DefaultValue": "Stratum Nimbus Backend", "EnumValues": {} }, - { "DisplayName": "Welcome Message", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Welcome message shown when a player joins", "Keywords": "welcome,message", "FieldName": "WelcomeMessage", "InputType": "text", "ParamFieldName": "$.WelcomeMessage", "IncludeInCommandLine": false, "DefaultValue": "Welcome, {0}, may you survive well and prosper", "EnumValues": {} }, - { "DisplayName": "Player Limit", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Maximum simultaneous players on this backend", "Keywords": "players,limit", "FieldName": "$MaxUsers", "InputType": "number", "ParamFieldName": "$.MaxClients", "IncludeInCommandLine": false, "DefaultValue": "16", "MinValue": "1", "EnumValues": {} }, - { "DisplayName": "Whitelist Mode", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Vintage Story whitelist mode", "Keywords": "whitelist", "FieldName": "WhitelistMode", "InputType": "enum", "ParamFieldName": "$.WhitelistMode", "IncludeInCommandLine": false, "DefaultValue": "0", "EnumValues": { "0": "Default", "1": "Off", "2": "On" } }, - { "DisplayName": "Allow PvP", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Allow players to damage other players", "Keywords": "pvp", "FieldName": "AllowPvP", "InputType": "checkbox", "ParamFieldName": "$.AllowPvP", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Enable UPnP", "Category": "Vintage Story:stadia_controller", "Subcategory": "Server:dns:1", "Description": "Normally disabled for a private Nimbus backend", "Keywords": "upnp", "FieldName": "Upnp", "InputType": "checkbox", "ParamFieldName": "$.Upnp", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Vintage Story Version", "Category": "Updates", "Subcategory": "Compatibility:verified_user:-1", "Description": "Required Vintage Story base version. AMP only selects Stratum and Nimbus releases that declare this exact game version", "Keywords": "vintage,story,version", "FieldName": "ServerVersion", "InputType": "text", "ParamFieldName": "ServerVersion", "IncludeInCommandLine": false, "Required": true, "DefaultValue": "1.22.6", "Placeholder": "1.22.6", "EnumValues": {} }, - { "DisplayName": "Stratum Version", "Category": "Updates", "Subcategory": "Compatibility:verified_user:-1", "Description": "Optional exact Stratum release tag. Empty selects the highest stable Stratum revision for the configured Vintage Story version", "Keywords": "stratum,version,release", "FieldName": "StratumVersion", "InputType": "text", "ParamFieldName": "StratumVersion", "IncludeInCommandLine": false, "DefaultValue": "", "Placeholder": "v1.22.6-stratum.2", "EnumValues": {} }, - { "DisplayName": "Nimbus Version", "Category": "Updates", "Subcategory": "Compatibility:verified_user:-1", "Description": "Optional exact Nimbus release tag. Empty selects the newest stable release whose tagged README declares the configured Vintage Story version", "Keywords": "nimbus,version,release", "FieldName": "NimbusVersion", "InputType": "text", "ParamFieldName": "NimbusVersion", "IncludeInCommandLine": false, "DefaultValue": "", "Placeholder": "v0.5.0", "EnumValues": {} }, - { "DisplayName": ".NET Release Stream", "Category": "Updates", "Subcategory": "Runtime:memory:-1", "Description": ".NET SDK release stream required by current Stratum and Nimbus releases", "Keywords": "dotnet,sdk,runtime", "FieldName": "DotnetRelease", "InputType": "enum", "ParamFieldName": "DotnetRelease", "IncludeInCommandLine": false, "DefaultValue": "10.0", "EnumValues": { "10.0": "10.0" } }, - { "DisplayName": ".NET SDK Version", "Category": "Updates", "Subcategory": "Runtime:memory:-1", "Description": "Optional exact SDK version. Empty installs the newest SDK in the selected stream", "Keywords": "dotnet,sdk,version", "FieldName": "DotnetSDKVersion", "InputType": "text", "ParamFieldName": "DotnetSDKVersion", "IncludeInCommandLine": false, "DefaultValue": "", "Placeholder": "10.0.100", "EnumValues": {} }, - { "DisplayName": "Enable Nimbus", "Category": "Nimbus Backend:share", "Subcategory": "Network:dns:1", "Description": "Enable Nimbus.ServerMod on this backend", "Keywords": "nimbus,enable", "FieldName": "NimbusEnabled", "InputType": "checkbox", "ParamFieldName": "$.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Nimbus Server ID", "Category": "Nimbus Backend:share", "Subcategory": "Network:dns:1", "Description": "Unique backend ID matching a key in the proxy Backend Servers setting", "Keywords": "nimbus,server,id", "FieldName": "NimbusServerId", "InputType": "text", "ParamFieldName": "$.ServerId", "IncludeInCommandLine": false, "Required": true, "DefaultValue": "backend-1", "EnumValues": {} }, - { "DisplayName": "Nimbus Display Name", "Category": "Nimbus Backend:share", "Subcategory": "Network:dns:1", "Description": "Human-readable backend name", "Keywords": "nimbus,display,name", "FieldName": "NimbusDisplayName", "InputType": "text", "ParamFieldName": "$.DisplayName", "IncludeInCommandLine": false, "DefaultValue": "Backend 1", "EnumValues": {} }, - { "DisplayName": "Nimbus Public Host", "Category": "Nimbus Backend:share", "Subcategory": "Network:dns:1", "Description": "Host address the proxy network uses to reach this backend", "Keywords": "nimbus,host,address", "FieldName": "NimbusPublicHost", "InputType": "text", "ParamFieldName": "$.PublicHost", "IncludeInCommandLine": false, "Required": true, "DefaultValue": "127.0.0.1", "EnumValues": {} }, - { "DisplayName": "Nimbus Public Port", "Category": "Nimbus Backend:share", "Subcategory": "Network:dns:1", "Description": "Port the proxy network uses to reach this backend", "Keywords": "nimbus,port", "FieldName": "NimbusPublicPort", "InputType": "number", "ParamFieldName": "$.PublicPort", "IncludeInCommandLine": false, "DefaultValue": "42421", "MinValue": "1", "MaxValue": "65535", "EnumValues": {} }, - { "DisplayName": "Nimbus Registry URL", "Category": "Nimbus Backend:share", "Subcategory": "Registry:dns:2", "Description": "Reachable HTTP URL of the proxy's embedded registry", "Keywords": "nimbus,registry,url", "FieldName": "NimbusRegistryUrl", "InputType": "text", "ParamFieldName": "$.RegistryUrl", "IncludeInCommandLine": false, "Required": true, "DefaultValue": "http://127.0.0.1:8765", "EnumValues": {} }, - { "DisplayName": "Nimbus Shared Secret", "Category": "Nimbus Backend:share", "Subcategory": "Registry:dns:2", "Description": "Copy registry.embedded_shared_secret from the proxy's nimbus.proxy.toml. Every backend must use the exact same value", "Keywords": "nimbus,secret,hmac", "FieldName": "NimbusSharedSecret", "InputType": "password", "ParamFieldName": "$.SharedSecret", "IncludeInCommandLine": false, "Required": true, "DefaultValue": "PASTE-THE-SECRET-FROM-nimbus.proxy.toml", "EnumValues": {} }, - { "DisplayName": "Maintenance Mode", "Category": "Nimbus Backend:share", "Subcategory": "Routing:swap_horiz:3", "Description": "Remove this backend from routing while keeping it online", "Keywords": "maintenance,routing", "FieldName": "NimbusMaintenance", "InputType": "checkbox", "ParamFieldName": "$.Maintenance", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Require Proxy Reservation", "Category": "Nimbus Backend:share", "Subcategory": "Routing:swap_horiz:3", "Description": "Reject direct joins that did not receive a Nimbus proxy reservation", "Keywords": "reservation,proxy", "FieldName": "NimbusReservationRequired", "InputType": "checkbox", "ParamFieldName": "$.ReservationRequired", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Fail Closed When Registry Is Unreachable", "Category": "Nimbus Backend:share", "Subcategory": "Routing:swap_horiz:3", "Description": "Reject joins during registry outages instead of failing open", "Keywords": "registry,fail,closed", "FieldName": "NimbusFailClosed", "InputType": "checkbox", "ParamFieldName": "$.FailClosedWhenRegistryUnreachable", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Allow Player Server Command", "Category": "Nimbus Backend:share", "Subcategory": "Transfers:swap_horiz:4", "Description": "Allow players to use /server and /join", "Keywords": "player,server,command", "FieldName": "NimbusAllowPlayerServerCommand", "InputType": "checkbox", "ParamFieldName": "$.AllowPlayerServerCommand", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Transfer Mode", "Category": "Nimbus Backend:share", "Subcategory": "Transfers:swap_horiz:4", "Description": "Redirect is the supported production transfer mode", "Keywords": "transfer,redirect", "FieldName": "NimbusTransferMode", "InputType": "enum", "ParamFieldName": "$.TransferMode", "IncludeInCommandLine": false, "DefaultValue": "redirect", "EnumValues": { "redirect": "Redirect" } }, - { "DisplayName": "Stratum Update Checks", "Category": "Stratum:security", "Subcategory": "Updates:update:1", "Description": "Let Stratum notify staff about matching updates in game", "Keywords": "stratum,update,check", "FieldName": "StratumUpdateChecks", "InputType": "checkbox", "ParamFieldName": "$.UpdateChecker.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Anonymous Stratum Statistics", "Category": "Stratum:security", "Subcategory": "Privacy:visibility:2", "Description": "Send anonymous Stratum version and player-count statistics", "Keywords": "statistics,privacy", "FieldName": "StratumServerStats", "InputType": "checkbox", "ParamFieldName": "$.ServerStats.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Preserve Vanilla Protocol", "Category": "Stratum:security", "Subcategory": "Compatibility:verified_user:3", "Description": "Keep Stratum compatible with the vanilla network protocol", "Keywords": "protocol,compatibility", "FieldName": "StratumPreserveProtocol", "InputType": "checkbox", "ParamFieldName": "$.Hardening.PreserveVanillaProtocol", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Packet Limits", "Category": "Stratum:security", "Subcategory": "Hardening:shield:4", "Description": "Enable per-client packet rate and size limits", "Keywords": "packet,limits,hardening", "FieldName": "StratumPacketLimits", "InputType": "checkbox", "ParamFieldName": "$.PacketLimits.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Log Packet Violations", "Category": "Stratum:security", "Subcategory": "Hardening:shield:4", "Description": "Log packet-limit violations", "Keywords": "packet,log,violation", "FieldName": "StratumLogPacketViolations", "InputType": "checkbox", "ParamFieldName": "$.PacketLimits.LogViolations", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Packet Violations Before Kick", "Category": "Stratum:security", "Subcategory": "Hardening:shield:4", "Description": "Number of packet violations in the window before disconnecting a client", "Keywords": "packet,kick,violations", "FieldName": "StratumPacketKickThreshold", "InputType": "number", "ParamFieldName": "$.PacketLimits.KickAfterViolations", "IncludeInCommandLine": false, "DefaultValue": "8", "MinValue": "0", "EnumValues": {} }, - { "DisplayName": "Packet Back-Pressure", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Cap main-thread packet drain work per tick", "Keywords": "packet,backpressure,performance", "FieldName": "StratumPacketBackPressure", "InputType": "checkbox", "ParamFieldName": "$.PacketBackPressure.Enabled", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Strict Client Mod Whitelist", "Category": "Stratum:security", "Subcategory": "Hardening:shield:4", "Description": "Only permit client mods included by Stratum's client mod policy", "Keywords": "client,mod,whitelist", "FieldName": "StratumStrictClientMods", "InputType": "checkbox", "ParamFieldName": "$.ClientModPolicy.StrictWhitelist", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Split Terrain Pass", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Run terrain generation as two stages; automatic compatibility fallback remains enabled", "Keywords": "worldgen,terrain,performance", "FieldName": "StratumSplitTerrain", "InputType": "checkbox", "ParamFieldName": "$.Worldgen.SplitTerrainPass", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Login Protection", "Category": "Stratum:security", "Subcategory": "Hardening:shield:4", "Description": "Temporarily protect players from damage after joining", "Keywords": "login,protection", "FieldName": "StratumLoginProtection", "InputType": "checkbox", "ParamFieldName": "$.LoginProtection.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Player Privacy", "Category": "Stratum:security", "Subcategory": "Privacy:visibility:2", "Description": "Enable Stratum map-pin and coordinate privacy controls", "Keywords": "player,privacy,map", "FieldName": "StratumPlayerPrivacy", "InputType": "checkbox", "ParamFieldName": "$.PlayerPrivacy.Enabled", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Stratum Backups", "Category": "Stratum:security", "Subcategory": "Backups:save:6", "Description": "Enable Stratum's scheduled backup system", "Keywords": "backup,save", "FieldName": "StratumBackups", "InputType": "checkbox", "ParamFieldName": "$.Backup.Enabled", "IncludeInCommandLine": false, "DefaultValue": "false", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Chunk Sending Optimizations", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Enable Stratum chunk-send scheduling and overload controls", "Keywords": "chunks,sending,performance", "FieldName": "StratumChunkSending", "InputType": "checkbox", "ParamFieldName": "$.ChunkSending.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Chunk Generation Optimizations", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Enable Stratum chunk-generation request limits", "Keywords": "chunks,generation,performance", "FieldName": "StratumChunkGeneration", "InputType": "checkbox", "ParamFieldName": "$.ChunkGeneration.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Entity Ticking Optimizations", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Enable distance-aware entity ticking", "Keywords": "entity,ticking,performance", "FieldName": "StratumEntityTicking", "InputType": "checkbox", "ParamFieldName": "$.EntityTicking.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Autosave Smoothing", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Enable incremental autosave and chunk-pressure delays", "Keywords": "autosave,performance", "FieldName": "StratumAutosave", "InputType": "checkbox", "ParamFieldName": "$.AutoSave.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Block Tick Smoothing", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Enable caps and smoothing for block tick work", "Keywords": "block,tick,performance", "FieldName": "StratumBlockTicks", "InputType": "checkbox", "ParamFieldName": "$.BlockTicks.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } }, - { "DisplayName": "Windows Timer Resolution", "Category": "Stratum:security", "Subcategory": "Performance:speed:5", "Description": "Request high-resolution Windows timers; ignored on Linux", "Keywords": "windows,timer,performance", "FieldName": "StratumTimerResolution", "InputType": "checkbox", "ParamFieldName": "$.TimerResolution.Enabled", "IncludeInCommandLine": false, "DefaultValue": "true", "EnumValues": { "True": "true", "False": "false" } } -] From 19ede494c362d764e1a02ff4f7c322deafe29c59 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Thu, 13 Aug 2026 11:22:06 -0500 Subject: [PATCH 38/50] Delete stratum-nimbusupdates.json --- stratum-nimbusupdates.json | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 stratum-nimbusupdates.json diff --git a/stratum-nimbusupdates.json b/stratum-nimbusupdates.json deleted file mode 100644 index 836501be3..000000000 --- a/stratum-nimbusupdates.json +++ /dev/null @@ -1,15 +0,0 @@ -[ - { "UpdateStageName": "Server Directory Creation", "UpdateSourcePlatform": "All", "UpdateSource": "CreateDirectory", "UpdateSourceArgs": "{{$FullBaseDir}}server", "SkipOnFailure": false }, - { "UpdateStageName": "Data Directory Creation", "UpdateSourcePlatform": "All", "UpdateSource": "CreateDirectory", "UpdateSourceArgs": "{{$FullBaseDir}}data", "SkipOnFailure": false }, - { "UpdateStageName": "Mods Directory Creation", "UpdateSourcePlatform": "All", "UpdateSource": "CreateDirectory", "UpdateSourceArgs": "{{$FullBaseDir}}data/Mods", "SkipOnFailure": false }, - { "UpdateStageName": "Dotnet Directory Creation", "UpdateSourcePlatform": "All", "UpdateSource": "CreateDirectory", "UpdateSourceArgs": "{{$FullBaseDir}}dotnet", "SkipOnFailure": false }, - { "UpdateStageName": ".NET SDK Download", "UpdateSourcePlatform": "Linux", "UpdateSourceArch": "x86_64", "UpdateSource": "Executable", "UpdateSourceData": "/bin/bash", "UpdateSourceArgs": "-c \"DotnetVersion=\\\"{{DotnetSDKVersion}}\\\"; cd \\\"{{$FullBaseDir}}\\\" && if [[ -x dotnet/dotnet ]]; then InstalledVersion=$(dotnet/dotnet --version | xargs); else InstalledVersion=\\\"\\\"; fi; if [[ -z \\\"$DotnetVersion\\\" ]]; then DotnetVersion=$(wget -qO- https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json | jq -r \\\".[\\\\\\\"latest-sdk\\\\\\\"]\\\"); fi; if [[ ! \\\"$DotnetVersion\\\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+$ ]]; then echo \\\"Invalid .NET SDK version format specified\\\" && exit 1; elif [[ \\\"$InstalledVersion\\\" == \\\"$DotnetVersion\\\" ]]; then echo \\\".NET SDK v$DotnetVersion already installed. Skipping\\\" && exit 0; else rm -f dotnet.tar.gz; wget -qO dotnet.tar.gz https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-linux-x64.tar.gz || { echo \\\".NET SDK download failed\\\"; exit 1; }; rm -rf dotnet/* && tar -xzf dotnet.tar.gz -C dotnet && rm -f dotnet.tar.gz && echo \\\".NET SDK v$DotnetVersion downloaded\\\"; fi\"", "SkipOnFailure": false }, - { "UpdateStageName": ".NET SDK Download", "UpdateSourcePlatform": "Windows", "UpdateSource": "Executable", "UpdateSourceData": "powershell.exe", "UpdateSourceArgs": "-NoProfile -Command \"$ProgressPreference='SilentlyContinue'; [Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $DotnetVersion='{{DotnetSDKVersion}}'; Set-Location '{{$FullBaseDir}}'; if (Test-Path 'dotnet/dotnet.exe') { $InstalledVersion=(& dotnet/dotnet.exe --version).Trim() } else { $InstalledVersion='' }; if ([string]::IsNullOrWhiteSpace($DotnetVersion)) { $DotnetVersion=(Invoke-RestMethod -UseBasicParsing 'https://builds.dotnet.microsoft.com/dotnet/release-metadata/{{DotnetRelease}}/releases.json').'latest-sdk' }; if ($DotnetVersion -notmatch '^\\d+\\.\\d+\\.\\d+$') { throw 'Invalid .NET SDK version format specified' }; if ($InstalledVersion -eq $DotnetVersion) { Write-Output \\\".NET SDK v$DotnetVersion already installed. Skipping\\\"; exit 0 }; Invoke-WebRequest -UseBasicParsing -Uri \\\"https://builds.dotnet.microsoft.com/dotnet/Sdk/$DotnetVersion/dotnet-sdk-$DotnetVersion-win-x64.zip\\\" -OutFile dotnet.zip -ErrorAction Stop; Remove-Item 'dotnet/*' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive dotnet.zip dotnet -Force; Remove-Item dotnet.zip -Force; Write-Output \\\".NET SDK v$DotnetVersion downloaded\\\"\"", "SkipOnFailure": false }, - { "UpdateStageName": "Stratum Download", "UpdateSourcePlatform": "Windows", "UpdateSource": "Executable", "UpdateSourceData": "powershell.exe", "UpdateSourceArgs": "-NoProfile -Command \"$ErrorActionPreference='Stop'; $ProgressPreference='SilentlyContinue'; $game='{{ServerVersion}}'.Trim(); if ($game -notmatch '^\\d+\\.\\d+\\.\\d+(-rc\\.\\d+|-pre\\.\\d+)?$') { throw 'Invalid Vintage Story version' }; $requested='{{StratumVersion}}'.Trim(); if ($requested -and -not $requested.StartsWith('v')) { $requested='v'+$requested }; $releases=Invoke-RestMethod -UseBasicParsing 'https://api.github.com/repos/StratumServer/Stratum/releases?per_page=100'; if ($requested) { if ($requested -notmatch ('^v'+[regex]::Escape($game)+'-stratum\\.[0-9]+(?:\\.[0-9]+)*(?:-[0-9A-Za-z.-]+)?$')) { throw 'The requested Stratum tag does not match the configured Vintage Story version' }; $selected=$releases | Where-Object { $_.tag_name -eq $requested -and -not $_.draft } | Select-Object -First 1 } else { $pattern='^v'+[regex]::Escape($game)+'-stratum\\.([0-9]+(?:\\.[0-9]+)*)\\z'; $selected=$releases | Where-Object { -not $_.draft -and -not $_.prerelease -and $_.tag_name -match $pattern } | Sort-Object { [datetimeoffset]$_.published_at } -Descending | Select-Object -First 1 }; if (-not $selected) { throw \\\"No stable Stratum release was found for Vintage Story $game\\\" }; $version=$selected.tag_name.Substring(1); $assetName=\\\"stratum-$version-win-x64.zip\\\"; $asset=$selected.assets | Where-Object { $_.name -eq $assetName } | Select-Object -First 1; if (-not $asset -or $asset.browser_download_url -notmatch '^https://') { throw \\\"Release asset $assetName was not found\\\" }; Invoke-WebRequest -UseBasicParsing -Uri $asset.browser_download_url -OutFile '{{$FullBaseDir}}stratum.zip'; Remove-Item '{{$FullBaseDir}}stratum-temp' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive '{{$FullBaseDir}}stratum.zip' '{{$FullBaseDir}}stratum-temp' -Force; if (-not (Test-Path '{{$FullBaseDir}}stratum-temp/StratumServer.exe')) { throw 'StratumServer.exe was not found in the release' }; Copy-Item '{{$FullBaseDir}}stratum-temp/*' '{{$FullBaseDir}}server' -Recurse -Force; [IO.File]::WriteAllText('{{$FullBaseDir}}.stratum-version',$selected.tag_name); Remove-Item '{{$FullBaseDir}}stratum-temp','{{$FullBaseDir}}stratum.zip' -Recurse -Force; Write-Output (\\\"Stratum $($selected.tag_name) installed for Vintage Story $game\\\")\"", "SkipOnFailure": false }, - { "UpdateStageName": "Stratum Download", "UpdateSourcePlatform": "Linux", "UpdateSourceArch": "x86_64", "UpdateSource": "Executable", "UpdateSourceData": "/bin/bash", "UpdateSourceArgs": "-c \"set -euo pipefail; game='{{ServerVersion}}'; requested='{{StratumVersion}}'; [[ \\\"$game\\\" =~ ^[0-9]+\\.[0-9]+\\.[0-9]+(-rc\\.[0-9]+|-pre\\.[0-9]+)?$ ]] || { echo 'Invalid Vintage Story version'; exit 1; }; [[ -z \\\"$requested\\\" || \\\"$requested\\\" == v* ]] || requested=\\\"v$requested\\\"; releases='{{$FullBaseDir}}stratum-releases.json'; wget -qO \\\"$releases\\\" 'https://api.github.com/repos/StratumServer/Stratum/releases?per_page=100'; escaped_game=${game//./\\.}; if [[ -n \\\"$requested\\\" ]]; then [[ \\\"$requested\\\" =~ ^v${escaped_game}-stratum\\.[0-9]+(\\.[0-9]+)*(-[0-9A-Za-z.-]+)?$ ]] || { echo 'The requested Stratum tag does not match the configured Vintage Story version'; exit 1; }; selected=$(jq -r --arg tag \\\"$requested\\\" '.[] | select(.tag_name==$tag and (.draft|not)) | .tag_name' \\\"$releases\\\" | head -1); else selected=$(jq -r '.[] | select((.draft|not) and (.prerelease|not)) | .tag_name' \\\"$releases\\\" | grep -E \\\"^v${escaped_game}-stratum\\\\.[0-9]+(\\\\.[0-9]+)*$\\\" | sort -V | tail -1); fi; [[ -n \\\"$selected\\\" ]] || { echo \\\"No stable Stratum release was found for Vintage Story $game\\\"; exit 1; }; version=${selected#v}; asset=\\\"stratum-$version-linux-x64.zip\\\"; url=$(jq -r --arg tag \\\"$selected\\\" --arg asset \\\"$asset\\\" '.[] | select(.tag_name==$tag) | .assets[] | select(.name==$asset) | .browser_download_url' \\\"$releases\\\" | head -1); [[ \\\"$url\\\" == https://* ]] || { echo \\\"Release asset $asset was not found\\\"; exit 1; }; wget -qO '{{$FullBaseDir}}stratum.zip' \\\"$url\\\"; rm -rf '{{$FullBaseDir}}stratum-temp'; mkdir -p '{{$FullBaseDir}}stratum-temp'; unzip -qo '{{$FullBaseDir}}stratum.zip' -d '{{$FullBaseDir}}stratum-temp'; [[ -f '{{$FullBaseDir}}stratum-temp/StratumServer' ]] || { echo 'StratumServer was not found in the release'; exit 1; }; cp -rf '{{$FullBaseDir}}stratum-temp/.' '{{$FullBaseDir}}server/'; chmod +x '{{$FullBaseDir}}server/StratumServer'; printf '%s' \\\"$selected\\\" > '{{$FullBaseDir}}.stratum-version'; rm -rf '{{$FullBaseDir}}stratum-temp' '{{$FullBaseDir}}stratum.zip' \\\"$releases\\\"; echo \\\"Stratum $selected installed for Vintage Story $game\\\"\"", "SkipOnFailure": false }, - { "UpdateStageName": "Nimbus Server Mod Download", "UpdateSourcePlatform": "Windows", "UpdateSource": "Executable", "UpdateSourceData": "powershell.exe", "UpdateSourceArgs": "-NoProfile -Command \"$ErrorActionPreference='Stop'; $ProgressPreference='SilentlyContinue'; $game='{{ServerVersion}}'.Trim(); $requested='{{NimbusVersion}}'.Trim(); if ($requested -and -not $requested.StartsWith('v')) { $requested='v'+$requested }; $releases=Invoke-RestMethod -UseBasicParsing 'https://api.github.com/repos/StratumServer/Nimbus/releases?per_page=100'; if ($requested) { $candidates=@($releases | Where-Object { $_.tag_name -eq $requested -and -not $_.draft }) } else { $candidates=@($releases | Where-Object { -not $_.draft -and -not $_.prerelease }) }; $selected=$null; foreach ($release in $candidates) { try { $readme=Invoke-WebRequest -UseBasicParsing -Uri ('https://raw.githubusercontent.com/StratumServer/Nimbus/'+$release.tag_name+'/README.md') | Select-Object -ExpandProperty Content } catch { continue }; $match=[regex]::Match($readme,'Built and tested against Vintage Story\\s+([0-9]+\\.[0-9]+\\.[0-9]+(?:-rc\\.[0-9]+|-pre\\.[0-9]+)?)',[Text.RegularExpressions.RegexOptions]::IgnoreCase); if ($match.Success -and $match.Groups[1].Value -eq $game) { $selected=$release; break } }; if (-not $selected) { throw \\\"No Nimbus release declares compatibility with Vintage Story $game\\\" }; $assetName='Nimbus.ServerMod-'+$selected.tag_name+'.zip'; $asset=$selected.assets | Where-Object { $_.name -eq $assetName } | Select-Object -First 1; if (-not $asset -or $asset.browser_download_url -notmatch '^https://') { throw \\\"Release asset $assetName was not found\\\" }; Invoke-WebRequest -UseBasicParsing -Uri $asset.browser_download_url -OutFile '{{$FullBaseDir}}nimbus-mod.zip'; Remove-Item '{{$FullBaseDir}}nimbus-mod-temp' -Recurse -Force -ErrorAction SilentlyContinue; Expand-Archive '{{$FullBaseDir}}nimbus-mod.zip' '{{$FullBaseDir}}nimbus-mod-temp' -Force; if (-not (Test-Path '{{$FullBaseDir}}nimbus-mod-temp/modinfo.json')) { throw 'Nimbus ServerMod modinfo.json was not found in the release' }; Remove-Item '{{$FullBaseDir}}data/Mods/Nimbus.ServerMod' -Recurse -Force -ErrorAction SilentlyContinue; New-Item -ItemType Directory '{{$FullBaseDir}}data/Mods/Nimbus.ServerMod' -Force | Out-Null; Copy-Item '{{$FullBaseDir}}nimbus-mod-temp/*' '{{$FullBaseDir}}data/Mods/Nimbus.ServerMod' -Recurse -Force; [IO.File]::WriteAllText('{{$FullBaseDir}}.nimbus-version',$selected.tag_name); Remove-Item '{{$FullBaseDir}}nimbus-mod-temp','{{$FullBaseDir}}nimbus-mod.zip' -Recurse -Force; Write-Output (\\\"Nimbus ServerMod $($selected.tag_name) installed for Vintage Story $game\\\")\"", "SkipOnFailure": false }, - { "UpdateStageName": "Nimbus Server Mod Download", "UpdateSourcePlatform": "Linux", "UpdateSourceArch": "x86_64", "UpdateSource": "Executable", "UpdateSourceData": "/bin/bash", "UpdateSourceArgs": "-c \"set -euo pipefail; game='{{ServerVersion}}'; requested='{{NimbusVersion}}'; [[ -z \\\"$requested\\\" || \\\"$requested\\\" == v* ]] || requested=\\\"v$requested\\\"; releases='{{$FullBaseDir}}nimbus-releases.json'; wget -qO \\\"$releases\\\" 'https://api.github.com/repos/StratumServer/Nimbus/releases?per_page=100'; if [[ -n \\\"$requested\\\" ]]; then tags=\\\"$requested\\\"; else tags=$(jq -r '.[] | select((.draft|not) and (.prerelease|not)) | .tag_name' \\\"$releases\\\"); fi; selected=''; while IFS= read -r tag; do [[ -n \\\"$tag\\\" ]] || continue; readme=$(wget -qO- \\\"https://raw.githubusercontent.com/StratumServer/Nimbus/$tag/README.md\\\" || true); compatible=$(printf '%s' \\\"$readme\\\" | grep -Eio 'Built and tested against Vintage Story[[:space:]]+[0-9]+\\.[0-9]+\\.[0-9]+(-rc\\.[0-9]+|-pre\\.[0-9]+)?' | head -1 | awk '{print $7}'); if [[ \\\"$compatible\\\" == \\\"$game\\\" ]]; then selected=\\\"$tag\\\"; break; fi; done <<< \\\"$tags\\\"; [[ -n \\\"$selected\\\" ]] || { echo \\\"No Nimbus release declares compatibility with Vintage Story $game\\\"; exit 1; }; asset=\\\"Nimbus.ServerMod-$selected.zip\\\"; url=$(jq -r --arg tag \\\"$selected\\\" --arg asset \\\"$asset\\\" '.[] | select(.tag_name==$tag) | .assets[] | select(.name==$asset) | .browser_download_url' \\\"$releases\\\" | head -1); [[ \\\"$url\\\" == https://* ]] || { echo \\\"Release asset $asset was not found\\\"; exit 1; }; wget -qO '{{$FullBaseDir}}nimbus-mod.zip' \\\"$url\\\"; rm -rf '{{$FullBaseDir}}nimbus-mod-temp'; mkdir -p '{{$FullBaseDir}}nimbus-mod-temp'; unzip -qo '{{$FullBaseDir}}nimbus-mod.zip' -d '{{$FullBaseDir}}nimbus-mod-temp'; [[ -f '{{$FullBaseDir}}nimbus-mod-temp/modinfo.json' ]] || { echo 'Nimbus ServerMod modinfo.json was not found in the release'; exit 1; }; rm -rf '{{$FullBaseDir}}data/Mods/Nimbus.ServerMod'; mkdir -p '{{$FullBaseDir}}data/Mods/Nimbus.ServerMod'; cp -rf '{{$FullBaseDir}}nimbus-mod-temp/.' '{{$FullBaseDir}}data/Mods/Nimbus.ServerMod/'; printf '%s' \\\"$selected\\\" > '{{$FullBaseDir}}.nimbus-version'; rm -rf '{{$FullBaseDir}}nimbus-mod-temp' '{{$FullBaseDir}}nimbus-mod.zip' \\\"$releases\\\"; echo \\\"Nimbus ServerMod $selected installed for Vintage Story $game\\\"\"", "SkipOnFailure": false }, - { "UpdateStageName": "Start Server", "UpdateSourcePlatform": "All", "UpdateSource": "StartApplication", "SkipOnFailure": false }, - { "UpdateStageName": "Wait For Server Start", "UpdateSourcePlatform": "All", "UpdateSource": "WaitForStartupComplete", "SkipOnFailure": false }, - { "UpdateStageName": "Stop Server", "UpdateSourcePlatform": "All", "UpdateSource": "ShutdownApplication", "SkipOnFailure": false } -] From 47625ab97348e16850cbd41689f09e608e56037a Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Thu, 13 Aug 2026 11:22:21 -0500 Subject: [PATCH 39/50] Delete stratum-nimbusmetaconfig.json --- stratum-nimbusmetaconfig.json | 27 --------------------------- 1 file changed, 27 deletions(-) delete mode 100644 stratum-nimbusmetaconfig.json diff --git a/stratum-nimbusmetaconfig.json b/stratum-nimbusmetaconfig.json deleted file mode 100644 index 576fdc6f7..000000000 --- a/stratum-nimbusmetaconfig.json +++ /dev/null @@ -1,27 +0,0 @@ -[ - { - "ConfigFile": "data/serverconfig.json", - "AutoMap": true, - "ConfigType": "json" - }, - { - "ConfigFile": "data/ModConfig/nimbus-server.json", - "AutoMap": true, - "ConfigType": "json" - }, - { - "ConfigFile": "data/ModConfig/stratum.json", - "AutoMap": true, - "ConfigType": "json" - }, - { - "ConfigFile": "data/ModConfig/stratum-commands.json", - "AutoMap": true, - "ConfigType": "json" - }, - { - "ConfigFile": "data/ModConfig/stratum-performance.json", - "AutoMap": true, - "ConfigType": "json" - } -] From 58e0c03322432bccfa7b7809949ce9036e841e03 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Thu, 13 Aug 2026 12:56:19 -0500 Subject: [PATCH 40/50] Delete vintage-story-stratumstart.json --- vintage-story-stratumstart.json | 1 - 1 file changed, 1 deletion(-) delete mode 100644 vintage-story-stratumstart.json diff --git a/vintage-story-stratumstart.json b/vintage-story-stratumstart.json deleted file mode 100644 index fe51488c7..000000000 --- a/vintage-story-stratumstart.json +++ /dev/null @@ -1 +0,0 @@ -[] From 53e03da17e1cfb1582e15bf5fcd7b5ecca4881b2 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Sat, 15 Aug 2026 19:55:42 -0500 Subject: [PATCH 41/50] Delete renown.kvp --- renown.kvp | 117 ----------------------------------------------------- 1 file changed, 117 deletions(-) delete mode 100644 renown.kvp diff --git a/renown.kvp b/renown.kvp deleted file mode 100644 index 9ec34646f..000000000 --- a/renown.kvp +++ /dev/null @@ -1,117 +0,0 @@ -Meta.DisplayName=Renown -Meta.Description=Renown Dedicated Server -Meta.OS=Windows, Linux -Meta.AarchSupport=Unknown -Meta.Arch=x86_64 -Meta.Author=Greelan, TheCatDied -Meta.URL=https://playrenown.com/ -Meta.DisplayImageSource=steam:1488310 -Meta.EndpointURIFormat=steam://connect/{ip}:{GenericModule.App.Ports.$QueryPort} -Meta.ConfigManifest=renownconfig.json -Meta.MetaConfigManifest=renownmetaconfig.json -Meta.ConfigRoot=renown.kvp -Meta.MinAMPVersion=2.6.2.8 -Meta.SpecificDockerImage=cubecoders/ampbase:debian -Meta.DockerRequired=False -Meta.DockerBaseReadOnly=False -Meta.ContainerPolicy=Supported -Meta.ContainerPolicyReason= -Meta.ExtraSetupStepsURI= -Meta.Prerequisites=[] -Meta.ExtraContainerPackages=[] -Meta.ConfigReleaseState=NotSpecified -Meta.NoCommercialUsage=False -Meta.ConfigVersion=2 -Meta.ReleaseNotes= -Meta.BreakingReleaseNotes= -Meta.AppConfigId=3a94e6c8-e0f9-4008-afc8-903c7e372bad -Meta.ImportableExtensions=[".ini"] -Meta.AppIsMultiIPAware=False -App.DisplayName=Renown -App.RootDir=./renown/ -App.BaseDirectory=./renown/1512690/ -App.SteamWorkshopDownloadLocation= -App.ExecutableWin=1512690\Renown_Combat\Binaries\Win64\Renown_CombatServer-Win64-Shipping.exe -App.ExecutableLinux=1512690/Renown_Combat/Binaries/Linux/Renown_CombatServer-Linux-Shipping -App.WorkingDir=1512690 -App.LinuxCommandLineArgs= -App.WindowsCommandLineArgs=-stdout -FullStdOutLogOutput -App.CommandLineArgs=Renown_Combat -Port={{$GamePort}} -QueryPort={{$QueryPort}} -BeaconPort={{$BeaconPort}} -RCONPort={{$RCONPort}} -RCONPassword="{{$RemoteAdminPassword}}" {{$FormattedArgs}} {{$PlatformArgs}} -ini:Engine:[EpicOnlineServices]:DedicatedServerClientId=xyza78917DzEE5Ey0isciVt66QDm5IzM -ini:Engine:[EpicOnlineServices]:DedicatedServerClientSecret=m/mrnywFCdeA1mW3ZSvv3qcVlQlfwi1a+7Z63Q44EGU -App.UseLinuxIOREDIR=False -App.AppSettings={} -App.EnvironmentVariables={"LD_LIBRARY_PATH":"{{$FullBaseDir}}linux64:%LD_LIBRARY_PATH%","SteamAppId":"1488310"} -App.CommandLineParameterFormat=-{0}={1} -App.CommandLineParameterDelimiter= -App.ExitMethod=String -App.ExitMethodWindows=None -App.ExitTimeout=90 -App.ExitString=DoExit 1 -App.ExitFile=app_exit.lck -App.HasWriteableConsole=True -App.HasReadableConsole=True -App.UDPLogger=False -App.SupportsLiveSettingsChanges=False -App.LiveSettingChangeCommandFormat=set {0} "{1}" -App.ForceIPBinding=False -App.SupportsIPv6=False -App.ApplicationIPBinding=0.0.0.0 -App.Ports=@IncludeJson[renownports.json] -App.AdminPortRef=RCONPort -App.PrimaryApplicationPortRef=GamePort -App.UniversalSleepApplicationUDPPortRef=GamePort -App.UniversalSleepSteamQueryPortRef=QueryPort -App.MaxUsers=40 -App.UseRandomAdminPassword=True -App.PersistRandomPassword=True -App.RemoteAdminPassword= -App.AdminMethod=SourceRCON -App.IgnoreSTDOUTAfterRCON=False -App.AdminLoginTransform=None -App.StripANSIControlCodes=True -App.LoginTransformPrefix= -App.RCONConnectDelaySeconds=15 -App.RCONConnectRetrySeconds=15 -App.RCONHeartbeatMinutes=29 -App.RCONHeartbeatCommand=getchat -App.RCONSelectIPMethod=Default -App.TelnetLoginFormat={0} -App.TelnetNewLineType=Default -App.TailLogFilePath=server.log -App.UpdateSources=@IncludeJson[renownupdates.json] -App.PreStartStages=[] -App.UserActions=[] -App.ForceUpdate=False -App.ForceUpdateReason= -App.Compatibility=None -App.SteamUpdateAnonymousLogin=True -App.SteamForceLoginPrompt=False -App.RapidStartup=False -App.SmartExcludeExemptions=["*.cfg","*.conf","*.config","*.ini","*.json","*.xml","*.properties","*.kvp","*.yml","*.yaml","*.toml","*.lua"] -App.SmartExcludeSupported=True -App.DumpFullChildProcessTree=False -App.MonitorChildProcessName= -App.MonitorDirectChildOnly=False -App.SupportsUniversalSleep=False -App.WakeupMode=Any -App.ApplicationReadyMode=RegexMatch -Console.FilterMatchRegex=Command unknown\. ping Try: help -Console.FilterMatchReplacement= -Console.ThrowawayMessageRegex=^(WARNING|ERROR): Shader.+$ -Console.AppReadyRegex=^\[[\d\.]+-[\d\.:]+\]\[[\d ]+\]LogGameState: Match State Changed from WaitingToStart to InProgress$ -Console.UserJoinRegex=^\[[\d\.]+-[\d\.:]+\]\[[\d ]+\]LogBlueprintUserMessages:.*[\d-]+T[\d\.:]+Z\* (?.+?) has joined the server\. (?\d+?)$ -Console.UserLeaveRegex=^\[[\d\.]+-[\d\.:]+\]\[[\d ]+\]LogBlueprintUserMessages:.*\*Chat\*System \d+:\d+(?:am|pm) .* \d+ (?.+?) has left the server\.- \((?\d+?)\)$ -Console.UserChatRegex=^$ -Console.UpdateAvailableRegex=^\[\d\d:\d\d:\d\d\] \[INFO\] A new server update is available! v[\d\.]+.$ -Console.PreConnectRegex= -Console.ConnectIPRegex= -Console.MetricsRegex= -Console.ServerInfoRegex= -Console.HideFromConsoleRegex= -Console.SuppressLogAtStart=False -Console.UserActions={} -Limits.SleepMode=True -Limits.SleepOnStart=False -Limits.SleepDelayMinutes=5 -Limits.DozeDelay=2 -Limits.AutoRetryCount=2 -Limits.SleepStartThresholdSeconds=25 From c498115593da73abaf7173ee23c4c2ecefe4d4b7 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Sat, 15 Aug 2026 19:56:01 -0500 Subject: [PATCH 42/50] Delete renownconfig.json --- renownconfig.json | 1161 --------------------------------------------- 1 file changed, 1161 deletions(-) delete mode 100644 renownconfig.json diff --git a/renownconfig.json b/renownconfig.json deleted file mode 100644 index 4b74c2b72..000000000 --- a/renownconfig.json +++ /dev/null @@ -1,1161 +0,0 @@ -[ - { - "DisplayName": "Enable RCON", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "", - "Keywords": "", - "FieldName": "EnableRCON", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.EnableRCON", - "Hidden": true, - "DefaultValue": "True", - "ExcludeFromImport": true, - "EnumValues": {} - }, - { - "DisplayName": "RCON Password", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "", - "Keywords": "", - "FieldName": "$RemoteAdminPassword", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONPassword", - "Hidden": true, - "ExcludeFromImport": true, - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "RCON Port", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "", - "Keywords": "", - "FieldName": "$RCONPort", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONPort", - "Hidden": true, - "ExcludeFromImport": true, - "EnumValues": {} - }, - { - "DisplayName": "Server Name", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the name of the server that is displayed in the server browser", - "Keywords": "server,name,ServerName", - "FieldName": "ServerName", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.ServerName", - "DefaultValue": "AMP Powered Renown Server", - "Placeholder": "AMP Powered Renown Server", - "EnumValues": {} - }, - { - "DisplayName": "Server Region", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the region tag for the server as shown in the server browser. The official tags appear in the dropdown. If 'Custom' is selected, Custom Server Region must also be set", - "Keywords": "region", - "FieldName": "Region", - "InputType": "enum", - "ParamFieldName": "Region", - "DefaultValue": "", - "EnumValues": { - "": "--None--", - "US East": "US East", - "US West": "US West", - "US Central": "US Central", - "Europe": "Europe", - "South America": "South America", - "Asia": "Asia", - "Oceania": "Oceania", - "{{CustomRegion}}": "--Custom--" - } - }, - { - "DisplayName": "Custom Server Region", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets a custom region tag for the server, if 'Custom' is selected under Server Region", - "Keywords": "custom,region", - "FieldName": "CustomRegion", - "InputType": "text", - "ParamFieldName": "CustomRegion", - "DefaultValue": "", - "Placeholder": "Modded", - "EnumValues": {} - }, - { - "DisplayName": "Make Server Private", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "If set, the server will not be listed in the server browser and can only be joined via direct connect", - "Keywords": "private,session,PrivateSession", - "FieldName": "PrivateSession", - "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.PrivateSession", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Server MOTD", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the message of the day (MOTD) shown to players when they join", - "Keywords": "motd,message,day", - "FieldName": "MOTD", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MOTD", - "DefaultValue": "Welcome to my server!", - "EnumValues": {} - }, - { - "DisplayName": "Server Password", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the password required to join the server. Empty = no password", - "Keywords": "server,password,ServerPassword", - "FieldName": "ServerPassword", - "InputType": "Password", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.ServerPassword", - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Admin Password", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the password for server admins in-game", - "Keywords": "admin,password,AdminPassword", - "FieldName": "AdminPassword", - "InputType": "Password", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.AdminPassword", - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Player Limit", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the maximum number of players allowed on the server at one time", - "Keywords": "max,players,MaxPlayers", - "FieldName": "$MaxUsers", - "InputType": "number", - "MinValue": "1", - "MaxValue": "100", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxPlayers", - "DefaultValue": "40", - "Placeholder": "40", - "Suffix": "players", - "EnumValues": {} - }, - { - "DisplayName": "Player Limit", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "", - "Keywords": "", - "FieldName": "$MaxUsers", - "InputType": "number", - "ParamFieldName": "/Script/Engine.GameSession.MaxPlayers", - "Hidden": true, - "EnumValues": {} - }, - { - "DisplayName": "Map Rotation", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Map rotations can be set in Game.ini. Format: MapRotation=RSurv-AlgaraIsle_p. One map entry per line", - "Keywords": "map,rotation,MapRotation", - "FieldName": "MapRotation", - "InputType": "hidden", - "ParamFieldName": "MapRotation", - "DefaultValue": "RSurv-AlgaraIsle_p", - "EnumValues": {} - }, - { - "DisplayName": "Game Save Name", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the name of the game save", - "Keywords": "game,save,name,GameSaveName", - "FieldName": "GameSaveName", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.GameSaveName", - "DefaultValue": "Save 1", - "Placeholder": "Save 1", - "Required": true, - "EnumValues": {} - }, - { - "DisplayName": "Maximum Ping", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the maximum ping allowed for players to join the server. 0 = no limit", - "Keywords": "max,ping,MaxPing", - "FieldName": "MaxPing", - "InputType": "number", - "MinValue": "0", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxPing", - "DefaultValue": "195", - "Placeholder": "195", - "EnumValues": {} - }, - { - "DisplayName": "RCON Chat Messages Limit", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Sets the limit for RCON chat messages", - "Keywords": "rcon,chat,messages,limit", - "FieldName": "RCONChatMessagesLimit", - "InputType": "number", - "MinValue": "0", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONChatMessagesLimit", - "DefaultValue": "50", - "Placeholder": "50", - "EnumValues": {} - }, - { - "DisplayName": "Network Maximum Tick Rate (SteamSockets)", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:lan:3", - "Description": "Sets the maximum tick rate for the server's SteamSockets network driver", - "Keywords": "net,server,tick,rate,NetServerMaxTickRate", - "FieldName": "NetServerMaxTickRate", - "InputType": "number", - "MinValue": "1", - "ParamFieldName": "/Script/SteamSockets.SteamSocketsNetDriver.NetServerMaxTickRate", - "DefaultValue": "30", - "Placeholder": "30", - "EnumValues": {} - }, - { - "DisplayName": "Resource Gain Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Sets the multiplier for resource gain, which determines how much players gather from resources", - "Keywords": "resource,gain,multiplier,ResourceGainMultiplier", - "FieldName": "ResourceGainMultiplier", - "InputType": "number", - "MinValue": "0", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.ResourceGainMultiplier", - "DefaultValue": "1", - "Placeholder": "1", - "EnumValues": {} - }, - { - "DisplayName": "Gold Coin Gain Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Sets the multiplier for gold coin gain, which determines how much gold players earn", - "Keywords": "gold,coin,gain,multiplier,GoldCoinGainMultiplier", - "FieldName": "GoldCoinGainMultiplier", - "InputType": "number", - "MinValue": "0", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GoldCoinGainMultiplier", - "DefaultValue": "1", - "Placeholder": "1", - "EnumValues": {} - }, - { - "DisplayName": "Global Crafting Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Sets the multiplier for crafting speed globally", - "Keywords": "crafting,multiplier,global,CraftingSpeedMultiplier", - "FieldName": "GlobalCraftingMultiplier", - "InputType": "number", - "MinValue": "0", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalCraftingMultiplier", - "DefaultValue": "1", - "Placeholder": "1", - "EnumValues": {} - }, - { - "DisplayName": "Global Smelting Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Sets the multiplier for smelting speed globally", - "Keywords": "smelting,multiplier,global,GlobalSmeltingMultiplier", - "FieldName": "GlobalSmeltingMultiplier", - "InputType": "number", - "MinValue": "0", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalSmeltingMultiplier", - "DefaultValue": "1", - "Placeholder": "1", - "EnumValues": {} - }, - { - "DisplayName": "Enable First Person Only", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "If set, the server will enforce first-person-only gameplay", - "Keywords": "first,person,only,Server.FirstPersonOnly", - "FieldName": "Server.FirstPersonOnly", - "InputType": "checkbox", - "ParamFieldName": "SystemSettings.Server.FirstPersonOnly", - "DefaultValue": "0", - "EnumValues": { - "False": "0", - "True": "1" - } - }, - { - "DisplayName": "RCON Server Max Uptime", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Server uptime limit used by the RCON uptime/restart handling, in seconds", - "Keywords": "RCON,uptime,reboot", - "FieldName": "RCON_ServerMaxUptime", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCON_ServerMaxUptime", - "DefaultValue": "1800", - "Suffix": "seconds", - "EnumValues": {} - }, - { - "DisplayName": "Max Server Uptime", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Server uptime limit before the server restarts itself, in seconds. Overlaps with Auto Reboot Interval and RCON Server Max Uptime — set only one", - "Keywords": "max,uptime,restart", - "FieldName": "MaxServerUptime", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxServerUptime", - "DefaultValue": "28800", - "Suffix": "seconds", - "EnumValues": {} - }, - { - "DisplayName": "Public Listing", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "List this server publicly in the in-game server browser", - "Keywords": "public,listing", - "FieldName": "Public", - "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.Public", - "DefaultValue": "True", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "LAN Mode", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Run the server in LAN mode instead of listing it over the internet", - "Keywords": "LAN,bLAN", - "FieldName": "bLAN", - "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.bLAN", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Anti-Cheat Enabled", - "Category": "Renown:stadia_controller", - "Subcategory": "Security:security:4", - "Description": "Enable Renown's built-in anti-cheat", - "Keywords": "anticheat,bAntiCheat", - "FieldName": "bAntiCheat", - "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.bAntiCheat", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Game Description", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Description text shown alongside the server in the browser", - "Keywords": "description,GameDescription", - "FieldName": "GameDescription", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.GameDescription", - "DefaultValue": "Renown", - "EnumValues": {} - }, - { - "DisplayName": "Admin Whitelist", - "Category": "Renown:stadia_controller", - "Subcategory": "Security:security:4", - "Description": "Steam IDs granted persistent in-game admin access, in addition to the admin password", - "Keywords": "admin,whitelist", - "FieldName": "AdminWhitelist", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.AdminWhitelist", - "DefaultValue": "", - "Placeholder": "7656119...,7656119...", - "EnumValues": {} - }, - { - "DisplayName": "Use First Map", - "Category": "Renown:stadia_controller", - "Subcategory": "Server:dns:1", - "Description": "Load the first entry of the map rotation when the server starts", - "Keywords": "UseFirstMap", - "FieldName": "UseFirstMap", - "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.UseFirstMap", - "DefaultValue": "True", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Ban List", - "Category": "Renown:stadia_controller", - "Subcategory": "Security:security:4", - "Description": "Server ban list entry in Game.ini", - "Keywords": "ban,BanList", - "FieldName": "BanList", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.BanList", - "DefaultValue": "", - "EnumValues": {} - }, - { - "DisplayName": "Debug RCON Logs", - "Category": "Renown:stadia_controller", - "Subcategory": "Security:security:4", - "Description": "Write verbose RCON diagnostics to the server log", - "Keywords": "debug,DebugRCON", - "FieldName": "DebugRCON", - "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.DebugRCON", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Match Time Limit", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Round time limit for timed game modes. 0 disables the limit", - "Keywords": "TimeLimit", - "FieldName": "TimeLimit", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.TimeLimit", - "DefaultValue": "0", - "Placeholder": "0", - "Suffix": "seconds", - "EnumValues": {} - }, - { - "DisplayName": "Auto Balance Teams", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Automatically balance sides where the game mode supports it", - "Keywords": "AutoBalance", - "FieldName": "AutoBalance", - "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.AutoBalance", - "DefaultValue": "0", - "EnumValues": { - "False": "0", - "True": "1" - } - }, - { - "DisplayName": "Maintenance Rate", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Maintenance rate as an (X=,Y=) tuple, e.g. (X=0.500000,Y=1.000000)", - "Keywords": "MaintenanceRate", - "FieldName": "MaintenanceRate", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.MaintenanceRate", - "DefaultValue": "(X=0.500000,Y=1.000000)", - "Placeholder": "(X=0.500000,Y=1.000000)", - "EnumValues": {} - }, - { - "DisplayName": "Global Resource Respawn Time Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Multiplier for resource respawn timers", - "Keywords": "GlobalResourceRespawnTimeMultiplier", - "FieldName": "GlobalResourceRespawnTimeMultiplier", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalResourceRespawnTimeMultiplier", - "DefaultValue": "1", - "Placeholder": "1", - "EnumValues": {} - }, - { - "DisplayName": "Global Maintenance Cost Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Multiplier for structure upkeep costs", - "Keywords": "GlobalMaintenanceCostMultiplier", - "FieldName": "GlobalMaintenanceCostMultiplier", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalMaintenanceCostMultiplier", - "DefaultValue": "1", - "Placeholder": "1", - "EnumValues": {} - }, - { - "DisplayName": "Global Decay Damage Multiplier", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Multiplier for decay damage to structures", - "Keywords": "GlobalDecayDamageMultiplier", - "FieldName": "GlobalDecayDamageMultiplier", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalDecayDamageMultiplier", - "DefaultValue": "1", - "Placeholder": "1", - "EnumValues": {} - }, - { - "DisplayName": "Kick Idle Players", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Automatically kick idle players", - "Keywords": "KickIdlePlayers", - "FieldName": "KickIdlePlayers", - "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.KickIdlePlayers", - "DefaultValue": "True", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Idle Timeout", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Time before idle player is kicked", - "Keywords": "IdleTimeOutTime", - "FieldName": "IdleTimeOutTime", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.IdleTimeOutTime", - "DefaultValue": "300", - "Placeholder": "300", - "Suffix": "seconds", - "EnumValues": {} - }, - { - "DisplayName": "Max Players Per Banner", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Limit on how many players may join a single banner. 0 leaves it unlimited", - "Keywords": "MaxPlayersPerBanner", - "FieldName": "MaxPlayersPerBanner", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.MaxPlayersPerBanner", - "DefaultValue": "0", - "Placeholder": "0", - "EnumValues": {} - }, - { - "DisplayName": "Auto Reboot Interval", - "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:autorenew:5", - "Description": "Automatically reboot the server on this interval, in minutes", - "Keywords": "ServerRebootTimeMinutes", - "FieldName": "ServerRebootTimeMinutes", - "InputType": "number", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.ServerRebootTimeMinutes", - "DefaultValue": "120", - "Placeholder": "120", - "Suffix": "minutes", - "EnumValues": {} - }, - { - "DisplayName": "Raid Window Times", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Raid window as an (X=,Y=) tuple of 24-hour clock hours, e.g. (X=16,Y=0)", - "Keywords": "raid,window,times,RaidWindowTimes", - "FieldName": "RaidWindowTimes", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.RaidWindowTimes", - "DefaultValue": "(X=16,Y=0)", - "Placeholder": "(X=16,Y=0)", - "EnumValues": {} - }, - { - "DisplayName": "Offline Raid Protection", - "Category": "Renown:stadia_controller", - "Subcategory": "Gameplay:joystick:2", - "Description": "Damage multiplier applied to a base while its owner is offline. Lower values mean less damage taken", - "Keywords": "offline,raid,protection", - "FieldName": "OfflineRaidProtectionMultiplier", - "InputType": "number", - "MinValue": "0", - "MaxValue": "1", - "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.OfflineRaidProtectionMultiplier", - "DefaultValue": "0.99", - "Placeholder": "0.99", - "EnumValues": {} - }, - { - "DisplayName": "Enable Server Queue", - "Category": "Renown:stadia_controller", - "Subcategory": "Queue:groups:6", - "Description": "Enable join queue when server is full or starting", - "Keywords": "queue,bEnableServerQueue", - "FieldName": "bEnableServerQueue", - "InputType": "checkbox", - "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.bEnableServerQueue", - "DefaultValue": "True", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Run On LAN (Queue)", - "Category": "Renown:stadia_controller", - "Subcategory": "Queue:groups:6", - "Description": "Run queue in LAN mode", - "Keywords": "bRunOnLan", - "FieldName": "bRunOnLan", - "InputType": "checkbox", - "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.bRunOnLan", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Client & Server Same Machine", - "Category": "Renown:stadia_controller", - "Subcategory": "Queue:groups:6", - "Description": "Optimizations if client and server run on same machine", - "Keywords": "bIsServerClientRunningOnSameMachine", - "FieldName": "bIsServerClientRunningOnSameMachine", - "InputType": "checkbox", - "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.bIsServerClientRunningOnSameMachine", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Reconnection Grace", - "Category": "Renown:stadia_controller", - "Subcategory": "Queue:groups:6", - "Description": "How long a disconnecting player can rejoin without losing spot", - "Keywords": "ReconnectionGracePeriodSeconds", - "FieldName": "ReconnectionGracePeriodSeconds", - "InputType": "number", - "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.ReconnectionGracePeriodSeconds", - "DefaultValue": "90", - "Suffix": "seconds", - "EnumValues": {} - }, - { - "DisplayName": "Max Join Duration", - "Category": "Renown:stadia_controller", - "Subcategory": "Queue:groups:6", - "Description": "Time window to complete a join from queue", - "Keywords": "ServerQueueMaxJoinDuration", - "FieldName": "ServerQueueMaxJoinDuration", - "InputType": "number", - "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.ServerQueueMaxJoinDuration", - "DefaultValue": "300", - "Suffix": "seconds", - "EnumValues": {} - }, - { - "DisplayName": "Purge Pending Connections", - "Category": "Renown:stadia_controller", - "Subcategory": "Queue:groups:6", - "Description": "Purge half-open connections after this time", - "Keywords": "PurgePendingPlayerConnections", - "FieldName": "PurgePendingPlayerConnections", - "InputType": "number", - "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.PurgePendingPlayerConnections", - "DefaultValue": "60", - "Suffix": "seconds", - "EnumValues": {} - }, - { - "DisplayName": "Player Slots To Consume", - "Category": "Renown:stadia_controller", - "Subcategory": "Queue:groups:6", - "Description": "Player slots reserved by the server queue", - "Keywords": "PlayerSlotsToConsume", - "FieldName": "PlayerSlotsToConsume", - "InputType": "number", - "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.PlayerSlotsToConsume", - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Max Client Reconnect Attempts", - "Category": "Renown:stadia_controller", - "Subcategory": "Queue:groups:6", - "Description": "How many reconnect tries are allowed", - "Keywords": "MaxClientReconnectAttempts", - "FieldName": "MaxClientReconnectAttempts", - "InputType": "number", - "ParamFieldName": "/Script/Renown_Combat.RenownDeveloperSettings.MaxClientReconnectAttempts", - "DefaultValue": "0", - "EnumValues": {} - }, - { - "DisplayName": "Default Max Party Size", - "Category": "Renown:stadia_controller", - "Subcategory": "Social:groups:7", - "Description": "Max party size in lobby", - "Keywords": "party,DefaultMaxPartySize", - "FieldName": "DefaultMaxPartySize", - "InputType": "number", - "ParamFieldName": "/Script/Party.Party.DefaultMaxPartySize", - "DefaultValue": "5", - "EnumValues": {} - }, - { - "DisplayName": "Wait For Players Time Remaining", - "Category": "Renown:stadia_controller", - "Subcategory": "Social:groups:7", - "Description": "Time the lobby waits before starting", - "Keywords": "Lobby,WaitForPlayersTimeRemaining", - "FieldName": "WaitForPlayersTimeRemaining", - "InputType": "number", - "ParamFieldName": "/Script/Lobby.LobbyBeaconState.WaitForPlayersTimeRemaining", - "DefaultValue": "20.0", - "Suffix": "seconds", - "EnumValues": {} - }, - { - "DisplayName": "Max Spectators", - "Category": "Renown:stadia_controller", - "Subcategory": "Social:groups:7", - "Description": "Number of spectator slots", - "Keywords": "spectators,MaxSpectators", - "FieldName": "MaxSpectators", - "InputType": "number", - "ParamFieldName": "/Script/Engine.GameSession.MaxSpectators", - "DefaultValue": "2", - "EnumValues": {} - }, - { - "DisplayName": "Requires Push-To-Talk", - "Category": "Renown:stadia_controller", - "Subcategory": "Social:groups:7", - "Description": "Require PTT for in-game voice", - "Keywords": "voice,bRequiresPushToTalk", - "FieldName": "bRequiresPushToTalk", - "InputType": "checkbox", - "ParamFieldName": "/Script/Engine.GameSession.bRequiresPushToTalk", - "DefaultValue": "True", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Total Net Bandwidth", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:lan:3", - "Description": "Total replication bandwidth budget shared across all clients, in bytes/sec", - "Keywords": "bandwidth,TotalNetBandwidth", - "FieldName": "TotalNetBandwidth", - "InputType": "number", - "ParamFieldName": "/Script/Engine.GameNetworkManager.TotalNetBandwidth", - "DefaultValue": "4000000", - "EnumValues": {} - }, - { - "DisplayName": "Max Dynamic Bandwidth", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:lan:3", - "Description": "Upper bound on per-client bandwidth, in bytes/sec", - "Keywords": "bandwidth,MaxDynamicBandwidth", - "FieldName": "MaxDynamicBandwidth", - "InputType": "number", - "ParamFieldName": "/Script/Engine.GameNetworkManager.MaxDynamicBandwidth", - "DefaultValue": "100000", - "EnumValues": {} - }, - { - "DisplayName": "Min Dynamic Bandwidth", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:lan:3", - "Description": "Lower bound on per-client bandwidth, in bytes/sec", - "Keywords": "bandwidth,MinDynamicBandwidth", - "FieldName": "MinDynamicBandwidth", - "InputType": "number", - "ParamFieldName": "/Script/Engine.GameNetworkManager.MinDynamicBandwidth", - "DefaultValue": "40000", - "EnumValues": {} - }, - { - "DisplayName": "Smooth Frame Rate", - "Category": "Renown:stadia_controller", - "Subcategory": "Performance:speed:8", - "Description": "Enable Unreal frame rate smoothing", - "Keywords": "bSmoothFrameRate", - "FieldName": "bSmoothFrameRate", - "InputType": "checkbox", - "ParamFieldName": "/Script/Engine.Engine.bSmoothFrameRate", - "DefaultValue": "True", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "IP Driver: Connection Timeout", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:lan:3", - "Description": "Timeout for network connections", - "Keywords": "IpNetDriver,ConnectionTimeout", - "FieldName": "ConnectionTimeout", - "InputType": "number", - "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.ConnectionTimeout", - "DefaultValue": "60.0", - "Suffix": "seconds", - "EnumValues": {} - }, - { - "DisplayName": "IP Driver: Initial Connect Timeout", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:lan:3", - "Description": "Initial connection timeout", - "Keywords": "IpNetDriver,InitialConnectTimeout", - "FieldName": "InitialConnectTimeout", - "InputType": "number", - "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.InitialConnectTimeout", - "DefaultValue": "60.0", - "Suffix": "seconds", - "EnumValues": {} - }, - { - "DisplayName": "IP Driver: Max Client Rate", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:lan:3", - "Description": "Max client rate", - "Keywords": "IpNetDriver,MaxClientRate", - "FieldName": "MaxClientRate", - "InputType": "number", - "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.MaxClientRate", - "DefaultValue": "100000", - "Suffix": "bytes/sec", - "EnumValues": {} - }, - { - "DisplayName": "IP Driver: Max Internet Client Rate", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:lan:3", - "Description": "Max internet client rate", - "Keywords": "IpNetDriver,MaxInternetClientRate", - "FieldName": "MaxInternetClientRate", - "InputType": "number", - "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.MaxInternetClientRate", - "DefaultValue": "100000", - "Suffix": "bytes/sec", - "EnumValues": {} - }, - { - "DisplayName": "IP Driver: Relevant Timeout", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:lan:3", - "Description": "Relevancy timeout", - "Keywords": "IpNetDriver,RelevantTimeout", - "FieldName": "RelevantTimeout", - "InputType": "number", - "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.RelevantTimeout", - "DefaultValue": "5.0", - "Suffix": "seconds", - "EnumValues": {} - }, - { - "DisplayName": "IP Driver: Spawn Priority Seconds", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:lan:3", - "Description": "Spawn priority seconds", - "Keywords": "IpNetDriver,SpawnPrioritySeconds", - "FieldName": "SpawnPrioritySeconds", - "InputType": "number", - "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.SpawnPrioritySeconds", - "DefaultValue": "1.0", - "Suffix": "seconds", - "EnumValues": {} - }, - { - "DisplayName": "IP Driver: Server Travel Pause", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:lan:3", - "Description": "Pause during seamless travel", - "Keywords": "IpNetDriver,ServerTravelPause", - "FieldName": "ServerTravelPause", - "InputType": "number", - "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.ServerTravelPause", - "DefaultValue": "4.0", - "Suffix": "seconds", - "EnumValues": {} - }, - { - "DisplayName": "IP Driver: Net Server Max Tick Rate", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:lan:3", - "Description": "Tick rate for IpNetDriver", - "Keywords": "IpNetDriver,NetServerMaxTickRate", - "FieldName": "IpNetDriver_NetServerMaxTickRate", - "InputType": "number", - "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.NetServerMaxTickRate", - "DefaultValue": "30", - "EnumValues": {} - }, - { - "DisplayName": "IP Driver: Max Net Tick Rate", - "Category": "Renown:stadia_controller", - "Subcategory": "Networking:lan:3", - "Description": "Overall max network tick rate", - "Keywords": "IpNetDriver,MaxNetTickRate", - "FieldName": "MaxNetTickRate", - "InputType": "number", - "ParamFieldName": "/Script/OnlineSubsystemUtils.IpNetDriver.MaxNetTickRate", - "DefaultValue": "120", - "EnumValues": {} - }, - { - "DisplayName": "DDoS Detection Enabled", - "Category": "Renown:stadia_controller", - "Subcategory": "Security:security:4", - "Description": "Enable UE DDoS detection", - "Keywords": "DDoS,bDDoSDetection", - "FieldName": "bDDoSDetection", - "InputType": "checkbox", - "ParamFieldName": "DDoSDetection.bDDoSDetection", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "DDoS Analytics Enabled", - "Category": "Renown:stadia_controller", - "Subcategory": "Security:security:4", - "Description": "Enable DDoS analytics", - "Keywords": "DDoS,bDDoSAnalytics", - "FieldName": "bDDoSAnalytics", - "InputType": "checkbox", - "ParamFieldName": "DDoSDetection.bDDoSAnalytics", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "DDoS Log Spam Limit", - "Category": "Renown:stadia_controller", - "Subcategory": "Security:security:4", - "Description": "Limit for DDoS log spam", - "Keywords": "DDoS,Log", - "FieldName": "DDoSLogSpamLimit", - "InputType": "number", - "ParamFieldName": "DDoSDetection.DDoSLogSpamLimit", - "DefaultValue": "64", - "EnumValues": {} - }, - { - "DisplayName": "Hitch Time Quota", - "Category": "Renown:stadia_controller", - "Subcategory": "Performance:speed:8", - "Description": "Hitch detection time quota", - "Keywords": "HitchTimeQuotaMS", - "FieldName": "HitchTimeQuotaMS", - "InputType": "number", - "ParamFieldName": "DDoSDetection.HitchTimeQuotaMS", - "DefaultValue": "500", - "Suffix": "milliseconds", - "EnumValues": {} - }, - { - "DisplayName": "Hitch Frame Tolerance", - "Category": "Renown:stadia_controller", - "Subcategory": "Performance:speed:8", - "Description": "Hitch detection frame tolerance", - "Keywords": "HitchFrameTolerance", - "FieldName": "HitchFrameTolerance", - "InputType": "number", - "ParamFieldName": "DDoSDetection.HitchFrameTolerance", - "DefaultValue": "3", - "EnumValues": {} - }, - { - "DisplayName": "Purge Logs After", - "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:autorenew:5", - "Description": "Delete logs older than this many days", - "Keywords": "logs,PurgeLogsDays", - "FieldName": "PurgeLogsDays", - "InputType": "number", - "ParamFieldName": "LogFiles.PurgeLogsDays", - "DefaultValue": "5", - "Suffix": "days", - "EnumValues": {} - }, - { - "DisplayName": "Max Log Files On Disk", - "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:autorenew:5", - "Description": "Limit number of rotated log files", - "Keywords": "logs,MaxLogFilesOnDisk", - "FieldName": "MaxLogFilesOnDisk", - "InputType": "number", - "ParamFieldName": "LogFiles.MaxLogFilesOnDisk", - "DefaultValue": "10", - "EnumValues": {} - }, - { - "DisplayName": "Log Times", - "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:autorenew:5", - "Description": "Include timestamps in logs", - "Keywords": "logs,LogTimes", - "FieldName": "LogTimes", - "InputType": "checkbox", - "ParamFieldName": "LogFiles.LogTimes", - "DefaultValue": "True", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Server Language Culture", - "Category": "Renown:stadia_controller", - "Subcategory": "Localization:language:9", - "Description": "Server locale, e.g. en or es-MX", - "Keywords": "language,culture,Internationalization", - "FieldName": "Culture", - "InputType": "text", - "ParamFieldName": "Internationalization.Culture", - "DefaultValue": "en", - "EnumValues": {} - }, - { - "DisplayName": "EOS Voice Chat Enabled", - "Category": "Renown:stadia_controller", - "Subcategory": "Voice:mic:10", - "Description": "Enable Epic Online Services voice chat", - "Keywords": "voice,EOS,bEnabled", - "FieldName": "EOSVoiceChatEnabled", - "InputType": "checkbox", - "ParamFieldName": "EOSVoiceChat.bEnabled", - "DefaultValue": "True", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Use Official Wipe Schedule", - "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:autorenew:5", - "Description": "Follow the official wipe schedule instead of the interval below", - "Keywords": "wipe,schedule", - "FieldName": "bOfficialWipeSchedule", - "InputType": "checkbox", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.bOfficialWipeSchedule", - "DefaultValue": "False", - "EnumValues": { - "False": "False", - "True": "True" - } - }, - { - "DisplayName": "Wipe Interval", - "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:autorenew:5", - "Description": "How many days between scheduled wipes", - "Keywords": "wipe,interval", - "FieldName": "WipeInterval", - "InputType": "number", - "MinValue": "1", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.WipeInterval", - "DefaultValue": "7", - "Placeholder": "7", - "Suffix": "days", - "EnumValues": {} - }, - { - "DisplayName": "Wipe Start Day Of Week", - "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:autorenew:5", - "Description": "Day of the week the wipe schedule starts from", - "Keywords": "wipe,day", - "FieldName": "WipeStartDayOfWeek", - "InputType": "number", - "MinValue": "0", - "MaxValue": "6", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.WipeStartDayOfWeek", - "DefaultValue": "5", - "Placeholder": "5", - "EnumValues": {} - }, - { - "DisplayName": "Wipe Time", - "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:autorenew:5", - "Description": "Time of day the wipe runs, in 24-hour HH:MM form", - "Keywords": "wipe,time", - "FieldName": "WipeHourMinute", - "InputType": "text", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.WipeHourMinute", - "DefaultValue": "18:00", - "Placeholder": "18:00", - "Suffix": "HH:MM", - "EnumValues": {} - }, - { - "DisplayName": "Wipe Scheduler Check Interval", - "Category": "Renown:stadia_controller", - "Subcategory": "Maintenance:autorenew:5", - "Description": "How often the wipe scheduler checks for a due wipe. Do not set below the default of 300 seconds or wipe scheduling can misfire", - "Keywords": "wipe,scheduler", - "FieldName": "WipeSchedulerInterval", - "InputType": "number", - "MinValue": "300", - "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.WipeSchedulerInterval", - "DefaultValue": "300", - "Placeholder": "300", - "Suffix": "seconds", - "EnumValues": {} - }, - { - "DisplayName": "Server Release Version", - "Category": "Updates", - "Subcategory": "Steam Downloads:download", - "Description": "Sets the server release version to install. Update the server after changing this setting", - "Keywords": "server,version,public,beta", - "FieldName": "ServerVersion", - "InputType": "enum", - "ParamFieldName": "ServerVersion", - "DefaultValue": "public", - "EnumValues": { - "public": "Public (default)", - "beta": "Beta" - } - } -] From a337839c9792ebb8555fcc579cc81f5e3ef914a0 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Sat, 15 Aug 2026 19:56:17 -0500 Subject: [PATCH 43/50] Delete renowngame.ini --- renowngame.ini | 74 -------------------------------------------------- 1 file changed, 74 deletions(-) delete mode 100644 renowngame.ini diff --git a/renowngame.ini b/renowngame.ini deleted file mode 100644 index fd2b02444..000000000 --- a/renowngame.ini +++ /dev/null @@ -1,74 +0,0 @@ -[/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C] -EnableRCON=True -RCONPort=25575 -RCONChatMessagesLimit=50 -RCONPassword= -RCON_ServerMaxUptime=1800 -ServerPassword= -ServerName=AMP Powered Renown Server -MaxPlayers=40 -bLAN=False -bAntiCheat=False -GameSaveName=Save 1 -GameDescription=Renown -AdminPassword= -AdminWhitelist= -UseFirstMap=True -Public=True -MapRotation=RSurv-AlgaraIsle_p -BanList= -PrivateSession=False -MaxPing=195 -MOTD=Welcome to my server! -Region= -MaxServerUptime=28800 -DebugRCON=False -bOfficialWipeSchedule=False -WipeInterval=7 -WipeStartDayOfWeek=5 -WipeHourMinute=18:00 -WipeSchedulerInterval=300 - -[/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C] -TimeLimit=0 -AutoBalance=0 -MaintenanceRate=(X=0.500000,Y=1.000000) -ResourceGainMultiplier=1 -GoldCoinGainMultiplier=1 -GlobalCraftingMultiplier=1 -GlobalSmeltingMultiplier=1 -GlobalResourceRespawnTimeMultiplier=1 -GlobalMaintenanceCostMultiplier=1 -GlobalDecayDamageMultiplier=1 -KickIdlePlayers=True -IdleTimeOutTime=300 -MaxPlayersPerBanner=0 -ServerRebootTimeMinutes=120 -RaidWindowTimes=(X=16,Y=0) -OfflineRaidProtectionMultiplier=0.99 - -[/Script/Renown_Combat.RenownDeveloperSettings] -bEnableServerQueue=True -bRunOnLan=False -bIsServerClientRunningOnSameMachine=False -ReconnectionGracePeriodSeconds=90 -ServerQueueMaxJoinDuration=300 -PurgePendingPlayerConnections=60 -PlayerSlotsToConsume=0 -MaxClientReconnectAttempts=0 - -[/Script/Party.Party] -DefaultMaxPartySize=5 - -[/Script/Lobby.LobbyBeaconState] -WaitForPlayersTimeRemaining=20.0 - -[/Script/Engine.GameSession] -MaxPlayers=40 -MaxSpectators=2 -bRequiresPushToTalk=True - -[/Script/Engine.GameNetworkManager] -TotalNetBandwidth=4000000 -MaxDynamicBandwidth=100000 -MinDynamicBandwidth=40000 From 583cbf7a9c5325d36ec30b57c124248e624ca646 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Sat, 15 Aug 2026 19:56:27 -0500 Subject: [PATCH 44/50] Delete renownengine.ini --- renownengine.ini | 55 ------------------------------------------------ 1 file changed, 55 deletions(-) delete mode 100644 renownengine.ini diff --git a/renownengine.ini b/renownengine.ini deleted file mode 100644 index f09c6c5e6..000000000 --- a/renownengine.ini +++ /dev/null @@ -1,55 +0,0 @@ -[/Script/SteamSockets.SteamSocketsNetDriver] -NetServerMaxTickRate=30 - -[SystemSettings] -Server.FirstPersonOnly=0 - -[/Script/Engine.Engine] -bSmoothFrameRate=True - -[/Script/OnlineSubsystemUtils.IpNetDriver] -ConnectionTimeout=60.0 -InitialConnectTimeout=60.0 -MaxClientRate=100000 -MaxInternetClientRate=100000 -RelevantTimeout=5.0 -SpawnPrioritySeconds=1.0 -ServerTravelPause=4.0 -NetServerMaxTickRate=30 -MaxNetTickRate=120 - -[DDoSDetection] -bDDoSDetection=False -bDDoSAnalytics=False -DDoSLogSpamLimit=64 -HitchTimeQuotaMS=500 -HitchFrameTolerance=3 - -[LogFiles] -PurgeLogsDays=5 -MaxLogFilesOnDisk=10 -LogTimes=True - -[Core.Log] -Online=log -OnlineSession=log -OnlineGame=log -SteamCore=log -AssetLog=all off -LogRedpointEOS=all off -LogRedpointEOSIdentity=all off -LogRedpointEOSSocket=all off -LogRedpointEOSSocketLifecycle=all off -LogRedpointEOSSessionListening=all off -LogRedpointEOSNetworkTrace=all off -LogRedpointEOSNetworkAuth=all off -LogRedpointEOSStat=all off -LogRedpointEOSAntiCheat=all off -LogRedpointEOSFriends=all off -LogRedpointEOSFileTransfer=all off -LogRedpointEOSVoiceChat=all off -LogBeacon=log -LogServerQueue=log - -[EOSVoiceChat] -bEnabled=True From 3b0d47c144fa268e435f94226aec141b4953ab62 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Sat, 15 Aug 2026 19:56:37 -0500 Subject: [PATCH 45/50] Delete renownports.json --- renownports.json | 30 ------------------------------ 1 file changed, 30 deletions(-) delete mode 100644 renownports.json diff --git a/renownports.json b/renownports.json deleted file mode 100644 index 697b97f03..000000000 --- a/renownports.json +++ /dev/null @@ -1,30 +0,0 @@ -[ - { - "Protocol": "UDP", - "Port": 7777, - "Ref": "GamePort", - "Name": "Main Game Port", - "Description": "Port used for main game traffic" - }, - { - "Protocol": "UDP", - "Port": 27015, - "Ref": "QueryPort", - "Name": "Query Port", - "Description": "Port used for Steam query traffic" - }, - { - "Protocol": "UDP", - "Port": 9999, - "Ref": "BeaconPort", - "Name": "Beacon Port", - "Description": "Port used for beacon traffic" - }, - { - "Protocol": "TCP", - "Port": 25575, - "Ref": "RCONPort", - "Name": "RCON Port", - "Description": "Port used for RCON traffic" - } -] From f708b50f58a937de93d86ca42c03ca48de829064 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Sat, 15 Aug 2026 19:56:49 -0500 Subject: [PATCH 46/50] Delete renownupdates.json --- renownupdates.json | 88 ---------------------------------------------- 1 file changed, 88 deletions(-) delete mode 100644 renownupdates.json diff --git a/renownupdates.json b/renownupdates.json deleted file mode 100644 index 0b1b980b1..000000000 --- a/renownupdates.json +++ /dev/null @@ -1,88 +0,0 @@ -[ - { - "UpdateStageName": "SteamCMD Download", - "UpdateSourcePlatform": "All", - "UpdateSource": "SteamCMD", - "UpdateSourceData": "1512690", - "UpdateSourceArgs": "1488310", - "UpdateSourceVersion": "{{ServerVersion}}", - "SkipOnFailure": false - }, - { - "UpdateStageName": "SteamCMD Component Download", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "SteamCMD", - "UpdateSourceData": "1007", - "UpdateSourceArgs": "1488310", - "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Binaries/Win64", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Create Config Directory (Linux)", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Create Config Directory (Windows)", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "CreateDirectory", - "UpdateSourceArgs": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", - "SkipOnFailure": false - }, - { - "UpdateStageName": "Game.ini Download (Linux)", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/CubeCoders/AMPTemplates/main/renowngame.ini", - "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", - "UpdateSourceArgs": "Game.ini", - "OverwriteExistingFiles": false - }, - { - "UpdateStageName": "Game.ini Download (Windows)", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/CubeCoders/AMPTemplates/main/renowngame.ini", - "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", - "UpdateSourceArgs": "Game.ini", - "OverwriteExistingFiles": false - }, - { - "UpdateStageName": "Engine.ini Download (Linux)", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/CubeCoders/AMPTemplates/main/renownengine.ini", - "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", - "UpdateSourceArgs": "Engine.ini", - "OverwriteExistingFiles": false - }, - { - "UpdateStageName": "Engine.ini Download (Windows)", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/CubeCoders/AMPTemplates/main/renownengine.ini", - "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", - "UpdateSourceArgs": "Engine.ini", - "OverwriteExistingFiles": false - }, - { - "UpdateStageName": "GameUserSettings.ini Download (Linux)", - "UpdateSourcePlatform": "Linux", - "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/CubeCoders/AMPTemplates/main/renowngameusersettings.ini", - "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", - "UpdateSourceArgs": "GameUserSettings.ini", - "OverwriteExistingFiles": false - }, - { - "UpdateStageName": "GameUserSettings.ini Download (Windows)", - "UpdateSourcePlatform": "Windows", - "UpdateSource": "FetchURL", - "UpdateSourceData": "https://raw.githubusercontent.com/CubeCoders/AMPTemplates/main/renowngameusersettings.ini", - "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", - "UpdateSourceArgs": "GameUserSettings.ini", - "OverwriteExistingFiles": false - } -] From 5b6922dd788fbdb0210154b1bc408c746c774034 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Sat, 15 Aug 2026 19:56:59 -0500 Subject: [PATCH 47/50] Delete renownmetaconfig.json --- renownmetaconfig.json | 38 -------------------------------------- 1 file changed, 38 deletions(-) delete mode 100644 renownmetaconfig.json diff --git a/renownmetaconfig.json b/renownmetaconfig.json deleted file mode 100644 index 3c6ca890d..000000000 --- a/renownmetaconfig.json +++ /dev/null @@ -1,38 +0,0 @@ -[ - { - "ConfigFile": "Renown_Combat/Saved/Config/LinuxServer/Game.ini", - "ConfigType": "ini", - "AutoMap": true, - "Importable": true - }, - { - "ConfigFile": "Renown_Combat/Saved/Config/WindowsServer/Game.ini", - "ConfigType": "ini", - "AutoMap": true, - "Importable": true - }, - { - "ConfigFile": "Renown_Combat/Saved/Config/LinuxServer/Engine.ini", - "ConfigType": "ini", - "AutoMap": true, - "Importable": true - }, - { - "ConfigFile": "Renown_Combat/Saved/Config/WindowsServer/Engine.ini", - "ConfigType": "ini", - "AutoMap": true, - "Importable": true - }, - { - "ConfigFile": "Renown_Combat/Saved/Config/LinuxServer/GameUserSettings.ini", - "ConfigType": "ini", - "AutoMap": true, - "Importable": true - }, - { - "ConfigFile": "Renown_Combat/Saved/Config/WindowsServer/GameUserSettings.ini", - "ConfigType": "ini", - "AutoMap": true, - "Importable": true - } -] From 6980635b0703ec19dc51a6e3019a33f9e3cb0bf5 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Sat, 15 Aug 2026 19:57:09 -0500 Subject: [PATCH 48/50] Delete renowngameusersettings.ini --- renowngameusersettings.ini | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 renowngameusersettings.ini diff --git a/renowngameusersettings.ini b/renowngameusersettings.ini deleted file mode 100644 index e2dd90415..000000000 --- a/renowngameusersettings.ini +++ /dev/null @@ -1,2 +0,0 @@ -[Internationalization] -Culture=en From 1c14287c9f8ea7cfe11e131bbaea604207d346f5 Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Sat, 15 Aug 2026 20:06:45 -0500 Subject: [PATCH 49/50] Add files via upload --- renown.kvp | 117 +++++++++++++++ renownconfig.json | 325 ++++++++++++++++++++++++++++++++++++++++++ renowngame.ini | 24 ++++ renownmetaconfig.json | 14 ++ renownports.json | 30 ++++ renownupdates.json | 52 +++++++ 6 files changed, 562 insertions(+) create mode 100644 renown.kvp create mode 100644 renownconfig.json create mode 100644 renowngame.ini create mode 100644 renownmetaconfig.json create mode 100644 renownports.json create mode 100644 renownupdates.json diff --git a/renown.kvp b/renown.kvp new file mode 100644 index 000000000..9ec34646f --- /dev/null +++ b/renown.kvp @@ -0,0 +1,117 @@ +Meta.DisplayName=Renown +Meta.Description=Renown Dedicated Server +Meta.OS=Windows, Linux +Meta.AarchSupport=Unknown +Meta.Arch=x86_64 +Meta.Author=Greelan, TheCatDied +Meta.URL=https://playrenown.com/ +Meta.DisplayImageSource=steam:1488310 +Meta.EndpointURIFormat=steam://connect/{ip}:{GenericModule.App.Ports.$QueryPort} +Meta.ConfigManifest=renownconfig.json +Meta.MetaConfigManifest=renownmetaconfig.json +Meta.ConfigRoot=renown.kvp +Meta.MinAMPVersion=2.6.2.8 +Meta.SpecificDockerImage=cubecoders/ampbase:debian +Meta.DockerRequired=False +Meta.DockerBaseReadOnly=False +Meta.ContainerPolicy=Supported +Meta.ContainerPolicyReason= +Meta.ExtraSetupStepsURI= +Meta.Prerequisites=[] +Meta.ExtraContainerPackages=[] +Meta.ConfigReleaseState=NotSpecified +Meta.NoCommercialUsage=False +Meta.ConfigVersion=2 +Meta.ReleaseNotes= +Meta.BreakingReleaseNotes= +Meta.AppConfigId=3a94e6c8-e0f9-4008-afc8-903c7e372bad +Meta.ImportableExtensions=[".ini"] +Meta.AppIsMultiIPAware=False +App.DisplayName=Renown +App.RootDir=./renown/ +App.BaseDirectory=./renown/1512690/ +App.SteamWorkshopDownloadLocation= +App.ExecutableWin=1512690\Renown_Combat\Binaries\Win64\Renown_CombatServer-Win64-Shipping.exe +App.ExecutableLinux=1512690/Renown_Combat/Binaries/Linux/Renown_CombatServer-Linux-Shipping +App.WorkingDir=1512690 +App.LinuxCommandLineArgs= +App.WindowsCommandLineArgs=-stdout -FullStdOutLogOutput +App.CommandLineArgs=Renown_Combat -Port={{$GamePort}} -QueryPort={{$QueryPort}} -BeaconPort={{$BeaconPort}} -RCONPort={{$RCONPort}} -RCONPassword="{{$RemoteAdminPassword}}" {{$FormattedArgs}} {{$PlatformArgs}} -ini:Engine:[EpicOnlineServices]:DedicatedServerClientId=xyza78917DzEE5Ey0isciVt66QDm5IzM -ini:Engine:[EpicOnlineServices]:DedicatedServerClientSecret=m/mrnywFCdeA1mW3ZSvv3qcVlQlfwi1a+7Z63Q44EGU +App.UseLinuxIOREDIR=False +App.AppSettings={} +App.EnvironmentVariables={"LD_LIBRARY_PATH":"{{$FullBaseDir}}linux64:%LD_LIBRARY_PATH%","SteamAppId":"1488310"} +App.CommandLineParameterFormat=-{0}={1} +App.CommandLineParameterDelimiter= +App.ExitMethod=String +App.ExitMethodWindows=None +App.ExitTimeout=90 +App.ExitString=DoExit 1 +App.ExitFile=app_exit.lck +App.HasWriteableConsole=True +App.HasReadableConsole=True +App.UDPLogger=False +App.SupportsLiveSettingsChanges=False +App.LiveSettingChangeCommandFormat=set {0} "{1}" +App.ForceIPBinding=False +App.SupportsIPv6=False +App.ApplicationIPBinding=0.0.0.0 +App.Ports=@IncludeJson[renownports.json] +App.AdminPortRef=RCONPort +App.PrimaryApplicationPortRef=GamePort +App.UniversalSleepApplicationUDPPortRef=GamePort +App.UniversalSleepSteamQueryPortRef=QueryPort +App.MaxUsers=40 +App.UseRandomAdminPassword=True +App.PersistRandomPassword=True +App.RemoteAdminPassword= +App.AdminMethod=SourceRCON +App.IgnoreSTDOUTAfterRCON=False +App.AdminLoginTransform=None +App.StripANSIControlCodes=True +App.LoginTransformPrefix= +App.RCONConnectDelaySeconds=15 +App.RCONConnectRetrySeconds=15 +App.RCONHeartbeatMinutes=29 +App.RCONHeartbeatCommand=getchat +App.RCONSelectIPMethod=Default +App.TelnetLoginFormat={0} +App.TelnetNewLineType=Default +App.TailLogFilePath=server.log +App.UpdateSources=@IncludeJson[renownupdates.json] +App.PreStartStages=[] +App.UserActions=[] +App.ForceUpdate=False +App.ForceUpdateReason= +App.Compatibility=None +App.SteamUpdateAnonymousLogin=True +App.SteamForceLoginPrompt=False +App.RapidStartup=False +App.SmartExcludeExemptions=["*.cfg","*.conf","*.config","*.ini","*.json","*.xml","*.properties","*.kvp","*.yml","*.yaml","*.toml","*.lua"] +App.SmartExcludeSupported=True +App.DumpFullChildProcessTree=False +App.MonitorChildProcessName= +App.MonitorDirectChildOnly=False +App.SupportsUniversalSleep=False +App.WakeupMode=Any +App.ApplicationReadyMode=RegexMatch +Console.FilterMatchRegex=Command unknown\. ping Try: help +Console.FilterMatchReplacement= +Console.ThrowawayMessageRegex=^(WARNING|ERROR): Shader.+$ +Console.AppReadyRegex=^\[[\d\.]+-[\d\.:]+\]\[[\d ]+\]LogGameState: Match State Changed from WaitingToStart to InProgress$ +Console.UserJoinRegex=^\[[\d\.]+-[\d\.:]+\]\[[\d ]+\]LogBlueprintUserMessages:.*[\d-]+T[\d\.:]+Z\* (?.+?) has joined the server\. (?\d+?)$ +Console.UserLeaveRegex=^\[[\d\.]+-[\d\.:]+\]\[[\d ]+\]LogBlueprintUserMessages:.*\*Chat\*System \d+:\d+(?:am|pm) .* \d+ (?.+?) has left the server\.- \((?\d+?)\)$ +Console.UserChatRegex=^$ +Console.UpdateAvailableRegex=^\[\d\d:\d\d:\d\d\] \[INFO\] A new server update is available! v[\d\.]+.$ +Console.PreConnectRegex= +Console.ConnectIPRegex= +Console.MetricsRegex= +Console.ServerInfoRegex= +Console.HideFromConsoleRegex= +Console.SuppressLogAtStart=False +Console.UserActions={} +Limits.SleepMode=True +Limits.SleepOnStart=False +Limits.SleepDelayMinutes=5 +Limits.DozeDelay=2 +Limits.AutoRetryCount=2 +Limits.SleepStartThresholdSeconds=25 diff --git a/renownconfig.json b/renownconfig.json new file mode 100644 index 000000000..c4afaf6e0 --- /dev/null +++ b/renownconfig.json @@ -0,0 +1,325 @@ +[ + { + "DisplayName": "Enable RCON", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "", + "Keywords": "", + "FieldName": "EnableRCON", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.EnableRCON", + "Hidden": true, + "DefaultValue": "True", + "ExcludeFromImport": true, + "EnumValues": {} + }, + { + "DisplayName": "RCON Password", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "", + "Keywords": "", + "FieldName": "$RemoteAdminPassword", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONPassword", + "Hidden": true, + "ExcludeFromImport": true, + "EnumValues": {} + }, + { + "DisplayName": "RCON Port", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "", + "Keywords": "", + "FieldName": "$RCONPort", + "InputType": "number", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONPort", + "Hidden": true, + "ExcludeFromImport": true, + "EnumValues": {} + }, + { + "DisplayName": "Server Name", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the name of the server that is displayed in the server browser", + "Keywords": "server,name,ServerName", + "FieldName": "ServerName", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.ServerName", + "DefaultValue": "AMP Powered Renown Server", + "Placeholder": "AMP Powered Renown Server", + "EnumValues": {} + }, + { + "DisplayName": "Server Region", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the region tag for the server as shown in the server browser. The official tags appear in the dropdown. If 'Custom' is selected, Custom Server Region must also be set", + "Keywords": "region", + "FieldName": "Region", + "InputType": "enum", + "ParamFieldName": "Region", + "DefaultValue": "US Central", + "EnumValues": { + "US East": "US East", + "US West": "US West", + "US Central": "US Central", + "Europe": "Europe", + "South America": "South America", + "Asia": "Asia", + "Oceania": "Oceania", + "{{CustomRegion}}": "--Custom--" + } + }, + { + "DisplayName": "Custom Server Region", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets a custom region tag for the server, if 'Custom' is selected under Server Region", + "Keywords": "custom,region", + "FieldName": "CustomRegion", + "InputType": "text", + "ParamFieldName": "CustomRegion", + "DefaultValue": "", + "Placeholder": "Modded", + "EnumValues": {} + }, + { + "DisplayName": "Make Server Private", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "If set, the server will not be listed in the server browser and can only be joined via direct connect", + "Keywords": "private,session,PrivateSession", + "FieldName": "PrivateSession", + "InputType": "checkbox", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.PrivateSession", + "DefaultValue": "False", + "EnumValues": { + "False": "False", + "True": "True" + } + }, + { + "DisplayName": "Server MOTD", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the message of the day (MOTD) shown to players when they join", + "Keywords": "motd,message,day", + "FieldName": "MOTD", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MOTD", + "DefaultValue": "Welome to my server!", + "EnumValues": {} + }, + { + "DisplayName": "Server Password", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the password required to join the server. Empty = no password", + "Keywords": "server,password,ServerPassword", + "FieldName": "ServerPassword", + "InputType": "Password", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.ServerPassword", + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Admin Password", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the password for server admins in-game", + "Keywords": "admin,password,AdminPassword", + "FieldName": "AdminPassword", + "InputType": "Password", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.AdminPassword", + "DefaultValue": "", + "EnumValues": {} + }, + { + "DisplayName": "Player Limit", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the maximum number of players allowed on the server at one time", + "Keywords": "max,players,MaxPlayers", + "FieldName": "$MaxUsers", + "InputType": "number", + "MinValue": "1", + "MaxValue": "100", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxPlayers", + "DefaultValue": "40", + "Placeholder": "40", + "Suffix": "players", + "EnumValues": {} + }, + { + "DisplayName": "Player Limit", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "", + "Keywords": "", + "FieldName": "$MaxUsers", + "InputType": "number", + "ParamFieldName": "/Script/Engine.GameSession.MaxPlayers", + "Hidden": true, + "EnumValues": {} + }, + { + "DisplayName": "Map Rotation", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Map rotations can be set in Game.ini. Format: MapRotation=RSurv-AlgaraIsle_p. One map entry per line", + "Keywords": "map,rotation,MapRotation", + "FieldName": "MapRotation", + "InputType": "hidden", + "ParamFieldName": "MapRotation", + "EnumValues": {} + }, + { + "DisplayName": "Game Save Name", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the name of the game save", + "Keywords": "game,save,name,GameSaveName", + "FieldName": "GameSaveName", + "InputType": "text", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.GameSaveName", + "DefaultValue": "Save 1", + "Placeholder": "Save 1", + "Required": true, + "EnumValues": {} + }, + { + "DisplayName": "Maximum Ping", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the maximum ping allowed for players to join the server. 0 = no limit", + "Keywords": "max,ping,MaxPing", + "FieldName": "MaxPing", + "InputType": "number", + "MinValue": "0", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.MaxPing", + "DefaultValue": "180", + "Placeholder": "180", + "EnumValues": {} + }, + { + "DisplayName": "RCON Chat Messages Limit", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the limit for RCON chat messages", + "Keywords": "rcon,chat,messages,limit", + "FieldName": "RCONChatMessagesLimit", + "InputType": "number", + "MinValue": "0", + "ParamFieldName": "/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C.RCONChatMessagesLimit", + "DefaultValue": "30", + "Placeholder": "30", + "EnumValues": {} + }, + { + "DisplayName": "Network Maximum Tick Rate", + "Category": "Renown:stadia_controller", + "Subcategory": "Server:dns:1", + "Description": "Sets the maximum tick rate for the server's network driver", + "Keywords": "net,server,tick,rate,NetServerMaxTickRate", + "FieldName": "NetServerMaxTickRate", + "InputType": "number", + "MinValue": "1", + "ParamFieldName": "ini:Engine:[Script/SteamSockets.SteamSocketsNetDriver]:NetServerMaxTickRate", + "IncludeInCommandLine": true, + "SkipIfEmpty": true, + "DefaultValue": "30", + "Placeholder": "30", + "EnumValues": {} + }, + { + "DisplayName": "Resource Gain Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Sets the multiplier for resource gain, which determines how much players gather from resources", + "Keywords": "resource,gain,multiplier,ResourceGainMultiplier", + "FieldName": "ResourceGainMultiplier", + "InputType": "number", + "MinValue": "0", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.ResourceGainMultiplier", + "DefaultValue": "1", + "Placeholder": "1", + "EnumValues": {} + }, + { + "DisplayName": "Gold Coin Gain Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Sets the multiplier for gold coin gain, which determines how much gold players earn", + "Keywords": "gold,coin,gain,multiplier,GoldCoinGainMultiplier", + "FieldName": "GoldCoinGainMultiplier", + "InputType": "number", + "MinValue": "0", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GoldCoinGainMultiplier", + "DefaultValue": "1", + "Placeholder": "1", + "EnumValues": {} + }, + { + "DisplayName": "Global Crafting Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Sets the multiplier for crafting speed globally", + "Keywords": "crafting,multiplier,global,CraftingSpeedMultiplier", + "FieldName": "GlobalCraftingMultiplier", + "InputType": "number", + "MinValue": "0", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalCraftingMultiplier", + "DefaultValue": "1", + "Placeholder": "1", + "EnumValues": {} + }, + { + "DisplayName": "Global Smelting Multiplier", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "Sets the multiplier for smelting speed globally", + "Keywords": "smelting,multiplier,global,GlobalSmeltingMultiplier", + "FieldName": "GlobalSmeltingMultiplier", + "InputType": "number", + "MinValue": "0", + "ParamFieldName": "/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C.GlobalSmeltingMultiplier", + "DefaultValue": "1", + "Placeholder": "1", + "EnumValues": {} + }, + { + "DisplayName": "Enable First Person Only", + "Category": "Renown:stadia_controller", + "Subcategory": "Gameplay:joystick:2", + "Description": "If set, the server will enforce first-person-only gameplay", + "Keywords": "first,person,only,Server.FirstPersonOnly", + "FieldName": "Server.FirstPersonOnly", + "InputType": "checkbox", + "ParamFieldName": "ini:Engine:[SystemSettings]:Server.FirstPersonOnly", + "IncludeInCommandLine": true, + "SkipIfEmpty": true, + "DefaultValue": "0", + "EnumValues": { + "False": "0", + "True": "1" + } + }, + { + "DisplayName": "Server Release Version", + "Category": "Updates", + "Subcategory": "Steam Downloads:download", + "Description": "Sets the server release version to install. Update the server after changing this setting", + "Keywords": "server,version,public,beta", + "FieldName": "ServerVersion", + "InputType": "enum", + "ParamFieldName": "ServerVersion", + "DefaultValue": "public", + "EnumValues": { + "public": "Public (default)", + "beta": "Beta" + } + } +] \ No newline at end of file diff --git a/renowngame.ini b/renowngame.ini new file mode 100644 index 000000000..46795c155 --- /dev/null +++ b/renowngame.ini @@ -0,0 +1,24 @@ +[/Game/Core/Blueprints/Renown_GameInstance.Renown_GameInstance_C] +ServerName=AMP Powered Renown Server +MaxPlayers=40 +ServerPassword= +AdminPassword= +MapRotation=RSurv-AlgaraIsle_p +PrivateSession=False +GameSaveName=Save 1 +MaxPing=180 +EnableRCON=True +RCONPort=25575 +RCONChatMessagesLimit=30 +RCONPassword= +MOTD=Welome to my server! +Region= + +[/Script/Engine.GameSession] +MaxPlayers=40 + +[/Game/Core/Blueprints/GameModes/Renown_Survival_GameMode.Renown_Survival_GameMode_C] +ResourceGainMultiplier=1 +GoldCoinGainMultiplier=1 +GlobalCraftingMultiplier=1 +GlobalSmeltingMultiplier=1 diff --git a/renownmetaconfig.json b/renownmetaconfig.json new file mode 100644 index 000000000..f02299463 --- /dev/null +++ b/renownmetaconfig.json @@ -0,0 +1,14 @@ +[ + { + "ConfigFile": "Renown_Combat/Saved/Config/LinuxServer/Game.ini", + "ConfigType": "ini", + "AutoMap": true, + "Importable": true + }, + { + "ConfigFile": "Renown_Combat/Saved/Config/WindowsServer/Game.ini", + "ConfigType": "ini", + "AutoMap": true, + "Importable": true + } +] \ No newline at end of file diff --git a/renownports.json b/renownports.json new file mode 100644 index 000000000..07781e3d5 --- /dev/null +++ b/renownports.json @@ -0,0 +1,30 @@ +[ + { + "Protocol": "UDP", + "Port": 7777, + "Ref": "GamePort", + "Name": "Main Game Port", + "Description": "Port used for main game traffic" + }, + { + "Protocol": "UDP", + "Port": 27015, + "Ref": "QueryPort", + "Name": "Query Port", + "Description": "Port used for Steam query traffic" + }, + { + "Protocol": "UDP", + "Port": 9999, + "Ref": "BeaconPort", + "Name": "Beacon Port", + "Description": "Port used for beacon traffic" + }, + { + "Protocol": "TCP", + "Port": 25575, + "Ref": "RCONPort", + "Name": "RCON Port", + "Description": "Port used for RCON traffic" + } +] \ No newline at end of file diff --git a/renownupdates.json b/renownupdates.json new file mode 100644 index 000000000..3a7f24970 --- /dev/null +++ b/renownupdates.json @@ -0,0 +1,52 @@ +[ + { + "UpdateStageName": "SteamCMD Download", + "UpdateSourcePlatform": "All", + "UpdateSource": "SteamCMD", + "UpdateSourceData": "1512690", + "UpdateSourceArgs": "1488310", + "UpdateSourceVersion": "{{ServerVersion}}", + "SkipOnFailure": false + }, + { + "UpdateStageName": "SteamCMD Component Download", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "SteamCMD", + "UpdateSourceData": "1007", + "UpdateSourceArgs": "1488310", + "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Binaries/Win64", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create Config Directory", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Create Config Directory", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "CreateDirectory", + "UpdateSourceArgs": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Game.ini Download", + "UpdateSourcePlatform": "Linux", + "UpdateSource": "FetchURL", + "UpdateSourceData": "https://raw.githubusercontent.com/CubeCoders/AMPTemplates/main/renowngame.ini", + "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/LinuxServer", + "UpdateSourceArgs": "Game.ini", + "OverwriteExistingFiles": false + }, + { + "UpdateStageName": "Game.ini Download", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "FetchURL", + "UpdateSourceData": "https://raw.githubusercontent.com/CubeCoders/AMPTemplates/main/renowngame.ini", + "UpdateSourceTarget": "{{$FullBaseDir}}Renown_Combat/Saved/Config/WindowsServer", + "UpdateSourceArgs": "Game.ini", + "OverwriteExistingFiles": false + } +] \ No newline at end of file From a836e10bcca3264c99ee3727f04c055f60c7058a Mon Sep 17 00:00:00 2001 From: HuguesDePayens Date: Mon, 17 Aug 2026 19:41:40 -0500 Subject: [PATCH 50/50] Add files via upload --- vintage-story-stratum.kvp | 2 +- vintage-story-stratumconfig.json | 88 ++++++++++++++++++++----------- vintage-story-stratumstart.json | 1 + vintage-story-stratumupdates.json | 21 +++++++- 4 files changed, 79 insertions(+), 33 deletions(-) create mode 100644 vintage-story-stratumstart.json diff --git a/vintage-story-stratum.kvp b/vintage-story-stratum.kvp index fab63aa28..5538ab8a3 100644 --- a/vintage-story-stratum.kvp +++ b/vintage-story-stratum.kvp @@ -18,7 +18,7 @@ Meta.ExtraContainerPackages=["jq","unzip","curl","ca-certificates"] Meta.Prerequisites=[] Meta.ConfigReleaseState=NotSpecified Meta.NoCommercialUsage=False -Meta.ConfigVersion=3 +Meta.ConfigVersion=4 Meta.AppConfigId=ac764031-4749-46d1-b662-d3e9de8d9356 Meta.AppIsMultiIPAware=True Meta.ResourceUsageInfo=4 GB RAM minimum; 8 GB recommended for active worlds diff --git a/vintage-story-stratumconfig.json b/vintage-story-stratumconfig.json index 7dc9d8a65..c2b9d23d4 100644 --- a/vintage-story-stratumconfig.json +++ b/vintage-story-stratumconfig.json @@ -142,19 +142,34 @@ "True": "true", "False": "false" } - }, - { - "DisplayName": "Nimbus Server ID", - "Category": "Nimbus Backend:share", - "Subcategory": "Connection:dns:1", - "Description": "Unique ID that must exactly match this backend\u0027s key in the Proxy Backend Servers map.", + }, + { + "DisplayName": "Enable Nimbus Backend", + "Category": "Nimbus Backend:share", + "Subcategory": "Status:power_settings_new:0", + "Description": "Enable Nimbus backend networking. Leave disabled to run Stratum without Nimbus. Network settings below are required only when enabled.", + "Keywords": "nimbus,enable,disable,standalone", + "FieldName": "NimbusEnabled", + "InputType": "checkbox", + "ParamFieldName": "$.Enabled", + "IncludeInCommandLine": false, + "DefaultValue": "false", + "EnumValues": { + "True": "true", + "False": "false" + } + }, + { + "DisplayName": "Nimbus Server ID", + "Category": "Nimbus Backend:share", + "Subcategory": "Connection:dns:1", + "Description": "Required only when Nimbus is enabled. Unique ID that must exactly match this backend\u0027s key in the Proxy Backend Servers map.", "Keywords": "nimbus,id", "FieldName": "NimbusServerId", "InputType": "text", "ParamFieldName": "$.ServerId", "IncludeInCommandLine": false, - "Required": true, - "DefaultValue": "", + "DefaultValue": "", "Placeholder": "hub", "EnumValues": { @@ -177,28 +192,27 @@ } }, { - "DisplayName": "Proxy Public Host", + "DisplayName": "Backend Reachable Host", "Category": "Nimbus Backend:share", "Subcategory": "Connection:dns:1", - "Description": "Public hostname or IP players use for Nimbus Proxy, not this private backend.", - "Keywords": "proxy,host", + "Description": "Required only when Nimbus is enabled. Hostname or IP the Nimbus Proxy uses to reach this backend.", + "Keywords": "nimbus,backend,host", "FieldName": "NimbusPublicHost", "InputType": "text", "ParamFieldName": "$.PublicHost", "IncludeInCommandLine": false, - "Required": true, - "DefaultValue": "", - "Placeholder": "play.example.com", + "DefaultValue": "", + "Placeholder": "192.168.1.20", "EnumValues": { } }, { - "DisplayName": "Proxy Public Port", + "DisplayName": "Backend Reachable Port", "Category": "Nimbus Backend:share", "Subcategory": "Connection:dns:1", - "Description": "Public player port of Nimbus Proxy.", - "Keywords": "proxy,port", + "Description": "Port the Nimbus Proxy uses to reach this backend. Required only when Nimbus is enabled.", + "Keywords": "nimbus,backend,port", "FieldName": "NimbusPublicPort", "InputType": "number", "ParamFieldName": "$.PublicPort", @@ -214,14 +228,13 @@ "DisplayName": "Nimbus Registry URL", "Category": "Nimbus Backend:share", "Subcategory": "Registry:hub:2", - "Description": "HTTP URL reachable from this backend for the Proxy\u0027s embedded Registry or the optional standalone Registry.", + "Description": "Required only when Nimbus is enabled. HTTP URL reachable from this backend for the Proxy\u0027s embedded Registry or the optional standalone Registry.", "Keywords": "registry,url", "FieldName": "NimbusRegistryUrl", "InputType": "text", "ParamFieldName": "$.RegistryUrl", "IncludeInCommandLine": false, - "Required": true, - "DefaultValue": "", + "DefaultValue": "", "Placeholder": "http://proxy-host:8765", "EnumValues": { @@ -231,14 +244,13 @@ "DisplayName": "Nimbus Shared Secret", "Category": "Nimbus Backend:share", "Subcategory": "Registry:hub:2", - "Description": "Copy the generated shared secret from the Proxy or standalone Registry. Backends never generate it.", + "Description": "Required only when Nimbus is enabled. Copy the generated shared secret from the Proxy or standalone Registry. Backends never generate it.", "Keywords": "registry,secret", "FieldName": "NimbusSharedSecret", "InputType": "password", "ParamFieldName": "$.SharedSecret", "IncludeInCommandLine": false, - "Required": true, - "DefaultValue": "", + "DefaultValue": "", "EnumValues": { } @@ -247,7 +259,7 @@ "DisplayName": "Maintenance Mode", "Category": "Nimbus Backend:share", "Subcategory": "Routing:swap_horiz:3", - "Description": "Keep this backend online but remove it from normal routing.", + "Description": "Nimbus networks only. Keep this configured backend online and heartbeating but remove it from normal routing. This does not disable Nimbus.", "Keywords": "maintenance,routing", "FieldName": "NimbusMaintenance", "InputType": "checkbox", @@ -307,8 +319,8 @@ } }, - { - "DisplayName": "Nimbus Release Tag", + { + "DisplayName": "Nimbus Release Tag", "Category": "Updates:update", "Subcategory": "Version:verified_user:1", "Description": "Optional exact Nimbus release tag. Leave blank for the latest stable release.", @@ -319,8 +331,24 @@ "IncludeInCommandLine": false, "DefaultValue": "", "Placeholder": "v0.5.0", - "EnumValues": { - - } - } + "EnumValues": { + + } + }, + { + "DisplayName": "RedirectFix Release Tag", + "Category": "Updates:update", + "Subcategory": "Version:verified_user:1", + "Description": "Optional exact RedirectFix release tag. Leave blank to install and track the latest stable release.", + "Keywords": "redirectfix,version,client,mod", + "FieldName": "RedirectFixVersionTag", + "InputType": "text", + "ParamFieldName": "RedirectFixVersionTag", + "IncludeInCommandLine": false, + "DefaultValue": "", + "Placeholder": "v1.0.1", + "EnumValues": { + + } + } ] diff --git a/vintage-story-stratumstart.json b/vintage-story-stratumstart.json new file mode 100644 index 000000000..fe51488c7 --- /dev/null +++ b/vintage-story-stratumstart.json @@ -0,0 +1 @@ +[] diff --git a/vintage-story-stratumupdates.json b/vintage-story-stratumupdates.json index 2ad2e664d..e2ce5f9ca 100644 --- a/vintage-story-stratumupdates.json +++ b/vintage-story-stratumupdates.json @@ -123,7 +123,7 @@ "UpdateSourcePlatform": "All", "UpdateSource": "CreateFile", "UpdateSourceArgs": "{{$FullRootDir}}data/ModConfig/nimbus-server.json", - "UpdateSourceData": "{\n \"Enabled\": true,\n \"ServerId\": \"\",\n \"DisplayName\": \"\",\n \"PublicHost\": \"\",\n \"PublicPort\": 42420,\n \"RegistryUrl\": \"\",\n \"SharedSecret\": \"\",\n \"HeartbeatIntervalSeconds\": 5,\n \"RegistryHttpTimeoutSeconds\": 5,\n \"Maintenance\": false,\n \"ReservationRequired\": true,\n \"FailClosedWhenRegistryUnreachable\": false,\n \"AllowPlayerServerCommand\": true,\n \"TransferMode\": \"redirect\",\n \"SeamlessPrepareAckTimeoutSeconds\": 8,\n \"ShortcutCommands\": [],\n \"Tags\": []\n}\n", + "UpdateSourceData": "{\n \"Enabled\": false,\n \"ServerId\": \"\",\n \"DisplayName\": \"\",\n \"PublicHost\": \"\",\n \"PublicPort\": 42420,\n \"RegistryUrl\": \"\",\n \"SharedSecret\": \"\",\n \"HeartbeatIntervalSeconds\": 5,\n \"RegistryHttpTimeoutSeconds\": 5,\n \"Maintenance\": false,\n \"ReservationRequired\": true,\n \"FailClosedWhenRegistryUnreachable\": false,\n \"AllowPlayerServerCommand\": true,\n \"TransferMode\": \"redirect\",\n \"SeamlessPrepareAckTimeoutSeconds\": 8,\n \"ShortcutCommands\": [],\n \"Tags\": []\n}\n", "OverwriteExistingFiles": false, "SkipOnFailure": false }, @@ -143,5 +143,22 @@ "UpdateSourceData": "powershell.exe", "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference=\u0027Stop\u0027; $ProgressPreference=\u0027SilentlyContinue\u0027; $root=\u0027{{$FullRootDir}}\u0027; $tag=\u0027{{NimbusVersionTag}}\u0027.Trim(); $headers=@{\u0027User-Agent\u0027=\u0027AMP-Clean-Template\u0027}; if (-not $tag) { $tag=(Invoke-RestMethod -Headers $headers -Uri https://api.github.com/repos/StratumServer/Nimbus/releases/latest).tag_name }; if (-not $tag.StartsWith(\u0027v\u0027)) { $tag=\u0027v\u0027+$tag }; $stage=Join-Path $root \u0027.amp-nimbus-mod-stage\u0027; $archive=Join-Path $root \u0027.amp-nimbus-mod.zip\u0027; $target=Join-Path $root \u0027data\\Mods\\Nimbus.ServerMod\u0027; $old=Join-Path $root \u0027.amp-nimbus-mod-old\u0027; Remove-Item -LiteralPath $stage,$old,$archive -Recurse -Force -ErrorAction SilentlyContinue; New-Item -ItemType Directory -Path $stage | Out-Null; Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri (\u0027https://github.com/StratumServer/Nimbus/releases/download/\u0027+$tag+\u0027/Nimbus.ServerMod-\u0027+$tag+\u0027.zip\u0027) -OutFile $archive; Expand-Archive -LiteralPath $archive -DestinationPath $stage -Force; Remove-Item -LiteralPath $archive -Force; if (-not (Get-ChildItem -LiteralPath $stage -File -Recurse | Select-Object -First 1)) { throw \u0027Nimbus ServerMod archive was empty\u0027 }; if (Test-Path -LiteralPath $target) { Move-Item -LiteralPath $target -Destination $old }; try { Move-Item -LiteralPath $stage -Destination $target; Remove-Item -LiteralPath $old -Recurse -Force -ErrorAction SilentlyContinue } catch { if ((Test-Path -LiteralPath $old) -and -not (Test-Path -LiteralPath $target)) { Move-Item -LiteralPath $old -Destination $target }; throw }; [IO.File]::WriteAllText((Join-Path $target \u0027.amp-nimbus-release\u0027),$tag,(New-Object Text.UTF8Encoding $false))\"", "SkipOnFailure": false - } + }, + { + "UpdateStageName": "Install RedirectFix", + "UpdateSourcePlatform": "Linux", + "UpdateSourceArch": "x86_64", + "UpdateSource": "Executable", + "UpdateSourceData": "/bin/bash", + "UpdateSourceArgs": "-c \"set -euo pipefail; root=\u0027{{$FullRootDir}}\u0027; requested=\u0027{{RedirectFixVersionTag}}\u0027; api=\u0027https://api.github.com/repos/StratumServer/redirectfix/releases\u0027; if [ -z \\\"$requested\\\" ]; then release=\\\"$(curl -fsSL -H \u0027User-Agent: AMP-Clean-Template\u0027 \\\"$api/latest\\\")\\\"; else case \\\"$requested\\\" in v*) tag=\\\"$requested\\\";; *) tag=\\\"v$requested\\\";; esac; release=\\\"$(curl -fsSL -H \u0027User-Agent: AMP-Clean-Template\u0027 \\\"$api/tags/$tag\\\")\\\"; fi; tag=\\\"$(printf \u0027%s\u0027 \\\"$release\\\" | jq -r \u0027.tag_name // empty\u0027)\\\"; test -n \\\"$tag\\\"; version=\\\"\u0024{tag#v}\\\"; asset=\\\"redirectfix-$version.zip\\\"; url=\\\"$(printf \u0027%s\u0027 \\\"$release\\\" | jq -r --arg name \\\"$asset\\\" \u0027.assets[] | select(.name == $name) | .browser_download_url\u0027 | head -n 1)\\\"; test -n \\\"$url\\\"; mods=\\\"$root/data/Mods\\\"; mkdir -p \\\"$mods\\\"; target=\\\"$mods/redirectfix.zip\\\"; marker=\\\"$mods/.amp-redirectfix-version\\\"; installed=\u0027\u0027; valid=false; if [ -f \\\"$target\\\" ] && unzip -Z1 \\\"$target\\\" | grep -qx \u0027modinfo.json\u0027 && unzip -Z1 \\\"$target\\\" | grep -qx \u0027RedirectFix.dll\u0027; then installed=\\\"$(unzip -p \\\"$target\\\" modinfo.json | jq -r \u0027.Version // empty\u0027 2>/dev/null || true)\\\"; valid=true; fi; echo \\\"[AMP] RedirectFix installed=\u0024{installed:-\u003cnone\u003e} requested=$version\\\"; if [ \\\"$valid\\\" = true ] && [ \\\"$installed\\\" = \\\"$version\\\" ]; then printf \u0027%s\\n\u0027 \\\"$version\\\" \u003e \\\"$marker.tmp\\\"; mv -f \\\"$marker.tmp\\\" \\\"$marker\\\"; echo \\\"[AMP] RedirectFix $version is already current\\\"; exit 0; fi; tmp=\\\"$(mktemp \\\"$mods/.redirectfix.XXXXXX.zip\\\")\\\"; trap \u0027rm -f \\\"$tmp\\\" \\\"$marker.tmp\\\"\u0027 EXIT; curl -fL --retry 3 -o \\\"$tmp\\\" \\\"$url\\\"; unzip -Z1 \\\"$tmp\\\" | grep -qx \u0027modinfo.json\u0027; unzip -Z1 \\\"$tmp\\\" | grep -qx \u0027RedirectFix.dll\u0027; archive_version=\\\"$(unzip -p \\\"$tmp\\\" modinfo.json | jq -r \u0027.Version // empty\u0027)\\\"; [ \\\"$archive_version\\\" = \\\"$version\\\" ]; mv -f \\\"$tmp\\\" \\\"$target\\\"; printf \u0027%s\\n\u0027 \\\"$version\\\" \u003e \\\"$marker.tmp\\\"; mv -f \\\"$marker.tmp\\\" \\\"$marker\\\"; trap - EXIT; echo \\\"[AMP] RedirectFix updated to $version\\\"\"", + "SkipOnFailure": false + }, + { + "UpdateStageName": "Install RedirectFix", + "UpdateSourcePlatform": "Windows", + "UpdateSource": "Executable", + "UpdateSourceData": "powershell.exe", + "UpdateSourceArgs": "-NoProfile -ExecutionPolicy Bypass -Command \"$ErrorActionPreference=\u0027Stop\u0027; $ProgressPreference=\u0027SilentlyContinue\u0027; Add-Type -AssemblyName System.IO.Compression.FileSystem; $root=\u0027{{$FullRootDir}}\u0027; $requested=\u0027{{RedirectFixVersionTag}}\u0027.Trim(); $headers=@{\u0027User-Agent\u0027=\u0027AMP-Clean-Template\u0027}; $api=\u0027https://api.github.com/repos/StratumServer/redirectfix/releases\u0027; if ($requested) { $tag=if ($requested.StartsWith(\u0027v\u0027)) {$requested} else {\u0027v\u0027+$requested}; $release=Invoke-RestMethod -Headers $headers -Uri ($api+\u0027/tags/\u0027+$tag) } else { $release=Invoke-RestMethod -Headers $headers -Uri ($api+\u0027/latest\u0027) }; $tag=[string]$release.tag_name; if (-not $tag) { throw \u0027RedirectFix release has no tag\u0027 }; $version=$tag.TrimStart(\u0027v\u0027); $assetName=\u0027redirectfix-\u0027+$version+\u0027.zip\u0027; $asset=@($release.assets | Where-Object name -CEQ $assetName | Select-Object -First 1); if ($asset.Count -ne 1) { throw (\u0027RedirectFix release has no \u0027+$assetName) }; function Read-RedirectFixArchive([string]$path) { if (-not (Test-Path -LiteralPath $path -PathType Leaf)) { return $null }; $zip=[IO.Compression.ZipFile]::OpenRead($path); try { $info=@($zip.Entries | Where-Object FullName -CEQ \u0027modinfo.json\u0027); $dll=@($zip.Entries | Where-Object FullName -CEQ \u0027RedirectFix.dll\u0027); if ($info.Count -ne 1 -or $dll.Count -ne 1) { return $null }; $reader=New-Object IO.StreamReader($info[0].Open()); try { $meta=$reader.ReadToEnd() | ConvertFrom-Json } finally { $reader.Dispose() }; return [pscustomobject]@{Version=[string]$meta.Version} } finally { $zip.Dispose() } }; $mods=Join-Path $root \u0027data\\Mods\u0027; New-Item -ItemType Directory -Path $mods -Force | Out-Null; $target=Join-Path $mods \u0027redirectfix.zip\u0027; $marker=Join-Path $mods \u0027.amp-redirectfix-version\u0027; $current=Read-RedirectFixArchive $target; $installed=if ($null -eq $current -or -not $current.Version) {\u0027\u003cnone\u003e\u0027} else {$current.Version}; Write-Output (\u0027[AMP] RedirectFix installed=\u0027+$installed+\u0027 requested=\u0027+$version); if ($null -ne $current -and $current.Version -CEQ $version) { [IO.File]::WriteAllText($marker,$version+[Environment]::NewLine,(New-Object Text.UTF8Encoding $false)); Write-Output (\u0027[AMP] RedirectFix \u0027+$version+\u0027 is already current\u0027); exit 0 }; $tmp=Join-Path $mods (\u0027.redirectfix.\u0027+[guid]::NewGuid().ToString(\u0027N\u0027)+\u0027.zip\u0027); $backup=$target+\u0027.amp-backup\u0027; try { Invoke-WebRequest -UseBasicParsing -Headers $headers -Uri ([string]$asset.browser_download_url) -OutFile $tmp; $candidate=Read-RedirectFixArchive $tmp; if ($null -eq $candidate) { throw \u0027RedirectFix archive must contain root modinfo.json and RedirectFix.dll\u0027 }; if ($candidate.Version -CNE $version) { throw (\u0027RedirectFix archive version \u0027+$candidate.Version+\u0027 does not match \u0027+$version) }; Remove-Item -LiteralPath $backup -Force -ErrorAction SilentlyContinue; if (Test-Path -LiteralPath $target) { [IO.File]::Replace($tmp,$target,$backup,$true); Remove-Item -LiteralPath $backup -Force -ErrorAction SilentlyContinue } else { [IO.File]::Move($tmp,$target) }; [IO.File]::WriteAllText($marker,$version+[Environment]::NewLine,(New-Object Text.UTF8Encoding $false)); Write-Output (\u0027[AMP] RedirectFix updated to \u0027+$version) } finally { Remove-Item -LiteralPath $tmp -Force -ErrorAction SilentlyContinue }\"", + "SkipOnFailure": false + } ]