onelobby 0.2.0 → 0.2.1

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.
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.2.0/dist/onelobby.global.min.js"></script>
12
+ <script src="https://cdn.jsdelivr.net/npm/onelobby@0.2.1/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.2.0/dist/onelobby.bundle.mjs"`.
54
+ Without a bundler: `import { OneLobby } from "https://cdn.jsdelivr.net/npm/onelobby@0.2.1/dist/onelobby.bundle.mjs"`.
55
55
 
56
56
  ## Made for players
57
57
 
@@ -682,8 +682,26 @@ export class SignalingHub {
682
682
  const target = id === null ? undefined : lobby.find(id);
683
683
  if (id === null || id === s.member.peerId || !target)
684
684
  return this.error(s, "bad_request", "unknown peerId", field("peerId"));
685
- lobby.kicked.add(target.ip);
686
- this.removeMember(lobby, target, "kicked");
685
+ // ban:false disconnects without the ban; closeCode / closeReason are passed to the removed peer (spec/signaling.md)
686
+ const ban = bool(m, "ban");
687
+ if (has(m, "ban") && ban === null)
688
+ return this.error(s, "bad_request", "ban must be a boolean", field("ban"));
689
+ const code = int(m, "closeCode");
690
+ if (has(m, "closeCode") && (code === null || !(code === 1000 || (code >= 3000 && code <= 4999))))
691
+ return this.error(s, "bad_request", "closeCode must be 1000 or 3000-4999", field("closeCode"));
692
+ const closeReason = str(m, "closeReason");
693
+ if (has(m, "closeReason") && (closeReason === null || closeReason.length > 120))
694
+ return this.error(s, "bad_request", "closeReason must be a string of at most 120 characters", field("closeReason"));
695
+ const data = {};
696
+ if (ban === false)
697
+ data.ban = false;
698
+ if (code !== null)
699
+ data.closeCode = code;
700
+ if (closeReason !== null)
701
+ data.closeReason = closeReason;
702
+ if (ban !== false)
703
+ lobby.kicked.add(target.ip);
704
+ this.removeMember(lobby, target, ban === false ? "disconnected" : "kicked", Object.keys(data).length ? data : undefined);
687
705
  }
688
706
  approve(s, m) {
689
707
  const lobby = this.requireHost(s);
@@ -729,7 +747,7 @@ export class SignalingHub {
729
747
  }
730
748
  // ---------------------------------------------------------------- membership changes
731
749
  /** Removes a member for good. A member that is already detached was announced as left, so nothing is sent for it. */
732
- removeMember(lobby, mem, reason) {
750
+ removeMember(lobby, mem, reason, kickData) {
733
751
  const i = lobby.members.indexOf(mem);
734
752
  if (i < 0)
735
753
  return;
@@ -744,8 +762,8 @@ export class SignalingHub {
744
762
  }
745
763
  if (wasConnected) {
746
764
  this.broadcast(lobby, { t: "peer_left", peerId: mem.peerId, reason });
747
- if (reason === "kicked" && ms)
748
- this.error(ms, "kicked", "the host removed you from the lobby");
765
+ if ((reason === "kicked" || reason === "disconnected") && ms)
766
+ this.error(ms, "kicked", reason === "kicked" ? "the host removed you from the lobby" : "the host disconnected you", kickData);
749
767
  }
750
768
  this.logEvent(reason, lobby, ms);
751
769
  if (lobby.members.length === 0)
@@ -1 +1 @@
1
- {"version":3,"file":"hub.js","sourceRoot":"","sources":["../../src/direct/hub.ts"],"names":[],"mappings":"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","sourcesContent":["/// <reference types=\"node\" />\nimport { createHash, createHmac, randomBytes, randomInt } from \"node:crypto\";\n\n/**\n * The signaling hub (protocol lk1) in TypeScript, for a Node process that hosts direct-IP lobbies\n * (docs/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 are left out (that is onelobby-server's job); everything else (codes, list, resume, private lobbies,\n * kicks, migration claims, TURN credentials, rate limits) behaves as in C#.\n */\n\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 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, 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/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/** 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: () => void,\n readonly signalRate: RateWindow,\n ) {}\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 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 => randomBytes(n).toString(\"hex\");\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\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) => randomInt(n));\n this.log = deps.log ?? (() => {});\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: () => void): Session | null {\n const s = new Session(++this.nextSession, ip, hex(6), send, close, new RateWindow(this.o.signalPerSec * this.scale, 1000));\n s.lastSeen = this.now();\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 this.sessions.set(s.id, s);\n this.ipOf(ip).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 if (lobby.hostId === m.peerId) this.promoteHost(lobby, m.peerId);\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()]) if (now - s.lastSeen > this.o.idleTimeoutMs) this.closeSession(s);\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 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 // A token whose old socket is still open is a take-over: drop the old socket first (it detaches normally).\n const old = entry.member.session;\n if (old && old !== s) this.closeSession(old);\n if (entry.member.detachedAt > 0 && this.now() - entry.member.detachedAt < this.o.resumeWindowMs) {\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 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 = createHmac(\"sha1\", this.o.turnSecret).update(username).digest(\"base64\");\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 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 now = this.now();\n if (!this.o.disableIpLimits && !s.signalRate.tryHit(now)) return this.rateLimited(s, \"signal\", s.signalRate.retryAfterMs(now), null);\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 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 }\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 lobby.kicked.add(target.ip);\n this.removeMember(lobby, target, \"kicked\");\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 lobby.hostId = me.peerId;\n lobby.epoch = epoch;\n this.broadcast(lobby, { t: \"host_changed\", hostId: lobby.hostId, epoch: lobby.epoch });\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.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): 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 if (reason === \"kicked\" && ms) this.error(ms, \"kicked\", \"the host removed you from the lobby\");\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 let next = 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 lobby.epoch++;\n this.broadcast(lobby, { t: \"host_changed\", hostId: next.peerId, epoch: lobby.epoch });\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 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.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 createHash(\"sha256\").update(this.logSalt + ip).digest(\"hex\").slice(0, 8);\n }\n}\n"]}
1
+ {"version":3,"file":"hub.js","sourceRoot":"","sources":["../../src/direct/hub.ts"],"names":[],"mappings":"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","sourcesContent":["/// <reference types=\"node\" />\nimport { createHash, createHmac, randomBytes, randomInt } from \"node:crypto\";\n\n/**\n * The signaling hub (protocol lk1) in TypeScript, for a Node process that hosts direct-IP lobbies\n * (docs/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 are left out (that is onelobby-server's job); everything else (codes, list, resume, private lobbies,\n * kicks, migration claims, TURN credentials, rate limits) behaves as in C#.\n */\n\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 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, 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/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/** 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: () => void,\n readonly signalRate: RateWindow,\n ) {}\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 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 => randomBytes(n).toString(\"hex\");\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\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) => randomInt(n));\n this.log = deps.log ?? (() => {});\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: () => void): Session | null {\n const s = new Session(++this.nextSession, ip, hex(6), send, close, new RateWindow(this.o.signalPerSec * this.scale, 1000));\n s.lastSeen = this.now();\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 this.sessions.set(s.id, s);\n this.ipOf(ip).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 if (lobby.hostId === m.peerId) this.promoteHost(lobby, m.peerId);\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()]) if (now - s.lastSeen > this.o.idleTimeoutMs) this.closeSession(s);\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 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 // A token whose old socket is still open is a take-over: drop the old socket first (it detaches normally).\n const old = entry.member.session;\n if (old && old !== s) this.closeSession(old);\n if (entry.member.detachedAt > 0 && this.now() - entry.member.detachedAt < this.o.resumeWindowMs) {\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 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 = createHmac(\"sha1\", this.o.turnSecret).update(username).digest(\"base64\");\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 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 now = this.now();\n if (!this.o.disableIpLimits && !s.signalRate.tryHit(now)) return this.rateLimited(s, \"signal\", s.signalRate.retryAfterMs(now), null);\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 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 }\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) lobby.kicked.add(target.ip);\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 lobby.hostId = me.peerId;\n lobby.epoch = epoch;\n this.broadcast(lobby, { t: \"host_changed\", hostId: lobby.hostId, epoch: lobby.epoch });\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.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 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 let next = 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 lobby.epoch++;\n this.broadcast(lobby, { t: \"host_changed\", hostId: next.peerId, epoch: lobby.epoch });\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 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.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 createHash(\"sha256\").update(this.logSalt + ip).digest(\"hex\").slice(0, 8);\n }\n}\n"]}
@@ -20,8 +20,13 @@ export { PortMapper, isPublicIPv4, lanIPv4, localAddresses } from "./portmap.js"
20
20
  export type { PortMapResult, PortMapperOptions, PortMapMethod } from "./portmap.js";
21
21
  export { webRtcLinkFactoryFor } from "../webrtc.js";
22
22
  export interface DirectHostOptions {
23
- /** TCP and UDP port to listen on (default 47810). */
23
+ /**
24
+ * TCP and UDP port to listen on (default 47810). When it is busy (another program holds it) the next free one of the
25
+ * following `fallbackPorts` is used; the join code carries the port, so friends never type it.
26
+ */
24
27
  port?: number;
28
+ /** How many ports after `port` to try when it is busy; default 9 with `port` left out, else 0. */
29
+ fallbackPorts?: number;
25
30
  /** Optional; joiners must send the same one or get `bad_password`. */
26
31
  password?: string;
27
32
  maxPlayers?: number;
@@ -54,4 +59,6 @@ export type DirectLobby = Lobby & {
54
59
  * When the lobby ends (leave, or the process exits) the listener closes and the router mapping is removed; joiners
55
60
  * get `sessionEnded("host_left")`.
56
61
  */
62
+ /** With `port` left out, how many ports after the default `hostDirect` tries when it is busy. */
63
+ export declare const DEFAULT_FALLBACK_PORTS = 9;
57
64
  export declare function hostDirect(kit: OneLobby, o?: DirectHostOptions): Promise<DirectLobby>;
@@ -15,19 +15,28 @@ export { webRtcLinkFactoryFor } from "../webrtc.js";
15
15
  * When the lobby ends (leave, or the process exits) the listener closes and the router mapping is removed; joiners
16
16
  * get `sessionEnded("host_left")`.
17
17
  */
18
+ /** With `port` left out, how many ports after the default `hostDirect` tries when it is busy. */
19
+ export const DEFAULT_FALLBACK_PORTS = 9;
18
20
  export async function hostDirect(kit, o = {}) {
19
21
  const port = o.port ?? DEFAULT_DIRECT_PORT;
22
+ // busy (another program holds it): try the next fallbackPorts; the join code carries the port
23
+ const last = port + Math.max(0, o.fallbackPorts ?? (o.port === undefined ? DEFAULT_FALLBACK_PORTS : 0));
20
24
  const maxPlayers = o.maxPlayers ?? 4;
21
25
  let hub;
22
- try {
23
- hub = await DirectHubHost.listen(port, directHubOptions(maxPlayers, o.password));
24
- hub.http = o.http ?? null;
25
- }
26
- catch (e) {
27
- if (e instanceof PortInUseError)
28
- throw new OneLobbyError("port_in_use", e.message.replace(/^port_in_use: /, ""));
29
- throw e;
26
+ for (let p = port; !hub; p++) {
27
+ try {
28
+ hub = await DirectHubHost.listen(p, directHubOptions(maxPlayers, o.password));
29
+ }
30
+ catch (e) {
31
+ if (!(e instanceof PortInUseError))
32
+ throw e;
33
+ if (p < last)
34
+ continue;
35
+ const range = last > port ? `ports ${port}-${last}` : `port ${port}`;
36
+ throw new OneLobbyError("port_in_use", `cannot listen on ${range}: is another copy of the game hosting?`);
37
+ }
30
38
  }
39
+ hub.http = o.http ?? null;
31
40
  // The router request runs alongside lobby creation; it takes up to a few seconds when nothing answers.
32
41
  const mapping = o.openPort === false
33
42
  ? Promise.resolve(null)
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/direct/index.ts"],"names":[],"mappings":"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","sourcesContent":["/// <reference types=\"node\" />\n/**\n * `onelobby/direct` (Node only): host a direct-IP lobby from a Node process, with no server of anyone's\n * (docs/direct-ip.md). The process runs the signaling hub, listens on TCP `port`, binds its peer links to UDP `port`,\n * asks the router to forward both (UPnP, then NAT-PMP) and hands out a join code. Joiners use `kit.joinDirect(code)`\n * from `onelobby` (Node or browser) or `JoinDirectAsync` in C#; the wire protocol is the same, so they mix.\n *\n * WebRTC in Node needs an RTCPeerConnection: `npm install node-datachannel`, then\n * `advanced: { linkFactory: webRtcLinkFactoryFor(RTCPeerConnection) }` with\n * `import { RTCPeerConnection } from \"node-datachannel/polyfill\"`. Its libdatachannel honours the port pin.\n */\nimport type { HostOptions, OneLobby } from \"../onelobby.js\";\nimport type { Lobby, RateLimit } from \"../lobby.js\";\nimport type { LinkFactory } from \"../transport.js\";\nimport { encodeJoinCode } from \"../joincode.js\";\nimport { DEFAULT_DIRECT_PORT } from \"../direct-address.js\";\nimport { DirectHubHost, PortInUseError, type HttpHandler } from \"./hub-host.js\";\nimport { directHubOptions } from \"./hub.js\";\nimport { isPublicIPv4, lanIPv4, localAddresses, type PortMapResult, type PortMapperOptions } from \"./portmap.js\";\nimport { OneLobbyError } from \"../signaling.js\";\n\nexport { DirectHubHost, LocalHubSocket, PortInUseError } from \"./hub-host.js\";\nexport type { HttpHandler, HttpReply } from \"./hub-host.js\";\nexport { SignalingHub, Session, RateWindow, sanitize, defaultHubOptions, directHubOptions, PROTO } from \"./hub.js\";\nexport type { HubOptions, HubDeps } from \"./hub.js\";\nexport { PortMapper, isPublicIPv4, lanIPv4, localAddresses } from \"./portmap.js\";\nexport type { PortMapResult, PortMapperOptions, PortMapMethod } from \"./portmap.js\";\nexport { webRtcLinkFactoryFor } from \"../webrtc.js\";\n\nexport interface DirectHostOptions {\n /** TCP and UDP port to listen on (default 47810). */\n port?: number;\n /** Optional; joiners must send the same one or get `bad_password`. */\n password?: string;\n maxPlayers?: number;\n /** Lobby name; default \"<displayName>'s game\". */\n name?: string;\n lateJoin?: boolean;\n meta?: Record<string, string>;\n /** Ask the router to forward the port so the code works from the internet (s.2a). The host-menu toggle; default on. */\n openPort?: boolean;\n /** Test seam and knobs for the router request (description defaults to \"OneLobby <gameId>\"). */\n portMapping?: PortMapperOptions;\n /**\n * Serves plain-HTTP `GET`s on the same port, typically a join page for browsers (recipe s.4b). The page joins with\n * `kit.joinDirect(location.host)`; the lobby's `joinUrl` is then the link to share.\n */\n http?: HttpHandler;\n /** Per-joiner cap on incoming raw messages, e.g. `{ messages: 60, perMs: 1000 }`; the excess is dropped. */\n rateLimit?: RateLimit;\n}\n\n/** A direct host lobby: the normal Lobby, plus the hub behind it. Leaving or ending the lobby stops the hub. */\nexport type DirectLobby = Lobby & {\n directHub: DirectHubHost;\n /** With the `http` option: `http://<the code's address>:<port>/`, the link a browser opens to join. Else null. */\n joinUrl: string | null;\n};\n\n/**\n * Hosts a direct-IP lobby (docs/direct-ip.md s.3): starts the hub and listener on `port`, opens the router port\n * (unless `openPort: false`), connects `kit` to the hub in memory and creates the lobby. Resolves with the lobby;\n * show `lobby.joinCode` with `lobby.joinCodeKind` (\"internet\" or \"same_network\"). Rejects with `port_in_use`.\n * When the lobby ends (leave, or the process exits) the listener closes and the router mapping is removed; joiners\n * get `sessionEnded(\"host_left\")`.\n */\nexport async function hostDirect(kit: OneLobby, o: DirectHostOptions = {}): Promise<DirectLobby> {\n const port = o.port ?? DEFAULT_DIRECT_PORT;\n const maxPlayers = o.maxPlayers ?? 4;\n let hub: DirectHubHost;\n try {\n hub = await DirectHubHost.listen(port, directHubOptions(maxPlayers, o.password));\n hub.http = o.http ?? null;\n } catch (e) {\n if (e instanceof PortInUseError) throw new OneLobbyError(\"port_in_use\", e.message.replace(/^port_in_use: /, \"\"));\n throw e;\n }\n // The router request runs alongside lobby creation; it takes up to a few seconds when nothing answers.\n const mapping: Promise<PortMapResult | null> =\n o.openPort === false\n ? Promise.resolve(null)\n : hub.openPort({ description: `OneLobby ${kit.options.gameId}`, ...o.portMapping }).catch((e: Error) => ({\n mapped: false, method: \"none\" as const, externalIPv4: null, localIPv4: null, detail: e.message,\n }));\n const wrapLinks = (inner: LinkFactory): LinkFactory => ({\n create: (lo) => inner.create({ ...lo, iceServers: [], portRange: { begin: hub.port, end: hub.port } }),\n });\n let lobby: Lobby;\n try {\n const name = o.name ?? `${kit.options.displayName || \"Player\"}'s game`;\n const h: HostOptions = { name, maxPlayers, lateJoin: o.lateJoin ?? true, meta: o.meta, rateLimit: o.rateLimit };\n lobby = await kit.hostDirectWith(h, { socketFactory: () => hub.connectLocal(), wrapLinks });\n } catch (e) {\n await mapping;\n await hub.close();\n throw e;\n }\n lobby.on(\"sessionEnded\", () => void hub.close());\n const map = await mapping;\n lobby.directAddresses = localAddresses(hub.port);\n lobby.portMapping = map ? map.detail : \"off\";\n let codeIp: string | null = null;\n if (map?.mapped && isPublicIPv4(map.externalIPv4)) {\n codeIp = map.externalIPv4!;\n lobby.joinCode = encodeJoinCode(codeIp, hub.port);\n lobby.joinCodeKind = \"internet\";\n } else {\n codeIp = map?.localIPv4 ?? (await lanIPv4());\n if (codeIp) {\n lobby.joinCode = encodeJoinCode(codeIp, hub.port);\n lobby.joinCodeKind = \"same_network\";\n }\n }\n const joinUrl = o.http && codeIp ? `http://${codeIp}:${hub.port}/` : null;\n return Object.assign(lobby, { directHub: hub, joinUrl });\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/direct/index.ts"],"names":[],"mappings":"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","sourcesContent":["/// <reference types=\"node\" />\n/**\n * `onelobby/direct` (Node only): host a direct-IP lobby from a Node process, with no server of anyone's\n * (docs/direct-ip.md). The process runs the signaling hub, listens on TCP `port`, binds its peer links to UDP `port`,\n * asks the router to forward both (UPnP, then NAT-PMP) and hands out a join code. Joiners use `kit.joinDirect(code)`\n * from `onelobby` (Node or browser) or `JoinDirectAsync` in C#; the wire protocol is the same, so they mix.\n *\n * WebRTC in Node needs an RTCPeerConnection: `npm install node-datachannel`, then\n * `advanced: { linkFactory: webRtcLinkFactoryFor(RTCPeerConnection) }` with\n * `import { RTCPeerConnection } from \"node-datachannel/polyfill\"`. Its libdatachannel honours the port pin.\n */\nimport type { HostOptions, OneLobby } from \"../onelobby.js\";\nimport type { Lobby, RateLimit } from \"../lobby.js\";\nimport type { LinkFactory } from \"../transport.js\";\nimport { encodeJoinCode } from \"../joincode.js\";\nimport { DEFAULT_DIRECT_PORT } from \"../direct-address.js\";\nimport { DirectHubHost, PortInUseError, type HttpHandler } from \"./hub-host.js\";\nimport { directHubOptions } from \"./hub.js\";\nimport { isPublicIPv4, lanIPv4, localAddresses, type PortMapResult, type PortMapperOptions } from \"./portmap.js\";\nimport { OneLobbyError } from \"../signaling.js\";\n\nexport { DirectHubHost, LocalHubSocket, PortInUseError } from \"./hub-host.js\";\nexport type { HttpHandler, HttpReply } from \"./hub-host.js\";\nexport { SignalingHub, Session, RateWindow, sanitize, defaultHubOptions, directHubOptions, PROTO } from \"./hub.js\";\nexport type { HubOptions, HubDeps } from \"./hub.js\";\nexport { PortMapper, isPublicIPv4, lanIPv4, localAddresses } from \"./portmap.js\";\nexport type { PortMapResult, PortMapperOptions, PortMapMethod } from \"./portmap.js\";\nexport { webRtcLinkFactoryFor } from \"../webrtc.js\";\n\nexport interface DirectHostOptions {\n /**\n * TCP and UDP port to listen on (default 47810). When it is busy (another program holds it) the next free one of the\n * following `fallbackPorts` is used; the join code carries the port, so friends never type it.\n */\n port?: number;\n /** How many ports after `port` to try when it is busy; default 9 with `port` left out, else 0. */\n fallbackPorts?: number;\n /** Optional; joiners must send the same one or get `bad_password`. */\n password?: string;\n maxPlayers?: number;\n /** Lobby name; default \"<displayName>'s game\". */\n name?: string;\n lateJoin?: boolean;\n meta?: Record<string, string>;\n /** Ask the router to forward the port so the code works from the internet (s.2a). The host-menu toggle; default on. */\n openPort?: boolean;\n /** Test seam and knobs for the router request (description defaults to \"OneLobby <gameId>\"). */\n portMapping?: PortMapperOptions;\n /**\n * Serves plain-HTTP `GET`s on the same port, typically a join page for browsers (recipe s.4b). The page joins with\n * `kit.joinDirect(location.host)`; the lobby's `joinUrl` is then the link to share.\n */\n http?: HttpHandler;\n /** Per-joiner cap on incoming raw messages, e.g. `{ messages: 60, perMs: 1000 }`; the excess is dropped. */\n rateLimit?: RateLimit;\n}\n\n/** A direct host lobby: the normal Lobby, plus the hub behind it. Leaving or ending the lobby stops the hub. */\nexport type DirectLobby = Lobby & {\n directHub: DirectHubHost;\n /** With the `http` option: `http://<the code's address>:<port>/`, the link a browser opens to join. Else null. */\n joinUrl: string | null;\n};\n\n/**\n * Hosts a direct-IP lobby (docs/direct-ip.md s.3): starts the hub and listener on `port`, opens the router port\n * (unless `openPort: false`), connects `kit` to the hub in memory and creates the lobby. Resolves with the lobby;\n * show `lobby.joinCode` with `lobby.joinCodeKind` (\"internet\" or \"same_network\"). Rejects with `port_in_use`.\n * When the lobby ends (leave, or the process exits) the listener closes and the router mapping is removed; joiners\n * get `sessionEnded(\"host_left\")`.\n */\n/** With `port` left out, how many ports after the default `hostDirect` tries when it is busy. */\nexport const DEFAULT_FALLBACK_PORTS = 9;\n\nexport async function hostDirect(kit: OneLobby, o: DirectHostOptions = {}): Promise<DirectLobby> {\n const port = o.port ?? DEFAULT_DIRECT_PORT;\n // busy (another program holds it): try the next fallbackPorts; the join code carries the port\n const last = port + Math.max(0, o.fallbackPorts ?? (o.port === undefined ? DEFAULT_FALLBACK_PORTS : 0));\n const maxPlayers = o.maxPlayers ?? 4;\n let hub: DirectHubHost | undefined;\n for (let p = port; !hub; p++) {\n try {\n hub = await DirectHubHost.listen(p, directHubOptions(maxPlayers, o.password));\n } catch (e) {\n if (!(e instanceof PortInUseError)) throw e;\n if (p < last) continue;\n const range = last > port ? `ports ${port}-${last}` : `port ${port}`;\n throw new OneLobbyError(\"port_in_use\", `cannot listen on ${range}: is another copy of the game hosting?`);\n }\n }\n hub.http = o.http ?? null;\n // The router request runs alongside lobby creation; it takes up to a few seconds when nothing answers.\n const mapping: Promise<PortMapResult | null> =\n o.openPort === false\n ? Promise.resolve(null)\n : hub.openPort({ description: `OneLobby ${kit.options.gameId}`, ...o.portMapping }).catch((e: Error) => ({\n mapped: false, method: \"none\" as const, externalIPv4: null, localIPv4: null, detail: e.message,\n }));\n const wrapLinks = (inner: LinkFactory): LinkFactory => ({\n create: (lo) => inner.create({ ...lo, iceServers: [], portRange: { begin: hub.port, end: hub.port } }),\n });\n let lobby: Lobby;\n try {\n const name = o.name ?? `${kit.options.displayName || \"Player\"}'s game`;\n const h: HostOptions = { name, maxPlayers, lateJoin: o.lateJoin ?? true, meta: o.meta, rateLimit: o.rateLimit };\n lobby = await kit.hostDirectWith(h, { socketFactory: () => hub.connectLocal(), wrapLinks });\n } catch (e) {\n await mapping;\n await hub.close();\n throw e;\n }\n lobby.on(\"sessionEnded\", () => void hub.close());\n const map = await mapping;\n lobby.directAddresses = localAddresses(hub.port);\n lobby.portMapping = map ? map.detail : \"off\";\n let codeIp: string | null = null;\n if (map?.mapped && isPublicIPv4(map.externalIPv4)) {\n codeIp = map.externalIPv4!;\n lobby.joinCode = encodeJoinCode(codeIp, hub.port);\n lobby.joinCodeKind = \"internet\";\n } else {\n codeIp = map?.localIPv4 ?? (await lanIPv4());\n if (codeIp) {\n lobby.joinCode = encodeJoinCode(codeIp, hub.port);\n lobby.joinCodeKind = \"same_network\";\n }\n }\n const joinUrl = o.http && codeIp ? `http://${codeIp}:${hub.port}/` : null;\n return Object.assign(lobby, { directHub: hub, joinUrl });\n}\n"]}