five-on-it / apps/server/src/http
apps/server/src/http
The game server's HTTP endpoints and WebSocket routing, independent of the process:
GET /health: the default room's numbers (its level, game, tick, clients, bytes sent and its snapshots' figures undernet, road graph, AI) at the top level, as before rooms, every room underrooms, the loop's step times, and the WebRTC data channel's numbers underrtcwhen the server offers one (channels open and on their way, fall backs to the WebSocket).GET /metrics: the process's Prometheus metrics (metrics.ts), when it keeps them.GET /levels/<hash>.json: the level of an open room by its hash (level-files.ts), immutable and open to any page, for a client that connected with?levels=hash.POST /drainwith the room secret: the server drains for maintenance (its players told, its rooms closed at the deadline,restarting), then stops.- Admission (
capacity.ts): a server draining, past its players, too slow or at a cap of rooms it was given refuses a new room (503 to the API, saying why) and a level's room it would open (full, orroomsat that cap); a run's room also at its cap of runs (503, "takes no new run"); one draining refuses every connection (restarting). A room's place is held from the moment it is admitted (RoomHost.reserve, a run's counted as one), so rooms opened at the same time are counted against the caps before their artifacts and navigation come. GET /rooms: the open rooms.GET /runs/<id>: a debug run's result once it ended (debug-runs.ts).POST /roomsandDELETE /rooms/<id>: the platform API opens and closes rooms, with the room secret as a bearer token (only when the server has one:FOI_ROOM_SECRET).POST /rooms/<id>/seats(the room secret): the platform adds a seat to a room's run under way for a player it placed (aRunSeatSpec: 201{seat}, 409 when its team has no seat open, 404 for no such room, 400 for a body or an id that does not read).- The room secret is compared in constant time (
/drain,/roomsand every route under it): the digests of what came and of the secret, never the strings. - A WebSocket on
/(or any path but a room's) joins the default room (in the party itspartyparameter names, when the room's debug commands are on: two windows play a mission together without the platform; withrun=<mission>&team=<team>a seat in a run of the default room's game,debug-runs.ts), or with?level=<name>the room of that level that ships (level-rooms.ts: the main menu's level selection); one on/rooms/<id>?token=<join token>joins that room once the token checks out, as who the token says (an account, a name, a party; a run's seat). A run's room (run-host.ts) takes its roster alone: a token of another run, or of an account not on its roster or whose seat is gone for good, is refused like a voted-out one. A refused connection is closed with 4401 (no or a bad token), 4403 (the room voted that account out, or is a run's it is not on), 4404 (no such room), 4409 (the room is full), 4429 (a room it would have to open, at the cap of rooms the server was given:FOI_MAX_ROOMS) or 4430 (a debug run's room it would have to open, at its cap of runs:FOI_MAX_RUNS). - With
join: 'token'(FOI_JOIN=token: a platform for the game's owners), the default room and the levels' rooms ask for a join token too: a bare connection one for the roomdefault, one with?level=<name>one forlevel-<name>(what the platform'sGET /playsigns), checked before anything else, so a connection without one never makes the server open a level's room; it is closed with 4401. The token's account, name and party are the player's. Without it (open), a good token on such a connection gives only itsdebugclaim; the player is anyone otherwise, as before. - A token's
debugclaim (an account the platform'sFOI_DEBUG_ACCOUNTSnames) has that player's debug commands honoured in any room, whatever the room's own switch. - A public room asks the platform's moderation about each chat line (the URL its request named, with the room secret as a bearer token) before the room reads it.
- With a data channel host (
FOI_RTC=1), every connection a room takes is wrapped (rtc-transport.ts) and its welcome says the server offers the channel.