diff --git a/package.json b/package.json index 3ee9576c2..5b17c3ff9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "blitzkrieg", - "version": "1.5.4", + "version": "1.6.0", "description": "", "main": "index.js", "type": "module", diff --git a/src/commands/debug.ts b/src/commands/debug.ts index e7630f90d..17afcc4e8 100644 --- a/src/commands/debug.ts +++ b/src/commands/debug.ts @@ -13,7 +13,7 @@ const executionStart = new Date().getTime(); export default { inProduction: true, - inDevelopment: false, + inDevelopment: true, inPublic: true, command: new SlashCommandBuilder() diff --git a/src/commands/help.ts b/src/commands/help.ts index 6e50b7798..f9cc7a4bd 100644 --- a/src/commands/help.ts +++ b/src/commands/help.ts @@ -11,7 +11,7 @@ import { client } from '../index.js'; export default { inProduction: true, - inDevelopment: false, + inDevelopment: true, inPublic: true, command: new SlashCommandBuilder() diff --git a/src/commands/inactive.ts b/src/commands/inactive.ts index 9fc91a20d..38cdc0f9e 100644 --- a/src/commands/inactive.ts +++ b/src/commands/inactive.ts @@ -15,7 +15,7 @@ const DEFAULT_THRESHOLD = 7; export default { inProduction: true, - inDevelopment: false, + inDevelopment: true, inPublic: true, command: new SlashCommandBuilder() diff --git a/src/commands/ownedtanks.ts b/src/commands/ownedtanks.ts index 7e9e41ea5..26205ca59 100644 --- a/src/commands/ownedtanks.ts +++ b/src/commands/ownedtanks.ts @@ -36,7 +36,7 @@ const COMP_TANKS = [ export default { inProduction: true, - inDevelopment: false, + inDevelopment: true, inPublic: true, command: new SlashCommandBuilder() @@ -54,8 +54,7 @@ export default { async execute(interaction) { const tier = interaction.options.getInteger('tier')!; - const name = interaction.options.getString('username')!; - const account = await getBlitzAccount(interaction, name); + const account = await getBlitzAccount(interaction); const { id, server } = account; const accountInfo = await getWargamingResponse( `https://api.wotblitz.${server}/wotb/account/info/?application_id=${args['wargaming-application-id']}&account_id=${id}`, diff --git a/src/commands/playerachievements.ts b/src/commands/playerachievements.ts index 59b3c0048..38fb9f084 100644 --- a/src/commands/playerachievements.ts +++ b/src/commands/playerachievements.ts @@ -17,7 +17,7 @@ type SortBy = 'name' | 'count'; export default { inProduction: true, - inDevelopment: false, + inDevelopment: true, inPublic: true, command: new SlashCommandBuilder() @@ -36,8 +36,7 @@ export default { async execute(interaction) { const sortBy = (interaction.options.getString('sort') ?? 'name') as SortBy; - const name = interaction.options.getString('username')!; - const account = await getBlitzAccount(interaction, name); + const account = await getBlitzAccount(interaction); const { id, server } = account; const accounts = await getWargamingResponse( `https://api.wotblitz.${server}/wotb/account/info/?application_id=${args['wargaming-application-id']}&account_id=${id}`, diff --git a/src/commands/playerinfo.ts b/src/commands/playerinfo.ts index bb0f5634d..179d7c295 100644 --- a/src/commands/playerinfo.ts +++ b/src/commands/playerinfo.ts @@ -13,7 +13,7 @@ import { AccountInfo } from '../types/accountInfo.js'; export default { inProduction: true, - inDevelopment: false, + inDevelopment: true, inPublic: true, command: new SlashCommandBuilder() @@ -22,8 +22,7 @@ export default { .addStringOption(addUsernameOption), async execute(interaction) { - const name = interaction.options.getString('username')!; - const account = await getBlitzAccount(interaction, name); + const account = await getBlitzAccount(interaction); const { id, server } = account; const accounts = await getWargamingResponse( `https://api.wotblitz.${server}/wotb/account/info/?application_id=${args['wargaming-application-id']}&account_id=${id}`, diff --git a/src/commands/searchclans.ts b/src/commands/searchclans.ts index a52e50ddf..b680c6d27 100644 --- a/src/commands/searchclans.ts +++ b/src/commands/searchclans.ts @@ -12,7 +12,7 @@ import { ClanList } from '../types/clanList.js'; export default { inProduction: true, - inDevelopment: false, + inDevelopment: true, inPublic: true, command: new SlashCommandBuilder() diff --git a/src/commands/searchplayers.ts b/src/commands/searchplayers.ts index 9ea41a53a..e996b85a8 100644 --- a/src/commands/searchplayers.ts +++ b/src/commands/searchplayers.ts @@ -2,7 +2,7 @@ import { SlashCommandBuilder } from 'discord.js'; import markdownEscape from 'markdown-escape'; import { BLITZ_SERVERS, BlitzServer } from '../constants/servers.js'; import getWargamingResponse from '../core/blitz/getWargamingResponse.js'; -import { usernameRegex } from '../core/blitz/listAccountsPanServer.js'; +import { usernamePattern } from '../core/blitz/listAccountsPanServer.js'; import cmdName from '../core/interaction/cmdName.js'; import infoEmbed from '../core/interaction/infoEmbed.js'; import addServerChoices from '../core/options/addServerChoices.js'; @@ -13,7 +13,7 @@ import { AccountList } from '../types/accountList.js'; export default { inProduction: true, - inDevelopment: false, + inDevelopment: true, inPublic: true, command: new SlashCommandBuilder() @@ -21,7 +21,7 @@ export default { .setDescription('Search players in a Blitz server') .addStringOption(addServerChoices) .addStringOption((option) => - addUsernameOption(option).setAutocomplete(false), + addUsernameOption(option).setAutocomplete(false).setRequired(true), ) .addIntegerOption((option) => option @@ -36,7 +36,7 @@ export default { const name = interaction.options.getString('username')!; const limit = interaction.options.getInteger('limit') ?? 25; const trimmedSearch = name.trim(); - const players = usernameRegex.test(trimmedSearch) + const players = usernamePattern.test(trimmedSearch) ? await getWargamingResponse( `https://api.wotblitz.${server}/wotb/account/list/?application_id=${ args['wargaming-application-id'] diff --git a/src/commands/searchtanks.ts b/src/commands/searchtanks.ts index f14361372..49610e1f0 100644 --- a/src/commands/searchtanks.ts +++ b/src/commands/searchtanks.ts @@ -9,7 +9,7 @@ import { CommandRegistry } from '../events/interactionCreate.js'; export default { inProduction: true, - inDevelopment: false, + inDevelopment: true, inPublic: true, command: new SlashCommandBuilder() diff --git a/src/commands/stats.tsx b/src/commands/stats.tsx index f24192947..5c9f0ff83 100644 --- a/src/commands/stats.tsx +++ b/src/commands/stats.tsx @@ -40,7 +40,7 @@ import { PlayerClanData } from '../types/playerClanData.js'; export default { inProduction: true, - inDevelopment: false, + inDevelopment: true, inPublic: true, command: new SlashCommandBuilder() @@ -51,8 +51,7 @@ export default { async execute(interaction) { const period = interaction.options.getString('period') as StatPeriod; - const username = interaction.options.getString('username')!; - const blitzAccount = await getBlitzAccount(interaction, username); + const blitzAccount = await getBlitzAccount(interaction); const { id, server } = blitzAccount; const accountInfo = await getWargamingResponse( `https://api.wotblitz.${server}/wotb/account/info/?application_id=${args['wargaming-application-id']}&account_id=${id}`, diff --git a/src/commands/tankstats.tsx b/src/commands/tankstats.tsx index 305b420f3..6bf9b949a 100644 --- a/src/commands/tankstats.tsx +++ b/src/commands/tankstats.tsx @@ -40,7 +40,7 @@ import { AccountInfo, AllStats } from '../types/accountInfo.js'; export default { inProduction: true, - inDevelopment: false, + inDevelopment: true, inPublic: true, command: new SlashCommandBuilder() @@ -56,8 +56,7 @@ export default { interaction.options.getString('tank')!, ); const period = interaction.options.getString('period') as StatPeriod; - const username = interaction.options.getString('username')!; - const blitzAccount = await getBlitzAccount(interaction, username); + const blitzAccount = await getBlitzAccount(interaction); const { id, server } = blitzAccount; const accountInfo = await getWargamingResponse( `https://api.wotblitz.${server}/wotb/account/info/?application_id=${args['wargaming-application-id']}&account_id=${id}`, diff --git a/src/commands/today.tsx b/src/commands/today.tsx index c6f3e4d4d..bef142af5 100644 --- a/src/commands/today.tsx +++ b/src/commands/today.tsx @@ -32,7 +32,7 @@ import { PlayerClanData } from '../types/playerClanData.js'; export default { inProduction: true, - inDevelopment: false, + inDevelopment: true, inPublic: true, command: new SlashCommandBuilder() @@ -41,9 +41,7 @@ export default { .addStringOption(addUsernameOption), async execute(interaction) { - const username = interaction.options.getString('username')!; - const blitzAccount = await getBlitzAccount(interaction, username); - const { id, server } = blitzAccount; + const { id, server } = await getBlitzAccount(interaction); const tankStatsOverTime = await getTankStatsOverTime( interaction, server, diff --git a/src/commands/verify.ts b/src/commands/verify.ts index 41c89157e..163339825 100644 --- a/src/commands/verify.ts +++ b/src/commands/verify.ts @@ -14,17 +14,16 @@ import { PlayerClanData } from '../types/playerClanData.js'; export default { inProduction: true, - inDevelopment: false, + inDevelopment: true, inPublic: true, command: new SlashCommandBuilder() .setName(cmdName('verify')) .setDescription("Set's the user's username to their in-game name") - .addStringOption(addUsernameOption), + .addStringOption((option) => addUsernameOption(option).setRequired(true)), async execute(interaction) { - const name = interaction.options.getString('username')!; - const blitzAccount = await getBlitzAccount(interaction, name); + const blitzAccount = await getBlitzAccount(interaction); const { id, server } = blitzAccount; const accountInfo = await getWargamingResponse( `https://api.wotblitz.${server}/wotb/account/info/?application_id=${args['wargaming-application-id']}&account_id=${id}`, @@ -118,7 +117,7 @@ export default { .setColor(NEGATIVE_COLOR) .setTitle(`${interaction.user.username} failed to verify`) .setDescription( - "I can't change your nickname because you have higher permissions than me.", + "I can't change your nickname because you have higher permissions than me. Try setting your nickname to your Blitz username manually.", ), ], }); diff --git a/src/core/blitz/getBlitzAccount.ts b/src/core/blitz/getBlitzAccount.ts index e0fe4c4ea..5b3c8e72c 100644 --- a/src/core/blitz/getBlitzAccount.ts +++ b/src/core/blitz/getBlitzAccount.ts @@ -1,14 +1,36 @@ import { CacheType, ChatInputCommandInteraction } from 'discord.js'; import { BlitzServer } from '../../constants/servers.js'; import errorEmbed from '../interaction/errorEmbed.js'; -import listAccountsPanServer from './listAccountsPanServer.js'; +import listAccountsPanServer, { + usernamePatternWithoutPosition, +} from './listAccountsPanServer.js'; export const serverAndIdPattern = /(com|eu|asia)\/[0-9]+/; export default async function getBlitzAccount( interaction: ChatInputCommandInteraction, - username: string, ) { + const commandUsername = interaction.options.getString('username'); + const displayName = interaction.guild?.members.cache + .get(interaction.user.id) + ?.displayName.match(usernamePatternWithoutPosition)?.[0]; + const username = commandUsername ?? displayName; + + if (username === undefined) { + await interaction.editReply({ + embeds: [ + errorEmbed( + 'Username could not be inferred', + "You didn't provide me a username in the command nor was I able to infer your Blitz username from your Discord nickname. Try providing a username manually in the command or using the `/verify` command to set your Discord nickname to your Blitz username.", + ), + ], + }); + + throw new Error( + `No username provided commandUsername: ${commandUsername} displayName: ${displayName} username: ${username}`, + ); + } + if (serverAndIdPattern.test(username)) { const [server, accountId] = username.split('/'); return { server: server as BlitzServer, id: Number(accountId) }; @@ -22,7 +44,7 @@ export default async function getBlitzAccount( embeds: [ errorEmbed( 'Could not find user', - `I couldn't find user \`${username}\`. Try selecting a username from the search result.`, + `I couldn't find user \`${username}\`. Try providing a username manually or using the \`/verify\` command to set your Discord nickname to your Blitz username.`, ), ], }); diff --git a/src/core/blitz/listAccountsPanServer.ts b/src/core/blitz/listAccountsPanServer.ts index 70643e540..13137e432 100644 --- a/src/core/blitz/listAccountsPanServer.ts +++ b/src/core/blitz/listAccountsPanServer.ts @@ -7,14 +7,15 @@ export type AccountListWithServer = (Account & { server: 'com' | 'eu' | 'asia'; })[]; -export const usernameRegex = /^[a-zA-Z0-9_]{3,24}$/; +export const usernamePattern = /^[a-zA-Z0-9_]{3,24}$/; +export const usernamePatternWithoutPosition = /[a-zA-Z0-9_]{3,24}/; export default async function listAccountsPanServer(search: string, limit = 9) { const trimmedSearch = search.trim(); const normalizedLimit = Math.round(limit / 3); const encodedSearch = encodeURIComponent(trimmedSearch); - if (usernameRegex.test(trimmedSearch)) { + if (usernamePattern.test(trimmedSearch)) { return ( await Promise.all([ getWargamingResponse( diff --git a/src/core/options/addUsernameOption.ts b/src/core/options/addUsernameOption.ts index 8c0a45911..d9f323d77 100644 --- a/src/core/options/addUsernameOption.ts +++ b/src/core/options/addUsernameOption.ts @@ -4,6 +4,5 @@ export default function addUsernameOption(option: SlashCommandStringOption) { return option .setName('username') .setDescription('The username you use in Blitz') - .setAutocomplete(true) - .setRequired(true); + .setAutocomplete(true); }