onelobby 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +2 -2
  2. package/dist/direct/hub.d.ts +2 -0
  3. package/dist/direct/hub.js +20 -1
  4. package/dist/direct/hub.js.map +1 -1
  5. package/dist/friendly.d.ts +1 -0
  6. package/dist/friendly.js +2 -0
  7. package/dist/friendly.js.map +1 -1
  8. package/dist/index.d.ts +0 -2
  9. package/dist/index.js +0 -2
  10. package/dist/index.js.map +1 -1
  11. package/dist/lobby.d.ts +29 -1
  12. package/dist/lobby.js +26 -6
  13. package/dist/lobby.js.map +1 -1
  14. package/dist/nostr/limits.d.ts +2 -0
  15. package/dist/nostr/limits.js +2 -0
  16. package/dist/nostr/limits.js.map +1 -1
  17. package/dist/nostr/relays.js +11 -1
  18. package/dist/nostr/relays.js.map +1 -1
  19. package/dist/onelobby.bundle.js +10 -10
  20. package/dist/onelobby.bundle.js.map +4 -4
  21. package/dist/onelobby.bundle.mjs +10 -10
  22. package/dist/onelobby.bundle.mjs.map +4 -4
  23. package/dist/onelobby.d.ts +1 -1
  24. package/dist/onelobby.global.js +79 -19
  25. package/dist/onelobby.global.js.map +3 -3
  26. package/dist/onelobby.global.min.js +10 -10
  27. package/dist/onelobby.global.min.js.map +4 -4
  28. package/dist/onelobby.js +10 -1
  29. package/dist/onelobby.js.map +1 -1
  30. package/dist/signaling.d.ts +2 -0
  31. package/dist/signaling.js.map +1 -1
  32. package/dist/socket.d.ts +15 -6
  33. package/dist/socket.js.map +1 -1
  34. package/dist/testing.d.ts +2 -0
  35. package/dist/testing.js +18 -2
  36. package/dist/testing.js.map +1 -1
  37. package/dist/transport.d.ts +2 -0
  38. package/dist/transport.js.map +1 -1
  39. package/dist/webrtc.d.ts +5 -0
  40. package/dist/webrtc.js +21 -2
  41. package/dist/webrtc.js.map +1 -1
  42. package/package.json +1 -1
  43. package/dist/deprecated.d.ts +0 -18
  44. package/dist/deprecated.js +0 -11
  45. package/dist/deprecated.js.map +0 -1
package/README.md CHANGED
@@ -9,7 +9,7 @@ You need a OneLobby lobby server (the WebSocket URL, like `wss://lobby.example.c
9
9
  ## Use it from a `<script>` tag (no build tools)
10
10
 
11
11
  ```html
12
- <script src="https://cdn.jsdelivr.net/npm/onelobby@0.6.0/dist/onelobby.global.min.js"></script>
12
+ <script src="https://cdn.jsdelivr.net/npm/onelobby@0.7.0/dist/onelobby.global.min.js"></script>
13
13
  <script>
14
14
  const kit = new OneLobby.OneLobby({
15
15
  gameId: "com.you.yourgame", // any unique name for your game
@@ -51,7 +51,7 @@ const lobby = await kit.host({ name: "My game", maxPlayers: 4 });
51
51
  console.log("Tell your friend this code:", formatCode(lobby.code));
52
52
  ```
53
53
 
54
- Without a bundler: `import { OneLobby } from "https://cdn.jsdelivr.net/npm/onelobby@0.6.0/dist/onelobby.bundle.mjs"`.
54
+ Without a bundler: `import { OneLobby } from "https://cdn.jsdelivr.net/npm/onelobby@0.7.0/dist/onelobby.bundle.mjs"`.
55
55
 
56
56
  ## Made for players
57
57
 
@@ -98,6 +98,7 @@ declare class Member {
98
98
  detachedAt: number;
99
99
  token: string;
100
100
  ip: string;
101
+ renames: RateWindow | null;
101
102
  }
102
103
  declare class HubLobby {
103
104
  code: string;
@@ -183,6 +184,7 @@ export declare class SignalingHub {
183
184
  private signalRate;
184
185
  private requireHost;
185
186
  private hostMeta;
187
+ private setName;
186
188
  private hostPhase;
187
189
  private kick;
188
190
  private approve;
@@ -145,6 +145,7 @@ class Member {
145
145
  detachedAt = 0;
146
146
  token = "";
147
147
  ip = "";
148
+ renames = null;
148
149
  }
149
150
  class HubLobby {
150
151
  code = "";
@@ -174,7 +175,7 @@ class HubLobby {
174
175
  return this.members.find((m) => m.peerId === peerId);
175
176
  }
176
177
  }
177
- const KNOWN_TYPES = new Set(["hello", "create", "join", "list", "leave", "signal", "meta", "phase", "kick", "approve", "ping", "host_changed", "path"]);
178
+ const KNOWN_TYPES = new Set(["hello", "create", "join", "list", "leave", "signal", "meta", "phase", "kick", "approve", "ping", "host_changed", "path", "set_name"]);
178
179
  const str = (o, k) => (typeof o[k] === "string" ? o[k] : null);
179
180
  const int = (o, k) => {
180
181
  const v = o[k];
@@ -386,6 +387,7 @@ export class SignalingHub {
386
387
  }
387
388
  case "host_changed": return this.claimHost(s, msg);
388
389
  case "path": return this.pathReport(s, msg);
390
+ case "set_name": return this.setName(s, msg);
389
391
  default: return; // unknown types are ignored
390
392
  }
391
393
  }
@@ -439,6 +441,7 @@ export class SignalingHub {
439
441
  ice: this.iceList(s),
440
442
  serverTime: this.now(),
441
443
  limits: { maxMsg: this.o.maxMessageBytes, maxPlayers: this.o.hardMaxPlayers },
444
+ features: ["set_name"],
442
445
  };
443
446
  if (resumed)
444
447
  w.peerId = resumed.peerId;
@@ -748,6 +751,22 @@ export class SignalingHub {
748
751
  lobby.meta = meta.meta;
749
752
  this.broadcastLobby(lobby);
750
753
  }
754
+ setName(s, m) {
755
+ if (!s.lobby || !s.member)
756
+ return this.error(s, "bad_request", "not in a lobby");
757
+ const name = typeof m.name === "string" ? sanitize(m.name, NAME_MAX) : "";
758
+ if (!name)
759
+ return this.error(s, "bad_request", "name must be a non-empty string", field("name"));
760
+ if (name === s.member.name)
761
+ return;
762
+ const now = this.now();
763
+ const rate = (s.member.renames ??= new RateWindow(this.scale, 1000));
764
+ if (!rate.tryHit(now))
765
+ return this.rateLimited(s, "set_name", rate.retryAfterMs(now), null);
766
+ s.member.name = name;
767
+ s.name = name;
768
+ this.broadcastLobby(s.lobby);
769
+ }
751
770
  hostPhase(s, m) {
752
771
  const lobby = this.requireHost(s);
753
772
  if (!lobby)
@@ -1 +1 @@
1
- {"version":3,"file":"hub.js","sourceRoot":"","sources":["../../src/direct/hub.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The signaling hub (protocol lk1) in TypeScript, for a Node process or a browser tab that hosts direct lobbies\n * (docs/design/direct-ip.md s.2): a line-by-line port of `server/OneLobby.Hub/Hub.cs`, held to the same rules by\n * `conformance/server`. Transport-agnostic: feed it text frames with `receive`, call `tick` about once a second.\n * Metrics (same names, labels and help text as C#, rendered by `metrics.render()`) are counted too, so every hub shape\n * looks the same from outside; everything else (codes, list, resume, private lobbies, kicks, migration claims, TURN\n * credentials, rate limits) behaves as in C#.\n */\n\nimport { Metrics } from \"./metrics.js\";\nimport { randomBelow, randomHex, shortHash, turnCredential } from \"./sha1.js\";\n\nexport { Metrics };\nexport const PROTO = \"lk1\";\nconst NAME_MAX = 24;\nconst LOBBY_NAME_MAX = 48;\nconst META_KEYS_MAX = 16;\nconst META_LEN_MAX = 64;\nconst PENDING_MAX = 8;\nconst CROCKFORD = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\nconst GAME_ID = /^[A-Za-z0-9._-]{1,64}$/;\n\n/** The settings the hub reads; same names and defaults as C#'s `HubOptions`. */\nexport interface HubOptions {\n turnUrls: string[];\n turnSecret: string;\n stunUrls: string[];\n region: string;\n /** Empty = every gameId allowed. */\n allowedGames: string[];\n gameQuotas: Record<string, number>;\n maxLobbies: number;\n maxPeers: number;\n /** Default and advertised maxPlayers limit; create accepts 2..this. */\n hardMaxPlayers: number;\n rateScale: number;\n turnTtlSeconds: number;\n maxMessageBytes: number;\n disableIpLimits: boolean;\n createPerMin: number;\n joinPerMin: number;\n signalPerSec: number;\n /** Open sockets per address (loopback included); `disableIpLimits` lifts it, `rateScale` scales it. */\n socketsPerIp: number;\n openLobbiesPerIp: number;\n idleTimeoutMs: number;\n resumeWindowMs: number;\n codeReuseMs: number;\n listLimitMax: number;\n /** One lobby per hub (direct IP): later creates are refused, a join without a code joins it. */\n singleLobby: boolean;\n /** When set, join must carry the same password or gets bad_password. */\n password: string | null;\n /** False: lobby messages carry code \"\" and list is empty. */\n issueCodes: boolean;\n}\n\nexport function defaultHubOptions(): HubOptions {\n return {\n turnUrls: [], turnSecret: \"\", stunUrls: [\"stun:stun.l.google.com:19302\"], region: \"\", allowedGames: [], gameQuotas: {},\n maxLobbies: 1000, maxPeers: 10000, hardMaxPlayers: 64, rateScale: 1, turnTtlSeconds: 3600, maxMessageBytes: 16 * 1024,\n disableIpLimits: false, createPerMin: 10, joinPerMin: 60, signalPerSec: 20, socketsPerIp: 32, openLobbiesPerIp: 8, idleTimeoutMs: 30_000,\n resumeWindowMs: 60_000, codeReuseMs: 24 * 3600 * 1000, listLimitMax: 100, singleLobby: false, password: null, issueCodes: true,\n };\n}\n\n/** Settings for a hub inside the host's game (docs/design/direct-ip.md s.2): no codes, no list, no ICE servers. */\nexport function directHubOptions(maxPlayers: number, password?: string | null): HubOptions {\n const n = Math.min(250, Math.max(2, maxPlayers));\n return {\n ...defaultHubOptions(),\n singleLobby: true, issueCodes: false, password: password ? password : null, stunUrls: [], turnUrls: [],\n maxLobbies: 1, hardMaxPlayers: n, maxPeers: n + 8,\n };\n}\n\n/** A session's total `signal` budget is this many targets' worth of `signalPerSec` (spec/signaling.md rate limits). */\nexport const SIGNAL_FANOUT = 8;\n/** Hub sessions bridged from Nostr have the address `nostr:<pubkey prefix>`. */\nexport const NOSTR_ADDR = \"nostr:\";\n/** `signal` per second per (sender, Nostr target): relays reject high publish rates. */\nexport const NOSTR_SIGNAL_PER_SEC = 10;\n\n/** Sliding-window counter: at most `limit` events per `windowMs`. */\nexport class RateWindow {\n private hits: number[] = [];\n constructor(readonly limit: number, readonly windowMs: number) {}\n tryHit(now: number): boolean {\n this.trim(now);\n if (this.hits.length >= this.limit) return false;\n this.hits.push(now);\n return true;\n }\n retryAfterMs(now: number): number {\n this.trim(now);\n return this.hits.length < this.limit || this.hits.length === 0 ? 0 : Math.max(1, this.windowMs - (now - this.hits[0]));\n }\n isIdle(now: number): boolean {\n this.trim(now);\n return this.hits.length === 0;\n }\n private trim(now: number): void {\n while (this.hits.length > 0 && now - this.hits[0] >= this.windowMs) this.hits.shift();\n }\n}\n\n/** Control characters and bidi overrides out, then at most `max` UTF-16 units without splitting a surrogate pair. */\nexport function sanitize(s: string | null | undefined, max: number, fallback = \"\"): string {\n if (!s) return fallback;\n let r = \"\";\n for (const ch of s) {\n const c = ch.charCodeAt(0);\n if (ch.length === 1 && (c <= 0x1f || (c >= 0x7f && c <= 0x9f) || (c >= 0x202a && c <= 0x202e) || (c >= 0x2066 && c <= 0x2069))) continue;\n r += ch;\n }\n if (r.length > max) {\n r = r.slice(0, max);\n const last = r.charCodeAt(r.length - 1);\n if (last >= 0xd800 && last <= 0xdbff) r = r.slice(0, -1);\n }\n return r.length === 0 ? fallback : r;\n}\n\nfunction normalizeCode(input: unknown): string | null {\n if (typeof input !== \"string\") return null;\n let out = \"\";\n for (const raw of input) {\n if (raw === \" \" || raw === \"-\") continue;\n let ch = raw >= \"a\" && raw <= \"z\" ? raw.toUpperCase() : raw;\n if (ch === \"I\" || ch === \"L\") ch = \"1\";\n else if (ch === \"O\") ch = \"0\";\n if (CROCKFORD.indexOf(ch) < 0 || out.length >= 6) return null;\n out += ch;\n }\n return out.length === 6 ? out : null;\n}\n\ntype Json = Record<string, unknown>;\n\n/** One signaling connection. The hub only calls `send` and `close`. */\nexport class Session {\n closed = false;\n lastSeen = 0;\n helloDone = false;\n gameId = \"\";\n netVersion = \"\";\n name = \"\";\n lobby: HubLobby | null = null;\n member: Member | null = null;\n pendingIn: HubLobby | null = null;\n pendingMember: Member | null = null;\n constructor(\n readonly id: number,\n readonly ip: string,\n readonly connId: string,\n readonly send: (text: string) => void,\n readonly close: (code?: number, reason?: string) => void,\n ) {}\n /** Nostr joiners: the remote address of the host's WebRTC link to this session, once known (kick bans it too). */\n linkIp: string | null = null;\n /** One window per target member (a member belongs to one lobby, so a new lobby starts fresh). */\n readonly signalRates = new Map<Member, RateWindow>();\n /** All signals of this session, so the per-target budget does not grow without bound with the lobby. */\n signalTotal: RateWindow | null = null;\n}\n\nclass Member {\n peerId = 0;\n name = \"\";\n joinedAt = 0;\n session: Session | null = null;\n detachedAt = 0;\n token = \"\";\n ip = \"\";\n}\n\nclass HubLobby {\n code = \"\";\n gameId = \"\";\n netVersion = \"\";\n name = \"\";\n visibility = \"public\";\n mode = \"lockstep\";\n tickRate = 20;\n lateJoin = false;\n relayOnly = false;\n phase = \"lobby\";\n maxPlayers = 0;\n createdAt = 0;\n ownerIp = \"\";\n meta: Record<string, string> = {};\n members: Member[] = [];\n pending: Member[] = [];\n kicked = new Set<string>();\n hostId = 0;\n epoch = 0;\n /** Highest valid host_changed claim a member made while the host was still connected; applied when the host goes. */\n pendingClaimPeer = 0;\n pendingClaimEpoch = 0;\n nextPeerId = 1;\n find(peerId: number): Member | undefined {\n return this.members.find((m) => m.peerId === peerId);\n }\n}\n\ninterface IpState {\n create: RateWindow;\n join: RateWindow;\n open: number;\n sockets: number;\n}\n\nconst KNOWN_TYPES = new Set([\"hello\", \"create\", \"join\", \"list\", \"leave\", \"signal\", \"meta\", \"phase\", \"kick\", \"approve\", \"ping\", \"host_changed\", \"path\"]);\n\nconst str = (o: Json, k: string): string | null => (typeof o[k] === \"string\" ? (o[k] as string) : null);\nconst int = (o: Json, k: string): number | null => {\n const v = o[k];\n return typeof v === \"number\" && Number.isInteger(v) && Math.abs(v) < 2147483647 ? v : null;\n};\nconst bool = (o: Json, k: string): boolean | null => (typeof o[k] === \"boolean\" ? (o[k] as boolean) : null);\nconst has = (o: Json, k: string): boolean => o[k] !== undefined && o[k] !== null;\nconst field = (name: string): Json => ({ field: name });\nconst hex = (n: number): string => randomHex(n);\nconst byCode = (a: string, b: string): number => (a < b ? -1 : a > b ? 1 : 0);\n\n/** Not sanitised (spec/signaling.md): over the limits or non-string values are rejected. */\nfunction readMeta(node: unknown): { meta: Record<string, string> } | { err: string } {\n if (node === undefined || node === null) return { meta: {} };\n if (typeof node !== \"object\" || Array.isArray(node)) return { err: \"meta must be an object of strings\" };\n const entries = Object.entries(node as Json);\n if (entries.length > META_KEYS_MAX) return { err: `meta allows at most ${META_KEYS_MAX} keys` };\n const meta: Record<string, string> = {};\n for (const [k, v] of entries.sort(([a], [b]) => byCode(a, b))) {\n if (typeof v !== \"string\") return { err: \"meta values must be strings\" };\n if (k.length > META_LEN_MAX || v.length > META_LEN_MAX) return { err: `meta keys and values are limited to ${META_LEN_MAX} chars` };\n meta[k] = v;\n }\n return { meta };\n}\n\nexport interface HubDeps {\n /** Unix milliseconds; injected so tests drive time. */\n now?: () => number;\n /** Uniform integer in [0, n). */\n randomInt?: (n: number) => number;\n log?: (line: string) => void;\n}\n\n/** All signaling state and rules (DESIGN s.6, s.7, s.9, s.10, s.12; spec/signaling.md). */\nexport class SignalingHub {\n private readonly o: HubOptions;\n private readonly now: () => number;\n private readonly rand: (n: number) => number;\n private readonly log: (line: string) => void;\n private readonly lobbies = new Map<string, HubLobby>();\n private readonly retired = new Map<string, number>();\n private readonly tokens = new Map<string, { lobby: HubLobby; member: Member }>();\n private readonly sessions = new Map<number, Session>();\n private readonly gameLobbies = new Map<string, number>();\n private readonly ips = new Map<string, IpState>();\n private nextSession = 0;\n private createdOnce = false;\n private members = 0;\n private readonly logSalt = hex(8);\n readonly metrics = new Metrics();\n\n constructor(options: Partial<HubOptions> = {}, deps: HubDeps = {}) {\n this.o = { ...defaultHubOptions(), ...options };\n this.now = deps.now ?? (() => Date.now());\n this.rand = deps.randomInt ?? ((n) => randomBelow(n));\n this.log = deps.log ?? (() => {});\n const m = this.metrics;\n m.gauge(\"onelobby_lobbies\", \"Live lobbies.\", () => this.lobbyCount);\n m.gauge(\"onelobby_sockets\", \"Open signaling sockets.\", () => this.socketCount);\n m.gauge(\"onelobby_lobbies_retired\", \"Join codes held back from reuse.\", () => this.retired.size);\n m.describe(\"onelobby_messages_total\", \"Client messages received, by type.\");\n m.describe(\"onelobby_errors_total\", \"Error replies sent, by code.\");\n m.describe(\"onelobby_path_total\", \"ICE path reports from peers: direct vs relayed (DESIGN s.10).\");\n m.describe(\"onelobby_connections_total\", \"Sockets accepted since start.\");\n m.describe(\"onelobby_lobbies_created_total\", \"Lobbies created since start.\");\n m.describe(\"onelobby_rate_limit_hits_total\", \"Requests refused by a rate limit, by kind.\");\n }\n\n get lobbyCount(): number {\n return this.lobbies.size;\n }\n get socketCount(): number {\n return this.sessions.size;\n }\n private get scale(): number {\n return Math.max(1, this.o.rateScale);\n }\n\n // ---------------------------------------------------------------- connection lifecycle\n\n /** Registers a socket. Returns null (after sending server_full and closing) when over maxPeers. */\n connect(ip: string, send: (text: string) => void, close: (code?: number, reason?: string) => void): Session | null {\n const s = new Session(++this.nextSession, ip, hex(6), send, close);\n s.lastSeen = this.now();\n this.metrics.inc(\"onelobby_connections_total\");\n if (this.sessions.size >= this.o.maxPeers) {\n this.error(s, \"server_full\", \"server is at its peer limit\");\n s.close();\n return null;\n }\n const st = this.ipOf(ip);\n if (!this.o.disableIpLimits && st.sockets >= this.o.socketsPerIp * this.scale) {\n this.rateLimited(s, \"sockets\", 5000, \"max_sockets\");\n s.close(1008, \"too_many_sockets\");\n return null;\n }\n this.sessions.set(s.id, s);\n st.sockets++;\n return s;\n }\n\n disconnect(s: Session): void {\n if (!this.sessions.delete(s.id)) return;\n s.closed = true;\n const st = this.ips.get(s.ip);\n if (st) st.sockets--;\n if (s.pendingIn) {\n s.pendingIn.pending = s.pendingIn.pending.filter((p) => p !== s.pendingMember);\n s.pendingIn = null;\n s.pendingMember = null;\n }\n const m = s.member;\n const lobby = s.lobby;\n if (m && lobby) {\n // The slot and token stay reserved for the resume window (tick expires them); others hear peer_left{timeout} now.\n m.session = null;\n m.detachedAt = this.now();\n s.member = null;\n s.lobby = null;\n this.logEvent(\"detach\", lobby, s);\n this.broadcast(lobby, { t: \"peer_left\", peerId: m.peerId, reason: \"timeout\" });\n this.metrics.inc(\"onelobby_peers_left_total\", \"reason\", \"timeout\");\n if (lobby.hostId === m.peerId) this.promoteHost(lobby, m.peerId);\n }\n }\n\n /**\n * The host's WebRTC link to joiner `peerId` has the remote address `ip` (selected candidate pair; the host's own\n * lobby reports it, a relayed or mDNS address must not be passed). Only Nostr sessions take it: their socket address\n * is a pubkey the joiner chose. A joiner whose link address is banned is removed as kicked; a later kick bans it.\n */\n reportLinkAddress(peerId: number, ip: string): void {\n for (const lobby of this.lobbies.values()) {\n const mem = lobby.find(peerId);\n const sess = mem?.session;\n if (!mem || !sess || !sess.ip.startsWith(NOSTR_ADDR)) continue;\n sess.linkIp = ip;\n if (lobby.kicked.has(ip)) {\n this.removeMember(lobby, mem, \"kicked\");\n this.closeSession(sess);\n }\n return;\n }\n }\n\n private closeSession(s: Session): void {\n s.close();\n this.disconnect(s);\n }\n\n // ---------------------------------------------------------------- time\n\n /** Call about once a second: idle timeouts, resume-window expiry, code retirement. */\n tick(): void {\n const now = this.now();\n for (const s of [...this.sessions.values()])\n if (now - s.lastSeen > this.o.idleTimeoutMs) {\n this.metrics.inc(\"onelobby_idle_timeouts_total\");\n this.closeSession(s);\n }\n for (const lobby of [...this.lobbies.values()])\n for (const m of [...lobby.members]) if (m.detachedAt > 0 && now - m.detachedAt >= this.o.resumeWindowMs) this.removeMember(lobby, m, \"timeout\");\n for (const [code, at] of [...this.retired]) if (now - at >= this.o.codeReuseMs) this.retired.delete(code);\n for (const [key, st] of [...this.ips])\n if (st.sockets <= 0 && st.open <= 0 && st.create.isIdle(now) && st.join.isIdle(now)) this.ips.delete(key);\n }\n\n // ---------------------------------------------------------------- inbound\n\n receive(s: Session, text: string): void {\n if (s.closed) return;\n s.lastSeen = this.now();\n if (text.length > this.o.maxMessageBytes) {\n this.error(s, \"bad_request\", \"message too large\");\n this.closeSession(s);\n return;\n }\n let msg: Json | null = null;\n try {\n const v = JSON.parse(text) as unknown;\n msg = v && typeof v === \"object\" && !Array.isArray(v) ? (v as Json) : null;\n } catch {\n msg = null;\n }\n const t = msg ? str(msg, \"t\") : null;\n if (!msg || t === null) {\n this.error(s, \"bad_request\", \"expected a JSON object with a string t\", field(\"t\"));\n return;\n }\n this.metrics.inc(\"onelobby_messages_total\", \"type\", KNOWN_TYPES.has(t) ? t : \"unknown\");\n if (t === \"hello\") return this.hello(s, msg);\n if (!s.helloDone) {\n if (KNOWN_TYPES.has(t)) this.error(s, \"bad_request\", \"send hello first\");\n return;\n }\n switch (t) {\n case \"create\": return this.create(s, msg);\n case \"join\": return this.join(s, msg);\n case \"list\": return this.list(s, msg);\n case \"leave\": return this.leave(s);\n case \"signal\": return this.signal(s, msg);\n case \"meta\": return this.hostMeta(s, msg);\n case \"phase\": return this.hostPhase(s, msg);\n case \"kick\": return this.kick(s, msg);\n case \"approve\": return this.approve(s, msg);\n case \"ping\": {\n const n = int(msg, \"n\");\n if (n === null || n < 0) return this.error(s, \"bad_request\", \"ping needs an integer n\", field(\"n\"));\n return this.send(s, { t: \"pong\", n });\n }\n case \"host_changed\": return this.claimHost(s, msg);\n case \"path\": return this.pathReport(s, msg);\n default: return; // unknown types are ignored\n }\n }\n\n // ---------------------------------------------------------------- hello / welcome\n\n private hello(s: Session, m: Json): void {\n if (s.helloDone) return this.error(s, \"bad_request\", \"hello already sent\");\n if (str(m, \"proto\") !== PROTO) {\n this.error(s, \"bad_request\", \"unsupported proto, expected lk1\", { supported: [PROTO] });\n this.closeSession(s);\n return;\n }\n if (has(m, \"name\") && str(m, \"name\") === null) return this.error(s, \"bad_request\", \"name must be a string\", field(\"name\"));\n if (has(m, \"client\") && (typeof m.client !== \"object\" || Array.isArray(m.client)))\n return this.error(s, \"bad_request\", \"client must be an object\", field(\"client\"));\n const gameId = str(m, \"gameId\");\n const netVersion = str(m, \"netVersion\");\n if (gameId === null || !GAME_ID.test(gameId)) return this.error(s, \"bad_request\", \"gameId must match [A-Za-z0-9._-]{1,64}\", field(\"gameId\"));\n if (!netVersion || netVersion.length > 32) return this.error(s, \"bad_request\", \"netVersion must be 1-32 characters\", field(\"netVersion\"));\n if (this.o.allowedGames.length > 0 && !this.o.allowedGames.includes(gameId)) {\n this.error(s, \"game_not_allowed\", \"this server does not host that game\");\n this.closeSession(s);\n return;\n }\n s.gameId = gameId;\n s.netVersion = netVersion;\n s.name = sanitize(str(m, \"name\"), NAME_MAX, \"Player\");\n s.helloDone = true;\n\n let resumed: Member | null = null;\n let rl: HubLobby | null = null;\n const token = str(m, \"resumeToken\");\n const entry = token !== null ? this.tokens.get(token) : undefined;\n if (entry && entry.lobby.gameId === gameId && entry.lobby.netVersion === netVersion) {\n // Validate first: a live socket (take-over) or a detached seat still inside the resume window. Only a valid\n // resume closes the old socket (it detaches normally, which starts the window anew).\n const old = entry.member.session;\n const takeOver = old !== null && old !== undefined && old !== s;\n const inWindow = entry.member.detachedAt > 0 && this.now() - entry.member.detachedAt < this.o.resumeWindowMs;\n if (takeOver || inWindow) {\n if (takeOver) this.closeSession(old!);\n resumed = entry.member;\n rl = entry.lobby;\n }\n }\n\n const w: Json = {\n t: \"welcome\",\n ice: this.iceList(s),\n serverTime: this.now(),\n limits: { maxMsg: this.o.maxMessageBytes, maxPlayers: this.o.hardMaxPlayers },\n };\n if (resumed) w.peerId = resumed.peerId;\n this.send(s, w);\n\n if (resumed && rl) {\n this.tokens.delete(resumed.token);\n resumed.token = hex(16);\n this.tokens.set(resumed.token, { lobby: rl, member: resumed });\n resumed.session = s;\n resumed.detachedAt = 0;\n s.lobby = rl;\n s.member = resumed;\n this.logEvent(\"resume\", rl, s);\n this.metrics.inc(\"onelobby_resumes_total\");\n for (const other of rl.members) if (other !== resumed) this.sendTo(other, { t: \"peer_joined\", peer: this.peerObj(resumed) });\n this.send(s, this.lobbyMsg(rl, resumed));\n }\n }\n\n private iceList(s: Session): Json[] {\n const ice: Json[] = [];\n if (this.o.stunUrls.length > 0) ice.push({ urls: [...this.o.stunUrls] });\n if (this.o.turnUrls.length > 0 && this.o.turnSecret.length > 0) {\n const expiry = Math.floor(this.now() / 1000) + this.o.turnTtlSeconds;\n const username = `${expiry}:${s.connId}`;\n const credential = turnCredential(this.o.turnSecret, username);\n ice.push({ urls: [...this.o.turnUrls], username, credential, ttl: this.o.turnTtlSeconds });\n }\n return ice;\n }\n\n // ---------------------------------------------------------------- create / join / list / leave\n\n private ipOf(ip: string): IpState {\n let st = this.ips.get(ip);\n if (!st) {\n st = { create: new RateWindow(this.o.createPerMin * this.scale, 60_000), join: new RateWindow(this.o.joinPerMin * this.scale, 60_000), open: 0, sockets: 0 };\n this.ips.set(ip, st);\n }\n return st;\n }\n\n private create(s: Session, m: Json): void {\n if (s.lobby || s.pendingIn) return this.error(s, \"bad_request\", \"already in a lobby\");\n const ip = this.ipOf(s.ip);\n const now = this.now();\n if (!this.o.disableIpLimits) {\n if (!ip.create.tryHit(now)) return this.rateLimited(s, \"create\", ip.create.retryAfterMs(now), null);\n if (ip.open >= this.o.openLobbiesPerIp * this.scale) return this.rateLimited(s, \"open_lobbies\", 5000, \"max_lobbies\");\n }\n if (this.o.singleLobby && this.createdOnce) return this.error(s, \"server_full\", \"this host runs one lobby\");\n if (this.lobbies.size >= this.o.maxLobbies || this.members >= this.o.maxPeers) return this.error(s, \"server_full\", \"server is at its lobby limit\");\n const quota = this.o.gameQuotas[s.gameId];\n if (quota !== undefined && (this.gameLobbies.get(s.gameId) ?? 0) >= quota) return this.error(s, \"server_full\", \"lobby quota for this game is reached\");\n\n if (has(m, \"name\") && str(m, \"name\") === null) return this.error(s, \"bad_request\", \"name must be a string\", field(\"name\"));\n const vis = str(m, \"visibility\") ?? \"public\";\n const mode = str(m, \"mode\") ?? \"lockstep\";\n if (vis !== \"public\" && vis !== \"unlisted\" && vis !== \"private\") return this.error(s, \"bad_request\", \"visibility must be public, unlisted or private\", field(\"visibility\"));\n if (mode !== \"lockstep\" && mode !== \"raw\") return this.error(s, \"bad_request\", \"mode must be lockstep or raw\", field(\"mode\"));\n if (has(m, \"maxPlayers\") && int(m, \"maxPlayers\") === null) return this.error(s, \"bad_request\", \"maxPlayers must be an integer\", field(\"maxPlayers\"));\n const maxPlayers = int(m, \"maxPlayers\") ?? 8;\n if (maxPlayers < 2 || maxPlayers > this.o.hardMaxPlayers) return this.error(s, \"bad_request\", `maxPlayers must be 2-${this.o.hardMaxPlayers}`, field(\"maxPlayers\"));\n if (has(m, \"tickRate\") && int(m, \"tickRate\") === null) return this.error(s, \"bad_request\", \"tickRate must be an integer\", field(\"tickRate\"));\n const tick = int(m, \"tickRate\") ?? 20;\n if (tick < 1 || tick > 255) return this.error(s, \"bad_request\", \"tickRate must be 1-255\", field(\"tickRate\"));\n if (has(m, \"lateJoin\") && bool(m, \"lateJoin\") === null) return this.error(s, \"bad_request\", \"lateJoin must be a boolean\", field(\"lateJoin\"));\n if (has(m, \"relayOnly\") && bool(m, \"relayOnly\") === null) return this.error(s, \"bad_request\", \"relayOnly must be a boolean\", field(\"relayOnly\"));\n const meta = readMeta(m.meta);\n if (\"err\" in meta) return this.error(s, \"bad_request\", meta.err, field(\"meta\"));\n\n const code = this.newCode();\n if (code === null) return this.error(s, \"server_full\", \"could not allocate a join code\");\n\n const lobby = new HubLobby();\n Object.assign(lobby, {\n code, gameId: s.gameId, netVersion: s.netVersion, name: sanitize(str(m, \"name\"), LOBBY_NAME_MAX, `${s.name}'s lobby`),\n visibility: vis, mode, tickRate: tick, lateJoin: bool(m, \"lateJoin\") ?? false, relayOnly: bool(m, \"relayOnly\") ?? false,\n maxPlayers, createdAt: now, ownerIp: s.ip, meta: meta.meta,\n });\n this.lobbies.set(code, lobby);\n this.createdOnce = true;\n this.gameLobbies.set(s.gameId, (this.gameLobbies.get(s.gameId) ?? 0) + 1);\n ip.open++;\n this.metrics.inc(\"onelobby_lobbies_created_total\");\n const host = this.addMember(lobby, s, null);\n lobby.hostId = host.peerId;\n this.logEvent(\"create\", lobby, s);\n this.send(s, this.lobbyMsg(lobby, host));\n }\n\n private join(s: Session, m: Json): void {\n if (s.lobby || s.pendingIn) return this.error(s, \"bad_request\", \"already in a lobby\");\n const ip = this.ipOf(s.ip);\n const now = this.now();\n if (!this.o.disableIpLimits && !ip.join.tryHit(now)) return this.rateLimited(s, \"join\", ip.join.retryAfterMs(now), null);\n let lobby: HubLobby | undefined;\n if (this.o.singleLobby && !has(m, \"code\")) {\n // direct IP: the address is the invitation, so a join without a code means the one lobby\n lobby = this.lobbies.values().next().value;\n if (!lobby || lobby.gameId !== s.gameId) return this.error(s, \"unknown_code\", \"this host has no open lobby for that game\");\n } else {\n const code = normalizeCode(m.code);\n if (code === null) return this.error(s, \"bad_request\", \"malformed join code\", field(\"code\"));\n lobby = this.lobbies.get(code);\n if (!lobby || lobby.gameId !== s.gameId) return this.error(s, \"unknown_code\", \"no lobby with that code\");\n }\n if (this.o.password !== null && str(m, \"password\") !== this.o.password) return this.error(s, \"bad_password\", \"wrong password for this lobby\");\n if (lobby.netVersion !== s.netVersion)\n return this.error(s, \"version_mismatch\", `host is on ${lobby.netVersion}, you are on ${s.netVersion}`, { hostNetVersion: lobby.netVersion, yourNetVersion: s.netVersion });\n if (lobby.kicked.has(s.ip)) return this.error(s, \"kicked\", \"you were removed from this lobby\");\n if (lobby.phase === \"in_game\" && !lobby.lateJoin) return this.error(s, \"in_game\", \"the game has already started\");\n if (lobby.members.length >= lobby.maxPlayers) return this.error(s, \"lobby_full\", \"lobby is full\");\n if (this.members >= this.o.maxPeers) return this.error(s, \"server_full\", \"server is at its peer limit\");\n\n if (lobby.visibility === \"private\") {\n if (lobby.pending.length >= PENDING_MAX) return this.error(s, \"lobby_full\", \"too many pending requests\");\n const pm = new Member();\n pm.peerId = lobby.nextPeerId++;\n pm.name = s.name;\n pm.session = s;\n pm.ip = s.ip;\n lobby.pending.push(pm);\n s.pendingIn = lobby;\n s.pendingMember = pm;\n const hs = lobby.find(lobby.hostId)?.session;\n if (hs) this.send(hs, { t: \"join_request\", peer: this.peerObj(pm) });\n this.logEvent(\"join_request\", lobby, s);\n return;\n }\n this.admit(lobby, s, null);\n }\n\n private admit(lobby: HubLobby, s: Session, pending: Member | null): void {\n const joiner = this.addMember(lobby, s, pending);\n this.logEvent(\"join\", lobby, s);\n for (const other of lobby.members) if (other !== joiner) this.sendTo(other, { t: \"peer_joined\", peer: this.peerObj(joiner) });\n // A lobby whose host slot is only reserved (host dropped, nobody was connected) hands over to the first newcomer.\n if (!lobby.find(lobby.hostId)?.session) this.promoteHost(lobby, lobby.hostId);\n this.send(s, this.lobbyMsg(lobby, joiner));\n }\n\n private addMember(lobby: HubLobby, s: Session, reuse: Member | null): Member {\n const mem = reuse ?? new Member();\n if (!reuse) mem.peerId = lobby.nextPeerId++;\n mem.name = s.name;\n mem.session = s;\n mem.ip = s.ip;\n mem.joinedAt = this.now();\n mem.detachedAt = 0;\n mem.token = hex(16);\n lobby.members.push(mem);\n this.members++;\n this.tokens.set(mem.token, { lobby, member: mem });\n s.lobby = lobby;\n s.member = mem;\n s.pendingIn = null;\n s.pendingMember = null;\n return mem;\n }\n\n private list(s: Session, m: Json): void {\n const vis = str(m, \"visibility\");\n if (!this.o.issueCodes) return this.send(s, { t: \"lobbies\", items: [] });\n if (vis !== \"public\") return this.error(s, \"bad_request\", \"only public lobbies can be listed\", field(\"visibility\"));\n let limit = 50;\n if (has(m, \"limit\")) {\n const l = int(m, \"limit\");\n if (l === null || l < 1 || l > this.o.listLimitMax) return this.error(s, \"bad_request\", `limit must be 1-${this.o.listLimitMax}`, field(\"limit\"));\n limit = l;\n }\n let offset = 0;\n if (has(m, \"cursor\")) {\n const c = str(m, \"cursor\");\n if (c === null || !/^\\d+$/.test(c)) return this.error(s, \"bad_request\", \"bad cursor\", field(\"cursor\"));\n offset = Number(c);\n }\n let filter: Record<string, string> | null = null;\n if (has(m, \"meta\")) {\n if (typeof m.meta !== \"object\" || Array.isArray(m.meta)) return this.error(s, \"bad_request\", \"meta must be an object\", field(\"meta\"));\n filter = {};\n for (const [k, v] of Object.entries(m.meta as Json)) {\n if (typeof v !== \"string\") return this.error(s, \"bad_request\", \"meta values must be strings\", field(\"meta\"));\n filter[k] = v;\n }\n }\n const all = [...this.lobbies.values()]\n .filter((l) => l.gameId === s.gameId && l.netVersion === s.netVersion && l.visibility === \"public\" && (l.phase !== \"in_game\" || l.lateJoin)\n && (filter === null || Object.entries(filter).every(([k, v]) => l.meta[k] === v)))\n .sort((a, b) => a.createdAt - b.createdAt || byCode(a.code, b.code));\n const page = all.slice(offset, offset + limit);\n const items = page.map((l) => ({\n code: l.code, gameId: l.gameId, netVersion: l.netVersion, name: l.name, hostName: l.find(l.hostId)?.name ?? \"\",\n players: l.members.length, maxPlayers: l.maxPlayers, phase: l.phase, meta: { ...l.meta }, region: this.o.region, createdAt: l.createdAt,\n }));\n const reply: Json = { t: \"lobbies\", items };\n if (offset + page.length < all.length) reply.cursor = String(offset + page.length);\n this.send(s, reply);\n }\n\n private leave(s: Session): void {\n if (s.pendingIn) {\n s.pendingIn.pending = s.pendingIn.pending.filter((p) => p !== s.pendingMember);\n s.pendingIn = null;\n s.pendingMember = null;\n return;\n }\n if (!s.lobby || !s.member) return;\n this.removeMember(s.lobby, s.member, \"left\");\n }\n\n // ---------------------------------------------------------------- relay + host-only\n\n private signal(s: Session, m: Json): void {\n const lobby = s.lobby;\n const me = s.member;\n if (!lobby || !me) return this.error(s, \"bad_request\", \"not in a lobby\");\n const to = int(m, \"to\");\n const target = to === null ? undefined : lobby.find(to);\n if (!target || !target.session || target === me) return this.error(s, \"bad_request\", \"unknown signal target\", field(\"to\"));\n // a direct hub has no migration: the only peer links are host <-> joiner, so a joiner cannot dial another joiner\n if (this.o.singleLobby && me.peerId !== lobby.hostId && target.peerId !== lobby.hostId)\n return this.error(s, \"bad_request\", \"signals go to or from the host only\", field(\"to\"));\n const now = this.now();\n const rate = this.signalRate(s, target, now);\n if (!rate.tryHit(now)) return this.rateLimited(s, \"signal\", rate.retryAfterMs(now), null);\n const total = (s.signalTotal ??= new RateWindow(this.o.signalPerSec * SIGNAL_FANOUT * this.scale, 1000));\n if (!total.tryHit(now)) return this.rateLimited(s, \"signal\", total.retryAfterMs(now), null);\n if (!has(m, \"sdp\") && !has(m, \"ice\")) return this.error(s, \"bad_request\", \"signal needs sdp or ice\", field(\"sdp\"));\n const o: Json = { t: \"signal\", from: me.peerId };\n if (has(m, \"sdp\")) o.sdp = m.sdp;\n if (has(m, \"ice\")) o.ice = m.ice;\n this.send(target.session, o);\n this.metrics.inc(\"onelobby_signals_relayed_total\");\n }\n\n /**\n * spec/signaling.md rate limits: `signal` is counted per sender and target, so a host answering several joiners at once\n * gets the budget for each, and per sender in total (SIGNAL_FANOUT targets' worth).\n */\n private signalRate(s: Session, to: Member, now: number): RateWindow {\n let w = s.signalRates.get(to);\n if (!w) {\n for (const [k, v] of s.signalRates) if (v.isIdle(now)) s.signalRates.delete(k);\n // relays refuse high publish rates, so a Nostr-bridged target gets half the budget\n w = new RateWindow((to.session?.ip.startsWith(NOSTR_ADDR) ? NOSTR_SIGNAL_PER_SEC : this.o.signalPerSec) * this.scale, 1000);\n s.signalRates.set(to, w);\n }\n return w;\n }\n\n private requireHost(s: Session): HubLobby | null {\n if (!s.lobby || !s.member) {\n this.error(s, \"bad_request\", \"not in a lobby\");\n return null;\n }\n if (s.lobby.hostId !== s.member.peerId) {\n this.error(s, \"not_host\", \"only the host can do that\");\n return null;\n }\n return s.lobby;\n }\n\n private hostMeta(s: Session, m: Json): void {\n const lobby = this.requireHost(s);\n if (!lobby) return;\n const meta = readMeta(m.meta);\n if (\"err\" in meta || !has(m, \"meta\")) return this.error(s, \"bad_request\", \"err\" in meta ? meta.err : \"meta is required\", field(\"meta\"));\n lobby.meta = meta.meta;\n this.broadcastLobby(lobby);\n }\n\n private hostPhase(s: Session, m: Json): void {\n const lobby = this.requireHost(s);\n if (!lobby) return;\n const ph = str(m, \"phase\");\n if (ph !== \"in_game\" && ph !== \"lobby\") return this.error(s, \"bad_request\", \"phase must be in_game or lobby\", field(\"phase\"));\n lobby.phase = ph;\n this.logEvent(`phase:${ph}`, lobby, s);\n this.broadcastLobby(lobby);\n }\n\n private kick(s: Session, m: Json): void {\n const lobby = this.requireHost(s);\n if (!lobby) return;\n const id = int(m, \"peerId\");\n const target = id === null ? undefined : lobby.find(id);\n if (id === null || id === s.member!.peerId || !target) return this.error(s, \"bad_request\", \"unknown peerId\", field(\"peerId\"));\n // ban:false disconnects without the ban; closeCode / closeReason are passed to the removed peer (spec/signaling.md)\n const ban = bool(m, \"ban\");\n if (has(m, \"ban\") && ban === null) return this.error(s, \"bad_request\", \"ban must be a boolean\", field(\"ban\"));\n const code = int(m, \"closeCode\");\n if (has(m, \"closeCode\") && (code === null || !(code === 1000 || (code >= 3000 && code <= 4999))))\n return this.error(s, \"bad_request\", \"closeCode must be 1000 or 3000-4999\", field(\"closeCode\"));\n const closeReason = str(m, \"closeReason\");\n if (has(m, \"closeReason\") && (closeReason === null || closeReason.length > 120))\n return this.error(s, \"bad_request\", \"closeReason must be a string of at most 120 characters\", field(\"closeReason\"));\n const data: Json = {};\n if (ban === false) data.ban = false;\n if (code !== null) data.closeCode = code;\n if (closeReason !== null) data.closeReason = closeReason;\n if (ban !== false) {\n lobby.kicked.add(target.ip);\n // a Nostr joiner picks its own key, so also ban the address its WebRTC link came from, when the host saw it\n const link = target.session?.linkIp;\n if (link && target.ip.startsWith(NOSTR_ADDR)) lobby.kicked.add(link);\n }\n this.removeMember(lobby, target, ban === false ? \"disconnected\" : \"kicked\", Object.keys(data).length ? data : undefined);\n }\n\n private approve(s: Session, m: Json): void {\n const lobby = this.requireHost(s);\n if (!lobby) return;\n const id = int(m, \"peerId\");\n const pm = id === null ? undefined : lobby.pending.find((p) => p.peerId === id);\n const js = pm?.session;\n if (!pm || !js) return this.error(s, \"bad_request\", \"no such pending request\", field(\"peerId\"));\n if (has(m, \"ok\") && bool(m, \"ok\") === null) return this.error(s, \"bad_request\", \"ok must be a boolean\", field(\"ok\"));\n lobby.pending = lobby.pending.filter((p) => p !== pm);\n js.pendingIn = null;\n js.pendingMember = null;\n if (bool(m, \"ok\") !== true) return this.error(js, \"kicked\", \"the host declined your request\", { reason: \"denied\" });\n if (lobby.members.length >= lobby.maxPlayers) return this.error(js, \"lobby_full\", \"lobby is full\");\n if (lobby.phase === \"in_game\" && !lobby.lateJoin) return this.error(js, \"in_game\", \"the game has already started\");\n this.admit(lobby, js, pm);\n }\n\n /** Peer-side migration (s.9) tells the server: the new host announces itself with a higher epoch. */\n private claimHost(s: Session, m: Json): void {\n const lobby = s.lobby;\n const me = s.member;\n if (!lobby || !me) return;\n const host = int(m, \"hostId\");\n const epoch = int(m, \"epoch\");\n if (host !== me.peerId || epoch === null || epoch <= lobby.epoch) return;\n if (this.o.singleLobby) return; // direct lobbies have no migration: the host leaving ends the session\n if (lobby.hostId !== me.peerId && lobby.find(lobby.hostId)?.session) {\n // The host is still here, so a member cannot take over. Remember the best claim for when the host goes.\n if (epoch > lobby.pendingClaimEpoch) {\n lobby.pendingClaimPeer = me.peerId;\n lobby.pendingClaimEpoch = epoch;\n }\n return;\n }\n lobby.hostId = me.peerId;\n lobby.epoch = epoch;\n lobby.pendingClaimPeer = lobby.pendingClaimEpoch = 0;\n this.broadcast(lobby, { t: \"host_changed\", hostId: lobby.hostId, epoch: lobby.epoch });\n this.metrics.inc(\"onelobby_host_changes_total\");\n this.logEvent(\"host_claim\", lobby, s);\n }\n\n private pathReport(s: Session, m: Json): void {\n const p = str(m, \"path\");\n if (p === \"relayed\" || p === \"direct\") this.metrics.inc(\"onelobby_path_total\", \"path\", p);\n else this.error(s, \"bad_request\", \"path must be relayed or direct\", field(\"path\"));\n }\n\n // ---------------------------------------------------------------- membership changes\n\n /** Removes a member for good. A member that is already detached was announced as left, so nothing is sent for it. */\n private removeMember(lobby: HubLobby, mem: Member, reason: string, kickData?: Json): void {\n const i = lobby.members.indexOf(mem);\n if (i < 0) return;\n lobby.members.splice(i, 1);\n this.members--;\n this.tokens.delete(mem.token);\n const ms = mem.session;\n const wasConnected = mem.detachedAt === 0;\n if (ms) {\n ms.lobby = null;\n ms.member = null;\n }\n if (wasConnected) {\n this.broadcast(lobby, { t: \"peer_left\", peerId: mem.peerId, reason });\n this.metrics.inc(\"onelobby_peers_left_total\", \"reason\", reason);\n if ((reason === \"kicked\" || reason === \"disconnected\") && ms)\n this.error(ms, \"kicked\", reason === \"kicked\" ? \"the host removed you from the lobby\" : \"the host disconnected you\", kickData);\n }\n this.logEvent(reason, lobby, ms);\n if (lobby.members.length === 0) return this.closeLobby(lobby);\n if (lobby.hostId === mem.peerId) this.promoteHost(lobby, mem.peerId);\n }\n\n /** Server mirror of the peer-side rule (s.9): new host is the lowest peerId still connected; epoch +1. */\n private promoteHost(lobby: HubLobby, leavingId: number): void {\n // A claim made while the old host was alive wins if its claimant is still connected.\n const claimant =\n lobby.pendingClaimEpoch > lobby.epoch && lobby.pendingClaimPeer !== leavingId\n ? lobby.members.find((x) => x.peerId === lobby.pendingClaimPeer && x.session)\n : undefined;\n const claimEpoch = lobby.pendingClaimEpoch;\n lobby.pendingClaimPeer = lobby.pendingClaimEpoch = 0;\n let next = claimant ?? lobby.members.filter((x) => x.session && x.peerId !== leavingId).sort((a, b) => a.peerId - b.peerId)[0];\n if (!next) {\n // Nobody connected. Keep a reserved host slot (it may resume); otherwise fall back to the lowest slot.\n if (lobby.find(leavingId)) return;\n next = [...lobby.members].sort((a, b) => a.peerId - b.peerId)[0];\n if (!next) return;\n }\n lobby.hostId = next.peerId;\n if (claimant) lobby.epoch = claimEpoch;\n else lobby.epoch++;\n this.broadcast(lobby, { t: \"host_changed\", hostId: next.peerId, epoch: lobby.epoch });\n this.metrics.inc(\"onelobby_host_changes_total\");\n const hs = next.session;\n if (hs) for (const pm of lobby.pending) this.send(hs, { t: \"join_request\", peer: this.peerObj(pm) }); // the new host inherits the pending requests\n this.logEvent(\"host_changed\", lobby, next.session);\n }\n\n private closeLobby(lobby: HubLobby): void {\n this.lobbies.delete(lobby.code);\n this.retired.set(lobby.code, this.now());\n const n = this.gameLobbies.get(lobby.gameId);\n if (n !== undefined) {\n if (n <= 1) this.gameLobbies.delete(lobby.gameId);\n else this.gameLobbies.set(lobby.gameId, n - 1);\n }\n const ip = this.ips.get(lobby.ownerIp);\n if (ip && ip.open > 0) ip.open--;\n for (const pm of [...lobby.pending]) {\n const ps = pm.session;\n if (ps) {\n ps.pendingIn = null;\n ps.pendingMember = null;\n this.error(ps, \"unknown_code\", \"the lobby closed\");\n }\n }\n lobby.pending = [];\n this.logEvent(\"close\", lobby, null);\n }\n\n private newCode(): string | null {\n for (let i = 0; i < 100; i++) {\n let c = \"\";\n for (let k = 0; k < 6; k++) c += CROCKFORD[this.rand(32)];\n if (!this.lobbies.has(c) && !this.retired.has(c)) return c;\n }\n return null;\n }\n\n // ---------------------------------------------------------------- output helpers\n\n private lobbyMsg(l: HubLobby, you: Member): Json {\n const peers = l.members\n .filter((x) => x.detachedAt === 0)\n .sort((a, b) => a.peerId - b.peerId)\n .map((p) => ({ peerId: p.peerId, name: p.name, joinedAt: p.joinedAt }));\n return {\n t: \"lobby\", code: this.o.issueCodes ? l.code : \"\", gameId: l.gameId, netVersion: l.netVersion, hostId: l.hostId, you: you.peerId,\n mode: l.mode, tickRate: l.tickRate, lateJoin: l.lateJoin, phase: l.phase, meta: { ...l.meta }, peers, resumeToken: you.token,\n name: l.name, maxPlayers: l.maxPlayers, visibility: l.visibility, relayOnly: l.relayOnly,\n };\n }\n\n private broadcastLobby(l: HubLobby): void {\n for (const m of l.members) if (m.session) this.sendTo(m, this.lobbyMsg(l, m));\n }\n\n private broadcast(l: HubLobby, o: Json): void {\n for (const m of l.members) this.sendTo(m, o);\n }\n\n private peerObj(m: Member): Json {\n return { peerId: m.peerId, name: m.name };\n }\n\n private send(s: Session, o: Json): void {\n if (!s.closed) s.send(JSON.stringify(o));\n }\n\n private sendTo(m: Member, o: Json): void {\n if (m.session) this.send(m.session, o);\n }\n\n private error(s: Session, code: string, msg: string, data?: Json): void {\n this.metrics.inc(\"onelobby_errors_total\", \"code\", code);\n const o: Json = { t: \"error\", code, msg };\n if (data !== undefined) o.data = data;\n s.send(JSON.stringify(o));\n }\n\n private rateLimited(s: Session, kind: string, retryAfterMs: number, reason: string | null): void {\n this.metrics.inc(\"onelobby_rate_limit_hits_total\", \"kind\", kind);\n this.log(`rate_limit kind=${kind} ip=${this.hashIp(s.ip)}`);\n const data: Json = { retryAfterMs };\n if (reason !== null) data.reason = reason;\n this.error(s, \"rate_limited\", `too many ${kind} requests`, data);\n }\n\n private logEvent(ev: string, l: HubLobby, s: Session | null): void {\n this.log(`lobby ${ev} code=${l.code} game=${l.gameId} players=${l.members.length} ip=${s ? this.hashIp(s.ip) : \"-\"}`);\n }\n\n private hashIp(ip: string): string {\n return shortHash(this.logSalt + ip);\n }\n}\n"]}
1
+ {"version":3,"file":"hub.js","sourceRoot":"","sources":["../../src/direct/hub.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The signaling hub (protocol lk1) in TypeScript, for a Node process or a browser tab that hosts direct lobbies\n * (docs/design/direct-ip.md s.2): a line-by-line port of `server/OneLobby.Hub/Hub.cs`, held to the same rules by\n * `conformance/server`. Transport-agnostic: feed it text frames with `receive`, call `tick` about once a second.\n * Metrics (same names, labels and help text as C#, rendered by `metrics.render()`) are counted too, so every hub shape\n * looks the same from outside; everything else (codes, list, resume, private lobbies, kicks, migration claims, TURN\n * credentials, rate limits) behaves as in C#.\n */\n\nimport { Metrics } from \"./metrics.js\";\nimport { randomBelow, randomHex, shortHash, turnCredential } from \"./sha1.js\";\n\nexport { Metrics };\nexport const PROTO = \"lk1\";\nconst NAME_MAX = 24;\nconst LOBBY_NAME_MAX = 48;\nconst META_KEYS_MAX = 16;\nconst META_LEN_MAX = 64;\nconst PENDING_MAX = 8;\nconst CROCKFORD = \"0123456789ABCDEFGHJKMNPQRSTVWXYZ\";\nconst GAME_ID = /^[A-Za-z0-9._-]{1,64}$/;\n\n/** The settings the hub reads; same names and defaults as C#'s `HubOptions`. */\nexport interface HubOptions {\n turnUrls: string[];\n turnSecret: string;\n stunUrls: string[];\n region: string;\n /** Empty = every gameId allowed. */\n allowedGames: string[];\n gameQuotas: Record<string, number>;\n maxLobbies: number;\n maxPeers: number;\n /** Default and advertised maxPlayers limit; create accepts 2..this. */\n hardMaxPlayers: number;\n rateScale: number;\n turnTtlSeconds: number;\n maxMessageBytes: number;\n disableIpLimits: boolean;\n createPerMin: number;\n joinPerMin: number;\n signalPerSec: number;\n /** Open sockets per address (loopback included); `disableIpLimits` lifts it, `rateScale` scales it. */\n socketsPerIp: number;\n openLobbiesPerIp: number;\n idleTimeoutMs: number;\n resumeWindowMs: number;\n codeReuseMs: number;\n listLimitMax: number;\n /** One lobby per hub (direct IP): later creates are refused, a join without a code joins it. */\n singleLobby: boolean;\n /** When set, join must carry the same password or gets bad_password. */\n password: string | null;\n /** False: lobby messages carry code \"\" and list is empty. */\n issueCodes: boolean;\n}\n\nexport function defaultHubOptions(): HubOptions {\n return {\n turnUrls: [], turnSecret: \"\", stunUrls: [\"stun:stun.l.google.com:19302\"], region: \"\", allowedGames: [], gameQuotas: {},\n maxLobbies: 1000, maxPeers: 10000, hardMaxPlayers: 64, rateScale: 1, turnTtlSeconds: 3600, maxMessageBytes: 16 * 1024,\n disableIpLimits: false, createPerMin: 10, joinPerMin: 60, signalPerSec: 20, socketsPerIp: 32, openLobbiesPerIp: 8, idleTimeoutMs: 30_000,\n resumeWindowMs: 60_000, codeReuseMs: 24 * 3600 * 1000, listLimitMax: 100, singleLobby: false, password: null, issueCodes: true,\n };\n}\n\n/** Settings for a hub inside the host's game (docs/design/direct-ip.md s.2): no codes, no list, no ICE servers. */\nexport function directHubOptions(maxPlayers: number, password?: string | null): HubOptions {\n const n = Math.min(250, Math.max(2, maxPlayers));\n return {\n ...defaultHubOptions(),\n singleLobby: true, issueCodes: false, password: password ? password : null, stunUrls: [], turnUrls: [],\n maxLobbies: 1, hardMaxPlayers: n, maxPeers: n + 8,\n };\n}\n\n/** A session's total `signal` budget is this many targets' worth of `signalPerSec` (spec/signaling.md rate limits). */\nexport const SIGNAL_FANOUT = 8;\n/** Hub sessions bridged from Nostr have the address `nostr:<pubkey prefix>`. */\nexport const NOSTR_ADDR = \"nostr:\";\n/** `signal` per second per (sender, Nostr target): relays reject high publish rates. */\nexport const NOSTR_SIGNAL_PER_SEC = 10;\n\n/** Sliding-window counter: at most `limit` events per `windowMs`. */\nexport class RateWindow {\n private hits: number[] = [];\n constructor(readonly limit: number, readonly windowMs: number) {}\n tryHit(now: number): boolean {\n this.trim(now);\n if (this.hits.length >= this.limit) return false;\n this.hits.push(now);\n return true;\n }\n retryAfterMs(now: number): number {\n this.trim(now);\n return this.hits.length < this.limit || this.hits.length === 0 ? 0 : Math.max(1, this.windowMs - (now - this.hits[0]));\n }\n isIdle(now: number): boolean {\n this.trim(now);\n return this.hits.length === 0;\n }\n private trim(now: number): void {\n while (this.hits.length > 0 && now - this.hits[0] >= this.windowMs) this.hits.shift();\n }\n}\n\n/** Control characters and bidi overrides out, then at most `max` UTF-16 units without splitting a surrogate pair. */\nexport function sanitize(s: string | null | undefined, max: number, fallback = \"\"): string {\n if (!s) return fallback;\n let r = \"\";\n for (const ch of s) {\n const c = ch.charCodeAt(0);\n if (ch.length === 1 && (c <= 0x1f || (c >= 0x7f && c <= 0x9f) || (c >= 0x202a && c <= 0x202e) || (c >= 0x2066 && c <= 0x2069))) continue;\n r += ch;\n }\n if (r.length > max) {\n r = r.slice(0, max);\n const last = r.charCodeAt(r.length - 1);\n if (last >= 0xd800 && last <= 0xdbff) r = r.slice(0, -1);\n }\n return r.length === 0 ? fallback : r;\n}\n\nfunction normalizeCode(input: unknown): string | null {\n if (typeof input !== \"string\") return null;\n let out = \"\";\n for (const raw of input) {\n if (raw === \" \" || raw === \"-\") continue;\n let ch = raw >= \"a\" && raw <= \"z\" ? raw.toUpperCase() : raw;\n if (ch === \"I\" || ch === \"L\") ch = \"1\";\n else if (ch === \"O\") ch = \"0\";\n if (CROCKFORD.indexOf(ch) < 0 || out.length >= 6) return null;\n out += ch;\n }\n return out.length === 6 ? out : null;\n}\n\ntype Json = Record<string, unknown>;\n\n/** One signaling connection. The hub only calls `send` and `close`. */\nexport class Session {\n closed = false;\n lastSeen = 0;\n helloDone = false;\n gameId = \"\";\n netVersion = \"\";\n name = \"\";\n lobby: HubLobby | null = null;\n member: Member | null = null;\n pendingIn: HubLobby | null = null;\n pendingMember: Member | null = null;\n constructor(\n readonly id: number,\n readonly ip: string,\n readonly connId: string,\n readonly send: (text: string) => void,\n readonly close: (code?: number, reason?: string) => void,\n ) {}\n /** Nostr joiners: the remote address of the host's WebRTC link to this session, once known (kick bans it too). */\n linkIp: string | null = null;\n /** One window per target member (a member belongs to one lobby, so a new lobby starts fresh). */\n readonly signalRates = new Map<Member, RateWindow>();\n /** All signals of this session, so the per-target budget does not grow without bound with the lobby. */\n signalTotal: RateWindow | null = null;\n}\n\nclass Member {\n peerId = 0;\n name = \"\";\n joinedAt = 0;\n session: Session | null = null;\n detachedAt = 0;\n token = \"\";\n ip = \"\";\n renames: RateWindow | null = null;\n}\n\nclass HubLobby {\n code = \"\";\n gameId = \"\";\n netVersion = \"\";\n name = \"\";\n visibility = \"public\";\n mode = \"lockstep\";\n tickRate = 20;\n lateJoin = false;\n relayOnly = false;\n phase = \"lobby\";\n maxPlayers = 0;\n createdAt = 0;\n ownerIp = \"\";\n meta: Record<string, string> = {};\n members: Member[] = [];\n pending: Member[] = [];\n kicked = new Set<string>();\n hostId = 0;\n epoch = 0;\n /** Highest valid host_changed claim a member made while the host was still connected; applied when the host goes. */\n pendingClaimPeer = 0;\n pendingClaimEpoch = 0;\n nextPeerId = 1;\n find(peerId: number): Member | undefined {\n return this.members.find((m) => m.peerId === peerId);\n }\n}\n\ninterface IpState {\n create: RateWindow;\n join: RateWindow;\n open: number;\n sockets: number;\n}\n\nconst KNOWN_TYPES = new Set([\"hello\", \"create\", \"join\", \"list\", \"leave\", \"signal\", \"meta\", \"phase\", \"kick\", \"approve\", \"ping\", \"host_changed\", \"path\", \"set_name\"]);\n\nconst str = (o: Json, k: string): string | null => (typeof o[k] === \"string\" ? (o[k] as string) : null);\nconst int = (o: Json, k: string): number | null => {\n const v = o[k];\n return typeof v === \"number\" && Number.isInteger(v) && Math.abs(v) < 2147483647 ? v : null;\n};\nconst bool = (o: Json, k: string): boolean | null => (typeof o[k] === \"boolean\" ? (o[k] as boolean) : null);\nconst has = (o: Json, k: string): boolean => o[k] !== undefined && o[k] !== null;\nconst field = (name: string): Json => ({ field: name });\nconst hex = (n: number): string => randomHex(n);\nconst byCode = (a: string, b: string): number => (a < b ? -1 : a > b ? 1 : 0);\n\n/** Not sanitised (spec/signaling.md): over the limits or non-string values are rejected. */\nfunction readMeta(node: unknown): { meta: Record<string, string> } | { err: string } {\n if (node === undefined || node === null) return { meta: {} };\n if (typeof node !== \"object\" || Array.isArray(node)) return { err: \"meta must be an object of strings\" };\n const entries = Object.entries(node as Json);\n if (entries.length > META_KEYS_MAX) return { err: `meta allows at most ${META_KEYS_MAX} keys` };\n const meta: Record<string, string> = {};\n for (const [k, v] of entries.sort(([a], [b]) => byCode(a, b))) {\n if (typeof v !== \"string\") return { err: \"meta values must be strings\" };\n if (k.length > META_LEN_MAX || v.length > META_LEN_MAX) return { err: `meta keys and values are limited to ${META_LEN_MAX} chars` };\n meta[k] = v;\n }\n return { meta };\n}\n\nexport interface HubDeps {\n /** Unix milliseconds; injected so tests drive time. */\n now?: () => number;\n /** Uniform integer in [0, n). */\n randomInt?: (n: number) => number;\n log?: (line: string) => void;\n}\n\n/** All signaling state and rules (DESIGN s.6, s.7, s.9, s.10, s.12; spec/signaling.md). */\nexport class SignalingHub {\n private readonly o: HubOptions;\n private readonly now: () => number;\n private readonly rand: (n: number) => number;\n private readonly log: (line: string) => void;\n private readonly lobbies = new Map<string, HubLobby>();\n private readonly retired = new Map<string, number>();\n private readonly tokens = new Map<string, { lobby: HubLobby; member: Member }>();\n private readonly sessions = new Map<number, Session>();\n private readonly gameLobbies = new Map<string, number>();\n private readonly ips = new Map<string, IpState>();\n private nextSession = 0;\n private createdOnce = false;\n private members = 0;\n private readonly logSalt = hex(8);\n readonly metrics = new Metrics();\n\n constructor(options: Partial<HubOptions> = {}, deps: HubDeps = {}) {\n this.o = { ...defaultHubOptions(), ...options };\n this.now = deps.now ?? (() => Date.now());\n this.rand = deps.randomInt ?? ((n) => randomBelow(n));\n this.log = deps.log ?? (() => {});\n const m = this.metrics;\n m.gauge(\"onelobby_lobbies\", \"Live lobbies.\", () => this.lobbyCount);\n m.gauge(\"onelobby_sockets\", \"Open signaling sockets.\", () => this.socketCount);\n m.gauge(\"onelobby_lobbies_retired\", \"Join codes held back from reuse.\", () => this.retired.size);\n m.describe(\"onelobby_messages_total\", \"Client messages received, by type.\");\n m.describe(\"onelobby_errors_total\", \"Error replies sent, by code.\");\n m.describe(\"onelobby_path_total\", \"ICE path reports from peers: direct vs relayed (DESIGN s.10).\");\n m.describe(\"onelobby_connections_total\", \"Sockets accepted since start.\");\n m.describe(\"onelobby_lobbies_created_total\", \"Lobbies created since start.\");\n m.describe(\"onelobby_rate_limit_hits_total\", \"Requests refused by a rate limit, by kind.\");\n }\n\n get lobbyCount(): number {\n return this.lobbies.size;\n }\n get socketCount(): number {\n return this.sessions.size;\n }\n private get scale(): number {\n return Math.max(1, this.o.rateScale);\n }\n\n // ---------------------------------------------------------------- connection lifecycle\n\n /** Registers a socket. Returns null (after sending server_full and closing) when over maxPeers. */\n connect(ip: string, send: (text: string) => void, close: (code?: number, reason?: string) => void): Session | null {\n const s = new Session(++this.nextSession, ip, hex(6), send, close);\n s.lastSeen = this.now();\n this.metrics.inc(\"onelobby_connections_total\");\n if (this.sessions.size >= this.o.maxPeers) {\n this.error(s, \"server_full\", \"server is at its peer limit\");\n s.close();\n return null;\n }\n const st = this.ipOf(ip);\n if (!this.o.disableIpLimits && st.sockets >= this.o.socketsPerIp * this.scale) {\n this.rateLimited(s, \"sockets\", 5000, \"max_sockets\");\n s.close(1008, \"too_many_sockets\");\n return null;\n }\n this.sessions.set(s.id, s);\n st.sockets++;\n return s;\n }\n\n disconnect(s: Session): void {\n if (!this.sessions.delete(s.id)) return;\n s.closed = true;\n const st = this.ips.get(s.ip);\n if (st) st.sockets--;\n if (s.pendingIn) {\n s.pendingIn.pending = s.pendingIn.pending.filter((p) => p !== s.pendingMember);\n s.pendingIn = null;\n s.pendingMember = null;\n }\n const m = s.member;\n const lobby = s.lobby;\n if (m && lobby) {\n // The slot and token stay reserved for the resume window (tick expires them); others hear peer_left{timeout} now.\n m.session = null;\n m.detachedAt = this.now();\n s.member = null;\n s.lobby = null;\n this.logEvent(\"detach\", lobby, s);\n this.broadcast(lobby, { t: \"peer_left\", peerId: m.peerId, reason: \"timeout\" });\n this.metrics.inc(\"onelobby_peers_left_total\", \"reason\", \"timeout\");\n if (lobby.hostId === m.peerId) this.promoteHost(lobby, m.peerId);\n }\n }\n\n /**\n * The host's WebRTC link to joiner `peerId` has the remote address `ip` (selected candidate pair; the host's own\n * lobby reports it, a relayed or mDNS address must not be passed). Only Nostr sessions take it: their socket address\n * is a pubkey the joiner chose. A joiner whose link address is banned is removed as kicked; a later kick bans it.\n */\n reportLinkAddress(peerId: number, ip: string): void {\n for (const lobby of this.lobbies.values()) {\n const mem = lobby.find(peerId);\n const sess = mem?.session;\n if (!mem || !sess || !sess.ip.startsWith(NOSTR_ADDR)) continue;\n sess.linkIp = ip;\n if (lobby.kicked.has(ip)) {\n this.removeMember(lobby, mem, \"kicked\");\n this.closeSession(sess);\n }\n return;\n }\n }\n\n private closeSession(s: Session): void {\n s.close();\n this.disconnect(s);\n }\n\n // ---------------------------------------------------------------- time\n\n /** Call about once a second: idle timeouts, resume-window expiry, code retirement. */\n tick(): void {\n const now = this.now();\n for (const s of [...this.sessions.values()])\n if (now - s.lastSeen > this.o.idleTimeoutMs) {\n this.metrics.inc(\"onelobby_idle_timeouts_total\");\n this.closeSession(s);\n }\n for (const lobby of [...this.lobbies.values()])\n for (const m of [...lobby.members]) if (m.detachedAt > 0 && now - m.detachedAt >= this.o.resumeWindowMs) this.removeMember(lobby, m, \"timeout\");\n for (const [code, at] of [...this.retired]) if (now - at >= this.o.codeReuseMs) this.retired.delete(code);\n for (const [key, st] of [...this.ips])\n if (st.sockets <= 0 && st.open <= 0 && st.create.isIdle(now) && st.join.isIdle(now)) this.ips.delete(key);\n }\n\n // ---------------------------------------------------------------- inbound\n\n receive(s: Session, text: string): void {\n if (s.closed) return;\n s.lastSeen = this.now();\n if (text.length > this.o.maxMessageBytes) {\n this.error(s, \"bad_request\", \"message too large\");\n this.closeSession(s);\n return;\n }\n let msg: Json | null = null;\n try {\n const v = JSON.parse(text) as unknown;\n msg = v && typeof v === \"object\" && !Array.isArray(v) ? (v as Json) : null;\n } catch {\n msg = null;\n }\n const t = msg ? str(msg, \"t\") : null;\n if (!msg || t === null) {\n this.error(s, \"bad_request\", \"expected a JSON object with a string t\", field(\"t\"));\n return;\n }\n this.metrics.inc(\"onelobby_messages_total\", \"type\", KNOWN_TYPES.has(t) ? t : \"unknown\");\n if (t === \"hello\") return this.hello(s, msg);\n if (!s.helloDone) {\n if (KNOWN_TYPES.has(t)) this.error(s, \"bad_request\", \"send hello first\");\n return;\n }\n switch (t) {\n case \"create\": return this.create(s, msg);\n case \"join\": return this.join(s, msg);\n case \"list\": return this.list(s, msg);\n case \"leave\": return this.leave(s);\n case \"signal\": return this.signal(s, msg);\n case \"meta\": return this.hostMeta(s, msg);\n case \"phase\": return this.hostPhase(s, msg);\n case \"kick\": return this.kick(s, msg);\n case \"approve\": return this.approve(s, msg);\n case \"ping\": {\n const n = int(msg, \"n\");\n if (n === null || n < 0) return this.error(s, \"bad_request\", \"ping needs an integer n\", field(\"n\"));\n return this.send(s, { t: \"pong\", n });\n }\n case \"host_changed\": return this.claimHost(s, msg);\n case \"path\": return this.pathReport(s, msg);\n case \"set_name\": return this.setName(s, msg);\n default: return; // unknown types are ignored\n }\n }\n\n // ---------------------------------------------------------------- hello / welcome\n\n private hello(s: Session, m: Json): void {\n if (s.helloDone) return this.error(s, \"bad_request\", \"hello already sent\");\n if (str(m, \"proto\") !== PROTO) {\n this.error(s, \"bad_request\", \"unsupported proto, expected lk1\", { supported: [PROTO] });\n this.closeSession(s);\n return;\n }\n if (has(m, \"name\") && str(m, \"name\") === null) return this.error(s, \"bad_request\", \"name must be a string\", field(\"name\"));\n if (has(m, \"client\") && (typeof m.client !== \"object\" || Array.isArray(m.client)))\n return this.error(s, \"bad_request\", \"client must be an object\", field(\"client\"));\n const gameId = str(m, \"gameId\");\n const netVersion = str(m, \"netVersion\");\n if (gameId === null || !GAME_ID.test(gameId)) return this.error(s, \"bad_request\", \"gameId must match [A-Za-z0-9._-]{1,64}\", field(\"gameId\"));\n if (!netVersion || netVersion.length > 32) return this.error(s, \"bad_request\", \"netVersion must be 1-32 characters\", field(\"netVersion\"));\n if (this.o.allowedGames.length > 0 && !this.o.allowedGames.includes(gameId)) {\n this.error(s, \"game_not_allowed\", \"this server does not host that game\");\n this.closeSession(s);\n return;\n }\n s.gameId = gameId;\n s.netVersion = netVersion;\n s.name = sanitize(str(m, \"name\"), NAME_MAX, \"Player\");\n s.helloDone = true;\n\n let resumed: Member | null = null;\n let rl: HubLobby | null = null;\n const token = str(m, \"resumeToken\");\n const entry = token !== null ? this.tokens.get(token) : undefined;\n if (entry && entry.lobby.gameId === gameId && entry.lobby.netVersion === netVersion) {\n // Validate first: a live socket (take-over) or a detached seat still inside the resume window. Only a valid\n // resume closes the old socket (it detaches normally, which starts the window anew).\n const old = entry.member.session;\n const takeOver = old !== null && old !== undefined && old !== s;\n const inWindow = entry.member.detachedAt > 0 && this.now() - entry.member.detachedAt < this.o.resumeWindowMs;\n if (takeOver || inWindow) {\n if (takeOver) this.closeSession(old!);\n resumed = entry.member;\n rl = entry.lobby;\n }\n }\n\n const w: Json = {\n t: \"welcome\",\n ice: this.iceList(s),\n serverTime: this.now(),\n limits: { maxMsg: this.o.maxMessageBytes, maxPlayers: this.o.hardMaxPlayers },\n features: [\"set_name\"],\n };\n if (resumed) w.peerId = resumed.peerId;\n this.send(s, w);\n\n if (resumed && rl) {\n this.tokens.delete(resumed.token);\n resumed.token = hex(16);\n this.tokens.set(resumed.token, { lobby: rl, member: resumed });\n resumed.session = s;\n resumed.detachedAt = 0;\n s.lobby = rl;\n s.member = resumed;\n this.logEvent(\"resume\", rl, s);\n this.metrics.inc(\"onelobby_resumes_total\");\n for (const other of rl.members) if (other !== resumed) this.sendTo(other, { t: \"peer_joined\", peer: this.peerObj(resumed) });\n this.send(s, this.lobbyMsg(rl, resumed));\n }\n }\n\n private iceList(s: Session): Json[] {\n const ice: Json[] = [];\n if (this.o.stunUrls.length > 0) ice.push({ urls: [...this.o.stunUrls] });\n if (this.o.turnUrls.length > 0 && this.o.turnSecret.length > 0) {\n const expiry = Math.floor(this.now() / 1000) + this.o.turnTtlSeconds;\n const username = `${expiry}:${s.connId}`;\n const credential = turnCredential(this.o.turnSecret, username);\n ice.push({ urls: [...this.o.turnUrls], username, credential, ttl: this.o.turnTtlSeconds });\n }\n return ice;\n }\n\n // ---------------------------------------------------------------- create / join / list / leave\n\n private ipOf(ip: string): IpState {\n let st = this.ips.get(ip);\n if (!st) {\n st = { create: new RateWindow(this.o.createPerMin * this.scale, 60_000), join: new RateWindow(this.o.joinPerMin * this.scale, 60_000), open: 0, sockets: 0 };\n this.ips.set(ip, st);\n }\n return st;\n }\n\n private create(s: Session, m: Json): void {\n if (s.lobby || s.pendingIn) return this.error(s, \"bad_request\", \"already in a lobby\");\n const ip = this.ipOf(s.ip);\n const now = this.now();\n if (!this.o.disableIpLimits) {\n if (!ip.create.tryHit(now)) return this.rateLimited(s, \"create\", ip.create.retryAfterMs(now), null);\n if (ip.open >= this.o.openLobbiesPerIp * this.scale) return this.rateLimited(s, \"open_lobbies\", 5000, \"max_lobbies\");\n }\n if (this.o.singleLobby && this.createdOnce) return this.error(s, \"server_full\", \"this host runs one lobby\");\n if (this.lobbies.size >= this.o.maxLobbies || this.members >= this.o.maxPeers) return this.error(s, \"server_full\", \"server is at its lobby limit\");\n const quota = this.o.gameQuotas[s.gameId];\n if (quota !== undefined && (this.gameLobbies.get(s.gameId) ?? 0) >= quota) return this.error(s, \"server_full\", \"lobby quota for this game is reached\");\n\n if (has(m, \"name\") && str(m, \"name\") === null) return this.error(s, \"bad_request\", \"name must be a string\", field(\"name\"));\n const vis = str(m, \"visibility\") ?? \"public\";\n const mode = str(m, \"mode\") ?? \"lockstep\";\n if (vis !== \"public\" && vis !== \"unlisted\" && vis !== \"private\") return this.error(s, \"bad_request\", \"visibility must be public, unlisted or private\", field(\"visibility\"));\n if (mode !== \"lockstep\" && mode !== \"raw\") return this.error(s, \"bad_request\", \"mode must be lockstep or raw\", field(\"mode\"));\n if (has(m, \"maxPlayers\") && int(m, \"maxPlayers\") === null) return this.error(s, \"bad_request\", \"maxPlayers must be an integer\", field(\"maxPlayers\"));\n const maxPlayers = int(m, \"maxPlayers\") ?? 8;\n if (maxPlayers < 2 || maxPlayers > this.o.hardMaxPlayers) return this.error(s, \"bad_request\", `maxPlayers must be 2-${this.o.hardMaxPlayers}`, field(\"maxPlayers\"));\n if (has(m, \"tickRate\") && int(m, \"tickRate\") === null) return this.error(s, \"bad_request\", \"tickRate must be an integer\", field(\"tickRate\"));\n const tick = int(m, \"tickRate\") ?? 20;\n if (tick < 1 || tick > 255) return this.error(s, \"bad_request\", \"tickRate must be 1-255\", field(\"tickRate\"));\n if (has(m, \"lateJoin\") && bool(m, \"lateJoin\") === null) return this.error(s, \"bad_request\", \"lateJoin must be a boolean\", field(\"lateJoin\"));\n if (has(m, \"relayOnly\") && bool(m, \"relayOnly\") === null) return this.error(s, \"bad_request\", \"relayOnly must be a boolean\", field(\"relayOnly\"));\n const meta = readMeta(m.meta);\n if (\"err\" in meta) return this.error(s, \"bad_request\", meta.err, field(\"meta\"));\n\n const code = this.newCode();\n if (code === null) return this.error(s, \"server_full\", \"could not allocate a join code\");\n\n const lobby = new HubLobby();\n Object.assign(lobby, {\n code, gameId: s.gameId, netVersion: s.netVersion, name: sanitize(str(m, \"name\"), LOBBY_NAME_MAX, `${s.name}'s lobby`),\n visibility: vis, mode, tickRate: tick, lateJoin: bool(m, \"lateJoin\") ?? false, relayOnly: bool(m, \"relayOnly\") ?? false,\n maxPlayers, createdAt: now, ownerIp: s.ip, meta: meta.meta,\n });\n this.lobbies.set(code, lobby);\n this.createdOnce = true;\n this.gameLobbies.set(s.gameId, (this.gameLobbies.get(s.gameId) ?? 0) + 1);\n ip.open++;\n this.metrics.inc(\"onelobby_lobbies_created_total\");\n const host = this.addMember(lobby, s, null);\n lobby.hostId = host.peerId;\n this.logEvent(\"create\", lobby, s);\n this.send(s, this.lobbyMsg(lobby, host));\n }\n\n private join(s: Session, m: Json): void {\n if (s.lobby || s.pendingIn) return this.error(s, \"bad_request\", \"already in a lobby\");\n const ip = this.ipOf(s.ip);\n const now = this.now();\n if (!this.o.disableIpLimits && !ip.join.tryHit(now)) return this.rateLimited(s, \"join\", ip.join.retryAfterMs(now), null);\n let lobby: HubLobby | undefined;\n if (this.o.singleLobby && !has(m, \"code\")) {\n // direct IP: the address is the invitation, so a join without a code means the one lobby\n lobby = this.lobbies.values().next().value;\n if (!lobby || lobby.gameId !== s.gameId) return this.error(s, \"unknown_code\", \"this host has no open lobby for that game\");\n } else {\n const code = normalizeCode(m.code);\n if (code === null) return this.error(s, \"bad_request\", \"malformed join code\", field(\"code\"));\n lobby = this.lobbies.get(code);\n if (!lobby || lobby.gameId !== s.gameId) return this.error(s, \"unknown_code\", \"no lobby with that code\");\n }\n if (this.o.password !== null && str(m, \"password\") !== this.o.password) return this.error(s, \"bad_password\", \"wrong password for this lobby\");\n if (lobby.netVersion !== s.netVersion)\n return this.error(s, \"version_mismatch\", `host is on ${lobby.netVersion}, you are on ${s.netVersion}`, { hostNetVersion: lobby.netVersion, yourNetVersion: s.netVersion });\n if (lobby.kicked.has(s.ip)) return this.error(s, \"kicked\", \"you were removed from this lobby\");\n if (lobby.phase === \"in_game\" && !lobby.lateJoin) return this.error(s, \"in_game\", \"the game has already started\");\n if (lobby.members.length >= lobby.maxPlayers) return this.error(s, \"lobby_full\", \"lobby is full\");\n if (this.members >= this.o.maxPeers) return this.error(s, \"server_full\", \"server is at its peer limit\");\n\n if (lobby.visibility === \"private\") {\n if (lobby.pending.length >= PENDING_MAX) return this.error(s, \"lobby_full\", \"too many pending requests\");\n const pm = new Member();\n pm.peerId = lobby.nextPeerId++;\n pm.name = s.name;\n pm.session = s;\n pm.ip = s.ip;\n lobby.pending.push(pm);\n s.pendingIn = lobby;\n s.pendingMember = pm;\n const hs = lobby.find(lobby.hostId)?.session;\n if (hs) this.send(hs, { t: \"join_request\", peer: this.peerObj(pm) });\n this.logEvent(\"join_request\", lobby, s);\n return;\n }\n this.admit(lobby, s, null);\n }\n\n private admit(lobby: HubLobby, s: Session, pending: Member | null): void {\n const joiner = this.addMember(lobby, s, pending);\n this.logEvent(\"join\", lobby, s);\n for (const other of lobby.members) if (other !== joiner) this.sendTo(other, { t: \"peer_joined\", peer: this.peerObj(joiner) });\n // A lobby whose host slot is only reserved (host dropped, nobody was connected) hands over to the first newcomer.\n if (!lobby.find(lobby.hostId)?.session) this.promoteHost(lobby, lobby.hostId);\n this.send(s, this.lobbyMsg(lobby, joiner));\n }\n\n private addMember(lobby: HubLobby, s: Session, reuse: Member | null): Member {\n const mem = reuse ?? new Member();\n if (!reuse) mem.peerId = lobby.nextPeerId++;\n mem.name = s.name;\n mem.session = s;\n mem.ip = s.ip;\n mem.joinedAt = this.now();\n mem.detachedAt = 0;\n mem.token = hex(16);\n lobby.members.push(mem);\n this.members++;\n this.tokens.set(mem.token, { lobby, member: mem });\n s.lobby = lobby;\n s.member = mem;\n s.pendingIn = null;\n s.pendingMember = null;\n return mem;\n }\n\n private list(s: Session, m: Json): void {\n const vis = str(m, \"visibility\");\n if (!this.o.issueCodes) return this.send(s, { t: \"lobbies\", items: [] });\n if (vis !== \"public\") return this.error(s, \"bad_request\", \"only public lobbies can be listed\", field(\"visibility\"));\n let limit = 50;\n if (has(m, \"limit\")) {\n const l = int(m, \"limit\");\n if (l === null || l < 1 || l > this.o.listLimitMax) return this.error(s, \"bad_request\", `limit must be 1-${this.o.listLimitMax}`, field(\"limit\"));\n limit = l;\n }\n let offset = 0;\n if (has(m, \"cursor\")) {\n const c = str(m, \"cursor\");\n if (c === null || !/^\\d+$/.test(c)) return this.error(s, \"bad_request\", \"bad cursor\", field(\"cursor\"));\n offset = Number(c);\n }\n let filter: Record<string, string> | null = null;\n if (has(m, \"meta\")) {\n if (typeof m.meta !== \"object\" || Array.isArray(m.meta)) return this.error(s, \"bad_request\", \"meta must be an object\", field(\"meta\"));\n filter = {};\n for (const [k, v] of Object.entries(m.meta as Json)) {\n if (typeof v !== \"string\") return this.error(s, \"bad_request\", \"meta values must be strings\", field(\"meta\"));\n filter[k] = v;\n }\n }\n const all = [...this.lobbies.values()]\n .filter((l) => l.gameId === s.gameId && l.netVersion === s.netVersion && l.visibility === \"public\" && (l.phase !== \"in_game\" || l.lateJoin)\n && (filter === null || Object.entries(filter).every(([k, v]) => l.meta[k] === v)))\n .sort((a, b) => a.createdAt - b.createdAt || byCode(a.code, b.code));\n const page = all.slice(offset, offset + limit);\n const items = page.map((l) => ({\n code: l.code, gameId: l.gameId, netVersion: l.netVersion, name: l.name, hostName: l.find(l.hostId)?.name ?? \"\",\n players: l.members.length, maxPlayers: l.maxPlayers, phase: l.phase, meta: { ...l.meta }, region: this.o.region, createdAt: l.createdAt,\n }));\n const reply: Json = { t: \"lobbies\", items };\n if (offset + page.length < all.length) reply.cursor = String(offset + page.length);\n this.send(s, reply);\n }\n\n private leave(s: Session): void {\n if (s.pendingIn) {\n s.pendingIn.pending = s.pendingIn.pending.filter((p) => p !== s.pendingMember);\n s.pendingIn = null;\n s.pendingMember = null;\n return;\n }\n if (!s.lobby || !s.member) return;\n this.removeMember(s.lobby, s.member, \"left\");\n }\n\n // ---------------------------------------------------------------- relay + host-only\n\n private signal(s: Session, m: Json): void {\n const lobby = s.lobby;\n const me = s.member;\n if (!lobby || !me) return this.error(s, \"bad_request\", \"not in a lobby\");\n const to = int(m, \"to\");\n const target = to === null ? undefined : lobby.find(to);\n if (!target || !target.session || target === me) return this.error(s, \"bad_request\", \"unknown signal target\", field(\"to\"));\n // a direct hub has no migration: the only peer links are host <-> joiner, so a joiner cannot dial another joiner\n if (this.o.singleLobby && me.peerId !== lobby.hostId && target.peerId !== lobby.hostId)\n return this.error(s, \"bad_request\", \"signals go to or from the host only\", field(\"to\"));\n const now = this.now();\n const rate = this.signalRate(s, target, now);\n if (!rate.tryHit(now)) return this.rateLimited(s, \"signal\", rate.retryAfterMs(now), null);\n const total = (s.signalTotal ??= new RateWindow(this.o.signalPerSec * SIGNAL_FANOUT * this.scale, 1000));\n if (!total.tryHit(now)) return this.rateLimited(s, \"signal\", total.retryAfterMs(now), null);\n if (!has(m, \"sdp\") && !has(m, \"ice\")) return this.error(s, \"bad_request\", \"signal needs sdp or ice\", field(\"sdp\"));\n const o: Json = { t: \"signal\", from: me.peerId };\n if (has(m, \"sdp\")) o.sdp = m.sdp;\n if (has(m, \"ice\")) o.ice = m.ice;\n this.send(target.session, o);\n this.metrics.inc(\"onelobby_signals_relayed_total\");\n }\n\n /**\n * spec/signaling.md rate limits: `signal` is counted per sender and target, so a host answering several joiners at once\n * gets the budget for each, and per sender in total (SIGNAL_FANOUT targets' worth).\n */\n private signalRate(s: Session, to: Member, now: number): RateWindow {\n let w = s.signalRates.get(to);\n if (!w) {\n for (const [k, v] of s.signalRates) if (v.isIdle(now)) s.signalRates.delete(k);\n // relays refuse high publish rates, so a Nostr-bridged target gets half the budget\n w = new RateWindow((to.session?.ip.startsWith(NOSTR_ADDR) ? NOSTR_SIGNAL_PER_SEC : this.o.signalPerSec) * this.scale, 1000);\n s.signalRates.set(to, w);\n }\n return w;\n }\n\n private requireHost(s: Session): HubLobby | null {\n if (!s.lobby || !s.member) {\n this.error(s, \"bad_request\", \"not in a lobby\");\n return null;\n }\n if (s.lobby.hostId !== s.member.peerId) {\n this.error(s, \"not_host\", \"only the host can do that\");\n return null;\n }\n return s.lobby;\n }\n\n private hostMeta(s: Session, m: Json): void {\n const lobby = this.requireHost(s);\n if (!lobby) return;\n const meta = readMeta(m.meta);\n if (\"err\" in meta || !has(m, \"meta\")) return this.error(s, \"bad_request\", \"err\" in meta ? meta.err : \"meta is required\", field(\"meta\"));\n lobby.meta = meta.meta;\n this.broadcastLobby(lobby);\n }\n\n private setName(s: Session, m: Json): void {\n if (!s.lobby || !s.member) return this.error(s, \"bad_request\", \"not in a lobby\");\n const name = typeof m.name === \"string\" ? sanitize(m.name, NAME_MAX) : \"\";\n if (!name) return this.error(s, \"bad_request\", \"name must be a non-empty string\", field(\"name\"));\n if (name === s.member.name) return;\n const now = this.now();\n const rate = (s.member.renames ??= new RateWindow(this.scale, 1000));\n if (!rate.tryHit(now)) return this.rateLimited(s, \"set_name\", rate.retryAfterMs(now), null);\n s.member.name = name;\n s.name = name;\n this.broadcastLobby(s.lobby);\n }\n\n private hostPhase(s: Session, m: Json): void {\n const lobby = this.requireHost(s);\n if (!lobby) return;\n const ph = str(m, \"phase\");\n if (ph !== \"in_game\" && ph !== \"lobby\") return this.error(s, \"bad_request\", \"phase must be in_game or lobby\", field(\"phase\"));\n lobby.phase = ph;\n this.logEvent(`phase:${ph}`, lobby, s);\n this.broadcastLobby(lobby);\n }\n\n private kick(s: Session, m: Json): void {\n const lobby = this.requireHost(s);\n if (!lobby) return;\n const id = int(m, \"peerId\");\n const target = id === null ? undefined : lobby.find(id);\n if (id === null || id === s.member!.peerId || !target) return this.error(s, \"bad_request\", \"unknown peerId\", field(\"peerId\"));\n // ban:false disconnects without the ban; closeCode / closeReason are passed to the removed peer (spec/signaling.md)\n const ban = bool(m, \"ban\");\n if (has(m, \"ban\") && ban === null) return this.error(s, \"bad_request\", \"ban must be a boolean\", field(\"ban\"));\n const code = int(m, \"closeCode\");\n if (has(m, \"closeCode\") && (code === null || !(code === 1000 || (code >= 3000 && code <= 4999))))\n return this.error(s, \"bad_request\", \"closeCode must be 1000 or 3000-4999\", field(\"closeCode\"));\n const closeReason = str(m, \"closeReason\");\n if (has(m, \"closeReason\") && (closeReason === null || closeReason.length > 120))\n return this.error(s, \"bad_request\", \"closeReason must be a string of at most 120 characters\", field(\"closeReason\"));\n const data: Json = {};\n if (ban === false) data.ban = false;\n if (code !== null) data.closeCode = code;\n if (closeReason !== null) data.closeReason = closeReason;\n if (ban !== false) {\n lobby.kicked.add(target.ip);\n // a Nostr joiner picks its own key, so also ban the address its WebRTC link came from, when the host saw it\n const link = target.session?.linkIp;\n if (link && target.ip.startsWith(NOSTR_ADDR)) lobby.kicked.add(link);\n }\n this.removeMember(lobby, target, ban === false ? \"disconnected\" : \"kicked\", Object.keys(data).length ? data : undefined);\n }\n\n private approve(s: Session, m: Json): void {\n const lobby = this.requireHost(s);\n if (!lobby) return;\n const id = int(m, \"peerId\");\n const pm = id === null ? undefined : lobby.pending.find((p) => p.peerId === id);\n const js = pm?.session;\n if (!pm || !js) return this.error(s, \"bad_request\", \"no such pending request\", field(\"peerId\"));\n if (has(m, \"ok\") && bool(m, \"ok\") === null) return this.error(s, \"bad_request\", \"ok must be a boolean\", field(\"ok\"));\n lobby.pending = lobby.pending.filter((p) => p !== pm);\n js.pendingIn = null;\n js.pendingMember = null;\n if (bool(m, \"ok\") !== true) return this.error(js, \"kicked\", \"the host declined your request\", { reason: \"denied\" });\n if (lobby.members.length >= lobby.maxPlayers) return this.error(js, \"lobby_full\", \"lobby is full\");\n if (lobby.phase === \"in_game\" && !lobby.lateJoin) return this.error(js, \"in_game\", \"the game has already started\");\n this.admit(lobby, js, pm);\n }\n\n /** Peer-side migration (s.9) tells the server: the new host announces itself with a higher epoch. */\n private claimHost(s: Session, m: Json): void {\n const lobby = s.lobby;\n const me = s.member;\n if (!lobby || !me) return;\n const host = int(m, \"hostId\");\n const epoch = int(m, \"epoch\");\n if (host !== me.peerId || epoch === null || epoch <= lobby.epoch) return;\n if (this.o.singleLobby) return; // direct lobbies have no migration: the host leaving ends the session\n if (lobby.hostId !== me.peerId && lobby.find(lobby.hostId)?.session) {\n // The host is still here, so a member cannot take over. Remember the best claim for when the host goes.\n if (epoch > lobby.pendingClaimEpoch) {\n lobby.pendingClaimPeer = me.peerId;\n lobby.pendingClaimEpoch = epoch;\n }\n return;\n }\n lobby.hostId = me.peerId;\n lobby.epoch = epoch;\n lobby.pendingClaimPeer = lobby.pendingClaimEpoch = 0;\n this.broadcast(lobby, { t: \"host_changed\", hostId: lobby.hostId, epoch: lobby.epoch });\n this.metrics.inc(\"onelobby_host_changes_total\");\n this.logEvent(\"host_claim\", lobby, s);\n }\n\n private pathReport(s: Session, m: Json): void {\n const p = str(m, \"path\");\n if (p === \"relayed\" || p === \"direct\") this.metrics.inc(\"onelobby_path_total\", \"path\", p);\n else this.error(s, \"bad_request\", \"path must be relayed or direct\", field(\"path\"));\n }\n\n // ---------------------------------------------------------------- membership changes\n\n /** Removes a member for good. A member that is already detached was announced as left, so nothing is sent for it. */\n private removeMember(lobby: HubLobby, mem: Member, reason: string, kickData?: Json): void {\n const i = lobby.members.indexOf(mem);\n if (i < 0) return;\n lobby.members.splice(i, 1);\n this.members--;\n this.tokens.delete(mem.token);\n const ms = mem.session;\n const wasConnected = mem.detachedAt === 0;\n if (ms) {\n ms.lobby = null;\n ms.member = null;\n }\n if (wasConnected) {\n this.broadcast(lobby, { t: \"peer_left\", peerId: mem.peerId, reason });\n this.metrics.inc(\"onelobby_peers_left_total\", \"reason\", reason);\n if ((reason === \"kicked\" || reason === \"disconnected\") && ms)\n this.error(ms, \"kicked\", reason === \"kicked\" ? \"the host removed you from the lobby\" : \"the host disconnected you\", kickData);\n }\n this.logEvent(reason, lobby, ms);\n if (lobby.members.length === 0) return this.closeLobby(lobby);\n if (lobby.hostId === mem.peerId) this.promoteHost(lobby, mem.peerId);\n }\n\n /** Server mirror of the peer-side rule (s.9): new host is the lowest peerId still connected; epoch +1. */\n private promoteHost(lobby: HubLobby, leavingId: number): void {\n // A claim made while the old host was alive wins if its claimant is still connected.\n const claimant =\n lobby.pendingClaimEpoch > lobby.epoch && lobby.pendingClaimPeer !== leavingId\n ? lobby.members.find((x) => x.peerId === lobby.pendingClaimPeer && x.session)\n : undefined;\n const claimEpoch = lobby.pendingClaimEpoch;\n lobby.pendingClaimPeer = lobby.pendingClaimEpoch = 0;\n let next = claimant ?? lobby.members.filter((x) => x.session && x.peerId !== leavingId).sort((a, b) => a.peerId - b.peerId)[0];\n if (!next) {\n // Nobody connected. Keep a reserved host slot (it may resume); otherwise fall back to the lowest slot.\n if (lobby.find(leavingId)) return;\n next = [...lobby.members].sort((a, b) => a.peerId - b.peerId)[0];\n if (!next) return;\n }\n lobby.hostId = next.peerId;\n if (claimant) lobby.epoch = claimEpoch;\n else lobby.epoch++;\n this.broadcast(lobby, { t: \"host_changed\", hostId: next.peerId, epoch: lobby.epoch });\n this.metrics.inc(\"onelobby_host_changes_total\");\n const hs = next.session;\n if (hs) for (const pm of lobby.pending) this.send(hs, { t: \"join_request\", peer: this.peerObj(pm) }); // the new host inherits the pending requests\n this.logEvent(\"host_changed\", lobby, next.session);\n }\n\n private closeLobby(lobby: HubLobby): void {\n this.lobbies.delete(lobby.code);\n this.retired.set(lobby.code, this.now());\n const n = this.gameLobbies.get(lobby.gameId);\n if (n !== undefined) {\n if (n <= 1) this.gameLobbies.delete(lobby.gameId);\n else this.gameLobbies.set(lobby.gameId, n - 1);\n }\n const ip = this.ips.get(lobby.ownerIp);\n if (ip && ip.open > 0) ip.open--;\n for (const pm of [...lobby.pending]) {\n const ps = pm.session;\n if (ps) {\n ps.pendingIn = null;\n ps.pendingMember = null;\n this.error(ps, \"unknown_code\", \"the lobby closed\");\n }\n }\n lobby.pending = [];\n this.logEvent(\"close\", lobby, null);\n }\n\n private newCode(): string | null {\n for (let i = 0; i < 100; i++) {\n let c = \"\";\n for (let k = 0; k < 6; k++) c += CROCKFORD[this.rand(32)];\n if (!this.lobbies.has(c) && !this.retired.has(c)) return c;\n }\n return null;\n }\n\n // ---------------------------------------------------------------- output helpers\n\n private lobbyMsg(l: HubLobby, you: Member): Json {\n const peers = l.members\n .filter((x) => x.detachedAt === 0)\n .sort((a, b) => a.peerId - b.peerId)\n .map((p) => ({ peerId: p.peerId, name: p.name, joinedAt: p.joinedAt }));\n return {\n t: \"lobby\", code: this.o.issueCodes ? l.code : \"\", gameId: l.gameId, netVersion: l.netVersion, hostId: l.hostId, you: you.peerId,\n mode: l.mode, tickRate: l.tickRate, lateJoin: l.lateJoin, phase: l.phase, meta: { ...l.meta }, peers, resumeToken: you.token,\n name: l.name, maxPlayers: l.maxPlayers, visibility: l.visibility, relayOnly: l.relayOnly,\n };\n }\n\n private broadcastLobby(l: HubLobby): void {\n for (const m of l.members) if (m.session) this.sendTo(m, this.lobbyMsg(l, m));\n }\n\n private broadcast(l: HubLobby, o: Json): void {\n for (const m of l.members) this.sendTo(m, o);\n }\n\n private peerObj(m: Member): Json {\n return { peerId: m.peerId, name: m.name };\n }\n\n private send(s: Session, o: Json): void {\n if (!s.closed) s.send(JSON.stringify(o));\n }\n\n private sendTo(m: Member, o: Json): void {\n if (m.session) this.send(m.session, o);\n }\n\n private error(s: Session, code: string, msg: string, data?: Json): void {\n this.metrics.inc(\"onelobby_errors_total\", \"code\", code);\n const o: Json = { t: \"error\", code, msg };\n if (data !== undefined) o.data = data;\n s.send(JSON.stringify(o));\n }\n\n private rateLimited(s: Session, kind: string, retryAfterMs: number, reason: string | null): void {\n this.metrics.inc(\"onelobby_rate_limit_hits_total\", \"kind\", kind);\n this.log(`rate_limit kind=${kind} ip=${this.hashIp(s.ip)}`);\n const data: Json = { retryAfterMs };\n if (reason !== null) data.reason = reason;\n this.error(s, \"rate_limited\", `too many ${kind} requests`, data);\n }\n\n private logEvent(ev: string, l: HubLobby, s: Session | null): void {\n this.log(`lobby ${ev} code=${l.code} game=${l.gameId} players=${l.members.length} ip=${s ? this.hashIp(s.ip) : \"-\"}`);\n }\n\n private hashIp(ip: string): string {\n return shortHash(this.logSalt + ip);\n }\n}\n"]}
@@ -31,6 +31,7 @@ export declare const ErrorCodes: {
31
31
  readonly DirectUnreachable: "direct_unreachable";
32
32
  readonly BadAddress: "bad_address";
33
33
  readonly PortInUse: "port_in_use";
34
+ readonly Unsupported: "unsupported";
34
35
  readonly ConnectFailed: "connect_failed";
35
36
  readonly Closed: "closed";
36
37
  readonly ServerLost: "server_lost";
package/dist/friendly.js CHANGED
@@ -29,6 +29,7 @@ export const ErrorCodes = {
29
29
  DirectUnreachable: "direct_unreachable",
30
30
  BadAddress: "bad_address",
31
31
  PortInUse: "port_in_use",
32
+ Unsupported: "unsupported",
32
33
  ConnectFailed: "connect_failed",
33
34
  Closed: "closed",
34
35
  ServerLost: "server_lost",
@@ -69,6 +70,7 @@ const TEXT = {
69
70
  ice_failed: { message: "Couldn't connect to the other players.", hint: "Some networks (school, work, public Wi-Fi) block game connections. Try another network or a phone hotspot." },
70
71
  no_server: { message: "This game has no lobby server address yet.", hint: "Enter one in the multiplayer settings, or host from your own computer with a join code." },
71
72
  timeout: { message: "The connection took too long.", hint: "Check your internet connection, then try again." },
73
+ unsupported: { message: "The host's game is too old for that.", hint: "Ask the host to update the game." },
72
74
  voice_disabled: { message: "Voice chat is turned off in this game." },
73
75
  chat_disabled: { message: "Text chat is turned off in this game." },
74
76
  pause_disabled: { message: "Pausing is turned off in this game." },