mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 10:47:04 +02:00
feat: custom periods for /stats and /tankstats
This commit is contained in:
1 parent
78424c1535
commit
e0c1db2a0b
14 files changed
+125
-49
No files matched your search
@@ -60,7 +60,6 @@ export default {
|
||||
|
||||
if (clan === 'SKLLD') {
|
||||
const tankStatsOverTime = await getTankStatsOverTime(
|
||||
interaction,
|
||||
server,
|
||||
id,
|
||||
getPeriodicStart('30'),
|
||||
|
||||
@@ -73,7 +73,7 @@ export default {
|
||||
const accountInfo = await getWargamingResponse<AccountInfo>(
|
||||
`https://api.wotblitz.${server}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}`,
|
||||
);
|
||||
const tankStats = await getTankStats(interaction, server, id);
|
||||
const tankStats = await getTankStats(server, id);
|
||||
const tanks = tankStats
|
||||
.map((tankData) => tankopedia[tankData.tank_id])
|
||||
.filter((tank) => tank?.tier === tier);
|
||||
|
||||
+39
-12
@@ -14,15 +14,17 @@ import sumStats from '../core/blitz/sumStats.js';
|
||||
import { tankopedia } from '../core/blitz/tankopedia.js';
|
||||
import getPeriodNow from '../core/blitzstars/getPeriodNow.js';
|
||||
import getPeriodicStart from '../core/blitzstars/getPeriodStart.js';
|
||||
import getPeriodStartFromDaysAgo from '../core/blitzstars/getPeriodStartFromDaysAgo.js';
|
||||
import getTankStatsOverTime from '../core/blitzstars/getTankStatsOverTime.js';
|
||||
import { tankAverages } from '../core/blitzstars/tankAverages.js';
|
||||
import cmdName from '../core/interaction/cmdName.js';
|
||||
import fullBlitzStarsStats from '../core/interaction/fullBlitzStarsStats.js';
|
||||
import { supportBlitzStars } from '../core/interaction/supportBlitzStars.js';
|
||||
import addStatPeriodChoices, {
|
||||
import addCustomPeriodOption from '../core/options/addCustomPeriodOption.js';
|
||||
import addPeriodChoices, {
|
||||
StatPeriod,
|
||||
statPeriodNames,
|
||||
} from '../core/options/addStatPeriodChoices.js';
|
||||
} from '../core/options/addPeriodChoices.js';
|
||||
import addUsernameOption from '../core/options/addUsernameOption.js';
|
||||
import { WARGAMING_APPLICATION_ID } from '../core/process/args.js';
|
||||
import { CommandRegistry } from '../events/interactionCreate.js';
|
||||
@@ -35,14 +37,25 @@ import { PlayerClanData } from '../types/playerClanData.js';
|
||||
|
||||
export default {
|
||||
inProduction: true,
|
||||
inDevelopment: false,
|
||||
inDevelopment: true,
|
||||
inPublic: true,
|
||||
|
||||
command: new SlashCommandBuilder()
|
||||
.setName(cmdName('stats'))
|
||||
.setDescription("Gets the user's in-game statistics")
|
||||
.addStringOption(addStatPeriodChoices)
|
||||
.addStringOption(addUsernameOption),
|
||||
.addSubcommand((option) =>
|
||||
option
|
||||
.setName('period')
|
||||
.setDescription('Pick from a predetermined periods')
|
||||
.addStringOption(addPeriodChoices)
|
||||
.addStringOption(addUsernameOption),
|
||||
)
|
||||
.addSubcommand((option) =>
|
||||
addCustomPeriodOption(option)
|
||||
.setName('customperiod')
|
||||
.setDescription('Custom periods')
|
||||
.addStringOption(addUsernameOption),
|
||||
),
|
||||
|
||||
async execute(interaction) {
|
||||
const period = interaction.options.getString('period') as StatPeriod;
|
||||
@@ -53,12 +66,25 @@ export default {
|
||||
const clanData = await getWargamingResponse<PlayerClanData>(
|
||||
`https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}&extra=clan`,
|
||||
);
|
||||
const tankStats = await getTankStats(interaction, server, id);
|
||||
let stats: AllStats;
|
||||
let supplementaryStats: SupplementaryStats | undefined;
|
||||
let hasWN8AccumulatedAtAll = false;
|
||||
const isCustomPeriod =
|
||||
interaction.options.getSubcommand() === 'customperiod';
|
||||
let periodName: string;
|
||||
const startRaw = interaction.options.getInteger('start')!;
|
||||
const endRaw = interaction.options.getInteger('end')!;
|
||||
const start = Math.max(startRaw, endRaw);
|
||||
const end = Math.min(startRaw, endRaw);
|
||||
|
||||
if (isCustomPeriod) {
|
||||
periodName = `${start} to ${end} days ago`;
|
||||
} else {
|
||||
periodName = statPeriodNames[period];
|
||||
}
|
||||
|
||||
if (period === 'career') {
|
||||
const tankStats = await getTankStats(server, id);
|
||||
stats = accountInfo[id].statistics.all;
|
||||
const totalBattles = tankStats.reduce(
|
||||
(accumulator, { all }) => accumulator + all.battles,
|
||||
@@ -87,11 +113,12 @@ export default {
|
||||
};
|
||||
} else {
|
||||
const tankStatsOverTime = await getTankStatsOverTime(
|
||||
interaction,
|
||||
server,
|
||||
id,
|
||||
getPeriodicStart(period),
|
||||
getPeriodNow(),
|
||||
isCustomPeriod
|
||||
? getPeriodStartFromDaysAgo(start)
|
||||
: getPeriodicStart(period),
|
||||
isCustomPeriod ? getPeriodStartFromDaysAgo(end) : getPeriodNow(),
|
||||
);
|
||||
const entries = Object.entries(tankStatsOverTime);
|
||||
const totalBattles = entries.reduce(
|
||||
@@ -141,9 +168,9 @@ export default {
|
||||
? `https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanData[id]?.clan?.emblem_set_id}.png`
|
||||
: undefined
|
||||
}
|
||||
description={`${
|
||||
statPeriodNames[period]
|
||||
} • ${new Date().toDateString()} • ${BLITZ_SERVERS[server]}`}
|
||||
description={`${periodName} • ${new Date().toDateString()} • ${
|
||||
BLITZ_SERVERS[server]
|
||||
}`}
|
||||
/>
|
||||
|
||||
{stats.battles === 0 && <NoData type={NoDataType.BattlesInPeriod} />}
|
||||
|
||||
+41
-13
@@ -16,6 +16,7 @@ import resolveTankName from '../core/blitz/resolveTankName.js';
|
||||
import { tankopedia } from '../core/blitz/tankopedia.js';
|
||||
import getPeriodNow from '../core/blitzstars/getPeriodNow.js';
|
||||
import getPeriodicStart from '../core/blitzstars/getPeriodStart.js';
|
||||
import getPeriodStartFromDaysAgo from '../core/blitzstars/getPeriodStartFromDaysAgo.js';
|
||||
import getTankStatsOverTime, {
|
||||
emptyAllStats,
|
||||
} from '../core/blitzstars/getTankStatsOverTime.js';
|
||||
@@ -23,10 +24,11 @@ import { tankAverages } from '../core/blitzstars/tankAverages.js';
|
||||
import cmdName from '../core/interaction/cmdName.js';
|
||||
import fullBlitzStarsStats from '../core/interaction/fullBlitzStarsStats.js';
|
||||
import { supportBlitzStars } from '../core/interaction/supportBlitzStars.js';
|
||||
import addStatPeriodChoices, {
|
||||
import addCustomPeriodOption from '../core/options/addCustomPeriodOption.js';
|
||||
import addPeriodChoices, {
|
||||
StatPeriod,
|
||||
statPeriodNames,
|
||||
} from '../core/options/addStatPeriodChoices.js';
|
||||
} from '../core/options/addPeriodChoices.js';
|
||||
import addTankChoices from '../core/options/addTankChoices.js';
|
||||
import addUsernameOption from '../core/options/addUsernameOption.js';
|
||||
import { WARGAMING_APPLICATION_ID } from '../core/process/args.js';
|
||||
@@ -35,15 +37,27 @@ import { AccountInfo, AllStats } from '../types/accountInfo.js';
|
||||
|
||||
export default {
|
||||
inProduction: true,
|
||||
inDevelopment: false,
|
||||
inDevelopment: true,
|
||||
inPublic: true,
|
||||
|
||||
command: new SlashCommandBuilder()
|
||||
.setName(cmdName('tankstats'))
|
||||
.setDescription('Stats for a tank over a period')
|
||||
.addStringOption(addTankChoices)
|
||||
.addStringOption(addStatPeriodChoices)
|
||||
.addStringOption(addUsernameOption),
|
||||
.addSubcommand((option) =>
|
||||
option
|
||||
.setName('period')
|
||||
.setDescription('Pick from a predetermined periods')
|
||||
.addStringOption(addTankChoices)
|
||||
.addStringOption(addPeriodChoices)
|
||||
.addStringOption(addUsernameOption),
|
||||
)
|
||||
.addSubcommand((option) =>
|
||||
addCustomPeriodOption(option)
|
||||
.setName('customperiod')
|
||||
.addStringOption(addTankChoices)
|
||||
.setDescription('Custom periods')
|
||||
.addStringOption(addUsernameOption),
|
||||
),
|
||||
|
||||
async execute(interaction) {
|
||||
const tank = await resolveTankId(
|
||||
@@ -56,9 +70,22 @@ export default {
|
||||
const accountInfo = await getWargamingResponse<AccountInfo>(
|
||||
`https://api.wotblitz.${server}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}`,
|
||||
);
|
||||
const tankStats = await getTankStats(interaction, server, id);
|
||||
const tankStats = await getTankStats(server, id);
|
||||
let stats: AllStats;
|
||||
const tankId = Number(tank);
|
||||
const isCustomPeriod =
|
||||
interaction.options.getSubcommand() === 'customperiod';
|
||||
let periodName: string;
|
||||
const startRaw = interaction.options.getInteger('start')!;
|
||||
const endRaw = interaction.options.getInteger('end')!;
|
||||
const start = Math.max(startRaw, endRaw);
|
||||
const end = Math.min(startRaw, endRaw);
|
||||
|
||||
if (isCustomPeriod) {
|
||||
periodName = `${start} to ${end} days ago`;
|
||||
} else {
|
||||
periodName = statPeriodNames[period];
|
||||
}
|
||||
|
||||
if (period === 'career') {
|
||||
stats =
|
||||
@@ -66,11 +93,12 @@ export default {
|
||||
emptyAllStats;
|
||||
} else {
|
||||
const tankStatsOverTime = await getTankStatsOverTime(
|
||||
interaction,
|
||||
server,
|
||||
id,
|
||||
getPeriodicStart(period),
|
||||
getPeriodNow(),
|
||||
isCustomPeriod
|
||||
? getPeriodStartFromDaysAgo(start)
|
||||
: getPeriodicStart(period),
|
||||
isCustomPeriod ? getPeriodStartFromDaysAgo(end) : getPeriodNow(),
|
||||
);
|
||||
|
||||
stats = tankStatsOverTime[tankId] ?? emptyAllStats;
|
||||
@@ -82,9 +110,9 @@ export default {
|
||||
name={accountInfo[id].nickname}
|
||||
nameDiscriminator={`(${resolveTankName(tankId)})`}
|
||||
image={tankopedia[tankId].images.normal}
|
||||
description={`${
|
||||
statPeriodNames[period]
|
||||
} • ${new Date().toDateString()} • ${BLITZ_SERVERS[server]}`}
|
||||
description={`${periodName} • ${new Date().toDateString()} • ${
|
||||
BLITZ_SERVERS[server]
|
||||
}`}
|
||||
/>
|
||||
|
||||
{stats.battles === 0 && <NoData type={NoDataType.BattlesInPeriod} />}
|
||||
|
||||
@@ -38,7 +38,6 @@ export default {
|
||||
async execute(interaction) {
|
||||
const { id, server } = await getBlitzAccount(interaction);
|
||||
const tankStatsOverTime = await getTankStatsOverTime(
|
||||
interaction,
|
||||
server,
|
||||
id,
|
||||
last5AM().getTime() / 1000,
|
||||
@@ -50,7 +49,7 @@ export default {
|
||||
const clanData = await getWargamingResponse<PlayerClanData>(
|
||||
`https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}&extra=clan`,
|
||||
);
|
||||
const careerTankStatsRaw = await getTankStats(interaction, server, id);
|
||||
const careerTankStatsRaw = await getTankStats(server, id);
|
||||
const careerStats: Record<number, AllStats> = {
|
||||
0: accountInfo[id].statistics.all,
|
||||
};
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
import { CacheType, ChatInputCommandInteraction } from 'discord.js';
|
||||
import { BLITZ_SERVERS, BlitzServer } from '../../constants/servers.js';
|
||||
import { TanksStats } from '../../types/tanksStats.js';
|
||||
import { WARGAMING_APPLICATION_ID } from '../process/args.js';
|
||||
import errorWithCause from '../process/errorWithCause.js';
|
||||
import getWargamingResponse from './getWargamingResponse.js';
|
||||
|
||||
export default async function getTankStats(
|
||||
interaction: ChatInputCommandInteraction<CacheType>,
|
||||
server: BlitzServer,
|
||||
id: number,
|
||||
) {
|
||||
export default async function getTankStats(server: BlitzServer, id: number) {
|
||||
const tankStats = await getWargamingResponse<TanksStats>(
|
||||
`https://api.wotblitz.${server}/wotb/tanks/stats/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}`,
|
||||
);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { StatPeriod } from '../options/addStatPeriodChoices.js';
|
||||
import { StatPeriod } from '../options/addPeriodChoices.js';
|
||||
import getPeriodStartFromDaysAgo from './getPeriodStartFromDaysAgo.js';
|
||||
|
||||
export default function getPeriodicStart(period: StatPeriod) {
|
||||
if (period === 'career') {
|
||||
@@ -12,12 +13,6 @@ export default function getPeriodicStart(period: StatPeriod) {
|
||||
|
||||
return now.getTime() / 1000;
|
||||
} else {
|
||||
const daysAgo = Number(period) - 1;
|
||||
const periodStart = new Date();
|
||||
|
||||
periodStart.setDate(periodStart.getDate() - daysAgo);
|
||||
periodStart.setHours(5, 0, 0, 0);
|
||||
|
||||
return periodStart.getTime() / 1000;
|
||||
return getPeriodStartFromDaysAgo(Number(period));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
export default function getPeriodStartFromDaysAgo(period: number) {
|
||||
const daysAgo = Number(period) - 1;
|
||||
const periodStart = new Date();
|
||||
|
||||
periodStart.setDate(periodStart.getDate() - daysAgo);
|
||||
periodStart.setHours(5, 0, 0, 0);
|
||||
|
||||
return periodStart.getTime() / 1000;
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
import { CacheType, ChatInputCommandInteraction } from 'discord.js';
|
||||
import { BlitzServer } from '../../constants/servers.js';
|
||||
import { AllStats } from '../../types/accountInfo.js';
|
||||
import getTankStats from '../blitz/getTankStats.js';
|
||||
@@ -44,13 +43,12 @@ export const emptyTankHistoryNode: TankHistoryNode = {
|
||||
export type TankHistory = TankHistoryNode[];
|
||||
|
||||
export default async function getTankStatsOverTime(
|
||||
interaction: ChatInputCommandInteraction<CacheType>,
|
||||
server: BlitzServer,
|
||||
id: number,
|
||||
start: number,
|
||||
end: number,
|
||||
) {
|
||||
const latestTankStatsRaw = await getTankStats(interaction, server, id);
|
||||
const latestTankStatsRaw = await getTankStats(server, id);
|
||||
const tankHistoriesResponse = await fetch(
|
||||
`https://www.blitzstars.com/api/tankhistories/for/${id}/`,
|
||||
);
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { SlashCommandSubcommandBuilder } from 'discord.js';
|
||||
|
||||
export default function addCustomPeriodOption(
|
||||
option: SlashCommandSubcommandBuilder,
|
||||
) {
|
||||
return option
|
||||
.addIntegerOption((option) =>
|
||||
option
|
||||
.setName('start')
|
||||
.setDescription('Start of period in days ago from today')
|
||||
.setMinValue(0)
|
||||
.setRequired(true),
|
||||
)
|
||||
.addIntegerOption((option) =>
|
||||
option
|
||||
.setName('end')
|
||||
.setDescription('End of period in days ago from today')
|
||||
.setMinValue(0)
|
||||
.setRequired(true),
|
||||
);
|
||||
}
|
||||
@@ -8,7 +8,7 @@ export const statPeriodNames: Record<StatPeriod, string> = {
|
||||
90: '90-day statistics',
|
||||
career: 'Career statistics',
|
||||
};
|
||||
export default function addStatPeriodChoices(option: SlashCommandStringOption) {
|
||||
export default function addPeriodChoices(option: SlashCommandStringOption) {
|
||||
return option
|
||||
.setName('period')
|
||||
.setDescription('The period to get stats for')
|
||||
@@ -3,6 +3,8 @@ import { SlashCommandStringOption } from 'discord.js';
|
||||
export default function addUsernameOption(option: SlashCommandStringOption) {
|
||||
return option
|
||||
.setName('username')
|
||||
.setDescription('The username you use in Blitz')
|
||||
.setDescription(
|
||||
'The username you use in Blitz (inferred from Discord nickname by default)',
|
||||
)
|
||||
.setAutocomplete(true);
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
RESTPostAPIChatInputApplicationCommandsJSONBody,
|
||||
Routes,
|
||||
SlashCommandBuilder,
|
||||
SlashCommandSubcommandsOnlyBuilder,
|
||||
} from 'discord.js';
|
||||
import discord from '../../discord.json' assert { type: 'json' };
|
||||
import debug from '../commands/debug.js';
|
||||
@@ -46,7 +47,7 @@ export type CommandRegistry = {
|
||||
inProduction: boolean;
|
||||
inPublic: boolean;
|
||||
|
||||
command: Omit<SlashCommandBuilder, 'addSubcommand' | 'addSubcommandGroup'>;
|
||||
command: SlashCommandBuilder | SlashCommandSubcommandsOnlyBuilder;
|
||||
autocomplete?: (interaction: AutocompleteInteraction<CacheType>) => void;
|
||||
} & (
|
||||
| {
|
||||
|
||||
Reference in new issue
Block a user