diff --git a/docs/changelogs/1.20.3.md b/docs/changelogs/1.20.3.md new file mode 100644 index 000000000..bf8ff1d73 --- /dev/null +++ b/docs/changelogs/1.20.3.md @@ -0,0 +1,14 @@ +# BlitzKit 1.20.3 + +A bug turns into a rating command feature! + +## Features + +- The rating command was giving seasonal statistics instead for the current day; this bug has now been made a feature through the new `/rating season` command + +## Fixes + +- Missing WN8 is now displayed with "--" instead of `NaN` +- Players who have not participated in the rating gamemode are handled correctly +- Decreasing position is now positive indicated in `/rating` +- `/rating` now displays today's statics correctly once again diff --git a/package.json b/package.json index 1e6c503f5..af98f0f5d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blitzkit", - "version": "1.20.1", + "version": "1.20.3", "description": "🎉 Tools for everything World of Tanks Blitz", "main": "src/server.ts", "type": "module", @@ -75,7 +75,7 @@ "react-fuzzysort": "^1.0.1", "react-promise-suspense": "^0.3.4", "satori": "^0.10.13", - "sharp": "^0.33.3", + "sharp": "^0.33.4", "three": "0.159.0", "three-stdlib": "^2.29.4", "vite-node": "^0.34.5", diff --git a/src/commands/rating.tsx b/src/commands/rating.tsx index 51a19c3d7..885baa713 100644 --- a/src/commands/rating.tsx +++ b/src/commands/rating.tsx @@ -1,3 +1,4 @@ +import { SlashCommandSubcommandBuilder } from 'discord.js'; import markdownEscape from 'markdown-escape'; import { Glow } from '../components/AllStatsOverview/components/HeroStat/components/Glow'; import CommandWrapper from '../components/CommandWrapper'; @@ -31,20 +32,42 @@ const LEAGUE_ACCENT = [ export const ratingCommand = new Promise((resolve) => { resolve({ - command: - createLocalizedCommand('rating').addStringOption(addUsernameChoices), + command: createLocalizedCommand('rating', [ + { + subcommand: 'today', + modify(option: SlashCommandSubcommandBuilder) { + option.addStringOption(addUsernameChoices); + }, + }, + { + subcommand: 'season', + modify(option: SlashCommandSubcommandBuilder) { + option.addStringOption(addUsernameChoices); + }, + }, + ]), inProduction: true, inPublic: true, async handler(interaction) { + const subcommand = interaction.options.getSubcommand(true) as + | 'season' + | 'today'; const { t, translate } = 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 getArchivedRatingMidnightLeaderboard( region, - 53, + ratingInfo.current_season - (subcommand === 'today' ? 0 : 1), ); if (leaderboard?.format === BkrlFormat.Base) { @@ -53,7 +76,6 @@ export const ratingCommand = new Promise((resolve) => { ); } - const ratingInfo = await getRatingInfo(region); const accountInfo = await getAccountInfo(region, id, [ 'statistics.rating', ]); @@ -63,12 +85,17 @@ export const ratingCommand = new Promise((resolve) => { const statsA = leaderboard ? leaderboard.entries[statsIndex!] : null; const positionA = leaderboard ? statsIndex! + 1 : undefined; const statsB1 = accountInfo.statistics.rating!; - const [statsB2] = (await getRatingNeighbors(region, id, 0)).neighbors; + const statsB2Array = (await getRatingNeighbors(region, id, 0)).neighbors; + + if (statsB2Array === undefined) { + return translate('bot.commands.rating.errors.no_participation', [ + markdownEscape(accountInfo.nickname), + ]); + } + + const [statsB2] = statsB2Array; const league = getLeagueFromScore(statsB2.score); - if (ratingInfo.detail) { - throw new Error(`Rating info not available for ${region}`); - } if (!statsA) { return t`bot.commands.rating.errors.unrecorded_stats`; } @@ -98,7 +125,7 @@ export const ratingCommand = new Promise((resolve) => { @@ -212,13 +239,13 @@ export const ratingCommand = new Promise((resolve) => { {positionDelta !== undefined && positionDelta !== 0 && ( <> - + 0 - ? theme.colors.textLowContrast_green - : theme.colors.textLowContrast_red, + ? theme.colors.textLowContrast_red + : theme.colors.textLowContrast_green, fontSize: 16, }} > diff --git a/src/components/AllStatsOverview/index.tsx b/src/components/AllStatsOverview/index.tsx index 8e87d2ff5..2763d434f 100644 --- a/src/components/AllStatsOverview/index.tsx +++ b/src/components/AllStatsOverview/index.tsx @@ -32,14 +32,15 @@ export default function AllStatsOverview({ }: AllStatsOverviewProps) { const { t, translate } = translator(locale); const percentile = - supplementaryStats.WN8 === undefined - ? Percentile.VeryBad - : getWN8Percentile(supplementaryStats.WN8); + typeof supplementaryStats.WN8 === 'number' + ? getWN8Percentile(supplementaryStats.WN8) + : Percentile.VeryBad; const color = PERCENTILE_COLORS[percentile]; + const heroStat = - supplementaryStats.WN8 === undefined - ? '--' - : supplementaryStats.WN8.toFixed(0); + typeof supplementaryStats.WN8 === 'number' + ? supplementaryStats.WN8.toFixed(0) + : '--'; return (