aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/database.ts67
-rw-r--r--src/index.ts2
2 files changed, 55 insertions, 14 deletions
diff --git a/src/database.ts b/src/database.ts
index 6e37d5f..93e2a40 100644
--- a/src/database.ts
+++ b/src/database.ts
@@ -9,7 +9,7 @@ import { Collection, Db, MongoClient, WithId } from 'mongodb'
import { CleanMember } from './cleaners/skyblock/member.js'
import * as cached from './hypixelCached.js'
import * as constants from './constants.js'
-import { letterFromColorCode, minecraftColorCodes, shuffle, sleep } from './util.js'
+import { isUuid, letterFromColorCode, minecraftColorCodes, shuffle, sleep } from './util.js'
import * as discord from './discord.js'
import NodeCache from 'node-cache'
import { v4 as uuid4 } from 'uuid'
@@ -431,6 +431,7 @@ async function fetchMemberLeaderboardRaw(name: string): Promise<memberRawLeaderb
fetchingRawLeaderboardNames.add(name)
+ if (debug) console.debug(`Fetching leaderboard ${name} from database...`)
try {
const leaderboardRaw: memberRawLeaderboardItem[] = (await memberLeaderboardsCollection
.find(query)
@@ -452,6 +453,7 @@ async function fetchMemberLeaderboardRaw(name: string): Promise<memberRawLeaderb
} catch (e) {
// if it fails while fetching, remove it from fetchingRawLeaderboardNames
fetchingRawLeaderboardNames.delete(name)
+ if (debug) console.debug(`Failed getting leaderboard ${name}!`)
throw e
}
}
@@ -611,22 +613,52 @@ interface LeaderboardSpot {
}
/** Get the leaderboard positions a member is on. This may take a while depending on whether stuff is cached */
-export async function fetchMemberLeaderboardSpots(player: string, profile: string): Promise<LeaderboardSpot[] | null> {
- const fullProfile = await cached.fetchProfile(player, profile)
- if (!fullProfile) return null
- const fullMember = fullProfile.members.find(m => m.username.toLowerCase() === player.toLowerCase() || m.uuid === player)
- if (!fullMember) return null
+export async function fetchMemberLeaderboardSpots(player: string, profile: string, lazy = false): Promise<LeaderboardSpot[] | null> {
+ let playerUuid: string | undefined
+ let profileUuid: string | undefined
+ if (isUuid(player)) playerUuid = player
+ if (isUuid(profile)) profileUuid = profile
+
+ let fullProfile: CleanFullProfile
+ let fullMember: CleanMember
+ if (!(lazy && profileUuid)) {
+ const fullProfileNullable = await cached.fetchProfile(player, profile)
+ if (!fullProfileNullable) return null
+ fullProfile = fullProfileNullable
+ profileUuid = fullProfile.uuid
+
+ if (!(lazy && playerUuid)) {
+ const fullMemberNullable = fullProfile.members.find(m => m.username.toLowerCase() === player.toLowerCase() || m.uuid === player)
+ if (!fullMemberNullable) return null
+ fullMember = fullMemberNullable
+ playerUuid = fullMember.uuid
+ }
+ }
- // update the leaderboard positions for the member
- await updateDatabaseMember(fullMember, fullProfile)
+ let applicableAttributes: StringNumber = {}
+ if (!lazy) {
+ // update the leaderboard positions for the member
+ await updateDatabaseMember(fullMember!, fullProfile!)
- const applicableAttributes = await getApplicableMemberLeaderboardAttributes(fullMember)
+ applicableAttributes = await getApplicableMemberLeaderboardAttributes(fullMember!)
+ } else {
+ const memberDoc = await memberLeaderboardsCollection.findOne({
+ uuid: playerUuid,
+ profile: profileUuid
+ })
+ applicableAttributes = memberDoc?.stats ?? {}
+ }
const memberLeaderboardSpots: LeaderboardSpot[] = []
+ let leaderboardPromises: Promise<memberRawLeaderboardItem[]>[] = []
+ for (const leaderboardName in applicableAttributes)
+ leaderboardPromises.push(fetchMemberLeaderboardRaw(leaderboardName))
for (const leaderboardName in applicableAttributes) {
- const leaderboard = await fetchMemberLeaderboardRaw(leaderboardName)
- const leaderboardPositionIndex = leaderboard.findIndex(i => i.uuid === fullMember.uuid && i.profile === fullProfile.uuid)
+ const leaderboard = await leaderboardPromises.shift()!
+ const leaderboardPositionIndexByValue = leaderboard.findIndex(i => i.value === applicableAttributes[leaderboardName])
+ const leaderboardPositionIndexByUser = leaderboard.findIndex(i => i.uuid === playerUuid && i.profile === profileUuid)
+ const leaderboardPositionIndex = leaderboardPositionIndexByValue !== -1 ? leaderboardPositionIndexByValue : leaderboardPositionIndexByUser
memberLeaderboardSpots.push({
name: leaderboardName,
@@ -975,8 +1007,17 @@ async function fetchAllLeaderboards(): Promise<void> {
if (debug) console.debug('Caching raw leaderboards!')
- for (const leaderboard of shuffle(leaderboards))
- await fetchMemberLeaderboardRaw(leaderboard)
+ let concurrentlyFetching = 0
+
+ for (const leaderboard of shuffle(leaderboards)) {
+ let fetchLeaderboardPromise = fetchMemberLeaderboardRaw(leaderboard)
+ concurrentlyFetching++
+ if (concurrentlyFetching > 10) {
+ await fetchLeaderboardPromise
+ concurrentlyFetching--
+ } else
+ fetchLeaderboardPromise.then(() => concurrentlyFetching--)
+ }
finishedCachingRawLeaderboards = true
}
diff --git a/src/index.ts b/src/index.ts
index 34f941b..1d75830 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -101,7 +101,7 @@ app.get('/player/:user/:profile', async (req, res) => {
app.get('/player/:user/:profile/leaderboards', async (req, res) => {
try {
res.json(
- await fetchMemberLeaderboardSpots(req.params.user, req.params.profile)
+ await fetchMemberLeaderboardSpots(req.params.user, req.params.profile, req.query.lazy === 'true')
)
} catch (err) {
console.error(err)