diff options
author | mat <27899617+mat-1@users.noreply.github.com> | 2021-02-28 01:23:18 -0600 |
---|---|---|
committer | mat <27899617+mat-1@users.noreply.github.com> | 2021-02-28 01:23:18 -0600 |
commit | 6dadf95683a8b8574976c9d024b0b148521012f7 (patch) | |
tree | edd88502959e8b74c76d47a82a5b98a646b26eb4 /src/hypixel.ts | |
parent | 78198ac4812f6f33f412bdc62216567aa08d8199 (diff) | |
download | skyblock-api-6dadf95683a8b8574976c9d024b0b148521012f7.tar.gz skyblock-api-6dadf95683a8b8574976c9d024b0b148521012f7.tar.bz2 skyblock-api-6dadf95683a8b8574976c9d024b0b148521012f7.zip |
Add leaderboards
Diffstat (limited to 'src/hypixel.ts')
-rw-r--r-- | src/hypixel.ts | 230 |
1 files changed, 135 insertions, 95 deletions
diff --git a/src/hypixel.ts b/src/hypixel.ts index 83ad419..3b8a952 100644 --- a/src/hypixel.ts +++ b/src/hypixel.ts @@ -6,9 +6,10 @@ import { CleanPlayer, cleanPlayerResponse } from './cleaners/player' import { chooseApiKey, HypixelResponse, sendApiRequest } from './hypixelApi' import * as cached from './hypixelCached' import { CleanBasicMember, CleanMemberProfile } from './cleaners/skyblock/member' -import { cleanSkyblockProfileResponse, CleanProfile, CleanBasicProfile } from './cleaners/skyblock/profile' +import { cleanSkyblockProfileResponse, CleanProfile, CleanBasicProfile, CleanFullProfile, CleanFullProfileBasicMembers } from './cleaners/skyblock/profile' import { cleanSkyblockProfilesResponse } from './cleaners/skyblock/profiles' import { debug } from '.' +import { updateDatabaseMember } from './database' export type Included = 'profiles' | 'player' | 'stats' | 'inventories' @@ -23,46 +24,47 @@ export const maxMinion = 11 */ export interface ApiOptions { - mainMemberUuid?: string + mainMemberUuid?: string } +/** Sends an API request to Hypixel and cleans it up. */ export async function sendCleanApiRequest({ path, args }, included?: Included[], options?: ApiOptions) { - const key = await chooseApiKey() - const rawResponse = await sendApiRequest({ path, key, args }) - if (rawResponse.throttled) { + const key = await chooseApiKey() + const rawResponse = await sendApiRequest({ path, key, args }) + if (rawResponse.throttled) { // if it's throttled, wait a second and try again await new Promise(resolve => setTimeout(resolve, 1000)) - return await sendCleanApiRequest({ path, args }, included, options) - } + return await sendCleanApiRequest({ path, args }, included, options) + } - // clean the response - return await cleanResponse({ path, data: rawResponse }, options ?? {}) + // clean the response + return await cleanResponse({ path, data: rawResponse }, options ?? {}) } async function cleanResponse({ path, data }: { path: string, data: HypixelResponse }, options: ApiOptions) { - // Cleans up an api response - switch (path) { - case 'player': return await cleanPlayerResponse(data.player) - case 'skyblock/profile': return await cleanSkyblockProfileResponse(data.profile, options) - case 'skyblock/profiles': return await cleanSkyblockProfilesResponse(data.profiles) - } + // Cleans up an api response + switch (path) { + case 'player': return await cleanPlayerResponse(data.player) + case 'skyblock/profile': return await cleanSkyblockProfileResponse(data.profile, options) + case 'skyblock/profiles': return await cleanSkyblockProfilesResponse(data.profiles) + } } /* ----------------------------- */ export interface UserAny { - user?: string - uuid?: string - username?: string + user?: string + uuid?: string + username?: string } export interface CleanUser { - player: CleanPlayer - profiles?: CleanProfile[] - activeProfile?: string - online?: boolean + player: CleanPlayer + profiles?: CleanProfile[] + activeProfile?: string + online?: boolean } @@ -73,52 +75,52 @@ export interface CleanUser { * used inclusions: player, profiles */ export async function fetchUser({ user, uuid, username }: UserAny, included: Included[]=['player']): Promise<CleanUser> { - if (!uuid) { - // If the uuid isn't provided, get it - uuid = await cached.uuidFromUser(user || username) - } - if (!uuid) { - // the user doesn't exist. - if (debug) console.log('error:', user, 'doesnt exist') - return null - } - - const includePlayers = included.includes('player') - const includeProfiles = included.includes('profiles') - - let profilesData: CleanProfile[] - let basicProfilesData: CleanBasicProfile[] - let playerData: CleanPlayer - - if (includePlayers) { - playerData = await cached.fetchPlayer(uuid) - // if not including profiles, include lightweight profiles just in case - if (!includeProfiles) - basicProfilesData = playerData.profiles - playerData.profiles = undefined - } - if (includeProfiles) { - profilesData = await cached.fetchSkyblockProfiles(uuid) - } - - let activeProfile: CleanProfile = null - let lastOnline: number = 0 - - if (includeProfiles) { - for (const profile of profilesData) { - const member = profile.members.find(member => member.uuid === uuid) - if (member.last_save > lastOnline) { - lastOnline = member.last_save - activeProfile = profile - } - } - } - return { - player: playerData ?? null, - profiles: profilesData ?? basicProfilesData, - activeProfile: includeProfiles ? activeProfile?.uuid : undefined, - online: includeProfiles ? lastOnline > (Date.now() - saveInterval): undefined - } + if (!uuid) { + // If the uuid isn't provided, get it + uuid = await cached.uuidFromUser(user || username) + } + if (!uuid) { + // the user doesn't exist. + if (debug) console.log('error:', user, 'doesnt exist') + return null + } + + const includePlayers = included.includes('player') + const includeProfiles = included.includes('profiles') + + let profilesData: CleanProfile[] + let basicProfilesData: CleanBasicProfile[] + let playerData: CleanPlayer + + if (includePlayers) { + playerData = await cached.fetchPlayer(uuid) + // if not including profiles, include lightweight profiles just in case + if (!includeProfiles) + basicProfilesData = playerData.profiles + playerData.profiles = undefined + } + if (includeProfiles) { + profilesData = await cached.fetchSkyblockProfiles(uuid) + } + + let activeProfile: CleanProfile = null + let lastOnline: number = 0 + + if (includeProfiles) { + for (const profile of profilesData) { + const member = profile.members.find(member => member.uuid === uuid) + if (member.last_save > lastOnline) { + lastOnline = member.last_save + activeProfile = profile + } + } + } + return { + player: playerData ?? null, + profiles: profilesData ?? basicProfilesData, + activeProfile: includeProfiles ? activeProfile?.uuid : undefined, + online: includeProfiles ? lastOnline > (Date.now() - saveInterval): undefined + } } /** @@ -128,40 +130,78 @@ export async function fetchUser({ user, uuid, username }: UserAny, included: Inc * @param profile A profile name or profile uuid */ export async function fetchMemberProfile(user: string, profile: string): Promise<CleanMemberProfile> { - const playerUuid = await cached.uuidFromUser(user) - const profileUuid = await cached.fetchProfileUuid(user, profile) + const playerUuid = await cached.uuidFromUser(user) + const profileUuid = await cached.fetchProfileUuid(user, profile) - // if the profile doesn't have an id, just return - if (!profileUuid) return null + // if the profile doesn't have an id, just return + if (!profileUuid) return null - const player = await cached.fetchPlayer(playerUuid) + const player = await cached.fetchPlayer(playerUuid) - const cleanProfile = await cached.fetchProfile(playerUuid, profileUuid) + const cleanProfile = await cached.fetchProfile(playerUuid, profileUuid) as CleanFullProfileBasicMembers - const member = cleanProfile.members.find(m => m.uuid === playerUuid) + const member = cleanProfile.members.find(m => m.uuid === playerUuid) - // remove unnecessary member data - const simpleMembers: CleanBasicMember[] = cleanProfile.members.map(m => { - return { - uuid: m.uuid, - username: m.username, - first_join: m.first_join, - last_save: m.last_save, - rank: m.rank - } - }) + // remove unnecessary member data + const simpleMembers: CleanBasicMember[] = cleanProfile.members.map(m => { + return { + uuid: m.uuid, + username: m.username, + first_join: m.first_join, + last_save: m.last_save, + rank: m.rank + } + }) - cleanProfile.members = simpleMembers + cleanProfile.members = simpleMembers - return { - member: { + return { + member: { // the profile name is in member rather than profile since they sometimes differ for each member - profileName: cleanProfile.name, + profileName: cleanProfile.name, // add all the member data - ...member, - // add all other data relating to the hypixel player, such as username, rank, etc - ...player - }, - profile: cleanProfile - } + ...member, + // add all other data relating to the hypixel player, such as username, rank, etc + ...player + }, + profile: cleanProfile + } } + +/** + * Fetches the Hypixel API to get a CleanFullProfile. This doesn't do any caching and you should use hypixelCached.fetchProfile instead + * @param playerUuid The UUID of the Minecraft player + * @param profileUuid The UUID of the Hypixel SkyBlock profile + */ +export async function fetchMemberProfileUncached(playerUuid: string, profileUuid: string): Promise<CleanFullProfile> { + const profile: CleanFullProfile = await sendCleanApiRequest( + { + path: 'skyblock/profile', + args: { profile: profileUuid } + }, + null, + { mainMemberUuid: playerUuid } + ) + for (const member of profile.members) + updateDatabaseMember(member) + return profile +} + + +export async function fetchMemberProfilesUncached(playerUuid: string): Promise<CleanFullProfile[]> { + const profiles: CleanFullProfile[] = await sendCleanApiRequest({ + path: 'skyblock/profiles', + args: { + uuid: playerUuid + }}, + null, + { + // only the inventories for the main player are generated, this is for optimization purposes + mainMemberUuid: playerUuid + } + ) + for (const profile of profiles) + for (const member of profile.members) + updateDatabaseMember(member) + return profiles +}
\ No newline at end of file |