mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 02:37:05 +02:00
feat: /stats
This commit is contained in:
1 parent
bf7993fa38
commit
4482b76746
8 files changed
+192
-37
No files matched your search
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"cSpell.words": ["Abhi", "accountinfo", "SKLLD", "wargaming"],
|
||||
"cSpell.words": ["Abhi", "accountinfo", "SKLLD", "wargaming", "winrate"],
|
||||
"deno.enable": false,
|
||||
"deno.unstable": false
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { EmbedBuilder, GuildMember, TextChannel } from 'discord.js';
|
||||
import discord from '../../discord.json' assert { type: 'json' };
|
||||
import { SKILLED_COLOR } from '../constants/colors.js';
|
||||
|
||||
export default async function (member: GuildMember) {
|
||||
console.log(`${member.user.tag} joined`);
|
||||
@@ -10,7 +11,7 @@ export default async function (member: GuildMember) {
|
||||
).send({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setColor('#8e3cf5')
|
||||
.setColor(SKILLED_COLOR)
|
||||
.setTitle(`Welcome ${member.user.username}`)
|
||||
.setDescription(
|
||||
`Welcome to the Skilled server, **${
|
||||
|
||||
+75
-2
@@ -1,14 +1,88 @@
|
||||
import {
|
||||
CacheType,
|
||||
ChatInputCommandInteraction,
|
||||
EmbedBuilder,
|
||||
SlashCommandBuilder,
|
||||
} from 'discord.js';
|
||||
import fetch from 'node-fetch';
|
||||
import { SKILLED_COLOR } from '../constants/colors.js';
|
||||
import { SERVERS } from '../constants/servers.js';
|
||||
import { PlayerStatistics } from '../types/statistics.js';
|
||||
import getBlitzAccount from '../utilities/getBlitzAccount.js';
|
||||
|
||||
export async function execute(
|
||||
interaction: ChatInputCommandInteraction<CacheType>,
|
||||
) {
|
||||
interaction.reply('YOU SUCK MORON GO PLAY ROBLOX');
|
||||
const ign = interaction.options.getString('ign')!;
|
||||
const server = interaction.options.getString(
|
||||
'server',
|
||||
) as keyof typeof SERVERS;
|
||||
const period = interaction.options.getString('period')! as
|
||||
| '30'
|
||||
| '90'
|
||||
| 'career';
|
||||
|
||||
getBlitzAccount(interaction, ign, server, async (account) => {
|
||||
const data = (await (
|
||||
await fetch(
|
||||
`https://www.blitzstars.com/api/top/player/${account.account_id}`,
|
||||
)
|
||||
).json()) as PlayerStatistics;
|
||||
const stats =
|
||||
period === 'career' ? data.statistics : data[`period${period}d`];
|
||||
|
||||
interaction.reply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setColor(SKILLED_COLOR)
|
||||
.setTitle(
|
||||
`${data.nickname}'s ${
|
||||
period === 'career' ? period : `${period} day`
|
||||
} stats`,
|
||||
)
|
||||
.setDescription(
|
||||
`${[
|
||||
['Winrate', `${stats.special.winrate.toFixed(2)}%`],
|
||||
['Survival', `${stats.special.survivalRate.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)],
|
||||
[],
|
||||
['Hits per battle', stats.special.hpb.toFixed(0)],
|
||||
['Damage per battle', stats.special.dpb.toFixed(0)],
|
||||
['Kills per battle', stats.special.kpb.toFixed(2)],
|
||||
['Spots per battle', stats.special.spb.toFixed(2)],
|
||||
[
|
||||
'Shots per battle',
|
||||
(stats.all.shots / stats.all.battles).toFixed(2),
|
||||
],
|
||||
[
|
||||
'Hits per battle',
|
||||
(stats.all.hits / stats.all.battles).toFixed(2),
|
||||
],
|
||||
['XP per battle', (stats.all.xp / stats.all.battles).toFixed(2)],
|
||||
[],
|
||||
['Damage ratio', stats.special.damageRatio.toFixed(2)],
|
||||
['Kills to death ratio', stats.special.kdr.toFixed(2)],
|
||||
]
|
||||
.map((array) =>
|
||||
array.length === 0 ? '' : `**${array[0]}**: ${array[1]}`,
|
||||
)
|
||||
.join(
|
||||
'\n',
|
||||
)}\n\nPowered by [BlitzStars](https://www.blitzstars.com/)`,
|
||||
),
|
||||
],
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export const data = new SlashCommandBuilder()
|
||||
@@ -37,7 +111,6 @@ export const data = new SlashCommandBuilder()
|
||||
.setDescription('The last number of days of stats')
|
||||
.setChoices(
|
||||
{ name: '30 Days', value: '30' },
|
||||
{ name: '60 Days', value: '60' },
|
||||
{ name: '90 Days', value: '90' },
|
||||
{ name: 'Career', value: 'career' },
|
||||
)
|
||||
|
||||
+11
-32
@@ -6,8 +6,9 @@ import {
|
||||
} from 'discord.js';
|
||||
import fetch from 'node-fetch';
|
||||
import discord from '../../discord.json' assert { type: 'json' };
|
||||
import { NEGATIVE_COLOR, POSITIVE_COLOR } from '../constants/colors.js';
|
||||
import { SERVERS } from '../constants/servers.js';
|
||||
import AccountList from '../types/accountList.js';
|
||||
import getBlitzAccount from '../utilities/getBlitzAccount.js';
|
||||
|
||||
export const disabled = true;
|
||||
|
||||
@@ -15,20 +16,18 @@ export async function execute(
|
||||
interaction: ChatInputCommandInteraction<CacheType>,
|
||||
) {
|
||||
const ign = interaction.options.getString('ign')!;
|
||||
const server = interaction.options.getString('server')!;
|
||||
const serverName = SERVERS[server as keyof typeof SERVERS];
|
||||
const players = (await fetch(
|
||||
`https://api.wotblitz.${server}/wotb/account/list/?application_id=${process.env.WARGAMING_APPLICATION_ID}&search=${ign}`,
|
||||
).then((response) => response.json())) as AccountList;
|
||||
const server = interaction.options.getString(
|
||||
'server',
|
||||
) as keyof typeof SERVERS;
|
||||
|
||||
if (players?.data?.[0]?.nickname === ign) {
|
||||
getBlitzAccount(interaction, ign, server, async (account) => {
|
||||
// good match
|
||||
const clanData = (await fetch(
|
||||
`https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${process.env.WARGAMING_APPLICATION_ID}&account_id=${players.data[0].account_id}&extra=clan`,
|
||||
`https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${process.env.WARGAMING_APPLICATION_ID}&account_id=${account.account_id}&extra=clan`,
|
||||
).then((response) => response.json())) as {
|
||||
data: { [key: number]: { clan: { tag: string } | null } };
|
||||
};
|
||||
const clan = clanData.data[players.data[0].account_id].clan;
|
||||
const clan = clanData.data[account.account_id].clan;
|
||||
const clanTag = clan === null ? '' : ` [${clan.tag}]`;
|
||||
|
||||
if (interaction.member && interaction.guild) {
|
||||
@@ -44,7 +43,7 @@ export async function execute(
|
||||
await interaction.reply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setColor('#82ff29')
|
||||
.setColor(POSITIVE_COLOR)
|
||||
.setTitle(`${interaction.user.username} is verified`)
|
||||
.setDescription(`The user is now verified as ${ign}${clanTag}`),
|
||||
],
|
||||
@@ -58,7 +57,7 @@ export async function execute(
|
||||
await interaction.reply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setColor('#ff4747')
|
||||
.setColor(NEGATIVE_COLOR)
|
||||
.setTitle(`${interaction.user.username} failed to verify`)
|
||||
.setDescription(
|
||||
'I may not have the permission to change your nickname.',
|
||||
@@ -71,27 +70,7 @@ export async function execute(
|
||||
);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// no exact match
|
||||
interaction.reply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setColor('#ff4747')
|
||||
.setTitle(`Account not found`)
|
||||
.setDescription(
|
||||
`Are you sure your username is exactly "${ign}" in the ${serverName} server? I found ${
|
||||
players?.data
|
||||
? players.data.length < 100
|
||||
? players.data.length
|
||||
: 'over 100'
|
||||
: 'no'
|
||||
} similarly spelled account${
|
||||
players?.data?.length !== 1 ? 's' : ''
|
||||
}. Try re-running the command. Don't make typos and capitalize correctly.`,
|
||||
),
|
||||
],
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const data = new SlashCommandBuilder()
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export const SKILLED_COLOR = '#8e3cf5';
|
||||
export const POSITIVE_COLOR = '#82ff29';
|
||||
export const NEGATIVE_COLOR = '#ff4747';
|
||||
@@ -1,6 +1,11 @@
|
||||
export interface Account {
|
||||
nickname: string;
|
||||
account_id: number;
|
||||
}
|
||||
|
||||
type AccountList =
|
||||
| {
|
||||
data?: { nickname: string; account_id: number }[];
|
||||
data?: Account[];
|
||||
}
|
||||
| undefined;
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
export interface PeriodStatistics {
|
||||
all: {
|
||||
spotted: number;
|
||||
hits: number;
|
||||
frags: number;
|
||||
wins: number;
|
||||
losses: number;
|
||||
capture_points: number;
|
||||
battles: number;
|
||||
damage_dealt: number;
|
||||
damage_received: number;
|
||||
shots: number;
|
||||
frags8p: number;
|
||||
xp: number;
|
||||
win_and_survived: number;
|
||||
survived_battles: number;
|
||||
dropped_capture_points: number;
|
||||
};
|
||||
special: {
|
||||
winrate: number;
|
||||
damageRatio: number;
|
||||
kdr: number;
|
||||
dpb: number;
|
||||
kpb: number;
|
||||
hpb: number;
|
||||
spb: number;
|
||||
hitRate: number;
|
||||
survivalRate: number;
|
||||
};
|
||||
|
||||
wn7: number;
|
||||
wn8: number;
|
||||
avg_tier: number;
|
||||
pwp: number;
|
||||
}
|
||||
|
||||
export interface PlayerStatistics {
|
||||
statistics: PeriodStatistics;
|
||||
period30d: PeriodStatistics;
|
||||
period90d: PeriodStatistics;
|
||||
|
||||
_id: string;
|
||||
nickname: string;
|
||||
nickname_lowercase: string;
|
||||
region: string;
|
||||
last_battle_time: number;
|
||||
__v: number;
|
||||
updatedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import {
|
||||
CacheType,
|
||||
ChatInputCommandInteraction,
|
||||
EmbedBuilder,
|
||||
} from 'discord.js';
|
||||
import { NEGATIVE_COLOR } from '../constants/colors.js';
|
||||
import { SERVERS } from '../constants/servers.js';
|
||||
import AccountList, { Account } from '../types/accountList.js';
|
||||
|
||||
export default async function getBlitzAccount(
|
||||
interaction: ChatInputCommandInteraction<CacheType>,
|
||||
ign: string,
|
||||
server: keyof typeof SERVERS,
|
||||
callback: (account: Account) => void,
|
||||
) {
|
||||
const serverName = SERVERS[server];
|
||||
const players = (await fetch(
|
||||
`https://api.wotblitz.${server}/wotb/account/list/?application_id=${process.env.WARGAMING_APPLICATION_ID}&search=${ign}`,
|
||||
).then((response) => response.json())) as AccountList;
|
||||
|
||||
if (players?.data?.[0]?.nickname === ign) {
|
||||
callback(players.data[0]);
|
||||
} else {
|
||||
// no exact match
|
||||
interaction.reply({
|
||||
embeds: [
|
||||
new EmbedBuilder()
|
||||
.setColor(NEGATIVE_COLOR)
|
||||
.setTitle(`Account not found`)
|
||||
.setDescription(
|
||||
`Are you sure your username is exactly "${ign}" in the ${serverName} server? I found ${
|
||||
players?.data
|
||||
? players.data.length < 100
|
||||
? players.data.length
|
||||
: 'over 100'
|
||||
: 0
|
||||
} similarly spelled account${
|
||||
players?.data?.length !== 1 ? 's' : ''
|
||||
}. Try re-running the command. Don't make typos and capitalize correctly.`,
|
||||
),
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user