69 lines
2.6 KiB
JavaScript
69 lines
2.6 KiB
JavaScript
import { spawn } from 'node:child_process';
|
|
import { existsSync, readFileSync } from 'node:fs';
|
|
import { join } from 'node:path';
|
|
import { serverInstallDir } from './paths.js';
|
|
const STEAMCMD_PATH = process.env.STEAMCMD_PATH || '/opt/steamcmd/steamcmd.sh';
|
|
const WINDROSE_APP_ID = Number(process.env.WINDROSE_APP_ID || '4129620');
|
|
function getSteamLoginArgs() {
|
|
const username = process.env.STEAM_USERNAME;
|
|
const password = process.env.STEAM_PASSWORD;
|
|
const gslt = process.env.STEAM_GSLT;
|
|
if (!username) {
|
|
throw new Error("STEAM_USERNAME is required but not set.");
|
|
}
|
|
// Prefer GSLT if provided (safer for headless servers)
|
|
if (gslt) {
|
|
return ['+login', username, gslt];
|
|
}
|
|
if (!password) {
|
|
throw new Error("STEAM_PASSWORD is required but not set (or provide STEAM_GSLT).");
|
|
}
|
|
return ['+login', username, password];
|
|
}
|
|
export function runSteamCmd(args) {
|
|
// === ENV DEBUG START ===
|
|
console.log("=== ENV DUMP START ===");
|
|
console.log("STEAM_USERNAME =", process.env.STEAM_USERNAME);
|
|
console.log("STEAM_PASSWORD =", process.env.STEAM_PASSWORD);
|
|
console.log("STEAM_GSLT =", process.env.STEAM_GSLT);
|
|
console.log("=== ENV DUMP END ===");
|
|
// === ENV DEBUG END ===
|
|
return new Promise((resolve, reject) => {
|
|
const child = spawn(STEAMCMD_PATH, args, {
|
|
env: process.env,
|
|
});
|
|
child.stdout.on('data', (d) => process.stdout.write(d));
|
|
child.stderr.on('data', (d) => process.stderr.write(d));
|
|
child.on('exit', (code) => {
|
|
if (code === 0)
|
|
resolve();
|
|
else
|
|
reject(new Error(`SteamCMD exited with code ${code}`));
|
|
});
|
|
child.on('error', reject);
|
|
});
|
|
}
|
|
export async function installOrUpdateServer(id, appId) {
|
|
const installDir = serverInstallDir(id);
|
|
const steamArgs = [
|
|
'+force_install_dir', installDir,
|
|
...getSteamLoginArgs(),
|
|
'+app_update', String(appId), 'validate',
|
|
'+quit',
|
|
];
|
|
await runSteamCmd(steamArgs);
|
|
}
|
|
export async function readInstalledVersion(id) {
|
|
const installDir = serverInstallDir(id);
|
|
const manifestPath = join(installDir, 'steamapps', `appmanifest_${WINDROSE_APP_ID}.acf`);
|
|
if (!existsSync(manifestPath))
|
|
return null;
|
|
const raw = readFileSync(manifestPath, 'utf-8');
|
|
const buildIdMatch = raw.match(/"buildid"\s+"(\d+)"/);
|
|
const timeUpdatedMatch = raw.match(/"LastUpdated"\s+"(\d+)"/);
|
|
return {
|
|
buildId: buildIdMatch ? Number(buildIdMatch[1]) : null,
|
|
lastUpdated: timeUpdatedMatch ? Number(timeUpdatedMatch[1]) : null,
|
|
};
|
|
}
|