1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
import typedHypixelApi from 'typed-hypixel-api'
import { fetchAchievements } from '../hypixelCached.js'
interface TieredAchievement {
id: string
name: string
tier: number
amount: number
/**
* The amount that has to be gotten to get to the next tier. If this is
* null, that means the player is at the max tier.
*/
next: number | null
description: string
}
interface ChallengeAchievement {
id: string
name: string
unlocked: boolean
description: string
}
export interface Achievements {
tiered: TieredAchievement[]
challenge: ChallengeAchievement[]
}
export async function cleanPlayerAchievements(data: typedHypixelApi.PlayerDataResponse['player']): Promise<Achievements> {
const gameAchievements: typedHypixelApi.AchievementsResponse['achievements'] = await fetchAchievements()
for (const [gameId, achievementsData] of Object.entries(gameAchievements)) {
if (gameId !== 'skyblock') continue
let tieredAchievements: TieredAchievement[] = []
for (const [achievementId, achievementData] of Object.entries(achievementsData.tiered)) {
const amount = data.achievements[`skyblock_${achievementId.toLowerCase()}`] ?? null
let tier = 0
for (const tierData of achievementData.tiers) {
if (amount >= tierData.amount)
tier = tierData.tier
else
break
}
const next = achievementData.tiers[tier]?.amount ?? null
tieredAchievements.push({
id: achievementId.toLowerCase(),
name: achievementData.name,
tier,
next,
amount,
description: achievementData.description.replace(/%s/g, (achievementData.tiers[Math.max(0, tier - 1)].amount).toString())
})
}
tieredAchievements.sort((a, b) => (b.amount ?? 0) - (a.amount ?? 0))
let unlockedChallengeAchievements: ChallengeAchievement[] = []
let lockedChallengeAchievements: ChallengeAchievement[] = []
for (const [achievementId, achievementData] of Object.entries(achievementsData.one_time)) {
const achievement: ChallengeAchievement = {
id: achievementId.toLowerCase(),
name: achievementData.name,
unlocked: data.achievementsOneTime.includes(`skyblock_${achievementId.toLowerCase()}`),
description: achievementData.description
}
if (achievement.unlocked)
unlockedChallengeAchievements.push(achievement)
else
lockedChallengeAchievements.push(achievement)
}
return {
tiered: tieredAchievements, challenge: [
...unlockedChallengeAchievements,
...lockedChallengeAchievements
]
}
}
// this shouldn't be possible
console.debug('skyblock not found in achievements?')
return { tiered: [], challenge: [] }
}
|