feat: add UE4SS DLL runtime extension
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-07-22
|
||||
@@ -0,0 +1,87 @@
|
||||
## Context
|
||||
|
||||
`game.scum` currently declares a Windows client-manager package that is built from a Git repository. The replacement is not a user-built executable: it is a publisher-built UE4SS `main.dll` that UE4SS loads into SCUM during the normal server process startup. The supplied RCON project requires UE4SS EngineTick and therefore cannot be loaded by an external EXE or attached safely to an already running SCUM process.
|
||||
|
||||
The Platform already owns plugin manifest validation, runtime binding selection, lifecycle job dispatch, and safe browser DTOs. Run already owns bounded HTTPS dependency downloads, scoped workspaces, direct executable vectors, and lifecycle process supervision. Neither currently has a typed server DLL extension plan or a real RCON adapter.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Let a plugin declare a prebuilt Windows UE4SS DLL release and update policy without exposing user-side compilation, arbitrary commands, host paths, or secrets.
|
||||
- Have Run synchronize the declared release automatically before each SCUM `process.start`, only after Platform has frozen the declaration into the leased job input.
|
||||
- Stage the DLL atomically below a logical server workspace, preserve the previous managed DLL for rollback, generate a local-only RCON configuration, and load through the normal UE4SS startup chain.
|
||||
- Expose safe declaration and synchronization state to the existing plugin/server management views.
|
||||
- Reject Linux for this Windows DLL extension explicitly.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- Do not run a compiler, CMake, UE4SS source checkout, or arbitrary executable on an operator machine.
|
||||
- Do not inject a live process, use `rundll32`, `LD_PRELOAD`, remote threads, manual mapping, or a generic DLL loader.
|
||||
- Do not claim a Linux `.dll` equivalent. A future Linux `.so` loader is a separate, game-specific change.
|
||||
- Do not delete or migrate existing client-manager installations automatically.
|
||||
- Do not add per-command confirmation or persisted raw-command history for the future RCON console.
|
||||
|
||||
## Decisions
|
||||
|
||||
### Decision: Model the payload as a Windows UE4SS DLL extension, not a client manager or executable
|
||||
|
||||
The manifest adds `runtimeProfiles.dllExtensions`. A ready profile has a fixed release URL/checksum/size/version, Windows amd64 target, compatible SCUM executable checksum, UE4SS ABI marker, logical target key, update policy, and loopback health contract. `kind` is fixed to `ue4ss-dll`, `activation` is fixed to `server-start`, and `supportedTargets` is fixed to Windows amd64. An explicit `unpublished` declaration may document an intended release URL but cannot be selected by a lifecycle profile or frozen into a job; this prevents placeholder hashes from reaching an operator machine.
|
||||
|
||||
The SCUM manifest declares the extension while retaining legacy client-manager metadata for existing installations. New server starts use the extension profile rather than building a companion executable.
|
||||
|
||||
Alternative considered: reuse `clientManagers`. Rejected because a UE4SS DLL is loaded by SCUM rather than supervised as an independent component process.
|
||||
|
||||
### Decision: Synchronize within the existing `process.start` lifecycle job
|
||||
|
||||
Platform copies the selected DLL extension plan into the fenced start-job execution input. Run performs sync before it launches the server executable. The job is the automatic update check: every start compares the installed managed release checksum/version with the declaration and updates only when necessary.
|
||||
|
||||
This avoids a new always-on download poller, preserves control/job/log/artifact channel isolation, and means Run never obtains unleased plugin configuration. A version change takes effect at the next normal server start. Future scheduled maintenance can queue an ordinary restart/start lifecycle job.
|
||||
|
||||
Alternative considered: let Run periodically poll plugin URLs directly. Rejected because it makes Run independently trust mutable plugin configuration and consumes network/resources outside Platform job fencing.
|
||||
|
||||
### Decision: Use release-pinned, scoped, atomic deployment
|
||||
|
||||
Run accepts only HTTPS URLs with a declared `sha256:` checksum and a bounded size. It downloads to a per-server extension staging root, verifies bytes before activation, and replaces only the managed DLL path atomically. It records a small local managed-release marker and retains one previous DLL copy for rollback. It never extracts archives, follows unsafe redirects, or accepts arbitrary target paths.
|
||||
|
||||
The generated `config.ini` contains a locally supplied RCON password reference/value only in the protected server workspace; it is not returned to Platform, plugins, browser DTOs, artifacts, or logs. `mods.txt` is updated idempotently using the exact declared extension key. UE4SS bootstrap files are not silently installed by this first change; the extension reports a blocked health result when the expected UE4SS layout is absent.
|
||||
|
||||
Alternative considered: download a whole UE4SS/bootstrap package on every server. Rejected for the first release because shared loader ownership and rollback across other mods requires a separate extension-runtime manager.
|
||||
|
||||
### Decision: Windows-only activation and explicit Linux rejection
|
||||
|
||||
The supplied module links Windows APIs and produces a `.dll`. Windows activation is the standard UE4SS startup path: the already-installed UE4SS loader reads `mods.txt` and loads the DLL after SCUM starts. Run does not mount or execute the DLL itself.
|
||||
|
||||
Linux would require a separately built `.so`, an independently verified UE4SS/Linux loader path, and game-specific compatibility. Run returns `unsupported_extension_platform` for this profile on Linux and does not try `LD_PRELOAD`.
|
||||
|
||||
### Decision: Address compatibility is owned by the DLL release
|
||||
|
||||
Native SCUM executor addresses are not configured in Platform or Run. The publisher-built DLL holds the vetted resolver table keyed by SCUM executable compatibility data and fails closed when its native probe cannot resolve exactly once. Platform/Run only select the right declared DLL release by compatible SCUM executable checksum.
|
||||
|
||||
Alternative considered: Run-side signature scanning or automatic generation. Rejected because it would make the executor a reverse-engineering authority and could execute an incorrect native address.
|
||||
|
||||
### Decision: Safe UI projections and no raw command history
|
||||
|
||||
Plugin detail and server detail show release version, checksum prefix, loading mode, supported target, update-on-start policy, last safe sync state, and Linux incompatibility. They do not show raw paths, URLs with credentials, RCON passwords, Run sessions, or native signatures. A future RCON console is direct operator input with transient delivery; it is not a confirmation dialog or a persisted command-history feature.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [A SCUM update changes native code] → DLL fails its internal probe; Run leaves the previous managed release in place and reports extension health unavailable rather than guessing an address.
|
||||
- [A malicious/changed CDN response] → checksum, HTTPS validation, bounded size, and staged verification block activation.
|
||||
- [UE4SS is not installed or incompatible] → sync completes the managed DLL only when safe, then reports a clear blocked health state; it does not copy proxy DLLs or alter shared loader files.
|
||||
- [A server host has multiple instances] → extension target and port are scoped by the existing server workspace/runtime binding; no global path is projected.
|
||||
- [Start job fails after update] → previous managed DLL is retained and a retry sees a coherent marker; full SCUM process rollback remains the existing lifecycle responsibility.
|
||||
- [Linux host selected] → the job is rejected before download and UI projects the unsupported platform state.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Register a new `game.scum` manifest version with a Windows UE4SS extension profile and preserve legacy client-manager declarations.
|
||||
2. On the next Windows start, Platform freezes the extension plan into the lifecycle job and Run syncs it before process launch.
|
||||
3. Operators ensure the approved UE4SS runtime is already present once; the DLL and generated configuration are then managed automatically.
|
||||
4. Roll back by publishing/reselecting the previous pinned DLL declaration and restarting the server; Run restores the previous managed DLL if activation fails.
|
||||
5. Existing client-manager installations are not stopped, deleted, or migrated automatically.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- A future change may manage the shared UE4SS bootstrap/runtime as a separately owned, reference-counted extension dependency.
|
||||
- A future Linux SCUM/UE4SS `.so` implementation requires its own compatibility and loader design.
|
||||
@@ -0,0 +1,33 @@
|
||||
## Why
|
||||
|
||||
The current SCUM plugin declares a separately built companion client, but the new SCUM RCON integration is a prebuilt UE4SS DLL that must load with the SCUM server process. Operators must not compile it, Run must not execute arbitrary binaries or inject a running process, and the platform currently has no declared, version-pinned DLL extension lifecycle.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add a plugin-declared Windows-only UE4SS DLL extension profile with a fixed HTTPS release URL, SHA-256 checksum, file size, compatible SCUM executable checksum, UE4SS ABI marker, logical deployment target, and loopback RCON health probe.
|
||||
- Freeze the declared extension plan into the existing fenced `process.start` job. Run stages the approved DLL, generated configuration, and deterministic `mods.txt` entry before the normal SCUM process starts; there is no independent sync job or background poller.
|
||||
- Add Run-side verified DLL synchronization with bounded HTTPS download, scoped file ownership, atomic replacement, rollback, no runtime process injection, and an explicit Linux rejection for the Windows DLL extension.
|
||||
- Surface declared extension metadata and safe per-server state in plugin and server management views. The UI shows the release/version/checksum/loading mode and that Linux is unsupported, without exposing host paths, RCON passwords, or Run credentials.
|
||||
- Replace the SCUM example's new-server dependency on the `scum-client-manager` path with the UE4SS RCON extension declaration. Existing client-manager records remain compatible and are not deleted by this change.
|
||||
- Provision the extension's loopback-only Source RCON configuration for the existing declared remote-access boundary. This change does not create a second command console, per-command confirmation, or raw-command history.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `plugin-runtime-dll-extensions`: Plugin manifest, Platform validation, safe projections, and server-start ordering for versioned Windows UE4SS DLL extensions.
|
||||
- `run-ue4ss-dll-synchronization`: Independent Run download, staging, activation, UE4SS configuration, health preconditions, and rollback behavior for an approved UE4SS DLL extension.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- None.
|
||||
|
||||
## Impact
|
||||
|
||||
- `plugins/`: manifest schema, validator, SCUM example declaration, and fixtures.
|
||||
- `platform/`: domain/DTO/validation/job contracts, server start dispatch, fenced extension-sync input, safe state projection, and API handlers.
|
||||
- `platform_web/`: API types and existing plugin/server detail surfaces for declared extension state.
|
||||
- Independent `run/`: protocol copies, extension-sync executor, generated local-only RCON configuration, tests, and documentation. It remains an independent Git repository and is not added to this repository.
|
||||
- No user-side compiler, arbitrary executable launch, runtime remote-process injection, Linux DLL support, raw host-path exposure, raw RCON-password exposure, or unrelated product areas are introduced.
|
||||
|
||||
The supplied CDN URL currently has no downloadable DLL. The SCUM example therefore carries an explicit unpublished declaration rather than an invented checksum, and it is not bound to `process.start` until the publisher supplies the real release pins. Ready declarations remain fully immutable and are the only declarations that can be frozen into a start job.
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Plugin declares a bounded Windows UE4SS DLL extension
|
||||
The plugin manifest SHALL support `runtimeProfiles.dllExtensions` entries only for a fixed `ue4ss-dll` kind, Windows amd64 target, `server-start` activation, logical target key, declared DLL relative path, and update-on-start policy. A `ready` release SHALL additionally have an HTTPS release URL, SHA-256 checksum, bounded byte size, SCUM executable checksum, and UE4SS ABI marker. An `unpublished` declaration MAY document an intended release URL but SHALL not be frozen into a start job. The manifest validator SHALL reject executable references, shell arguments, Linux targets, unsafe URLs, non-DLL paths, missing ready-release integrity metadata, and unsafe logical keys.
|
||||
|
||||
#### Scenario: Valid SCUM DLL declaration registers
|
||||
- **WHEN** `game.scum` registers a Windows UE4SS DLL extension with all required immutable release and compatibility fields
|
||||
- **THEN** Platform persists a typed declaration and exposes only a safe projection to browser clients.
|
||||
|
||||
#### Scenario: Unsafe DLL declaration is rejected
|
||||
- **WHEN** a manifest declares a non-HTTPS URL, missing checksum, Linux target, executable command, unsafe path, or missing compatibility checksum
|
||||
- **THEN** manifest validation rejects the registration before it is persisted.
|
||||
|
||||
#### Scenario: Unpublished SCUM release stays inactive
|
||||
- **WHEN** a plugin documents an unpublished UE4SS DLL release before the publisher has supplied its immutable release pins
|
||||
- **THEN** the declaration is safe to display but cannot be referenced by a server-start lifecycle profile or dispatched to Run.
|
||||
|
||||
### Requirement: Server start freezes the declared extension plan
|
||||
Platform SHALL add the selected compatible DLL extension plan to the fenced `process.start` Run job input. The frozen plan SHALL contain only logical target identifiers and release integrity/compatibility metadata, and SHALL reject a start when the selected runtime profile or endpoint platform does not support the extension.
|
||||
|
||||
#### Scenario: Compatible Windows server start includes extension plan
|
||||
- **WHEN** a Windows amd64 SCUM server with a selected compatible runtime profile is started
|
||||
- **THEN** its Run start job includes the current immutable DLL extension plan before process execution.
|
||||
|
||||
#### Scenario: Linux server is rejected without a download
|
||||
- **WHEN** a Linux endpoint is selected for a UE4SS DLL extension profile
|
||||
- **THEN** Platform rejects the extension path with an explicit unsupported-platform result and does not dispatch a DLL download.
|
||||
|
||||
### Requirement: Browser receives a safe extension projection
|
||||
Platform SHALL project extension key, display name, release version, checksum prefix, supported OS/architecture, loading mode, update-on-start policy, compatibility marker, and safe synchronization state to plugin and server management views. It SHALL NOT project RCON passwords, raw host paths, signed Run job data, native signatures, or raw local file metadata.
|
||||
|
||||
#### Scenario: Server detail renders declaration without secrets
|
||||
- **WHEN** an authorized operator views a SCUM plugin or server detail
|
||||
- **THEN** the UI displays safe DLL extension metadata and does not contain credentials, host paths, or native resolver data.
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Run synchronizes a frozen DLL plan before server start
|
||||
Run SHALL synchronize a declared UE4SS DLL extension before executing the associated `process.start` command. It SHALL compare the local managed-release marker against the frozen version/checksum, skip unchanged releases, and otherwise download, checksum-verify, stage, and atomically activate the declared DLL path within the scoped server workspace.
|
||||
|
||||
#### Scenario: Changed approved DLL updates before launch
|
||||
- **WHEN** a start job carries a valid extension plan whose release differs from the managed marker
|
||||
- **THEN** Run verifies and activates the new DLL before launching the server process.
|
||||
|
||||
#### Scenario: Unchanged approved DLL is reused
|
||||
- **WHEN** a start job carries the same version and checksum as the managed marker
|
||||
- **THEN** Run does not download the DLL again and proceeds to server launch.
|
||||
|
||||
### Requirement: Run preserves DLL deployment safety boundaries
|
||||
Run SHALL require HTTPS, a SHA-256 checksum, bounded content length, a safe logical target, and a declared `.dll` path. It SHALL write only managed extension files, retain one previous DLL for rollback, redact sensitive generated configuration, and never execute the DLL, inject a running process, load arbitrary libraries, or expose raw local paths/credentials through Platform-facing results.
|
||||
|
||||
#### Scenario: Invalid or mismatched payload does not activate
|
||||
- **WHEN** download fails, exceeds its byte limit, has a checksum mismatch, or the declared DLL path is unsafe
|
||||
- **THEN** Run keeps the prior managed DLL intact and returns a safe failed start result.
|
||||
|
||||
### Requirement: Run explicitly rejects Linux UE4SS DLL activation
|
||||
Run SHALL reject a `ue4ss-dll` extension plan when its local platform is not Windows amd64. It SHALL not attempt to map the DLL, invoke a shell loader, or substitute `LD_PRELOAD`.
|
||||
|
||||
#### Scenario: Linux extension start fails closed
|
||||
- **WHEN** a Linux Run receives a UE4SS DLL extension plan
|
||||
- **THEN** it returns `unsupported_extension_platform` before any download or process launch.
|
||||
|
||||
### Requirement: Extension synchronization does not block independent channels
|
||||
DLL download and verification SHALL run inside the claimed lifecycle job with bounded context while Run control heartbeat, job acknowledgement/result, cancellation polling, log spool upload, and artifact transfer remain independently scheduled.
|
||||
|
||||
#### Scenario: Slow DLL download preserves control and log traffic
|
||||
- **WHEN** a DLL download is blocked or slow during a start job
|
||||
- **THEN** Run continues its control heartbeat and durable log upload within their configured deadlines.
|
||||
@@ -0,0 +1,24 @@
|
||||
## 1. Plugin and Platform contracts
|
||||
|
||||
- [x] 1.1 Add the typed UE4SS DLL extension declaration to plugin schema, validator, fixtures, and the SCUM manifest with Windows-only compatibility metadata and an inactive unpublished-release guard.
|
||||
- [x] 1.2 Add domain, DTO, validator, and safe API projection types for declared DLL extensions and frozen start-job extension plans.
|
||||
- [x] 1.3 Freeze compatible extension plans into SCUM `process.start` jobs and reject incompatible Linux endpoint plans before Run dispatch.
|
||||
- [x] 1.4 Add focused Platform tests for registration, safe projection, start-job fencing, and unsupported-platform behavior.
|
||||
|
||||
## 2. Management console
|
||||
|
||||
- [x] 2.1 Extend typed frontend API/schema contracts for safe DLL extension declarations.
|
||||
- [x] 2.2 Render the declared Windows-only UE4SS extension and update-on-start policy in existing plugin/server detail surfaces without paths or secrets.
|
||||
- [x] 2.3 Add focused frontend tests for declaration rendering and Linux unsupported state.
|
||||
|
||||
## 3. Independent Run extension synchronization
|
||||
|
||||
- [x] 3.1 Mirror the frozen extension plan in the independent Run protocol and validate bounded, Windows-only DLL fields.
|
||||
- [x] 3.2 Implement scoped staged DLL download, checksum verification, managed-release marker, atomic activation, previous-DLL rollback, generated UE4SS mod configuration, and deterministic mods index update.
|
||||
- [x] 3.3 Gate `process.start` on extension synchronization and fail closed on non-Windows targets, unsafe payloads, or missing UE4SS layout without executing/loading the DLL directly.
|
||||
- [x] 3.4 Add Run unit tests for update/no-op/rollback/Linux rejection and channel independence.
|
||||
|
||||
## 4. Verification and delivery
|
||||
|
||||
- [x] 4.1 Run manifest, Platform, frontend, and Run focused tests; run `openspec validate add-scum-ue4ss-dll-runtime-extension --strict` and `scripts/check-structure.sh`.
|
||||
- [ ] 4.2 Review scoped diffs, stage only task files in browser and independent Run repositories, commit, and push both configured branches.
|
||||
Reference in New Issue
Block a user