Apply selected server maps automatically without config overlays

This commit is contained in:
2026-09-17 11:05:01 -04:00
parent 1cd4eb6f09
commit 3f0d6dd87d
12 changed files with 431 additions and 59 deletions
+37
View File
@@ -14,6 +14,8 @@
// - Line endings default to \n for the composed output. Baseline CRLF is
// preserved if the baseline uses CRLF throughout.
import { T5_ZOMBIE_MAPS } from './map-aliases.js';
interface CfgLine {
kind: 'set' | 'raw';
key?: string;
@@ -122,3 +124,38 @@ export function composeCfg(baselineText: string, overlays: OverlayInput[]): stri
// matches upstream cfg conventions.
return bodyLines.join(parsed.eol) + parsed.eol;
}
/** Compose a server config, with its catalog map taking precedence over presets. */
export function composeServerCfg(
baselineText: string,
overlays: OverlayInput[],
game: string | null,
map: string | null
): string {
const composed = composeCfg(baselineText, overlays);
const selected = game === 't5' ? T5_ZOMBIE_MAPS.find((entry) => entry.canonical === map) : undefined;
// Legacy/unrecognized servers retain their existing config semantics.
if (!selected) return composed;
const eol = parseCfg(composed).eol;
const lines = composed.split(/\r?\n/);
lines.pop(); // composeCfg always emits a trailing newline.
const rotation = `set sv_maprotation "map ${selected.canonical}"`;
// Dvars are case-insensitive. Remove duplicate assignments, including
// seta and bare forms, so old map-choice overlays cannot undo selection.
const isRotation = /^\s*(?:(?:set|seta)\s+)?sv_maprotation\s+/i;
let applied = false;
const result: string[] = [];
for (const line of lines) {
if (!isRotation.test(line)) {
result.push(line);
} else if (!applied) {
result.push(rotation);
applied = true;
}
}
if (!applied) {
result.push('// Map selected by Electric Cherry', rotation);
}
return result.join(eol) + eol;
}