added new logic to the new rewards

This commit is contained in:
DeSqBlocki
2026-08-23 00:43:43 +02:00
parent 4d858554be
commit 425686ec40
15 changed files with 1644 additions and 2662 deletions
+38 -35
View File
@@ -1,51 +1,54 @@
const {
requireProfileOwner,
buildAchievementsEmbed,
buildProfileButtons,
buildProfilePaginationButtons
} = require("../../utils/profileSystem");
getProfileContextFromFooter,
requireProfileOwner
} = require(
"../../utils/profileSystem"
);
module.exports = {
name: "profileAchievements",
name:
"profileAchievements",
async execute(interaction) {
const session = await requireProfileOwner(
interaction
);
async execute(
interaction
) {
const context =
await requireProfileOwner(
interaction
);
if (!session) {
if (!context) {
return;
}
const user = await interaction.client.users.fetch(
session.profileUserId
);
const result = await buildAchievementsEmbed(
interaction.guildId,
user,
0,
session.sessionOwnerId
);
const components = [
...buildProfileButtons()
];
if (result.pageCount > 1) {
components.push(
buildProfilePaginationButtons(
"profileAchievementsLeft",
"profileAchievementsRight",
result.page,
result.pageCount
)
const user =
await interaction.client.users.fetch(
context.profileUserId
);
const embed =
await buildAchievementsEmbed(
interaction.guildId,
user,
context.sessionOwnerId,
0
);
const pageContext =
getProfileContextFromFooter(
embed.data.footer?.text
);
}
return interaction.update({
embeds: [result.embed],
components
embeds: [embed],
components:
buildProfileButtons(
"achievements",
pageContext?.page ?? 0,
pageContext?.pageCount ?? 1
)
});
}
};
+38 -37
View File
@@ -1,53 +1,54 @@
// buttons/profile/achievementsLeft.js
const {
requireProfileOwner,
buildAchievementsEmbed,
buildProfileButtons,
buildProfilePaginationButtons
} = require("../../utils/profileSystem");
getProfileContextFromFooter,
requireProfileOwner
} = require(
"../../utils/profileSystem"
);
module.exports = {
name: "profileAchievementsLeft",
name:
"profileAchievementsLeft",
async execute(interaction) {
const session = await requireProfileOwner(
interaction
);
async execute(
interaction
) {
const context =
await requireProfileOwner(
interaction
);
if (!session) {
if (!context) {
return;
}
const user = await interaction.client.users.fetch(
session.profileUserId
);
const result = await buildAchievementsEmbed(
interaction.guildId,
user,
session.page - 1,
session.sessionOwnerId
);
const components = [
...buildProfileButtons()
];
if (result.pageCount > 1) {
components.push(
buildProfilePaginationButtons(
"profileAchievementsLeft",
"profileAchievementsRight",
result.page,
result.pageCount
)
const user =
await interaction.client.users.fetch(
context.profileUserId
);
const embed =
await buildAchievementsEmbed(
interaction.guildId,
user,
context.sessionOwnerId,
context.page - 1
);
const pageContext =
getProfileContextFromFooter(
embed.data.footer?.text
);
}
return interaction.update({
embeds: [result.embed],
components
embeds: [embed],
components:
buildProfileButtons(
"achievements",
pageContext?.page ?? 0,
pageContext?.pageCount ?? 1
)
});
}
};
+38 -37
View File
@@ -1,53 +1,54 @@
// buttons/profile/achievementsRight.js
const {
requireProfileOwner,
buildAchievementsEmbed,
buildProfileButtons,
buildProfilePaginationButtons
} = require("../../utils/profileSystem");
getProfileContextFromFooter,
requireProfileOwner
} = require(
"../../utils/profileSystem"
);
module.exports = {
name: "profileAchievementsRight",
name:
"profileAchievementsRight",
async execute(interaction) {
const session = await requireProfileOwner(
interaction
);
async execute(
interaction
) {
const context =
await requireProfileOwner(
interaction
);
if (!session) {
if (!context) {
return;
}
const user = await interaction.client.users.fetch(
session.profileUserId
);
const result = await buildAchievementsEmbed(
interaction.guildId,
user,
session.page + 1,
session.sessionOwnerId
);
const components = [
...buildProfileButtons()
];
if (result.pageCount > 1) {
components.push(
buildProfilePaginationButtons(
"profileAchievementsLeft",
"profileAchievementsRight",
result.page,
result.pageCount
)
const user =
await interaction.client.users.fetch(
context.profileUserId
);
const embed =
await buildAchievementsEmbed(
interaction.guildId,
user,
context.sessionOwnerId,
context.page + 1
);
const pageContext =
getProfileContextFromFooter(
embed.data.footer?.text
);
}
return interaction.update({
embeds: [result.embed],
components
embeds: [embed],
components:
buildProfileButtons(
"achievements",
pageContext?.page ?? 0,
pageContext?.pageCount ?? 1
)
});
}
};
+38 -35
View File
@@ -1,51 +1,54 @@
const {
requireProfileOwner,
buildBadgesEmbed,
buildProfileButtons,
buildProfilePaginationButtons
} = require("../../utils/profileSystem");
getProfileContextFromFooter,
requireProfileOwner
} = require(
"../../utils/profileSystem"
);
module.exports = {
name: "profileBadges",
name:
"profileBadges",
async execute(interaction) {
const session = await requireProfileOwner(
interaction
);
async execute(
interaction
) {
const context =
await requireProfileOwner(
interaction
);
if (!session) {
if (!context) {
return;
}
const user = await interaction.client.users.fetch(
session.profileUserId
);
const result = await buildBadgesEmbed(
interaction.guildId,
user,
0,
session.sessionOwnerId
);
const components = [
...buildProfileButtons()
];
if (result.pageCount > 1) {
components.push(
buildProfilePaginationButtons(
"profileBadgesLeft",
"profileBadgesRight",
result.page,
result.pageCount
)
const user =
await interaction.client.users.fetch(
context.profileUserId
);
const embed =
await buildBadgesEmbed(
interaction.guildId,
user,
context.sessionOwnerId,
0
);
const pageContext =
getProfileContextFromFooter(
embed.data.footer?.text
);
}
return interaction.update({
embeds: [result.embed],
components
embeds: [embed],
components:
buildProfileButtons(
"badges",
pageContext?.page ?? 0,
pageContext?.pageCount ?? 1
)
});
}
};
+38 -37
View File
@@ -1,53 +1,54 @@
// buttons/profile/badgesLeft.js
const {
requireProfileOwner,
buildBadgesEmbed,
buildProfileButtons,
buildProfilePaginationButtons
} = require("../../utils/profileSystem");
getProfileContextFromFooter,
requireProfileOwner
} = require(
"../../utils/profileSystem"
);
module.exports = {
name: "profileBadgesLeft",
name:
"profileBadgesLeft",
async execute(interaction) {
const session = await requireProfileOwner(
interaction
);
async execute(
interaction
) {
const context =
await requireProfileOwner(
interaction
);
if (!session) {
if (!context) {
return;
}
const user = await interaction.client.users.fetch(
session.profileUserId
);
const result = await buildBadgesEmbed(
interaction.guildId,
user,
session.page - 1,
session.sessionOwnerId
);
const components = [
...buildProfileButtons()
];
if (result.pageCount > 1) {
components.push(
buildProfilePaginationButtons(
"profileBadgesLeft",
"profileBadgesRight",
result.page,
result.pageCount
)
const user =
await interaction.client.users.fetch(
context.profileUserId
);
const embed =
await buildBadgesEmbed(
interaction.guildId,
user,
context.sessionOwnerId,
context.page - 1
);
const pageContext =
getProfileContextFromFooter(
embed.data.footer?.text
);
}
return interaction.update({
embeds: [result.embed],
components
embeds: [embed],
components:
buildProfileButtons(
"badges",
pageContext?.page ?? 0,
pageContext?.pageCount ?? 1
)
});
}
};
+38 -37
View File
@@ -1,53 +1,54 @@
// buttons/profile/badgesRight.js
const {
requireProfileOwner,
buildBadgesEmbed,
buildProfileButtons,
buildProfilePaginationButtons
} = require("../../utils/profileSystem");
getProfileContextFromFooter,
requireProfileOwner
} = require(
"../../utils/profileSystem"
);
module.exports = {
name: "profileBadgesRight",
name:
"profileBadgesRight",
async execute(interaction) {
const session = await requireProfileOwner(
interaction
);
async execute(
interaction
) {
const context =
await requireProfileOwner(
interaction
);
if (!session) {
if (!context) {
return;
}
const user = await interaction.client.users.fetch(
session.profileUserId
);
const result = await buildBadgesEmbed(
interaction.guildId,
user,
session.page + 1,
session.sessionOwnerId
);
const components = [
...buildProfileButtons()
];
if (result.pageCount > 1) {
components.push(
buildProfilePaginationButtons(
"profileBadgesLeft",
"profileBadgesRight",
result.page,
result.pageCount
)
const user =
await interaction.client.users.fetch(
context.profileUserId
);
const embed =
await buildBadgesEmbed(
interaction.guildId,
user,
context.sessionOwnerId,
context.page + 1
);
const pageContext =
getProfileContextFromFooter(
embed.data.footer?.text
);
}
return interaction.update({
embeds: [result.embed],
components
embeds: [embed],
components:
buildProfileButtons(
"badges",
pageContext?.page ?? 0,
pageContext?.pageCount ?? 1
)
});
}
};
+32 -19
View File
@@ -1,34 +1,47 @@
const {
requireProfileOwner,
buildProfileStatsEmbed,
buildProfileButtons
} = require("../../utils/profileSystem");
buildStatsEmbed,
buildProfileButtons,
requireProfileOwner
} = require(
"../../utils/profileSystem"
);
module.exports = {
name: "profileStats",
name:
"profileStats",
async execute(interaction) {
const session = await requireProfileOwner(
interaction
);
async execute(
interaction
) {
const context =
await requireProfileOwner(
interaction
);
if (!session) {
if (!context) {
return;
}
const user = await interaction.client.users.fetch(
session.profileUserId
);
const user =
await interaction.client.users.fetch(
context.profileUserId
);
const embed = await buildProfileStatsEmbed(
interaction.guildId,
user,
session.sessionOwnerId
);
const embed =
await buildStatsEmbed(
interaction.guildId,
user,
context.sessionOwnerId
);
return interaction.update({
embeds: [embed],
components: buildProfileButtons()
components:
buildProfileButtons(
"stats",
0,
1
)
});
}
};
+51 -34
View File
@@ -1,46 +1,63 @@
const { SlashCommandBuilder } = require("discord.js");
const {
SlashCommandBuilder
} = require(
"discord.js"
);
const {
buildProfileOverview,
buildProfileButtons
} = require("../../utils/profileSystem");
const {
createInteractionSession
} = require("../../utils/interactionSession");
} = require(
"../../utils/profileSystem"
);
module.exports = {
data: new SlashCommandBuilder()
.setName("profile")
.setDescription("View a player profile")
.addUserOption(option =>
option
.setName("user")
.setDescription("Player to view")
),
data:
new SlashCommandBuilder()
.setName(
"profile"
)
.setDescription(
"View a player profile"
)
.addUserOption(
option =>
option
.setName(
"user"
)
.setDescription(
"Player to view"
)
),
async execute(interaction) {
const user = interaction.options.getUser("user") ?? interaction.user;
async execute(
interaction
) {
const user =
interaction.options.getUser(
"user"
) ??
interaction.user;
const embed = await buildProfileOverview(
interaction.guildId,
user,
interaction.user.id
);
const sessionOwnerId =
interaction.user.id;
await interaction.reply({
const embed =
await buildProfileOverview(
interaction.guildId,
user,
sessionOwnerId
);
return interaction.reply({
embeds: [embed],
components: buildProfileButtons()
components:
buildProfileButtons(
"overview",
0,
1
)
});
const message = await interaction.fetchReply();
await createInteractionSession(
interaction,
{
messageId: message.id,
ownerId: interaction.user.id,
kind: "profile",
targetId: user.id
}
);
}
};
+189 -341
View File
@@ -1,415 +1,263 @@
const {
SlashCommandBuilder,
MessageFlags
} = require(
"discord.js"
);
PermissionFlagsBits,
MessageFlags,
EmbedBuilder
} = require("discord.js");
const {
requireAdminAccess
reconcileUserAchievements,
reconcileAllAchievements,
auditProfileData
} = require(
"../../utils/permissions"
"../../utils/profileMaintenance"
);
const {
reconcileProfileAchievements,
auditProfileSystem
} = require(
"../../utils/profileSystem"
);
/*
* ============================================================
* COMMAND
* ============================================================
*/
module.exports = {
data:
new SlashCommandBuilder()
.setName(
"profileadmin"
)
.setDescription(
"Profile and achievement administration."
"Administrative profile maintenance tools"
)
.setDefaultMemberPermissions(
PermissionFlagsBits.Administrator
)
/*
* =================================================
* RECONCILE
* =================================================
*/
.addSubcommand(
subcommand =>
subcommand
.setName(
"reconcile"
)
.setDescription(
"Re-evaluate stored statistics for achievements."
"Backfill database-trackable achievements"
)
.addUserOption(
option =>
option
.setName(
"user"
)
.setDescription(
"Only reconcile this user's profile."
)
.setRequired(
false
"Only reconcile this user; omit for everyone"
)
)
.addBooleanOption(
option =>
option
.setName(
"dry-run"
)
.setDescription(
"Show what would change without unlocking anything."
)
.setRequired(
false
"Show what would change without writing it"
)
)
)
/*
* =================================================
* AUDIT
* =================================================
*/
.addSubcommand(
subcommand =>
subcommand
.setName(
"audit"
)
.setDescription(
"Audit the profile and achievement system."
"Audit stored profile statistics for inconsistencies"
)
),
/*
* ========================================================
* EXECUTE
* ========================================================
*/
async execute(
interaction
) {
/*
* Runtime authorization.
*
* This intentionally replaces:
*
* .setDefaultMemberPermissions(
* PermissionFlagsBits.Administrator
* )
*
* so BOT_AUTHOR_ID can also invoke the command.
*/
if (
!await requireAdminAccess(
interaction
)
) {
return;
}
const subcommand =
interaction.options
.getSubcommand();
interaction.options.getSubcommand();
await interaction.deferReply({
flags:
MessageFlags.Ephemeral
});
switch (
subcommand
if (
subcommand ===
"reconcile"
) {
case "reconcile":
return runReconcile(
interaction
const user =
interaction.options.getUser(
"user"
);
const dryRun =
interaction.options.getBoolean(
"dry-run"
) ?? false;
case "audit":
if (user) {
const result =
await reconcileUserAchievements({
guildId:
interaction.guildId,
userId:
user.id,
dryRun
});
return runAudit(
interaction
);
default:
return interaction.reply({
content:
"Unknown profile administration action.",
flags:
MessageFlags.Ephemeral
return interaction.editReply({
embeds: [
new EmbedBuilder()
.setTitle(
"🛠️ Profile Reconciliation"
)
.setDescription(
`${dryRun ? "Dry run for" : "Reconciled"} ${user}.`
)
.addFields(
{
name:
"New unlocks",
value:
`**${result.unlocked}**`,
inline:
true
},
{
name:
"Definitions checked",
value:
`**${result.checked}**`,
inline:
true
},
{
name:
"Event-only skipped",
value:
`**${result.skippedEventOnly}**`,
inline:
true
}
)
]
});
}
}
};
/*
* ============================================================
* RECONCILE
* ============================================================
*/
async function runReconcile(
interaction
) {
const target =
interaction.options.getUser(
"user"
);
const dryRun =
interaction.options.getBoolean(
"dry-run"
)
??
false;
/*
* This can touch multiple Mongo documents,
* so acknowledge the interaction first.
*/
await interaction.deferReply({
flags:
MessageFlags.Ephemeral
});
try {
const result =
await reconcileProfileAchievements(
interaction.guildId,
{
userId:
target?.id
??
null,
dryRun
}
);
const lines = [
dryRun
? "### 🔎 Profile Reconciliation — Dry Run"
: "### ✅ Profile Reconciliation Complete",
"",
target
? `Target: ${target}`
: "Target: **Entire Guild**",
"",
`Profiles checked: **${result.profilesChecked ?? 0}**`,
`Achievement unlocks found: **${result.unlocksFound ?? 0}**`
];
if (
!dryRun
) {
lines.push(
`Achievements unlocked: **${result.unlocksApplied ?? 0}**`
);
}
if (
result.skippedEventOnly !==
undefined
) {
lines.push(
`Event-only checks skipped: **${result.skippedEventOnly}**`
);
}
if (
Array.isArray(
result.details
)
&&
result.details.length >
0
) {
const preview =
result.details
.slice(
0,
15
)
.map(
entry => {
if (
typeof entry ===
"string"
) {
return `• ${entry}`;
}
return (
`• <@${entry.userId}> — ` +
`${entry.achievementName ?? entry.achievementId}`
);
}
);
lines.push(
"",
"### Changes",
...preview
);
if (
result.details.length >
preview.length
) {
lines.push(
"",
`*...and ${result.details.length - preview.length} more.*`
);
}
const summary =
await reconcileAllAchievements({
guildId:
interaction.guildId,
dryRun
});
return interaction.editReply({
embeds: [
new EmbedBuilder()
.setTitle(
"🛠️ Profile Reconciliation"
)
.setDescription(
`${dryRun ? "Dry run completed" : "Reconciliation completed"} for stored profile users.`
)
.addFields(
{
name:
"Users",
value:
`**${summary.users}**`,
inline:
true
},
{
name:
"New unlocks",
value:
`**${summary.unlocked}**`,
inline:
true
},
{
name:
"Event-only checks skipped",
value:
`**${summary.skippedEventOnly}**`,
inline:
true
}
)
]
});
}
return interaction.editReply({
content:
lines.join(
"\n"
)
});
} catch (error) {
console.error(
"[ProfileAdmin] Reconciliation failed:",
error
);
return interaction.editReply({
content:
"Profile reconciliation failed. Check the bot logs for details."
});
}
}
/*
* ============================================================
* AUDIT
* ============================================================
*/
async function runAudit(
interaction
) {
await interaction.deferReply({
flags:
MessageFlags.Ephemeral
});
try {
const result =
await auditProfileSystem(
const audit =
await auditProfileData(
interaction.guildId
);
const lines = [
"### 🧾 Profile System Audit",
"",
`Profile documents: **${result.profileDocuments ?? 0}**`,
`Achievement documents: **${result.achievementDocuments ?? 0}**`,
`Active achievement definitions: **${result.activeAchievements ?? 0}**`,
`Legacy achievement definitions: **${result.legacyAchievements ?? 0}**`,
`Guild badges: **${result.badges ?? 0}**`,
`Claimed badges: **${result.claimedBadges ?? 0}**`,
`Available badges: **${result.availableBadges ?? 0}**`
];
if (
Array.isArray(
result.warnings
)
&&
result.warnings.length >
0
) {
lines.push(
"",
"### ⚠️ Warnings",
...result.warnings.map(
warning =>
`• ${warning}`
)
);
}
else {
lines.push(
"",
"✅ No obvious profile-system issues were found."
);
}
const issuePreview =
audit.issues
.slice(0, 10)
.join("\n");
return interaction.editReply({
content:
lines.join(
"\n"
)
});
} catch (error) {
console.error(
"[ProfileAdmin] Audit failed:",
error
);
return interaction.editReply({
content:
"Profile audit failed. Check the bot logs for details."
embeds: [
new EmbedBuilder()
.setTitle(
"🔎 Profile Data Audit"
)
.addFields(
{
name:
"Stats documents",
value:
`**${audit.statDocuments}**`,
inline:
true
},
{
name:
"Achievement documents",
value:
`**${audit.achievementDocuments}**`,
inline:
true
},
{
name:
"Active achievements",
value:
`**${audit.activeAchievements}**`,
inline:
true
},
{
name:
"Global badges",
value:
`**${audit.badgeDocuments}** (${audit.claimedBadges} claimed)`,
inline:
true
},
{
name:
"Orphan achievement docs",
value:
`**${audit.orphanAchievementDocs}**`,
inline:
true
},
{
name:
"Issues",
value:
`**${audit.issueCount}**`,
inline:
true
}
)
.setDescription(
issuePreview
? `First issues:\n${issuePreview}`
: "No structural inconsistencies found."
)
]
});
}
}
};
+1 -1
View File
@@ -16,7 +16,7 @@ module.exports = {
"records"
)
.setDescription(
"View Shai Cookie and Crumb Saucer records"
"View Olymp Cookie and Crumb Saucer records"
)
.addStringOption(
option =>
+6 -6
View File
@@ -27,30 +27,30 @@ const HEIST_METHODS = {
baseChance: 0.65,
minStealPercent: 0.01,
maxStealPercent: 0.03,
maxStealAmount: 5000,
maxStealAmount: 1500,
minPenaltyPercent: 0.01,
maxPenaltyPercent: 0.04,
maxPenaltyAmount: 1500
maxPenaltyAmount: 750
},
Hack: {
baseChance: 0.45,
minStealPercent: 0.03,
maxStealPercent: 0.06,
maxStealAmount: 12500,
maxStealAmount: 3500,
minPenaltyPercent: 0.03,
maxPenaltyPercent: 0.07,
maxPenaltyAmount: 4000
maxPenaltyAmount: 2000
},
Smash: {
baseChance: 0.25,
minStealPercent: 0.06,
maxStealPercent: 0.12,
maxStealAmount: 25000,
maxStealAmount: 7500,
minPenaltyPercent: 0.06,
maxPenaltyPercent: 0.12,
maxPenaltyAmount: 10000
maxPenaltyAmount: 5000
}
};
+80 -10
View File
@@ -18,7 +18,8 @@ const {
} = require("./cookieEconomy");
const {
recordGameOutcome
recordGameOutcome,
trackProfileEvent
} = require("./profileSystem");
const GAME_COLLECTION =
@@ -112,7 +113,9 @@ async function startBlackjack(
interaction,
bet,
allowCustomBet = false,
allIn = false
source = "normal",
previousAllIn = false,
previousBet = 0
) {
if (
!allowCustomBet &&
@@ -196,6 +199,9 @@ async function startBlackjack(
getCookieBalance(houseId)
]);
const allIn =
bet === playerBalance;
if (playerBalance < bet) {
return temporaryEphemeralReply(
interaction,
@@ -276,6 +282,11 @@ async function startBlackjack(
doubled:
false,
allIn,
vaultAtBet:
playerBalance,
source,
previousAllIn,
previousBet,
deck,
playerCards,
dealerCards,
@@ -285,6 +296,20 @@ async function startBlackjack(
await games.insertOne(game);
await trackProfileEvent(
interaction,
playerId,
{
type: "game_start",
game: "blackjack",
source,
bet,
allIn,
previousAllIn,
previousBet
}
);
const playerBlackjack =
isBlackjack(playerCards);
@@ -370,7 +395,7 @@ async function startBlackjackAllIn(
interaction,
balance,
true,
true
"all_in"
);
}
@@ -405,6 +430,9 @@ async function runBlackjackBack(
const bet =
Number(parts[2]);
const previousAllIn =
parts[3] === "1";
if (
ownerId !==
interaction.user.id
@@ -435,7 +463,9 @@ async function runBlackjackBack(
interaction,
bet,
true,
false
"run_it_back",
previousAllIn,
bet
);
}
@@ -803,6 +833,32 @@ async function finishBlackjack(
game,
result
) {
const { db } = getCollections();
const claim = await db
.collection(GAME_COLLECTION)
.updateOne(
{
gameId: game.gameId,
state: "Playing"
},
{
$set: {
state: "Resolving"
}
}
);
if (claim.modifiedCount !== 1) {
return temporaryEphemeralReply(
interaction,
{
content:
"This Blackjack hand is already being resolved."
}
);
}
const houseId =
interaction.client.user.id;
@@ -845,6 +901,23 @@ async function finishBlackjack(
`[Blackjack] House cannot cover payout ${payout} for ${game.userId}`
);
await db
.collection(GAME_COLLECTION)
.updateOne(
{
gameId: game.gameId,
state: "Resolving"
},
{
$set: {
state: "Finished",
result: "PayoutError",
payout: 0,
finishedAt: getUnixTime()
}
}
);
return interaction.update({
embeds: [
new EmbedBuilder()
@@ -856,7 +929,7 @@ async function finishBlackjack(
)
.setFooter({
text:
`crumbBlackjackResult:${game.userId}:${game.originalBet}`
`crumbBlackjackResult:${game.userId}:${game.originalBet}:${game.allIn ? 1 : 0}`
})
],
components:
@@ -871,9 +944,6 @@ async function finishBlackjack(
);
}
const { db } =
getCollections();
await db
.collection(
GAME_COLLECTION
@@ -883,7 +953,7 @@ async function finishBlackjack(
gameId:
game.gameId,
state:
"Playing"
"Resolving"
},
{
$set: {
@@ -1010,7 +1080,7 @@ async function finishBlackjack(
)
.setFooter({
text:
`crumbBlackjackResult:${game.userId}:${game.originalBet}`
`crumbBlackjackResult:${game.userId}:${game.originalBet}:${game.allIn ? 1 : 0}`
});
return interaction.update({
+37 -9
View File
@@ -12,7 +12,8 @@ const {
} = require("./cookieEconomy");
const {
recordGameOutcome
recordGameOutcome,
trackProfileEvent
} = require("./profileSystem");
const ROULETTE_BETS = [
@@ -206,7 +207,10 @@ async function startRouletteAllIn(
async function showRouletteChoices(
interaction,
bet,
allIn = false
requestedAllIn = false,
source = "normal",
previousAllIn = false,
previousBet = 0
) {
if (
!Number.isSafeInteger(bet) ||
@@ -262,7 +266,7 @@ async function showRouletteChoices(
})
.setFooter({
text:
`crumbRouletteBet:${interaction.user.id}:${bet}:${allIn ? 1 : 0}`
`crumbRouletteBet:${interaction.user.id}:${bet}:${requestedAllIn ? 1 : 0}:${source}:${previousAllIn ? 1 : 0}:${previousBet}`
});
return interaction.update({
@@ -303,6 +307,9 @@ async function runRouletteBack(
const bet =
Number(parts[2]);
const previousAllIn =
parts[3] === "1";
if (
ownerId !==
interaction.user.id
@@ -383,8 +390,14 @@ async function playRoulette(
const bet =
Number(parts[2]);
const allIn =
parts[3] === "1";
const source =
parts[4] || "normal";
const previousAllIn =
parts[5] === "1";
const previousBet =
Number(parts[6] ?? 0);
if (
ownerId !==
@@ -476,6 +489,23 @@ async function playRoulette(
throw error;
}
const allIn =
bet === playerBalance;
await trackProfileEvent(
interaction,
playerId,
{
type: "game_start",
game: "roulette",
source,
bet,
allIn,
previousAllIn,
previousBet
}
);
await interaction.update({
embeds: [
buildSpinEmbed(
@@ -594,9 +624,7 @@ async function playRoulette(
won &&
choiceKey ===
"Zero",
allIn:
won &&
allIn
allIn
}
);
@@ -664,7 +692,7 @@ async function playRoulette(
)
.setFooter({
text:
`crumbRouletteResult:${playerId}:${bet}`
`crumbRouletteResult:${playerId}:${bet}:${allIn ? 1 : 0}`
});
return interaction.editReply({
+21 -3
View File
@@ -13,7 +13,8 @@ const {
} = require("./cookieEconomy");
const {
recordGameOutcome
recordGameOutcome,
trackProfileEvent
} = require("./profileSystem");
const SLOT_BETS = [
@@ -104,7 +105,8 @@ async function showSlots(interaction) {
async function playSlots(
interaction,
bet
bet,
source = "normal"
) {
const ownerId =
getSlotsSessionOwner(
@@ -197,6 +199,17 @@ async function playSlots(
throw error;
}
await trackProfileEvent(
interaction,
playerId,
{
type: "game_start",
game: "slots",
source,
bet
}
);
await interaction.update({
embeds: [
buildSpinningEmbed(
@@ -321,6 +334,10 @@ async function playSlots(
? "loss"
: "push",
profit,
triplet:
outcome.type === "triple"
? outcome.symbol
: null,
jackpot:
outcome.type ===
"triple" &&
@@ -460,7 +477,8 @@ async function runSlotsBack(
return playSlots(
interaction,
bet
bet,
"run_it_back"
);
}
+991 -2013
View File
File diff suppressed because it is too large Load Diff