feat: username inferring from discord nickname

This commit is contained in:
TresAbhi committed 2023-06-03 18:05:09 +00:00
1 parent f4bc66658b
commit db881f44d4
17 files changed
+55 -41

No files matched your search

+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "blitzkrieg", "name": "blitzkrieg",
"version": "1.5.4", "version": "1.6.0",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"type": "module", "type": "module",
+1 -1
View File
@@ -13,7 +13,7 @@ const executionStart = new Date().getTime();
export default { export default {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
+1 -1
View File
@@ -11,7 +11,7 @@ import { client } from '../index.js';
export default { export default {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
+1 -1
View File
@@ -15,7 +15,7 @@ const DEFAULT_THRESHOLD = 7;
export default { export default {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
+2 -3
View File
@@ -36,7 +36,7 @@ const COMP_TANKS = [
export default { export default {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
@@ -54,8 +54,7 @@ export default {
async execute(interaction) { async execute(interaction) {
const tier = interaction.options.getInteger('tier')!; const tier = interaction.options.getInteger('tier')!;
const name = interaction.options.getString('username')!; const account = await getBlitzAccount(interaction);
const account = await getBlitzAccount(interaction, name);
const { id, server } = account; const { id, server } = account;
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}`,
+2 -3
View File
@@ -17,7 +17,7 @@ type SortBy = 'name' | 'count';
export default { export default {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
@@ -36,8 +36,7 @@ export default {
async execute(interaction) { async execute(interaction) {
const sortBy = (interaction.options.getString('sort') ?? 'name') as SortBy; const sortBy = (interaction.options.getString('sort') ?? 'name') as SortBy;
const name = interaction.options.getString('username')!; const account = await getBlitzAccount(interaction);
const account = await getBlitzAccount(interaction, name);
const { id, server } = account; const { id, server } = account;
const accounts = await getWargamingResponse<AccountInfo>( const accounts = 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}`,
+2 -3
View File
@@ -13,7 +13,7 @@ import { AccountInfo } from '../types/accountInfo.js';
export default { export default {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
@@ -22,8 +22,7 @@ export default {
.addStringOption(addUsernameOption), .addStringOption(addUsernameOption),
async execute(interaction) { async execute(interaction) {
const name = interaction.options.getString('username')!; const account = await getBlitzAccount(interaction);
const account = await getBlitzAccount(interaction, name);
const { id, server } = account; const { id, server } = account;
const accounts = await getWargamingResponse<AccountInfo>( const accounts = 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}`,
+1 -1
View File
@@ -12,7 +12,7 @@ import { ClanList } from '../types/clanList.js';
export default { export default {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
+4 -4
View File
@@ -2,7 +2,7 @@ import { SlashCommandBuilder } from 'discord.js';
import markdownEscape from 'markdown-escape'; import markdownEscape from 'markdown-escape';
import { BLITZ_SERVERS, BlitzServer } from '../constants/servers.js'; import { BLITZ_SERVERS, BlitzServer } from '../constants/servers.js';
import getWargamingResponse from '../core/blitz/getWargamingResponse.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 cmdName from '../core/interaction/cmdName.js';
import infoEmbed from '../core/interaction/infoEmbed.js'; import infoEmbed from '../core/interaction/infoEmbed.js';
import addServerChoices from '../core/options/addServerChoices.js'; import addServerChoices from '../core/options/addServerChoices.js';
@@ -13,7 +13,7 @@ import { AccountList } from '../types/accountList.js';
export default { export default {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
@@ -21,7 +21,7 @@ export default {
.setDescription('Search players in a Blitz server') .setDescription('Search players in a Blitz server')
.addStringOption(addServerChoices) .addStringOption(addServerChoices)
.addStringOption((option) => .addStringOption((option) =>
addUsernameOption(option).setAutocomplete(false), addUsernameOption(option).setAutocomplete(false).setRequired(true),
) )
.addIntegerOption((option) => .addIntegerOption((option) =>
option option
@@ -36,7 +36,7 @@ export default {
const name = interaction.options.getString('username')!; const name = interaction.options.getString('username')!;
const limit = interaction.options.getInteger('limit') ?? 25; const limit = interaction.options.getInteger('limit') ?? 25;
const trimmedSearch = name.trim(); const trimmedSearch = name.trim();
const players = usernameRegex.test(trimmedSearch) const players = usernamePattern.test(trimmedSearch)
? await getWargamingResponse<AccountList>( ? await getWargamingResponse<AccountList>(
`https://api.wotblitz.${server}/wotb/account/list/?application_id=${ `https://api.wotblitz.${server}/wotb/account/list/?application_id=${
args['wargaming-application-id'] args['wargaming-application-id']
+1 -1
View File
@@ -9,7 +9,7 @@ import { CommandRegistry } from '../events/interactionCreate.js';
export default { export default {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
+2 -3
View File
@@ -40,7 +40,7 @@ import { PlayerClanData } from '../types/playerClanData.js';
export default { export default {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
@@ -51,8 +51,7 @@ export default {
async execute(interaction) { async execute(interaction) {
const period = interaction.options.getString('period') as StatPeriod; const period = interaction.options.getString('period') as StatPeriod;
const username = interaction.options.getString('username')!; const blitzAccount = await getBlitzAccount(interaction);
const blitzAccount = await getBlitzAccount(interaction, username);
const { id, server } = blitzAccount; const { id, server } = blitzAccount;
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}`,
+2 -3
View File
@@ -40,7 +40,7 @@ import { AccountInfo, AllStats } from '../types/accountInfo.js';
export default { export default {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
@@ -56,8 +56,7 @@ export default {
interaction.options.getString('tank')!, interaction.options.getString('tank')!,
); );
const period = interaction.options.getString('period') as StatPeriod; const period = interaction.options.getString('period') as StatPeriod;
const username = interaction.options.getString('username')!; const blitzAccount = await getBlitzAccount(interaction);
const blitzAccount = await getBlitzAccount(interaction, username);
const { id, server } = blitzAccount; const { id, server } = blitzAccount;
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}`,
+2 -4
View File
@@ -32,7 +32,7 @@ import { PlayerClanData } from '../types/playerClanData.js';
export default { export default {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
@@ -41,9 +41,7 @@ export default {
.addStringOption(addUsernameOption), .addStringOption(addUsernameOption),
async execute(interaction) { async execute(interaction) {
const username = interaction.options.getString('username')!; const { id, server } = await getBlitzAccount(interaction);
const blitzAccount = await getBlitzAccount(interaction, username);
const { id, server } = blitzAccount;
const tankStatsOverTime = await getTankStatsOverTime( const tankStatsOverTime = await getTankStatsOverTime(
interaction, interaction,
server, server,
+4 -5
View File
@@ -14,17 +14,16 @@ import { PlayerClanData } from '../types/playerClanData.js';
export default { export default {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
.setName(cmdName('verify')) .setName(cmdName('verify'))
.setDescription("Set's the user's username to their in-game name") .setDescription("Set's the user's username to their in-game name")
.addStringOption(addUsernameOption), .addStringOption((option) => addUsernameOption(option).setRequired(true)),
async execute(interaction) { async execute(interaction) {
const name = interaction.options.getString('username')!; const blitzAccount = await getBlitzAccount(interaction);
const blitzAccount = await getBlitzAccount(interaction, name);
const { id, server } = blitzAccount; const { id, server } = blitzAccount;
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}`,
@@ -118,7 +117,7 @@ export default {
.setColor(NEGATIVE_COLOR) .setColor(NEGATIVE_COLOR)
.setTitle(`${interaction.user.username} failed to verify`) .setTitle(`${interaction.user.username} failed to verify`)
.setDescription( .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.",
), ),
], ],
}); });
+25 -3
View File
@@ -1,14 +1,36 @@
import { CacheType, ChatInputCommandInteraction } from 'discord.js'; import { CacheType, ChatInputCommandInteraction } from 'discord.js';
import { BlitzServer } from '../../constants/servers.js'; import { BlitzServer } from '../../constants/servers.js';
import errorEmbed from '../interaction/errorEmbed.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 const serverAndIdPattern = /(com|eu|asia)\/[0-9]+/;
export default async function getBlitzAccount( export default async function getBlitzAccount(
interaction: ChatInputCommandInteraction<CacheType>, interaction: ChatInputCommandInteraction<CacheType>,
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)) { if (serverAndIdPattern.test(username)) {
const [server, accountId] = username.split('/'); const [server, accountId] = username.split('/');
return { server: server as BlitzServer, id: Number(accountId) }; return { server: server as BlitzServer, id: Number(accountId) };
@@ -22,7 +44,7 @@ export default async function getBlitzAccount(
embeds: [ embeds: [
errorEmbed( errorEmbed(
'Could not find user', '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.`,
), ),
], ],
}); });
+3 -2
View File
@@ -7,14 +7,15 @@ export type AccountListWithServer = (Account & {
server: 'com' | 'eu' | 'asia'; 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) { export default async function listAccountsPanServer(search: string, limit = 9) {
const trimmedSearch = search.trim(); const trimmedSearch = search.trim();
const normalizedLimit = Math.round(limit / 3); const normalizedLimit = Math.round(limit / 3);
const encodedSearch = encodeURIComponent(trimmedSearch); const encodedSearch = encodeURIComponent(trimmedSearch);
if (usernameRegex.test(trimmedSearch)) { if (usernamePattern.test(trimmedSearch)) {
return ( return (
await Promise.all([ await Promise.all([
getWargamingResponse<AccountList>( getWargamingResponse<AccountList>(
+1 -2
View File
@@ -4,6 +4,5 @@ export default function addUsernameOption(option: SlashCommandStringOption) {
return option return option
.setName('username') .setName('username')
.setDescription('The username you use in Blitz') .setDescription('The username you use in Blitz')
.setAutocomplete(true) .setAutocomplete(true);
.setRequired(true);
} }