diff options
-rw-r--r-- | src/cleaners/achievements.ts | 48 | ||||
-rw-r--r-- | src/cleaners/player.ts | 2 | ||||
-rw-r--r-- | src/cleaners/skyblock/stats.ts | 1 | ||||
-rw-r--r-- | src/cleaners/skyblock/zones.ts | 1 | ||||
-rw-r--r-- | src/hypixel.ts | 11 | ||||
-rw-r--r-- | src/hypixelCached.ts | 14 |
6 files changed, 62 insertions, 15 deletions
diff --git a/src/cleaners/achievements.ts b/src/cleaners/achievements.ts index 9e4c7ae..d556f74 100644 --- a/src/cleaners/achievements.ts +++ b/src/cleaners/achievements.ts @@ -1,18 +1,50 @@ import typedHypixelApi from 'typed-hypixel-api' +import { fetchAchievements } from '../hypixelCached.js' + +interface Achievement { + id: string + name: string + value: number | boolean + description: string +} export interface Achievements { - skyblock: Record<string, number> + skyblock: Achievement[] } -export function cleanPlayerAchievements(data: typedHypixelApi.PlayerDataResponse['player']): Achievements { - const achievements: Achievements = { - skyblock: {} +export async function cleanPlayerAchievements(data: typedHypixelApi.PlayerDataResponse['player']): Promise<Achievements> { + const playerAchievements: Achievements = { + skyblock: [] } - for (const [id, value] of Object.entries(data.achievements)) { - if (id.startsWith('skyblock_')) - achievements.skyblock[id.substring(9)] = value + const gameAchievements: typedHypixelApi.AchievementsResponse['achievements'] = await fetchAchievements() + + for (const [gameId, achievementsData] of Object.entries(gameAchievements)) { + if (gameId !== 'skyblock') continue + + let tieredAchievements: Achievement[] = [] + for (const [achievementId, achievementData] of Object.entries(achievementsData.tiered)) { + const value = data.achievements[`skyblock_${achievementId}`] ?? 0 + tieredAchievements.push({ + id: achievementId.toLowerCase(), + name: achievementData.name, + value, + description: achievementData.description.replace(/%s/g, value.toString()) + }) + } + + let oneTimeAchievements: Achievement[] = [] + for (const [achievementId, achievementData] of Object.entries(achievementsData.one_time)) { + oneTimeAchievements.push({ + id: achievementId.toLowerCase(), + name: achievementData.name, + value: data.achievementsOneTime.includes(`skyblock_${achievementId}`), + description: achievementData.description + }) + } + + playerAchievements[gameId] = [...tieredAchievements, ...oneTimeAchievements] } - return achievements + return playerAchievements } diff --git a/src/cleaners/player.ts b/src/cleaners/player.ts index 8facdad..5de65de 100644 --- a/src/cleaners/player.ts +++ b/src/cleaners/player.ts @@ -44,6 +44,6 @@ export async function cleanPlayerResponse(data: typedHypixelApi.PlayerDataRespon socials: cleanSocialMedia(data), profiles: cleanPlayerSkyblockProfiles(data.stats?.SkyBlock?.profiles), claimed: cleanPlayerSkyblockClaimed(data), - achievements: cleanPlayerAchievements(data) + achievements: await cleanPlayerAchievements(data) } } diff --git a/src/cleaners/skyblock/stats.ts b/src/cleaners/skyblock/stats.ts index fc55577..8105f26 100644 --- a/src/cleaners/skyblock/stats.ts +++ b/src/cleaners/skyblock/stats.ts @@ -102,7 +102,6 @@ export function getStatUnit(name: string): string | null { export function cleanProfileStats(data: typedHypixelApi.SkyBlockProfileMember): StatItem[] { - // TODO: add type for statsRaw (probably in hypixelApi.ts since its coming from there) const stats: StatItem[] = [] const rawStats = data?.stats ?? {} diff --git a/src/cleaners/skyblock/zones.ts b/src/cleaners/skyblock/zones.ts index 92f4e81..6d75cec 100644 --- a/src/cleaners/skyblock/zones.ts +++ b/src/cleaners/skyblock/zones.ts @@ -17,7 +17,6 @@ export async function cleanVisitedZones(data: typedHypixelApi.SkyBlockProfileMem constants.addZones(rawZones) - // TODO: store all the zones that exist in SkyBlock, add add those to the array with visited being false const zones: Zone[] = [] const knownZones = await constants.fetchZones() diff --git a/src/hypixel.ts b/src/hypixel.ts index e0575dd..ba0b83c 100644 --- a/src/hypixel.ts +++ b/src/hypixel.ts @@ -53,13 +53,18 @@ export interface ApiOptions { basic?: boolean } -/** Sends an API request to Hypixel and cleans it up. */ -export async function sendCleanApiRequest<P extends keyof typeof cleanResponseFunctions>(path: P, args: Omit<typedHypixelApi.Requests[P]['options'], 'key'>, options?: ApiOptions): Promise<Awaited<ReturnType<typeof cleanResponseFunctions[P]>>> { +/** Sends an API request to Hypixel and returns the response. */ +export async function sendUncleanApiRequest<P extends keyof typedHypixelApi.Requests>(path: P, args: Omit<typedHypixelApi.Requests[P]['options'], 'key'>): Promise<typedHypixelApi.Requests[P]['response']['data']> { const key = await chooseApiKey() const data = await sendApiRequest(path, { key, ...args }) if (!data) throw new Error(`No data returned from ${path}`) - // clean the response + return data +} + +/** Sends an API request to Hypixel and cleans it up. */ +export async function sendCleanApiRequest<P extends keyof typeof cleanResponseFunctions>(path: P, args: Omit<typedHypixelApi.Requests[P]['options'], 'key'>, options?: ApiOptions): Promise<Awaited<ReturnType<typeof cleanResponseFunctions[P]>>> { + const data = await sendUncleanApiRequest(path, args) return await cleanResponse(path, data, options ?? {}) } diff --git a/src/hypixelCached.ts b/src/hypixelCached.ts index 164cf63..cf055da 100644 --- a/src/hypixelCached.ts +++ b/src/hypixelCached.ts @@ -3,7 +3,7 @@ */ import { CleanProfile, CleanFullProfile, CleanBasicProfile } from './cleaners/skyblock/profile.js' -import { isUuid, sleep, undashUuid } from './util.js' +import { isUuid, sleep, undashUuid, withCache } from './util.js' import { CleanFullPlayer, CleanPlayer } from './cleaners/player.js' import * as hypixel from './hypixel.js' import * as mojang from './mojang.js' @@ -11,6 +11,7 @@ import NodeCache from 'node-cache' import { debug } from './index.js' import LRUCache from 'lru-cache' import { CleanBasicMember } from './cleaners/skyblock/member.js' +import { sendUncleanApiRequest } from './hypixel.js' // cache usernames for 30 minutes @@ -442,3 +443,14 @@ export async function fetchProfileName(user: string, profile: string): Promise<s profileNameCache.set(`${playerUuid}.${profileUuid}`, profileName) return profileName } + +export async function fetchAchievements() { + return await withCache( + 'achievements', + 30 * 60 * 1000, + async () => { + return (await sendUncleanApiRequest('resources/achievements', {})).achievements + } + ) +} + |