The install script fetches RunicNPC's tarball with the rest, checks it against
the bundle's sha256, its API against the bundle and its file against its own
manifest, and places RunicNPC.cs before the bridge. Its data directory is left
for RunicNPC to make (runicnpc PLAN.md §1.5). rust-link/bundle.json names it.
Walked against a mock Gitea with and without RunicNPC.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
Rust-Plugins now releases a ZoneManager helper, RunicGatewayZones.cs, beside
the bridge (docs/modules/rust/PLAN_FIXES.md D181, D182), installed by default.
The egg copied only RunicGateway.cs out of the tarball.
It now takes every .cs the plugin manifest lists in `files`, checks each
against its own sha256 before anything is placed (the bridge's own checksum
was never checked by the egg before), and refuses a name that is not a plain
<Name>.cs. A release older than helpers lists only the bridge and installs
exactly what it did before. Exercised in an Alpine shell against both, a
tampered helper, a missing one, `../evil.cs` and `evil.dll`.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
Module-rust phase 18, step 4 of docs/modules/rust/PLAN.md §34.2.7.
The Windows service (D149, §34.2.5): src/windows.rs, ported from link's fix
for error 1053. The same exe tries the SCM handshake and falls through to a
console run on 1063; it reports Running only once the listener and store are
up, and logs to a daily file beside its config. One binary serves every
RunicGatewayRust-<id> instance, because the SCM ignores the dispatcher's name
for an own-process service.
An empty environment variable now counts as unset. A Pterodactyl egg exports
every variable it declares, so a blank RUSTLINK_WEB_TOKEN arrived as "" and
overrode the saved token, and a new one was generated and persisted on every
boot. That breaks D152, which this change makes true.
The egg (R20, R22, D151, D152, §34.2.6), in egg/:
- install.sh is egg 18's script with two changes. A wipe guard moves
rust-link/ to /tmp around `rm -rf ${REMOVE_FILES}`. The bridge block then
fetches a schema-2 Rust bundle (pinnable by RUNICGATEWAY_BUNDLE), checks
every asset's sha256 and the plugin's protocol before placing anything, and
places the plugin by FRAMEWORK. Vanilla installs nothing and does not fail.
- with-sidecar.sh is the launcher. It unsets blank variables, builds the web
bind from RUSTLINK_WEB_PORT, and runs --print-config so that a newly
generated token is printed once. It prints the URL and server id for the
admin page, then execs the game. It no longer uses `set -e`: nothing the
bridge gets wrong may keep the game from booting.
- The startup's launcher prefix is conditional, so a server with no bridge
boots exactly as egg 18 does.
- build.sh assembles egg-rust-runicgateway.json. PR Checks runs it.
The release (D145, §34.2.1) reuses servuo-plugins' engine. It publishes the
static musl Linux binary, the Windows exe, the launcher, the egg and
SHA256SUMS, and dispatches the installer's bundle.yml. PR Checks gains a
clippy run for the Windows target.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY