Organize scripts and add TWS plugins with HTTP timeouts

Vendor pinned T5 and T6 plugin sources under the new plugins layout. Add native HTTP deadlines, status and timing diagnostics, telemetry integration, and build/test tooling.
This commit is contained in:
2026-10-09 11:02:20 -04:00
parent b172086301
commit 1121b44857
253 changed files with 28028 additions and 59 deletions
+145
View File
@@ -0,0 +1,145 @@
# T6 port notes
T6 is ported from T5. Both source trees contain common, HUD, AFK, join, lock,
telemetry and leaderboard modules; neither includes bank or database modules.
## Differences retained for T6 and requested fixes
| Area | Difference from T5 | Reason |
| --- | --- | --- |
| Paths | `maps/mp/_utility`, `scripts/zm/tws_t6_common` | T6 namespaces and requested filenames |
| Loading | No T5 `zombiemode` dvar gate; each module has `main()` and `init()` | Zombies-only folder loading; avoid r5346 missing-main warnings |
| HUD positioning | Fullscreen screen anchors, same 10-unit margin | Requested fix for inset HUD |
| HUD rendering | Precached white shader, local max-health fallback, floating-point ratio, `getPlayers()` | T6 rendering/state handling without changing player max health |
| Enemy count | Stock `_zm_utility::get_current_zombie_count()` plus queued zombies | Uses the map's zombie team and enemy filters |
| Timers | Seed elapsed time for late joiners; stop round watcher/reset on game over | T6 timer behavior; keep frozen timers frozen |
| AFK | Maintain control freeze, disable guns/grenades, guard player state and stale grace threads | Requested movement/shooting fix; retain `.afk` / `.back` and two-second grace |
| Telemetry | Global `httpPost(url, options)`; T5-parity queue + heartbeat + game_start/end + watchdog + log-level dvar; per-player `guid` sources from Plutonium's `player.guid` engine property (T5 uses `player getGuid()` method); per-match `kills`/`headshots`/`downs`/`revives` read from `player.pers[]`, with missing or negative values reported as `0` | T6 has no `getGuid` method but exposes the persistent identity as `.guid` on the player entity; stock `initpersstat` / `incpersstat` maintain match counters in `player.pers[]`, whereas T5 uses `player.stats[]`. Payload keys match T5 for downstream shape parity |
| Join | Port of T5 `tws_t5_join.gsc`; uses `level.spawnplayer` / `level.custom_spawnplayer` (lowercase) and `maps\mp\zombies\_zm::spectator_respawn`; readiness gated on `self.sessionstate == "spectator"` instead of T5's `self.initialized` | T6 stock spectator respawn hook lives in `_zm.gsc`; `self.initialized` is a T5 SP zombiemode marker that T6 stock does not populate the same way |
Common retains the T5 HUD constants, helpers and first-spawn dispatcher.
HUD again owns the `hud_game_over` notification fan-out. Lock again waits on HUD
notifications, applies T5's random password, and clears it on startup/game over.
The added password-preservation dvars and independent lock watcher are gone.
Common also listens for `.help` through the native `say` notification, independent
of first-spawn initialization so newcomers can view commands while spectating.
Each loaded command module registers its command and description with
`register_help_command()` during `init()`. Lazy registry initialization preserves
registrations regardless of module initialization order. Help uses client HUD
elements below the health bar, sharing the HUD's anchors to avoid overlap with
timers, zombie count and health numbers. Text is created once per connection and
reused; each request restarts a 12-second visibility timer. Disconnect cleanup
is independent of that timer. The command handlers retain their existing listeners.
AFK again listens to the native `say` notification, so it no longer needs plugin
chat registration. The additional T6 controls are only held while AFK; `.back`
releases them before the protection grace period. Restoration is deferred during
death/laststand/intermission until active play. Other mods controlling the same
invulnerability or weapon flags can still conflict and need live testing.
The existing optional T5 dvars remain. Leaderboard adds the three settings
documented in the [shared README](../../README.md#map-record-announcements).
`common_config()` and `ensure_config()` are original T5 in-memory HUD helpers,
not an external configuration system.
## Leaderboard join announcements
The module is `tws_t6_leaderboard.gsc` in T6 and `tws_t5_leaderboard.gsc` in T5.
Common's existing
connection listener now also dispatches optional connection handlers after a
one-frame yield. Leaderboard waits for player readiness and uses a level-owned
HTTP cache, independent of the first-playable-spawn handlers. T6 spectators keep
`hasSpawned` false, so T6 readiness uses session state and the intro-screen flag;
T5 sets `hasSpawned` for both playable and spectator spawns.
T6's active `scr_zm_ui_gametype` / `scr_zm_map_start_location` fields come from
[stock `_zm.gsc`](https://github.com/plutoniummod/t6-scripts/blob/2d8440321602f22f63f5335817110d60ddf223d5/ZM/Core/maps/mp/zombies/_zm.gsc).
Mode/location combinations follow the
[T6 server configurations](https://github.com/xerxes-at/T6ServerConfigs/tree/master/localappdata/Plutonium/storage/t6/gamesettings)
and Electric Cherry's map catalogue. Unknown selections require an explicit API
key instead of falling back to another variant sharing the engine map.
Validation for this change: 135 fixture/static checks pass using the actual
data-handling functions from both scripts with JavaScript engine-value shims.
All seven T6 scripts compile and assemble using a local Intel macOS driver built
from gsc-tool 1.5.1 sources. PowerShell was unavailable, so `check.ps1` itself was
not executed here. T5 compilation and live plugin/gameplay checks were not run;
gsc-tool has no T5 backend. The production API could not be reached from this
environment. See the shared README for the live validation cases.
## Verified primary sources
- [Plutonium loading guide](https://plutonium.pw/docs/modding/loading-mods/): T6
source scripts load from `storage/t6/scripts/zm`.
- [Entry-point lifecycle](https://plutonium.pw/docs/modding/gsc/new-scripting-features/):
`main()` runs early; `init()` runs after gametype startup. Empty `main()` must
not call `init()` and duplicate initialization.
- [Plutonium changelog, r2234](https://plutonium.pw/docs/changelog/): documents T6
`level waittill("say", message, player)`.
- [Stock T6 Zombies](https://github.com/plutoniummod/t6-scripts/blob/2d8440321602f22f63f5335817110d60ddf223d5/ZM/Core/maps/mp/zombies/_zm.gsc):
round state, `end_game`, invulnerability, and stock control resets.
- [Stock zombie utility](https://github.com/plutoniummod/t6-scripts/blob/2d8440321602f22f63f5335817110d60ddf223d5/ZM/Core/maps/mp/zombies/_zm_utility.gsc):
map-aware enemy counting.
- [Released plugin HTTP implementation](https://github.com/alicealys/t6-gsc-utils/blob/v3.1.1/src/component/http.cpp):
global `httpPost(url, options)` takes an options array with `body` and `headers`.
Its positional README example does not match this implementation.
Completion is `done(response, success, error)`; success reports transport only.
- [Plugin JSON implementation](https://github.com/alicealys/t6-gsc-utils/blob/v3.1.1/src/component/json.cpp):
`jsonSerialize` handles the event payload.
Do not create a dummy `http.gsc`. An unresolved `httpPost`/`jsonSerialize` means
the installed server/plugin must be checked. Installing a DLL requires a full
server-process restart, not just a map restart.
## Telemetry reboot investigation
The T5 and T6 implementations are not runtime-verified equivalents. In particular,
[T6 plugin v3.0.4](https://github.com/alicealys/t6-gsc-utils/blob/v3.0.4/src/component/http.cpp)
expects `httpPost(url, body, headers)` and notifies only the response body;
v3.1.1 expects `httpPost(url, options)` and also provides success/error values.
The current script targets the [TWS build](../plugins/README.md) based on v3.1.1,
which appends diagnostics and enforces native HTTP deadlines. Switching the function name does not establish
compatibility with an unknown installed DLL.
Console markers identify `main`, `init`, round serialization, HTTP invocation,
handle return and completion. They do not log the URL or response body. If startup
fails before `main`, inspect the first linker/plugin error, not the last supervisor
restart message. If no occupied positive round was observed, this script has not
called JSON serialization or HTTP yet.
Earlier live validation: the operator confirmed successful server startup and
Fleet delivery with the original direct reporter. The earlier reboot cause was
not established; logging alone should not be treated as a proven fix.
To recover the server while investigating, move `tws_t6_telemetry.gsc` outside the
autoload directory. The enable dvar cannot bypass unresolved native functions
at link time. The other four TWS modules can run without telemetry.
## Checks
Local: `tools/check.ps1` compiles all seven files for T6 PC and checks shared
references and entry points. It requires PowerShell and gsc-tool. The `.help`
change passed the static entry-point/reference checks, but compilation and live
gameplay were not run. Compiler success does not certify runtime linking.
Live checks after deploying:
1. Join, late-join, die/respawn, and reconnect: one HUD per player, correct corner
position, health/Juggernog changes, zombies remaining, timers frozen at game over.
2. `.afk` blocks movement, shooting and grenades; `.back` restores them. Try rapid
toggles, a round transition, death/respawn and game over.
3. Lock fires at the threshold and clears on game over/restart. HUD must be installed.
T5 semantics intentionally clear an existing password at startup.
4. Telemetry sends the initial occupied round and each new round to the existing
endpoint. Check server ID/player count, same-round joins and an unreachable API.
5. Repeat on the actual server maps, especially afterlife and special-enemy rounds.
6. Type `.help` and `.HELP` before first spawn, during play and while AFK: see
`.help`, `.afk`, `.back` and `.join` with descriptions, only on the requesting
player's screen below the health bar. Take damage so health numbers appear
and verify they do not overlap help. Repeat the command before 12 seconds
elapse: one list should remain visible until 12 seconds after the latest
request. Reopen after expiry and reconnect; verify no duplicates or leftovers.
Remove the AFK or Join module, restart the map and confirm its commands are
absent. Restore the modules and confirm `.afk`, `.back` and `.join` still
behave as before.