The host clears seats and closes rooms
Two lobby-lifecycle gaps from tonight's duels (a token lost to a client bug left an unkickable ghost seat holding a chair in VQJW). kickSeat: the host removes any other seat from an unstarted room — the kick is a ledger line so restarts replay it, and a kicked live socket is set adrift with notice. abandonRoom: the host dissolves a lobby or a finished game; every member is notified and detached, and the ledger is archived to rooms-abandoned/ — moved, never deleted. The lobby shows hosts a ✕ per seat and an abandon-room control. Proven live: kick with notice, kick surviving a server restart, and abandonment archiving its ledger. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015RCWSTnb1KYTPyL4GmhGnF
This commit is contained in:
co-authored by
Claude Fable 5
parent
4c7633097b
commit
9af7bd80ce
@@ -57,6 +57,8 @@ import {
|
||||
summarize,
|
||||
viewForPlayer,
|
||||
type Room,
|
||||
kickSeat,
|
||||
abandonRoom,
|
||||
} from "./rooms";
|
||||
import { engagementStats, recordHotseat } from "./stats";
|
||||
import { getShare, loadShares, mintShare } from "./shares";
|
||||
@@ -526,6 +528,38 @@ wss.on("connection", (socket) => {
|
||||
session.token = null;
|
||||
break;
|
||||
}
|
||||
case "kickSeat": {
|
||||
const room = session.roomId ? getRoom(session.roomId) : undefined;
|
||||
if (!room || !session.playerId) return send(socket, { type: "error", message: "not in a room" });
|
||||
const problem = kickSeat(room, session.playerId, String(msg.name ?? ""));
|
||||
if (problem) return send(socket, { type: "error", message: problem });
|
||||
// A kicked live socket is set adrift so it cannot act on a seat it lost.
|
||||
for (const other of sessions) {
|
||||
if (other.roomId === room.id && other.playerId === msg.name) {
|
||||
other.playerId = null;
|
||||
other.roomId = null;
|
||||
other.token = null;
|
||||
send(other.socket, { type: "kicked", roomId: room.id });
|
||||
}
|
||||
}
|
||||
broadcastRoomState(room);
|
||||
break;
|
||||
}
|
||||
case "abandonRoom": {
|
||||
const room = session.roomId ? getRoom(session.roomId) : undefined;
|
||||
if (!room || !session.playerId) return send(socket, { type: "error", message: "not in a room" });
|
||||
const problem = abandonRoom(room, session.playerId);
|
||||
if (problem) return send(socket, { type: "error", message: problem });
|
||||
for (const other of sessions) {
|
||||
if (other.roomId === room.id) {
|
||||
other.playerId = null;
|
||||
other.roomId = null;
|
||||
other.token = null;
|
||||
send(other.socket, { type: "roomAbandoned", roomId: room.id });
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "addBot": {
|
||||
const room = session.roomId ? getRoom(session.roomId) : undefined;
|
||||
if (!room || !session.playerId) return send(socket, { type: "error", message: "not in a room" });
|
||||
|
||||
Reference in New Issue
Block a user