import { deltaBkrlBlitzStats, emblemURL, getAccountInfo, getArchivedRatingLeaderboard, getClanAccountInfo, getLeagueFromScore, getRatingInfo, getRatingNeighbors, imgur, } from "@blitzkit/core"; import { literals } from "@blitzkit/i18n"; import { SlashCommandSubcommandBuilder } from "discord.js"; import markdownEscape from "markdown-escape"; import { Glow } from "../components/AllStatsOverview/components/HeroStat/components/Glow"; import { CommandWrapper } from "../components/CommandWrapper"; import { DeltaCaret } from "../components/DeltaCaret"; import { TitleBar } from "../components/TitleBar"; import { normalizeLeagueIcon } from "../core/blitz/normalizeLeagueIcon"; import { iconPng } from "../core/blitzkit/iconPng"; import { addUsernameChoices } from "../core/discord/addUsernameChoices"; import { createLocalizedCommand } from "../core/discord/createLocalizedCommand"; import { resolvePlayerFromCommand } from "../core/discord/resolvePlayerFromCommand"; import { translator } from "../core/localization/translator"; import type { CommandRegistry } from "../events/interactionCreate"; import { theme } from "../stitches.config"; const LEAGUE_ACCENT = [ "_purple", "_sand", "_amber", "_mauve", "_brown", ] as const; export const ratingCommand = new Promise((resolve) => { resolve({ command: createLocalizedCommand("rating", [ { subcommand: "today", modify(option: SlashCommandSubcommandBuilder) { option.addStringOption(addUsernameChoices); }, }, { subcommand: "season", modify(option: SlashCommandSubcommandBuilder) { option.addStringOption(addUsernameChoices); }, }, ]), async handler(interaction) { const subcommand = interaction.options.getSubcommand(true) as | "season" | "today"; const { strings } = translator(interaction.locale); const { id, region } = await resolvePlayerFromCommand(interaction); const clan = (await getClanAccountInfo(region, id, ["clan"]))?.clan; const clanImage = clan ? emblemURL(clan.emblem_set_id) : undefined; const ratingInfo = await getRatingInfo(region); if (ratingInfo.detail) { throw new Error(`Rating info not available for ${region}`); } const leaderboard = await getArchivedRatingLeaderboard( region, ratingInfo.current_season - (subcommand === "today" ? 0 : 1) ); if (leaderboard.version!.$case === "v1") { throw new Error( "Encountered bkrl minimal format in latest season. Wait till next cron?" ); } const accountInfo = await getAccountInfo(region, id, [ "statistics.rating", ]); const statsIndex = leaderboard.version!.value.entries.findIndex( (entry) => entry.id === id ); 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; if (statsB2Array === undefined) { return literals(strings.bot.commands.rating.errors.no_participation, { name: markdownEscape(accountInfo.nickname), }); } const [statsB2] = statsB2Array; const league = getLeagueFromScore(statsB2.score); if (!statsA) { return strings.bot.commands.rating.errors.unrecorded_stats; } if (!statsB1) { return literals(strings.bot.commands.rating.errors.no_participation, { name: markdownEscape(accountInfo.nickname), }); } const reward = ratingInfo.rewards.find( (reward) => statsB2.number >= reward.from_position && statsB2.number <= reward.to_position ); const positionDelta = leaderboard ? statsB2.number - positionA! : undefined; const delta = deltaBkrlBlitzStats( statsA, accountInfo.statistics.rating!, statsB2 ); const leagueTheme = LEAGUE_ACCENT[league.index]; let rewardImage = reward ? reward.type === "vehicle" ? reward.vehicle.preview_image_url : reward.stuff.image_url : undefined; if (rewardImage) { const { ok } = await fetch(rewardImage); if (!ok) { rewardImage = imgur("kP88vqr"); } } return (
{reward === undefined && ( )}
{`League
{statsB2.score.toLocaleString(interaction.locale)} {delta.score !== 0 && ( <> 0 ? theme.colors.textLowContrast_green : theme.colors.textLowContrast_red, fontSize: 16, }} > {Math.abs(delta.score).toLocaleString( interaction.locale )} )}
#{statsB2.number.toLocaleString(interaction.locale)} {positionDelta !== undefined && positionDelta !== 0 && ( <> 0 ? theme.colors.textLowContrast_red : theme.colors.textLowContrast_green, fontSize: 16, }} > {Math.abs(positionDelta).toLocaleString( interaction.locale )} )}
{reward && (
{reward.type === "vehicle" ? reward.vehicle.user_string : reward.stuff.title}
Reward {reward.type === "stuff" ? ` x${reward.count}` : ""}
)} {reward === undefined && ( )}
{/* separated because fragment middle man invalidates relative parent: https://github.com/vercel/satori/issues/605 */} {reward && ( )} {reward && ( )}
{delta.battles > 0 && (
{delta.battles.toLocaleString(interaction.locale)} Battles
{(100 * (delta.wins / delta.battles)).toFixed(0)}% Winrate
{Math.round(delta.damage / delta.battles).toLocaleString( interaction.locale )} Damage
{(100 * (delta.survived / delta.battles)).toFixed(0)}% Survival
{(delta.kills / delta.battles).toFixed(2)} Kills
)}
); }, }); });