feat(facade): append rcon_password as final server.cfg line
Source cvar semantics are last-wins; appending the rcon_password after all overlay exec lines and blueprint config ensures no overlay or user config line can silently override it. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
83d2a9932c
commit
2a440dae45
2 changed files with 48 additions and 1 deletions
|
|
@ -44,11 +44,16 @@ def build_server_spec_payload(
|
|||
for overlay_id, _, expose in reversed(overlay_rows)
|
||||
if expose
|
||||
]
|
||||
config_lines: list[str] = exec_lines + json.loads(blueprint.config)
|
||||
# rcon_password is appended LAST so neither overlays nor user blueprint
|
||||
# config can override it (Source's cvar semantics are last-wins).
|
||||
if server.rcon_password:
|
||||
config_lines.append(f'rcon_password "{server.rcon_password}"')
|
||||
return {
|
||||
"port": server.port,
|
||||
"overlays": overlays,
|
||||
"arguments": json.loads(blueprint.arguments),
|
||||
"config": exec_lines + json.loads(blueprint.config),
|
||||
"config": config_lines,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -343,3 +343,45 @@ def test_initialize_fails_fast_on_uncached_workshop_items(
|
|||
assert all("initialize" not in cmd for cmd in invocations), invocations
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# build_server_spec_payload — rcon_password injection
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def _make_server_blueprint(rcon: str = "") -> tuple[Server, Blueprint]:
|
||||
bp = Blueprint(
|
||||
id=1, user_id=1, name="bp",
|
||||
arguments='["-tickrate","60"]',
|
||||
config='["sv_consistency 1","mp_gamemode coop"]',
|
||||
)
|
||||
srv = Server(
|
||||
id=1, user_id=1, blueprint_id=1, name="s", port=27500,
|
||||
rcon_password=rcon,
|
||||
)
|
||||
return srv, bp
|
||||
|
||||
|
||||
def test_build_server_spec_payload_appends_rcon_password_last() -> None:
|
||||
from l4d2web.services.l4d2_facade import build_server_spec_payload
|
||||
|
||||
srv, bp = _make_server_blueprint(rcon="topsecret123")
|
||||
overlays = [(7, "/overlays/7", True), (8, "/overlays/8", False)]
|
||||
spec = build_server_spec_payload(srv, bp, overlays)
|
||||
|
||||
cfg = spec["config"]
|
||||
# rcon_password line is the LAST entry — overlay exec lines + blueprint
|
||||
# config + rcon_password.
|
||||
assert cfg[-1] == 'rcon_password "topsecret123"'
|
||||
# Lines before our injection still contain the blueprint config.
|
||||
assert "sv_consistency 1" in cfg
|
||||
assert "mp_gamemode coop" in cfg
|
||||
|
||||
|
||||
def test_build_server_spec_payload_omits_rcon_password_when_empty() -> None:
|
||||
from l4d2web.services.l4d2_facade import build_server_spec_payload
|
||||
|
||||
srv, bp = _make_server_blueprint(rcon="")
|
||||
spec = build_server_spec_payload(srv, bp, [])
|
||||
for line in spec["config"]:
|
||||
assert not line.startswith("rcon_password ")
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue