125 lines
7.4 KiB
Markdown
125 lines
7.4 KiB
Markdown
# tws-zombies-scripts
|
|
|
|
Combined working repo for the TWS Plutonium Zombies GSC scripts across two games.
|
|
|
|
## Layout
|
|
|
|
- [t5/](t5/) — Plutonium **T5** (Call of Duty: Black Ops 1) Zombies scripts. Most-developed baseline. See [t5/README.md](t5/README.md) and [t5/NOTES.md](t5/NOTES.md).
|
|
- [t6/](t6/) — Plutonium **T6** (Call of Duty: Black Ops 2) Zombies scripts. Ported from T5; at parity on common, HUD, AFK, lock, telemetry, join and leaderboard. See [t6/README.md](t6/README.md), [t6/NOTES.md](t6/NOTES.md), and [t6/tools/check.ps1](t6/tools/check.ps1).
|
|
|
|
## Parity
|
|
|
|
T5 and T6 are separate source trees, not a shared library — GSC namespaces, includes, and stock APIs differ enough between the two engines that a shared file is not practical. Feature parity is enforced pairwise: a change landed in `t5/` should be considered for a companion change in `t6/`, adapted to T6 conventions.
|
|
|
|
Modules currently in each tree:
|
|
|
|
| Module | T5 | T6 |
|
|
|------------|-------------------------------|---------------------------------|
|
|
| common | `t5/tws_t5_common.gsc` | `t6/tws_t6_common.gsc` |
|
|
| hud | `t5/tws_t5_hud.gsc` | `t6/tws_t6_hud.gsc` |
|
|
| afk | `t5/tws_t5_afk.gsc` | `t6/tws_t6_afk.gsc` |
|
|
| lock | `t5/tws_t5_lock.gsc` | `t6/tws_t6_lock.gsc` |
|
|
| telemetry | `t5/tws_t5_telemetry.gsc` | `t6/tws_t6_telemetry.gsc` — queued `game_start` / `heartbeat` / `round_change` / `game_end` matching T5 |
|
|
| join | `t5/tws_t5_join.gsc` | `t6/tws_t6_join.gsc` |
|
|
| leaderboard | `t5/tws_t5_leaderboard.gsc` | `t6/tws_t6_leaderboard.gsc` |
|
|
|
|
## Map record announcements
|
|
|
|
Install `tws_t5_leaderboard.gsc` for T5 or `tws_t6_leaderboard.gsc` for T6,
|
|
**along with the updated common module** for that game.
|
|
The new module privately announces the current map's fleet-wide highest recorded
|
|
round and every tied holder once per connection, including spectator newcomers.
|
|
It reads Electric Cherry's public `/api/leaderboard` endpoint without a token;
|
|
only completed matches contribute. Ties may come from the same run or separate
|
|
runs. Names are the API's latest player names, with players identified by GUID.
|
|
|
|
Both versions default to `https://ec.thewrightserver.net/api/leaderboard`.
|
|
T5 discovers the map by engine identifier. T6 selects the exact variant using
|
|
the active mode/location, so Town Survival, TranZit and Town Grief stay separate.
|
|
See the game READMEs for plugin requirements and installation paths.
|
|
|
|
| Dvar | Default | Purpose |
|
|
| --- | --- | --- |
|
|
| `tws_leaderboard_enabled` | enabled | `0` disables announcements and requests |
|
|
| `tws_leaderboard_url` | endpoint above | Full HTTPS API endpoint, without query parameters |
|
|
| `tws_leaderboard_map_key` | automatic | Exact, decoded API map key when automatic selection is unavailable |
|
|
|
|
For example, `set tws_leaderboard_map_key "t6:zm_transit:town"` explicitly
|
|
selects Town Survival. Normally this setting is unnecessary. An override must
|
|
exist in the API's map list and match the current game and engine map. Clear it
|
|
when changing variants; restart the map after changing these settings.
|
|
|
|
The announcement starts five seconds after player readiness and waits for the
|
|
initial record fetch if necessary. It appears in the same HUD area as `.help`,
|
|
below the health bar, with a heading such as `Record: Round 23` and holder names
|
|
underneath. Each page shows up to three holder lines for 12 seconds. Opening
|
|
`.help` hides the record and pauses its display time until help closes.
|
|
All holders are included; colour/control codes are removed, and unusually long
|
|
names are shortened to keep messages readable. HUD elements are removed when
|
|
the announcement finishes, the player disconnects, or the game ends.
|
|
|
|
One level worker fetches the map list and pages of three players, stopping when
|
|
the highest-round tie ends. Successful snapshots refresh every five minutes.
|
|
Failures retry after 30 seconds and retain the last complete snapshot for up to
|
|
15 minutes. An empty selection says “No recorded high round yet”; unavailable,
|
|
malformed or ambiguous results are logged and skipped when no usable cache exists.
|
|
Partial page results never replace the cache. The API has no pagination snapshot
|
|
token: changed totals/record rounds reject the refresh, but concurrent renames can
|
|
still move entries between pages. Refreshes deduplicate GUIDs.
|
|
|
|
Requests have a 15-second GSC wait limit. The plugins cannot cancel a native
|
|
request, so a stalled request prevents new leaderboard requests until it finishes;
|
|
player threads never wait directly on HTTP. Responses at the plugins' 20 KiB
|
|
truncation boundary are rejected. The complete JSON grammar, UTF-8, string escapes
|
|
and response shape are checked before consuming data. These guards also reject
|
|
HTML/error bodies; the plugins do not expose HTTP status or response headers.
|
|
|
|
Run the portable data/structure checks with `node tools/check_leaderboard.mjs`.
|
|
They execute the scripts' data helpers with engine-value shims, not a game VM.
|
|
Live checks: join while playing and spectating; die/respawn (no repeat); reconnect
|
|
(one new announcement); compare Town/TranZit/Grief; check one holder, ties across
|
|
pages, no records, and a slow/unavailable/malformed API. Disconnect or end the game
|
|
mid-announcement and confirm messages stop. Verify existing HUD, `.help`, `.join`
|
|
and telemetry still work. Open `.help` during a record page and check that the
|
|
record resumes afterwards without overlapping it. Runtime linking and client
|
|
readiness require Plutonium.
|
|
|
|
## Telemetry authentication (T5 and T6)
|
|
|
|
Both reporters default to `https://ec.thewrightserver.net/api/telemetry` and send
|
|
`Authorization: Bearer <token>` plus `Content-Type: application/json` on every
|
|
POST. Existing event fields and queue behavior are unchanged. An explicit
|
|
`tws_telemetry_url` override must also use HTTPS; remove any old HTTP override.
|
|
|
|
Before upgrading the API or loading these reporters:
|
|
|
|
1. Set the Electric Cherry service's **environment variable**
|
|
`EC_TELEMETRY_TOKEN` to a separate shared secret of at least 32 characters.
|
|
A missing service token disables ingestion.
|
|
2. Both telemetry scripts embed the matching reporter secret in
|
|
`level.telemetry_token`. No game-server token dvar or private config is needed.
|
|
3. Keep `tws_server_id` set to the exact registered server name, then restart
|
|
the map. Both reporters refuse to start with a short embedded token or a
|
|
non-HTTPS URL. Rotating the service token requires editing the token in both
|
|
scripts, deploying them to every game server, and restarting the maps.
|
|
|
|
The API also accepts `X-EC-Telemetry-Token`; these reporters use Bearer auth.
|
|
Cookies, query parameters, and JSON fields cannot authenticate telemetry.
|
|
Missing or incorrect request tokens are rejected before payload parsing or
|
|
recording. Reporters that cannot set headers need a trusted relay with an HTTPS
|
|
reporter-facing endpoint. The plugins used here accept a headers array.
|
|
|
|
After deployment, verify all four event types reach Electric Cherry. On a test
|
|
server, also verify that a short embedded token and an HTTP URL prevent startup,
|
|
that a wrong token is rejected without recording an event, and that deploying
|
|
the correct token restores ingestion. Plugin transport completion alone does
|
|
not prove API acceptance; inspect the API response or ingestion records.
|
|
|
|
## Validating T6
|
|
|
|
```powershell
|
|
powershell -File t6/tools/check.ps1
|
|
```
|
|
|
|
Requires `gsc-tool` 1.4.10 (T6 PC) on PATH.
|