From 5bf6a14cff411c1310fe04bb2ddeed0835928802 Mon Sep 17 00:00:00 2001 From: tresabhi <43380238+tresabhi@users.noreply.github.com> Date: Wed, 20 Nov 2024 10:50:09 -0600 Subject: [PATCH] fix: some rating functionality --- packages/bot/src/commands/rating.tsx | 13 +-- .../bot/src/commands/ratingLeaderboard.tsx | 80 +++++++++++-------- .../bot/src/events/interactionCreate/index.ts | 6 +- packages/core/src/blitz/getRatingInfo.ts | 55 ++++++++----- packages/core/src/blitz/index.ts | 2 +- packages/core/src/blitz/rating.ts | 10 +-- .../blitzkit/getArchivedRatingLeaderboard.ts | 15 +--- .../getArchivedRatingMidnightLeaderboard.ts | 32 -------- packages/core/src/blitzkit/index.ts | 2 +- 9 files changed, 104 insertions(+), 111 deletions(-) delete mode 100644 packages/core/src/blitzkit/getArchivedRatingMidnightLeaderboard.ts diff --git a/packages/bot/src/commands/rating.tsx b/packages/bot/src/commands/rating.tsx index afbe9a0c4..29ddaf439 100644 --- a/packages/bot/src/commands/rating.tsx +++ b/packages/bot/src/commands/rating.tsx @@ -1,9 +1,8 @@ import { - BkrlFormat, deltaBkrlBlitzStats, emblemURL, getAccountInfo, - getArchivedRatingMidnightLeaderboard, + getArchivedRatingLeaderboard, getClanAccountInfo, getLeagueFromScore, getRatingInfo, @@ -64,12 +63,12 @@ export const ratingCommand = new Promise((resolve) => { throw new Error(`Rating info not available for ${region}`); } - const leaderboard = await getArchivedRatingMidnightLeaderboard( + const leaderboard = await getArchivedRatingLeaderboard( region, ratingInfo.current_season - (subcommand === 'today' ? 0 : 1), ); - if (leaderboard?.format === BkrlFormat.Base) { + if (leaderboard.version!.$case === 'v1') { throw new Error( 'Encountered bkrl minimal format in latest season. Wait till next cron?', ); @@ -78,10 +77,12 @@ export const ratingCommand = new Promise((resolve) => { const accountInfo = await getAccountInfo(region, id, [ 'statistics.rating', ]); - const statsIndex = leaderboard?.entries.findIndex( + const statsIndex = leaderboard.version!.value.entries.findIndex( (entry) => entry.id === id, ); - const statsA = leaderboard ? leaderboard.entries[statsIndex!] : null; + const statsA = leaderboard + ? leaderboard.version!.value.entries[statsIndex!] + : null; const positionA = leaderboard ? statsIndex! + 1 : undefined; const statsB1 = accountInfo.statistics.rating!; const statsB2Array = (await getRatingNeighbors(region, id, 0)).neighbors; diff --git a/packages/bot/src/commands/ratingLeaderboard.tsx b/packages/bot/src/commands/ratingLeaderboard.tsx index 5f527b7d2..4e73f69ce 100644 --- a/packages/bot/src/commands/ratingLeaderboard.tsx +++ b/packages/bot/src/commands/ratingLeaderboard.tsx @@ -1,16 +1,18 @@ import { - BkrlDiscriminatedEntries, FIRST_MINIMAL_ARCHIVED_RATING_SEASON, getAccountInfo, getArchivedLatestSeasonNumber, getArchivedRatingLeaderboard, - getArchivedRatingMidnightLeaderboard, getClanAccountInfo, + getLeagueFromScore, getRatingInfo, getRatingLeague, getRatingNeighbors, + imgur, isOnGoingRatingSeason, LEAGUES, + RatingInfo, + RatingLeaderboard, Region, } from '@blitzkit/core'; import { @@ -199,9 +201,9 @@ export const ratingLeaderboardCommand = new Promise( let titleDescription: string; let playersAfter: number; let players: SimplifiedPlayer[] | undefined; - let midnightLeaderboard: BkrlDiscriminatedEntries | null; + let archivedLeaderboard: RatingLeaderboard | null; let playerId: number | undefined; - let regionRatingInfo: RatingInfo; + let regionRatingInfo: RatingInfo | null; if (subcommand === 'league') { const leagueIndex = parseInt( @@ -210,10 +212,14 @@ export const ratingLeaderboardCommand = new Promise( const region = interaction.options.getString('region') as Region; regionRatingInfo = await (isCurrentSeason ? getRatingInfo(region) - : getArchivedRatingInfo(region, season!)); + : null); - if (regionRatingInfo.detail !== undefined) + if ( + regionRatingInfo !== null && + regionRatingInfo.detail !== undefined + ) { return t`bot.commands.rating_leaderboard.body.no_ongoing_season`; + } const result = isCurrentSeason ? await getRatingLeague(region, leagueIndex).then(async (result) => @@ -233,12 +239,12 @@ export const ratingLeaderboardCommand = new Promise( const firstPlayerIndex = leagueIndex === 0 ? 0 - : players.entries.findIndex( + : players.version!.value.entries.findIndex( (player) => player.score < LEAGUES[leagueIndex - 1].minScore, ); const lastPlayerIndex = firstPlayerIndex + limit - 1; - const trimmed = players.entries.slice( + const trimmed = players.version!.value.entries.slice( firstPlayerIndex, lastPlayerIndex + 1, ); @@ -265,25 +271,24 @@ export const ratingLeaderboardCommand = new Promise( ); }, ); - const leagueInfo = regionRatingInfo.leagues[leagueIndex]; - midnightLeaderboard = isCurrentSeason - ? await getArchivedRatingMidnightLeaderboard( - region, - regionRatingInfo.current_season, - ) - : await getArchivedRatingMidnightLeaderboard(region, season!); + const score = result.find(({ id }) => id === playerId)!.score; + const leagueInfo = getLeagueFromScore(score); + archivedLeaderboard = await getArchivedRatingLeaderboard( + region, + season, + ); players = result; playersAfter = - regionRatingInfo.count - result[result.length - 1].position; + (regionRatingInfo === null + ? archivedLeaderboard.version!.value.entries.length + : regionRatingInfo.count) - result[result.length - 1].position; titleName = `${ leagueInfo ? translate(`common.leagues.${LEAGUES[leagueInfo.index].name}`) : '' } - ${translate(`common.regions.short.${region}`)}`; - titleImage = leagueInfo.big_icon.startsWith('http') - ? leagueInfo.big_icon - : `https:${leagueInfo.big_icon}`; + titleImage = imgur(leagueInfo.icon); titleDescription = translate( 'bot.commands.rating_leaderboard.body.top_players', [`${limit}`], @@ -292,10 +297,14 @@ export const ratingLeaderboardCommand = new Promise( const { region, id } = await resolvePlayerFromCommand(interaction); regionRatingInfo = isCurrentSeason ? await getRatingInfo(region) - : await getArchivedRatingInfo(region, season!); + : null; - if (regionRatingInfo.detail !== undefined) + if ( + regionRatingInfo !== null && + regionRatingInfo.detail !== undefined + ) { return t`bot.commands.rating_leaderboard.body.no_ongoing_season`; + } const accountInfo = await getAccountInfo(region, id); const clan = (await getClanAccountInfo(region, id, ['clan']))?.clan; @@ -315,7 +324,7 @@ export const ratingLeaderboardCommand = new Promise( ) : await getArchivedRatingLeaderboard(region, season!).then( async (players) => { - const playerIndex = players.entries.findIndex( + const playerIndex = players.version!.value.entries.findIndex( (player) => player.id === id, ); @@ -329,7 +338,7 @@ export const ratingLeaderboardCommand = new Promise( } const halfRange = Math.round(limit / 2); - const trimmed = players.entries.slice( + const trimmed = players.version!.value.entries.slice( playerIndex - halfRange, playerIndex + halfRange + 1, ); @@ -350,12 +359,10 @@ export const ratingLeaderboardCommand = new Promise( })); }, ); - midnightLeaderboard = isCurrentSeason - ? await getArchivedRatingMidnightLeaderboard( - region, - regionRatingInfo.current_season, - ) - : await getArchivedRatingMidnightLeaderboard(region, season!); + archivedLeaderboard = await getArchivedRatingLeaderboard( + region, + season, + ); players = neighbors; titleImage = clan @@ -364,18 +371,23 @@ export const ratingLeaderboardCommand = new Promise( titleName = neighbors ? accountInfo.nickname : ''; titleDescription = t`bot.commands.rating_leaderboard.body.neighbors`; playersAfter = - regionRatingInfo.count - neighbors[neighbors.length - 1].position; + (regionRatingInfo === null + ? archivedLeaderboard.version!.value.entries.length + : regionRatingInfo.count) - + neighbors[neighbors.length - 1].position; playerId = id; } const items = players.map((player) => { - const midnightIndex = midnightLeaderboard?.entries.findIndex( - (item) => item.id === player.id, - ); + const midnightIndex = + archivedLeaderboard?.version!.value.entries.findIndex( + (item) => item.id === player.id, + ); const midnightScore = midnightIndex === undefined ? player.score - : midnightLeaderboard!.entries[midnightIndex].score; + : archivedLeaderboard!.version!.value.entries[midnightIndex] + .score; const midnightPosition = midnightIndex === undefined ? player.position : midnightIndex + 1; diff --git a/packages/bot/src/events/interactionCreate/index.ts b/packages/bot/src/events/interactionCreate/index.ts index 7325b6d64..6b8d84021 100644 --- a/packages/bot/src/events/interactionCreate/index.ts +++ b/packages/bot/src/events/interactionCreate/index.ts @@ -25,6 +25,8 @@ import { ownedTanksCommand } from '../../commands/ownedTanks'; import { permissionsCommand } from '../../commands/permissions'; import { pingCommand } from '../../commands/ping'; import { playerInfoCommand } from '../../commands/playerInfo'; +import { ratingCommand } from '../../commands/rating'; +import { ratingLeaderboardCommand } from '../../commands/ratingLeaderboard'; import { replayCommand } from '../../commands/replay'; import { researchCommand } from '../../commands/research'; import { searchClansCommand } from '../../commands/searchClans'; @@ -88,10 +90,10 @@ export const COMMANDS_RAW: Promise[] = [ pingCommand, evolutionCommand, statsCommand, - // ratingLeaderboardCommand, + ratingLeaderboardCommand, todayCommand, researchCommand, - // ratingCommand, + ratingCommand, replayCommand, ]; diff --git a/packages/core/src/blitz/getRatingInfo.ts b/packages/core/src/blitz/getRatingInfo.ts index d778ea600..afe2f96dc 100644 --- a/packages/core/src/blitz/getRatingInfo.ts +++ b/packages/core/src/blitz/getRatingInfo.ts @@ -1,24 +1,41 @@ -// import { Region } from '@blitzkit/core'; -// import { context } from '../blitzkit/context'; -// import { patientFetch } from '../blitzkit/patientFetch'; -// import { regionToRegionSubdomain } from './regionToRegionSubdomain'; +import { RatingLeague, RatingReward, Region } from '@blitzkit/core'; +import { context } from '../blitzkit/context'; +import { patientFetch } from '../blitzkit/patientFetch'; +import { regionToRegionSubdomain } from './regionToRegionSubdomain'; -// const cache: Partial> = {}; +export type RatingInfo = + | { + detail: undefined; -// export async function getRatingInfo(region: Region) { -// if (cache[region]) return cache[region]!; + title: string; + icon: string | null; + start_at: string; + finish_at: string; + current_season: number; + updated_at: string; + count: number; -// const response = await patientFetch( -// context === 'website' -// ? `/api/${region}/rating/current/info` -// : `https://${regionToRegionSubdomain( -// region, -// )}.wotblitz.com/en/api/rating-leaderboards/season/`, -// undefined, -// ); -// const data = (await response.json()) as RatingInfo; + rewards: RatingReward[]; + leagues: RatingLeague[]; + } + | { detail: { error: string } }; -// cache[region] = data; +const cache: Partial> = {}; -// return data; -// } +export async function getRatingInfo(region: Region) { + if (cache[region]) return cache[region]!; + + const response = await patientFetch( + context === 'website' + ? `/api/${region}/rating/current/info` + : `https://${regionToRegionSubdomain( + region, + )}.wotblitz.com/en/api/rating-leaderboards/season/`, + undefined, + ); + const data = (await response.json()) as RatingInfo; + + cache[region] = data; + + return data; +} diff --git a/packages/core/src/blitz/index.ts b/packages/core/src/blitz/index.ts index e69009f61..aa2aadf58 100644 --- a/packages/core/src/blitz/index.ts +++ b/packages/core/src/blitz/index.ts @@ -9,7 +9,7 @@ export * from './getAccountInfo'; export * from './getClanAccountInfo'; export * from './getClanInfo'; export * from './getLeagueFromScore'; -// export * from './getRatingInfo'; +export * from './getRatingInfo'; export * from './getRatingLeague'; export * from './getRatingNeighbors'; export * from './getTankStats'; diff --git a/packages/core/src/blitz/rating.ts b/packages/core/src/blitz/rating.ts index 7f5365880..ed6a6c70b 100644 --- a/packages/core/src/blitz/rating.ts +++ b/packages/core/src/blitz/rating.ts @@ -1,11 +1,11 @@ import { RatingPlayer } from '../statistics'; export const LEAGUES = [ - { name: 'diamond', minScore: 5000, index: 0 }, - { name: 'platinum', minScore: 4000, index: 1 }, - { name: 'gold', minScore: 3000, index: 2 }, - { name: 'silver', minScore: 2000, index: 3 }, - { name: 'bronze', minScore: -Infinity, index: 4 }, + { name: 'diamond', minScore: 5000, index: 0, icon: 'YOw6mZ4' }, + { name: 'platinum', minScore: 4000, index: 1, icon: 'AOzDENm' }, + { name: 'gold', minScore: 3000, index: 2, icon: 'InVGtQy' }, + { name: 'silver', minScore: 2000, index: 3, icon: 'HD4ADcL' }, + { name: 'bronze', minScore: -Infinity, index: 4, icon: 'Ka4nNyv' }, ]; export interface RatingNeighbors { neighbors: RatingPlayer[]; diff --git a/packages/core/src/blitzkit/getArchivedRatingLeaderboard.ts b/packages/core/src/blitzkit/getArchivedRatingLeaderboard.ts index 0991d783c..4eee07a1b 100644 --- a/packages/core/src/blitzkit/getArchivedRatingLeaderboard.ts +++ b/packages/core/src/blitzkit/getArchivedRatingLeaderboard.ts @@ -1,11 +1,6 @@ -import { - asset, - BkrlDiscriminatedEntries, - BkrlReadStream, - Region, -} from '@blitzkit/core'; +import { asset, RatingLeaderboard, Region } from '@blitzkit/core'; -const cache: Record> = { +const cache: Record> = { asia: {}, eu: {}, com: {}, @@ -16,11 +11,9 @@ export async function getArchivedRatingLeaderboard( season: number, ) { if (!cache[region][season]) { - const info = await fetch( - asset(`regions/${region}/rating/${season}/latest.bkrl`), - ) + const info = await fetch(asset(`regions/${region}/rating/${season}.pb`)) .then((response) => response.arrayBuffer()) - .then((buffer) => new BkrlReadStream(buffer).bkrl()); + .then((buffer) => RatingLeaderboard.decode(new Uint8Array(buffer))); cache[region][season] = info; } diff --git a/packages/core/src/blitzkit/getArchivedRatingMidnightLeaderboard.ts b/packages/core/src/blitzkit/getArchivedRatingMidnightLeaderboard.ts deleted file mode 100644 index d40df8ea1..000000000 --- a/packages/core/src/blitzkit/getArchivedRatingMidnightLeaderboard.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { - asset, - BkrlDiscriminatedEntries, - BkrlReadStream, - Region, -} from '@blitzkit/core'; - -const cache: Record> = { - com: {}, - eu: {}, - asia: {}, -}; - -export async function getArchivedRatingMidnightLeaderboard( - region: Region, - season: number, -) { - if (!cache[region][season]) { - const info = await fetch( - asset(`regions/${region}/rating/${season}/midnight.bkrl`), - ) - .then((response) => - response.status === 404 ? null : response.arrayBuffer(), - ) - .then((buffer) => - buffer === null ? null : new BkrlReadStream(buffer).bkrl(), - ); - cache[region][season] = info; - } - - return cache[region][season]; -} diff --git a/packages/core/src/blitzkit/index.ts b/packages/core/src/blitzkit/index.ts index 496b1330d..955b6d924 100644 --- a/packages/core/src/blitzkit/index.ts +++ b/packages/core/src/blitzkit/index.ts @@ -18,7 +18,7 @@ export * from './gameDefinitions'; export * from './getArchivedLatestSeasonNumber'; // export * from './getArchivedRatingInfo'; export * from './getArchivedRatingLeaderboard'; -export * from './getArchivedRatingMidnightLeaderboard'; +// export * from './getArchivedRatingMidnightLeaderboard'; export * from './getTimeDaysAgo'; export * from './isExplosive'; export * from './linkBlitzAndDiscord';