snapshot_poker_phase4_hotfix

This commit is contained in:
DeSqBlocki
2026-09-08 20:17:19 +02:00
parent 903a2f3081
commit 136a5902c0
2 changed files with 135 additions and 39 deletions
+28 -1
View File
@@ -153,6 +153,32 @@ async function recoverPoker(
const result =
await service.recover();
const activeTables =
await service.listActiveTables();
/*
* Rehydrate every still-active public Poker table after
* restart, even when no recovery action was necessary.
* Mongo remains authoritative; the Discord embed is only
* a projection of the current stored game state.
*/
for (const game of activeTables) {
try {
await refreshPokerTableMessage(
client,
game
);
}
catch (error) {
console.error(
`[Poker] Failed to refresh active table ${game.gameId}:`,
error
);
}
}
for (
const turn
of result.turns ?? []
@@ -212,7 +238,8 @@ async function recoverPoker(
`${result.cashouts.length} cash-out(s), ` +
`${result.closingTables.length} closing table(s), ` +
`${result.turns.length} expired turn(s), ` +
`${result.lobbies.length} expired lobby/lobbies.`
`${result.lobbies.length} expired lobby/lobbies, ` +
`${activeTables.length} active table(s) refreshed.`
);
}
+107 -38
View File
@@ -36,7 +36,7 @@ const POKER_DEFAULT_BIG_BLIND =
200;
const POKER_DEFAULT_BUY_IN =
5000;
1000;
const POKER_TURN_TIMEOUT =
30;
@@ -652,6 +652,22 @@ function getSpecialGameCollection() {
);
}
function stripMongoId(
document
) {
if (!document) {
return null;
}
const {
_id,
...rest
} = document;
return rest;
}
function createMongoPokerStore(
collection =
getSpecialGameCollection()
@@ -660,13 +676,18 @@ function createMongoPokerStore(
async getGame(
gameId
) {
return collection.findOne({
gameId,
gameType:
POKER_GAME_TYPE,
recordType:
"game"
});
const document =
await collection.findOne({
gameId,
gameType:
POKER_GAME_TYPE,
recordType:
"game"
});
return stripMongoId(
document
);
},
async insertGame(
@@ -687,6 +708,14 @@ function createMongoPokerStore(
const replacement =
clone(nextGame);
/*
* MongoDB owns _id. Domain game objects must never
* replace it, especially after structuredClone()
* has converted a BSON ObjectId into a plain object.
*/
delete replacement._id;
const result =
await collection.replaceOne(
{
@@ -709,24 +738,29 @@ function createMongoPokerStore(
guildId,
userId
) {
return collection.findOne({
gameType:
POKER_GAME_TYPE,
recordType:
"game",
guildId,
state: {
$nin: [
"CLOSED"
]
},
"data.players": {
$elemMatch: {
userId:
String(userId)
const document =
await collection.findOne({
gameType:
POKER_GAME_TYPE,
recordType:
"game",
guildId,
state: {
$nin: [
"CLOSED"
]
},
"data.players": {
$elemMatch: {
userId:
String(userId)
}
}
}
});
});
return stripMongoId(
document
);
},
async listJoinableGames(
@@ -751,21 +785,50 @@ function createMongoPokerStore(
channelId;
}
return collection
.find(filter)
.sort({
updatedAt: -1
})
.limit(
Math.max(
1,
Math.min(
25,
Number(limit) || 25
const documents =
await collection
.find(filter)
.sort({
updatedAt: -1
})
.limit(
Math.max(
1,
Math.min(
25,
Number(limit) || 25
)
)
)
)
.toArray();
.toArray();
return documents.map(
stripMongoId
);
},
async listActiveGames() {
const documents =
await collection
.find({
gameType:
POKER_GAME_TYPE,
recordType:
"game",
state: {
$nin: [
"CLOSED"
]
}
})
.sort({
updatedAt: -1
})
.toArray();
return documents.map(
stripMongoId
);
},
async claimMembership({
@@ -2624,6 +2687,11 @@ function createPokerService({
return results;
}
async function listActiveTables() {
return store.listActiveGames();
}
async function recover() {
const [
memberships,
@@ -2670,6 +2738,7 @@ function createPokerService({
recoverClosingTables,
recoverPendingMemberships,
recover,
listActiveTables,
publicTableState,
sanitizeGameForCaller