added bankruptcy
This commit is contained in:
@@ -0,0 +1,284 @@
|
||||
const { EmbedBuilder, MessageFlags } = require("discord.js");
|
||||
const { mClient } = require("../index");
|
||||
|
||||
const DATABASE_NAME = process.env.M_DB;
|
||||
const SESSION_COLLECTION = "items_sessions";
|
||||
const DEFAULT_SESSION_LIFETIME_MS = 24 * 60 * 60 * 1000;
|
||||
|
||||
function getSessionCollection() {
|
||||
if (!DATABASE_NAME) {
|
||||
throw new Error("M_DB is not configured in .env");
|
||||
}
|
||||
|
||||
return mClient.db(DATABASE_NAME).collection(SESSION_COLLECTION);
|
||||
}
|
||||
|
||||
async function ensureInteractionSessionIndexes() {
|
||||
const sessions = getSessionCollection();
|
||||
|
||||
await sessions.createIndex(
|
||||
{ messageId: 1 },
|
||||
{ unique: true }
|
||||
);
|
||||
|
||||
await sessions.createIndex(
|
||||
{ expiresAt: 1 },
|
||||
{ expireAfterSeconds: 0 }
|
||||
);
|
||||
}
|
||||
|
||||
async function createInteractionSession(
|
||||
interaction,
|
||||
{
|
||||
messageId = null,
|
||||
ownerId = interaction.user.id,
|
||||
kind = "menu",
|
||||
targetId = null,
|
||||
metadata = {},
|
||||
lifetimeMs = DEFAULT_SESSION_LIFETIME_MS
|
||||
} = {}
|
||||
) {
|
||||
const resolvedMessageId =
|
||||
messageId ?? interaction.message?.id;
|
||||
|
||||
if (!resolvedMessageId) {
|
||||
throw new Error("SESSION_MESSAGE_ID_REQUIRED");
|
||||
}
|
||||
|
||||
const sessions = getSessionCollection();
|
||||
const now = new Date();
|
||||
const expiresAt = new Date(now.getTime() + lifetimeMs);
|
||||
|
||||
await sessions.updateOne(
|
||||
{ messageId: resolvedMessageId },
|
||||
{
|
||||
$set: {
|
||||
messageId: resolvedMessageId,
|
||||
ownerId,
|
||||
guildId: interaction.guildId ?? null,
|
||||
channelId: interaction.channelId ?? null,
|
||||
kind,
|
||||
targetId,
|
||||
metadata,
|
||||
active: true,
|
||||
updatedAt: now,
|
||||
expiresAt
|
||||
},
|
||||
$setOnInsert: {
|
||||
createdAt: now
|
||||
}
|
||||
},
|
||||
{ upsert: true }
|
||||
);
|
||||
|
||||
return sessions.findOne({ messageId: resolvedMessageId });
|
||||
}
|
||||
|
||||
async function registerReplySession(interaction, options = {}) {
|
||||
const message = await interaction.fetchReply();
|
||||
|
||||
return createInteractionSession(
|
||||
interaction,
|
||||
{
|
||||
...options,
|
||||
messageId: message.id
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
async function getInteractionSession(interaction) {
|
||||
const messageId = interaction.message?.id;
|
||||
|
||||
if (!messageId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getSessionCollection().findOne({
|
||||
messageId,
|
||||
active: true,
|
||||
expiresAt: { $gt: new Date() }
|
||||
});
|
||||
}
|
||||
|
||||
function inferLegacyOwnerId(interaction) {
|
||||
const footer = interaction.message?.embeds?.[0]?.footer?.text;
|
||||
const parts = footer?.split(":") ?? [];
|
||||
|
||||
if (!parts.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (parts[0]) {
|
||||
case "profile":
|
||||
case "crumbSaucer":
|
||||
case "crumbSaucerCollect":
|
||||
case "crumbSaucerSlots":
|
||||
case "crumbSaucerSlotsResult":
|
||||
case "crumbSaucerBlackjack":
|
||||
case "crumbBlackjackResult":
|
||||
case "crumbRouletteMenu":
|
||||
case "crumbRouletteBet":
|
||||
case "crumbRouletteResult":
|
||||
case "cookieHeist":
|
||||
return parts[1] ?? null;
|
||||
|
||||
case "crumbBlackjack":
|
||||
return parts[2] ?? null;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function replySessionError(
|
||||
interaction,
|
||||
content = "This isn't your session."
|
||||
) {
|
||||
const payload = {
|
||||
content,
|
||||
flags: MessageFlags.Ephemeral
|
||||
};
|
||||
|
||||
if (interaction.replied || interaction.deferred) {
|
||||
return interaction.followUp(payload);
|
||||
}
|
||||
|
||||
return interaction.reply(payload);
|
||||
}
|
||||
|
||||
async function requireInteractionSession(
|
||||
interaction,
|
||||
{
|
||||
kinds = null,
|
||||
allowLegacy = true
|
||||
} = {}
|
||||
) {
|
||||
const session = await getInteractionSession(interaction);
|
||||
|
||||
if (session) {
|
||||
if (session.ownerId !== interaction.user.id) {
|
||||
await replySessionError(interaction);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (
|
||||
Array.isArray(kinds) &&
|
||||
kinds.length > 0 &&
|
||||
!kinds.includes(session.kind)
|
||||
) {
|
||||
await replySessionError(
|
||||
interaction,
|
||||
"This control belongs to a different session."
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
if (allowLegacy) {
|
||||
const ownerId = inferLegacyOwnerId(interaction);
|
||||
|
||||
if (ownerId) {
|
||||
if (ownerId !== interaction.user.id) {
|
||||
await replySessionError(interaction);
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
messageId: interaction.message?.id ?? null,
|
||||
ownerId,
|
||||
guildId: interaction.guildId ?? null,
|
||||
channelId: interaction.channelId ?? null,
|
||||
kind: "legacy",
|
||||
targetId: null,
|
||||
metadata: {},
|
||||
active: true,
|
||||
legacy: true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
messageId: interaction.message?.id ?? null,
|
||||
ownerId: interaction.user.id,
|
||||
kind: "unmanaged",
|
||||
metadata: {},
|
||||
active: true,
|
||||
unmanaged: true
|
||||
};
|
||||
}
|
||||
|
||||
async function guardSessionInteraction(interaction) {
|
||||
if (!interaction.isButton()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const session = await getInteractionSession(interaction);
|
||||
|
||||
if (session) {
|
||||
if (session.ownerId === interaction.user.id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
await replySessionError(interaction);
|
||||
return false;
|
||||
}
|
||||
|
||||
const ownerId = inferLegacyOwnerId(interaction);
|
||||
|
||||
if (!ownerId || ownerId === interaction.user.id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
await replySessionError(interaction);
|
||||
return false;
|
||||
}
|
||||
|
||||
async function closeInteractionSession(interaction) {
|
||||
const session = await requireInteractionSession(interaction);
|
||||
|
||||
if (!session) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (session.messageId && !session.unmanaged) {
|
||||
await getSessionCollection().updateOne(
|
||||
{ messageId: session.messageId },
|
||||
{
|
||||
$set: {
|
||||
active: false,
|
||||
closedAt: new Date(),
|
||||
updatedAt: new Date()
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle("Session Closed")
|
||||
.setDescription("Closing menu. . .");
|
||||
|
||||
await interaction.update({
|
||||
embeds: [embed],
|
||||
components: []
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
interaction.deleteReply().catch(() => {});
|
||||
}, 1200);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
ensureInteractionSessionIndexes,
|
||||
createInteractionSession,
|
||||
registerReplySession,
|
||||
getInteractionSession,
|
||||
requireInteractionSession,
|
||||
guardSessionInteraction,
|
||||
closeInteractionSession,
|
||||
replySessionError,
|
||||
inferLegacyOwnerId
|
||||
};
|
||||
Reference in New Issue
Block a user