snapshot_poker_uiux_cleanup_2
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
const {
|
||||
EmbedBuilder,
|
||||
ActionRowBuilder,
|
||||
ButtonBuilder,
|
||||
ButtonStyle
|
||||
} = require("discord.js");
|
||||
|
||||
const {
|
||||
getPokerService
|
||||
} = require("../../utils/crumbPoker");
|
||||
|
||||
const {
|
||||
POKER_TABLE_FOOTER_PREFIX,
|
||||
deferPokerReply,
|
||||
editPokerError,
|
||||
getPokerGameIdFromInteraction
|
||||
} = require("../../utils/pokerDiscord");
|
||||
|
||||
module.exports = {
|
||||
name: "pokerCancel",
|
||||
|
||||
async execute(interaction) {
|
||||
await deferPokerReply(interaction);
|
||||
|
||||
const gameId =
|
||||
getPokerGameIdFromInteraction(interaction);
|
||||
|
||||
if (!gameId) {
|
||||
return interaction.editReply({
|
||||
content: "❌ This Poker table is no longer active.",
|
||||
embeds: [],
|
||||
components: []
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const game =
|
||||
await getPokerService().getTable({ gameId });
|
||||
|
||||
if (
|
||||
String(game.data.ownerId) !==
|
||||
String(interaction.user.id)
|
||||
) {
|
||||
return interaction.editReply({
|
||||
content: "❌ Only the table owner can cancel this Poker table.",
|
||||
embeds: [],
|
||||
components: []
|
||||
});
|
||||
}
|
||||
|
||||
return interaction.editReply({
|
||||
content: "",
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setTitle("🛑 Cancel Poker Table?")
|
||||
.setDescription(
|
||||
[
|
||||
"All seated players will be safely cashed out.",
|
||||
"",
|
||||
"This cannot be undone."
|
||||
].join("\n")
|
||||
)
|
||||
.setFooter({
|
||||
text: `${POKER_TABLE_FOOTER_PREFIX}:${gameId}`
|
||||
})
|
||||
],
|
||||
components: [
|
||||
new ActionRowBuilder().addComponents(
|
||||
new ButtonBuilder()
|
||||
.setCustomId("pokerCancelConfirm")
|
||||
.setLabel("Cancel Table")
|
||||
.setEmoji("🛑")
|
||||
.setStyle(ButtonStyle.Danger),
|
||||
new ButtonBuilder()
|
||||
.setCustomId("pokerCancelKeep")
|
||||
.setLabel("Keep Table")
|
||||
.setStyle(ButtonStyle.Secondary)
|
||||
)
|
||||
]
|
||||
});
|
||||
} catch (error) {
|
||||
return editPokerError(interaction, error);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,50 @@
|
||||
const {
|
||||
getPokerService
|
||||
} = require("../../utils/crumbPoker");
|
||||
|
||||
const {
|
||||
deferPokerReply,
|
||||
editPokerError,
|
||||
getPokerGameIdFromInteraction,
|
||||
refreshPokerTableMessage
|
||||
} = require("../../utils/pokerDiscord");
|
||||
|
||||
module.exports = {
|
||||
name: "pokerCancelConfirm",
|
||||
|
||||
async execute(interaction) {
|
||||
await deferPokerReply(interaction);
|
||||
|
||||
const gameId =
|
||||
getPokerGameIdFromInteraction(interaction);
|
||||
|
||||
if (!gameId) {
|
||||
return interaction.editReply({
|
||||
content: "❌ This Poker table is no longer active.",
|
||||
embeds: [],
|
||||
components: []
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
const game =
|
||||
await getPokerService().cancelTable({
|
||||
gameId,
|
||||
userId: interaction.user.id
|
||||
});
|
||||
|
||||
await refreshPokerTableMessage(
|
||||
interaction.client,
|
||||
game
|
||||
);
|
||||
|
||||
return interaction.editReply({
|
||||
content: "✅ Poker table cancelled. All seated players were cashed out.",
|
||||
embeds: [],
|
||||
components: []
|
||||
});
|
||||
} catch (error) {
|
||||
return editPokerError(interaction, error);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
const {
|
||||
deferPokerReply
|
||||
} = require("../../utils/pokerDiscord");
|
||||
|
||||
module.exports = {
|
||||
name: "pokerCancelKeep",
|
||||
|
||||
async execute(interaction) {
|
||||
await deferPokerReply(interaction);
|
||||
|
||||
return interaction.editReply({
|
||||
content: "✅ Poker table left open.",
|
||||
embeds: [],
|
||||
components: []
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -470,6 +470,46 @@ async function changeCookiesOnce(
|
||||
}
|
||||
|
||||
|
||||
async function clearCookieOperation(
|
||||
userId,
|
||||
operationId
|
||||
) {
|
||||
if (
|
||||
typeof operationId !==
|
||||
"string"
|
||||
||
|
||||
!/^[A-Za-z0-9:_-]{1,160}$/.test(
|
||||
operationId
|
||||
)
|
||||
) {
|
||||
throw new Error(
|
||||
"INVALID_COOKIE_OPERATION_ID"
|
||||
);
|
||||
}
|
||||
|
||||
const {
|
||||
cookies
|
||||
} =
|
||||
getCollections();
|
||||
|
||||
const result =
|
||||
await cookies.updateOne(
|
||||
{
|
||||
userId
|
||||
},
|
||||
{
|
||||
$pull: {
|
||||
appliedCookieOperations:
|
||||
operationId
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return result.modifiedCount ===
|
||||
1;
|
||||
}
|
||||
|
||||
|
||||
async function hasCookieOperation(
|
||||
userId,
|
||||
operationId
|
||||
@@ -1435,6 +1475,7 @@ module.exports = {
|
||||
changeCookies,
|
||||
changeCookiesOnce,
|
||||
hasCookieOperation,
|
||||
clearCookieOperation,
|
||||
transferCookies,
|
||||
|
||||
getCooldown,
|
||||
|
||||
@@ -818,6 +818,22 @@ function createMongoPokerStore(
|
||||
);
|
||||
},
|
||||
|
||||
async deleteGame(
|
||||
gameId
|
||||
) {
|
||||
const result =
|
||||
await collection.deleteOne({
|
||||
gameId,
|
||||
gameType:
|
||||
POKER_GAME_TYPE,
|
||||
recordType:
|
||||
"game"
|
||||
});
|
||||
|
||||
return result.deletedCount ===
|
||||
1;
|
||||
},
|
||||
|
||||
async listActiveGames() {
|
||||
const documents =
|
||||
await collection
|
||||
@@ -1114,6 +1130,22 @@ function createDefaultPokerEconomy() {
|
||||
userId,
|
||||
operationId
|
||||
);
|
||||
},
|
||||
|
||||
async clearOperation(
|
||||
userId,
|
||||
operationId
|
||||
) {
|
||||
const {
|
||||
clearCookieOperation
|
||||
} = require(
|
||||
"./cookieEconomy"
|
||||
);
|
||||
|
||||
return clearCookieOperation(
|
||||
userId,
|
||||
operationId
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1139,6 +1171,43 @@ function createPokerService({
|
||||
lobbyTimeout =
|
||||
POKER_LOBBY_TIMEOUT
|
||||
} = {}) {
|
||||
async function clearOperationQuietly(
|
||||
userId,
|
||||
operationId
|
||||
) {
|
||||
try {
|
||||
await economy.clearOperation(
|
||||
userId,
|
||||
operationId
|
||||
);
|
||||
}
|
||||
|
||||
catch (error) {
|
||||
console.error(
|
||||
`[Poker] Failed to clear completed Cookie operation ${operationId} for ${userId}:`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteGameQuietly(
|
||||
gameId
|
||||
) {
|
||||
try {
|
||||
await store.deleteGame(
|
||||
gameId
|
||||
);
|
||||
}
|
||||
|
||||
catch (error) {
|
||||
console.error(
|
||||
`[Poker] Failed to delete settled table ${gameId}:`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function readGame(
|
||||
gameId
|
||||
) {
|
||||
@@ -1234,6 +1303,22 @@ function createPokerService({
|
||||
gameId,
|
||||
sessionId
|
||||
);
|
||||
|
||||
await clearOperationQuietly(
|
||||
userId,
|
||||
buyInOperationId(
|
||||
gameId,
|
||||
sessionId
|
||||
)
|
||||
);
|
||||
|
||||
await clearOperationQuietly(
|
||||
userId,
|
||||
buyInRefundOperationId(
|
||||
gameId,
|
||||
sessionId
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1362,6 +1447,14 @@ function createPokerService({
|
||||
sessionId,
|
||||
now()
|
||||
);
|
||||
|
||||
await clearOperationQuietly(
|
||||
ownerId,
|
||||
buyInOperationId(
|
||||
gameId,
|
||||
sessionId
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
catch (error) {
|
||||
@@ -1519,6 +1612,14 @@ function createPokerService({
|
||||
sessionId,
|
||||
now()
|
||||
);
|
||||
|
||||
await clearOperationQuietly(
|
||||
userId,
|
||||
buyInOperationId(
|
||||
gameId,
|
||||
sessionId
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
catch (error) {
|
||||
@@ -2317,6 +2418,23 @@ function createPokerService({
|
||||
player.sessionId
|
||||
);
|
||||
|
||||
await clearOperationQuietly(
|
||||
userId,
|
||||
cashOutOperationId(
|
||||
gameId,
|
||||
player.sessionId
|
||||
)
|
||||
);
|
||||
|
||||
if (
|
||||
nextGame.state ===
|
||||
"CLOSED"
|
||||
) {
|
||||
await deleteGameQuietly(
|
||||
gameId
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
amount,
|
||||
game:
|
||||
@@ -2403,6 +2521,23 @@ function createPokerService({
|
||||
closed
|
||||
)
|
||||
) {
|
||||
for (
|
||||
const player
|
||||
of current.data.players
|
||||
) {
|
||||
await clearOperationQuietly(
|
||||
player.userId,
|
||||
cashOutOperationId(
|
||||
gameId,
|
||||
player.sessionId
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
await deleteGameQuietly(
|
||||
gameId
|
||||
);
|
||||
|
||||
return closed;
|
||||
}
|
||||
}
|
||||
@@ -2413,6 +2548,88 @@ function createPokerService({
|
||||
);
|
||||
}
|
||||
|
||||
async function cancelTable({
|
||||
gameId,
|
||||
userId
|
||||
}) {
|
||||
const game =
|
||||
await readGame(
|
||||
gameId
|
||||
);
|
||||
|
||||
if (
|
||||
String(game.data.ownerId) !==
|
||||
String(userId)
|
||||
) {
|
||||
throw new PokerTableError(
|
||||
"NOT_TABLE_OWNER",
|
||||
"Only the Poker table owner can cancel this table."
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
isHandActive(
|
||||
game
|
||||
)
|
||||
) {
|
||||
throw new PokerTableError(
|
||||
"CANCEL_HAND_ACTIVE",
|
||||
"Finish the current hand before cancelling the table."
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
game.state ===
|
||||
"CLOSING"
|
||||
) {
|
||||
return finishClosingTable(
|
||||
gameId
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
!POKER_OPEN_STATES.includes(
|
||||
game.state
|
||||
)
|
||||
) {
|
||||
throw new PokerTableError(
|
||||
"TABLE_NOT_CANCELLABLE",
|
||||
"This Poker table cannot be cancelled in its current state."
|
||||
);
|
||||
}
|
||||
|
||||
const closing =
|
||||
clone(game);
|
||||
|
||||
closing.state =
|
||||
"CLOSING";
|
||||
|
||||
closing.version =
|
||||
game.version + 1;
|
||||
|
||||
closing.updatedAt =
|
||||
now();
|
||||
|
||||
const committed =
|
||||
await store.updateGameVersion(
|
||||
gameId,
|
||||
game.version,
|
||||
closing
|
||||
);
|
||||
|
||||
if (!committed) {
|
||||
throw new PokerTableError(
|
||||
"STATE_CONFLICT",
|
||||
"Poker table changed while cancellation was starting."
|
||||
);
|
||||
}
|
||||
|
||||
return finishClosingTable(
|
||||
gameId
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
async function expireLobby(
|
||||
gameId
|
||||
) {
|
||||
@@ -2569,6 +2786,28 @@ function createPokerService({
|
||||
player.sessionId
|
||||
);
|
||||
|
||||
await clearOperationQuietly(
|
||||
player.userId,
|
||||
cashOutOperationId(
|
||||
game.gameId,
|
||||
player.sessionId
|
||||
)
|
||||
);
|
||||
|
||||
const remainingGame =
|
||||
await store.getGame(
|
||||
game.gameId
|
||||
);
|
||||
|
||||
if (
|
||||
remainingGame?.state ===
|
||||
"CLOSED"
|
||||
) {
|
||||
await deleteGameQuietly(
|
||||
game.gameId
|
||||
);
|
||||
}
|
||||
|
||||
results.push({
|
||||
gameId:
|
||||
game.gameId,
|
||||
@@ -2651,6 +2890,14 @@ function createPokerService({
|
||||
now()
|
||||
);
|
||||
|
||||
await clearOperationQuietly(
|
||||
userId,
|
||||
buyInOperationId(
|
||||
tableGameId,
|
||||
sessionId
|
||||
)
|
||||
);
|
||||
|
||||
results.push({
|
||||
userId,
|
||||
gameId:
|
||||
@@ -2692,6 +2939,22 @@ function createPokerService({
|
||||
sessionId
|
||||
);
|
||||
|
||||
await clearOperationQuietly(
|
||||
userId,
|
||||
buyInOperationId(
|
||||
tableGameId,
|
||||
sessionId
|
||||
)
|
||||
);
|
||||
|
||||
await clearOperationQuietly(
|
||||
userId,
|
||||
buyInRefundOperationId(
|
||||
tableGameId,
|
||||
sessionId
|
||||
)
|
||||
);
|
||||
|
||||
results.push({
|
||||
userId,
|
||||
gameId:
|
||||
@@ -2750,6 +3013,7 @@ function createPokerService({
|
||||
processTurnTimeout,
|
||||
processExpiredTurns,
|
||||
cashOut,
|
||||
cancelTable,
|
||||
finishClosingTable,
|
||||
expireLobby,
|
||||
processExpiredLobbies,
|
||||
|
||||
@@ -110,6 +110,10 @@ function formatPokerError(
|
||||
"There is no active Poker hand.",
|
||||
HAND_ACTIVE:
|
||||
"You cannot cash out during an active Poker hand.",
|
||||
CANCEL_HAND_ACTIVE:
|
||||
"Finish the current hand before cancelling the table.",
|
||||
TABLE_NOT_CANCELLABLE:
|
||||
"This Poker table cannot be cancelled right now.",
|
||||
OUT_OF_TURN:
|
||||
"It isn't your turn.",
|
||||
TURN_EXPIRED:
|
||||
@@ -715,6 +719,20 @@ function buildPokerTableComponents(
|
||||
)
|
||||
.setStyle(
|
||||
ButtonStyle.Secondary
|
||||
),
|
||||
|
||||
new ButtonBuilder()
|
||||
.setCustomId(
|
||||
"pokerCancel"
|
||||
)
|
||||
.setLabel(
|
||||
"Cancel Table"
|
||||
)
|
||||
.setEmoji(
|
||||
"🛑"
|
||||
)
|
||||
.setStyle(
|
||||
ButtonStyle.Danger
|
||||
)
|
||||
)
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user