0.2.3: Clementia S2 releases a dead, hidden, uncarriable or pathless rider at once (slot and weight back before the same tick's boarding checks); same-browser match recovery never takes the seat of a window that is reloading or still starting (a tab keeps its own session token; seats are stamped at the server's welcome, the older welcome wins); golden: diy-135 moves (outcome unchanged)

This commit is contained in:
sganggs committed 2026-10-10 01:58:06 +08:00
1 parent 821ab827bd
commit ba5b998a72
19 files changed
+580 -60

No files matched your search

+8
View File
@@ -96,6 +96,8 @@ export class Session {
this.ws = null;
/** @type {boolean} */
this.connected = false;
/** @type {number | null} local first-welcome stamp of the attached client (optional, not authentication) */
this.claimAt = null;
/** @type {number} ms epoch of the last inbound frame / pong */
this.lastSeen = now;
/** @type {number | null} ms epoch when the socket was lost (null while connected) */
@@ -647,6 +649,11 @@ export class Network {
if (!session) {
session = msg.token ? this.registry.byToken(msg.token) : null;
if (session) {
if (session.connected && session.ws && session.ws !== conn.ws
&& (msg.noReplace || (Number.isFinite(msg.claimAt) && session.claimAt != null && msg.claimAt > session.claimAt))) {
this.reply(conn, errorMsg(ERR.SESSION_IN_USE, rid));
return;
}
resumed = true;
if (session.ws && session.ws !== conn.ws) this.detachReplaced(session.ws);
} else {
@@ -656,6 +663,7 @@ export class Network {
conn.session = session;
session.ws = conn.ws;
session.connected = true;
session.claimAt = Number.isFinite(msg.claimAt) ? msg.claimAt : null;
session.disconnectedAt = null;
}
session.name = name;