aboutsummaryrefslogtreecommitdiff
path: root/src/database.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/database.ts')
-rw-r--r--src/database.ts70
1 files changed, 55 insertions, 15 deletions
diff --git a/src/database.ts b/src/database.ts
index 29760ef..466e2f1 100644
--- a/src/database.ts
+++ b/src/database.ts
@@ -12,6 +12,7 @@ import { shuffle, sleep } from './util'
import { CleanFullProfile } from './cleaners/skyblock/profile'
import { categorizeStat } from './cleaners/skyblock/stats'
import Queue from 'queue-promise'
+import { debug } from '.'
// don't update the user for 3 minutes
const recentlyUpdated = new NodeCache({
@@ -34,10 +35,14 @@ interface LeaderboardItem {
const cachedRawLeaderboards: Map<string, DatabaseLeaderboardItem[]> = new Map()
const leaderboardMax = 100
-const reversedStats = [
+const reversedLeaderboards = [
'first_join',
'_best_time', '_best_time_2'
]
+const leaderboardUnits = {
+ time: ['_best_time', '_best_time_2'],
+ date: ['first_join']
+}
let client: MongoClient
let database: Db
@@ -131,19 +136,34 @@ export async function fetchAllMemberLeaderboardAttributes(): Promise<string[]> {
}
function isLeaderboardReversed(name: string): boolean {
- for (const statMatch of reversedStats) {
- let trailingEnd = statMatch[0] === '_'
- let trailingStart = statMatch.substr(-1) === '_'
+ for (const leaderboardMatch of reversedLeaderboards) {
+ let trailingEnd = leaderboardMatch[0] === '_'
+ let trailingStart = leaderboardMatch.substr(-1) === '_'
if (
- (trailingStart && name.startsWith(statMatch))
- || (trailingEnd && name.endsWith(statMatch))
- || (name == statMatch)
+ (trailingStart && name.startsWith(leaderboardMatch))
+ || (trailingEnd && name.endsWith(leaderboardMatch))
+ || (name == leaderboardMatch)
)
return true
}
return false
}
+function getLeaderboardUnit(name: string): string {
+ for (const [ unitName, leaderboardMatchers ] of Object.entries(leaderboardUnits)) {
+ for (const leaderboardMatch of leaderboardMatchers) {
+ let trailingEnd = leaderboardMatch[0] === '_'
+ let trailingStart = leaderboardMatch.substr(-1) === '_'
+ if (
+ (trailingStart && name.startsWith(leaderboardMatch))
+ || (trailingEnd && name.endsWith(leaderboardMatch))
+ || (name == leaderboardMatch)
+ )
+ return unitName
+ }
+ }
+}
+
async function fetchMemberLeaderboardRaw(name: string): Promise<DatabaseLeaderboardItem[]> {
if (cachedRawLeaderboards.has(name))
return cachedRawLeaderboards.get(name)
@@ -163,7 +183,7 @@ export async function fetchMemberLeaderboard(name: string) {
const leaderboardRaw = await fetchMemberLeaderboardRaw(name)
const fetchLeaderboardPlayer = async(item: DatabaseLeaderboardItem): Promise<LeaderboardItem> => {
return {
- player: await cached.fetchPlayer(item.uuid),
+ player: await cached.fetchBasicPlayer(item.uuid),
value: item.stats[name]
}
}
@@ -172,7 +192,11 @@ export async function fetchMemberLeaderboard(name: string) {
promises.push(fetchLeaderboardPlayer(item))
}
const leaderboard = await Promise.all(promises)
- return leaderboard
+ return {
+ name: name,
+ unit: getLeaderboardUnit(name) ?? null,
+ list: leaderboard
+ }
}
async function getMemberLeaderboardRequirement(name: string): Promise<number> {
@@ -192,14 +216,12 @@ async function getApplicableAttributes(member): Promise<{ [key: string]: number
const requirement = await getMemberLeaderboardRequirement(attributeName)
if (!requirement || attributeValue > requirement)
applicableAttributes[attributeName] = attributeValue
- console.log(attributeName)
}
return applicableAttributes
}
/** Update the member's leaderboard data on the server if applicable */
export async function updateDatabaseMember(member: CleanMember, profile: CleanFullProfile) {
- console.log('updating', member.uuid)
if (!client) return // the db client hasn't been initialized
// the member's been updated too recently, just return
if (recentlyUpdated.get(profile.uuid + member.uuid))
@@ -243,7 +265,6 @@ export async function updateDatabaseMember(member: CleanMember, profile: CleanFu
.slice(0, 100)
cachedRawLeaderboards.set(attributeName, newRawLeaderboard)
}
- console.log('updated', member.uuid)
}
const queue = new Queue({
@@ -265,7 +286,7 @@ async function removeBadMemberLeaderboardAttributes() {
// shuffle so if the application is restarting many times itll still be useful
for (const leaderboard of shuffle(leaderboards)) {
// wait 10 seconds so it doesnt use as much ram
- await sleep(100000)
+ await sleep(10 * 1000)
const unsetValue = {}
unsetValue[leaderboard] = ''
@@ -283,7 +304,26 @@ async function removeBadMemberLeaderboardAttributes() {
}
}
+/** Fetch all the leaderboards, used for caching. Don't call this often! */
+async function fetchAllLeaderboards() {
+ const leaderboards = await fetchAllMemberLeaderboardAttributes()
+ // shuffle so if the application is restarting many times itll still be useful
+ if (debug) console.log('Caching leaderboards!')
+ for (const leaderboard of shuffle(leaderboards)) {
+ // wait 2 seconds so it doesnt use as much ram
+ await sleep(2 * 1000)
+
+ await fetchMemberLeaderboard(leaderboard)
+ }
+ if (debug) console.log('Finished caching leaderboards!')
+}
-connect()
- .then(removeBadMemberLeaderboardAttributes)
+connect().then(() => {
+ // when it connects, cache the leaderboards and remove bad members
+ removeBadMemberLeaderboardAttributes()
+ // cache leaderboards on startup so its faster later on
+ fetchAllLeaderboards()
+ // cache leaderboard players again every hour
+ setInterval(fetchAllLeaderboards, 4 * 60 * 60 * 1000)
+})