diff options
Diffstat (limited to 'build/database.js')
-rw-r--r-- | build/database.js | 64 |
1 files changed, 47 insertions, 17 deletions
diff --git a/build/database.js b/build/database.js index 9cb62c6..1edb990 100644 --- a/build/database.js +++ b/build/database.js @@ -37,6 +37,7 @@ const recentlyUpdated = new node_cache_1.default({ checkperiod: 60, useClones: false, }); +const cachedRawLeaderboards = new Map(); const cachedLeaderboards = new Map(); const leaderboardMax = 100; let client; @@ -85,15 +86,22 @@ async function fetchAllMemberLeaderboardAttributes() { 'visited_zones', ]; } -async function fetchMemberLeaderboard(name) { - if (cachedLeaderboards.has(name)) - return cachedLeaderboards.get(name); +async function fetchMemberLeaderboardRaw(name) { + if (cachedRawLeaderboards.has(name)) + return cachedRawLeaderboards.get(name); // typescript forces us to make a new variable and set it this way because it gives an error otherwise const query = {}; query[`stats.${name}`] = { '$exists': true }; const sortQuery = {}; sortQuery[`stats.${name}`] = -1; const leaderboardRaw = await memberLeaderboardsCollection.find(query).sort(sortQuery).limit(leaderboardMax).toArray(); + cachedRawLeaderboards.set(name, leaderboardRaw); + return leaderboardRaw; +} +async function fetchMemberLeaderboard(name) { + if (cachedLeaderboards.has(name)) + return cachedLeaderboards.get(name); + const leaderboardRaw = await fetchMemberLeaderboardRaw(name); const fetchLeaderboardPlayer = async (item) => { return { player: await cached.fetchPlayer(item.uuid), @@ -110,45 +118,67 @@ async function fetchMemberLeaderboard(name) { } exports.fetchMemberLeaderboard = fetchMemberLeaderboard; async function getMemberLeaderboardRequirement(name) { - const leaderboard = await fetchMemberLeaderboard(name); + const leaderboard = await fetchMemberLeaderboardRaw(name); // if there's more than 100 items, return the 100th. if there's less, return null if (leaderboard.length >= leaderboardMax) - return leaderboard[leaderboardMax - 1].value; + return leaderboard[leaderboardMax - 1].stats[name]; else return null; } /** Get the attributes for the member, but only ones that would put them on the top 100 for leaderboards */ async function getApplicableAttributes(member) { const leaderboardAttributes = getMemberLeaderboardAttributes(member); - const applicableAttributes = []; + const applicableAttributes = {}; for (const [attributeName, attributeValue] of Object.entries(leaderboardAttributes)) { const requirement = await getMemberLeaderboardRequirement(attributeName); if (!requirement || attributeValue > requirement) applicableAttributes[attributeName] = attributeValue; } + return applicableAttributes; } /** Update the member's leaderboard data on the server if applicable */ -async function updateDatabaseMember(member) { +async function updateDatabaseMember(member, profile) { if (!client) return; // the db client hasn't been initialized // the member's been updated too recently, just return - if (recentlyUpdated.get(member.uuid)) + if (recentlyUpdated.get(profile.uuid + member.uuid)) return; // store the member in recentlyUpdated so it cant update for 3 more minutes - recentlyUpdated.set(member.uuid, true); + recentlyUpdated.set(profile.uuid + member.uuid, true); await constants.addStats(Object.keys(member.rawHypixelStats)); await constants.addCollections(member.collections.map(value => value.name)); const leaderboardAttributes = await getApplicableAttributes(member); - await memberLeaderboardsCollection.updateOne({ - uuid: member.uuid - }, { + await memberLeaderboardsCollection.updateOne({ uuid: member.uuid }, { '$set': { - 'stats': leaderboardAttributes, - 'last_updated': new Date() + stats: leaderboardAttributes, + last_updated: new Date() } - }, { - upsert: true - }); + }, { upsert: true }); + for (const [attributeName, attributeValue] of Object.entries(leaderboardAttributes)) { + const existingLeaderboard = await fetchMemberLeaderboard(attributeName); + const existingRawLeaderboard = await fetchMemberLeaderboardRaw(attributeName); + const newLeaderboard = existingLeaderboard + // remove the player from the leaderboard, if they're there + .filter(value => value.player.uuid !== member.uuid) + .concat([{ + player: await cached.fetchPlayer(member.uuid), + value: attributeValue + }]) + .sort((a, b) => b.value - a.value) + .slice(0, 100); + const newRawLeaderboard = existingRawLeaderboard + // remove the player from the leaderboard, if they're there + .filter(value => value.uuid !== member.uuid) + .concat([{ + last_updated: new Date(), + stats: leaderboardAttributes, + uuid: member.uuid + }]) + .sort((a, b) => b.stats[attributeName] - a.stats[attributeName]) + .slice(0, 100); + cachedLeaderboards.set(attributeName, newLeaderboard); + cachedRawLeaderboards.set(attributeName, newRawLeaderboard); + } } exports.updateDatabaseMember = updateDatabaseMember; /** |