diff --git a/packages/kol.js/src/Player.test.ts b/packages/kol.js/src/Player.test.ts index 6865676..b68c0c1 100644 --- a/packages/kol.js/src/Player.test.ts +++ b/packages/kol.js/src/Player.test.ts @@ -47,6 +47,8 @@ describe("Player searching", () => { // Learns correct capitalisation expect(player.name).toBe("Beldur"); expect(player.level).toBe(0); + // We display Astral Spirit even though the search page says Seal Clubber. + expect(player.kolClass).toBe("Astral Spirit"); }); }); diff --git a/packages/kol.js/src/Player.ts b/packages/kol.js/src/Player.ts index 1d36dd0..51e0bb2 100644 --- a/packages/kol.js/src/Player.ts +++ b/packages/kol.js/src/Player.ts @@ -98,12 +98,14 @@ export class Player { return null; } + const clazz = match.level ? match.class : "Astral Spirit"; + return new Player( client, Number(match.playerId), match.playerName, parseInt(match.level) || 0, - match.class, + clazz, ); } catch (error) { return null; diff --git a/packages/oaf/src/commands/kol/whois.ts b/packages/oaf/src/commands/kol/whois.ts index 29d0676..507bbf7 100644 --- a/packages/oaf/src/commands/kol/whois.ts +++ b/packages/oaf/src/commands/kol/whois.ts @@ -94,80 +94,86 @@ export async function execute(interaction: ChatInputCommandInteraction) { return; } + const astralSpirit = (player.level = 0); + const fields: APIEmbedField[] = [ { name: "Class", value: player.kolClass || "Unlisted" }, - { name: "Level", value: player.level.toString() }, - { + { name: "Level", value: astralSpirit ? "∞" : player.level.toString() }, + ]; + + const isOnline = await player.isOnline(); + + if (!astralSpirit) { + fields.push({ name: "Ascensions", value: hyperlink( player.ascensions.toLocaleString(), toKoldbLink(player.name), ), - }, - ]; + }); - if (player.favoriteFood) - fields.push({ name: "Favorite Food", value: player.favoriteFood }); - if (player.favoriteBooze) - fields.push({ name: "Favorite Booze", value: player.favoriteBooze }); + if (player.favoriteFood) + fields.push({ name: "Favorite Food", value: player.favoriteFood }); + if (player.favoriteBooze) + fields.push({ name: "Favorite Booze", value: player.favoriteBooze }); + + const lastLogin = (() => { + if (isOnline) return "Currently online"; + if (!player.lastLogin) return null; + // We don't want to get more specific than days, but the Discord relative time formatter will say silly things + // Like "8 hours ago" even if that player is logged in right now + if (player.lastLogin.getDay() === new Date().getDay()) return "Today"; + if (Date.now() - player.lastLogin.getTime() < 1000 * 60 * 60 * 24) + return "Yesterday"; + return time(player.lastLogin, "R"); + })(); + if (lastLogin) { + fields.push({ name: "Last Login", value: lastLogin }); + } - const isOnline = await player.isOnline(); - const lastLogin = (() => { - if (isOnline) return "Currently online"; - if (!player.lastLogin) return null; - // We don't want to get more specific than days, but the Discord relative time formatter will say silly things - // Like "8 hours ago" even if that player is logged in right now - if (player.lastLogin.getDay() === new Date().getDay()) return "Today"; - if (Date.now() - player.lastLogin.getTime() < 1000 * 60 * 60 * 24) - return "Yesterday"; - return time(player.lastLogin, "R"); - })(); - if (lastLogin) { - fields.push({ name: "Last Login", value: lastLogin }); - } + if (player.createdDate) + fields.push({ + name: "Account Created", + value: time(player.createdDate, "R"), + }); - if (player.createdDate) fields.push({ - name: "Account Created", - value: time(player.createdDate, "R"), + name: "Display Case", + value: player.hasDisplayCase + ? hyperlink("Browse", toMuseumLink(player.id)) + : italic("none"), }); - fields.push({ - name: "Display Case", - value: player.hasDisplayCase - ? hyperlink("Browse", toMuseumLink(player.id)) - : italic("none"), - }); + // Save a database hit if we got here by tracking a claimed Discord account in the first place + if (knownPlayer === null) + knownPlayer = await findPlayer({ playerId: player.id }); + + // Show different greenboxen services + const greenboxes = []; + if (knownPlayer?.greenbox) { + greenboxes.push( + `${hyperlink( + `Greenbox`, + `https://greenbox.loathers.net/?u=${player.id}`, + )} (updated ${time(knownPlayer.greenbox.createdAt, "R")})`, + ); + } + const snapshot = await snapshotClient.getInfo(player.name); + if (snapshot) { + greenboxes.push( + `${hyperlink(`Snapshot`, snapshot.link)} (updated ${time( + snapshot.date, + "R", + )})`, + ); + } - // Save a database hit if we got here by tracking a claimed Discord account in the first place - if (knownPlayer === null) - knownPlayer = await findPlayer({ playerId: player.id }); - - // Show different greenboxen services - const greenboxes = []; - if (knownPlayer?.greenbox) { - greenboxes.push( - `${hyperlink( - `Greenbox`, - `https://greenbox.loathers.net/?u=${player.id}`, - )} (updated ${time(knownPlayer.greenbox.createdAt, "R")})`, - ); - } - const snapshot = await snapshotClient.getInfo(player.name); - if (snapshot) { - greenboxes.push( - `${hyperlink(`Snapshot`, snapshot.link)} (updated ${time( - snapshot.date, - "R", - )})`, - ); + fields.push({ + name: "Greenboxes", + value: greenboxes.join(" / ") || italic("none"), + }); } - fields.push({ - name: "Greenboxes", - value: greenboxes.join(" / ") || italic("none"), - }); - // Use this opportunity to either // a) learn about a new player for our database, or // b) update player names either from name changes or capitalization changes