Merge pull request #9 from tresabhi/1.7.6

This commit is contained in:
TrèsAbhi authored and GitHub committed 2023-06-16 12:44:35 -05:00
commit 6f90d4fb75
21 files changed
+168 -195

No files matched your search

+5
View File
@@ -8,13 +8,18 @@
"kranvagn", "kranvagn",
"outfile", "outfile",
"ownedtanks", "ownedtanks",
"playerachievements",
"playerinfo",
"Resvg", "Resvg",
"searchclans",
"searchplayers", "searchplayers",
"searchtanks",
"SKLLD", "SKLLD",
"Smri", "Smri",
"startcase", "startcase",
"strvk", "strvk",
"tankopedia", "tankopedia",
"tankstats",
"Unicum", "Unicum",
"Unregistering", "Unregistering",
"vickers", "vickers",
+2 -2
View File
@@ -5,8 +5,8 @@
"main": "src/index.ts", "main": "src/index.ts",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "yarn build && yarn start", "dev": "yarn build --dev && yarn start",
"start": "node --enable-source-maps dist/index.cjs", "start": "node --enable-source-maps --trace-warnings dist/index.cjs",
"zip": "zip -r dist.zip dist", "zip": "zip -r dist.zip dist",
"build": "node scripts/build", "build": "node scripts/build",
"lint": "tsc" "lint": "tsc"
+9 -5
View File
@@ -1,10 +1,14 @@
import { build } from 'esbuild'; import { build } from 'esbuild';
import { rmSync } from 'fs'; import { rmSync } from 'fs';
import { argv } from 'process';
const isDev = argv.includes('--dev');
const isProd = !isDev;
console.log('Removing dist...'); console.log('Removing dist...');
rmSync('dist', { recursive: true, force: true }); rmSync('dist', { recursive: true, force: true });
console.log('Creating context...'); console.log('Building...');
build({ build({
entryPoints: ['src/index.ts'], entryPoints: ['src/index.ts'],
outfile: 'dist/index.cjs', outfile: 'dist/index.cjs',
@@ -15,9 +19,9 @@ build({
'.ttf': 'file', '.ttf': 'file',
}, },
bundle: true, bundle: isProd,
sourcemap: true, sourcemap: isProd,
minifyIdentifiers: false, // causes errors minifyIdentifiers: false, // causes errors
minifySyntax: true, minifySyntax: isProd,
minifyWhitespace: true, minifyWhitespace: isProd,
}); });
+3 -7
View File
@@ -20,13 +20,11 @@ export default {
.setName(cmdName('debug')) .setName(cmdName('debug'))
.setDescription('Debug information about the bot'), .setDescription('Debug information about the bot'),
async execute(interaction) { execute(interaction) {
const currentTime = new Date().getTime(); const currentTime = new Date().getTime();
const uptime = currentTime - executionStart; const uptime = currentTime - executionStart;
await interaction.editReply({ return infoEmbed(
embeds: [
infoEmbed(
`${client.user?.username} debug information`, `${client.user?.username} debug information`,
cleanTable([ cleanTable([
['Version', packageJSON.version], ['Version', packageJSON.version],
@@ -43,8 +41,6 @@ export default {
['Tankopedia cached', `${tankopedia !== undefined}`], ['Tankopedia cached', `${tankopedia !== undefined}`],
['Tank averages cached', `${tankAverages !== undefined}`], ['Tank averages cached', `${tankAverages !== undefined}`],
]), ]),
), );
],
});
}, },
} satisfies CommandRegistry; } satisfies CommandRegistry;
+1 -5
View File
@@ -166,10 +166,6 @@ export default {
)}`; )}`;
} }
await interaction.editReply({ return (isEligible ? positiveEmbed : negativeEmbed)(title, body);
embeds: isEligible
? [positiveEmbed(title, body)]
: [negativeEmbed(title, body)],
});
}, },
} satisfies CommandRegistry; } satisfies CommandRegistry;
+7 -13
View File
@@ -1,7 +1,7 @@
import { EmbedBuilder, SlashCommandBuilder } from 'discord.js'; import { SlashCommandBuilder } from 'discord.js';
import discord from '../../discord.json' assert { type: 'json' }; import discord from '../../discord.json' assert { type: 'json' };
import { ACCENT_COLOR } from '../constants/colors.js';
import cmdName from '../core/interaction/cmdName.js'; import cmdName from '../core/interaction/cmdName.js';
import infoEmbed from '../core/interaction/infoEmbed.js';
import { import {
CommandRegistry, CommandRegistry,
guildCommands, guildCommands,
@@ -11,20 +11,16 @@ import { client } from '../index.js';
export default { export default {
inProduction: true, inProduction: true,
inDevelopment: true, inDevelopment: false,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
.setName(cmdName('help')) .setName(cmdName('help'))
.setDescription('All the help you need about the bot'), .setDescription('All the help you need about the bot'),
async execute(interaction) { execute(interaction) {
await interaction.editReply({ return infoEmbed(
embeds: [ `${client.user?.username} help`,
new EmbedBuilder()
.setTitle(`${client.user?.username} help`)
.setColor(ACCENT_COLOR)
.setDescription(
`**About**\n${ `**About**\n${
client.user?.username client.user?.username
} automates many mundane tasks and provide statistics in numerous flexible ways.\n\nMade by TresAbhi from the Skilled [SKLLD] clan.\nGitHub: https://github.com/tresabhi/blitzkrieg\nDiscord server: https://discord.gg/nDt7AjGJQH\nSkilled server: https://discord.gg/ZPvcEG7DS8\n\n**Commands**\n${(interaction.guildId === } automates many mundane tasks and provide statistics in numerous flexible ways.\n\nMade by TresAbhi from the Skilled [SKLLD] clan.\nGitHub: https://github.com/tresabhi/blitzkrieg\nDiscord server: https://discord.gg/nDt7AjGJQH\nSkilled server: https://discord.gg/ZPvcEG7DS8\n\n**Commands**\n${(interaction.guildId ===
@@ -36,8 +32,6 @@ export default {
.join( .join(
'\n', '\n',
)}\n\n*I am a new bot; I may make mistakes and go offline unexpectedly from time to time.*`, )}\n\n*I am a new bot; I may make mistakes and go offline unexpectedly from time to time.*`,
), );
],
});
}, },
} satisfies CommandRegistry; } satisfies CommandRegistry;
+2 -5
View File
@@ -11,7 +11,6 @@ import getWargamingResponse from '../core/blitz/getWargamingResponse.js';
import cmdName from '../core/interaction/cmdName.js'; import cmdName from '../core/interaction/cmdName.js';
import addClanChoices from '../core/options/addClanChoices.js'; import addClanChoices from '../core/options/addClanChoices.js';
import { WARGAMING_APPLICATION_ID } from '../core/process/args.js'; import { WARGAMING_APPLICATION_ID } from '../core/process/args.js';
import render from '../core/ui/render.js';
import { CommandRegistry } from '../events/interactionCreate.js'; import { CommandRegistry } from '../events/interactionCreate.js';
import { AccountInfo } from '../types/accountInfo.js'; import { AccountInfo } from '../types/accountInfo.js';
import { ClanInfo } from '../types/clanInfo.js'; import { ClanInfo } from '../types/clanInfo.js';
@@ -67,7 +66,7 @@ export default {
); );
const hasInactiveMembers = inactive.length > 0; const hasInactiveMembers = inactive.length > 0;
const image = await render( return (
<Wrapper> <Wrapper>
<TitleBar <TitleBar
name={clanData.name} name={clanData.name}
@@ -82,10 +81,8 @@ export default {
{hasInactiveMembers && <GenericStats stats={inactive} />} {hasInactiveMembers && <GenericStats stats={inactive} />}
<PoweredByWargaming /> <PoweredByWargaming />
</Wrapper>, </Wrapper>
); );
await interaction.editReply({ files: [image] });
}, },
autocomplete: clanAutocomplete, autocomplete: clanAutocomplete,
+17 -10
View File
@@ -13,7 +13,6 @@ import { TIER_ROMAN_NUMERALS, tankopedia } from '../core/blitz/tankopedia.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 { WARGAMING_APPLICATION_ID } from '../core/process/args.js'; import { WARGAMING_APPLICATION_ID } from '../core/process/args.js';
import render from '../core/ui/render.js';
import { CommandRegistry } from '../events/interactionCreate.js'; import { CommandRegistry } from '../events/interactionCreate.js';
import { AccountInfo } from '../types/accountInfo.js'; import { AccountInfo } from '../types/accountInfo.js';
import { PlayerClanData } from '../types/playerClanData.js'; import { PlayerClanData } from '../types/playerClanData.js';
@@ -41,24 +40,34 @@ const COMP_TANKS = [
export default { export default {
inProduction: true, inProduction: true,
inDevelopment: true, inDevelopment: false,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
.setName(cmdName('ownedtanks')) .setName(cmdName('ownedtanks'))
.setDescription("Shows a player's owned tanks") .setDescription("Shows a player's owned tanks")
.addIntegerOption((option) => .addStringOption((option) =>
option option
.setName('tier') .setName('tier')
.setDescription('The tier you want to see') .setDescription('The tier you want to see')
.setMinValue(1) .setChoices(
.setMaxValue(10) { name: 'Tier I', value: '1' },
{ name: 'Tier II', value: '2' },
{ name: 'Tier III', value: '3' },
{ name: 'Tier IV', value: '4' },
{ name: 'Tier V', value: '5' },
{ name: 'Tier VI', value: '6' },
{ name: 'Tier VII', value: '7' },
{ name: 'Tier VIII', value: '8' },
{ name: 'Tier IX', value: '9' },
{ name: 'Tier X', value: '10' },
)
.setRequired(true), .setRequired(true),
) )
.addStringOption(addUsernameOption), .addStringOption(addUsernameOption),
async execute(interaction) { async execute(interaction) {
const tier = interaction.options.getInteger('tier')!; const tier = Number(interaction.options.getString('tier'));
const account = await getBlitzAccount(interaction); const account = await getBlitzAccount(interaction);
const { id, server } = account; const { id, server } = account;
const accountInfo = await getWargamingResponse<AccountInfo>( const accountInfo = await getWargamingResponse<AccountInfo>(
@@ -72,7 +81,7 @@ export default {
`https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}&extra=clan`, `https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}&extra=clan`,
); );
const image = await render( return (
<Wrapper> <Wrapper>
{/* TODO: integrate some of these into title bar */} {/* TODO: integrate some of these into title bar */}
<TitleBar <TitleBar
@@ -104,10 +113,8 @@ export default {
)} )}
<PoweredByWargaming /> <PoweredByWargaming />
</Wrapper>, </Wrapper>
); );
await interaction.editReply({ files: [image] });
}, },
autocomplete: usernameAutocomplete, autocomplete: usernameAutocomplete,
+2 -6
View File
@@ -51,9 +51,7 @@ export default {
...accountAchievements.max_series, ...accountAchievements.max_series,
}; };
interaction.editReply({ return infoEmbed(
embeds: [
infoEmbed(
`${markdownEscape(accounts[id].nickname)}'s information`, `${markdownEscape(accounts[id].nickname)}'s information`,
cleanTable( cleanTable(
@@ -72,9 +70,7 @@ export default {
] as TableInputEntry, ] as TableInputEntry,
), ),
), ),
), );
],
});
}, },
autocomplete: usernameAutocomplete, autocomplete: usernameAutocomplete,
+2 -6
View File
@@ -29,9 +29,7 @@ export default {
); );
const accountInfo = accounts[id]; const accountInfo = accounts[id];
interaction.editReply({ return infoEmbed(
embeds: [
infoEmbed(
`${markdownEscape(accountInfo.nickname)}'s information`, `${markdownEscape(accountInfo.nickname)}'s information`,
cleanTable([ cleanTable([
@@ -56,9 +54,7 @@ export default {
`${new Date(accountInfo.last_battle_time * 1000).toDateString()}`, `${new Date(accountInfo.last_battle_time * 1000).toDateString()}`,
], ],
]), ]),
), );
],
});
}, },
autocomplete: usernameAutocomplete, autocomplete: usernameAutocomplete,
+3 -9
View File
@@ -36,19 +36,13 @@ export default {
`https://api.wotblitz.${server}/wotb/clans/list/?application_id=${WARGAMING_APPLICATION_ID}&search=${clan}&limit=${limit}`, `https://api.wotblitz.${server}/wotb/clans/list/?application_id=${WARGAMING_APPLICATION_ID}&search=${clan}&limit=${limit}`,
); );
await interaction.editReply({ return infoEmbed(
embeds: [ `Clan search for "${markdownEscape(clan)}" in ${BLITZ_SERVERS[server]}`,
infoEmbed(
`Clan search for "${markdownEscape(clan)}" in ${
BLITZ_SERVERS[server]
}`,
clanList.length === 0 clanList.length === 0
? 'No clans found.' ? 'No clans found.'
: `\`\`\`\n${clanList : `\`\`\`\n${clanList
.map((clan) => `${clan.name} [${clan.tag}]`) .map((clan) => `${clan.name} [${clan.tag}]`)
.join('\n')}\n\`\`\``, .join('\n')}\n\`\`\``,
), );
],
});
}, },
} satisfies CommandRegistry; } satisfies CommandRegistry;
+3 -9
View File
@@ -44,19 +44,13 @@ export default {
) )
: []; : [];
await interaction.editReply({ return infoEmbed(
embeds: [ `Player search for "${markdownEscape(name)}" in ${BLITZ_SERVERS[server]}`,
infoEmbed(
`Player search for "${markdownEscape(name)}" in ${
BLITZ_SERVERS[server]
}`,
`\`\`\`${ `\`\`\`${
players.length === 0 players.length === 0
? 'No players found.' ? 'No players found.'
: players.map((player) => player.nickname).join('\n') : players.map((player) => player.nickname).join('\n')
}\`\`\``, }\`\`\``,
), );
],
});
}, },
} satisfies CommandRegistry; } satisfies CommandRegistry;
+2 -6
View File
@@ -31,15 +31,11 @@ export default {
(result) => result.target, (result) => result.target,
); );
await interaction.editReply({ return infoEmbed(
embeds: [
infoEmbed(
`Tank search for "${markdownEscape(tank)}"`, `Tank search for "${markdownEscape(tank)}"`,
results.length === 0 results.length === 0
? 'No tanks found.' ? 'No tanks found.'
: `\`\`\`\n${results.join('\n')}\n\`\`\``, : `\`\`\`\n${results.join('\n')}\n\`\`\``,
), );
],
});
}, },
} satisfies CommandRegistry; } satisfies CommandRegistry;
+3 -16
View File
@@ -1,8 +1,4 @@
import { import { SlashCommandBuilder } from 'discord.js';
ActionRowBuilder,
ButtonBuilder,
SlashCommandBuilder,
} from 'discord.js';
import GenericAllStats from '../components/GenericAllStats.js'; import GenericAllStats from '../components/GenericAllStats.js';
import NoData, { NoDataType } from '../components/NoData.js'; import NoData, { NoDataType } from '../components/NoData.js';
import PoweredByBlitzStars from '../components/PoweredByBlitzStars.js'; import PoweredByBlitzStars from '../components/PoweredByBlitzStars.js';
@@ -29,7 +25,6 @@ import addStatPeriodChoices, {
} from '../core/options/addStatPeriodChoices.js'; } from '../core/options/addStatPeriodChoices.js';
import addUsernameOption from '../core/options/addUsernameOption.js'; import addUsernameOption from '../core/options/addUsernameOption.js';
import { WARGAMING_APPLICATION_ID } from '../core/process/args.js'; import { WARGAMING_APPLICATION_ID } from '../core/process/args.js';
import render from '../core/ui/render.js';
import { CommandRegistry } from '../events/interactionCreate.js'; import { CommandRegistry } from '../events/interactionCreate.js';
import { import {
AccountInfo, AccountInfo,
@@ -134,7 +129,7 @@ export default {
if (!hasWN8AccumulatedAtAll) supplementaryStats.WN8 = undefined; if (!hasWN8AccumulatedAtAll) supplementaryStats.WN8 = undefined;
const image = await render( return [
<Wrapper> <Wrapper>
<TitleBar <TitleBar
name={accountInfo[id].nickname} name={accountInfo[id].nickname}
@@ -161,17 +156,9 @@ export default {
<PoweredByBlitzStars /> <PoweredByBlitzStars />
</Wrapper>, </Wrapper>,
);
const actionRow = new ActionRowBuilder<ButtonBuilder>().addComponents(
fullBlitzStarsStats(server, accountInfo[id].nickname), fullBlitzStarsStats(server, accountInfo[id].nickname),
supportBlitzStars, supportBlitzStars,
); ];
await interaction.editReply({
files: [image],
components: [actionRow],
});
}, },
autocomplete: usernameAutocomplete, autocomplete: usernameAutocomplete,
+4 -17
View File
@@ -1,8 +1,4 @@
import { import { SlashCommandBuilder } from 'discord.js';
ActionRowBuilder,
ButtonBuilder,
SlashCommandBuilder,
} from 'discord.js';
import GenericAllStats from '../components/GenericAllStats.js'; import GenericAllStats from '../components/GenericAllStats.js';
import NoData, { NoDataType } from '../components/NoData.js'; import NoData, { NoDataType } from '../components/NoData.js';
import PoweredByBlitzStars from '../components/PoweredByBlitzStars.js'; import PoweredByBlitzStars from '../components/PoweredByBlitzStars.js';
@@ -34,13 +30,12 @@ import addStatPeriodChoices, {
import addTankChoices from '../core/options/addTankChoices.js'; import addTankChoices from '../core/options/addTankChoices.js';
import addUsernameOption from '../core/options/addUsernameOption.js'; import addUsernameOption from '../core/options/addUsernameOption.js';
import { WARGAMING_APPLICATION_ID } from '../core/process/args.js'; import { WARGAMING_APPLICATION_ID } from '../core/process/args.js';
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';
export default { export default {
inProduction: true, inProduction: true,
inDevelopment: true, inDevelopment: false,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
@@ -81,7 +76,7 @@ export default {
stats = tankStatsOverTime[tankId] ?? emptyAllStats; stats = tankStatsOverTime[tankId] ?? emptyAllStats;
} }
const image = await render( return [
<Wrapper> <Wrapper>
<TitleBar <TitleBar
name={accountInfo[id].nickname} name={accountInfo[id].nickname}
@@ -105,17 +100,9 @@ export default {
<PoweredByBlitzStars /> <PoweredByBlitzStars />
</Wrapper>, </Wrapper>,
);
const actionRow = new ActionRowBuilder<ButtonBuilder>().addComponents(
fullBlitzStarsStats(server, accountInfo[id].nickname), fullBlitzStarsStats(server, accountInfo[id].nickname),
supportBlitzStars, supportBlitzStars,
); ];
await interaction.editReply({
files: [image],
components: [actionRow],
});
}, },
autocomplete: (interaction) => { autocomplete: (interaction) => {
+3 -16
View File
@@ -1,8 +1,4 @@
import { import { SlashCommandBuilder } from 'discord.js';
ActionRowBuilder,
ButtonBuilder,
SlashCommandBuilder,
} from 'discord.js';
import * as Breakdown from '../components/Breakdown/index.js'; import * as Breakdown from '../components/Breakdown/index.js';
import NoData, { NoDataType } from '../components/NoData.js'; import NoData, { NoDataType } from '../components/NoData.js';
import PoweredByBlitzStars from '../components/PoweredByBlitzStars.js'; import PoweredByBlitzStars from '../components/PoweredByBlitzStars.js';
@@ -25,7 +21,6 @@ import fullBlitzStarsStats from '../core/interaction/fullBlitzStarsStats.js';
import { supportBlitzStars } from '../core/interaction/supportBlitzStars.js'; import { supportBlitzStars } from '../core/interaction/supportBlitzStars.js';
import addUsernameOption from '../core/options/addUsernameOption.js'; import addUsernameOption from '../core/options/addUsernameOption.js';
import { WARGAMING_APPLICATION_ID } from '../core/process/args.js'; import { WARGAMING_APPLICATION_ID } from '../core/process/args.js';
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';
@@ -159,7 +154,7 @@ export default {
); );
}); });
const image = await render( return [
<Wrapper> <Wrapper>
<TitleBar <TitleBar
name={accountInfo[id].nickname} name={accountInfo[id].nickname}
@@ -181,17 +176,9 @@ export default {
<PoweredByBlitzStars /> <PoweredByBlitzStars />
</Wrapper>, </Wrapper>,
);
const actionRow = new ActionRowBuilder<ButtonBuilder>().addComponents(
fullBlitzStarsStats(server, accountInfo[id].nickname), fullBlitzStarsStats(server, accountInfo[id].nickname),
supportBlitzStars, supportBlitzStars,
); ];
await interaction.editReply({
files: [image],
components: [actionRow],
});
}, },
autocomplete: usernameAutocomplete, autocomplete: usernameAutocomplete,
+24 -58
View File
@@ -1,11 +1,12 @@
import { EmbedBuilder, SlashCommandBuilder } from 'discord.js'; import { SlashCommandBuilder } from 'discord.js';
import markdownEscape from 'markdown-escape'; import markdownEscape from 'markdown-escape';
import discord from '../../discord.json' assert { type: 'json' }; import discord from '../../discord.json' assert { type: 'json' };
import { NEGATIVE_COLOR, POSITIVE_COLOR } from '../constants/colors.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 cmdName from '../core/interaction/cmdName.js'; import cmdName from '../core/interaction/cmdName.js';
import negativeEmbed from '../core/interaction/negativeEmbed.js';
import positiveEmbed from '../core/interaction/positiveEmbed.js';
import addUsernameOption from '../core/options/addUsernameOption.js'; import addUsernameOption from '../core/options/addUsernameOption.js';
import { WARGAMING_APPLICATION_ID } from '../core/process/args.js'; import { WARGAMING_APPLICATION_ID } from '../core/process/args.js';
import { CommandRegistry } from '../events/interactionCreate.js'; import { CommandRegistry } from '../events/interactionCreate.js';
@@ -33,84 +34,49 @@ export default {
); );
const clan = clanData[id]?.clan; const clan = clanData[id]?.clan;
const clanTag = clan ? ` [${clan!.tag}]` : ''; const clanTag = clan ? ` [${clan!.tag}]` : '';
const member =
interaction.member &&
interaction.guild?.members.cache.get(interaction.member?.user.id);
if (!interaction.guild?.members.me?.permissions.has('ManageNicknames')) { if (!interaction.guild?.members.me?.permissions.has('ManageNicknames')) {
interaction.editReply({ return negativeEmbed(
embeds: [
new EmbedBuilder()
.setColor(NEGATIVE_COLOR)
.setTitle(
`${markdownEscape(interaction.user.username)} failed to verify`, `${markdownEscape(interaction.user.username)} failed to verify`,
)
.setDescription(
"I don't have the permission to change your nickname.", "I don't have the permission to change your nickname.",
), );
], }
}); if (!interaction.member || !member) {
return negativeEmbed(
return; `${interaction.user.username} is not in this server`,
"I couldn't find this person in this server. Did they leave?",
);
} }
if (interaction.member) {
const member = interaction.guild?.members.cache.get(
interaction.member?.user.id,
);
if (member) {
try { try {
await member.setNickname(`${accountInfo[id].nickname}${clanTag}`); await member.setNickname(`${accountInfo[id].nickname}${clanTag}`);
if (interaction.guildId === discord.sklld_guild_id) { if (interaction.guildId === discord.sklld_guild_id) {
if ( if (!interaction.guild?.members.me?.permissions.has('ManageRoles')) {
!interaction.guild?.members.me?.permissions.has('ManageRoles') return negativeEmbed(
) { `${markdownEscape(interaction.user.username)} failed to verify`,
await interaction.editReply({
embeds: [
new EmbedBuilder()
.setColor(NEGATIVE_COLOR)
.setTitle(
`${markdownEscape(
interaction.user.username,
)} failed to verify`,
)
.setDescription(
"I don't have the permission to change your manage roles.", "I don't have the permission to change your manage roles.",
), );
],
});
return;
} }
await member.roles.remove(discord.sklld_verify_role); await member.roles.remove(discord.sklld_verify_role);
await member.roles.add(discord.sklld_peasant_role); await member.roles.add(discord.sklld_peasant_role);
} }
await interaction.editReply({ return positiveEmbed(
embeds: [ `${interaction.user.username} is verified`,
new EmbedBuilder()
.setColor(POSITIVE_COLOR)
.setTitle(`${interaction.user.username} is verified`)
.setDescription(
`The user is now verified as ${markdownEscape( `The user is now verified as ${markdownEscape(
accountInfo[id].nickname, accountInfo[id].nickname,
)}${markdownEscape(clanTag)}`, )}${markdownEscape(clanTag)}`,
), );
],
});
} catch (error) { } catch (error) {
await interaction.editReply({ return negativeEmbed(
embeds: [ `${interaction.user.username} failed to verify`,
new EmbedBuilder()
.setColor(NEGATIVE_COLOR)
.setTitle(`${interaction.user.username} failed to verify`)
.setDescription(
"I can't change your nickname because you have higher permissions than me. Try setting your nickname to your Blitz username manually.", "I can't change your nickname because you have higher permissions than me. Try setting your nickname to your Blitz username manually.",
), );
],
});
}
}
} }
}, },
+2 -1
View File
@@ -1,3 +1,4 @@
export const ACCENT_COLOR = '#ecedee'; // theme.colors.textHighContrast export const ACCENT_COLOR = '#ecedee';
export const POSITIVE_COLOR = '#82ff29'; export const POSITIVE_COLOR = '#82ff29';
export const NEGATIVE_COLOR = '#ff4747'; export const NEGATIVE_COLOR = '#ff4747';
export const WARNING_COLOR = '#ffab00';
+9
View File
@@ -0,0 +1,9 @@
import { EmbedBuilder } from 'discord.js';
import { WARNING_COLOR } from '../../constants/colors.js';
export default function warningEmbed(title: string, description: string) {
return new EmbedBuilder()
.setColor(WARNING_COLOR)
.setTitle(title)
.setDescription(description);
}
+20
View File
@@ -0,0 +1,20 @@
export interface PSAData {
title: string;
description: string;
}
export interface PSA {
data?: PSAData;
}
export const psa: PSA = {};
console.log('Caching PSA...');
fetch(
'https://gist.githubusercontent.com/tresabhi/ed4b136f08856e615212e573aabe1968/raw',
)
.then((response) => response.json())
.then((data) => {
psa.data = data as PSAData;
console.log('PSA cached');
});
+45 -4
View File
@@ -5,7 +5,9 @@ import {
ButtonStyle, ButtonStyle,
CacheType, CacheType,
ChatInputCommandInteraction, ChatInputCommandInteraction,
EmbedBuilder,
Interaction, Interaction,
InteractionEditReplyOptions,
REST, REST,
RESTPostAPIChatInputApplicationCommandsJSONBody, RESTPostAPIChatInputApplicationCommandsJSONBody,
Routes, Routes,
@@ -27,24 +29,33 @@ import tankstats from '../commands/tankstats.js';
import today from '../commands/today.js'; import today from '../commands/today.js';
import verify from '../commands/verify.js'; import verify from '../commands/verify.js';
import negativeEmbed from '../core/interaction/negativeEmbed.js'; import negativeEmbed from '../core/interaction/negativeEmbed.js';
import warningEmbed from '../core/interaction/warningEmbed.js';
import { DISCORD_TOKEN } from '../core/process/args.js'; import { DISCORD_TOKEN } from '../core/process/args.js';
import getClientId from '../core/process/getClientId.js'; import getClientId from '../core/process/getClientId.js';
import isDev from '../core/process/isDev.js'; import isDev from '../core/process/isDev.js';
import { psa } from '../core/process/psa.js';
import render from '../core/ui/render.js';
import { handleError } from './error.js'; import { handleError } from './error.js';
export type CommandReturnable = EmbedBuilder | ButtonBuilder | JSX.Element;
export type RichCommandReturnable = CommandReturnable | CommandReturnable[];
export interface CommandRegistry { export interface CommandRegistry {
inDevelopment: boolean; inDevelopment: boolean;
inProduction: boolean; inProduction: boolean;
inPublic: boolean; inPublic: boolean;
command: Omit<SlashCommandBuilder, 'addSubcommand' | 'addSubcommandGroup'>; command: Omit<SlashCommandBuilder, 'addSubcommand' | 'addSubcommandGroup'>;
execute: (interaction: ChatInputCommandInteraction<CacheType>) => void; execute: (
interaction: ChatInputCommandInteraction<CacheType>,
) => RichCommandReturnable | Promise<RichCommandReturnable>;
autocomplete?: (interaction: AutocompleteInteraction<CacheType>) => void; autocomplete?: (interaction: AutocompleteInteraction<CacheType>) => void;
} }
const rest = new REST().setToken(DISCORD_TOKEN); const rest = new REST().setToken(DISCORD_TOKEN);
const commands = [ const commands = (
[
debug, debug,
eligible, eligible,
help, help,
@@ -59,7 +70,8 @@ const commands = [
tankstats, tankstats,
today, today,
verify, verify,
].reduce<Record<string, CommandRegistry>>((accumulator, registry) => { ] as CommandRegistry[]
).reduce<Record<string, CommandRegistry>>((accumulator, registry) => {
return { ...accumulator, [registry.command.name]: registry }; return { ...accumulator, [registry.command.name]: registry };
}, {}); }, {});
@@ -138,7 +150,36 @@ export default async function interactionCreate(
await interaction.deferReply(); await interaction.deferReply();
try { try {
await command.execute(interaction); const result = await command.execute(interaction);
const normalizedResult = Array.isArray(result) ? result : [result];
const reply: InteractionEditReplyOptions = {};
if (psa.data) {
normalizedResult.push(
warningEmbed(psa.data.title, psa.data.description),
);
}
await Promise.all(
normalizedResult.map(async (item) => {
if (item instanceof EmbedBuilder) {
if (!reply.embeds) reply.embeds = [];
reply.embeds.push(item);
} else if (item instanceof ButtonBuilder) {
if (!reply.components)
reply.components = [new ActionRowBuilder<ButtonBuilder>()];
(
reply.components[0] as ActionRowBuilder<ButtonBuilder>
).addComponents(item);
} else {
const image = await render(item);
if (!reply.files) reply.files = [];
reply.files.push(image);
}
}),
);
await interaction.editReply(reply);
} catch (error) { } catch (error) {
const actionRow = new ActionRowBuilder<ButtonBuilder>().addComponents( const actionRow = new ActionRowBuilder<ButtonBuilder>().addComponents(
new ButtonBuilder() new ButtonBuilder()