diff options
author | mat <27899617+mat-1@users.noreply.github.com> | 2021-02-13 13:56:19 -0600 |
---|---|---|
committer | mat <27899617+mat-1@users.noreply.github.com> | 2021-02-13 13:56:19 -0600 |
commit | a23103ec24128f2e24b93ad101ade6dfdd4758c3 (patch) | |
tree | c4d543a2003062a7c213d37f5d06a826c2a88798 /cleaners | |
parent | d7b9d1fc5cfc8c648604eb1d178091873ea698a6 (diff) | |
download | skyblock-api-a23103ec24128f2e24b93ad101ade6dfdd4758c3.tar.gz skyblock-api-a23103ec24128f2e24b93ad101ade6dfdd4758c3.tar.bz2 skyblock-api-a23103ec24128f2e24b93ad101ade6dfdd4758c3.zip |
Basic profile stats
Diffstat (limited to 'cleaners')
-rw-r--r-- | cleaners/player.ts | 28 | ||||
-rw-r--r-- | cleaners/rank.ts | 66 | ||||
-rw-r--r-- | cleaners/skyblock/minions.ts | 70 | ||||
-rw-r--r-- | cleaners/skyblock/stats.ts | 73 | ||||
-rw-r--r-- | cleaners/socialmedia.ts | 14 |
5 files changed, 251 insertions, 0 deletions
diff --git a/cleaners/player.ts b/cleaners/player.ts new file mode 100644 index 0000000..c3afd6f --- /dev/null +++ b/cleaners/player.ts @@ -0,0 +1,28 @@ +import { CleanBasicProfile, cleanPlayerSkyblockProfiles, Included } from '../hypixel' +import { CleanSocialMedia, parseSocialMedia } from './socialmedia' +import { CleanRank, parseRank } from './rank' +import { HypixelPlayer } from '../hypixelApi' +import { undashUuid } from '../util' + +export interface CleanBasicPlayer { + uuid: string + username: string +} + +export interface CleanPlayer extends CleanBasicPlayer { + rank: CleanRank + socials: CleanSocialMedia + profiles?: CleanBasicProfile[] +} + +export async function cleanPlayerResponse(data: HypixelPlayer): Promise<CleanPlayer> { + // Cleans up a 'player' api response + console.log('cleanPlayerResponse', data.stats.SkyBlock.profiles) + return { + uuid: undashUuid(data.uuid), + username: data.displayname, + rank: parseRank(data), + socials: parseSocialMedia(data.socialMedia), + profiles: cleanPlayerSkyblockProfiles(data.stats.SkyBlock.profiles) + } +} diff --git a/cleaners/rank.ts b/cleaners/rank.ts new file mode 100644 index 0000000..928373a --- /dev/null +++ b/cleaners/rank.ts @@ -0,0 +1,66 @@ +import { HypixelPlayer } from '../hypixelApi' +import { colorCodeFromName, minecraftColorCodes } from '../util' + +const rankColors: { [ name: string ]: string } = { + 'NONE': '7', + 'VIP': 'a', + 'VIP+': 'a', + 'MVP': 'b', + 'MVP+': 'b', + 'MVP++': '6', + 'YOUTUBE': 'c', + 'HELPER': '9', + 'MODERATOR': '2', + 'ADMIN': 'c' +} + +export interface CleanRank { + name: string, + color: string | null, + colored: string | null, +} + +/** Response cleaning (reformatting to be nicer) */ +export function parseRank({ + packageRank, + newPackageRank, + monthlyPackageRank, + rankPlusColor, + rank, + prefix +}: HypixelPlayer): CleanRank { + let name + let color + let colored + if (prefix) { // derive values from prefix + colored = prefix + color = minecraftColorCodes[colored.match(/§./)[0][1]] + name = colored.replace(/§./g, '').replace(/[\[\]]/g, '') + } else { + name = rank + || newPackageRank.replace('_PLUS', '+') + || packageRank.replace('_PLUS', '+') + || monthlyPackageRank + + // MVP++ is called Superstar for some reason + if (name === 'SUPERSTAR') name = 'MVP++' + // YouTube rank is called YouTuber, change this to the proper name + else if (name === 'YOUTUBER') name = 'YOUTUBE' + + const plusColor = colorCodeFromName(rankPlusColor) + color = minecraftColorCodes[rankColors[name]] + const rankColorPrefix = rankColors[name] ? '§' + rankColors[name] : '' + const nameWithoutPlus = name.split('+')[0] + const plusesInName = '+'.repeat(name.split('+').length - 1) + console.log(plusColor, nameWithoutPlus, plusesInName) + if (plusColor && plusesInName.length >= 1) + colored = `${rankColorPrefix}[${nameWithoutPlus}§${plusColor}${plusesInName}${rankColorPrefix}]` + else + colored = `${rankColorPrefix}[${name}]` + } + return { + name, + color, + colored + } +} diff --git a/cleaners/skyblock/minions.ts b/cleaners/skyblock/minions.ts new file mode 100644 index 0000000..da69634 --- /dev/null +++ b/cleaners/skyblock/minions.ts @@ -0,0 +1,70 @@ +import { maxMinion } from '../../hypixel' + +export interface CleanMinion { + name: string, + levels: boolean[] +} + + +/** + * Clean the minions provided by Hypixel + * @param minionsRaw The minion data provided by the Hypixel API + */ +export function cleanMinions(minionsRaw: string[]): CleanMinion[] { + const minions: CleanMinion[] = [] + for (const minionRaw of minionsRaw ?? []) { + // do some regex magic to get the minion name and level + // examples of potential minion names: CLAY_11, PIG_1, MAGMA_CUBE_4 + const minionName = minionRaw.split(/_\d/)[0].toLowerCase() + const minionLevel = parseInt(minionRaw.split(/\D*_/)[1]) + let matchingMinion = minions.find(m => m.name === minionName) + if (!matchingMinion) { + // if the minion doesnt already exist in the minions array, then create it + matchingMinion = { + name: minionName, + levels: new Array(maxMinion).fill(false) + } + minions.push(matchingMinion) + } + while (minionLevel > matchingMinion.levels.length) + // if hypixel increases the minion level, this will increase with it + matchingMinion.levels.push(false) + + // set the minion at that level to true + matchingMinion.levels[minionLevel - 1] = true + } + return minions +} + +/** + * Combine multiple arrays of minions into one, useful when getting the minions for members + * @param minions An array of arrays of minions + */ +export function combineMinionArrays(minions: CleanMinion[][]): CleanMinion[] { + const resultMinions: CleanMinion[] = [] + + for (const memberMinions of minions) { + for (const minion of memberMinions) { + // this is a reference, so we can directly modify the attributes for matchingMinionReference + // and they'll be in the resultMinions array + const matchingMinionReference = resultMinions.find(m => m.name === minion.name) + if (!matchingMinionReference) { + // if the minion name isn't already in the array, add it! + resultMinions.push(minion) + } else { + + // This should never happen, but in case the length of `minion.levels` is longer than + // `matchingMinionReference.levels`, then it should be extended to be equal length + while (matchingMinionReference.levels.length < minion.levels.length) + matchingMinionReference.levels.push(null) + + for (let i = 0; i < minion.levels.length; i++) { + if (minion.levels[i]) + matchingMinionReference.levels[i] = true + } + } + } + } + + return resultMinions +}
\ No newline at end of file diff --git a/cleaners/skyblock/stats.ts b/cleaners/skyblock/stats.ts new file mode 100644 index 0000000..07d9133 --- /dev/null +++ b/cleaners/skyblock/stats.ts @@ -0,0 +1,73 @@ +const statCategories: { [ key: string ]: string[] | null } = { // sorted in order of importance + 'deaths': ['deaths_', 'deaths'], + 'kills': ['kills_', 'kills'], + 'fishing': ['items_fished_', 'items_fished'], + 'auctions': ['auctions_'], + 'races': ['_best_time'], + 'misc': null // everything else goes here +} + +interface statCategory { + category: string, + name: string +} + +function categorizeStat(statNameRaw: string): statCategory { + // 'deaths_void' + for (const statCategory in statCategories) { + // 'deaths' + const statCategoryMatchers = statCategories[statCategory] + if (statCategoryMatchers == null) { + // If it's null, just go with this. Can only ever be 'misc' + return { + category: statCategory, + name: statNameRaw + } + } + for (const categoryMatch of statCategoryMatchers) { + // ['deaths_'] + let trailingEnd = categoryMatch[0] == '_' + let trailingStart = categoryMatch.substr(-1) == '_' + if (trailingStart && statNameRaw.startsWith(categoryMatch)) { + return { + category: statCategory, + name: statNameRaw.substr(categoryMatch.length) + } + } else if (trailingEnd && statNameRaw.endsWith(categoryMatch)) { + return { + category: statCategory, + name: statNameRaw.substr(0, categoryMatch.length) + } + } else if (statNameRaw == categoryMatch) { + // if it matches exactly, we don't know the name. will be defaulted to category later on + return { + category: statCategory, + name: null + } + } + } + } + // this should never happen, as it'll default to misc and return if nothing is found + return { + category: null, + name: statNameRaw + } +} + +export interface CleanProfileStats { + [ category: string ]: { + [ stat: string ]: any + total?: any + } +} + +export function cleanProfileStats(statsRaw): CleanProfileStats { + // TODO: add type for statsRaw (probably in hypixelApi.ts since its coming from there) + const stats: CleanProfileStats = {} + for (let statNameRaw in statsRaw) { + let { category: statCategory, name: statName } = categorizeStat(statNameRaw) + if (!stats[statCategory]) stats[statCategory] = {} + stats[statCategory][statName || 'total'] = statsRaw[statNameRaw] + } + return stats +} diff --git a/cleaners/socialmedia.ts b/cleaners/socialmedia.ts new file mode 100644 index 0000000..c1f9551 --- /dev/null +++ b/cleaners/socialmedia.ts @@ -0,0 +1,14 @@ +import { HypixelPlayerSocialMedia } from "../hypixelApi"; + +export interface CleanSocialMedia { + discord: string | null + forums: string | null +} + +export function parseSocialMedia(socialMedia: HypixelPlayerSocialMedia): CleanSocialMedia { + return { + discord: socialMedia?.links?.DISCORD || null, + forums: socialMedia?.links?.HYPIXEL || null + } +} + |