From 96ae6b715fb1ba257df558794a40bb2309389784 Mon Sep 17 00:00:00 2001 From: tresabhi Date: Sat, 3 Jun 2023 01:19:52 +0000 Subject: [PATCH 1/3] fix: tank stats being null for players without battles --- src/commands/ownedtanks.ts | 8 ++---- src/commands/stats.tsx | 1 + src/commands/tankstats.tsx | 9 +++--- src/commands/today.tsx | 9 +++--- src/core/blitz/getTankStats.ts | 31 +++++++++++++++++++++ src/core/blitzstars/getTankStatsOverTime.ts | 12 ++++---- 6 files changed, 48 insertions(+), 22 deletions(-) create mode 100644 src/core/blitz/getTankStats.ts diff --git a/src/commands/ownedtanks.ts b/src/commands/ownedtanks.ts index 069200ea0..7e9e41ea5 100644 --- a/src/commands/ownedtanks.ts +++ b/src/commands/ownedtanks.ts @@ -2,6 +2,7 @@ import { SlashCommandBuilder } from 'discord.js'; import markdownEscape from 'markdown-escape'; import usernameAutocomplete from '../core/autocomplete/username.js'; import getBlitzAccount from '../core/blitz/getBlitzAccount.js'; +import getTankStats from '../core/blitz/getTankStats.js'; import getWargamingResponse from '../core/blitz/getWargamingResponse.js'; import resolveTankName from '../core/blitz/resolveTankName.js'; import { TANK_TYPE_EMOJIS, tankopedia } from '../core/blitz/tankopedia.js'; @@ -11,7 +12,6 @@ import addUsernameOption from '../core/options/addUsernameOption.js'; import { args } from '../core/process/args.js'; import { CommandRegistry } from '../events/interactionCreate.js'; import { AccountInfo } from '../types/accountInfo.js'; -import { TanksStats } from '../types/tanksStats.js'; const COMP_TANKS = [ // light tanks @@ -60,10 +60,8 @@ export default { const accountInfo = await getWargamingResponse( `https://api.wotblitz.${server}/wotb/account/info/?application_id=${args['wargaming-application-id']}&account_id=${id}`, ); - const tankStats = await getWargamingResponse( - `https://api.wotblitz.${server}/wotb/tanks/stats/?application_id=${args['wargaming-application-id']}&account_id=${id}`, - ); - const tanks = tankStats[id] + const tankStats = await getTankStats(interaction, server, id); + const tanks = tankStats .map((tankData) => tankopedia[tankData.tank_id]) .filter((tank) => tank?.tier === tier); diff --git a/src/commands/stats.tsx b/src/commands/stats.tsx index 1ed746868..87d744228 100644 --- a/src/commands/stats.tsx +++ b/src/commands/stats.tsx @@ -66,6 +66,7 @@ export default { stats = accountInfo[id].statistics.all; } else { const tankStatsOverTime = await getTankStatsOverTime( + interaction, server, id, getPeriodicStart(period), diff --git a/src/commands/tankstats.tsx b/src/commands/tankstats.tsx index 9e34edf7e..305b420f3 100644 --- a/src/commands/tankstats.tsx +++ b/src/commands/tankstats.tsx @@ -12,6 +12,7 @@ import { BLITZ_SERVERS } from '../constants/servers.js'; import tanksAutocomplete from '../core/autocomplete/tanks.js'; import usernameAutocomplete from '../core/autocomplete/username.js'; import getBlitzAccount from '../core/blitz/getBlitzAccount.js'; +import getTankStats from '../core/blitz/getTankStats.js'; import getWN8 from '../core/blitz/getWN8.js'; import getWargamingResponse from '../core/blitz/getWargamingResponse.js'; import resolveTankId from '../core/blitz/resolveTankId.js'; @@ -36,7 +37,6 @@ import { args } from '../core/process/args.js'; import render from '../core/ui/render.js'; import { CommandRegistry } from '../events/interactionCreate.js'; import { AccountInfo, AllStats } from '../types/accountInfo.js'; -import { TanksStats } from '../types/tanksStats.js'; export default { inProduction: true, @@ -62,18 +62,17 @@ export default { const accountInfo = await getWargamingResponse( `https://api.wotblitz.${server}/wotb/account/info/?application_id=${args['wargaming-application-id']}&account_id=${id}`, ); - const tankStats = await getWargamingResponse( - `https://api.wotblitz.${server}/wotb/tanks/stats/?application_id=${args['wargaming-application-id']}&account_id=${id}`, - ); + const tankStats = await getTankStats(interaction, server, id); let stats: AllStats; const tankId = Number(tank); if (period === 'career') { stats = - tankStats[id].find((stats) => stats.tank_id === tankId)?.all ?? + tankStats.find((stats) => stats.tank_id === tankId)?.all ?? emptyAllStats; } else { const tankStatsOverTime = await getTankStatsOverTime( + interaction, server, id, getPeriodicStart(period), diff --git a/src/commands/today.tsx b/src/commands/today.tsx index 6328760ca..59e02c578 100644 --- a/src/commands/today.tsx +++ b/src/commands/today.tsx @@ -11,6 +11,7 @@ import Wrapper, { WrapperSize } from '../components/Wrapper.js'; import { BLITZ_SERVERS } from '../constants/servers.js'; import usernameAutocomplete from '../core/autocomplete/username.js'; import getBlitzAccount from '../core/blitz/getBlitzAccount.js'; +import getTankStats from '../core/blitz/getTankStats.js'; import getWN8 from '../core/blitz/getWN8.js'; import getWargamingResponse from '../core/blitz/getWargamingResponse.js'; import resolveTankName from '../core/blitz/resolveTankName.js'; @@ -28,7 +29,6 @@ import render from '../core/ui/render.js'; import { CommandRegistry } from '../events/interactionCreate.js'; import { AccountInfo, AllStats } from '../types/accountInfo.js'; import { PlayerClanData } from '../types/playerClanData.js'; -import { TanksStats } from '../types/tanksStats.js'; export default { inProduction: true, @@ -45,6 +45,7 @@ export default { const blitzAccount = await getBlitzAccount(interaction, username); const { id, server } = blitzAccount; const tankStatsOverTime = await getTankStatsOverTime( + interaction, server, id, last5AM().getTime() / 1000, @@ -56,9 +57,7 @@ export default { const clanData = await getWargamingResponse( `https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${args['wargaming-application-id']}&account_id=${id}&extra=clan`, ); - const careerTankStatsRaw = await getWargamingResponse( - `https://api.wotblitz.${server}/wotb/tanks/stats/?application_id=${args['wargaming-application-id']}&account_id=${id}`, - ); + const careerTankStatsRaw = await getTankStats(interaction, server, id); const careerStats: Record = { 0: accountInfo[id].statistics.all, }; @@ -67,7 +66,7 @@ export default { Object.entries(tankStatsOverTime).forEach(([, tankStats]) => { allStatsToAccumulate.push(tankStats); }); - Object.entries(careerTankStatsRaw[id]).forEach(([, tankStats]) => { + Object.entries(careerTankStatsRaw).forEach(([, tankStats]) => { careerStats[tankStats.tank_id] = tankStats.all; }); diff --git a/src/core/blitz/getTankStats.ts b/src/core/blitz/getTankStats.ts new file mode 100644 index 000000000..6569c694c --- /dev/null +++ b/src/core/blitz/getTankStats.ts @@ -0,0 +1,31 @@ +import { CacheType, ChatInputCommandInteraction } from 'discord.js'; +import { BLITZ_SERVERS, BlitzServer } from '../../constants/servers.js'; +import { TanksStats } from '../../types/tanksStats.js'; +import errorEmbed from '../interaction/errorEmbed.js'; +import { args } from '../process/args.js'; +import getWargamingResponse from './getWargamingResponse.js'; + +export default async function getTankStats( + interaction: ChatInputCommandInteraction, + server: BlitzServer, + id: number, +) { + const tankStats = await getWargamingResponse( + `https://api.wotblitz.${server}/wotb/tanks/stats/?application_id=${args['wargaming-application-id']}&account_id=${id}`, + ); + + if (tankStats[id] === null) { + interaction.editReply({ + embeds: [ + errorEmbed( + 'No tank stats available', + `Wargaming says there is no tank stats for this account. This account may not have any battles/tanks or exist in the ${BLITZ_SERVERS[server]} server.`, + ), + ], + }); + + throw new Error(`No tank stats available for ${server}/${id}`); + } + + return tankStats[id]; +} diff --git a/src/core/blitzstars/getTankStatsOverTime.ts b/src/core/blitzstars/getTankStatsOverTime.ts index 1230d7c0f..08d30e592 100644 --- a/src/core/blitzstars/getTankStatsOverTime.ts +++ b/src/core/blitzstars/getTankStatsOverTime.ts @@ -1,8 +1,7 @@ +import { CacheType, ChatInputCommandInteraction } from 'discord.js'; import { BlitzServer } from '../../constants/servers.js'; import { AllStats } from '../../types/accountInfo.js'; -import { TanksStats } from '../../types/tanksStats.js'; -import getWargamingResponse from '../blitz/getWargamingResponse.js'; -import { args } from '../process/args.js'; +import getTankStats from '../blitz/getTankStats.js'; export interface TankHistoryNode { all: AllStats; @@ -45,19 +44,18 @@ export const emptyTankHistoryNode: TankHistoryNode = { export type TankHistory = TankHistoryNode[]; export default async function getTankStatsOverTime( + interaction: ChatInputCommandInteraction, server: BlitzServer, id: number, start: number, end: number, ) { - const latestTankStatsRaw = await getWargamingResponse( - `https://api.wotblitz.${server}/wotb/tanks/stats/?application_id=${args['wargaming-application-id']}&account_id=${id}`, - ); + const latestTankStatsRaw = await getTankStats(interaction, server, id); const tankHistoriesResponse = await fetch( `https://www.blitzstars.com/api/tankhistories/for/${id}/`, ); const tankHistories = (await tankHistoriesResponse.json()) as TankHistory; - const history = [...tankHistories, ...latestTankStatsRaw[id]]; + const history = [...tankHistories, ...latestTankStatsRaw]; // sort them even though most won't be used const tankSortedHistory: Record = {}; From 84056d70360dface69b139a9f4e0adaf1c36478a Mon Sep 17 00:00:00 2001 From: tresabhi Date: Sat, 3 Jun 2023 01:22:24 +0000 Subject: [PATCH 2/3] fix: removed not needed try catch for executing commands --- src/events/interactionCreate.ts | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/src/events/interactionCreate.ts b/src/events/interactionCreate.ts index 07955bf91..b64e953ac 100644 --- a/src/events/interactionCreate.ts +++ b/src/events/interactionCreate.ts @@ -80,11 +80,7 @@ export default async function interactionCreate( return; } - try { - if (command.autocomplete) command.autocomplete(interaction); - } catch (error) { - console.error(error); - } + if (command.autocomplete) command.autocomplete(interaction); } else if (interaction.isChatInputCommand()) { const command = commandCollection.get(interaction.commandName); @@ -95,22 +91,8 @@ export default async function interactionCreate( return; } - try { - await interaction.deferReply(); - console.log(interaction.toString()); - command.execute(interaction); - } catch (error) { - console.error(error); - if (interaction.replied || interaction.deferred) { - await interaction.followUp({ - content: 'There was an error while executing this command!', - ephemeral: true, - }); - } else { - await interaction.editReply({ - content: 'There was an error while executing this command!', - }); - } - } + console.log(interaction.toString()); + await interaction.deferReply(); + command.execute(interaction); } } From 843cc8e861b68c07ab2236c7faf788bf07bc983f Mon Sep 17 00:00:00 2001 From: tresabhi Date: Sat, 3 Jun 2023 01:29:42 +0000 Subject: [PATCH 3/3] fix: /stats now uses double hyphens like /today for WN8 --- src/commands/stats.tsx | 5 +++++ src/components/GenericAllStats.tsx | 8 ++++++-- src/types/accountInfo.ts | 3 ++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/commands/stats.tsx b/src/commands/stats.tsx index 87d744228..20f36d380 100644 --- a/src/commands/stats.tsx +++ b/src/commands/stats.tsx @@ -78,6 +78,8 @@ export default { 0, ); + let hasWN8AccumulatedAtAll = false; + supplementaryStats = { tier: entries.reduce((accumulator, [tankIdString, stats]) => { @@ -93,11 +95,14 @@ export default { // edge case where new tanks don't have averages if (tankAverages[tankId]) { const tankWN8 = getWN8(tankAverages[tankId].all, stats); + hasWN8AccumulatedAtAll = true; return accumulator + tankWN8 * stats.battles; } else return accumulator; }, 0) / totalBattles, }; + if (!hasWN8AccumulatedAtAll) supplementaryStats.WN8 = undefined; + stats = sumStats(entries.map(([, stats]) => stats)); } diff --git a/src/components/GenericAllStats.tsx b/src/components/GenericAllStats.tsx index 7388aa7fa..c919ab223 100644 --- a/src/components/GenericAllStats.tsx +++ b/src/components/GenericAllStats.tsx @@ -17,10 +17,14 @@ export default function GenericAllStats({ ['Winrate', `${(100 * (stats.wins / stats.battles)).toFixed(2)}%`], [ 'WN8', - supplementaryStats?.WN8.toFixed(0), supplementaryStats - ? getWN8Percentile(supplementaryStats.WN8) + ? supplementaryStats.WN8 === undefined + ? '--' + : supplementaryStats.WN8.toFixed(0) : undefined, + supplementaryStats?.WN8 === undefined + ? undefined + : getWN8Percentile(supplementaryStats.WN8), ], [ 'Survival', diff --git a/src/types/accountInfo.ts b/src/types/accountInfo.ts index 908930892..eae1a94d6 100644 --- a/src/types/accountInfo.ts +++ b/src/types/accountInfo.ts @@ -19,7 +19,8 @@ export interface AllStats { } export interface SupplementaryStats { - WN8: number; + // if undefined, WN8 is not available for tanks without averages + WN8?: number; tier: number; }