Compare commits

...
6 Commits
Author SHA1 Message Date
TrèsAbhi c1bd91a7f9 Merge pull request #63 from tresabhi/1.15.11 2024-01-21 18:48:12 -06:00
TrèsAbhi 1d65ff3e0c fix: type 2024-01-21 18:46:38 -06:00
TrèsAbhi f7fac5ad26 feat: chagelogs 2024-01-21 18:44:58 -06:00
TrèsAbhi e45f055493 feat: permissions command 2024-01-21 18:43:07 -06:00
TrèsAbhi 8946f115c0 feat: no embed errors 2024-01-21 18:29:32 -06:00
TrèsAbhi 6094875ffb discord tokens... for some reason? 2024-01-19 21:52:50 -06:00
16 changed files with 73 additions and 45 deletions

No files matched your search

+1 -1
View File
@@ -35,4 +35,4 @@ jobs:
run: yarn run: yarn
- name: Generate leaderboard - name: Generate leaderboard
run: GH_TOKEN=${{ secrets.GH_TOKEN }} yarn publish:ratingsleaderboard --region=asia --target=${{ github.event.schedule == '0 0 * * *' && 'latest' || 'midnight' }} run: GH_TOKEN=${{ secrets.GH_TOKEN }} DISCORD_TOKEN=${{ secrets.DISCORD_TOKEN }} yarn publish:ratingsleaderboard --region=asia --target=${{ github.event.schedule == '0 0 * * *' && 'latest' || 'midnight' }}
+1 -1
View File
@@ -35,4 +35,4 @@ jobs:
run: yarn run: yarn
- name: Generate leaderboard - name: Generate leaderboard
run: GH_TOKEN=${{ secrets.GH_TOKEN }} yarn publish:ratingsleaderboard --region=eu --target=${{ github.event.schedule == '0 0 * * *' && 'latest' || 'midnight' }} run: GH_TOKEN=${{ secrets.GH_TOKEN }} DISCORD_TOKEN=${{ secrets.DISCORD_TOKEN }} yarn publish:ratingsleaderboard --region=eu --target=${{ github.event.schedule == '0 0 * * *' && 'latest' || 'midnight' }}
+1 -1
View File
@@ -35,4 +35,4 @@ jobs:
run: yarn run: yarn
- name: Generate leaderboard - name: Generate leaderboard
run: GH_TOKEN=${{ secrets.GH_TOKEN }} yarn publish:ratingsleaderboard --region=na --target=${{ github.event.schedule == '0 0 * * *' && 'latest' || 'midnight' }} run: GH_TOKEN=${{ secrets.GH_TOKEN }} DISCORD_TOKEN=${{ secrets.DISCORD_TOKEN }} yarn publish:ratingsleaderboard --region=na --target=${{ github.event.schedule == '0 0 * * *' && 'latest' || 'midnight' }}
+11
View File
@@ -0,0 +1,11 @@
# Blitzkrieg 1.15.11
There's an easter egg somewhere in this update 🤔
## Features
- Added `/permissions` which lists all permissions required to run the bot and checks if the bot has them or not
## Changes
- Error messages now do no use embeds, instead utilize simple headings and paragraphs
-7
View File
@@ -1,7 +0,0 @@
# Permissions
The following Discord permissions are required by the bot to ensure full functionality:
- Manage nicknames
- Read messages / view channels
- Attach files
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "blitzkrieg", "name": "blitzkrieg",
"version": "1.15.10", "version": "1.15.11",
"description": "🎉 Tools for everything World of Tanks Blitz", "description": "🎉 Tools for everything World of Tanks Blitz",
"main": "src/server.ts", "main": "src/server.ts",
"type": "module", "type": "module",
-2
View File
@@ -6,7 +6,6 @@ import { COMMANDS_RAW, CommandRegistry } from '../events/interactionCreate';
const RAW_PATH = `https://raw.githubusercontent.com/tresabhi/blitzkrieg/main/docs/`; const RAW_PATH = `https://raw.githubusercontent.com/tresabhi/blitzkrieg/main/docs/`;
const DOCS = { const DOCS = {
permissions: 'guide/permissions',
embeds: 'guide/embeds', embeds: 'guide/embeds',
introduction: 'guide/introduction', introduction: 'guide/introduction',
invite: 'guide/invite', invite: 'guide/invite',
@@ -14,7 +13,6 @@ const DOCS = {
creators: 'guide/creators', creators: 'guide/creators',
}; };
const DOC_DESCRIPTIONS: Record<keyof typeof DOCS, string> = { const DOC_DESCRIPTIONS: Record<keyof typeof DOCS, string> = {
permissions: 'The permissions needed for the bot to function',
embeds: 'How embeds work', embeds: 'How embeds work',
introduction: 'About the bot', introduction: 'About the bot',
invite: 'How to invite the bot', invite: 'How to invite the bot',
+42
View File
@@ -0,0 +1,42 @@
import { SlashCommandBuilder } from 'discord.js';
import { CommandRegistry } from '../events/interactionCreate';
export const permissionsCommand: CommandRegistry = {
inProduction: true,
inPublic: true,
command: new SlashCommandBuilder()
.setName('permissions')
.setDescription('Checks wether the bot has the required permissions'),
async handler(interaction) {
// friday the 13th permissions easter egg
const isFridayThe13th =
new Date().getDay() === 5 && new Date().getDate() === 13;
const permissions = [
[
interaction.appPermissions?.has('ViewChannel'),
'View channels: needed for the refresh button to work',
],
[
interaction.appPermissions?.has('ReadMessageHistory'),
'Read message history: also needed for the refresh button to work',
],
[
interaction.appPermissions?.has('AttachFiles'),
'Attach files: needed for image-based commands to work',
],
];
const body = permissions
.map(([hasPermission, description]) => {
if (hasPermission) {
return `${isFridayThe13th ? '😇' : '✅'} ${description}`;
} else {
return `${isFridayThe13th ? '💀' : '❌'} ${description}`;
}
})
.join('\n');
return `# Permissions\n${body}`;
},
};
+2 -2
View File
@@ -4,6 +4,7 @@ import {
SlashCommandSubcommandBuilder, SlashCommandSubcommandBuilder,
} from 'discord.js'; } from 'discord.js';
import { range } from 'lodash'; import { range } from 'lodash';
import markdownEscape from 'markdown-escape';
import { BlitzkriegRatingsLeaderboard } from '../../scripts/buildRatingsLeaderboard'; import { BlitzkriegRatingsLeaderboard } from '../../scripts/buildRatingsLeaderboard';
import * as Leaderboard from '../components/Leaderboard'; import * as Leaderboard from '../components/Leaderboard';
import TitleBar from '../components/TitleBar'; import TitleBar from '../components/TitleBar';
@@ -337,8 +338,7 @@ export const ratingsCommand = new Promise<CommandRegistryPromisable>(
if (playerIndex === -1) { if (playerIndex === -1) {
throw new UserError( throw new UserError(
`${accountInfo.nickname} didn't play ratings in season ${season}`, `# ${markdownEscape(accountInfo.nickname)} didn't play ratings in season ${season}\nThis player did not participate in this season or did not get past calibration.`,
'This player did not participate in this season or did not get past calibration.',
); );
} }
+1 -2
View File
@@ -11,8 +11,7 @@ export default async function getTankStats(region: Region, id: number) {
if (tankStats[id] === null) { if (tankStats[id] === null) {
throw new UserError( throw new UserError(
'No tank stats available', "# No tank stats available\nThis player doesn't have any stats available. This may not be the player you are looking for.",
"This player doesn't have any stats available. This may not be the player you are looking for.",
); );
} }
+3 -4
View File
@@ -1,4 +1,5 @@
import { go } from 'fuzzysort'; import { go } from 'fuzzysort';
import markdownEscape from 'markdown-escape';
import { import {
tankDefinitions, tankDefinitions,
tanksDefinitionsArray, tanksDefinitionsArray,
@@ -16,8 +17,7 @@ export default async function resolveTankId(tank: string | number) {
if (searchResult.length === 0) { if (searchResult.length === 0) {
throw new UserError( throw new UserError(
'Tank not found', `# Tank not found\nCould not find tank by the name "${markdownEscape(`${tank}`)}".`,
`Could not find tank by the name "${tank}".`,
); );
} else { } else {
return searchResult[0].obj.id; return searchResult[0].obj.id;
@@ -27,8 +27,7 @@ export default async function resolveTankId(tank: string | number) {
return number; return number;
} else { } else {
throw new UserError( throw new UserError(
'Tank not found', `# Tank not found\nCould not find tank by the ID "${number}". Try typing the name of the tank instead of a number.`,
`Could not find tank by the ID "${number}". Try typing the name of the tank instead of a number.`,
); );
} }
} }
+1 -4
View File
@@ -2,8 +2,5 @@
* Discriminator for user caused errors to not report in logs * Discriminator for user caused errors to not report in logs
*/ */
export class UserError { export class UserError {
constructor( constructor(public message: string) {}
public message: string,
public cause: string,
) {}
} }
+2 -2
View File
@@ -1,4 +1,5 @@
import { ChatInputCommandInteraction } from 'discord.js'; import { ChatInputCommandInteraction } from 'discord.js';
import markdownEscape from 'markdown-escape';
import { Region } from '../../constants/regions'; import { Region } from '../../constants/regions';
import searchClansAcrossRegions from '../blitz/searchClansAcrossRegions'; import searchClansAcrossRegions from '../blitz/searchClansAcrossRegions';
import { UserError } from '../blitzkrieg/userError'; import { UserError } from '../blitzkrieg/userError';
@@ -19,8 +20,7 @@ export default async function resolveClanFromCommand(
return { region: accounts[0].region, id: accounts[0].clan_id }; return { region: accounts[0].region, id: accounts[0].clan_id };
} else { } else {
throw new UserError( throw new UserError(
'Could not find clan', `# Could not find clan\nCouldn't find "${markdownEscape(clan)}". Try selecting a clan from the search result.`,
`\`${clan}\` was not found. Try selecting a clan from the search result.`,
); );
} }
} }
+2 -4
View File
@@ -35,8 +35,7 @@ export default async function resolvePlayerFromCommand(
} satisfies ResolvedPlayer; } satisfies ResolvedPlayer;
} else { } else {
throw new UserError( throw new UserError(
'Could not find user', `# Could not find user\nI couldn't find user "${markdownEscape(
`I couldn't find user "${markdownEscape(
commandUsername, commandUsername,
)}". Try picking an user from the search result, typing in a valid username, or using the \`/link\` command.`, )}". Try picking an user from the search result, typing in a valid username, or using the \`/link\` command.`,
); );
@@ -49,8 +48,7 @@ export default async function resolvePlayerFromCommand(
return { region: account.region, id: account.blitz }; return { region: account.region, id: account.blitz };
} else { } else {
throw new UserError( throw new UserError(
"You're account isn't linked with Blitzkrieg yet", "# I don't know who you are\nUse the `/link` command to get started.",
'Use the `/link` command to get started.',
); );
} }
} }
@@ -11,7 +11,6 @@ import { commands } from '..';
import discord from '../../../../discord.json' assert { type: 'json' }; import discord from '../../../../discord.json' assert { type: 'json' };
import { UserError } from '../../../core/blitzkrieg/userError'; import { UserError } from '../../../core/blitzkrieg/userError';
import buttonLink from '../../../core/discord/buttonLink'; import buttonLink from '../../../core/discord/buttonLink';
import embedNegative from '../../../core/discord/embedNegative';
import embedWarning from '../../../core/discord/embedWarning'; import embedWarning from '../../../core/discord/embedWarning';
import normalizeInteractionReturnable from '../../../core/discord/normalizeInteractionReturnable'; import normalizeInteractionReturnable from '../../../core/discord/normalizeInteractionReturnable';
import { psa } from '../../../core/discord/psa'; import { psa } from '../../../core/discord/psa';
@@ -119,25 +118,15 @@ export default async function handleChatInputCommand(
if (error instanceof UserError) { if (error instanceof UserError) {
interaction.editReply({ interaction.editReply({
embeds: [ content: error.message,
embedNegative(
error.message,
(error.cause as string | undefined) ??
'No further information is available.',
),
],
components, components,
}); });
} else { } else {
console.error(interaction.commandName, error); console.error(interaction.commandName, error);
interaction.editReply({ interaction.editReply({
embeds: [ content:
embedNegative( "# Blitzkrieg ran into an error!\nWe're so sorry about this. Feel free to [join the official Discord server](https://discord.gg/nDt7AjGJQH) to get help.",
'Blitzkrieg ran into an error!',
"We're so sorry about this. Feel free to [join the official Discord server](https://discord.gg/nDt7AjGJQH) to get help.",
),
],
components, components,
}); });
} }
+2
View File
@@ -23,6 +23,7 @@ import { fullStatsCommand } from '../../commands/fullStats';
import { inactiveCommand } from '../../commands/inactive'; import { inactiveCommand } from '../../commands/inactive';
import { verifyCommand } from '../../commands/link'; import { verifyCommand } from '../../commands/link';
import { ownedTanksCommand } from '../../commands/ownedTanks'; import { ownedTanksCommand } from '../../commands/ownedTanks';
import { permissionsCommand } from '../../commands/permissions';
import { pingCommand } from '../../commands/ping'; import { pingCommand } from '../../commands/ping';
import { playerAchievementsCommand } from '../../commands/playerAchievements'; import { playerAchievementsCommand } from '../../commands/playerAchievements';
import { playerInfoCommand } from '../../commands/playerInfo'; import { playerInfoCommand } from '../../commands/playerInfo';
@@ -90,6 +91,7 @@ export type CommandRegistry =
const rest = new REST().setToken(secrets.DISCORD_TOKEN); const rest = new REST().setToken(secrets.DISCORD_TOKEN);
export const COMMANDS_RAW: CommandRegistry[] = [ export const COMMANDS_RAW: CommandRegistry[] = [
permissionsCommand,
debugCommand, debugCommand,
eligibleCommand, eligibleCommand,
aboutCommand, aboutCommand,