feat: all stats row

This commit is contained in:
TresAbhi committed 2023-05-29 17:44:32 +00:00
1 parent 7a6de17c1c
commit 513bea6f09
6 files changed
+142 -66

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "blitzkrieg", "name": "blitzkrieg",
"version": "1.3.3", "version": "1.4.0",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"type": "module", "type": "module",
+11 -15
View File
@@ -24,9 +24,8 @@ import { AccountInfo, AllStats } from '../types/accountInfo.js';
import { PlayerClanData } from '../types/playerClanData.js'; import { PlayerClanData } from '../types/playerClanData.js';
import { BlitzStartsComputedPeriodicStatistics } from '../types/statistics.js'; import { BlitzStartsComputedPeriodicStatistics } from '../types/statistics.js';
type Period = 'today' | '30' | '90' | 'career'; export type StatPeriod = 'today' | '30' | '90' | 'career';
export const statPeriodNames: Record<StatPeriod, string> = {
const periodNames: Record<Period, string> = {
today: "Today's statistics", today: "Today's statistics",
30: '30-day statistics', 30: '30-day statistics',
90: '90-day statistics', 90: '90-day statistics',
@@ -35,7 +34,7 @@ const periodNames: Record<Period, string> = {
export default { export default {
inProduction: true, inProduction: true,
inDevelopment: true, inDevelopment: false,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
@@ -46,17 +45,17 @@ export default {
.setName('period') .setName('period')
.setDescription('The last number of days of stats') .setDescription('The last number of days of stats')
.setChoices( .setChoices(
{ name: 'Today', value: 'today' satisfies Period }, { name: 'Today', value: 'today' satisfies StatPeriod },
{ name: '30 Days', value: '30' satisfies Period }, { name: '30 Days', value: '30' satisfies StatPeriod },
{ name: '90 Days', value: '90' satisfies Period }, { name: '90 Days', value: '90' satisfies StatPeriod },
{ name: 'Career', value: 'career' satisfies Period }, { name: 'Career', value: 'career' satisfies StatPeriod },
) )
.setRequired(true), .setRequired(true),
) )
.addStringOption(addUsernameOption), .addStringOption(addUsernameOption),
async execute(interaction) { 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 username = interaction.options.getString('username')!;
const blitzAccount = await getBlitzAccount(interaction, username); const blitzAccount = await getBlitzAccount(interaction, username);
const { id, server } = blitzAccount; const { id, server } = blitzAccount;
@@ -74,9 +73,6 @@ export default {
const a2 = accountInfo[id].statistics; const a2 = accountInfo[id].statistics;
const battles = a2.all.battles - a1.all.battles; 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) { function diff(value: (allStats: AllStats) => number) {
return value(a2.all) - value(a1.all); return value(a2.all) - value(a1.all);
} }
@@ -92,8 +88,8 @@ export default {
frags8p: diff((a) => a.frags8p), frags8p: diff((a) => a.frags8p),
hits: diff((a) => a.hits), hits: diff((a) => a.hits),
losses: diff((a) => a.losses), losses: diff((a) => a.losses),
max_frags: max((a) => a.max_frags), max_frags: a2.all.max_frags,
max_xp: max((a) => a.max_xp), max_xp: a2.all.max_xp,
shots: diff((a) => a.shots), shots: diff((a) => a.shots),
spotted: diff((a) => a.spotted), spotted: diff((a) => a.spotted),
survived_battles: diff((a) => a.survived_battles), survived_battles: diff((a) => a.survived_battles),
@@ -125,7 +121,7 @@ export default {
: undefined : undefined
} }
description={`${ description={`${
periodNames[period] statPeriodNames[period]
} • ${new Date().toDateString()} • ${BLITZ_SERVERS[server]}`} } • ${new Date().toDateString()} • ${BLITZ_SERVERS[server]}`}
/> />
+44 -26
View File
@@ -14,6 +14,7 @@ import { supportBlitzStars } from '../core/actions/supportBlitzStars.js';
import usernameAutocomplete from '../core/autocomplete/username.js'; import usernameAutocomplete from '../core/autocomplete/username.js';
import getBlitzAccount from '../core/blitz/getBlitzAccount.js'; import getBlitzAccount from '../core/blitz/getBlitzAccount.js';
import getWargamingResponse from '../core/blitz/getWargamingResponse.js'; import getWargamingResponse from '../core/blitz/getWargamingResponse.js';
import sumStats from '../core/blitz/sumStats.js';
import getTankStatsOverTime from '../core/blitzstars/getTankStatsOverTime.js'; import getTankStatsOverTime from '../core/blitzstars/getTankStatsOverTime.js';
import last5AM from '../core/blitzstars/last5AM.js'; import last5AM from '../core/blitzstars/last5AM.js';
import { tankopedia } from '../core/blitzstars/tankopedia.js'; import { tankopedia } from '../core/blitzstars/tankopedia.js';
@@ -56,38 +57,55 @@ export default {
const careerTankStatsRaw = await getWargamingResponse<TanksStats>( const careerTankStatsRaw = await getWargamingResponse<TanksStats>(
`https://api.wotblitz.${server}/wotb/tanks/stats/?application_id=${args['wargaming-application-id']}&account_id=${id}`, `https://api.wotblitz.${server}/wotb/tanks/stats/?application_id=${args['wargaming-application-id']}&account_id=${id}`,
); );
const careerStats: Record<number, AllStats> = {}; const careerStats: Record<number, AllStats> = {
0: accountInfo[id].statistics.all,
};
const allStatsToAccumulate: AllStats[] = [];
Object.entries(tankStatsOverTime).forEach(([, tankStats]) => {
allStatsToAccumulate.push(tankStats);
});
Object.entries(careerTankStatsRaw[id]).forEach(([, tankStats]) => { Object.entries(careerTankStatsRaw[id]).forEach(([, tankStats]) => {
careerStats[tankStats.tank_id] = tankStats.all; careerStats[tankStats.tank_id] = tankStats.all;
}); });
const rows = Object.entries(tankStatsOverTime).map( const accumulatedStats = sumStats(allStatsToAccumulate);
([tankId, tankStats]) => {
const career = careerStats[tankId as unknown as number];
return ( const rows = Object.entries({
<Breakdown.Row 0: accumulatedStats,
key={tankId} ...tankStatsOverTime,
name={resolveTankName({ }).map(([tankId, tankStats]) => {
tank_id: tankId as unknown as number, const career = careerStats[tankId as unknown as number];
name: tankopedia[tankId as unknown as number].name,
})} return (
winrate={tankStats.wins / tankStats.battles} <Breakdown.Row
careerWinrate={career.wins / career.battles} key={tankId}
WN8={-Infinity} name={
careerWN8={-Infinity} tankId === '0'
damage={tankStats.damage_dealt / tankStats.battles} ? 'Today'
careerDamage={career.damage_dealt / career.battles} : resolveTankName({
survival={tankStats.survived_battles / tankStats.battles} tank_id: tankId as unknown as number,
careerSurvival={career.survived_battles / career.battles} name: tankopedia[tankId as unknown as number].name,
battles={tankStats.battles} })
careerBattles={career.battles} }
icon={tankopedia[tankId as unknown as number].images.normal} winrate={tankStats.wins / tankStats.battles}
/> careerWinrate={career.wins / career.battles}
); WN8={-Infinity}
}, careerWN8={-Infinity}
); damage={tankStats.damage_dealt / tankStats.battles}
careerDamage={career.damage_dealt / career.battles}
survival={tankStats.survived_battles / tankStats.battles}
careerSurvival={career.survived_battles / career.battles}
battles={tankStats.battles}
careerBattles={career.battles}
icon={
tankId === '0'
? undefined
: tankopedia[tankId as unknown as number].images.normal
}
/>
);
});
const image = await render( const image = await render(
<Wrapper> <Wrapper>
+30
View File
@@ -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;
}
+33
View File
@@ -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);
}
+23 -24
View File
@@ -13,31 +13,33 @@ export interface TankHistoryNode {
tank_id: number; 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 = { export const emptyTankHistoryNode: TankHistoryNode = {
account_id: 0, account_id: 0,
battle_life_time: 0, battle_life_time: 0,
last_battle_time: 0, last_battle_time: 0,
mark_of_mastery: 0, mark_of_mastery: 0,
tank_id: 0, tank_id: 0,
all: { all: emptyAllStats,
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 type TankHistory = TankHistoryNode[]; export type TankHistory = TankHistoryNode[];
@@ -91,9 +93,6 @@ export default async function getTankStatsOverTime(
function diff(get: (allStats: AllStats) => number) { function diff(get: (allStats: AllStats) => number) {
return get(latest.all) - get(previous.all); 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 // check if there was a change in battles as games in ratings do update last_battle_time
if (diff((a) => a.battles) > 0) { if (diff((a) => a.battles) > 0) {
@@ -107,8 +106,8 @@ export default async function getTankStatsOverTime(
frags8p: diff((a) => a.frags8p), frags8p: diff((a) => a.frags8p),
hits: diff((a) => a.hits), hits: diff((a) => a.hits),
losses: diff((a) => a.losses), losses: diff((a) => a.losses),
max_frags: max((a) => a.max_frags), max_frags: latest.all.max_frags,
max_xp: max((a) => a.max_xp), max_xp: latest.all.max_xp,
shots: diff((a) => a.shots), shots: diff((a) => a.shots),
spotted: diff((a) => a.spotted), spotted: diff((a) => a.spotted),
survived_battles: diff((a) => a.survived_battles), survived_battles: diff((a) => a.survived_battles),