diff options
-rw-r--r-- | build/cleaners/skyblock/member.js | 8 | ||||
-rw-r--r-- | build/cleaners/skyblock/stats.js | 34 | ||||
-rw-r--r-- | build/database.js | 30 | ||||
-rw-r--r-- | build/hypixel.js | 1 | ||||
-rw-r--r-- | src/cleaners/skyblock/member.ts | 14 | ||||
-rw-r--r-- | src/cleaners/skyblock/stats.ts | 49 | ||||
-rw-r--r-- | src/database.ts | 37 | ||||
-rw-r--r-- | src/hypixel.ts | 3 |
8 files changed, 100 insertions, 76 deletions
diff --git a/build/cleaners/skyblock/member.js b/build/cleaners/skyblock/member.js index 5c26e40..9869646 100644 --- a/build/cleaners/skyblock/member.js +++ b/build/cleaners/skyblock/member.js @@ -20,16 +20,16 @@ var __importStar = (this && this.__importStar) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.cleanSkyBlockProfileMemberResponse = exports.cleanSkyBlockProfileMemberResponseBasic = void 0; -const stats_1 = require("./stats"); +const collections_1 = require("./collections"); const inventory_1 = require("./inventory"); const fairysouls_1 = require("./fairysouls"); const objectives_1 = require("./objectives"); +const stats_1 = require("./stats"); const minions_1 = require("./minions"); +const slayers_1 = require("./slayers"); +const zones_1 = require("./zones"); const skills_1 = require("./skills"); const cached = __importStar(require("../../hypixelCached")); -const zones_1 = require("./zones"); -const collections_1 = require("./collections"); -const slayers_1 = require("./slayers"); async function cleanSkyBlockProfileMemberResponseBasic(member, included = null) { const player = await cached.fetchPlayer(member.uuid); return { diff --git a/build/cleaners/skyblock/stats.js b/build/cleaners/skyblock/stats.js index 9c6966f..5673d99 100644 --- a/build/cleaners/skyblock/stats.js +++ b/build/cleaners/skyblock/stats.js @@ -1,6 +1,6 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.cleanProfileStats = exports.categorizeStat = void 0; +exports.cleanProfileStats = exports.getStatUnit = exports.statUnits = exports.categorizeStat = void 0; const statCategories = { 'deaths': ['deaths_', 'deaths'], 'kills': ['kills_', 'kills'], @@ -56,17 +56,39 @@ function categorizeStat(statNameRaw) { }; } exports.categorizeStat = categorizeStat; +exports.statUnits = { + time: ['_best_time', '_best_time_2'], + date: ['first_join'], + coins: ['purse'] +}; +function getStatUnit(name) { + for (const [unitName, statMatchers] of Object.entries(exports.statUnits)) { + for (const statMatch of statMatchers) { + let trailingEnd = statMatch[0] === '_'; + let trailingStart = statMatch.substr(-1) === '_'; + if ((trailingStart && name.startsWith(statMatch)) + || (trailingEnd && name.endsWith(statMatch)) + || (name == statMatch)) + return unitName; + } + } +} +exports.getStatUnit = getStatUnit; function cleanProfileStats(data) { - var _a; + var _a, _b; // TODO: add type for statsRaw (probably in hypixelApi.ts since its coming from there) - const stats = {}; + const stats = []; const rawStats = (_a = data === null || data === void 0 ? void 0 : data.stats) !== null && _a !== void 0 ? _a : {}; for (const statNameRaw in rawStats) { const statValue = rawStats[statNameRaw]; let { category: statCategory, name: statName } = categorizeStat(statNameRaw); - if (!stats[statCategory]) - stats[statCategory] = {}; - stats[statCategory][statName || 'total'] = statValue; + stats.push({ + categorizedName: statName !== null && statName !== void 0 ? statName : 'total', + value: statValue, + rawName: statNameRaw, + category: statCategory, + unit: (_b = getStatUnit(statNameRaw)) !== null && _b !== void 0 ? _b : null + }); } return stats; } diff --git a/build/database.js b/build/database.js index 606a456..f397c3e 100644 --- a/build/database.js +++ b/build/database.js @@ -26,12 +26,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); exports.queueUpdateDatabaseMember = exports.updateDatabaseMember = exports.fetchMemberLeaderboardSpots = exports.fetchMemberLeaderboard = exports.fetchAllMemberLeaderboardAttributes = exports.fetchAllLeaderboardsCategorized = void 0; -const constants = __importStar(require("./constants")); -const cached = __importStar(require("./hypixelCached")); +const stats_1 = require("./cleaners/skyblock/stats"); const mongodb_1 = require("mongodb"); -const node_cache_1 = __importDefault(require("node-cache")); +const cached = __importStar(require("./hypixelCached")); +const constants = __importStar(require("./constants")); const util_1 = require("./util"); -const stats_1 = require("./cleaners/skyblock/stats"); +const node_cache_1 = __importDefault(require("node-cache")); const queue_promise_1 = __importDefault(require("queue-promise")); const _1 = require("."); // don't update the user for 3 minutes @@ -46,11 +46,6 @@ const reversedLeaderboards = [ 'first_join', '_best_time', '_best_time_2' ]; -const leaderboardUnits = { - time: ['_best_time', '_best_time_2'], - date: ['first_join'], - coins: ['purse'] -}; let client; let database; let memberLeaderboardsCollection; @@ -137,18 +132,6 @@ function isLeaderboardReversed(name) { } return false; } -function getLeaderboardUnit(name) { - 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) { if (cachedRawLeaderboards.has(name)) return cachedRawLeaderboards.get(name); @@ -165,6 +148,7 @@ async function fetchMemberLeaderboardRaw(name) { cachedRawLeaderboards.set(name, leaderboardRaw); return leaderboardRaw; } +/** Fetch a leaderboard that ranks members, as opposed to profiles */ async function fetchMemberLeaderboard(name) { var _a; const leaderboardRaw = await fetchMemberLeaderboardRaw(name); @@ -181,13 +165,14 @@ async function fetchMemberLeaderboard(name) { const leaderboard = await Promise.all(promises); return { name: name, - unit: (_a = getLeaderboardUnit(name)) !== null && _a !== void 0 ? _a : null, + unit: (_a = stats_1.getStatUnit(name)) !== null && _a !== void 0 ? _a : null, list: leaderboard }; } exports.fetchMemberLeaderboard = fetchMemberLeaderboard; /** Get the leaderboard positions a member is on. This may take a while depending on whether stuff is cached */ async function fetchMemberLeaderboardSpots(player, profile) { + var _a; const fullProfile = await cached.fetchProfile(player, profile); const fullMember = fullProfile.members.find(m => m.username.toLowerCase() === player.toLowerCase() || m.uuid === player); // update the leaderboard positions for the member @@ -201,6 +186,7 @@ async function fetchMemberLeaderboardSpots(player, profile) { name: leaderboardName, positionIndex: leaderboardPositionIndex, value: applicableAttributes[leaderboardName], + unit: (_a = stats_1.getStatUnit(leaderboardName)) !== null && _a !== void 0 ? _a : null }); } return memberLeaderboardSpots; diff --git a/build/hypixel.js b/build/hypixel.js index 9b307b5..175ee79 100644 --- a/build/hypixel.js +++ b/build/hypixel.js @@ -156,6 +156,7 @@ async function fetchMemberProfileUncached(playerUuid, profileUuid) { path: 'skyblock/profile', args: { profile: profileUuid } }, null, { mainMemberUuid: playerUuid }); + // queue updating the leaderboard positions for the member, eventually for (const member of profile.members) database_1.queueUpdateDatabaseMember(member, profile); return profile; diff --git a/src/cleaners/skyblock/member.ts b/src/cleaners/skyblock/member.ts index 424bb9b..fe86e2e 100644 --- a/src/cleaners/skyblock/member.ts +++ b/src/cleaners/skyblock/member.ts @@ -1,18 +1,18 @@ -import { CleanProfileStats, cleanProfileStats } from './stats' +import { cleanCollections, Collection } from './collections' import { cleanInventories, Inventories } from './inventory' import { cleanFairySouls, FairySouls } from './fairysouls' import { cleanObjectives, Objective } from './objectives' +import { CleanFullProfileBasicMembers } from './profile' +import { cleanProfileStats, StatItem } from './stats' import { CleanMinion, cleanMinions } from './minions' +import { cleanSlayers, SlayerData } from './slayers' +import { cleanVisitedZones, Zone } from './zones' import { cleanSkills, Skill } from './skills' import * as cached from '../../hypixelCached' -import { CleanFullProfile, CleanFullProfileBasicMembers } from './profile' import { Included } from '../../hypixel' import { CleanPlayer } from '../player' +import { CleanRank } from '../rank' import { Bank } from './bank' -import { cleanVisitedZones, Zone } from './zones' -import { cleanCollections, Collection } from './collections' -import { cleanSlayers, SlayerData } from './slayers' -import { cleanRank, CleanRank } from '../rank' export interface CleanBasicMember { uuid: string @@ -24,7 +24,7 @@ export interface CleanBasicMember { export interface CleanMember extends CleanBasicMember { purse: number - stats: CleanProfileStats + stats: StatItem[] rawHypixelStats?: { [ key: string ]: number } minions: CleanMinion[] fairy_souls: FairySouls diff --git a/src/cleaners/skyblock/stats.ts b/src/cleaners/skyblock/stats.ts index 7d8da57..efb79bd 100644 --- a/src/cleaners/skyblock/stats.ts +++ b/src/cleaners/skyblock/stats.ts @@ -59,22 +59,53 @@ export function categorizeStat(statNameRaw: string): StatCategory { } } -export interface CleanProfileStats { - [ category: string ]: { - [ stat: string ]: any - total?: any - } +export const statUnits = { + time: ['_best_time', '_best_time_2'], + date: ['first_join'], + coins: ['purse'] +} + +export interface StatItem { + rawName: string + value: number + categorizedName: string + category: string + unit: string +} + +export function getStatUnit(name: string): string { + for (const [ unitName, statMatchers ] of Object.entries(statUnits)) { + for (const statMatch of statMatchers) { + let trailingEnd = statMatch[0] === '_' + let trailingStart = statMatch.substr(-1) === '_' + if ( + (trailingStart && name.startsWith(statMatch)) + || (trailingEnd && name.endsWith(statMatch)) + || (name == statMatch) + ) + return unitName + } + } } -export function cleanProfileStats(data: any): CleanProfileStats { + +export function cleanProfileStats(data: any): StatItem[] { // TODO: add type for statsRaw (probably in hypixelApi.ts since its coming from there) - const stats: CleanProfileStats = {} + const stats: StatItem[] = [] + const rawStats = data?.stats ?? {} + for (const statNameRaw in rawStats) { const statValue = rawStats[statNameRaw] let { category: statCategory, name: statName } = categorizeStat(statNameRaw) - if (!stats[statCategory]) stats[statCategory] = {} - stats[statCategory][statName || 'total'] = statValue + stats.push({ + categorizedName: statName ?? 'total', + value: statValue, + rawName: statNameRaw, + category: statCategory, + unit: getStatUnit(statNameRaw) ?? null + }) } + return stats } diff --git a/src/database.ts b/src/database.ts index 6e5a41b..cfa95ac 100644 --- a/src/database.ts +++ b/src/database.ts @@ -2,15 +2,15 @@ * Store data about members for leaderboards */ -import * as constants from './constants' -import * as cached from './hypixelCached' -import { Collection, Db, MongoClient } from 'mongodb' -import NodeCache from 'node-cache' +import { categorizeStat, getStatUnit } from './cleaners/skyblock/stats' +import { CleanFullProfile } from './cleaners/skyblock/profile' import { CleanMember } from './cleaners/skyblock/member' +import { Collection, Db, MongoClient } from 'mongodb' import { CleanPlayer } from './cleaners/player' +import * as cached from './hypixelCached' +import * as constants from './constants' import { shuffle, sleep } from './util' -import { CleanFullProfile } from './cleaners/skyblock/profile' -import { categorizeStat } from './cleaners/skyblock/stats' +import NodeCache from 'node-cache' import Queue from 'queue-promise' import { debug } from '.' @@ -40,11 +40,6 @@ const reversedLeaderboards = [ 'first_join', '_best_time', '_best_time_2' ] -const leaderboardUnits = { - time: ['_best_time', '_best_time_2'], - date: ['first_join'], - coins: ['purse'] -} let client: MongoClient let database: Db @@ -154,21 +149,6 @@ function isLeaderboardReversed(name: string): boolean { 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) @@ -195,6 +175,7 @@ interface Leaderboard { list: LeaderboardItem[] } +/** Fetch a leaderboard that ranks members, as opposed to profiles */ export async function fetchMemberLeaderboard(name: string): Promise<Leaderboard> { const leaderboardRaw = await fetchMemberLeaderboardRaw(name) const fetchLeaderboardPlayer = async(item: DatabaseLeaderboardItem): Promise<LeaderboardItem> => { @@ -210,7 +191,7 @@ export async function fetchMemberLeaderboard(name: string): Promise<Leaderboard> const leaderboard = await Promise.all(promises) return { name: name, - unit: getLeaderboardUnit(name) ?? null, + unit: getStatUnit(name) ?? null, list: leaderboard } } @@ -234,7 +215,7 @@ export async function fetchMemberLeaderboardSpots(player: string, profile: strin name: leaderboardName, positionIndex: leaderboardPositionIndex, value: applicableAttributes[leaderboardName], - + unit: getStatUnit(leaderboardName) ?? null }) } diff --git a/src/hypixel.ts b/src/hypixel.ts index 979b57f..723feea 100644 --- a/src/hypixel.ts +++ b/src/hypixel.ts @@ -183,8 +183,11 @@ export async function fetchMemberProfileUncached(playerUuid: string, profileUuid null, { mainMemberUuid: playerUuid } ) + + // queue updating the leaderboard positions for the member, eventually for (const member of profile.members) queueUpdateDatabaseMember(member, profile) + return profile } |