mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: /stats to getTankStatsOverTime
This commit is contained in:
1 parent
513bea6f09
commit
fcf7d99012
2 files changed
+48
-104
No files matched your search
+48
-79
@@ -14,7 +14,8 @@ 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 getBlitzStarsAccount from '../core/blitzstars/getBlitzStarsAccount.js';
|
import sumStats from '../core/blitz/sumStats.js';
|
||||||
|
import getTankStatsOverTime from '../core/blitzstars/getTankStatsOverTime.js';
|
||||||
import cmdName from '../core/interaction/cmdName.js';
|
import cmdName from '../core/interaction/cmdName.js';
|
||||||
import addUsernameOption from '../core/options/addUsernameOption.js';
|
import addUsernameOption from '../core/options/addUsernameOption.js';
|
||||||
import { args } from '../core/process/args.js';
|
import { args } from '../core/process/args.js';
|
||||||
@@ -22,19 +23,19 @@ import render from '../core/ui/render.js';
|
|||||||
import { CommandRegistry } from '../events/interactionCreate.js';
|
import { CommandRegistry } from '../events/interactionCreate.js';
|
||||||
import { AccountInfo, AllStats } from '../types/accountInfo.js';
|
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';
|
|
||||||
|
|
||||||
export type StatPeriod = 'today' | '30' | '90' | 'career';
|
export type StatPeriod = 'today' | '30' | '60' | '90' | 'career';
|
||||||
export const statPeriodNames: Record<StatPeriod, string> = {
|
export const statPeriodNames: Record<StatPeriod, string> = {
|
||||||
today: "Today's statistics",
|
today: "Today's statistics",
|
||||||
30: '30-day statistics',
|
30: '30-day statistics',
|
||||||
|
60: '60-day statistics',
|
||||||
90: '90-day statistics',
|
90: '90-day statistics',
|
||||||
career: 'Career statistics',
|
career: 'Career statistics',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inProduction: true,
|
inProduction: true,
|
||||||
inDevelopment: false,
|
inDevelopment: true,
|
||||||
inPublic: true,
|
inPublic: true,
|
||||||
|
|
||||||
command: new SlashCommandBuilder()
|
command: new SlashCommandBuilder()
|
||||||
@@ -47,6 +48,7 @@ export default {
|
|||||||
.setChoices(
|
.setChoices(
|
||||||
{ name: 'Today', value: 'today' satisfies StatPeriod },
|
{ name: 'Today', value: 'today' satisfies StatPeriod },
|
||||||
{ name: '30 Days', value: '30' satisfies StatPeriod },
|
{ name: '30 Days', value: '30' satisfies StatPeriod },
|
||||||
|
{ name: '60 Days', value: '60' satisfies StatPeriod },
|
||||||
{ name: '90 Days', value: '90' satisfies StatPeriod },
|
{ name: '90 Days', value: '90' satisfies StatPeriod },
|
||||||
{ name: 'Career', value: 'career' satisfies StatPeriod },
|
{ name: 'Career', value: 'career' satisfies StatPeriod },
|
||||||
)
|
)
|
||||||
@@ -59,59 +61,39 @@ export default {
|
|||||||
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;
|
||||||
let stats: BlitzStartsComputedPeriodicStatistics;
|
|
||||||
const accountInfo = await getWargamingResponse<AccountInfo>(
|
const accountInfo = await getWargamingResponse<AccountInfo>(
|
||||||
`https://api.wotblitz.${server}/wotb/account/info/?application_id=${args['wargaming-application-id']}&account_id=${id}`,
|
`https://api.wotblitz.${server}/wotb/account/info/?application_id=${args['wargaming-application-id']}&account_id=${id}`,
|
||||||
);
|
);
|
||||||
const clanData = await getWargamingResponse<PlayerClanData>(
|
const clanData = await getWargamingResponse<PlayerClanData>(
|
||||||
`https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${args['wargaming-application-id']}&account_id=${id}&extra=clan`,
|
`https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${args['wargaming-application-id']}&account_id=${id}&extra=clan`,
|
||||||
);
|
);
|
||||||
const blitzStarsAccount = await getBlitzStarsAccount(interaction, id);
|
let stats: AllStats;
|
||||||
|
|
||||||
if (period === 'today') {
|
if (period === 'career') {
|
||||||
const a1 = blitzStarsAccount.statistics;
|
stats = accountInfo[id].statistics.all;
|
||||||
const a2 = accountInfo[id].statistics;
|
|
||||||
const battles = a2.all.battles - a1.all.battles;
|
|
||||||
|
|
||||||
function diff(value: (allStats: AllStats) => number) {
|
|
||||||
return value(a2.all) - value(a1.all);
|
|
||||||
}
|
|
||||||
|
|
||||||
stats = {
|
|
||||||
all: {
|
|
||||||
battles,
|
|
||||||
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: 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),
|
|
||||||
win_and_survived: diff((a) => a.win_and_survived),
|
|
||||||
wins: diff((a) => a.wins),
|
|
||||||
xp: diff((a) => a.xp),
|
|
||||||
},
|
|
||||||
avg_tier: -Infinity,
|
|
||||||
wn7: -Infinity,
|
|
||||||
wn8: -Infinity,
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
stats =
|
const daysAgo = period === 'today' ? 0 : Number(period) - 1;
|
||||||
period === 'career'
|
const periodStart = new Date();
|
||||||
? blitzStarsAccount.statistics
|
|
||||||
: blitzStarsAccount[`period${period}d`];
|
periodStart.setDate(periodStart.getDate() - daysAgo);
|
||||||
|
periodStart.setHours(5, 0, 0, 0);
|
||||||
|
|
||||||
|
stats = sumStats(
|
||||||
|
Object.entries(
|
||||||
|
await getTankStatsOverTime(
|
||||||
|
server,
|
||||||
|
id,
|
||||||
|
periodStart.getTime() / 1000,
|
||||||
|
new Date().getTime() / 1000,
|
||||||
|
),
|
||||||
|
).map(([, stats]) => stats),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const image = await render(
|
const image = await render(
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
<TitleBar
|
<TitleBar
|
||||||
name={blitzStarsAccount.nickname}
|
name={accountInfo[id].nickname}
|
||||||
nameDiscriminator={
|
nameDiscriminator={
|
||||||
clanData[id]?.clan ? `[${clanData[id]?.clan?.tag}]` : undefined
|
clanData[id]?.clan ? `[${clanData[id]?.clan?.tag}]` : undefined
|
||||||
}
|
}
|
||||||
@@ -125,57 +107,44 @@ export default {
|
|||||||
} • ${new Date().toDateString()} • ${BLITZ_SERVERS[server]}`}
|
} • ${new Date().toDateString()} • ${BLITZ_SERVERS[server]}`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{stats.all.battles === 0 && <NoBattlesInPeriod />}
|
{stats.battles === 0 && <NoBattlesInPeriod />}
|
||||||
{stats.all.battles > 0 && (
|
{stats.battles > 0 && (
|
||||||
<GenericStats
|
<GenericStats
|
||||||
stats={[
|
stats={[
|
||||||
[
|
[
|
||||||
'Winrate',
|
'Winrate',
|
||||||
`${(100 * (stats.all.wins / stats.all.battles)).toFixed(2)}%`,
|
`${(100 * (stats.wins / stats.battles)).toFixed(2)}%`,
|
||||||
],
|
],
|
||||||
['WN8', stats.wn8.toFixed(0)],
|
// ['WN8', stats.wn8.toFixed(0)],
|
||||||
[
|
[
|
||||||
'Survival',
|
'Survival',
|
||||||
`${(
|
`${(100 * (stats.survived_battles / stats.battles)).toFixed(
|
||||||
100 *
|
2,
|
||||||
(stats.all.survived_battles / stats.all.battles)
|
)}%`,
|
||||||
).toFixed(2)}%`,
|
|
||||||
],
|
],
|
||||||
[
|
['Accuracy', `${((stats.hits / stats.shots) * 100).toFixed(2)}%`],
|
||||||
'Accuracy',
|
['Battles', stats.battles],
|
||||||
`${((stats.all.hits / stats.all.shots) * 100).toFixed(2)}%`,
|
['Wins', stats.wins],
|
||||||
],
|
['Losses', stats.losses],
|
||||||
['Battles', stats.all.battles],
|
|
||||||
['Wins', stats.all.wins],
|
|
||||||
['Losses', stats.all.losses],
|
|
||||||
[
|
[
|
||||||
'Average damage',
|
'Average damage',
|
||||||
(stats.all.damage_dealt / stats.all.battles).toFixed(0),
|
(stats.damage_dealt / stats.battles).toFixed(0),
|
||||||
],
|
],
|
||||||
['Average XP', (stats.all.xp / stats.all.battles).toFixed(0)],
|
['Average XP', (stats.xp / stats.battles).toFixed(0)],
|
||||||
[
|
['Average shots', (stats.shots / stats.battles).toFixed(2)],
|
||||||
'Average shots',
|
['Average hits', (stats.hits / stats.battles).toFixed(2)],
|
||||||
(stats.all.shots / stats.all.battles).toFixed(2),
|
['Average kills', (stats.frags / stats.battles).toFixed(2)],
|
||||||
],
|
['Average spots', (stats.spotted / stats.battles).toFixed(2)],
|
||||||
['Average hits', (stats.all.hits / stats.all.battles).toFixed(2)],
|
// ['Average tier', stats.avg_tier.toFixed(2)],
|
||||||
[
|
|
||||||
'Average kills',
|
|
||||||
(stats.all.frags / stats.all.battles).toFixed(2),
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'Average spots',
|
|
||||||
(stats.all.spotted / stats.all.battles).toFixed(2),
|
|
||||||
],
|
|
||||||
['Average tier', stats.avg_tier.toFixed(2)],
|
|
||||||
[
|
[
|
||||||
'Damage ratio',
|
'Damage ratio',
|
||||||
(stats.all.damage_dealt / stats.all.damage_received).toFixed(2),
|
(stats.damage_dealt / stats.damage_received).toFixed(2),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Kills to death ratio',
|
'Kills to death ratio',
|
||||||
(
|
(
|
||||||
stats.all.frags /
|
stats.frags /
|
||||||
(stats.all.battles - stats.all.survived_battles)
|
(stats.battles - stats.survived_battles)
|
||||||
).toFixed(2),
|
).toFixed(2),
|
||||||
],
|
],
|
||||||
]}
|
]}
|
||||||
@@ -196,7 +165,7 @@ export default {
|
|||||||
components: [actionRow],
|
components: [actionRow],
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`Showing stats for ${blitzStarsAccount.nickname}`);
|
console.log(`Showing stats for ${accountInfo[id].nickname}`);
|
||||||
},
|
},
|
||||||
|
|
||||||
autocomplete: usernameAutocomplete,
|
autocomplete: usernameAutocomplete,
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
import { CacheType, ChatInputCommandInteraction } from 'discord.js';
|
|
||||||
import { PlayerPeriodicStatsCollection } from '../../types/statistics.js';
|
|
||||||
import { notTrackedByBlitzStars } from '../interaction/notTrackedByBlitzStars.js';
|
|
||||||
|
|
||||||
export default async function getBlitzStarsAccount(
|
|
||||||
interaction: ChatInputCommandInteraction<CacheType>,
|
|
||||||
accountId: number,
|
|
||||||
) {
|
|
||||||
try {
|
|
||||||
const response = await fetch(
|
|
||||||
`https://www.blitzstars.com/api/top/player/${accountId}`,
|
|
||||||
);
|
|
||||||
const parsed = (await response.json()) as PlayerPeriodicStatsCollection;
|
|
||||||
|
|
||||||
if (parsed.statistics) {
|
|
||||||
return parsed;
|
|
||||||
} else throw new Error('No data to display');
|
|
||||||
} catch (error) {
|
|
||||||
await interaction.editReply({
|
|
||||||
embeds: [notTrackedByBlitzStars],
|
|
||||||
});
|
|
||||||
|
|
||||||
throw new Error(`${accountId} not tracked by BlitzStars.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in new issue
Block a user