diff --git a/src/behaviors/interactionCreate.ts b/src/behaviors/interactionCreate.ts index 4b9f674e4..9397ea904 100644 --- a/src/behaviors/interactionCreate.ts +++ b/src/behaviors/interactionCreate.ts @@ -1,5 +1,6 @@ import { CacheType, + ChatInputCommandInteraction, Collection, Interaction, REST, @@ -13,34 +14,53 @@ import getClientId from '../utilities/getClientId.js'; import isDev from '../utilities/isDev.js'; export interface CommandRegistry { - inDev?: boolean; - data: SlashCommandBuilder; - execute: (interaction: Interaction) => void; + inDevelopment: boolean; // register with Skilled Bot (default: false) + inProduction: boolean; // register with Skilled Canary (default: false) + inPublic: boolean; // registers on all servers (default: true) + + command: Omit; + execute: (interaction: ChatInputCommandInteraction) => void; } -const commandCollection = new Collection(); -const commands: RESTPostAPIChatInputApplicationCommandsJSONBody[] = []; -const commandFolders = readdirSync('src/commands/'); const rest = new REST().setToken(process.env.DISCORD_TOKEN!); +const commandFolders = readdirSync('src/commands/'); +const commandCollection = new Collection(); +const guildCommands: RESTPostAPIChatInputApplicationCommandsJSONBody[] = []; +const publicCommands: RESTPostAPIChatInputApplicationCommandsJSONBody[] = []; for (const file of commandFolders) { - const command = (await import(`../commands/${file}`)) as CommandRegistry; + const command = (await import(`../commands/${file}`)) + .default as CommandRegistry; - if (isDev() ? command.inDev ?? false : true) { - commands.push(command.data.toJSON()); - commandCollection.set(command.data.name, command); + if (isDev() ? command.inDevelopment : command.inProduction) { + if (command.inPublic) { + publicCommands.push(command.command.toJSON()); + } else { + guildCommands.push(command.command.toJSON()); + } + + commandCollection.set(command.command.name, command); } } try { - console.log(`Started refreshing ${commands.length} command(s).`); + console.log(`Refreshing ${guildCommands.length} guild command(s).`); - const data = (await rest.put( + const guildData = (await rest.put( Routes.applicationGuildCommands(getClientId(), discord.guild_id), - { body: commands }, + { body: guildCommands }, )) as RESTPostAPIChatInputApplicationCommandsJSONBody[]; - console.log(`Successfully reloaded ${data.length} command(s).`); + console.log(`Successfully refreshed ${guildData.length} guild command(s).`); + + console.log(`Refreshing ${publicCommands.length} public command(s).`); + + const publicData = (await rest.put( + Routes.applicationCommands(getClientId()), + { body: publicCommands }, + )) as RESTPostAPIChatInputApplicationCommandsJSONBody[]; + + console.log(`Successfully refreshed ${publicData.length} public command(s).`); } catch (error) { console.error(error); } diff --git a/src/commands/eligible.ts b/src/commands/eligible.ts index 1e588bbbb..13d704eed 100644 --- a/src/commands/eligible.ts +++ b/src/commands/eligible.ts @@ -1,9 +1,5 @@ -import { - CacheType, - ChatInputCommandInteraction, - EmbedBuilder, - SlashCommandBuilder, -} from 'discord.js'; +import { EmbedBuilder, SlashCommandBuilder } from 'discord.js'; +import { CommandRegistry } from '../behaviors/interactionCreate.js'; import { NEGATIVE_COLOR, POSITIVE_COLOR } from '../constants/colors.js'; import { BLITZ_SERVERS, BlitzServer } from '../constants/servers.js'; import blitzLinks from '../utilities/blitzLinks.js'; @@ -22,131 +18,140 @@ export const CLANS = { }, }; -export async function execute( - interaction: ChatInputCommandInteraction, -) { - const ign = interaction.options.getString('ign')!; - const server = interaction.options.getString('server') as BlitzServer; - const clan = interaction.options.getString('clan') as keyof typeof CLANS; +export default { + inProduction: true, + inDevelopment: false, + inPublic: false, - getBlitzAccount(interaction, ign, server, async (account) => { - getBlitzStarsAccount(interaction, account.account_id, ign, async (data) => { - const issues: string[] = []; + command: new SlashCommandBuilder() + .setName('eligible') + .setDescription("Gets the user's eligibility for Skilled clans") + .addStringOption((option) => + option + .setName('clan') + .setDescription('The Skilled clan you are checking') + .addChoices( + { name: CLANS.sklld.name, value: 'sklld' }, + { name: CLANS.smri.name, value: 'smri' }, + ) + .setRequired(true), + ) + .addStringOption((option) => + option + .setName('server') + .setDescription('The Blitz server you are in') + .addChoices( + { name: BLITZ_SERVERS.com, value: 'com' }, + { name: BLITZ_SERVERS.eu, value: 'eu' }, + { name: BLITZ_SERVERS.asia, value: 'asia' }, + ) + .setRequired(true), + ) + .addStringOption((option) => + option + .setName('ign') + .setDescription('The username you use in Blitz') + .setRequired(true), + ), - if (clan === 'sklld') { - if (data.period30d.all.battles < 150) { - issues.push( - `**Battles**: ${data.period30d.all.battles} (${ - data.period30d.all.battles - 150 - })`, - ); - } - if (data.period30d.avg_tier < 8) { - issues.push( - `**Tier**: ${data.period30d.avg_tier.toFixed(2)} (${( - data.period30d.avg_tier - 8 - ).toFixed(2)})`, - ); - } - if (data.period30d.special.winrate < 60) { - issues.push( - `**Winrate**: ${data.period30d.special.winrate.toFixed(2)}% (${( - data.period30d.special.winrate - 60 - ).toFixed(2)}%)`, - ); - } - if (data.period30d.wn8 < 2100) { - issues.push( - `**WN8**: ${data.period30d.wn8.toFixed(0)} (${( - data.period30d.wn8 - 2100 - ).toFixed(0)})`, - ); - } - if (data.period30d.special.dpb < 2400) { - issues.push( - `**Damage per battle**: ${data.period30d.special.dpb.toFixed( - 0, - )} (${(data.period30d.special.dpb - 2400).toFixed(0)})`, - ); - } - } else { - if (data.statistics.all.battles < 1500) { - issues.push( - `**Battles**: ${data.statistics.all.battles} (${ - data.statistics.all.battles - 1500 - })`, - ); - } - if (data.statistics.special.winrate < 53) { - issues.push( - `**Winrate**: ${data.statistics.special.winrate.toFixed(2)}% (${( - data.statistics.special.winrate - 53 - ).toFixed(2)}%)`, - ); - } - } + execute(interaction) { + const ign = interaction.options.getString('ign')!; + const server = interaction.options.getString('server') as BlitzServer; + const clan = interaction.options.getString('clan') as keyof typeof CLANS; - const eligible = issues.length === 0; + getBlitzAccount(interaction, ign, server, async (account) => { + getBlitzStarsAccount( + interaction, + account.account_id, + ign, + async (data) => { + const issues: string[] = []; - await interaction.reply({ - embeds: [ - poweredByBlitzStars( - new EmbedBuilder() - .setTitle( - `${data.nickname} is ${eligible ? '' : 'not '}eligible for ${ - CLANS[clan].name - }`, - ) - .setColor(eligible ? POSITIVE_COLOR : NEGATIVE_COLOR) - .setDescription( - `${ - eligible - ? `${data.nickname} meets all the requirements set for ${CLANS[clan].name}.` - : `${data.nickname}'s shortcomings for ${ - CLANS[clan].name - } (${ - clan === 'sklld' ? '30 days stats' : 'career stats' - }):\n\n${issues.join('\n')}` - }\n\n${blitzLinks(data)}`, + if (clan === 'sklld') { + if (data.period30d.all.battles < 150) { + issues.push( + `**Battles**: ${data.period30d.all.battles} (${ + data.period30d.all.battles - 150 + })`, + ); + } + if (data.period30d.avg_tier < 8) { + issues.push( + `**Tier**: ${data.period30d.avg_tier.toFixed(2)} (${( + data.period30d.avg_tier - 8 + ).toFixed(2)})`, + ); + } + if (data.period30d.special.winrate < 60) { + issues.push( + `**Winrate**: ${data.period30d.special.winrate.toFixed(2)}% (${( + data.period30d.special.winrate - 60 + ).toFixed(2)}%)`, + ); + } + if (data.period30d.wn8 < 2100) { + issues.push( + `**WN8**: ${data.period30d.wn8.toFixed(0)} (${( + data.period30d.wn8 - 2100 + ).toFixed(0)})`, + ); + } + if (data.period30d.special.dpb < 2400) { + issues.push( + `**Damage per battle**: ${data.period30d.special.dpb.toFixed( + 0, + )} (${(data.period30d.special.dpb - 2400).toFixed(0)})`, + ); + } + } else { + if (data.statistics.all.battles < 1500) { + issues.push( + `**Battles**: ${data.statistics.all.battles} (${ + data.statistics.all.battles - 1500 + })`, + ); + } + if (data.statistics.special.winrate < 53) { + issues.push( + `**Winrate**: ${data.statistics.special.winrate.toFixed( + 2, + )}% (${(data.statistics.special.winrate - 53).toFixed(2)}%)`, + ); + } + } + + const eligible = issues.length === 0; + + await interaction.reply({ + embeds: [ + poweredByBlitzStars( + new EmbedBuilder() + .setTitle( + `${data.nickname} is ${ + eligible ? '' : 'not ' + }eligible for ${CLANS[clan].name}`, + ) + .setColor(eligible ? POSITIVE_COLOR : NEGATIVE_COLOR) + .setDescription( + `${ + eligible + ? `${data.nickname} meets all the requirements set for ${CLANS[clan].name}.` + : `${data.nickname}'s shortcomings for ${ + CLANS[clan].name + } (${ + clan === 'sklld' ? '30 days stats' : 'career stats' + }):\n\n${issues.join('\n')}` + }\n\n${blitzLinks(data)}`, + ), ), - ), - ], - }); + ], + }); - console.log( - `Showing ${data.nickname}'s eligibility for ${CLANS[clan].name}`, + console.log( + `Showing ${data.nickname}'s eligibility for ${CLANS[clan].name}`, + ); + }, ); }); - }); -} - -export const data = new SlashCommandBuilder() - .setName('eligible') - .setDescription("Gets the user's eligibility for Skilled clans") - .addStringOption((option) => - option - .setName('clan') - .setDescription('The Skilled clan you are checking') - .addChoices( - { name: CLANS.sklld.name, value: 'sklld' }, - { name: CLANS.smri.name, value: 'smri' }, - ) - .setRequired(true), - ) - .addStringOption((option) => - option - .setName('server') - .setDescription('The Blitz server you are in') - .addChoices( - { name: BLITZ_SERVERS.com, value: 'com' }, - { name: BLITZ_SERVERS.eu, value: 'eu' }, - { name: BLITZ_SERVERS.asia, value: 'asia' }, - ) - .setRequired(true), - ) - .addStringOption((option) => - option - .setName('ign') - .setDescription('The username you use in Blitz') - .setRequired(true), - ); + }, +} satisfies CommandRegistry; diff --git a/src/commands/inactive.ts b/src/commands/inactive.ts index 5237997c8..417216258 100644 --- a/src/commands/inactive.ts +++ b/src/commands/inactive.ts @@ -1,10 +1,6 @@ -import { - CacheType, - ChatInputCommandInteraction, - EmbedBuilder, - SlashCommandBuilder, -} from 'discord.js'; +import { EmbedBuilder, SlashCommandBuilder } from 'discord.js'; import fetch from 'node-fetch'; +import { CommandRegistry } from '../behaviors/interactionCreate.js'; import { NEGATIVE_COLOR, POSITIVE_COLOR } from '../constants/colors.js'; import { ClanDetails } from '../types/clanDetails.js'; import { PlayerPersonalData } from '../types/playerPersonalData.js'; @@ -12,85 +8,91 @@ import { CLANS } from './eligible.js'; const DEFAULT_THRESHOLD = 7; -export async function execute( - interaction: ChatInputCommandInteraction, -) { - const threshold = - interaction.options.getNumber('threshold')! ?? DEFAULT_THRESHOLD; - const time = new Date().getTime() / 1000; - const clanName = interaction.options.getString('clan') as keyof typeof CLANS; - const clanData = (await ( - await fetch( - `https://api.wotblitz.com/wotb/clans/info/?application_id=${process.env.WARGAMING_APPLICATION_ID}&clan_id=${CLANS[clanName].id}`, - ) - ).json()) as ClanDetails; - const clan = clanData.data[CLANS[clanName].id]; - const memberIds = clan.members_ids; - const playerPersonalData = (await ( - await fetch( - `https://api.wotblitz.com/wotb/account/info/?application_id=${ - process.env.WARGAMING_APPLICATION_ID - }&account_id=${memberIds.join(',')}`, - ) - ).json()) as PlayerPersonalData; +export default { + inProduction: true, + inDevelopment: false, + inPublic: false, - const inactiveInfo = memberIds - .map((memberId) => { - const member = playerPersonalData.data[memberId]; - const inactiveDays = (time - member.last_battle_time) / 60 / 60 / 24; - - return [member.nickname, inactiveDays] as const; - }) - .filter(([, inactiveDays]) => inactiveDays >= threshold) - .sort((a, b) => b[1] - a[1]) - .map(([nickname, inactiveDays]) => { - const days = Math.floor(inactiveDays); - return `**${nickname}**: ${days} day${days === 1 ? '' : 's'}`; - }); - const hasInactiveMembers = inactiveInfo.length > 0; - - await interaction.reply({ - embeds: [ - new EmbedBuilder() - .setColor(hasInactiveMembers ? NEGATIVE_COLOR : POSITIVE_COLOR) - .setTitle( - hasInactiveMembers - ? `${CLANS[clanName].name}'s inactive members` - : `No inactive members in ${CLANS[clanName].name}`, + command: new SlashCommandBuilder() + .setName('inactive') + .setDescription('Lists all inactive players') + .addStringOption((option) => + option + .setName('clan') + .setDescription('The Skilled clan you are checking') + .addChoices( + { name: CLANS.sklld.name, value: 'sklld' }, + { name: CLANS.smri.name, value: 'smri' }, ) + .setRequired(true), + ) + .addNumberOption((option) => + option + .setName('threshold') .setDescription( - hasInactiveMembers - ? `Players that exceed the threshold of ${threshold} days:\n\n${inactiveInfo.join( - '\n', - )}` - : `No players exceed the threshold of ${threshold} days.`, - ), - ], - }); + `The number of days inactive (default: ${DEFAULT_THRESHOLD})`, + ) + .setMinValue(0), + ), - console.log( - `Displaying inactive members in ${CLANS[clanName].name} for ${threshold} days`, - ); -} + async execute(interaction) { + const threshold = + interaction.options.getNumber('threshold')! ?? DEFAULT_THRESHOLD; + const time = new Date().getTime() / 1000; + const clanName = interaction.options.getString( + 'clan', + ) as keyof typeof CLANS; + const clanData = (await ( + await fetch( + `https://api.wotblitz.com/wotb/clans/info/?application_id=${process.env.WARGAMING_APPLICATION_ID}&clan_id=${CLANS[clanName].id}`, + ) + ).json()) as ClanDetails; + const clan = clanData.data[CLANS[clanName].id]; + const memberIds = clan.members_ids; + const playerPersonalData = (await ( + await fetch( + `https://api.wotblitz.com/wotb/account/info/?application_id=${ + process.env.WARGAMING_APPLICATION_ID + }&account_id=${memberIds.join(',')}`, + ) + ).json()) as PlayerPersonalData; -export const data = new SlashCommandBuilder() - .setName('inactive') - .setDescription('Lists all inactive players') - .addStringOption((option) => - option - .setName('clan') - .setDescription('The Skilled clan you are checking') - .addChoices( - { name: CLANS.sklld.name, value: 'sklld' }, - { name: CLANS.smri.name, value: 'smri' }, - ) - .setRequired(true), - ) - .addNumberOption((option) => - option - .setName('threshold') - .setDescription( - `The number of days inactive (default: ${DEFAULT_THRESHOLD})`, - ) - .setMinValue(0), - ); + const inactiveInfo = memberIds + .map((memberId) => { + const member = playerPersonalData.data[memberId]; + const inactiveDays = (time - member.last_battle_time) / 60 / 60 / 24; + + return [member.nickname, inactiveDays] as const; + }) + .filter(([, inactiveDays]) => inactiveDays >= threshold) + .sort((a, b) => b[1] - a[1]) + .map(([nickname, inactiveDays]) => { + const days = Math.floor(inactiveDays); + return `**${nickname}**: ${days} day${days === 1 ? '' : 's'}`; + }); + const hasInactiveMembers = inactiveInfo.length > 0; + + await interaction.reply({ + embeds: [ + new EmbedBuilder() + .setColor(hasInactiveMembers ? NEGATIVE_COLOR : POSITIVE_COLOR) + .setTitle( + hasInactiveMembers + ? `${CLANS[clanName].name}'s inactive members` + : `No inactive members in ${CLANS[clanName].name}`, + ) + .setDescription( + hasInactiveMembers + ? `Players that exceed the threshold of ${threshold} days:\n\n${inactiveInfo.join( + '\n', + )}` + : `No players exceed the threshold of ${threshold} days.`, + ), + ], + }); + + console.log( + `Displaying inactive members in ${CLANS[clanName].name} for ${threshold} days`, + ); + }, +} satisfies CommandRegistry; diff --git a/src/commands/stats.ts b/src/commands/stats.ts index 7e095ae53..052ecefe8 100644 --- a/src/commands/stats.ts +++ b/src/commands/stats.ts @@ -1,9 +1,5 @@ -import { - CacheType, - ChatInputCommandInteraction, - EmbedBuilder, - SlashCommandBuilder, -} from 'discord.js'; +import { EmbedBuilder, SlashCommandBuilder } from 'discord.js'; +import { CommandRegistry } from '../behaviors/interactionCreate.js'; import { SKILLED_COLOR } from '../constants/colors.js'; import { BLITZ_SERVERS, BlitzServer } from '../constants/servers.js'; import blitzLinks from '../utilities/blitzLinks.js'; @@ -11,113 +7,127 @@ import getBlitzAccount from '../utilities/getBlitzAccount.js'; import getBlitzStarsAccount from '../utilities/getBlitzStarsAccount.js'; import poweredByBlitzStars from '../utilities/poweredByBlitzStars.js'; -export async function execute( - interaction: ChatInputCommandInteraction, -) { - const ign = interaction.options.getString('ign')!; - const server = interaction.options.getString('server') as BlitzServer; - const period = interaction.options.getString('period')! as - | '30' - | '90' - | 'career'; +export default { + inProduction: true, + inDevelopment: true, + inPublic: true, - getBlitzAccount(interaction, ign, server, async (account) => { - getBlitzStarsAccount(interaction, account.account_id, ign, async (data) => { - { - const stats = - period === 'career' ? data.statistics : data[`period${period}d`]; + command: new SlashCommandBuilder() + .setName('stats') + .setDescription("Gets the user's in-game statistics") + .addStringOption((option) => + option + .setName('period') + .setDescription('The last number of days of stats') + .setChoices( + { name: '30 Days', value: '30' }, + { name: '90 Days', value: '90' }, + { name: 'Career', value: 'career' }, + ) + .setRequired(true), + ) + .addStringOption((option) => + option + .setName('server') + .setDescription('The Blitz server you are in') + .addChoices( + { name: BLITZ_SERVERS.com, value: 'com' }, + { name: BLITZ_SERVERS.eu, value: 'eu' }, + { name: BLITZ_SERVERS.asia, value: 'asia' }, + ) + .setRequired(true), + ) + .addStringOption((option) => + option + .setName('ign') + .setDescription('The username you use in Blitz') + .setRequired(true), + ), - await interaction.reply({ - embeds: [ - poweredByBlitzStars( - 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(2)], - ['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(0), - ], - [], - ['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]}`, + execute(interaction) { + const ign = interaction.options.getString('ign')!; + const server = interaction.options.getString('server') as BlitzServer; + const period = interaction.options.getString('period')! as + | '30' + | '90' + | 'career'; + + getBlitzAccount(interaction, ign, server, async (account) => { + getBlitzStarsAccount( + interaction, + account.account_id, + ign, + async (data) => { + { + const stats = + period === 'career' ? data.statistics : data[`period${period}d`]; + + await interaction.reply({ + embeds: [ + poweredByBlitzStars( + new EmbedBuilder() + .setColor(SKILLED_COLOR) + .setTitle( + `${data.nickname}'s ${ + period === 'career' ? period : `${period} day` + } stats`, ) - .join('\n')}\n\n${blitzLinks(data)}`, + .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(2)], + ['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(0), + ], + [], + ['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\n${blitzLinks(data)}`, + ), ), - ), - ], - }); + ], + }); - console.log(`Showing ${data.nickname}'s ${period} stats`); - } + console.log(`Showing ${data.nickname}'s ${period} stats`); + } + }, + ); }); - }); -} - -export const data = new SlashCommandBuilder() - .setName('stats') - .setDescription("Gets the user's in-game statistics") - .addStringOption((option) => - option - .setName('period') - .setDescription('The last number of days of stats') - .setChoices( - { name: '30 Days', value: '30' }, - { name: '90 Days', value: '90' }, - { name: 'Career', value: 'career' }, - ) - .setRequired(true), - ) - .addStringOption((option) => - option - .setName('server') - .setDescription('The Blitz server you are in') - .addChoices( - { name: BLITZ_SERVERS.com, value: 'com' }, - { name: BLITZ_SERVERS.eu, value: 'eu' }, - { name: BLITZ_SERVERS.asia, value: 'asia' }, - ) - .setRequired(true), - ) - .addStringOption((option) => - option - .setName('ign') - .setDescription('The username you use in Blitz') - .setRequired(true), - ); + }, +} satisfies CommandRegistry; diff --git a/src/commands/tanks.ts b/src/commands/tanks.ts index 9bf7d5740..631dfb888 100644 --- a/src/commands/tanks.ts +++ b/src/commands/tanks.ts @@ -1,85 +1,85 @@ -import { - CacheType, - ChatInputCommandInteraction, - EmbedBuilder, - SlashCommandBuilder, -} from 'discord.js'; +import { EmbedBuilder, SlashCommandBuilder } from 'discord.js'; import fetch from 'node-fetch'; +import { CommandRegistry } from '../behaviors/interactionCreate.js'; import { SKILLED_COLOR } from '../constants/colors.js'; import { BLITZ_SERVERS, BlitzServer } from '../constants/servers.js'; import { TanksStats } from '../types/tanksStats.js'; import getBlitzAccount from '../utilities/getBlitzAccount.js'; import { tankTypeEmojis, tankopedia } from '../utilities/tankopedia.js'; -export async function execute( - interaction: ChatInputCommandInteraction, -) { - const server = interaction.options.getString('server') as BlitzServer; - const ign = interaction.options.getString('ign')!; - const tier = Math.round(interaction.options.getNumber('tier')!); +export default { + inProduction: true, + inDevelopment: false, + inPublic: true, - getBlitzAccount(interaction, ign, server, async (account) => { - const tankStats = (await ( - await fetch( - `https://api.wotblitz.${server}/wotb/tanks/stats/?application_id=${process.env.WARGAMING_APPLICATION_ID}&account_id=${account.account_id}`, - ) - ).json()) as TanksStats; + command: new SlashCommandBuilder() + .setName('tanks') + .setDescription("Shows a player's owned tanks") + .addStringOption((option) => + option + .setName('server') + .setDescription('The Blitz server you are in') + .setRequired(true) + .addChoices( + { name: BLITZ_SERVERS.com, value: 'com' }, + { name: BLITZ_SERVERS.eu, value: 'eu' }, + { name: BLITZ_SERVERS.asia, value: 'asia' }, + ), + ) + .addStringOption((option) => + option + .setName('ign') + .setDescription('The username you use in Blitz') + .setRequired(true), + ) + .addNumberOption((option) => + option + .setName('tier') + .setDescription('The tier you want to see (default: all tiers)') + .setMinValue(1) + .setMaxValue(10) + .setRequired(true), + ), - const tanks = tankStats.data[account.account_id]!.map( - (tankData) => tankopedia.data[tankData.tank_id], - ).filter((tank) => tank.tier === tier); + execute(interaction) { + const server = interaction.options.getString('server') as BlitzServer; + const ign = interaction.options.getString('ign')!; + const tier = Math.round(interaction.options.getNumber('tier')!); - interaction.reply({ - embeds: [ - new EmbedBuilder() - .setTitle( - `${account.nickname}'s owned ${ - tier === null ? '' : `tier ${tier} ` - }tanks`, - ) - .setDescription( - tanks.length === 0 - ? `No tanks found for player in tier ${tier}` - : tanks - .map( - (tank) => - `${tankTypeEmojis[tank.type]} ${tank.name} ${ - tank.is_premium ? '⭐' : '' - }`, - ) - .join('\n'), - ) - .setColor(SKILLED_COLOR), - ], + getBlitzAccount(interaction, ign, server, async (account) => { + const tankStats = (await ( + await fetch( + `https://api.wotblitz.${server}/wotb/tanks/stats/?application_id=${process.env.WARGAMING_APPLICATION_ID}&account_id=${account.account_id}`, + ) + ).json()) as TanksStats; + + const tanks = tankStats.data[account.account_id]!.map( + (tankData) => tankopedia.data[tankData.tank_id], + ).filter((tank) => tank.tier === tier); + + interaction.reply({ + embeds: [ + new EmbedBuilder() + .setTitle( + `${account.nickname}'s owned ${ + tier === null ? '' : `tier ${tier} ` + }tanks`, + ) + .setDescription( + tanks.length === 0 + ? `No tanks found for player in tier ${tier}` + : tanks + .map( + (tank) => + `${tankTypeEmojis[tank.type]} ${tank.name} ${ + tank.is_premium ? '⭐' : '' + }`, + ) + .join('\n'), + ) + .setColor(SKILLED_COLOR), + ], + }); }); - }); -} - -export const data = new SlashCommandBuilder() - .setName('tanks') - .setDescription("Shows a player's owned tanks") - .addStringOption((option) => - option - .setName('server') - .setDescription('The Blitz server you are in') - .setRequired(true) - .addChoices( - { name: BLITZ_SERVERS.com, value: 'com' }, - { name: BLITZ_SERVERS.eu, value: 'eu' }, - { name: BLITZ_SERVERS.asia, value: 'asia' }, - ), - ) - .addStringOption((option) => - option - .setName('ign') - .setDescription('The username you use in Blitz') - .setRequired(true), - ) - .addNumberOption((option) => - option - .setName('tier') - .setDescription('The tier you want to see (default: all tiers)') - .setMinValue(1) - .setMaxValue(10) - .setRequired(true), - ); + }, +} satisfies CommandRegistry; diff --git a/src/commands/verify.ts b/src/commands/verify.ts index 1c70e1262..3223443d1 100644 --- a/src/commands/verify.ts +++ b/src/commands/verify.ts @@ -1,90 +1,92 @@ -import { - CacheType, - ChatInputCommandInteraction, - EmbedBuilder, - SlashCommandBuilder, -} from 'discord.js'; +import { EmbedBuilder, SlashCommandBuilder } from 'discord.js'; import fetch from 'node-fetch'; import discord from '../../discord.json' assert { type: 'json' }; +import { CommandRegistry } from '../behaviors/interactionCreate.js'; import { NEGATIVE_COLOR, POSITIVE_COLOR } from '../constants/colors.js'; import { BLITZ_SERVERS, BlitzServer } from '../constants/servers.js'; import { PlayerClanData } from '../types/playerClanData.js'; import getBlitzAccount from '../utilities/getBlitzAccount.js'; -export async function execute( - interaction: ChatInputCommandInteraction, -) { - const ign = interaction.options.getString('ign')!; - const server = interaction.options.getString('server') as BlitzServer; +export default { + inProduction: true, + inDevelopment: false, + inPublic: false, - 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=${account.account_id}&extra=clan`, - ).then((response) => response.json())) as PlayerClanData; - const clan = clanData.data[account.account_id].clan; - const clanTag = clan === null ? '' : ` [${clan!.tag}]`; + command: new SlashCommandBuilder() + .setName('verify') + .setDescription('Verifies the user with Blitz') + .addStringOption((option) => + option + .setName('server') + .setDescription('The Blitz server you are in') + .setRequired(true) + .addChoices( + { name: BLITZ_SERVERS.com, value: 'com' }, + { name: BLITZ_SERVERS.eu, value: 'eu' }, + { name: BLITZ_SERVERS.asia, value: 'asia' }, + ), + ) + .addStringOption((option) => + option + .setName('ign') + .setDescription('The username you use in Blitz') + .setRequired(true), + ), - if (interaction.member && interaction.guild) { - const member = interaction.guild?.members.cache.get( - interaction.member?.user.id, - ); + execute(interaction) { + const ign = interaction.options.getString('ign')!; + const server = interaction.options.getString('server') as BlitzServer; - member - ?.setNickname(`${ign}${clanTag}`) - .then(async () => { - await member.roles.remove(discord.verify_role); - await member.roles.add(discord.peasant_role); - await interaction.reply({ - embeds: [ - new EmbedBuilder() - .setColor(POSITIVE_COLOR) - .setTitle(`${interaction.user.username} is verified`) - .setDescription(`The user is now verified as ${ign}${clanTag}`), - ], + 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=${account.account_id}&extra=clan`, + ).then((response) => response.json())) as PlayerClanData; + const clan = clanData.data[account.account_id].clan; + const clanTag = clan === null ? '' : ` [${clan!.tag}]`; + + if (interaction.member && interaction.guild) { + const member = interaction.guild?.members.cache.get( + interaction.member?.user.id, + ); + + member + ?.setNickname(`${ign}${clanTag}`) + .then(async () => { + await member.roles.remove(discord.verify_role); + await member.roles.add(discord.peasant_role); + await interaction.reply({ + embeds: [ + new EmbedBuilder() + .setColor(POSITIVE_COLOR) + .setTitle(`${interaction.user.username} is verified`) + .setDescription( + `The user is now verified as ${ign}${clanTag}`, + ), + ], + }); + + console.log( + `${interaction.user.username} verified as ${ign}${clanTag}`, + ); + }) + .catch(async () => { + await interaction.reply({ + embeds: [ + new EmbedBuilder() + .setColor(NEGATIVE_COLOR) + .setTitle(`${interaction.user.username} failed to verify`) + .setDescription( + 'I may not have the permission to change your nickname.', + ), + ], + }); + + console.warn( + `${interaction.user.username} failed to verify as ${ign}${clanTag}`, + ); }); - - console.log( - `${interaction.user.username} verified as ${ign}${clanTag}`, - ); - }) - .catch(async () => { - await interaction.reply({ - embeds: [ - new EmbedBuilder() - .setColor(NEGATIVE_COLOR) - .setTitle(`${interaction.user.username} failed to verify`) - .setDescription( - 'I may not have the permission to change your nickname.', - ), - ], - }); - - console.warn( - `${interaction.user.username} failed to verify as ${ign}${clanTag}`, - ); - }); - } - }); -} - -export const data = new SlashCommandBuilder() - .setName('verify') - .setDescription('Verifies the user with Blitz') - .addStringOption((option) => - option - .setName('server') - .setDescription('The Blitz server you are in') - .setRequired(true) - .addChoices( - { name: BLITZ_SERVERS.com, value: 'com' }, - { name: BLITZ_SERVERS.eu, value: 'eu' }, - { name: BLITZ_SERVERS.asia, value: 'asia' }, - ), - ) - .addStringOption((option) => - option - .setName('ign') - .setDescription('The username you use in Blitz') - .setRequired(true), - ); + } + }); + }, +} satisfies CommandRegistry;