Compare commits
2 Commits
9710fc65bf
...
e3dbb11e12
| Author | SHA1 | Date | |
|---|---|---|---|
| e3dbb11e12 | |||
| 14a059034c |
@@ -1,3 +1,4 @@
|
||||
node_modules
|
||||
.env
|
||||
backup/
|
||||
*.bak
|
||||
@@ -451,8 +451,8 @@ async function steal(interaction) {
|
||||
interaction,
|
||||
user.id,
|
||||
{
|
||||
type:
|
||||
"steal_success",
|
||||
type: "steal_success",
|
||||
source: "steal",
|
||||
amount,
|
||||
targetUserId:
|
||||
target.id
|
||||
@@ -464,9 +464,11 @@ async function steal(interaction) {
|
||||
interaction,
|
||||
user.id,
|
||||
{
|
||||
type:
|
||||
"cookie_gain",
|
||||
amount
|
||||
type: "cookie_gain",
|
||||
source: "steal",
|
||||
amount,
|
||||
targetUserId:
|
||||
target.id
|
||||
}
|
||||
);
|
||||
|
||||
@@ -479,22 +481,23 @@ async function steal(interaction) {
|
||||
interaction,
|
||||
target.id,
|
||||
{
|
||||
type:
|
||||
"stolen_from_me",
|
||||
type: "stolen_from_me",
|
||||
source: "steal",
|
||||
amount,
|
||||
thiefUserId:
|
||||
user.id
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
await trackProfileEvent(
|
||||
interaction,
|
||||
target.id,
|
||||
{
|
||||
type:
|
||||
"cookie_loss",
|
||||
amount
|
||||
type: "cookie_loss",
|
||||
source: "steal",
|
||||
amount,
|
||||
thiefUserId:
|
||||
user.id
|
||||
}
|
||||
);
|
||||
|
||||
@@ -657,10 +660,12 @@ async function steal(interaction) {
|
||||
interaction,
|
||||
user.id,
|
||||
{
|
||||
type:
|
||||
"cookie_loss",
|
||||
type: "cookie_loss",
|
||||
source: "steal_penalty",
|
||||
amount:
|
||||
penalty
|
||||
penalty,
|
||||
targetUserId:
|
||||
target.id
|
||||
}
|
||||
);
|
||||
|
||||
@@ -669,10 +674,12 @@ async function steal(interaction) {
|
||||
interaction,
|
||||
target.id,
|
||||
{
|
||||
type:
|
||||
"cookie_gain",
|
||||
type: "cookie_gain",
|
||||
source: "steal_penalty",
|
||||
amount:
|
||||
penalty
|
||||
penalty,
|
||||
thiefUserId:
|
||||
user.id
|
||||
}
|
||||
);
|
||||
|
||||
@@ -906,9 +913,11 @@ async function give(interaction) {
|
||||
interaction,
|
||||
user.id,
|
||||
{
|
||||
type:
|
||||
"cookies_given",
|
||||
amount
|
||||
type: "cookies_given",
|
||||
source: "give",
|
||||
amount,
|
||||
targetUserId:
|
||||
target.id
|
||||
}
|
||||
);
|
||||
|
||||
@@ -921,9 +930,11 @@ async function give(interaction) {
|
||||
interaction,
|
||||
target.id,
|
||||
{
|
||||
type:
|
||||
"cookie_gain",
|
||||
amount
|
||||
type: "cookie_gain",
|
||||
source: "give",
|
||||
amount,
|
||||
senderUserId:
|
||||
user.id
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -166,6 +166,18 @@ async function declareBankruptcy(interaction, userId = interaction.user.id) {
|
||||
userId,
|
||||
{
|
||||
type: "cookie_gain",
|
||||
source: "bankruptcy",
|
||||
amount:
|
||||
BANKRUPTCY_GRANT
|
||||
}
|
||||
);
|
||||
|
||||
await trackProfileEvent(
|
||||
interaction,
|
||||
userId,
|
||||
{
|
||||
type: "bankruptcy",
|
||||
source: "bankruptcy",
|
||||
amount: BANKRUPTCY_GRANT
|
||||
}
|
||||
);
|
||||
|
||||
+10
-3
@@ -269,17 +269,24 @@ async function resolveCookieHeist(
|
||||
}
|
||||
);
|
||||
|
||||
/*
|
||||
* ============================================================
|
||||
* HEIST
|
||||
* ============================================================
|
||||
*/
|
||||
|
||||
await trackProfileEvent(
|
||||
interaction,
|
||||
playerId,
|
||||
{
|
||||
type:
|
||||
"vault_steal",
|
||||
type: "vault_steal",
|
||||
source: "heist",
|
||||
game: "heist",
|
||||
result: "win",
|
||||
amount
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
const [
|
||||
playerAfter,
|
||||
vaultAfter
|
||||
|
||||
@@ -303,7 +303,7 @@ async function startBlackjack(
|
||||
type: "game_start",
|
||||
game: "blackjack",
|
||||
source,
|
||||
bet,
|
||||
wager: bet,
|
||||
allIn,
|
||||
previousAllIn,
|
||||
previousBet
|
||||
|
||||
@@ -92,6 +92,7 @@ async function collectCookies(
|
||||
userId,
|
||||
{
|
||||
type: "cookie_gain",
|
||||
source: "collect",
|
||||
amount
|
||||
}
|
||||
);
|
||||
|
||||
@@ -502,7 +502,7 @@ async function playRoulette(
|
||||
type: "game_start",
|
||||
game: "roulette",
|
||||
source,
|
||||
bet,
|
||||
wager: bet,
|
||||
allIn,
|
||||
previousAllIn,
|
||||
previousBet
|
||||
|
||||
+8
-2
@@ -106,7 +106,9 @@ async function showSlots(interaction) {
|
||||
async function playSlots(
|
||||
interaction,
|
||||
bet,
|
||||
source = "normal"
|
||||
source = "normal",
|
||||
previousAllIn = false,
|
||||
previousBet = 0
|
||||
) {
|
||||
const ownerId =
|
||||
getSlotsSessionOwner(
|
||||
@@ -206,7 +208,11 @@ async function playSlots(
|
||||
type: "game_start",
|
||||
game: "slots",
|
||||
source,
|
||||
bet
|
||||
wager: bet,
|
||||
allIn:
|
||||
bet === playerBalance,
|
||||
previousAllIn,
|
||||
previousBet
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
+360
-2
@@ -6,10 +6,18 @@ const {
|
||||
} = require("./profileSystem");
|
||||
|
||||
const {
|
||||
getUnixTime
|
||||
getUnixTime,
|
||||
changeCookies
|
||||
} = require("./cookieEconomy");
|
||||
|
||||
|
||||
const DEFAULT_MAINTENANCE_REWARD_ID =
|
||||
"maintenance_2026_08_27";
|
||||
|
||||
const DEFAULT_MAINTENANCE_REWARD_AMOUNT =
|
||||
5000;
|
||||
|
||||
|
||||
function getActiveDefinitions(
|
||||
achievementConfig
|
||||
) {
|
||||
@@ -356,6 +364,292 @@ async function reconcileAllAchievements({
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function grantMaintenanceReward({
|
||||
guildId,
|
||||
rewardId =
|
||||
DEFAULT_MAINTENANCE_REWARD_ID,
|
||||
amount =
|
||||
DEFAULT_MAINTENANCE_REWARD_AMOUNT,
|
||||
dryRun = false
|
||||
}) {
|
||||
if (!guildId) {
|
||||
throw new Error(
|
||||
"guildId is required."
|
||||
);
|
||||
}
|
||||
|
||||
const normalizedRewardId =
|
||||
String(
|
||||
rewardId ?? ""
|
||||
).trim();
|
||||
|
||||
if (!normalizedRewardId) {
|
||||
throw new Error(
|
||||
"rewardId is required."
|
||||
);
|
||||
}
|
||||
|
||||
const normalizedAmount =
|
||||
Number(
|
||||
amount
|
||||
);
|
||||
|
||||
if (
|
||||
!Number.isSafeInteger(
|
||||
normalizedAmount
|
||||
)
|
||||
||
|
||||
normalizedAmount <= 0
|
||||
) {
|
||||
throw new Error(
|
||||
"Maintenance reward amount must be a positive safe integer."
|
||||
);
|
||||
}
|
||||
|
||||
const {
|
||||
stats
|
||||
} =
|
||||
getProfileCollections();
|
||||
|
||||
const userIds =
|
||||
await stats.distinct(
|
||||
"userId",
|
||||
{
|
||||
guildId
|
||||
}
|
||||
);
|
||||
|
||||
const summary = {
|
||||
guildId,
|
||||
rewardId:
|
||||
normalizedRewardId,
|
||||
amount:
|
||||
normalizedAmount,
|
||||
users:
|
||||
userIds.length,
|
||||
eligible:
|
||||
0,
|
||||
granted:
|
||||
0,
|
||||
alreadyClaimed:
|
||||
0,
|
||||
failed:
|
||||
0,
|
||||
dryRun,
|
||||
results: []
|
||||
};
|
||||
|
||||
for (const userId of userIds) {
|
||||
const existing =
|
||||
await stats.findOne(
|
||||
{
|
||||
userId,
|
||||
guildId
|
||||
},
|
||||
{
|
||||
projection: {
|
||||
"maintenance.rewardsClaimed":
|
||||
1
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const rewardsClaimed =
|
||||
Array.isArray(
|
||||
existing
|
||||
?.maintenance
|
||||
?.rewardsClaimed
|
||||
)
|
||||
? existing
|
||||
.maintenance
|
||||
.rewardsClaimed
|
||||
: [];
|
||||
|
||||
if (
|
||||
rewardsClaimed.includes(
|
||||
normalizedRewardId
|
||||
)
|
||||
) {
|
||||
summary.alreadyClaimed++;
|
||||
|
||||
summary.results.push({
|
||||
userId,
|
||||
status:
|
||||
"already_claimed"
|
||||
});
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
summary.eligible++;
|
||||
|
||||
if (dryRun) {
|
||||
summary.results.push({
|
||||
userId,
|
||||
status:
|
||||
"would_grant"
|
||||
});
|
||||
|
||||
console.log(
|
||||
`[ProfileMaintenance] Dry run: would grant ${normalizedAmount} Cookies to ${userId} for ${normalizedRewardId}.`
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
const reservation =
|
||||
await stats.updateOne(
|
||||
{
|
||||
userId,
|
||||
guildId,
|
||||
"maintenance.rewardsClaimed": {
|
||||
$ne:
|
||||
normalizedRewardId
|
||||
}
|
||||
},
|
||||
{
|
||||
$addToSet: {
|
||||
"maintenance.rewardsClaimed":
|
||||
normalizedRewardId
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (
|
||||
reservation.modifiedCount !==
|
||||
1
|
||||
) {
|
||||
summary.alreadyClaimed++;
|
||||
|
||||
summary.results.push({
|
||||
userId,
|
||||
status:
|
||||
"already_claimed"
|
||||
});
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
await changeCookies(
|
||||
userId,
|
||||
normalizedAmount
|
||||
);
|
||||
|
||||
summary.granted++;
|
||||
|
||||
summary.results.push({
|
||||
userId,
|
||||
status:
|
||||
"granted"
|
||||
});
|
||||
|
||||
console.log(
|
||||
`[ProfileMaintenance] Granted ${normalizedAmount} Cookies to ${userId} for ${normalizedRewardId}.`
|
||||
);
|
||||
}
|
||||
|
||||
catch (error) {
|
||||
await stats.updateOne(
|
||||
{
|
||||
userId,
|
||||
guildId
|
||||
},
|
||||
{
|
||||
$pull: {
|
||||
"maintenance.rewardsClaimed":
|
||||
normalizedRewardId
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
summary.failed++;
|
||||
|
||||
summary.results.push({
|
||||
userId,
|
||||
status:
|
||||
"failed",
|
||||
error:
|
||||
error?.message ??
|
||||
String(error)
|
||||
});
|
||||
|
||||
console.error(
|
||||
`[ProfileMaintenance] Failed to grant ${normalizedAmount} Cookies to ${userId} for ${normalizedRewardId}:`,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(
|
||||
`[ProfileMaintenance] Maintenance reward ${normalizedRewardId}: ${summary.granted} granted, ${summary.alreadyClaimed} already claimed, ${summary.failed} failed, ${summary.users} stored profile user(s) checked.`
|
||||
);
|
||||
|
||||
return summary;
|
||||
}
|
||||
|
||||
|
||||
async function getMaintenanceRewardStatus({
|
||||
guildId,
|
||||
rewardId =
|
||||
DEFAULT_MAINTENANCE_REWARD_ID
|
||||
}) {
|
||||
if (!guildId) {
|
||||
throw new Error(
|
||||
"guildId is required."
|
||||
);
|
||||
}
|
||||
|
||||
const normalizedRewardId =
|
||||
String(
|
||||
rewardId ?? ""
|
||||
).trim();
|
||||
|
||||
if (!normalizedRewardId) {
|
||||
throw new Error(
|
||||
"rewardId is required."
|
||||
);
|
||||
}
|
||||
|
||||
const {
|
||||
stats
|
||||
} =
|
||||
getProfileCollections();
|
||||
|
||||
const [
|
||||
users,
|
||||
claimed
|
||||
] =
|
||||
await Promise.all([
|
||||
stats.countDocuments({
|
||||
guildId
|
||||
}),
|
||||
|
||||
stats.countDocuments({
|
||||
guildId,
|
||||
"maintenance.rewardsClaimed":
|
||||
normalizedRewardId
|
||||
})
|
||||
]);
|
||||
|
||||
return {
|
||||
guildId,
|
||||
rewardId:
|
||||
normalizedRewardId,
|
||||
amount:
|
||||
DEFAULT_MAINTENANCE_REWARD_AMOUNT,
|
||||
users,
|
||||
claimed,
|
||||
remaining:
|
||||
Math.max(
|
||||
0,
|
||||
users - claimed
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
async function auditProfileData(
|
||||
guildId
|
||||
) {
|
||||
@@ -783,6 +1077,65 @@ async function auditProfileData(
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------
|
||||
* MAINTENANCE REWARDS
|
||||
* ----------------------------------------------------
|
||||
*/
|
||||
|
||||
const rewardsClaimed =
|
||||
document
|
||||
.maintenance
|
||||
?.rewardsClaimed;
|
||||
|
||||
if (
|
||||
rewardsClaimed !==
|
||||
undefined
|
||||
&&
|
||||
!Array.isArray(
|
||||
rewardsClaimed
|
||||
)
|
||||
) {
|
||||
issues.push(
|
||||
`${document.userId}: maintenance.rewardsClaimed is not an array.`
|
||||
);
|
||||
}
|
||||
|
||||
else if (
|
||||
Array.isArray(
|
||||
rewardsClaimed
|
||||
)
|
||||
) {
|
||||
const uniqueRewards =
|
||||
new Set(
|
||||
rewardsClaimed
|
||||
);
|
||||
|
||||
if (
|
||||
uniqueRewards.size !==
|
||||
rewardsClaimed.length
|
||||
) {
|
||||
issues.push(
|
||||
`${document.userId}: maintenance.rewardsClaimed contains duplicate reward IDs.`
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
rewardsClaimed.some(
|
||||
rewardId =>
|
||||
typeof rewardId !==
|
||||
"string"
|
||||
||
|
||||
!rewardId.trim()
|
||||
)
|
||||
) {
|
||||
issues.push(
|
||||
`${document.userId}: maintenance.rewardsClaimed contains an invalid reward ID.`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------
|
||||
* SCHEMA VERSION
|
||||
@@ -1407,5 +1760,10 @@ function isValidWeekKey(
|
||||
module.exports = {
|
||||
reconcileUserAchievements,
|
||||
reconcileAllAchievements,
|
||||
auditProfileData
|
||||
grantMaintenanceReward,
|
||||
getMaintenanceRewardStatus,
|
||||
auditProfileData,
|
||||
|
||||
DEFAULT_MAINTENANCE_REWARD_ID,
|
||||
DEFAULT_MAINTENANCE_REWARD_AMOUNT
|
||||
};
|
||||
+702
-24
@@ -409,6 +409,145 @@ async function ensureProfileSystem() {
|
||||
);
|
||||
}
|
||||
|
||||
async function evaluateSocialRelationshipFlags(
|
||||
userId,
|
||||
guildId,
|
||||
event
|
||||
) {
|
||||
const {
|
||||
stats
|
||||
} =
|
||||
getProfileCollections();
|
||||
|
||||
|
||||
const document =
|
||||
await stats.findOne({
|
||||
userId,
|
||||
guildId
|
||||
});
|
||||
|
||||
|
||||
if (!document) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const social =
|
||||
document.social ?? {};
|
||||
|
||||
|
||||
const set = {};
|
||||
|
||||
|
||||
/*
|
||||
* ========================================================
|
||||
* ET TU, CRUMB?
|
||||
* ========================================================
|
||||
*
|
||||
* Successfully steal from somebody who has
|
||||
* previously gifted Cookies to you.
|
||||
*/
|
||||
|
||||
if (
|
||||
event.type ===
|
||||
"steal_success"
|
||||
&&
|
||||
event.targetUserId
|
||||
&&
|
||||
Array.isArray(
|
||||
social.receivedFrom
|
||||
)
|
||||
&&
|
||||
social.receivedFrom.includes(
|
||||
event.targetUserId
|
||||
)
|
||||
) {
|
||||
set[
|
||||
"special.etTuCrumb"
|
||||
] = 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ========================================================
|
||||
* NO HARD FEELINGS
|
||||
* ========================================================
|
||||
*
|
||||
* Give Cookies to somebody who has previously
|
||||
* successfully stolen from you.
|
||||
*/
|
||||
|
||||
if (
|
||||
event.type ===
|
||||
"cookies_given"
|
||||
&&
|
||||
event.targetUserId
|
||||
&&
|
||||
Array.isArray(
|
||||
social.successfullyStolenBy
|
||||
)
|
||||
&&
|
||||
social.successfullyStolenBy.includes(
|
||||
event.targetUserId
|
||||
)
|
||||
) {
|
||||
set[
|
||||
"special.noHardFeelings"
|
||||
] = 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ========================================================
|
||||
* COOKIE LAUNDERING
|
||||
* ========================================================
|
||||
*
|
||||
* Give Cookies to somebody you have previously
|
||||
* successfully stolen from.
|
||||
*/
|
||||
|
||||
if (
|
||||
event.type ===
|
||||
"cookies_given"
|
||||
&&
|
||||
event.targetUserId
|
||||
&&
|
||||
Array.isArray(
|
||||
social.successfullyStolenFrom
|
||||
)
|
||||
&&
|
||||
social.successfullyStolenFrom.includes(
|
||||
event.targetUserId
|
||||
)
|
||||
) {
|
||||
set[
|
||||
"special.cookieLaundering"
|
||||
] = 1;
|
||||
}
|
||||
|
||||
|
||||
if (
|
||||
Object.keys(
|
||||
set
|
||||
).length ===
|
||||
0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
await stats.updateOne(
|
||||
{
|
||||
userId,
|
||||
guildId
|
||||
},
|
||||
{
|
||||
$set:
|
||||
set
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function getDefaultStats(userId, guildId) {
|
||||
return {
|
||||
userId,
|
||||
@@ -486,8 +625,21 @@ function getDefaultStats(userId, guildId) {
|
||||
bestLoss: 0
|
||||
},
|
||||
|
||||
social: {
|
||||
giftedTo: [],
|
||||
receivedFrom: [],
|
||||
successfullyStolenFrom: [],
|
||||
successfullyStolenBy: []
|
||||
},
|
||||
|
||||
special: {
|
||||
allInRunItBack: 0
|
||||
allInRunItBack: 0,
|
||||
bankruptcyCount: 0,
|
||||
bankruptcyRecoveryBest: 0,
|
||||
|
||||
etTuCrumb: 0,
|
||||
noHardFeelings: 0,
|
||||
cookieLaundering: 0
|
||||
},
|
||||
|
||||
activity: {
|
||||
@@ -517,6 +669,22 @@ function getDefaultStats(userId, guildId) {
|
||||
evening: 0
|
||||
}
|
||||
},
|
||||
daily: {
|
||||
dateKey: null,
|
||||
|
||||
gamesPlayed: [],
|
||||
gamesWon: [],
|
||||
gamesLost: [],
|
||||
|
||||
collectedCookies: false,
|
||||
gambledAfterCollect: false,
|
||||
|
||||
wonAnyGame: false,
|
||||
lostAnyGame: false,
|
||||
|
||||
gaveCookies: false,
|
||||
stoleCookies: false
|
||||
},
|
||||
|
||||
profileSchemaVersion: 2
|
||||
};
|
||||
@@ -590,16 +758,54 @@ async function trackProfileEvent(
|
||||
switch (event.type) {
|
||||
case "cookie_gain":
|
||||
await stats.updateOne(
|
||||
{ userId, guildId },
|
||||
{
|
||||
userId,
|
||||
guildId
|
||||
},
|
||||
{
|
||||
$inc: {
|
||||
"economy.cookiesObtainedTotal":
|
||||
event.amount
|
||||
},
|
||||
|
||||
...(
|
||||
event.source === "give" &&
|
||||
event.senderUserId
|
||||
? {
|
||||
$addToSet: {
|
||||
"social.receivedFrom":
|
||||
event.senderUserId
|
||||
},
|
||||
|
||||
$set: {
|
||||
"special.lastGiftSenderId":
|
||||
event.senderUserId
|
||||
}
|
||||
}
|
||||
: {}
|
||||
)
|
||||
}
|
||||
);
|
||||
break;
|
||||
case "bankruptcy":
|
||||
await stats.updateOne(
|
||||
{
|
||||
userId,
|
||||
guildId
|
||||
},
|
||||
{
|
||||
$inc: {
|
||||
"special.bankruptcyCount":
|
||||
1
|
||||
},
|
||||
|
||||
$set: {
|
||||
"special.bankruptcyRecoveryBest":
|
||||
0
|
||||
}
|
||||
}
|
||||
);
|
||||
break;
|
||||
|
||||
case "cookie_loss":
|
||||
await stats.updateOne(
|
||||
{ userId, guildId },
|
||||
@@ -614,48 +820,87 @@ async function trackProfileEvent(
|
||||
|
||||
case "cookies_given":
|
||||
await stats.updateOne(
|
||||
{ userId, guildId },
|
||||
{
|
||||
userId,
|
||||
guildId
|
||||
},
|
||||
{
|
||||
$inc: {
|
||||
"economy.cookiesGivenTotal":
|
||||
event.amount
|
||||
},
|
||||
|
||||
...(event.targetUserId
|
||||
? {
|
||||
$addToSet: {
|
||||
"social.giftedTo":
|
||||
event.targetUserId
|
||||
},
|
||||
|
||||
$set: {
|
||||
"special.lastGiftTargetId":
|
||||
event.targetUserId
|
||||
}
|
||||
}
|
||||
: {})
|
||||
}
|
||||
);
|
||||
break;
|
||||
|
||||
case "steal_success":
|
||||
await stats.updateOne(
|
||||
{ userId, guildId },
|
||||
{
|
||||
userId,
|
||||
guildId
|
||||
},
|
||||
{
|
||||
$inc: {
|
||||
"economy.stolenTotal":
|
||||
event.amount
|
||||
},
|
||||
|
||||
$addToSet: {
|
||||
"unique.playersStolenFrom":
|
||||
event.targetUserId,
|
||||
|
||||
"social.successfullyStolenFrom":
|
||||
event.targetUserId
|
||||
},
|
||||
|
||||
$set: {
|
||||
"special.lastSuccessfulStealTargetId":
|
||||
event.targetUserId
|
||||
}
|
||||
}
|
||||
);
|
||||
break;
|
||||
|
||||
case "stolen_from_me":
|
||||
await stats.updateOne(
|
||||
{ userId, guildId },
|
||||
{
|
||||
userId,
|
||||
guildId
|
||||
},
|
||||
{
|
||||
$inc: {
|
||||
"economy.stolenFromMeTotal":
|
||||
event.amount
|
||||
},
|
||||
|
||||
$addToSet: {
|
||||
"unique.playersStolenBy":
|
||||
event.thiefUserId,
|
||||
|
||||
"social.successfullyStolenBy":
|
||||
event.thiefUserId
|
||||
},
|
||||
|
||||
$set: {
|
||||
"special.lastSuccessfulThiefId":
|
||||
event.thiefUserId
|
||||
}
|
||||
}
|
||||
);
|
||||
break;
|
||||
|
||||
case "vault_steal":
|
||||
await stats.updateOne(
|
||||
{ userId, guildId },
|
||||
@@ -694,6 +939,53 @@ async function trackProfileEvent(
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (
|
||||
[
|
||||
"steal_success",
|
||||
"cookies_given"
|
||||
].includes(
|
||||
event.type
|
||||
)
|
||||
) {
|
||||
await evaluateSocialRelationshipFlags(
|
||||
userId,
|
||||
guildId,
|
||||
event
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
if (
|
||||
[
|
||||
"cookie_gain",
|
||||
"cookie_loss",
|
||||
"game_result",
|
||||
"bankruptcy"
|
||||
].includes(
|
||||
event.type
|
||||
)
|
||||
) {
|
||||
await updateBankruptcyRecovery(
|
||||
userId,
|
||||
guildId
|
||||
);
|
||||
}
|
||||
if (
|
||||
event.type ===
|
||||
"game_result"
|
||||
) {
|
||||
await trackDailyGameState(
|
||||
userId,
|
||||
guildId,
|
||||
event
|
||||
);
|
||||
}
|
||||
await trackDailyNarrativeState(
|
||||
userId,
|
||||
guildId,
|
||||
event
|
||||
);
|
||||
const updatedStats =
|
||||
await getProfileStats(
|
||||
userId,
|
||||
@@ -804,18 +1096,22 @@ async function trackGameStart(
|
||||
|
||||
const set = {};
|
||||
|
||||
const previousBet = Number(
|
||||
event.previousBet ?? 0
|
||||
const previousWager = Number(
|
||||
event.previousWager ??
|
||||
event.previousBet ??
|
||||
0
|
||||
);
|
||||
|
||||
const currentBet = Number(
|
||||
event.bet ?? 0
|
||||
const currentWager = Number(
|
||||
event.wager ??
|
||||
event.bet ??
|
||||
0
|
||||
);
|
||||
|
||||
const chainedAllIn =
|
||||
event.previousAllIn === true &&
|
||||
previousBet > 0 &&
|
||||
currentBet === previousBet;
|
||||
previousWager > 0 &&
|
||||
currentWager === previousWager;
|
||||
|
||||
if (chainedAllIn) {
|
||||
set["special.allInRunItBack"] = 1;
|
||||
@@ -1401,8 +1697,21 @@ async function evaluateBadges(
|
||||
event.type === "game_start" &&
|
||||
event.source === "run_it_back" &&
|
||||
event.previousAllIn === true &&
|
||||
Number(event.previousBet) > 0 &&
|
||||
Number(event.bet) === Number(event.previousBet)
|
||||
Number(
|
||||
event.previousWager ??
|
||||
event.previousBet ??
|
||||
0
|
||||
) > 0 &&
|
||||
Number(
|
||||
event.wager ??
|
||||
event.bet ??
|
||||
0
|
||||
) ===
|
||||
Number(
|
||||
event.previousWager ??
|
||||
event.previousBet ??
|
||||
0
|
||||
)
|
||||
) {
|
||||
await tryClaimBadge(
|
||||
interaction,
|
||||
@@ -1434,15 +1743,14 @@ async function evaluateCollectorBadges(
|
||||
.find({
|
||||
active: {
|
||||
$ne: false
|
||||
},
|
||||
measure: {
|
||||
$ne:
|
||||
"achievementPercentage"
|
||||
}
|
||||
})
|
||||
.toArray()
|
||||
).filter(achievement =>
|
||||
Boolean(achievement.stat)
|
||||
).filter(
|
||||
achievement =>
|
||||
isStatBackfillableAchievement(
|
||||
achievement
|
||||
)
|
||||
);
|
||||
|
||||
if (
|
||||
@@ -2070,8 +2378,9 @@ async function buildAchievementsEmbed(
|
||||
const collectibleDefinitions =
|
||||
definitions.filter(
|
||||
definition =>
|
||||
definition.measure !==
|
||||
"achievementPercentage"
|
||||
isStatBackfillableAchievement(
|
||||
definition
|
||||
)
|
||||
);
|
||||
|
||||
const unlockedCollectible =
|
||||
@@ -3279,6 +3588,371 @@ async function evaluateEventAchievements(
|
||||
);
|
||||
}
|
||||
}
|
||||
async function updateBankruptcyRecovery(
|
||||
userId,
|
||||
guildId
|
||||
) {
|
||||
const {
|
||||
stats
|
||||
} =
|
||||
getProfileCollections();
|
||||
|
||||
const document =
|
||||
await stats.findOne(
|
||||
{
|
||||
userId,
|
||||
guildId
|
||||
},
|
||||
{
|
||||
projection: {
|
||||
"special.bankruptcyCount":
|
||||
1
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
if (
|
||||
Number(
|
||||
document
|
||||
?.special
|
||||
?.bankruptcyCount ?? 0
|
||||
) <= 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const balance =
|
||||
await getCookieBalance(
|
||||
userId
|
||||
);
|
||||
|
||||
|
||||
await stats.updateOne(
|
||||
{
|
||||
userId,
|
||||
guildId
|
||||
},
|
||||
{
|
||||
$max: {
|
||||
"special.bankruptcyRecoveryBest":
|
||||
balance
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
async function trackDailyGameState(
|
||||
userId,
|
||||
guildId,
|
||||
event
|
||||
) {
|
||||
if (
|
||||
event.type !==
|
||||
"game_result"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const game =
|
||||
String(
|
||||
event.game ?? ""
|
||||
).toLowerCase();
|
||||
|
||||
const result =
|
||||
String(
|
||||
event.result ?? ""
|
||||
).toLowerCase();
|
||||
|
||||
if (
|
||||
![
|
||||
"slots",
|
||||
"blackjack",
|
||||
"roulette",
|
||||
"heist"
|
||||
].includes(
|
||||
game
|
||||
)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {
|
||||
stats
|
||||
} =
|
||||
getProfileCollections();
|
||||
|
||||
const {
|
||||
dateKey
|
||||
} =
|
||||
getActivityDateContext();
|
||||
|
||||
const document =
|
||||
await stats.findOne(
|
||||
{
|
||||
userId,
|
||||
guildId
|
||||
},
|
||||
{
|
||||
projection: {
|
||||
daily: 1
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const currentDateKey =
|
||||
document
|
||||
?.daily
|
||||
?.dateKey ?? null;
|
||||
|
||||
if (
|
||||
currentDateKey !==
|
||||
dateKey
|
||||
) {
|
||||
await stats.updateOne(
|
||||
{
|
||||
userId,
|
||||
guildId
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
"daily.dateKey":
|
||||
dateKey,
|
||||
|
||||
"daily.gamesPlayed":
|
||||
[game],
|
||||
|
||||
"daily.gamesWon":
|
||||
result === "win"
|
||||
? [game]
|
||||
: [],
|
||||
|
||||
"daily.gamesLost":
|
||||
result === "loss"
|
||||
? [game]
|
||||
: [],
|
||||
|
||||
"daily.collectedCookies":
|
||||
false,
|
||||
|
||||
"daily.gambledAfterCollect":
|
||||
false,
|
||||
|
||||
"daily.wonAnyGame":
|
||||
result === "win",
|
||||
|
||||
"daily.lostAnyGame":
|
||||
result === "loss",
|
||||
|
||||
"daily.gaveCookies":
|
||||
false,
|
||||
|
||||
"daily.stoleCookies":
|
||||
false
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const addToSet = {
|
||||
"daily.gamesPlayed":
|
||||
game
|
||||
};
|
||||
|
||||
const set = {};
|
||||
|
||||
if (
|
||||
result ===
|
||||
"win"
|
||||
) {
|
||||
addToSet[
|
||||
"daily.gamesWon"
|
||||
] = game;
|
||||
|
||||
set[
|
||||
"daily.wonAnyGame"
|
||||
] = true;
|
||||
}
|
||||
|
||||
if (
|
||||
result ===
|
||||
"loss"
|
||||
) {
|
||||
addToSet[
|
||||
"daily.gamesLost"
|
||||
] = game;
|
||||
|
||||
set[
|
||||
"daily.lostAnyGame"
|
||||
] = true;
|
||||
}
|
||||
|
||||
await stats.updateOne(
|
||||
{
|
||||
userId,
|
||||
guildId
|
||||
},
|
||||
{
|
||||
$addToSet:
|
||||
addToSet,
|
||||
|
||||
...(
|
||||
Object.keys(
|
||||
set
|
||||
).length
|
||||
? {
|
||||
$set:
|
||||
set
|
||||
}
|
||||
: {}
|
||||
)
|
||||
}
|
||||
);
|
||||
}
|
||||
async function trackDailyNarrativeState(
|
||||
userId,
|
||||
guildId,
|
||||
event
|
||||
) {
|
||||
const {
|
||||
stats
|
||||
} =
|
||||
getProfileCollections();
|
||||
|
||||
const {
|
||||
dateKey
|
||||
} =
|
||||
getActivityDateContext();
|
||||
|
||||
const document =
|
||||
await stats.findOne(
|
||||
{
|
||||
userId,
|
||||
guildId
|
||||
},
|
||||
{
|
||||
projection: {
|
||||
daily: 1
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const currentDateKey =
|
||||
document
|
||||
?.daily
|
||||
?.dateKey ?? null;
|
||||
|
||||
if (
|
||||
currentDateKey !==
|
||||
dateKey
|
||||
) {
|
||||
await stats.updateOne(
|
||||
{
|
||||
userId,
|
||||
guildId
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
"daily.dateKey":
|
||||
dateKey,
|
||||
|
||||
"daily.gamesPlayed":
|
||||
[],
|
||||
|
||||
"daily.gamesWon":
|
||||
[],
|
||||
|
||||
"daily.gamesLost":
|
||||
[],
|
||||
|
||||
"daily.collectedCookies":
|
||||
false,
|
||||
|
||||
"daily.gambledAfterCollect":
|
||||
false,
|
||||
|
||||
"daily.wonAnyGame":
|
||||
false,
|
||||
|
||||
"daily.lostAnyGame":
|
||||
false,
|
||||
|
||||
"daily.gaveCookies":
|
||||
false,
|
||||
|
||||
"daily.stoleCookies":
|
||||
false
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const set = {};
|
||||
|
||||
if (
|
||||
event.type ===
|
||||
"cookie_gain"
|
||||
&&
|
||||
event.source ===
|
||||
"collect"
|
||||
) {
|
||||
set[
|
||||
"daily.collectedCookies"
|
||||
] = true;
|
||||
}
|
||||
|
||||
if (
|
||||
event.type ===
|
||||
"cookies_given"
|
||||
) {
|
||||
set[
|
||||
"daily.gaveCookies"
|
||||
] = true;
|
||||
}
|
||||
|
||||
if (
|
||||
event.type ===
|
||||
"steal_success"
|
||||
) {
|
||||
set[
|
||||
"daily.stoleCookies"
|
||||
] = true;
|
||||
}
|
||||
|
||||
if (
|
||||
event.type ===
|
||||
"game_start"
|
||||
&&
|
||||
document
|
||||
?.daily
|
||||
?.collectedCookies === true
|
||||
) {
|
||||
set[
|
||||
"daily.gambledAfterCollect"
|
||||
] = true;
|
||||
}
|
||||
|
||||
if (
|
||||
Object.keys(
|
||||
set
|
||||
).length === 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
await stats.updateOne(
|
||||
{
|
||||
userId,
|
||||
guildId
|
||||
},
|
||||
{
|
||||
$set:
|
||||
set
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
ensureProfileSystem,
|
||||
@@ -3288,6 +3962,7 @@ module.exports = {
|
||||
getProfileCollections,
|
||||
getDefaultStats,
|
||||
getCompositeProgress,
|
||||
updateBankruptcyRecovery,
|
||||
|
||||
readStatValue,
|
||||
readStatPath,
|
||||
@@ -3316,4 +3991,7 @@ module.exports = {
|
||||
evaluateEventCondition,
|
||||
evaluateEventAchievement,
|
||||
evaluateEventAchievements,
|
||||
evaluateSocialRelationshipFlags,
|
||||
trackDailyGameState,
|
||||
trackDailyNarrativeState,
|
||||
};
|
||||
Reference in New Issue
Block a user