Close CPU tables as soon as every human player leaves

- When the last human presses leave on a CPU table (even mid-hand), the table
  is deleted right away instead of lingering with CPUs only; friends / cash-only
  tables keep the existing 30-minute idle cleanup
- Spectators still watching get a "テーブルが終了しました" notice, and the lobby
  updates immediately
- Don't show the "接続が切れました" banner when the page disconnects on purpose
  (closed or missing table)
- Test for the close condition; README notes the behavior

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
agomizi1cmandClaude Opus 5.5 committed 2026-10-17 17:03:58 +09:00
1 parent 0d3a054f0d
commit 02c8e76237
6 files changed
+63 -6

No files matched your search

+14 -1
View File
@@ -192,6 +192,17 @@ function changed(table) {
broadcastLobby();
}
// テーブルを削除し、残っている観戦者に知らせる(leaver: 退席した本人。すでにロビーへ戻るので知らせない)
function closeTable(table, leaver) {
tables.delete(table.id);
for (const s of roomSockets(table.id)) {
s.leave(roomOf(table.id));
if (s.data.tableId === table.id) s.data.tableId = null;
if (s !== leaver) s.emit('table:closed');
}
broadcastLobby();
}
// 二重チェック(allowRequest を通った後も念のため)
io.use((socket, next) => {
if (auth.isAuthedCookieHeader(socket.handshake.headers.cookie)) next();
@@ -274,7 +285,9 @@ io.on('connection', (socket) => {
if (!table) return reply(ack, { ok: false, error: 'NOT_FOUND' });
const error = fn(table, socket.data.token, p);
reply(ack, error ? { ok: false, error } : { ok: true });
if (!error) changed(table);
if (error) return;
if (event === 'table:leave' && table.shouldClose()) return closeTable(table, socket);
changed(table);
});
}