Files
blitzkit/src/commands/stats.ts
T

197 lines
7.4 KiB
TypeScript
Raw Normal View History

2023-04-26 00:02:10 +00:00
import { EmbedBuilder, SlashCommandBuilder } from 'discord.js';
2023-05-06 17:45:43 +00:00
import markdownEscape from 'markdown-escape';
2023-05-21 16:50:05 +00:00
import { INFO_COLOR } from '../constants/colors.js';
2023-05-14 17:13:42 +00:00
import usernameAutocomplete from '../core/autocomplete/username.js';
2023-05-16 02:02:50 +00:00
import getBlitzAccount from '../core/blitz/getBlitzAccount.js';
2023-05-13 22:01:58 +00:00
import getWargamingResponse from '../core/blitz/getWargamingResponse.js';
import blitzStarsLinks from '../core/blitzstars/blitzStarsLinks.js';
import getBlitzStarsAccount from '../core/blitzstars/getBlitzStarsAccount.js';
import poweredByBlitzStars from '../core/blitzstars/poweredByBlitzStars.js';
import cleanTable from '../core/interaction/cleanTable.js';
import cmdName from '../core/interaction/cmdName.js';
2023-05-14 17:13:42 +00:00
import addUsernameOption from '../core/options/addUsernameOption.js';
2023-05-13 22:01:58 +00:00
import { args } from '../core/process/args.js';
2023-05-19 23:50:24 +00:00
import { CommandRegistry } from '../events/interactionCreate.js';
2023-05-08 00:08:13 +00:00
import { AccountInfo, AllStats } from '../types/accountInfo.js';
2023-05-13 01:27:12 +00:00
import { BlitzStartsComputedPeriodicStatistics } from '../types/statistics.js';
2023-04-21 23:45:13 +00:00
2023-05-08 00:08:13 +00:00
type Period = 'today' | '30' | '90' | 'career';
2023-04-26 00:02:10 +00:00
export default {
inProduction: true,
2023-05-16 02:02:50 +00:00
inDevelopment: false,
2023-04-26 00:02:10 +00:00
inPublic: true,
2023-04-22 01:18:07 +00:00
2023-04-26 00:02:10 +00:00
command: new SlashCommandBuilder()
2023-05-13 01:27:12 +00:00
.setName(cmdName('stats'))
2023-04-26 00:02:10 +00:00
.setDescription("Gets the user's in-game statistics")
.addStringOption((option) =>
option
.setName('period')
.setDescription('The last number of days of stats')
.setChoices(
2023-05-08 00:08:13 +00:00
{ 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 },
2023-04-26 00:02:10 +00:00
)
.setRequired(true),
)
2023-05-14 17:13:42 +00:00
.addStringOption(addUsernameOption),
2023-04-22 01:18:07 +00:00
2023-05-08 01:03:05 +00:00
async execute(interaction) {
2023-05-08 00:08:13 +00:00
const period = interaction.options.getString('period') as Period;
2023-05-14 17:13:42 +00:00
const username = interaction.options.getString('username')!;
2023-05-16 02:02:50 +00:00
const blitzAccount = await getBlitzAccount(interaction, username);
2023-05-08 01:45:57 +00:00
if (!blitzAccount) return;
2023-05-16 02:02:50 +00:00
const { id, server } = blitzAccount;
2023-05-13 01:27:12 +00:00
let stats: BlitzStartsComputedPeriodicStatistics;
const accountInfo = await getWargamingResponse<AccountInfo>(
2023-05-16 02:02:50 +00:00
`https://api.wotblitz.${server}/wotb/account/info/?application_id=${args['wargaming-application-id']}&account_id=${id}`,
2023-05-13 01:27:12 +00:00
);
if (!accountInfo) return;
2023-05-16 02:02:50 +00:00
const blitzStarsAccount = await getBlitzStarsAccount(interaction, id);
2023-05-08 01:45:57 +00:00
if (!blitzStarsAccount) return;
2023-04-26 00:02:10 +00:00
2023-05-13 01:27:12 +00:00
if (period === 'today') {
2023-05-08 01:45:57 +00:00
const a1 = blitzStarsAccount.statistics;
2023-05-16 02:02:50 +00:00
const a2 = accountInfo[id].statistics;
2023-05-08 01:45:57 +00:00
const battles = a2.all.battles - a1.all.battles;
2023-05-08 00:08:13 +00:00
2023-05-08 01:45:57 +00:00
function pb(value: (allStats: AllStats) => number) {
return (value(a2.all) - value(a1.all)) / battles;
}
function diff(value: (allStats: AllStats) => number) {
return value(a2.all) - value(a1.all);
}
stats = {
all: {
battles,
capture_points: pb((a) => a.capture_points),
damage_dealt: pb((a) => a.damage_dealt),
damage_received: pb((a) => a.damage_received),
dropped_capture_points: diff((a) => a.dropped_capture_points),
frags: pb((a) => a.frags),
frags8p: pb((a) => a.frags8p),
hits: diff((a) => a.hits),
losses: diff((a) => a.losses),
max_frags: pb((a) => a.max_frags),
max_frags_tank_id: pb((a) => a.max_frags_tank_id),
max_xp: pb((a) => a.max_xp),
max_xp_tank_id: pb((a) => a.max_xp_tank_id),
shots: diff((a) => a.shots),
2023-05-13 01:27:12 +00:00
spotted: diff((a) => a.spotted),
survived_battles: diff((a) => a.survived_battles),
win_and_survived: diff((a) => a.win_and_survived),
2023-05-08 01:45:57 +00:00
wins: diff((a) => a.wins),
xp: diff((a) => a.xp),
},
avg_tier: -Infinity,
wn7: -Infinity,
wn8: -Infinity,
};
} else {
2023-05-13 01:27:12 +00:00
stats =
period === 'career'
? blitzStarsAccount.statistics
: blitzStarsAccount[`period${period}d`];
2023-05-08 01:45:57 +00:00
}
2023-05-13 01:27:12 +00:00
if (!stats!) return;
2023-05-08 01:45:57 +00:00
2023-05-13 01:27:12 +00:00
await interaction.editReply({
embeds: [
poweredByBlitzStars(
new EmbedBuilder()
2023-05-21 16:50:05 +00:00
.setColor(INFO_COLOR)
2023-05-13 01:27:12 +00:00
.setTitle(
2023-05-16 02:02:50 +00:00
`${markdownEscape(blitzStarsAccount.nickname)}'s ${
period === 'career'
? period
: `${period === 'today' ? 'today' : `${period} day`}`
2023-05-13 01:27:12 +00:00
} stats`,
)
.setDescription(
2023-05-13 17:50:03 +00:00
stats.all.battles > 0
? `${
period === 'today'
? '**⚠ "Today" stats are in development. Some stats are not available/wrong.**\n\n'
: ''
2023-05-13 21:42:40 +00:00
}${cleanTable([
2023-05-13 17:50:03 +00:00
[
'Winrate',
`${(100 * (stats.all.wins / stats.all.battles)).toFixed(
2,
)}%`,
],
[
'Survival',
`${(
100 *
(stats.all.survived_battles / stats.all.battles)
).toFixed(2)}%`,
],
[
'Accuracy',
`${((stats.all.hits / stats.all.shots) * 100).toFixed(
2,
)}%`,
],
['WN8', stats.wn8.toFixed(0)],
['WN7', stats.wn7.toFixed(0)],
[],
['Battles', stats.all.battles],
['Wins', stats.all.wins],
['Losses', stats.all.losses],
['Average tier', stats.avg_tier.toFixed(2)],
[],
[
'Shots per battle',
(stats.all.shots / stats.all.battles).toFixed(2),
],
[
'Hits per battle',
(stats.all.hits / stats.all.battles).toFixed(2),
],
[
'Damage per battle',
(stats.all.damage_dealt / stats.all.battles).toFixed(0),
],
[
'Kills per battle',
(stats.all.frags / stats.all.battles).toFixed(2),
],
[
'Spots per battle',
(stats.all.spotted / stats.all.battles).toFixed(2),
],
[
'XP per battle',
(stats.all.xp / stats.all.battles).toFixed(0),
],
[],
[
'Damage ratio',
(
stats.all.damage_dealt / stats.all.damage_received
).toFixed(2),
],
[
'Kills to death ratio',
(
stats.all.frags /
(stats.all.battles - stats.all.survived_battles)
).toFixed(2),
],
2023-05-16 02:02:50 +00:00
])}\n\n${blitzStarsLinks(server, blitzStarsAccount.nickname)}`
2023-05-13 17:50:03 +00:00
: 'No battles played in this period.',
2023-05-13 01:27:12 +00:00
),
),
],
});
2023-05-16 02:02:50 +00:00
console.log(`Showing stats for ${blitzStarsAccount.nickname}`);
2023-04-26 00:02:10 +00:00
},
2023-05-14 17:13:42 +00:00
autocomplete: usernameAutocomplete,
2023-04-26 00:02:10 +00:00
} satisfies CommandRegistry;