From c0c534dafb54ebf9f95a5054f576ad99de29f232 Mon Sep 17 00:00:00 2001 From: mat <27899617+mat-1@users.noreply.github.com> Date: Tue, 29 Jun 2021 17:52:00 -0500 Subject: enable strictNullChecks and fix all related issues (#65) --- src/hypixelCached.ts | 77 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 30 deletions(-) (limited to 'src/hypixelCached.ts') diff --git a/src/hypixelCached.ts b/src/hypixelCached.ts index 92a7801..4aa96ef 100644 --- a/src/hypixelCached.ts +++ b/src/hypixelCached.ts @@ -81,17 +81,17 @@ function waitForCacheSet(cache: NodeCache, key?: string, value?: string): Promis * Fetch the uuid from a user * @param user A user can be either a uuid or a username */ -export async function uuidFromUser(user: string): Promise { +export async function uuidFromUser(user: string): Promise { // if the user is 32 characters long, it has to be a uuid if (isUuid(user)) return undashUuid(user) if (usernameCache.has(undashUuid(user))) { // check if the uuid is a key - const username: Promise | string | null = usernameCache.get>(undashUuid(user)) + const username: Promise | string | undefined = usernameCache.get>(undashUuid(user)) // sometimes the username will be null, return that - if (username === null) return null + if (username === null) return undefined // if it has .then, then that means its a waitForCacheSet promise. This is done to prevent requests made while it is already requesting if ((username as Promise).then) { @@ -136,15 +136,16 @@ export async function uuidFromUser(user: string): Promise { * Fetch the username from a user * @param user A user can be either a uuid or a username */ -export async function usernameFromUser(user: string): Promise { +export async function usernameFromUser(user: string): Promise { if (usernameCache.has(undashUuid(user))) { if (debug) console.debug('Cache hit! usernameFromUser', user) - return usernameCache.get(undashUuid(user)) + return usernameCache.get(undashUuid(user)) ?? null } if (debug) console.debug('Cache miss: usernameFromUser', user) let { uuid, username } = await mojang.profileFromUser(user) + if (!uuid) return null uuid = undashUuid(uuid) usernameCache.set(uuid, username) return username @@ -152,12 +153,12 @@ export async function usernameFromUser(user: string): Promise { let fetchingPlayers: Set = new Set() -export async function fetchPlayer(user: string): Promise { +export async function fetchPlayer(user: string): Promise { const playerUuid = await uuidFromUser(user) - + if (!playerUuid) return null if (playerCache.has(playerUuid)) - return playerCache.get(playerUuid) + return playerCache.get(playerUuid)! // if it's already in the process of fetching, check every 100ms until it's not fetching the player anymore and fetch it again, since it'll be cached now if (fetchingPlayers.has(playerUuid)) { @@ -176,7 +177,7 @@ export async function fetchPlayer(user: string): Promise { fetchingPlayers.delete(playerUuid) - if (!cleanPlayer) return + if (!cleanPlayer) return null // clone in case it gets modified somehow later playerCache.set(playerUuid, cleanPlayer) @@ -190,14 +191,19 @@ export async function fetchPlayer(user: string): Promise { } /** Fetch a player without their profiles. This is heavily cached. */ -export async function fetchBasicPlayer(user: string): Promise { +export async function fetchBasicPlayer(user: string): Promise { const playerUuid = await uuidFromUser(user) + if (!playerUuid) return null + if (basicPlayerCache.has(playerUuid)) - return basicPlayerCache.get(playerUuid) + return basicPlayerCache.get(playerUuid)! const player = await fetchPlayer(playerUuid) - if (!player) console.debug('no player? this should never happen', user, playerUuid) + if (!player) { + console.debug('no player? this should never happen', user, playerUuid) + return null + } delete player.profiles return player @@ -206,7 +212,7 @@ export async function fetchBasicPlayer(user: string): Promise { export async function fetchSkyblockProfiles(playerUuid: string): Promise { if (profilesCache.has(playerUuid)) { if (debug) console.debug('Cache hit! fetchSkyblockProfiles', playerUuid) - return profilesCache.get(playerUuid) + return profilesCache.get(playerUuid)! } if (debug) console.debug('Cache miss: fetchSkyblockProfiles', playerUuid) @@ -220,7 +226,7 @@ export async function fetchSkyblockProfiles(playerUuid: string): Promise { + members: profile.members?.map(m => { return { uuid: m.uuid, username: m.username, @@ -240,14 +246,14 @@ export async function fetchSkyblockProfiles(playerUuid: string): Promise { +async function fetchBasicProfiles(user: string): Promise { const playerUuid = await uuidFromUser(user) - if (!playerUuid) return // invalid player, just return + if (!playerUuid) return null // invalid player, just return if (basicProfilesCache.has(playerUuid)) { if (debug) console.debug('Cache hit! fetchBasicProfiles', playerUuid) - return basicProfilesCache.get(playerUuid) + return basicProfilesCache.get(playerUuid)! } if (debug) console.debug('Cache miss: fetchBasicProfiles', user) @@ -259,6 +265,7 @@ async function fetchBasicProfiles(user: string): Promise { } const profiles = player.profiles basicProfilesCache.set(playerUuid, profiles) + if (!profiles) return null // cache the profile names and uuids to profileNameCache because we can for (const profile of profiles) @@ -272,7 +279,7 @@ async function fetchBasicProfiles(user: string): Promise { * @param user A username or uuid * @param profile A profile name or profile uuid */ -export async function fetchProfileUuid(user: string, profile: string): Promise { +export async function fetchProfileUuid(user: string, profile: string): Promise { // if a profile wasn't provided, return if (!profile) { if (debug) console.debug('no profile provided?', user, profile) @@ -282,12 +289,12 @@ export async function fetchProfileUuid(user: string, profile: string): Promise { +export async function fetchProfile(user: string, profile: string): Promise { const playerUuid = await uuidFromUser(user) + if (!playerUuid) return null const profileUuid = await fetchProfileUuid(playerUuid, profile) if (!profileUuid) return null @@ -309,13 +317,15 @@ export async function fetchProfile(user: string, profile: string): Promise { +export async function fetchBasicProfileFromUuid(profileUuid: string): Promise { if (profileCache.has(profileUuid)) { // we have the profile cached, return it :) if (debug) console.debug('Cache hit! fetchBasicProfileFromUuid', profileUuid) - const profile: CleanFullProfile = profileCache.get(profileUuid) + const profile: CleanFullProfile | undefined = profileCache.get(profileUuid) + if (!profile) return undefined return { uuid: profile.uuid, members: profile.members.map(m => ({ @@ -357,26 +368,32 @@ export async function fetchBasicProfileFromUuid(profileUuid: string): Promise { +export async function fetchProfileName(user: string, profile: string): Promise { // we're fetching the profile and player uuid again in case we were given a name, but it's cached so it's not much of a problem const profileUuid = await fetchProfileUuid(user, profile) - if (!profileUuid) - return null + if (!profileUuid) return null + const playerUuid = await uuidFromUser(user) + if (!playerUuid) return null + if (profileNameCache.has(`${playerUuid}.${profileUuid}`)) { // Return the profile name if it's cached if (debug) console.debug('Cache hit! fetchProfileName', profileUuid) - return profileNameCache.get(`${playerUuid}.${profileUuid}`) + return profileNameCache.get!(`${playerUuid}.${profileUuid}`) ?? null } if (debug) console.debug('Cache miss: fetchProfileName', user, profile) const basicProfiles = await fetchBasicProfiles(playerUuid) - let profileName + + if (!basicProfiles) return null + + let profileName: string | null = null + for (const basicProfile of basicProfiles) if (basicProfile.uuid === playerUuid) - profileName = basicProfile.name + profileName = basicProfile.name ?? null profileNameCache.set(`${playerUuid}.${profileUuid}`, profileName) return profileName -- cgit