78 lines
7.5 KiB
Markdown
78 lines
7.5 KiB
Markdown
## Context
|
|
|
|
The prior UE4SS DLL change provisions `ue4ss/Mods/scum_simple_rcon/config.ini` before a normal SCUM start, but the declared Run `rcon` adapter is only an envelope placeholder. The shipped DLL is a Source RCON server that is intentionally loopback-only and accepts raw SCUM commands on its game-thread queue; `SendChat <type> "message" [SteamID64]` is its supported chat form.
|
|
|
|
Platform and Run already use leased jobs, signed Run-only input routes, scoped workspaces, and durable job state. Sending a raw admin command through the generic remote-adapter `inputs` map would persist it in the Platform job and Run journal, conflicting with the requested no-history/no-audit behavior.
|
|
|
|
## Goals / Non-Goals
|
|
|
|
**Goals:**
|
|
|
|
- Let an authorized server operator send a typed chat message or raw SCUM command through the existing job channel without a second confirmation or command audit record.
|
|
- Transfer a command exactly once to the active leased Run worker without storing the raw text or RCON password in Platform persistence, job assignments, Run journals, browser DTOs, logs, or result messages.
|
|
- Bind every dispatch to a ready, selected Windows amd64 UE4SS DLL declaration and a fixed Source RCON loopback plan.
|
|
- Have Run authenticate to `127.0.0.1` using the protected generated config and implement the Source RCON wire protocol with bounded I/O.
|
|
|
|
**Non-Goals:**
|
|
|
|
- Do not modify, build, or redeploy the UE4SS DLL source as part of command transport.
|
|
- Do not create a generic remote TCP/RCON gateway, expose an RCON host or password, or allow browser-to-Run sockets.
|
|
- Do not persist raw command text, chat text, source responses, a command history, or per-command audit events.
|
|
- Do not retry a mutating command automatically, provide a Linux `.dll` fallback, or implement a separate Linux UE4SS `.so` runtime.
|
|
|
|
## Decisions
|
|
|
|
### Decision: Use a dedicated typed SCUM RCON request instead of generic remote-adapter inputs
|
|
|
|
Platform will expose a typed server-scoped request that accepts either a chat payload (`type`, message, optional SteamID64) or a bounded raw command. It validates the source DLL grammar and formats chat as `SendChat` internally. It validates ownership, the declared RCON capability, selected runtime binding, ready extension release, Windows amd64 endpoint, and the selected profile's RCON transport before it creates a job.
|
|
|
|
The job contains only an opaque input reference and a frozen `source-rcon` connection plan: extension key/mod key, logical config reference, and port. It contains no host, command, response, or secret. The existing generic remote-adapter endpoint remains suitable for declared non-secret inputs but is not used for raw SCUM commands.
|
|
|
|
Alternative considered: put `command` in `ExecutionInput.Inputs`. Rejected because Platform persistence, job claims, and Run's durable journal would retain the command.
|
|
|
|
### Decision: Use a one-time in-memory input broker fenced by the active Run lease
|
|
|
|
Platform stores each validated command in a mutex-protected, TTL-bounded in-memory broker before the corresponding job becomes claimable. The broker key is the job ID and cannot overwrite an outstanding submission with the same idempotency key. The signed Run-only RCON-input route first verifies endpoint, session, job, lease, attempt, capability, and frozen plan, then consumes and removes the payload.
|
|
|
|
The RCON job has exactly one attempt. A Platform restart, expired broker entry, worker crash after consume, or repeat input read fails closed rather than replaying a possibly mutating game command. Job/audit/result summaries use only generic delivery state.
|
|
|
|
Alternative considered: encrypting a durable broker row. Rejected because the explicit product boundary is no raw command persistence; encryption would still create history and recovery/replay semantics.
|
|
|
|
### Decision: Freeze a source-RCON loopback plan from the selected ready UE4SS extension
|
|
|
|
Platform derives the config reference from the extension's declared DLL layout (`ue4ss/Mods/<modKey>/config.ini`) and freezes the published port plus mod/extension identity. Because the actual SCUM executable may be below the workspace root, Run also owns a verified deployment-state marker that records the scoped logical config location written during DLL activation. The frozen plan carries only that safe marker reference; Run validates its extension/mod/port and expected config suffix before it reads the protected file. Run accepts only the `source-rcon` kind, Windows amd64, safe logical references, and an unprivileged declared port. There is no configurable host; Run always dials `127.0.0.1:<port>` in the server's scoped workspace.
|
|
|
|
The generator is corrected to write the DLL's actual `bind_address=127.0.0.1` setting. Run rejects a managed config whose port or bind address no longer matches the frozen plan.
|
|
|
|
Alternative considered: resolve paths or credentials in Platform. Rejected because Platform must not receive host paths or the generated RCON password.
|
|
|
|
### Decision: Treat Source RCON result bodies as sensitive transient data
|
|
|
|
Run authenticates, executes one command, and reads bounded response packets until the DLL's empty response sentinel. It classifies an `error:` response as a failed job but returns only a safe status/error code; it never includes raw command text, password, or response body in logs, artifacts, result messages, or Platform-facing payloads.
|
|
|
|
Alternative considered: stream full RCON output to the browser. Rejected because source responses may echo command text or game/player data and would reintroduce command history through job results/logs.
|
|
|
|
### Decision: Give the management console two direct entry points
|
|
|
|
The existing server detail surface gets a compact chat form and a raw-command form. Both submit immediately using typed API contracts and display only the current safe queue/result status. They intentionally do not add a confirmation modal, saved form history, command list, secret field, host field, or response transcript.
|
|
|
|
## Risks / Trade-offs
|
|
|
|
- [Platform or worker restarts during a command] → the broker payload is gone or consumed; the job fails closed and an operator can explicitly submit a new command.
|
|
- [SCUM/UE4SS is not loaded or the port is unavailable] → Run returns a safe connection/auth/protocol failure without falling back to a remote address.
|
|
- [An RCON response echoes sensitive input] → Run only classifies it and does not surface the body.
|
|
- [A user submits an unsupported chat target or malformed text] → Platform rejects it before a job/broker entry is created.
|
|
- [A DLL declaration is still unpublished] → the feature stays unavailable until real immutable release pins are published and selected.
|
|
|
|
## Migration Plan
|
|
|
|
1. Deploy Platform, Run, plugin manifest, and management-console changes together.
|
|
2. Publish a real ready DLL declaration, ensure the Windows UE4SS bootstrap is present, and restart SCUM so Run writes the managed loopback config.
|
|
3. Verify `rcon.status` or a harmless `rcon.chat` through the console on a non-production server, then send a broadcast and an allowed admin command.
|
|
4. Roll back by removing the new Run capability/using the previous Platform and Run releases; no persistent commands or secrets require migration or cleanup.
|
|
|
|
## Open Questions
|
|
|
|
- The current SCUM manifest is intentionally unpublished; end-to-end production dispatch remains gated until the publisher supplies the real DLL URL, checksum, size, executable checksum, and UE4SS ABI.
|
|
- Future command-output streaming would need a separate transient, authorization-reviewed design rather than reusing durable job results.
|