added achievements for new steal logic
This commit is contained in:
@@ -15,7 +15,9 @@ const {
|
|||||||
} = require("../../utils/cookieEconomy");
|
} = require("../../utils/cookieEconomy");
|
||||||
|
|
||||||
const {
|
const {
|
||||||
trackProfileEvent
|
trackProfileEvent,
|
||||||
|
getProfileCollections,
|
||||||
|
getDefaultStats
|
||||||
} = require("../../utils/profileSystem");
|
} = require("../../utils/profileSystem");
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -235,12 +237,8 @@ async function steal(interaction) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const { cookies } = getCookieCommandCollections();
|
||||||
cookies,
|
const { stats: statsProfile } = getProfileCollections();
|
||||||
statsProfile
|
|
||||||
} = getCookieCommandCollections({
|
|
||||||
requireStatsProfile: true
|
|
||||||
});
|
|
||||||
|
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
const stealWindowCutoff = new Date(
|
const stealWindowCutoff = new Date(
|
||||||
@@ -398,6 +396,27 @@ async function steal(interaction) {
|
|||||||
)
|
)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ensure the victim has a complete profile document before heat state is
|
||||||
|
* written. This avoids creating a sparse stats_profiles document when a
|
||||||
|
* player is targeted before any other profile event has initialized them.
|
||||||
|
*/
|
||||||
|
await statsProfile.updateOne(
|
||||||
|
{
|
||||||
|
userId: target.id,
|
||||||
|
guildId: interaction.guildId
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$setOnInsert: getDefaultStats(
|
||||||
|
target.id,
|
||||||
|
interaction.guildId
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
upsert: true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rolling heat protection.
|
* Rolling heat protection.
|
||||||
*
|
*
|
||||||
@@ -407,7 +426,8 @@ async function steal(interaction) {
|
|||||||
*/
|
*/
|
||||||
await statsProfile.updateOne(
|
await statsProfile.updateOne(
|
||||||
{
|
{
|
||||||
userId: target.id
|
userId: target.id,
|
||||||
|
guildId: interaction.guildId
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$pull: {
|
$pull: {
|
||||||
@@ -428,7 +448,8 @@ async function steal(interaction) {
|
|||||||
*/
|
*/
|
||||||
const heatUpdateResult = await statsProfile.findOneAndUpdate(
|
const heatUpdateResult = await statsProfile.findOneAndUpdate(
|
||||||
{
|
{
|
||||||
userId: target.id
|
userId: target.id,
|
||||||
|
guildId: interaction.guildId
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
$push: {
|
$push: {
|
||||||
@@ -439,7 +460,6 @@ async function steal(interaction) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
upsert: true,
|
|
||||||
returnDocument: "before"
|
returnDocument: "before"
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -451,6 +471,30 @@ async function steal(interaction) {
|
|||||||
const activeAttempts =
|
const activeAttempts =
|
||||||
targetProfile?.stealProtection?.attempts ?? [];
|
targetProfile?.stealProtection?.attempts ?? [];
|
||||||
|
|
||||||
|
const uniqueAttackers = new Set([
|
||||||
|
...activeAttempts.map(
|
||||||
|
attempt => attempt.userId
|
||||||
|
),
|
||||||
|
user.id
|
||||||
|
]).size;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Achievement/event tracking for the victim. The current attempt is
|
||||||
|
* included, while repeated attempts by the same user only count once
|
||||||
|
* toward the unique-attacker total.
|
||||||
|
*/
|
||||||
|
await trackProfileEvent(
|
||||||
|
interaction,
|
||||||
|
target.id,
|
||||||
|
{
|
||||||
|
type: "steal_targeted",
|
||||||
|
attackerUserId: user.id,
|
||||||
|
uniqueAttackers,
|
||||||
|
attemptsInWindow: activeAttempts.length + 1,
|
||||||
|
windowSeconds: heatWindowMs / 1000
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const heat = activeAttempts.reduce(
|
const heat = activeAttempts.reduce(
|
||||||
(total, attempt) => {
|
(total, attempt) => {
|
||||||
const timestamp = new Date(
|
const timestamp = new Date(
|
||||||
@@ -1111,9 +1155,7 @@ async function leaderboard(interaction) {
|
|||||||
* collection names for the two collections used by this command.
|
* collection names for the two collections used by this command.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function getCookieCommandCollections({
|
function getCookieCommandCollections() {
|
||||||
requireStatsProfile = false
|
|
||||||
} = {}) {
|
|
||||||
const collections = getCollections();
|
const collections = getCollections();
|
||||||
const database =
|
const database =
|
||||||
collections.db ??
|
collections.db ??
|
||||||
@@ -1125,28 +1167,13 @@ function getCookieCommandCollections({
|
|||||||
collections.items_cookies ??
|
collections.items_cookies ??
|
||||||
database?.collection?.("items_cookies");
|
database?.collection?.("items_cookies");
|
||||||
|
|
||||||
const statsProfile =
|
|
||||||
collections.statsProfile ??
|
|
||||||
collections.statsProfiles ??
|
|
||||||
collections.stats_profile ??
|
|
||||||
database?.collection?.("stats_profile");
|
|
||||||
|
|
||||||
if (!cookies) {
|
if (!cookies) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
"getCollections() must expose the items_cookies collection as cookies/itemsCookies/items_cookies, or expose a db handle."
|
"getCollections() must expose the items_cookies collection as cookies/itemsCookies/items_cookies, or expose a db handle."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requireStatsProfile && !statsProfile) {
|
return { cookies };
|
||||||
throw new Error(
|
|
||||||
"getCollections() must expose the stats_profile collection as statsProfile/statsProfiles/stats_profile, or expose a db handle."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
cookies,
|
|
||||||
statsProfile
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+17
-2
@@ -636,7 +636,7 @@ function getDefaultStats(userId, guildId) {
|
|||||||
allInRunItBack: 0,
|
allInRunItBack: 0,
|
||||||
bankruptcyCount: 0,
|
bankruptcyCount: 0,
|
||||||
bankruptcyRecoveryBest: 0,
|
bankruptcyRecoveryBest: 0,
|
||||||
|
maxUniqueStealAttackers: 0,
|
||||||
etTuCrumb: 0,
|
etTuCrumb: 0,
|
||||||
noHardFeelings: 0,
|
noHardFeelings: 0,
|
||||||
cookieLaundering: 0
|
cookieLaundering: 0
|
||||||
@@ -846,7 +846,22 @@ async function trackProfileEvent(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case "steal_targeted":
|
||||||
|
await stats.updateOne(
|
||||||
|
{
|
||||||
|
userId,
|
||||||
|
guildId
|
||||||
|
},
|
||||||
|
{
|
||||||
|
$max: {
|
||||||
|
"special.maxUniqueStealAttackers":
|
||||||
|
Number(
|
||||||
|
event.uniqueAttackers ?? 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
break;
|
||||||
case "steal_success":
|
case "steal_success":
|
||||||
await stats.updateOne(
|
await stats.updateOne(
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user