Fix SCUM SteamCMD lifecycle install
This commit is contained in:
@@ -26,8 +26,9 @@ from command text. Empty `shell` means argv-oriented execution.
|
|||||||
Game plugins own concrete game policy: install/update commands, app ids,
|
Game plugins own concrete game policy: install/update commands, app ids,
|
||||||
executable refs, default launch flags, stop-before-update behavior, and startup
|
executable refs, default launch flags, stop-before-update behavior, and startup
|
||||||
argument construction. For SCUM, the plugin action assets own the SteamCMD flow:
|
argument construction. For SCUM, the plugin action assets own the SteamCMD flow:
|
||||||
stop `SCUMServer.exe` when updating, run
|
stop `SCUMServer.exe` when updating, keep SteamCMD outside the server install
|
||||||
`steamcmd.exe +force_install_dir <serverRoot> +login anonymous +app_update 3792580 validate +quit`,
|
root, run
|
||||||
|
`steamcmd.exe +force_install_dir <serverRoot> +login anonymous +app_update 3792580 +quit`,
|
||||||
and start `<serverRoot>\\SCUM\\Binaries\\Win64\\SCUMServer.exe -port=<gamePort> -MaxPlayers=<maxPlayers> -log`.
|
and start `<serverRoot>\\SCUM\\Binaries\\Win64\\SCUMServer.exe -port=<gamePort> -MaxPlayers=<maxPlayers> -log`.
|
||||||
|
|
||||||
Generated Run distributions carry validated plugin lifecycle assets into the
|
Generated Run distributions carry validated plugin lifecycle assets into the
|
||||||
|
|||||||
@@ -9,8 +9,8 @@
|
|||||||
"SERVER_TEMPLATE": "scum-server",
|
"SERVER_TEMPLATE": "scum-server",
|
||||||
"SERVER_STEAM_APP_ID": "3792580",
|
"SERVER_STEAM_APP_ID": "3792580",
|
||||||
"SERVER_STEAMCMD_INSTALL_DIR_ARG": "+force_install_dir",
|
"SERVER_STEAMCMD_INSTALL_DIR_ARG": "+force_install_dir",
|
||||||
"SERVER_STEAMCMD_UPDATE_ARGS": "+login anonymous +app_update 3792580 validate +quit",
|
"SERVER_STEAMCMD_UPDATE_ARGS": "+login anonymous +app_update 3792580 +quit",
|
||||||
"SERVER_EXECUTABLE_REF": "SCUM/Binaries/Win64/SCUMServer.exe"
|
"SERVER_EXECUTABLE_REF": "SCUM/Binaries/Win64/SCUMServer.exe"
|
||||||
},
|
},
|
||||||
"timeoutMs": 300000
|
"timeoutMs": 7200000
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,21 +5,24 @@ if "%SERVER_ROOT%"=="" set "SERVER_ROOT=C:\scumserver"
|
|||||||
set "SERVER_ROOT_WINDOWS=%SERVER_ROOT:/=\%"
|
set "SERVER_ROOT_WINDOWS=%SERVER_ROOT:/=\%"
|
||||||
if "%SERVER_STEAM_APP_ID%"=="" set "SERVER_STEAM_APP_ID=3792580"
|
if "%SERVER_STEAM_APP_ID%"=="" set "SERVER_STEAM_APP_ID=3792580"
|
||||||
if "%SERVER_STEAMCMD_INSTALL_DIR_ARG%"=="" set "SERVER_STEAMCMD_INSTALL_DIR_ARG=+force_install_dir"
|
if "%SERVER_STEAMCMD_INSTALL_DIR_ARG%"=="" set "SERVER_STEAMCMD_INSTALL_DIR_ARG=+force_install_dir"
|
||||||
if "%SERVER_STEAMCMD_UPDATE_ARGS%"=="" set "SERVER_STEAMCMD_UPDATE_ARGS=+login anonymous +app_update 3792580 validate +quit"
|
if "%SERVER_STEAMCMD_UPDATE_ARGS%"=="" set "SERVER_STEAMCMD_UPDATE_ARGS=+login anonymous +app_update 3792580 +quit"
|
||||||
if "%SERVER_EXECUTABLE_REF%"=="" set "SERVER_EXECUTABLE_REF=SCUM\Binaries\Win64\SCUMServer.exe"
|
if "%SERVER_EXECUTABLE_REF%"=="" set "SERVER_EXECUTABLE_REF=SCUM\Binaries\Win64\SCUMServer.exe"
|
||||||
if "%SERVER_INSTALL_DIR%"=="" set "SERVER_INSTALL_DIR=%SERVER_ROOT_WINDOWS%"
|
if "%SERVER_INSTALL_DIR%"=="" set "SERVER_INSTALL_DIR=%SERVER_ROOT_WINDOWS%"
|
||||||
set "SERVER_INSTALL_DIR_WINDOWS=%SERVER_INSTALL_DIR:/=\%"
|
set "SERVER_INSTALL_DIR_WINDOWS=%SERVER_INSTALL_DIR:/=\%"
|
||||||
set "SERVER_INSTALL_DIR_STEAM=%SERVER_INSTALL_DIR_WINDOWS:\=/%"
|
set "SERVER_INSTALL_DIR_STEAM=%SERVER_INSTALL_DIR_WINDOWS:\=/%"
|
||||||
|
if "%SERVER_STEAMCMD_DIR%"=="" call :default_steamcmd_dir
|
||||||
|
set "SERVER_STEAMCMD_DIR_WINDOWS=%SERVER_STEAMCMD_DIR:/=\%"
|
||||||
if "%SERVER_STEAMCMD_MAX_ATTEMPTS%"=="" set "SERVER_STEAMCMD_MAX_ATTEMPTS=3"
|
if "%SERVER_STEAMCMD_MAX_ATTEMPTS%"=="" set "SERVER_STEAMCMD_MAX_ATTEMPTS=3"
|
||||||
if "%SERVER_STEAMCMD_RETRY_SECONDS%"=="" set "SERVER_STEAMCMD_RETRY_SECONDS=30"
|
if "%SERVER_STEAMCMD_RETRY_SECONDS%"=="" set "SERVER_STEAMCMD_RETRY_SECONDS=30"
|
||||||
|
|
||||||
set "STEAMCMD_DIR=%SERVER_ROOT_WINDOWS%\steamcmd"
|
set "STEAMCMD_DIR=%SERVER_STEAMCMD_DIR_WINDOWS%"
|
||||||
set "STEAMCMD_EXE=%STEAMCMD_DIR%\steamcmd.exe"
|
set "STEAMCMD_EXE=%STEAMCMD_DIR%\steamcmd.exe"
|
||||||
set "SCUM_EXE_MARKER=%SERVER_ROOT_WINDOWS%\.scum-exe-path"
|
set "SCUM_EXE_MARKER=%SERVER_ROOT_WINDOWS%\.scum-exe-path"
|
||||||
|
|
||||||
if not exist "%SERVER_ROOT_WINDOWS%" mkdir "%SERVER_ROOT_WINDOWS%"
|
if not exist "%SERVER_ROOT_WINDOWS%" mkdir "%SERVER_ROOT_WINDOWS%"
|
||||||
if not exist "%STEAMCMD_DIR%" mkdir "%STEAMCMD_DIR%"
|
if not exist "%STEAMCMD_DIR%" mkdir "%STEAMCMD_DIR%"
|
||||||
if not exist "%SERVER_INSTALL_DIR_WINDOWS%" mkdir "%SERVER_INSTALL_DIR_WINDOWS%"
|
if not exist "%SERVER_INSTALL_DIR_WINDOWS%" mkdir "%SERVER_INSTALL_DIR_WINDOWS%"
|
||||||
|
if /I "%STEAMCMD_DIR%"=="%SERVER_INSTALL_DIR_WINDOWS%" exit /b 3
|
||||||
|
|
||||||
if not exist "%STEAMCMD_EXE%" (
|
if not exist "%STEAMCMD_EXE%" (
|
||||||
powershell -NoProfile -ExecutionPolicy Bypass -Command "[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $zip=Join-Path $env:STEAMCMD_DIR 'steamcmd.zip'; Invoke-WebRequest -Uri 'https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip' -OutFile $zip; Expand-Archive -Path $zip -DestinationPath $env:STEAMCMD_DIR -Force; Remove-Item $zip -Force"
|
powershell -NoProfile -ExecutionPolicy Bypass -Command "[Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; $zip=Join-Path $env:STEAMCMD_DIR 'steamcmd.zip'; Invoke-WebRequest -Uri 'https://steamcdn-a.akamaihd.net/client/installer/steamcmd.zip' -OutFile $zip; Expand-Archive -Path $zip -DestinationPath $env:STEAMCMD_DIR -Force; Remove-Item $zip -Force"
|
||||||
@@ -54,3 +57,12 @@ set "SCUM_EXE=%SERVER_ROOT_WINDOWS%\steamcmd\steamapps\common\SCUM Server\%SERVE
|
|||||||
if exist "%SCUM_EXE%" exit /b 0
|
if exist "%SCUM_EXE%" exit /b 0
|
||||||
set "SCUM_EXE=%SERVER_ROOT_WINDOWS%\SCUM Server\%SERVER_EXECUTABLE_REF:/=\%"
|
set "SCUM_EXE=%SERVER_ROOT_WINDOWS%\SCUM Server\%SERVER_EXECUTABLE_REF:/=\%"
|
||||||
exit /b 0
|
exit /b 0
|
||||||
|
|
||||||
|
:default_steamcmd_dir
|
||||||
|
for %%I in ("%SERVER_ROOT_WINDOWS%") do set "SERVER_ROOT_DRIVE=%%~dI"
|
||||||
|
if "%SERVER_ROOT_DRIVE%"=="" (
|
||||||
|
set "SERVER_STEAMCMD_DIR=%SERVER_ROOT_WINDOWS%-steamcmd"
|
||||||
|
) else (
|
||||||
|
set "SERVER_STEAMCMD_DIR=%SERVER_ROOT_DRIVE%\steamcmd"
|
||||||
|
)
|
||||||
|
exit /b 0
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"id": "game.scum",
|
"id": "game.scum",
|
||||||
"name": "SCUM Server",
|
"name": "SCUM Server",
|
||||||
"description": "First-party SCUM game server operations plugin with platform-mediated lifecycle and companion bridge support.",
|
"description": "First-party SCUM game server operations plugin with platform-mediated lifecycle and companion bridge support.",
|
||||||
"version": "0.1.2",
|
"version": "0.1.4",
|
||||||
"kind": "game-plugin",
|
"kind": "game-plugin",
|
||||||
"tags": [
|
"tags": [
|
||||||
"scum",
|
"scum",
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
"additionalProperties": { "type": "string", "maxLength": 512 },
|
"additionalProperties": { "type": "string", "maxLength": 512 },
|
||||||
"maxProperties": 32
|
"maxProperties": 32
|
||||||
},
|
},
|
||||||
"timeoutMs": { "type": "integer", "minimum": 1, "maximum": 300000 },
|
"timeoutMs": { "type": "integer", "minimum": 1, "maximum": 7200000 },
|
||||||
"stopTimeoutMs": { "type": "integer", "minimum": 1, "maximum": 60000 }
|
"stopTimeoutMs": { "type": "integer", "minimum": 1, "maximum": 60000 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -199,11 +199,14 @@ describe("plugin manifest validation", () => {
|
|||||||
const startScript = fs.readFileSync(path.join(pluginDir, startAction.executableKey), "utf8");
|
const startScript = fs.readFileSync(path.join(pluginDir, startAction.executableKey), "utf8");
|
||||||
expect(manifest.runtimeProfiles.serverDeployments).toBeUndefined();
|
expect(manifest.runtimeProfiles.serverDeployments).toBeUndefined();
|
||||||
expect(assetPaths).toEqual(expect.arrayContaining(["actions/install.json", "actions/start.json", "bin/scum-install-update.cmd", "bin/scum-start.cmd"]));
|
expect(assetPaths).toEqual(expect.arrayContaining(["actions/install.json", "actions/start.json", "bin/scum-install-update.cmd", "bin/scum-start.cmd"]));
|
||||||
expect(installAction).toMatchObject({ executableKey: "bin/scum-install-update.cmd", environment: { SERVER_STEAM_APP_ID: "3792580", SERVER_STEAMCMD_UPDATE_ARGS: "+login anonymous +app_update 3792580 validate +quit" } });
|
expect(installAction).toMatchObject({ executableKey: "bin/scum-install-update.cmd", environment: { SERVER_STEAM_APP_ID: "3792580", SERVER_STEAMCMD_UPDATE_ARGS: "+login anonymous +app_update 3792580 +quit" } });
|
||||||
|
expect(installAction.timeoutMs).toBe(7200000);
|
||||||
expect(startAction).toMatchObject({ executableKey: "bin/scum-start.cmd", environment: { SERVER_LOG_FLAG: "-log" } });
|
expect(startAction).toMatchObject({ executableKey: "bin/scum-start.cmd", environment: { SERVER_LOG_FLAG: "-log" } });
|
||||||
expect(installScript).toContain("taskkill /IM SCUMServer.exe /F");
|
expect(installScript).toContain("taskkill /IM SCUMServer.exe /F");
|
||||||
expect(installScript).toContain("SERVER_ROOT_WINDOWS=%SERVER_ROOT:/=\\%");
|
expect(installScript).toContain("SERVER_ROOT_WINDOWS=%SERVER_ROOT:/=\\%");
|
||||||
expect(installScript).toContain("SERVER_INSTALL_DIR=%SERVER_ROOT_WINDOWS%");
|
expect(installScript).toContain("SERVER_INSTALL_DIR=%SERVER_ROOT_WINDOWS%");
|
||||||
|
expect(installScript).toContain("SERVER_STEAMCMD_DIR=%SERVER_ROOT_DRIVE%\\steamcmd");
|
||||||
|
expect(installScript).toContain("STEAMCMD_DIR=%SERVER_STEAMCMD_DIR_WINDOWS%");
|
||||||
expect(installScript).toContain("SERVER_INSTALL_DIR_STEAM=%SERVER_INSTALL_DIR_WINDOWS:\\=/%");
|
expect(installScript).toContain("SERVER_INSTALL_DIR_STEAM=%SERVER_INSTALL_DIR_WINDOWS:\\=/%");
|
||||||
expect(installScript).toContain("%SERVER_STEAMCMD_INSTALL_DIR_ARG% \"%SERVER_INSTALL_DIR_STEAM%\" %SERVER_STEAMCMD_UPDATE_ARGS%");
|
expect(installScript).toContain("%SERVER_STEAMCMD_INSTALL_DIR_ARG% \"%SERVER_INSTALL_DIR_STEAM%\" %SERVER_STEAMCMD_UPDATE_ARGS%");
|
||||||
expect(installScript).toContain("SERVER_STEAMCMD_MAX_ATTEMPTS=3");
|
expect(installScript).toContain("SERVER_STEAMCMD_MAX_ATTEMPTS=3");
|
||||||
|
|||||||
@@ -92,9 +92,29 @@ local_debug_seed_lifecycle_scope() {
|
|||||||
cp "$source_dir/actions/$action.json" "$scope/actions/$action.json"
|
cp "$source_dir/actions/$action.json" "$scope/actions/$action.json"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
cp "$true_binary" "$scope/bin/install-server"
|
local executable_key
|
||||||
cp "$true_binary" "$scope/bin/game-server"
|
while IFS= read -r executable_key; do
|
||||||
chmod +x "$scope/bin/install-server" "$scope/bin/game-server"
|
[[ -n "$executable_key" ]] || continue
|
||||||
|
local executable_target="$scope/$executable_key"
|
||||||
|
mkdir -p "$(dirname "$executable_target")"
|
||||||
|
cp "$true_binary" "$executable_target"
|
||||||
|
chmod +x "$executable_target"
|
||||||
|
done < <(node - "$scope/actions" <<'NODE'
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const actionsDir = process.argv[2];
|
||||||
|
for (const entry of fs.readdirSync(actionsDir)) {
|
||||||
|
if (!entry.endsWith(".json")) continue;
|
||||||
|
const action = JSON.parse(fs.readFileSync(path.join(actionsDir, entry), "utf8"));
|
||||||
|
const key = action.executableKey;
|
||||||
|
if (typeof key !== "string" || key.length === 0) continue;
|
||||||
|
if (path.posix.isAbsolute(key) || key.includes("\\") || key.split("/").includes("..")) {
|
||||||
|
throw new Error(`unsafe local-debug executableKey: ${key}`);
|
||||||
|
}
|
||||||
|
console.log(key);
|
||||||
|
}
|
||||||
|
NODE
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
local_debug_seed_plugin_lifecycle_template() {
|
local_debug_seed_plugin_lifecycle_template() {
|
||||||
|
|||||||
@@ -296,14 +296,19 @@ json_id() {
|
|||||||
|
|
||||||
require_scum_manifest_contract() {
|
require_scum_manifest_contract() {
|
||||||
local file="$1"
|
local file="$1"
|
||||||
node - "$file" <<'NODE'
|
local expected_version="$2"
|
||||||
|
node - "$file" "$expected_version" <<'NODE'
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const file = process.argv[2];
|
const file = process.argv[2];
|
||||||
|
const expectedVersion = process.argv[3];
|
||||||
const plugin = JSON.parse(fs.readFileSync(file, "utf8"));
|
const plugin = JSON.parse(fs.readFileSync(file, "utf8"));
|
||||||
const missing = [];
|
const missing = [];
|
||||||
const declaredPermissions = Array.isArray(plugin.declaredPermissions) ? plugin.declaredPermissions : [];
|
const declaredPermissions = Array.isArray(plugin.declaredPermissions) ? plugin.declaredPermissions : [];
|
||||||
const bridgeActions = Array.isArray(plugin.bridgeActions) ? plugin.bridgeActions : [];
|
const bridgeActions = Array.isArray(plugin.bridgeActions) ? plugin.bridgeActions : [];
|
||||||
const lifecycleProfiles = plugin.runtimeProfiles?.lifecycleProfiles ?? [];
|
const lifecycleProfiles = plugin.runtimeProfiles?.lifecycleProfiles ?? [];
|
||||||
|
if (plugin.version !== expectedVersion) {
|
||||||
|
missing.push(`version ${expectedVersion}`);
|
||||||
|
}
|
||||||
if (!declaredPermissions.includes("server.run.distribution")) {
|
if (!declaredPermissions.includes("server.run.distribution")) {
|
||||||
missing.push("server.run.distribution permission");
|
missing.push("server.run.distribution permission");
|
||||||
}
|
}
|
||||||
@@ -781,7 +786,8 @@ NODE
|
|||||||
printf 'registering SCUM plugin through platform API\n'
|
printf 'registering SCUM plugin through platform API\n'
|
||||||
register_plugin_manifest "SCUM plugin" "game.scum" "$WORK_DIR/register-scum-plugin.request.json" "$WORK_DIR/register-scum-plugin.response.json"
|
register_plugin_manifest "SCUM plugin" "game.scum" "$WORK_DIR/register-scum-plugin.request.json" "$WORK_DIR/register-scum-plugin.response.json"
|
||||||
reject_forbidden_fragments "$WORK_DIR/register-scum-plugin.response.json"
|
reject_forbidden_fragments "$WORK_DIR/register-scum-plugin.response.json"
|
||||||
require_scum_manifest_contract "$WORK_DIR/register-scum-plugin.response.json"
|
SCUM_PLUGIN_VERSION="$(node -e 'const fs=require("fs"); process.stdout.write(JSON.parse(fs.readFileSync(process.argv[1],"utf8")).version);' "$ROOT_DIR/plugins/examples/scum-server-plugin/manifest.json")"
|
||||||
|
require_scum_manifest_contract "$WORK_DIR/register-scum-plugin.response.json" "$SCUM_PLUGIN_VERSION"
|
||||||
|
|
||||||
printf 'waiting for run endpoint heartbeat\n'
|
printf 'waiting for run endpoint heartbeat\n'
|
||||||
for _ in $(seq 1 20); do
|
for _ in $(seq 1 20); do
|
||||||
|
|||||||
Reference in New Issue
Block a user