diff --git a/package.json b/package.json index 7b4afd2b7..de4d38909 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blitzkrieg", - "version": "1.3.3", + "version": "1.4.0", "description": "", "main": "index.js", "type": "module", diff --git a/src/commands/stats.tsx b/src/commands/stats.tsx index e26255ac3..277bf3d91 100644 --- a/src/commands/stats.tsx +++ b/src/commands/stats.tsx @@ -24,9 +24,8 @@ import { AccountInfo, AllStats } from '../types/accountInfo.js'; import { PlayerClanData } from '../types/playerClanData.js'; import { BlitzStartsComputedPeriodicStatistics } from '../types/statistics.js'; -type Period = 'today' | '30' | '90' | 'career'; - -const periodNames: Record = { +export type StatPeriod = 'today' | '30' | '90' | 'career'; +export const statPeriodNames: Record = { today: "Today's statistics", 30: '30-day statistics', 90: '90-day statistics', @@ -35,7 +34,7 @@ const periodNames: Record = { export default { inProduction: true, - inDevelopment: true, + inDevelopment: false, inPublic: true, command: new SlashCommandBuilder() @@ -46,17 +45,17 @@ export default { .setName('period') .setDescription('The last number of days of stats') .setChoices( - { name: 'Today', value: 'today' satisfies Period }, - { name: '30 Days', value: '30' satisfies Period }, - { name: '90 Days', value: '90' satisfies Period }, - { name: 'Career', value: 'career' satisfies Period }, + { name: 'Today', value: 'today' satisfies StatPeriod }, + { name: '30 Days', value: '30' satisfies StatPeriod }, + { name: '90 Days', value: '90' satisfies StatPeriod }, + { name: 'Career', value: 'career' satisfies StatPeriod }, ) .setRequired(true), ) .addStringOption(addUsernameOption), async execute(interaction) { - const period = interaction.options.getString('period') as Period; + const period = interaction.options.getString('period') as StatPeriod; const username = interaction.options.getString('username')!; const blitzAccount = await getBlitzAccount(interaction, username); const { id, server } = blitzAccount; @@ -74,9 +73,6 @@ export default { const a2 = accountInfo[id].statistics; const battles = a2.all.battles - a1.all.battles; - function max(value: (allStats: AllStats) => number) { - return Math.max(value(a2.all), value(a1.all)); - } function diff(value: (allStats: AllStats) => number) { return value(a2.all) - value(a1.all); } @@ -92,8 +88,8 @@ export default { frags8p: diff((a) => a.frags8p), hits: diff((a) => a.hits), losses: diff((a) => a.losses), - max_frags: max((a) => a.max_frags), - max_xp: max((a) => a.max_xp), + max_frags: a2.all.max_frags, + max_xp: a2.all.max_xp, shots: diff((a) => a.shots), spotted: diff((a) => a.spotted), survived_battles: diff((a) => a.survived_battles), @@ -125,7 +121,7 @@ export default { : undefined } description={`${ - periodNames[period] + statPeriodNames[period] } • ${new Date().toDateString()} • ${BLITZ_SERVERS[server]}`} /> diff --git a/src/commands/today.tsx b/src/commands/today.tsx index 0003eee57..4e3e197b0 100644 --- a/src/commands/today.tsx +++ b/src/commands/today.tsx @@ -14,6 +14,7 @@ import { supportBlitzStars } from '../core/actions/supportBlitzStars.js'; import usernameAutocomplete from '../core/autocomplete/username.js'; import getBlitzAccount from '../core/blitz/getBlitzAccount.js'; import getWargamingResponse from '../core/blitz/getWargamingResponse.js'; +import sumStats from '../core/blitz/sumStats.js'; import getTankStatsOverTime from '../core/blitzstars/getTankStatsOverTime.js'; import last5AM from '../core/blitzstars/last5AM.js'; import { tankopedia } from '../core/blitzstars/tankopedia.js'; @@ -56,38 +57,55 @@ export default { const careerTankStatsRaw = await getWargamingResponse( `https://api.wotblitz.${server}/wotb/tanks/stats/?application_id=${args['wargaming-application-id']}&account_id=${id}`, ); - const careerStats: Record = {}; + const careerStats: Record = { + 0: accountInfo[id].statistics.all, + }; + const allStatsToAccumulate: AllStats[] = []; + Object.entries(tankStatsOverTime).forEach(([, tankStats]) => { + allStatsToAccumulate.push(tankStats); + }); Object.entries(careerTankStatsRaw[id]).forEach(([, tankStats]) => { careerStats[tankStats.tank_id] = tankStats.all; }); - const rows = Object.entries(tankStatsOverTime).map( - ([tankId, tankStats]) => { - const career = careerStats[tankId as unknown as number]; + const accumulatedStats = sumStats(allStatsToAccumulate); - return ( - - ); - }, - ); + const rows = Object.entries({ + 0: accumulatedStats, + ...tankStatsOverTime, + }).map(([tankId, tankStats]) => { + const career = careerStats[tankId as unknown as number]; + + return ( + + ); + }); const image = await render( diff --git a/src/core/blitz/diffStats.ts b/src/core/blitz/diffStats.ts new file mode 100644 index 000000000..3c336d4d2 --- /dev/null +++ b/src/core/blitz/diffStats.ts @@ -0,0 +1,30 @@ +import { AllStats } from '../../types/accountInfo.js'; + +export default function diffStats(stats1: AllStats, stats2: AllStats) { + function diff(value: (allStats: AllStats) => number) { + return value(stats2) - value(stats1); + } + function max(value: (allStats: AllStats) => number) { + return Math.max(value(stats1), value(stats2)); + } + + return { + battles: diff((a) => a.battles), + wins: diff((a) => a.wins), + capture_points: diff((a) => a.capture_points), + damage_dealt: diff((a) => a.damage_dealt), + damage_received: diff((a) => a.damage_received), + dropped_capture_points: diff((a) => a.dropped_capture_points), + frags: diff((a) => a.frags), + frags8p: diff((a) => a.frags8p), + hits: diff((a) => a.hits), + losses: diff((a) => a.losses), + max_frags: max((a) => a.max_frags), + max_xp: max((a) => a.max_xp), + shots: diff((a) => a.shots), + spotted: diff((a) => a.spotted), + survived_battles: diff((a) => a.survived_battles), + win_and_survived: diff((a) => a.win_and_survived), + xp: diff((a) => a.xp), + } satisfies AllStats; +} diff --git a/src/core/blitz/sumStats.ts b/src/core/blitz/sumStats.ts new file mode 100644 index 000000000..7d990f44c --- /dev/null +++ b/src/core/blitz/sumStats.ts @@ -0,0 +1,33 @@ +import { AllStats } from '../../types/accountInfo.js'; +import { emptyAllStats } from '../blitzstars/getTankStatsOverTime.js'; + +export default function sumStats(allStatsCollection: AllStats[]) { + return allStatsCollection.reduce((accumulated, current) => { + function sum(value: (allStats: AllStats) => number) { + return value(accumulated) + value(current); + } + function max(value: (allStats: AllStats) => number) { + return Math.max(value(accumulated), value(current)); + } + + return { + battles: sum((a) => a.battles), + wins: sum((a) => a.wins), + capture_points: sum((a) => a.capture_points), + damage_dealt: sum((a) => a.damage_dealt), + damage_received: sum((a) => a.damage_received), + dropped_capture_points: sum((a) => a.dropped_capture_points), + frags: sum((a) => a.frags), + frags8p: sum((a) => a.frags8p), + hits: sum((a) => a.hits), + losses: sum((a) => a.losses), + max_frags: max((a) => a.max_frags), + max_xp: max((a) => a.max_xp), + shots: sum((a) => a.shots), + spotted: sum((a) => a.spotted), + survived_battles: sum((a) => a.survived_battles), + win_and_survived: sum((a) => a.win_and_survived), + xp: sum((a) => a.xp), + } satisfies AllStats; + }, emptyAllStats); +} diff --git a/src/core/blitzstars/getTankStatsOverTime.ts b/src/core/blitzstars/getTankStatsOverTime.ts index cffa7293f..662b41b3b 100644 --- a/src/core/blitzstars/getTankStatsOverTime.ts +++ b/src/core/blitzstars/getTankStatsOverTime.ts @@ -13,31 +13,33 @@ export interface TankHistoryNode { tank_id: number; } +export const emptyAllStats: AllStats = { + battles: 0, + capture_points: 0, + damage_dealt: 0, + damage_received: 0, + dropped_capture_points: 0, + frags: 0, + frags8p: 0, + hits: 0, + losses: 0, + max_frags: 0, + max_xp: 0, + shots: 0, + spotted: 0, + survived_battles: 0, + xp: 0, + win_and_survived: 0, + wins: 0, +}; + export const emptyTankHistoryNode: TankHistoryNode = { account_id: 0, battle_life_time: 0, last_battle_time: 0, mark_of_mastery: 0, tank_id: 0, - all: { - battles: 0, - capture_points: 0, - damage_dealt: 0, - damage_received: 0, - dropped_capture_points: 0, - frags: 0, - frags8p: 0, - hits: 0, - losses: 0, - max_frags: 0, - max_xp: 0, - shots: 0, - spotted: 0, - survived_battles: 0, - xp: 0, - win_and_survived: 0, - wins: 0, - }, + all: emptyAllStats, }; export type TankHistory = TankHistoryNode[]; @@ -91,9 +93,6 @@ export default async function getTankStatsOverTime( function diff(get: (allStats: AllStats) => number) { return get(latest.all) - get(previous.all); } - function max(get: (allStats: AllStats) => number) { - return Math.max(get(latest.all), get(previous.all)); - } // check if there was a change in battles as games in ratings do update last_battle_time if (diff((a) => a.battles) > 0) { @@ -107,8 +106,8 @@ export default async function getTankStatsOverTime( frags8p: diff((a) => a.frags8p), hits: diff((a) => a.hits), losses: diff((a) => a.losses), - max_frags: max((a) => a.max_frags), - max_xp: max((a) => a.max_xp), + max_frags: latest.all.max_frags, + max_xp: latest.all.max_xp, shots: diff((a) => a.shots), spotted: diff((a) => a.spotted), survived_battles: diff((a) => a.survived_battles),