aboutsummaryrefslogtreecommitdiff
path: root/hypixel.ts
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2021-02-13 14:13:42 -0600
committermat <27899617+mat-1@users.noreply.github.com>2021-02-13 14:13:42 -0600
commit52e38809212133ef673d11bfa96ba3bb43c3644c (patch)
treef54408afd41cc64b64d5e82a3ad814b1bb55d4a7 /hypixel.ts
parenta23103ec24128f2e24b93ad101ade6dfdd4758c3 (diff)
downloadskyblock-api-52e38809212133ef673d11bfa96ba3bb43c3644c.tar.gz
skyblock-api-52e38809212133ef673d11bfa96ba3bb43c3644c.tar.bz2
skyblock-api-52e38809212133ef673d11bfa96ba3bb43c3644c.zip
move stuff into src folder
Diffstat (limited to 'hypixel.ts')
-rw-r--r--hypixel.ts284
1 files changed, 0 insertions, 284 deletions
diff --git a/hypixel.ts b/hypixel.ts
deleted file mode 100644
index f17dc9e..0000000
--- a/hypixel.ts
+++ /dev/null
@@ -1,284 +0,0 @@
-import { CleanMinion, cleanMinions, combineMinionArrays } from './cleaners/skyblock/minions'
-import { CleanProfileStats, cleanProfileStats } from './cleaners/skyblock/stats'
-import { CleanPlayer, cleanPlayerResponse } from './cleaners/player'
-import { chooseApiKey, HypixelPlayerStatsSkyBlockProfiles, HypixelResponse, sendApiRequest } from './hypixelApi'
-import * as cached from './hypixelCached'
-
-export type Included = 'profiles' | 'player' | 'stats'
-
-// the interval at which the "last_save" parameter updates in the hypixel api, this is 3 minutes
-export const saveInterval = 60 * 3 * 1000
-
-// the highest level a minion can be
-export const maxMinion = 11
-
-/**
- * Send a request to api.hypixel.net using a random key, clean it up to be more useable, and return it
- */
-export async function sendCleanApiRequest({ path, args }, included?: Included[], cleaned=true) {
- const key = await chooseApiKey()
- const rawResponse = await sendApiRequest({ path, key, args })
- if (rawResponse.throttled) {
- // if it's throttled, wait a second and try again
- console.log('throttled :/')
- await new Promise(resolve => setTimeout(resolve, 1000))
- return await sendCleanApiRequest({ path, args }, included, cleaned)
- }
- if (cleaned) {
- // if it needs to clean the response, call cleanResponse
- return await cleanResponse({ path, data: rawResponse }, included=included)
- } else {
- // this is provided in case the caller wants to do the cleaning itself
- // used in skyblock/profile, as cleaning the entire profile would use too much cpu
- return rawResponse
- }
-}
-
-export interface CleanBasicMember {
- uuid: string
- username: string
- last_save: number
- first_join: number
-}
-
-interface CleanMember extends CleanBasicMember {
- stats?: CleanProfileStats
- minions?: CleanMinion[]
-}
-
-async function cleanSkyBlockProfileMemberResponse(member, included: Included[] = null): Promise<CleanMember> {
- // Cleans up a member (from skyblock/profile)
- // profiles.members[]
- const statsIncluded = included == null || included.includes('stats')
- return {
- uuid: member.uuid,
- username: await cached.usernameFromUser(member.uuid),
- last_save: member.last_save,
- first_join: member.first_join,
- // last_death: ??? idk how this is formatted,
- stats: statsIncluded ? cleanProfileStats(member.stats) : undefined,
- minions: statsIncluded ? cleanMinions(member.crafted_generators) : undefined,
- }
-}
-
-
-export interface CleanMemberProfilePlayer extends CleanPlayer {
- // The profile name may be different for each player, so we put it here
- profileName: string
- first_join: number
- last_save: number
- bank?: {
- balance: number
- history: any[]
- }
-}
-
-export interface CleanMemberProfile {
- member: CleanMemberProfilePlayer
- profile: {
-
- }
-}
-
-export interface CleanProfile extends CleanBasicProfile {
- members?: CleanBasicMember[]
-}
-
-export interface CleanFullProfile extends CleanProfile {
- members: CleanMember[]
- bank?: {
- balance: number
- history: any[]
- }
- minions: CleanMinion[]
-}
-
-/** Return a `CleanProfile` instead of a `CleanFullProfile`, useful when we need to get members but don't want to waste much ram */
-async function cleanSkyblockProfileResponseLighter(data): Promise<CleanProfile> {
- // We use Promise.all so it can fetch all the usernames at once instead of waiting for the previous promise to complete
- const promises: Promise<CleanMember>[] = []
-
- for (const memberUUID in data.members) {
- const memberRaw = data.members[memberUUID]
- memberRaw.uuid = memberUUID
- // we pass an empty array to make it not check stats
- promises.push(cleanSkyBlockProfileMemberResponse(memberRaw, []))
- }
-
- const cleanedMembers: CleanMember[] = await Promise.all(promises)
-
- return {
- uuid: data.profile_id,
- name: data.cute_name,
- members: cleanedMembers,
- }
-}
-
-/** This function is very costly and shouldn't be called often. Use cleanSkyblockProfileResponseLighter if you don't need all the data */
-async function cleanSkyblockProfileResponse(data: any): Promise<CleanFullProfile> {
- const cleanedMembers: CleanMember[] = []
-
- for (const memberUUID in data.members) {
- const memberRaw = data.members[memberUUID]
- memberRaw.uuid = memberUUID
- const member: CleanMember = await cleanSkyBlockProfileMemberResponse(memberRaw, ['stats'])
- cleanedMembers.push(member)
- }
-
- const memberMinions: CleanMinion[][] = []
-
- for (const member of cleanedMembers) {
- memberMinions.push(member.minions)
- }
- const minions: CleanMinion[] = combineMinionArrays(memberMinions)
-
- // return more detailed info
- return {
- uuid: data.profile_id,
- name: data.cute_name,
- members: cleanedMembers,
- bank: {
- balance: data?.banking?.balance ?? 0,
-
- // TODO: make transactions good
- history: data?.banking?.transactions ?? []
- },
- minions
- }
-}
-
-/** A basic profile that only includes the profile uuid and name */
-export interface CleanBasicProfile {
- uuid: string
-
- // the name depends on the user, so its sometimes not included
- name?: string
-}
-
-export function cleanPlayerSkyblockProfiles(rawProfiles: HypixelPlayerStatsSkyBlockProfiles): CleanBasicProfile[] {
- let profiles: CleanBasicProfile[] = []
- for (const profile of Object.values(rawProfiles)) {
- profiles.push({
- uuid: profile.profile_id,
- name: profile.cute_name
- })
- }
- console.log('cleanPlayerSkyblockProfiles', profiles)
- return profiles
-}
-
-/** Convert an array of raw profiles into clean profiles */
-async function cleanSkyblockProfilesResponse(data: any[]): Promise<CleanProfile[]> {
- const cleanedProfiles: CleanProfile[] = []
- for (const profile of data) {
- let cleanedProfile = await cleanSkyblockProfileResponseLighter(profile)
- cleanedProfiles.push(cleanedProfile)
- }
- return cleanedProfiles
-}
-
-async function cleanResponse({ path, data }: { path: string, data: HypixelResponse }, included?: Included[]) {
- // Cleans up an api response
- switch (path) {
- case 'player': return await cleanPlayerResponse(data.player)
- case 'skyblock/profile': return await cleanSkyblockProfileResponse(data.profile)
- case 'skyblock/profiles': return await cleanSkyblockProfilesResponse(data.profiles)
- }
-}
-
-/* ----------------------------- */
-
-export interface UserAny {
- user?: string
- uuid?: string
- username?: string
-}
-
-export interface CleanUser {
- player: any
- profiles?: any
- activeProfile?: string
- online?: boolean
-}
-
-
-/**
- * Higher level function that requests the api for a user, and returns the cleaned response
- * This is safe to fetch many times because the results are cached!
- * @param included lets you choose what is returned, so there's less processing required on the backend
- * 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)
- }
-
- 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
- }
-}
-
-/**
- * Fetch a CleanMemberProfile from a user and string
- * This is safe to use many times as the results are cached!
- * @param user A username or uuid
- * @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 player = await cached.fetchPlayer(playerUuid)
-
- const cleanProfile = await cached.fetchProfile(playerUuid, profileUuid)
-
- const member = cleanProfile.members.find(m => m.uuid === playerUuid)
-
- return {
- member: {
- profileName: cleanProfile.name,
- first_join: member.first_join,
- last_save: member.last_save,
-
- // add all other data relating to the hypixel player, such as username, rank, etc
- ...player
- },
- profile: {
- minions: cleanProfile.minions
- }
- }
-}