fix: some rating functionality

This commit is contained in:
tresabhi committed 2024-11-20 10:50:09 -06:00
1 parent fcb848df5b
commit 5bf6a14cff
9 files changed
+104 -111

No files matched your search

+7 -6
View File
@@ -1,9 +1,8 @@
import { import {
BkrlFormat,
deltaBkrlBlitzStats, deltaBkrlBlitzStats,
emblemURL, emblemURL,
getAccountInfo, getAccountInfo,
getArchivedRatingMidnightLeaderboard, getArchivedRatingLeaderboard,
getClanAccountInfo, getClanAccountInfo,
getLeagueFromScore, getLeagueFromScore,
getRatingInfo, getRatingInfo,
@@ -64,12 +63,12 @@ export const ratingCommand = new Promise<CommandRegistry>((resolve) => {
throw new Error(`Rating info not available for ${region}`); throw new Error(`Rating info not available for ${region}`);
} }
const leaderboard = await getArchivedRatingMidnightLeaderboard( const leaderboard = await getArchivedRatingLeaderboard(
region, region,
ratingInfo.current_season - (subcommand === 'today' ? 0 : 1), ratingInfo.current_season - (subcommand === 'today' ? 0 : 1),
); );
if (leaderboard?.format === BkrlFormat.Base) { if (leaderboard.version!.$case === 'v1') {
throw new Error( throw new Error(
'Encountered bkrl minimal format in latest season. Wait till next cron?', 'Encountered bkrl minimal format in latest season. Wait till next cron?',
); );
@@ -78,10 +77,12 @@ export const ratingCommand = new Promise<CommandRegistry>((resolve) => {
const accountInfo = await getAccountInfo(region, id, [ const accountInfo = await getAccountInfo(region, id, [
'statistics.rating', 'statistics.rating',
]); ]);
const statsIndex = leaderboard?.entries.findIndex( const statsIndex = leaderboard.version!.value.entries.findIndex(
(entry) => entry.id === id, (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 positionA = leaderboard ? statsIndex! + 1 : undefined;
const statsB1 = accountInfo.statistics.rating!; const statsB1 = accountInfo.statistics.rating!;
const statsB2Array = (await getRatingNeighbors(region, id, 0)).neighbors; const statsB2Array = (await getRatingNeighbors(region, id, 0)).neighbors;
+46 -34
View File
@@ -1,16 +1,18 @@
import { import {
BkrlDiscriminatedEntries,
FIRST_MINIMAL_ARCHIVED_RATING_SEASON, FIRST_MINIMAL_ARCHIVED_RATING_SEASON,
getAccountInfo, getAccountInfo,
getArchivedLatestSeasonNumber, getArchivedLatestSeasonNumber,
getArchivedRatingLeaderboard, getArchivedRatingLeaderboard,
getArchivedRatingMidnightLeaderboard,
getClanAccountInfo, getClanAccountInfo,
getLeagueFromScore,
getRatingInfo, getRatingInfo,
getRatingLeague, getRatingLeague,
getRatingNeighbors, getRatingNeighbors,
imgur,
isOnGoingRatingSeason, isOnGoingRatingSeason,
LEAGUES, LEAGUES,
RatingInfo,
RatingLeaderboard,
Region, Region,
} from '@blitzkit/core'; } from '@blitzkit/core';
import { import {
@@ -199,9 +201,9 @@ export const ratingLeaderboardCommand = new Promise<CommandRegistry>(
let titleDescription: string; let titleDescription: string;
let playersAfter: number; let playersAfter: number;
let players: SimplifiedPlayer[] | undefined; let players: SimplifiedPlayer[] | undefined;
let midnightLeaderboard: BkrlDiscriminatedEntries | null; let archivedLeaderboard: RatingLeaderboard | null;
let playerId: number | undefined; let playerId: number | undefined;
let regionRatingInfo: RatingInfo; let regionRatingInfo: RatingInfo | null;
if (subcommand === 'league') { if (subcommand === 'league') {
const leagueIndex = parseInt( const leagueIndex = parseInt(
@@ -210,10 +212,14 @@ export const ratingLeaderboardCommand = new Promise<CommandRegistry>(
const region = interaction.options.getString('region') as Region; const region = interaction.options.getString('region') as Region;
regionRatingInfo = await (isCurrentSeason regionRatingInfo = await (isCurrentSeason
? getRatingInfo(region) ? 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`; return t`bot.commands.rating_leaderboard.body.no_ongoing_season`;
}
const result = isCurrentSeason const result = isCurrentSeason
? await getRatingLeague(region, leagueIndex).then(async (result) => ? await getRatingLeague(region, leagueIndex).then(async (result) =>
@@ -233,12 +239,12 @@ export const ratingLeaderboardCommand = new Promise<CommandRegistry>(
const firstPlayerIndex = const firstPlayerIndex =
leagueIndex === 0 leagueIndex === 0
? 0 ? 0
: players.entries.findIndex( : players.version!.value.entries.findIndex(
(player) => (player) =>
player.score < LEAGUES[leagueIndex - 1].minScore, player.score < LEAGUES[leagueIndex - 1].minScore,
); );
const lastPlayerIndex = firstPlayerIndex + limit - 1; const lastPlayerIndex = firstPlayerIndex + limit - 1;
const trimmed = players.entries.slice( const trimmed = players.version!.value.entries.slice(
firstPlayerIndex, firstPlayerIndex,
lastPlayerIndex + 1, lastPlayerIndex + 1,
); );
@@ -265,25 +271,24 @@ export const ratingLeaderboardCommand = new Promise<CommandRegistry>(
); );
}, },
); );
const leagueInfo = regionRatingInfo.leagues[leagueIndex]; const score = result.find(({ id }) => id === playerId)!.score;
midnightLeaderboard = isCurrentSeason const leagueInfo = getLeagueFromScore(score);
? await getArchivedRatingMidnightLeaderboard( archivedLeaderboard = await getArchivedRatingLeaderboard(
region, region,
regionRatingInfo.current_season, season,
) );
: await getArchivedRatingMidnightLeaderboard(region, season!);
players = result; players = result;
playersAfter = playersAfter =
regionRatingInfo.count - result[result.length - 1].position; (regionRatingInfo === null
? archivedLeaderboard.version!.value.entries.length
: regionRatingInfo.count) - result[result.length - 1].position;
titleName = `${ titleName = `${
leagueInfo leagueInfo
? translate(`common.leagues.${LEAGUES[leagueInfo.index].name}`) ? translate(`common.leagues.${LEAGUES[leagueInfo.index].name}`)
: '' : ''
} - ${translate(`common.regions.short.${region}`)}`; } - ${translate(`common.regions.short.${region}`)}`;
titleImage = leagueInfo.big_icon.startsWith('http') titleImage = imgur(leagueInfo.icon);
? leagueInfo.big_icon
: `https:${leagueInfo.big_icon}`;
titleDescription = translate( titleDescription = translate(
'bot.commands.rating_leaderboard.body.top_players', 'bot.commands.rating_leaderboard.body.top_players',
[`${limit}`], [`${limit}`],
@@ -292,10 +297,14 @@ export const ratingLeaderboardCommand = new Promise<CommandRegistry>(
const { region, id } = await resolvePlayerFromCommand(interaction); const { region, id } = await resolvePlayerFromCommand(interaction);
regionRatingInfo = isCurrentSeason regionRatingInfo = isCurrentSeason
? await getRatingInfo(region) ? 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`; return t`bot.commands.rating_leaderboard.body.no_ongoing_season`;
}
const accountInfo = await getAccountInfo(region, id); const accountInfo = await getAccountInfo(region, id);
const clan = (await getClanAccountInfo(region, id, ['clan']))?.clan; const clan = (await getClanAccountInfo(region, id, ['clan']))?.clan;
@@ -315,7 +324,7 @@ export const ratingLeaderboardCommand = new Promise<CommandRegistry>(
) )
: await getArchivedRatingLeaderboard(region, season!).then( : await getArchivedRatingLeaderboard(region, season!).then(
async (players) => { async (players) => {
const playerIndex = players.entries.findIndex( const playerIndex = players.version!.value.entries.findIndex(
(player) => player.id === id, (player) => player.id === id,
); );
@@ -329,7 +338,7 @@ export const ratingLeaderboardCommand = new Promise<CommandRegistry>(
} }
const halfRange = Math.round(limit / 2); const halfRange = Math.round(limit / 2);
const trimmed = players.entries.slice( const trimmed = players.version!.value.entries.slice(
playerIndex - halfRange, playerIndex - halfRange,
playerIndex + halfRange + 1, playerIndex + halfRange + 1,
); );
@@ -350,12 +359,10 @@ export const ratingLeaderboardCommand = new Promise<CommandRegistry>(
})); }));
}, },
); );
midnightLeaderboard = isCurrentSeason archivedLeaderboard = await getArchivedRatingLeaderboard(
? await getArchivedRatingMidnightLeaderboard( region,
region, season,
regionRatingInfo.current_season, );
)
: await getArchivedRatingMidnightLeaderboard(region, season!);
players = neighbors; players = neighbors;
titleImage = clan titleImage = clan
@@ -364,18 +371,23 @@ export const ratingLeaderboardCommand = new Promise<CommandRegistry>(
titleName = neighbors ? accountInfo.nickname : ''; titleName = neighbors ? accountInfo.nickname : '';
titleDescription = t`bot.commands.rating_leaderboard.body.neighbors`; titleDescription = t`bot.commands.rating_leaderboard.body.neighbors`;
playersAfter = playersAfter =
regionRatingInfo.count - neighbors[neighbors.length - 1].position; (regionRatingInfo === null
? archivedLeaderboard.version!.value.entries.length
: regionRatingInfo.count) -
neighbors[neighbors.length - 1].position;
playerId = id; playerId = id;
} }
const items = players.map((player) => { const items = players.map((player) => {
const midnightIndex = midnightLeaderboard?.entries.findIndex( const midnightIndex =
(item) => item.id === player.id, archivedLeaderboard?.version!.value.entries.findIndex(
); (item) => item.id === player.id,
);
const midnightScore = const midnightScore =
midnightIndex === undefined midnightIndex === undefined
? player.score ? player.score
: midnightLeaderboard!.entries[midnightIndex].score; : archivedLeaderboard!.version!.value.entries[midnightIndex]
.score;
const midnightPosition = const midnightPosition =
midnightIndex === undefined ? player.position : midnightIndex + 1; midnightIndex === undefined ? player.position : midnightIndex + 1;
@@ -25,6 +25,8 @@ import { ownedTanksCommand } from '../../commands/ownedTanks';
import { permissionsCommand } from '../../commands/permissions'; import { permissionsCommand } from '../../commands/permissions';
import { pingCommand } from '../../commands/ping'; import { pingCommand } from '../../commands/ping';
import { playerInfoCommand } from '../../commands/playerInfo'; import { playerInfoCommand } from '../../commands/playerInfo';
import { ratingCommand } from '../../commands/rating';
import { ratingLeaderboardCommand } from '../../commands/ratingLeaderboard';
import { replayCommand } from '../../commands/replay'; import { replayCommand } from '../../commands/replay';
import { researchCommand } from '../../commands/research'; import { researchCommand } from '../../commands/research';
import { searchClansCommand } from '../../commands/searchClans'; import { searchClansCommand } from '../../commands/searchClans';
@@ -88,10 +90,10 @@ export const COMMANDS_RAW: Promise<CommandRegistry>[] = [
pingCommand, pingCommand,
evolutionCommand, evolutionCommand,
statsCommand, statsCommand,
// ratingLeaderboardCommand, ratingLeaderboardCommand,
todayCommand, todayCommand,
researchCommand, researchCommand,
// ratingCommand, ratingCommand,
replayCommand, replayCommand,
]; ];
+36 -19
View File
@@ -1,24 +1,41 @@
// import { Region } from '@blitzkit/core'; import { RatingLeague, RatingReward, Region } from '@blitzkit/core';
// import { context } from '../blitzkit/context'; import { context } from '../blitzkit/context';
// import { patientFetch } from '../blitzkit/patientFetch'; import { patientFetch } from '../blitzkit/patientFetch';
// import { regionToRegionSubdomain } from './regionToRegionSubdomain'; import { regionToRegionSubdomain } from './regionToRegionSubdomain';
// const cache: Partial<Record<Region, RatingInfo>> = {}; export type RatingInfo =
| {
detail: undefined;
// export async function getRatingInfo(region: Region) { title: string;
// if (cache[region]) return cache[region]!; icon: string | null;
start_at: string;
finish_at: string;
current_season: number;
updated_at: string;
count: number;
// const response = await patientFetch( rewards: RatingReward[];
// context === 'website' leagues: RatingLeague[];
// ? `/api/${region}/rating/current/info` }
// : `https://${regionToRegionSubdomain( | { detail: { error: string } };
// region,
// )}.wotblitz.com/en/api/rating-leaderboards/season/`,
// undefined,
// );
// const data = (await response.json()) as RatingInfo;
// cache[region] = data; const cache: Partial<Record<Region, RatingInfo>> = {};
// 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;
}
+1 -1
View File
@@ -9,7 +9,7 @@ export * from './getAccountInfo';
export * from './getClanAccountInfo'; export * from './getClanAccountInfo';
export * from './getClanInfo'; export * from './getClanInfo';
export * from './getLeagueFromScore'; export * from './getLeagueFromScore';
// export * from './getRatingInfo'; export * from './getRatingInfo';
export * from './getRatingLeague'; export * from './getRatingLeague';
export * from './getRatingNeighbors'; export * from './getRatingNeighbors';
export * from './getTankStats'; export * from './getTankStats';
+5 -5
View File
@@ -1,11 +1,11 @@
import { RatingPlayer } from '../statistics'; import { RatingPlayer } from '../statistics';
export const LEAGUES = [ export const LEAGUES = [
{ name: 'diamond', minScore: 5000, index: 0 }, { name: 'diamond', minScore: 5000, index: 0, icon: 'YOw6mZ4' },
{ name: 'platinum', minScore: 4000, index: 1 }, { name: 'platinum', minScore: 4000, index: 1, icon: 'AOzDENm' },
{ name: 'gold', minScore: 3000, index: 2 }, { name: 'gold', minScore: 3000, index: 2, icon: 'InVGtQy' },
{ name: 'silver', minScore: 2000, index: 3 }, { name: 'silver', minScore: 2000, index: 3, icon: 'HD4ADcL' },
{ name: 'bronze', minScore: -Infinity, index: 4 }, { name: 'bronze', minScore: -Infinity, index: 4, icon: 'Ka4nNyv' },
]; ];
export interface RatingNeighbors { export interface RatingNeighbors {
neighbors: RatingPlayer[]; neighbors: RatingPlayer[];
@@ -1,11 +1,6 @@
import { import { asset, RatingLeaderboard, Region } from '@blitzkit/core';
asset,
BkrlDiscriminatedEntries,
BkrlReadStream,
Region,
} from '@blitzkit/core';
const cache: Record<Region, Record<number, BkrlDiscriminatedEntries>> = { const cache: Record<Region, Record<number, RatingLeaderboard>> = {
asia: {}, asia: {},
eu: {}, eu: {},
com: {}, com: {},
@@ -16,11 +11,9 @@ export async function getArchivedRatingLeaderboard(
season: number, season: number,
) { ) {
if (!cache[region][season]) { if (!cache[region][season]) {
const info = await fetch( const info = await fetch(asset(`regions/${region}/rating/${season}.pb`))
asset(`regions/${region}/rating/${season}/latest.bkrl`),
)
.then((response) => response.arrayBuffer()) .then((response) => response.arrayBuffer())
.then((buffer) => new BkrlReadStream(buffer).bkrl()); .then((buffer) => RatingLeaderboard.decode(new Uint8Array(buffer)));
cache[region][season] = info; cache[region][season] = info;
} }
@@ -1,32 +0,0 @@
import {
asset,
BkrlDiscriminatedEntries,
BkrlReadStream,
Region,
} from '@blitzkit/core';
const cache: Record<Region, Record<number, BkrlDiscriminatedEntries | null>> = {
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];
}
+1 -1
View File
@@ -18,7 +18,7 @@ export * from './gameDefinitions';
export * from './getArchivedLatestSeasonNumber'; export * from './getArchivedLatestSeasonNumber';
// export * from './getArchivedRatingInfo'; // export * from './getArchivedRatingInfo';
export * from './getArchivedRatingLeaderboard'; export * from './getArchivedRatingLeaderboard';
export * from './getArchivedRatingMidnightLeaderboard'; // export * from './getArchivedRatingMidnightLeaderboard';
export * from './getTimeDaysAgo'; export * from './getTimeDaysAgo';
export * from './isExplosive'; export * from './isExplosive';
export * from './linkBlitzAndDiscord'; export * from './linkBlitzAndDiscord';