diff options
author | mat <github@matdoes.dev> | 2022-03-19 19:56:16 -0500 |
---|---|---|
committer | mat <github@matdoes.dev> | 2022-03-19 19:56:16 -0500 |
commit | 4fd4e4fdbd444466fd22827327eb36da1219eb9f (patch) | |
tree | 6cbdb9d729037c35180ee614fbcb88755be853e4 | |
parent | 53ebb73fa06f6b41793757375dea40bff75bef7e (diff) | |
download | skyblock-api-4fd4e4fdbd444466fd22827327eb36da1219eb9f.tar.gz skyblock-api-4fd4e4fdbd444466fd22827327eb36da1219eb9f.tar.bz2 skyblock-api-4fd4e4fdbd444466fd22827327eb36da1219eb9f.zip |
Squashed commit of the following:
commit 8de482698ce3b144a5208084299733a3951d691a
Author: mat <github@matdoes.dev>
Date: Sat Mar 19 19:39:21 2022 -0500
fix some issues with the typings
commit e4d72e4b66c1f013dab495786041e7ce0316b0af
Author: mat <github@matdoes.dev>
Date: Sat Mar 19 18:04:10 2022 -0500
Fix error when there is no slayer data
commit 706d044f6791272f3f4488d03884c33fc545a806
Author: mat <github@matdoes.dev>
Date: Sat Mar 19 18:02:04 2022 -0500
Fix wrong interface
commit d1cc698f4add94171004ca7039a452d38fa063b8
Merge: b490254 8843ccf
Author: mat <github@matdoes.dev>
Date: Sat Mar 19 17:54:00 2022 -0500
Merge branch 'main' into breaking
commit b490254510b43ca9ef9822c661f3bfeb2e9ec7ef
Author: mat <github@matdoes.dev>
Date: Sat Mar 5 13:09:26 2022 -0600
change some seconds to milliseconds
commit 09fc38f77faa88f7234f2496c7fd797b884cbf24
Author: mat <github@matdoes.dev>
Date: Sat Mar 5 13:04:46 2022 -0600
Update README.md
commit a470363ea7e7885c5c946aca9b40f73426a0e94c
Author: mat <github@matdoes.dev>
Date: Sat Mar 5 13:01:42 2022 -0600
Move `/leaderboard/` to `/leaderboards/`
commit 012525036db62fbb97a56576f80c231b4127736d
Author: mat <github@matdoes.dev>
Date: Sat Mar 5 13:00:06 2022 -0600
Rename collection `xp` to `amount`
commit dc8ea0588ad5357257767b37737da185e4dbffd0
Author: mat <github@matdoes.dev>
Date: Sat Mar 5 12:59:20 2022 -0600
Rename visited_zones to just zones
commit 6008feb15d36afd914efe98e90409327d3fc1322
Author: mat <github@matdoes.dev>
Date: Sat Mar 5 12:54:15 2022 -0600
Replace all snake_case keys with camelCase
-rw-r--r-- | README.md | 10 | ||||
-rw-r--r-- | src/cleaners/player.ts | 2 | ||||
-rw-r--r-- | src/cleaners/skyblock/collections.ts | 4 | ||||
-rw-r--r-- | src/cleaners/skyblock/election.ts | 4 | ||||
-rw-r--r-- | src/cleaners/skyblock/inventory.ts | 8 | ||||
-rw-r--r-- | src/cleaners/skyblock/member.ts | 47 | ||||
-rw-r--r-- | src/cleaners/skyblock/profile.ts | 6 | ||||
-rw-r--r-- | src/cleaners/skyblock/slayers.ts | 4 | ||||
-rw-r--r-- | src/database.ts | 30 | ||||
-rw-r--r-- | src/discord.ts | 4 | ||||
-rw-r--r-- | src/hypixel.ts | 22 | ||||
-rw-r--r-- | src/hypixelCached.ts | 8 | ||||
-rw-r--r-- | src/index.ts | 2 |
13 files changed, 75 insertions, 76 deletions
@@ -17,12 +17,6 @@ This is kinda like [Slothpixel](https://github.com/slothpixel/core), it fetches ## API conventions If you (this is really just here for myself so I don't forget) are adding a new API thing, follow these rules so the API is consistent with how it responds: -- Use camelCase. Some old things use snake_case but these are going to be changed at some point. +- Use camelCase for keys. +- Use snake_case for values. - Prefer arrays over dictionaries when the keys aren't static. For example `[ { name: "asdf", value: "dsfasg" } ]` rather than `{ "asdf": "dsfasg" }`. -- "name" fields should be snake_case ids. - -## Breaking changes todo -- Replace all snake_case keys with camelCase -- Rename visited_zones to just zones since it contains every zone -- Rename collection `xp` to `amount` -- Move `/leaderboard/` to `/leaderboards/` diff --git a/src/cleaners/player.ts b/src/cleaners/player.ts index 802cdd5..1fd6f85 100644 --- a/src/cleaners/player.ts +++ b/src/cleaners/player.ts @@ -14,7 +14,6 @@ export interface CleanPlayer extends CleanBasicPlayer { rank: CleanRank socials: CleanSocialMedia profiles?: CleanBasicProfile[] - // first_join?: number } export async function cleanPlayerResponse(data: HypixelPlayer): Promise<CleanPlayer | null> { @@ -26,7 +25,6 @@ export async function cleanPlayerResponse(data: HypixelPlayer): Promise<CleanPla username: data.displayname, rank: cleanRank(data), socials: cleanSocialMedia(data), - // first_join: data.firstLogin / 1000, profiles: cleanPlayerSkyblockProfiles(data.stats?.SkyBlock?.profiles) } } diff --git a/src/cleaners/skyblock/collections.ts b/src/cleaners/skyblock/collections.ts index 363a6e0..7be5a9d 100644 --- a/src/cleaners/skyblock/collections.ts +++ b/src/cleaners/skyblock/collections.ts @@ -81,7 +81,7 @@ type CollectionCategory = keyof typeof COLLECTIONS export interface Collection { name: string - xp: number + amount: number level: number category: CollectionCategory } @@ -127,7 +127,7 @@ export function cleanCollections(data: any): Collection[] { if (collectionLevel !== undefined) playerCollections.push({ name: collectionName, - xp: collectionXp, + amount: collectionXp, level: collectionLevel, category: collectionCategory }) diff --git a/src/cleaners/skyblock/election.ts b/src/cleaners/skyblock/election.ts index 127fe96..a773f4a 100644 --- a/src/cleaners/skyblock/election.ts +++ b/src/cleaners/skyblock/election.ts @@ -15,7 +15,7 @@ export interface Candidate { } export interface ElectionData { - last_updated: number + lastUpdated: number previous: { year: number winner: string @@ -42,7 +42,7 @@ function cleanCandidate(data: any, index: number): Candidate { export function cleanElectionResponse(data: any): ElectionData { const previousCandidates = data.mayor.election.candidates.map(cleanCandidate) return { - last_updated: data.lastUpdated / 1000, + lastUpdated: data.lastUpdated, previous: { year: data.mayor.election.year, winner: data.mayor.name, diff --git a/src/cleaners/skyblock/inventory.ts b/src/cleaners/skyblock/inventory.ts index 5ad6617..16c74fa 100644 --- a/src/cleaners/skyblock/inventory.ts +++ b/src/cleaners/skyblock/inventory.ts @@ -17,11 +17,11 @@ interface Item { } reforge?: string - anvil_uses?: number + anvilUses?: number timestamp?: string enchantments?: { [ name: string ]: number } - head_texture?: string + headTexture?: string } export type Inventory = Item[] @@ -63,10 +63,10 @@ function cleanItem(rawItem): Item | null { reforge: extraAttributes?.modifier, enchantments: extraAttributes?.enchantments, - anvil_uses: extraAttributes?.anvil_uses, + anvilUses: extraAttributes?.anvil_uses, timestamp: extraAttributes?.timestamp, - head_texture: headId, + headTexture: headId, } } diff --git a/src/cleaners/skyblock/member.ts b/src/cleaners/skyblock/member.ts index 8d1fdf1..b90d0c4 100644 --- a/src/cleaners/skyblock/member.ts +++ b/src/cleaners/skyblock/member.ts @@ -19,21 +19,21 @@ import { Bank } from './bank.js' export interface CleanBasicMember { uuid: string username: string - last_save: number - first_join: number + lastSave: number + firstJoin: number rank: CleanRank } export interface CleanMember extends CleanBasicMember { purse: number stats: StatItem[] - rawHypixelStats?: { [key: string]: number } + rawHypixelStats: { [key: string]: number } minions: CleanMinion[] - fairy_souls: FairySouls + fairySouls: FairySouls inventories?: Inventories objectives: Objective[] skills: Skill[] - visited_zones: Zone[] + zones: Zone[] collections: Collection[] slayers: SlayerData } @@ -44,8 +44,8 @@ export async function cleanSkyBlockProfileMemberResponseBasic(member: any): Prom return { uuid: member.uuid, username: player.username, - last_save: member.last_save / 1000, - first_join: member.first_join / 1000, + lastSave: member.last_save, + firstJoin: member.first_join, rank: player.rank } } @@ -65,8 +65,8 @@ export async function cleanSkyBlockProfileMemberResponse(member, included: Inclu return { uuid: member.uuid, username: player.username, - last_save: member.last_save / 1000, - first_join: member.first_join / 1000, + lastSave: member.last_save, + firstJoin: member.first_join, rank: player.rank, purse: member.coin_purse, @@ -77,11 +77,11 @@ export async function cleanSkyBlockProfileMemberResponse(member, included: Inclu rawHypixelStats: member.stats ?? {}, minions: await cleanMinions(member), - fairy_souls: fairySouls, + fairySouls: fairySouls, inventories: inventoriesIncluded ? await cleanInventories(member) : undefined, objectives: cleanObjectives(member), skills: await cleanSkills(member), - visited_zones: await cleanVisitedZones(member), + zones: await cleanVisitedZones(member), collections: cleanCollections(member), slayers: cleanSlayers(member) } @@ -91,20 +91,19 @@ export async function cleanSkyBlockProfileMemberResponse(member, included: Inclu 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?: Bank - purse?: number - stats?: StatItem[] - rawHypixelStats?: { [key: string]: number } - minions?: CleanMinion[] - fairy_souls?: FairySouls + firstJoin: number + lastSave: number + purse: number + stats: StatItem[] + rawHypixelStats: { [key: string]: number } + minions: CleanMinion[] + fairySouls: FairySouls inventories?: Inventories - objectives?: Objective[] - skills?: Skill[] - visited_zones?: Zone[] - collections?: Collection[] - slayers?: SlayerData + objectives: Objective[] + skills: Skill[] + zones: Zone[] + collections: Collection[] + slayers: SlayerData } export interface CleanMemberProfile { diff --git a/src/cleaners/skyblock/profile.ts b/src/cleaners/skyblock/profile.ts index d5ddc61..a510563 100644 --- a/src/cleaners/skyblock/profile.ts +++ b/src/cleaners/skyblock/profile.ts @@ -12,7 +12,7 @@ export interface CleanFullProfile extends CleanProfile { members: CleanMember[] bank: Bank minions: CleanMinion[] - minion_count: number + minionCount: number maxUniqueMinions: number } @@ -20,7 +20,7 @@ export interface CleanFullProfileBasicMembers extends CleanProfile { members: CleanBasicMember[] bank: Bank minions: CleanMinion[] - minion_count: number + minionCount: number maxUniqueMinions: number } @@ -94,7 +94,7 @@ export async function cleanSkyblockProfileResponse(data: any, options?: ApiOptio members: cleanedMembers, bank: cleanBank(data), minions: minions, - minion_count: uniqueMinions, + minionCount: uniqueMinions, maxUniqueMinions: maxUniqueMinions ?? 0, } } diff --git a/src/cleaners/skyblock/slayers.ts b/src/cleaners/skyblock/slayers.ts index 4852160..f4d203e 100644 --- a/src/cleaners/skyblock/slayers.ts +++ b/src/cleaners/skyblock/slayers.ts @@ -16,7 +16,7 @@ interface SlayerTier { export interface Slayer { name?: SlayerName - raw_name: string + rawName: string xp: number level: number kills: number @@ -81,7 +81,7 @@ export function cleanSlayers(data: any): SlayerData { const slayer: Slayer = { name: slayerName, - raw_name: slayerNameRaw, + rawName: slayerNameRaw, tiers: slayerTiers, xp: slayerXp ?? 0, level: slayerLevel, diff --git a/src/database.ts b/src/database.ts index c2fa026..f840d7b 100644 --- a/src/database.ts +++ b/src/database.ts @@ -35,14 +35,14 @@ interface DatabaseMemberLeaderboardItem { uuid: string profile: string stats: any - last_updated: Date + lastUpdated: Date } interface DatabaseProfileLeaderboardItem { uuid: string /** An array of uuids for each player in the profile */ players: string[] stats: any - last_updated: Date + lastUpdated: Date } @@ -111,10 +111,10 @@ let accountsCollection: Collection<AccountSchema> const leaderboardInfos: { [ leaderboardName: string ]: string } = { - highest_crit_damage: 'This leaderboard is capped at the integer limit because Hypixel, look at the <a href="/leaderboard/highest_critical_damage">highest critical damage leaderboard</a> instead.', + highest_crit_damage: 'This leaderboard is capped at the integer limit. Look at the <a href="/leaderboard/highest_critical_damage">highest critical damage leaderboard</a> instead.', highest_critical_damage: 'uhhhhh yeah idk either', - leaderboards_count: 'This leaderboard counts how many leaderboards players are in the top 100 for.', - top_1_leaderboards_count: 'This leaderboard counts how many leaderboards players are #1 for.', + leaderboards_count: 'This leaderboard counts how many leaderboards a player is in the top 100 spot for.', + top_1_leaderboards_count: 'This leaderboard counts how many leaderboards a player is in the #1 spot for.', skill_social: 'This leaderboard is inaccurate because Hypixel only shows social skill data on some API profiles.' } @@ -141,7 +141,7 @@ function getMemberCollectionAttributes(member: CleanMember): StringNumber { const collectionAttributes = {} for (const collection of member.collections) { const collectionLeaderboardName = `collection_${collection.name}` - collectionAttributes[collectionLeaderboardName] = collection.xp + collectionAttributes[collectionLeaderboardName] = collection.amount } return collectionAttributes } @@ -162,10 +162,10 @@ function getMemberSlayerAttributes(member: CleanMember): StringNumber { } for (const slayer of member.slayers.bosses) { - slayerAttributes[`slayer_${slayer.raw_name}_total_xp`] = slayer.xp - slayerAttributes[`slayer_${slayer.raw_name}_total_kills`] = slayer.kills + slayerAttributes[`slayer_${slayer.rawName}_total_xp`] = slayer.xp + slayerAttributes[`slayer_${slayer.rawName}_total_kills`] = slayer.kills for (const tier of slayer.tiers) { - slayerAttributes[`slayer_${slayer.raw_name}_${tier.tier}_kills`] = tier.kills + slayerAttributes[`slayer_${slayer.rawName}_${tier.tier}_kills`] = tier.kills } } @@ -187,17 +187,17 @@ function getMemberLeaderboardAttributes(member: CleanMember): StringNumber { // slayer leaderboards ...getMemberSlayerAttributes(member), - fairy_souls: member.fairy_souls.total, - first_join: member.first_join, + fairy_souls: member.fairySouls.total, + first_join: member.firstJoin, purse: member.purse, - visited_zones: member.visited_zones.length, + visited_zones: member.zones.filter(z => z.visited).length, } } function getProfileLeaderboardAttributes(profile: CleanFullProfile): StringNumber { // if you want to add a new leaderboard for member attributes, add it here (and getAllLeaderboardAttributes) return { - unique_minions: profile.minion_count + unique_minions: profile.minionCount } } @@ -618,8 +618,8 @@ export async function updateDatabaseMember(member: CleanMember, profile: CleanFu await constants.addStats(Object.keys(member.rawHypixelStats)) await constants.addCollections(member.collections.map(coll => coll.name)) await constants.addSkills(member.skills.map(skill => skill.name)) - await constants.addZones(member.visited_zones.map(zone => zone.name)) - await constants.addSlayers(member.slayers.bosses.map(s => s.raw_name)) + await constants.addZones(member.zones.map(zone => zone.name)) + await constants.addSlayers(member.slayers.bosses.map(s => s.rawName)) if (debug) console.debug('done constants..') diff --git a/src/discord.ts b/src/discord.ts index 16ca45f..7871fa3 100644 --- a/src/discord.ts +++ b/src/discord.ts @@ -15,6 +15,10 @@ export interface TokenResponse { token_type: string } +/** + * The information about the Discord user that's directly returned by the + * Discord API + */ export interface DiscordUser { id: string username: string diff --git a/src/hypixel.ts b/src/hypixel.ts index a9a0233..285ac4e 100644 --- a/src/hypixel.ts +++ b/src/hypixel.ts @@ -129,8 +129,8 @@ export async function fetchUser({ user, uuid, username }: UserAny, included: Inc if (includeProfiles) { for (const profile of profilesData!) { const member = profile.members?.find(member => member.uuid === uuid) - if (member && member.last_save > lastOnline) { - lastOnline = member.last_save + if (member && member.lastSave > lastOnline) { + lastOnline = member.lastSave activeProfile = profile } } @@ -167,11 +167,12 @@ export async function fetchMemberProfile(user: string, profile: string, customiz if (!profileUuid) return null if (!playerUuid) return null - const player = await cached.fetchPlayer(playerUuid) + const player: CleanPlayer | null = await cached.fetchPlayer(playerUuid) if (!player) return null // this should never happen, but if it does just return null - const cleanProfile = await cached.fetchProfile(playerUuid, profileUuid) as CleanFullProfileBasicMembers + const cleanProfile = await cached.fetchProfile(playerUuid, profileUuid) + if (!cleanProfile) return null const member = cleanProfile.members.find(m => m.uuid === playerUuid) if (!member) return null // this should never happen, but if it does just return null @@ -181,13 +182,16 @@ export async function fetchMemberProfile(user: string, profile: string, customiz return { uuid: m.uuid, username: m.username, - first_join: m.first_join, - last_save: m.last_save, + firstJoin: m.firstJoin, + lastSave: m.lastSave, rank: m.rank } }) - cleanProfile.members = simpleMembers + const cleanProfileBasicMembers: CleanFullProfileBasicMembers = { + ...cleanProfile, + members: simpleMembers + } let websiteAccount: WithId<AccountSchema> | null = null @@ -203,7 +207,7 @@ export async function fetchMemberProfile(user: string, profile: string, customiz // add all other data relating to the hypixel player, such as username, rank, etc ...player }, - profile: cleanProfile, + profile: cleanProfileBasicMembers, customization: websiteAccount?.customization } } @@ -301,7 +305,7 @@ export async function fetchElection(): Promise<ElectionData> { cachedElectionData = election // updates every 10 minutes - nextElectionUpdate = new Date((election.last_updated + 10 * 60) * 1000) + nextElectionUpdate = new Date((election.lastUpdated + 10 * 60) * 1000) return election } diff --git a/src/hypixelCached.ts b/src/hypixelCached.ts index 3130f41..3d8f04c 100644 --- a/src/hypixelCached.ts +++ b/src/hypixelCached.ts @@ -233,8 +233,8 @@ export async function fetchSkyblockProfiles(playerUuid: string): Promise<CleanPr return { uuid: m.uuid, username: m.username, - first_join: m.first_join, - last_save: m.last_save, + firstJoin: m.firstJoin, + lastSave: m.lastSave, rank: m.rank } }) @@ -354,8 +354,8 @@ export async function fetchBasicProfileFromUuid(profileUuid: string): Promise<Cl members: profile.members.map(m => ({ uuid: m.uuid, username: m.username, - last_save: m.last_save, - first_join: m.first_join, + lastSave: m.lastSave, + firstJoin: m.firstJoin, rank: m.rank, })), name: profile.name diff --git a/src/index.ts b/src/index.ts index 6608188..fe35009 100644 --- a/src/index.ts +++ b/src/index.ts @@ -109,7 +109,7 @@ app.get('/player/:user/:profile/leaderboards', async (req, res) => { } }) -app.get('/leaderboard/:name', async (req, res) => { +app.get('/leaderboards/:name', async (req, res) => { try { res.json( await fetchLeaderboard(req.params.name) |