实现账号绑定、持久登录与跨设备对局恢复
CI / test (ubuntu-latest, node 22) (push) Failing after 33m10s
CI / test (ubuntu-latest, node 24) (push) Failing after 34m41s
CI / tooling (lint, imports, typecheck) (push) Failing after 36m11s
CI / test (windows-latest, node 22) (push) Canceled after 0s
CI / test (windows-latest, node 24) (push) Canceled after 0s
CI / test (ubuntu-latest, node 22) (push) Failing after 33m10s
CI / test (ubuntu-latest, node 24) (push) Failing after 34m41s
CI / tooling (lint, imports, typecheck) (push) Failing after 36m11s
CI / test (windows-latest, node 22) (push) Canceled after 0s
CI / test (windows-latest, node 24) (push) Canceled after 0s
This commit is contained in:
1 parent
488db49f11
commit
7c25c89992
62 files changed
+6855
-1005
No files matched your search
@@ -4,6 +4,26 @@ Part of [DESIGN.md](../DESIGN.md) (the index; section numbers are global).
|
||||
|
||||
## 8. Network protocol (shared/protocol.js is normative)
|
||||
|
||||
**Fork account policy (opt-in `SP_SKLAND=1`, owner request 2026-10-14).** The existing WebSocket messages are
|
||||
unchanged. Hello may establish anonymous transport for account login, but room/game requests require the role
|
||||
owned by a persistent, server-verified JWT cookie. The server ignores a client's claimed nickname/UUID for account
|
||||
identity; it derives stable `playerId` from UID plus provider-reported server region (`channelName`). Nicknames
|
||||
may repeat, and optional provider `gameId` metadata does not affect identity. The public id uses 128 SHA-256 digest
|
||||
bits encoded as base64url after `a_` (24 characters), so normal field ids and per-player battle reports fit the
|
||||
existing protocol limits. A reconnect token alone cannot resume
|
||||
an account identity. A valid login plus the role's current reconnect token can resume its previous socket; each
|
||||
game frame checks the current login record and selected role, so logout or a role switch invalidates its authority.
|
||||
Cookie restoration and read-only recovery lookup never take over another device. An explicit authenticated
|
||||
enter/resume POST returns the selected role's token; the existing hello then attaches it and resends room/match state.
|
||||
Only after successful attachment is the account token rotated, so a stale device cannot silently retake the seat.
|
||||
The client stages the entry token in memory until welcome; local multi-tab claims still protect normal reconnects.
|
||||
Login lasts 30 days, survives process restart and is revoked on unbind. Room/match data remain in memory.
|
||||
Recovery selectors are scoped to the selected role and the particular room/match; stale selectors return 409 without
|
||||
creating a new game. The existing 10-minute / solo 24-hour disconnect windows are unchanged, and an expired seat is
|
||||
removed through the lobby before its stable playerId can be reused. Account API ownership and private DB handling
|
||||
are specified in [skland.md](../skland.md) §5/§9. The optional policy hooks leave module-off transport unchanged;
|
||||
no simulation rule, WebSocket message or protocol-version change is involved.
|
||||
|
||||
Transport: one WebSocket per tab at `/ws`, JSON text frames `{ t: '<type>', ...payload }`. Client requests may carry `rid` (request id); the server's direct reply echoes `rid` (`ok` or `error`). Server pushes have no `rid`. Max frame 64 KB inbound (a compressed frame counts its inflated size); rate limit 40 msgs/s per connection (excess dropped with `error RATE`). Frames from 1 KB up are compressed with permessage-deflate (RFC 7692; `server/http/websocket.js WS_DEFLATE`: no server context takeover, a 2 KB server window, zlib memLevel 7 — about 72 KB of zlib state per connection); smaller frames go out plain, and a client that offers no compression, or caps the server window below 2 KB, gets plain frames. A measured solo session (rounds 3–5, `/healthz?traffic=1`): 173 KB of server frames → 60 KB on the wire.
|
||||
|
||||
### 8.1 Session & lobby
|
||||
@@ -137,6 +157,8 @@ voting, refuses stale ids and cancels on disconnect/leave; DESIGN §28.21 / META
|
||||
|
||||
Explicit local recovery (§28.20) reuses saved hello tokens after a fresh live-tab claim check. Display names and room
|
||||
codes are UI metadata only, never authentication. No new network message or nickname/IP matching is introduced.
|
||||
The account-required fork replaces the visible local recovery entry with authenticated account recovery (§31.13);
|
||||
the generic local helper and its module-off handshake behavior are retained.
|
||||
|
||||
Optional `coins: [[id, balance, cap]]` is an integer skill-currency readout (§29.6), separate from ammo. It includes zero, is stepped between snapshots and clears when omitted. Result-validation names for board operators are resolved from the server's DIY/stand-in selections, never a supplied display name.
|
||||
|
||||
|
||||
Reference in new issue
Block a user