onelobby 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +77 -2
  3. package/dist/chat.d.ts +60 -0
  4. package/dist/chat.js +163 -0
  5. package/dist/chat.js.map +1 -0
  6. package/dist/chunking.d.ts +17 -0
  7. package/dist/chunking.js +59 -0
  8. package/dist/chunking.js.map +1 -0
  9. package/dist/clock.d.ts +8 -0
  10. package/dist/clock.js +39 -0
  11. package/dist/clock.js.map +1 -0
  12. package/dist/codec.d.ts +141 -0
  13. package/dist/codec.js +308 -0
  14. package/dist/codec.js.map +1 -0
  15. package/dist/crockford.d.ts +14 -0
  16. package/dist/crockford.js +55 -0
  17. package/dist/crockford.js.map +1 -0
  18. package/dist/deflate.d.ts +4 -0
  19. package/dist/deflate.js +32 -0
  20. package/dist/deflate.js.map +1 -0
  21. package/dist/deprecated.d.ts +18 -0
  22. package/dist/deprecated.js +11 -0
  23. package/dist/deprecated.js.map +1 -0
  24. package/dist/direct/hub-host.d.ts +82 -0
  25. package/dist/direct/hub-host.js +393 -0
  26. package/dist/direct/hub-host.js.map +1 -0
  27. package/dist/direct/hub.d.ts +178 -0
  28. package/dist/direct/hub.js +862 -0
  29. package/dist/direct/hub.js.map +1 -0
  30. package/dist/direct/index.d.ts +57 -0
  31. package/dist/direct/index.js +71 -0
  32. package/dist/direct/index.js.map +1 -0
  33. package/dist/direct/portmap.d.ts +84 -0
  34. package/dist/direct/portmap.js +465 -0
  35. package/dist/direct/portmap.js.map +1 -0
  36. package/dist/direct-address.d.ts +20 -0
  37. package/dist/direct-address.js +61 -0
  38. package/dist/direct-address.js.map +1 -0
  39. package/dist/emitter.d.ts +9 -0
  40. package/dist/emitter.js +36 -0
  41. package/dist/emitter.js.map +1 -0
  42. package/dist/friendly.d.ts +20 -0
  43. package/dist/friendly.js +120 -0
  44. package/dist/friendly.js.map +1 -0
  45. package/dist/global.d.ts +8 -0
  46. package/dist/global.js +9 -0
  47. package/dist/global.js.map +1 -0
  48. package/dist/gridpaint.d.ts +27 -0
  49. package/dist/gridpaint.js +106 -0
  50. package/dist/gridpaint.js.map +1 -0
  51. package/dist/hub.d.ts +25 -0
  52. package/dist/hub.js +2 -0
  53. package/dist/hub.js.map +1 -0
  54. package/dist/index.d.ts +35 -0
  55. package/dist/index.js +25 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/internals.d.ts +28 -0
  58. package/dist/internals.js +24 -0
  59. package/dist/internals.js.map +1 -0
  60. package/dist/joincode.d.ts +21 -0
  61. package/dist/joincode.js +84 -0
  62. package/dist/joincode.js.map +1 -0
  63. package/dist/lobby.d.ts +203 -0
  64. package/dist/lobby.js +840 -0
  65. package/dist/lobby.js.map +1 -0
  66. package/dist/lockstep.d.ts +132 -0
  67. package/dist/lockstep.js +471 -0
  68. package/dist/lockstep.js.map +1 -0
  69. package/dist/migration.d.ts +17 -0
  70. package/dist/migration.js +34 -0
  71. package/dist/migration.js.map +1 -0
  72. package/dist/onelobby.bundle.mjs +140 -0
  73. package/dist/onelobby.bundle.mjs.map +7 -0
  74. package/dist/onelobby.d.ts +151 -0
  75. package/dist/onelobby.global.js +3897 -0
  76. package/dist/onelobby.global.js.map +7 -0
  77. package/dist/onelobby.global.min.js +140 -0
  78. package/dist/onelobby.global.min.js.map +7 -0
  79. package/dist/onelobby.js +337 -0
  80. package/dist/onelobby.js.map +1 -0
  81. package/dist/signaling.d.ts +94 -0
  82. package/dist/signaling.js +134 -0
  83. package/dist/signaling.js.map +1 -0
  84. package/dist/socket.d.ts +63 -0
  85. package/dist/socket.js +142 -0
  86. package/dist/socket.js.map +1 -0
  87. package/dist/testing.d.ts +135 -0
  88. package/dist/testing.js +438 -0
  89. package/dist/testing.js.map +1 -0
  90. package/dist/transport.d.ts +80 -0
  91. package/dist/transport.js +7 -0
  92. package/dist/transport.js.map +1 -0
  93. package/dist/ui/controller.d.ts +137 -0
  94. package/dist/ui/controller.js +337 -0
  95. package/dist/ui/controller.js.map +1 -0
  96. package/dist/ui/element.d.ts +22 -0
  97. package/dist/ui/element.js +284 -0
  98. package/dist/ui/element.js.map +1 -0
  99. package/dist/ui/index.d.ts +5 -0
  100. package/dist/ui/index.js +9 -0
  101. package/dist/ui/index.js.map +1 -0
  102. package/dist/ui/server-url.d.ts +9 -0
  103. package/dist/ui/server-url.js +39 -0
  104. package/dist/ui/server-url.js.map +1 -0
  105. package/dist/ui/styles.d.ts +2 -0
  106. package/dist/ui/styles.js +70 -0
  107. package/dist/ui/styles.js.map +1 -0
  108. package/dist/voice-browser.d.ts +19 -0
  109. package/dist/voice-browser.js +151 -0
  110. package/dist/voice-browser.js.map +1 -0
  111. package/dist/voice-core.d.ts +98 -0
  112. package/dist/voice-core.js +233 -0
  113. package/dist/voice-core.js.map +1 -0
  114. package/dist/voice-types.d.ts +35 -0
  115. package/dist/voice-types.js +3 -0
  116. package/dist/voice-types.js.map +1 -0
  117. package/dist/voice.d.ts +68 -0
  118. package/dist/voice.js +223 -0
  119. package/dist/voice.js.map +1 -0
  120. package/dist/webrtc.d.ts +29 -0
  121. package/dist/webrtc.js +169 -0
  122. package/dist/webrtc.js.map +1 -0
  123. package/package.json +93 -4
@@ -0,0 +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"]}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * `onelobby/direct` (Node only): host a direct-IP lobby from a Node process, with no server of anyone's
3
+ * (docs/direct-ip.md). The process runs the signaling hub, listens on TCP `port`, binds its peer links to UDP `port`,
4
+ * asks the router to forward both (UPnP, then NAT-PMP) and hands out a join code. Joiners use `kit.joinDirect(code)`
5
+ * from `onelobby` (Node or browser) or `JoinDirectAsync` in C#; the wire protocol is the same, so they mix.
6
+ *
7
+ * WebRTC in Node needs an RTCPeerConnection: `npm install node-datachannel`, then
8
+ * `advanced: { linkFactory: webRtcLinkFactoryFor(RTCPeerConnection) }` with
9
+ * `import { RTCPeerConnection } from "node-datachannel/polyfill"`. Its libdatachannel honours the port pin.
10
+ */
11
+ import type { OneLobby } from "../onelobby.js";
12
+ import type { Lobby, RateLimit } from "../lobby.js";
13
+ import { DirectHubHost, type HttpHandler } from "./hub-host.js";
14
+ import { type PortMapperOptions } from "./portmap.js";
15
+ export { DirectHubHost, LocalHubSocket, PortInUseError } from "./hub-host.js";
16
+ export type { HttpHandler, HttpReply } from "./hub-host.js";
17
+ export { SignalingHub, Session, RateWindow, sanitize, defaultHubOptions, directHubOptions, PROTO } from "./hub.js";
18
+ export type { HubOptions, HubDeps } from "./hub.js";
19
+ export { PortMapper, isPublicIPv4, lanIPv4, localAddresses } from "./portmap.js";
20
+ export type { PortMapResult, PortMapperOptions, PortMapMethod } from "./portmap.js";
21
+ export { webRtcLinkFactoryFor } from "../webrtc.js";
22
+ export interface DirectHostOptions {
23
+ /** TCP and UDP port to listen on (default 47810). */
24
+ port?: number;
25
+ /** Optional; joiners must send the same one or get `bad_password`. */
26
+ password?: string;
27
+ maxPlayers?: number;
28
+ /** Lobby name; default "<displayName>'s game". */
29
+ name?: string;
30
+ lateJoin?: boolean;
31
+ meta?: Record<string, string>;
32
+ /** Ask the router to forward the port so the code works from the internet (s.2a). The host-menu toggle; default on. */
33
+ openPort?: boolean;
34
+ /** Test seam and knobs for the router request (description defaults to "OneLobby <gameId>"). */
35
+ portMapping?: PortMapperOptions;
36
+ /**
37
+ * Serves plain-HTTP `GET`s on the same port, typically a join page for browsers (recipe s.4b). The page joins with
38
+ * `kit.joinDirect(location.host)`; the lobby's `joinUrl` is then the link to share.
39
+ */
40
+ http?: HttpHandler;
41
+ /** Per-joiner cap on incoming raw messages, e.g. `{ messages: 60, perMs: 1000 }`; the excess is dropped. */
42
+ rateLimit?: RateLimit;
43
+ }
44
+ /** A direct host lobby: the normal Lobby, plus the hub behind it. Leaving or ending the lobby stops the hub. */
45
+ export type DirectLobby = Lobby & {
46
+ directHub: DirectHubHost;
47
+ /** With the `http` option: `http://<the code's address>:<port>/`, the link a browser opens to join. Else null. */
48
+ joinUrl: string | null;
49
+ };
50
+ /**
51
+ * Hosts a direct-IP lobby (docs/direct-ip.md s.3): starts the hub and listener on `port`, opens the router port
52
+ * (unless `openPort: false`), connects `kit` to the hub in memory and creates the lobby. Resolves with the lobby;
53
+ * show `lobby.joinCode` with `lobby.joinCodeKind` ("internet" or "same_network"). Rejects with `port_in_use`.
54
+ * When the lobby ends (leave, or the process exits) the listener closes and the router mapping is removed; joiners
55
+ * get `sessionEnded("host_left")`.
56
+ */
57
+ export declare function hostDirect(kit: OneLobby, o?: DirectHostOptions): Promise<DirectLobby>;
@@ -0,0 +1,71 @@
1
+ import { encodeJoinCode } from "../joincode.js";
2
+ import { DEFAULT_DIRECT_PORT } from "../direct-address.js";
3
+ import { DirectHubHost, PortInUseError } from "./hub-host.js";
4
+ import { directHubOptions } from "./hub.js";
5
+ import { isPublicIPv4, lanIPv4, localAddresses } from "./portmap.js";
6
+ import { OneLobbyError } from "../signaling.js";
7
+ export { DirectHubHost, LocalHubSocket, PortInUseError } from "./hub-host.js";
8
+ export { SignalingHub, Session, RateWindow, sanitize, defaultHubOptions, directHubOptions, PROTO } from "./hub.js";
9
+ export { PortMapper, isPublicIPv4, lanIPv4, localAddresses } from "./portmap.js";
10
+ export { webRtcLinkFactoryFor } from "../webrtc.js";
11
+ /**
12
+ * Hosts a direct-IP lobby (docs/direct-ip.md s.3): starts the hub and listener on `port`, opens the router port
13
+ * (unless `openPort: false`), connects `kit` to the hub in memory and creates the lobby. Resolves with the lobby;
14
+ * show `lobby.joinCode` with `lobby.joinCodeKind` ("internet" or "same_network"). Rejects with `port_in_use`.
15
+ * When the lobby ends (leave, or the process exits) the listener closes and the router mapping is removed; joiners
16
+ * get `sessionEnded("host_left")`.
17
+ */
18
+ export async function hostDirect(kit, o = {}) {
19
+ const port = o.port ?? DEFAULT_DIRECT_PORT;
20
+ const maxPlayers = o.maxPlayers ?? 4;
21
+ 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;
30
+ }
31
+ // The router request runs alongside lobby creation; it takes up to a few seconds when nothing answers.
32
+ const mapping = o.openPort === false
33
+ ? Promise.resolve(null)
34
+ : hub.openPort({ description: `OneLobby ${kit.options.gameId}`, ...o.portMapping }).catch((e) => ({
35
+ mapped: false, method: "none", externalIPv4: null, localIPv4: null, detail: e.message,
36
+ }));
37
+ const wrapLinks = (inner) => ({
38
+ create: (lo) => inner.create({ ...lo, iceServers: [], portRange: { begin: hub.port, end: hub.port } }),
39
+ });
40
+ let lobby;
41
+ try {
42
+ const name = o.name ?? `${kit.options.displayName || "Player"}'s game`;
43
+ const h = { name, maxPlayers, lateJoin: o.lateJoin ?? true, meta: o.meta, rateLimit: o.rateLimit };
44
+ lobby = await kit.hostDirectWith(h, { socketFactory: () => hub.connectLocal(), wrapLinks });
45
+ }
46
+ catch (e) {
47
+ await mapping;
48
+ await hub.close();
49
+ throw e;
50
+ }
51
+ lobby.on("sessionEnded", () => void hub.close());
52
+ const map = await mapping;
53
+ lobby.directAddresses = localAddresses(hub.port);
54
+ lobby.portMapping = map ? map.detail : "off";
55
+ let codeIp = null;
56
+ if (map?.mapped && isPublicIPv4(map.externalIPv4)) {
57
+ codeIp = map.externalIPv4;
58
+ lobby.joinCode = encodeJoinCode(codeIp, hub.port);
59
+ lobby.joinCodeKind = "internet";
60
+ }
61
+ else {
62
+ codeIp = map?.localIPv4 ?? (await lanIPv4());
63
+ if (codeIp) {
64
+ lobby.joinCode = encodeJoinCode(codeIp, hub.port);
65
+ lobby.joinCodeKind = "same_network";
66
+ }
67
+ }
68
+ const joinUrl = o.http && codeIp ? `http://${codeIp}:${hub.port}/` : null;
69
+ return Object.assign(lobby, { directHub: hub, joinUrl });
70
+ }
71
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/direct/index.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,cAAc,EAAoB,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,EAA8C,MAAM,cAAc,CAAC;AACjH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE9E,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEnH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAgCpD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAa,EAAE,IAAuB,EAAE;IACvE,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,mBAAmB,CAAC;IAC3C,MAAM,UAAU,GAAG,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC;IACrC,IAAI,GAAkB,CAAC;IACvB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,gBAAgB,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QACjF,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC;IAC5B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,cAAc;YAAE,MAAM,IAAI,aAAa,CAAC,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,CAAC;QACjH,MAAM,CAAC,CAAC;IACV,CAAC;IACD,uGAAuG;IACvG,MAAM,OAAO,GACX,CAAC,CAAC,QAAQ,KAAK,KAAK;QAClB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;QACvB,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,YAAY,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAQ,EAAE,EAAE,CAAC,CAAC;YACrG,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAe,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO;SAC/F,CAAC,CAAC,CAAC;IACV,MAAM,SAAS,GAAG,CAAC,KAAkB,EAAe,EAAE,CAAC,CAAC;QACtD,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;KACvG,CAAC,CAAC;IACH,IAAI,KAAY,CAAC;IACjB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,QAAQ,SAAS,CAAC;QACvE,MAAM,CAAC,GAAgB,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC;QAChH,KAAK,GAAG,MAAM,GAAG,CAAC,cAAc,CAAC,CAAC,EAAE,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IAC9F,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,OAAO,CAAC;QACd,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,CAAC,CAAC;IACV,CAAC;IACD,KAAK,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;IACjD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC;IAC1B,KAAK,CAAC,eAAe,GAAG,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACjD,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;IAC7C,IAAI,MAAM,GAAkB,IAAI,CAAC;IACjC,IAAI,GAAG,EAAE,MAAM,IAAI,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;QAClD,MAAM,GAAG,GAAG,CAAC,YAAa,CAAC;QAC3B,KAAK,CAAC,QAAQ,GAAG,cAAc,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QAClD,KAAK,CAAC,YAAY,GAAG,UAAU,CAAC;IAClC,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,GAAG,EAAE,SAAS,IAAI,CAAC,MAAM,OAAO,EAAE,CAAC,CAAC;QAC7C,IAAI,MAAM,EAAE,CAAC;YACX,KAAK,CAAC,QAAQ,GAAG,cAAc,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;YAClD,KAAK,CAAC,YAAY,GAAG,cAAc,CAAC;QACtC,CAAC;IACH,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,CAAC,CAAC,UAAU,MAAM,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1E,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;AAC3D,CAAC","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"]}
@@ -0,0 +1,84 @@
1
+ export type PortMapMethod = "none" | "upnp" | "natpmp";
2
+ /** What {@link PortMapper.open} found. `mapped` means TCP and UDP `port` both forward here. */
3
+ export interface PortMapResult {
4
+ mapped: boolean;
5
+ method: PortMapMethod;
6
+ /** The router's WAN address as it reports it (may itself be private or carrier-grade NAT). */
7
+ externalIPv4: string | null;
8
+ /** This PC's address on the router's network, when the router was found. */
9
+ localIPv4: string | null;
10
+ /** Why nothing was mapped, for logs. */
11
+ detail: string;
12
+ }
13
+ /** Seams for tests (a fake gateway on loopback) and the few knobs a game might want. Same as C#'s PortMapperOptions. */
14
+ export interface PortMapperOptions {
15
+ /** Where the SSDP M-SEARCH goes; default the UPnP multicast group 239.255.255.250:1900. */
16
+ ssdp?: {
17
+ address: string;
18
+ port: number;
19
+ };
20
+ /** NAT-PMP server; default this PC's IPv4 default gateway, port 5351. */
21
+ natPmp?: {
22
+ address: string;
23
+ port: number;
24
+ };
25
+ discoveryTimeoutMs?: number;
26
+ requestTimeoutMs?: number;
27
+ /** Lease asked for; renewed at half of it while hosting. Routers that only allow permanent leases get 0. */
28
+ leaseSeconds?: number;
29
+ description?: string;
30
+ tryUpnp?: boolean;
31
+ tryNatPmp?: boolean;
32
+ }
33
+ /**
34
+ * Opens TCP and UDP `port` on the home router for a direct-IP host (docs/direct-ip.md s.2a): UPnP IGD (SSDP, then
35
+ * GetExternalIPAddress + AddPortMapping), then NAT-PMP (RFC 6886). Node twin of C#'s `PortMapper`, same order and rules:
36
+ * same external and internal port or nothing (a join code carries one port), leases renew at half-life, {@link close}
37
+ * deletes the mappings. Windows Firewall drops SSDP replies on a network marked Public; the result is then unmapped.
38
+ */
39
+ export declare class PortMapper {
40
+ readonly port: number;
41
+ result: PortMapResult | null;
42
+ private readonly o;
43
+ private control;
44
+ private service;
45
+ private lease;
46
+ private natPmpAt;
47
+ private renew;
48
+ private stopped;
49
+ constructor(port: number, options?: PortMapperOptions);
50
+ /** Finds the router and maps TCP + UDP `port`. Never rejects for network trouble: see `detail`. */
51
+ open(): Promise<PortMapResult>;
52
+ private done;
53
+ private tryUpnp;
54
+ private addUpnpBoth;
55
+ /**
56
+ * SSDP search: multicast once per interface that has a gateway (so a Hyper-V, WSL or Docker adapter cannot swallow
57
+ * it), plus a unicast copy to the gateway.
58
+ */
59
+ private discover;
60
+ private soap;
61
+ /**
62
+ * One connection per request: some routers close after each reply without saying so, and a reused
63
+ * keep-alive socket then fails every second request with "socket hang up".
64
+ */
65
+ private http;
66
+ private tryNatPmp;
67
+ /** Maps UDP then TCP; null on success, else why. A different external port counts as failure (and is undone). */
68
+ private natPmpMapBoth;
69
+ private mapRequest;
70
+ /** RFC 6886 s.3.1 retransmission: 250 ms, doubling, 3 tries (under 2 s). Null when nobody answers. */
71
+ private natPmpRequest;
72
+ /** Deletes the mappings (best effort, bounded to about 1.5 s) and stops renewing. */
73
+ close(): Promise<void>;
74
+ private natPmpOnce;
75
+ }
76
+ /**
77
+ * True for an address the internet can route to: not private (RFC 1918), carrier-grade NAT (100.64/10), loopback,
78
+ * link-local, 0/8, or multicast/reserved (224+). A router that reports a non-public WAN address is itself behind NAT.
79
+ */
80
+ export declare function isPublicIPv4(address: string | null | undefined): boolean;
81
+ /** The IPv4 a same-network join code carries when the router was not found (see C#'s DirectAddress.LanIPv4). */
82
+ export declare function lanIPv4(): Promise<string | null>;
83
+ /** This machine's addresses with the port, IPv4 first, for an "Advanced" fold-out on the host screen. */
84
+ export declare function localAddresses(port: number): string[];