The template's lost-seat search counts the tables it cannot give back rather than naming them, leaves a seat a bot stands in for to the host, and the keeper's door looks a name up across tables
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CCLa2PaEeCj8njQZSWGqHx
This commit is contained in:
1 parent
dcb18b2b7e
commit
e3f8a03215
7 files changed
+69
-35
No files matched your search
@@ -337,17 +337,12 @@ export class Rooms<State, Input> {
|
||||
this.apply(room, line);
|
||||
}
|
||||
|
||||
/**
|
||||
* The seats a name holds at tables not yet over, for a browser that lost them. A seat last used from the
|
||||
* asker's own address, at a table where no other person shares that address, is theirs again with a new
|
||||
* token, the old one dead; the rest are named, so the asker can get a phrase from the host there.
|
||||
*/
|
||||
findSeats(rawName: string, addr: string, only?: string): { seated: { roomId: string; seat: SeatId; token: string }[]; elsewhere: { roomId: string; seat: SeatId; players: string[] }[] } {
|
||||
const name = cleanName(rawName).toLowerCase();
|
||||
const seated: { roomId: string; seat: SeatId; token: string }[] = [];
|
||||
const elsewhere: { roomId: string; seat: SeatId; players: string[] }[] = [];
|
||||
/** The tables not yet over, written to lately, where a person of this name sits; one table alone when it is named. */
|
||||
private tablesOf(name: string, only?: string): { room: Room<State>; seat: Seat }[] {
|
||||
const wanted = cleanName(name).toLowerCase();
|
||||
const since = Date.now() - LOST_SEAT_LOOKBACK_MS;
|
||||
const ids = only ? [normalizeCode(String(only))] : this.store.roomIds().filter((id) => this.store.updatedAt(id) > since);
|
||||
const found: { room: Room<State>; seat: Seat }[] = [];
|
||||
for (const id of ids) {
|
||||
let room: Room<State>;
|
||||
try {
|
||||
@@ -356,18 +351,37 @@ export class Rooms<State, Input> {
|
||||
continue;
|
||||
}
|
||||
if (room.over) continue;
|
||||
const person = (s: Seat) => !s.bot || s.standIn;
|
||||
const mine = room.seats.find((s) => person(s) && s.name.toLowerCase() === name);
|
||||
if (!mine) continue;
|
||||
const shared = room.seats.some((s) => s !== mine && person(s) && s.addr === addr);
|
||||
if (mine.addr === addr && !shared) {
|
||||
const { token } = this.reseat(room, mine.id);
|
||||
seated.push({ roomId: room.id, seat: mine.id, token });
|
||||
} else elsewhere.push({ roomId: room.id, seat: mine.id, players: room.seats.filter((s) => s !== mine).map((s) => s.name) });
|
||||
const seat = room.seats.find((s) => (!s.bot || s.standIn) && s.name.toLowerCase() === wanted);
|
||||
if (seat) found.push({ room, seat });
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* The seats a name holds at tables not yet over, for a browser that lost them. A seat last used from the
|
||||
* asker's own address, at a table where no other person shares that address, is theirs again with a new
|
||||
* token, the old one dead. The rest are only counted: a name proves nothing, so neither the tables nor the
|
||||
* company at them are told to the asker, who can get a phrase from the host, or a link from the keeper. A
|
||||
* seat the host gave to a bot is the host's to give back, by a phrase, never taken back by name.
|
||||
*/
|
||||
findSeats(rawName: string, addr: string, only?: string): { seated: { roomId: string; seat: SeatId; token: string }[]; elsewhere: number } {
|
||||
const seated: { roomId: string; seat: SeatId; token: string }[] = [];
|
||||
let elsewhere = 0;
|
||||
for (const { room, seat } of this.tablesOf(rawName, only)) {
|
||||
const shared = room.seats.some((s) => s !== seat && (!s.bot || s.standIn) && s.addr === addr);
|
||||
if (seat.addr === addr && !shared && !seat.standIn) {
|
||||
const { token } = this.reseat(room, seat.id);
|
||||
seated.push({ roomId: room.id, seat: seat.id, token });
|
||||
} else elsewhere += 1;
|
||||
}
|
||||
return { seated, elsewhere };
|
||||
}
|
||||
|
||||
/** For the keeper: every table not yet over where a person of this name sits, with the company there, to re-seat them by. */
|
||||
tablesForKeeper(name: string): { roomId: string; seat: SeatId; standIn: boolean; players: string[]; updatedAt: number }[] {
|
||||
return this.tablesOf(name).map(({ room, seat }) => ({ roomId: room.id, seat: seat.id, standIn: !!seat.standIn, players: room.seats.filter((s) => s !== seat).map((s) => s.name), updatedAt: room.updatedAt }));
|
||||
}
|
||||
|
||||
/** Claim a phrase: the seat and its token, once. Too many misses void every pending phrase. */
|
||||
claim(raw: unknown): { roomId: string; seat: SeatId; token: string } {
|
||||
const now = Date.now();
|
||||
|
||||
Reference in new issue
Block a user