diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bot.ts | 5 | ||||
-rw-r--r-- | src/commands/config/config.ts | 4 | ||||
-rw-r--r-- | src/commands/config/features.ts | 2 | ||||
-rw-r--r-- | src/commands/moderation/warn.ts | 1 | ||||
-rw-r--r-- | src/commands/utilities/wolframAlpha.ts | 4 | ||||
-rw-r--r-- | src/lib/extensions/discord-akairo/BushClientUtil.ts | 10 | ||||
-rw-r--r-- | src/lib/models/Guild.ts | 8 | ||||
-rw-r--r-- | src/lib/utils/BushConstants.ts | 3 | ||||
-rw-r--r-- | src/listeners/custom/bushMute.ts | 2 | ||||
-rw-r--r-- | src/listeners/guild/guildMemberAdd.ts | 37 | ||||
-rw-r--r-- | src/listeners/guild/guildMemberRemove.ts | 21 | ||||
-rw-r--r-- | src/listeners/message/automodCreate.ts | 5 |
12 files changed, 72 insertions, 30 deletions
@@ -1,8 +1,7 @@ import 'module-alias/register'; import 'source-map-support/register'; import config from './config/options'; -import { BushClient } from './lib/'; +import { BushClient } from './lib'; BushClient.preStart(); -const client = new BushClient(config); -void client.start(); +void new BushClient(config).start(); diff --git a/src/commands/config/config.ts b/src/commands/config/config.ts index 4cab741..2075531 100644 --- a/src/commands/config/config.ts +++ b/src/commands/config/config.ts @@ -198,7 +198,7 @@ export default class SettingsCommand extends BushCommand { const action = message.util.isSlash ? args.subcommand! : args.action!; const value = args.value; - let msg; + let msg: Message; if (!setting || action === 'view') { const messageOptions = await this.generateMessageOptions(message, setting ?? undefined); @@ -241,7 +241,7 @@ export default class SettingsCommand extends BushCommand { } const collector = msg.createMessageComponentCollector({ time: 300_000, - filter: (i) => i.guildId === message.guildId && i.message.id === message.id + filter: (i) => i.guildId === msg.guildId && i.message.id === msg.id }); collector.on('collect', async (interaction: MessageComponentInteraction) => { diff --git a/src/commands/config/features.ts b/src/commands/config/features.ts index 743b243..076d469 100644 --- a/src/commands/config/features.ts +++ b/src/commands/config/features.ts @@ -30,7 +30,7 @@ export default class FeaturesCommand extends BushCommand { const collector = msg.createMessageComponentCollector({ componentType: 'SELECT_MENU', time: 300_000, - filter: (i) => i.guildId === message.guildId && i.message.id === message.id + filter: (i) => i.guildId === msg.guildId && i.message.id === msg.id }); collector.on('collect', async (interaction: SelectMenuInteraction) => { diff --git a/src/commands/moderation/warn.ts b/src/commands/moderation/warn.ts index 44f4f5a..b4bf74d 100644 --- a/src/commands/moderation/warn.ts +++ b/src/commands/moderation/warn.ts @@ -60,6 +60,7 @@ export default class WarnCommand extends BushCommand { { user, reason, force }: { user: BushUser; reason: string; force: boolean } ): Promise<unknown> { const member = message.guild!.members.cache.get(user.id) as BushGuildMember; + if (!member) return message.util.reply(`${util.emojis.error} I cannot warn users that are not in the server.`); const useForce = force && message.author.isOwner(); if (!message.member) throw new Error(`message.member is null`); const canModerateResponse = await util.moderationPermissionCheck(message.member, member, 'warn', true, useForce); diff --git a/src/commands/utilities/wolframAlpha.ts b/src/commands/utilities/wolframAlpha.ts index 69e2ff4..2b64c9c 100644 --- a/src/commands/utilities/wolframAlpha.ts +++ b/src/commands/utilities/wolframAlpha.ts @@ -1,5 +1,5 @@ import { AllowedMentions, BushCommand, BushMessage, BushSlashMessage } from '@lib'; -import { MessageEmbed } from 'discord.js'; +import { CommandInteraction, MessageEmbed } from 'discord.js'; // @ts-expect-error: no types :( import WolframAlphaAPI from 'wolfram-alpha-api'; @@ -39,6 +39,8 @@ export default class WolframAlphaCommand extends BushCommand { }); } public override async exec(message: BushMessage | BushSlashMessage, args: { expression: string }): Promise<unknown> { + if (message.util.isSlash) await (message.interaction as CommandInteraction).deferReply(); + const waApi = WolframAlphaAPI(client.config.credentials.wolframAlphaAppId); const decodedEmbed = new MessageEmbed().addField('📥 Input', await util.inspectCleanRedactCodeblock(args.expression)); diff --git a/src/lib/extensions/discord-akairo/BushClientUtil.ts b/src/lib/extensions/discord-akairo/BushClientUtil.ts index 64616f0..498b9cb 100644 --- a/src/lib/extensions/discord-akairo/BushClientUtil.ts +++ b/src/lib/extensions/discord-akairo/BushClientUtil.ts @@ -1095,7 +1095,7 @@ export class BushClientUtil extends ClientUtil { if (force) return true; // If the victim is not in the guild anymore it will be undefined - if (!victim.guild && ['ban', 'unban'].includes(type)) return true; + if ((!victim || !victim.guild) && !['ban', 'unban'].includes(type)) return true; if (moderator.guild.id !== victim.guild.id) { throw new Error('moderator and victim not in same guild'); @@ -1519,6 +1519,14 @@ export class BushClientUtil extends ClientUtil { } /** + * Removes all characters in a string that are either control characters or change the direction of text etc. + */ + public sanitizeWtlAndControl(str: string) { + // eslint-disable-next-line no-control-regex + return str.replace(/[\u0000-\u001F\u007F-\u009F\u200B]/g, ''); + } + + /** * Discord.js's Util class */ get discord() { diff --git a/src/lib/models/Guild.ts b/src/lib/models/Guild.ts index 1897068..ab18d05 100644 --- a/src/lib/models/Guild.ts +++ b/src/lib/models/Guild.ts @@ -92,10 +92,10 @@ export const guildFeaturesObj = { name: 'Auto Publish', description: 'Publishes messages in configured announcement channels.' }, - autoThread: { - name: 'Auto Thread', - description: 'Creates a new thread for messages in configured channels.' - }, + // autoThread: { + // name: 'Auto Thread', + // description: 'Creates a new thread for messages in configured channels.' + // }, blacklistedFile: { name: 'Blacklisted File', description: 'Automatically deletes malicious files.' diff --git a/src/lib/utils/BushConstants.ts b/src/lib/utils/BushConstants.ts index 68c0951..0e1388e 100644 --- a/src/lib/utils/BushConstants.ts +++ b/src/lib/utils/BushConstants.ts @@ -228,8 +228,11 @@ export class BushConstants { REQUEST_TO_SPEAK: { name: 'Request to Speak', important: false }, MANAGE_THREADS: { name: 'Manage Threads', important: true }, USE_PUBLIC_THREADS: { name: 'Use public Threads', important: false }, + CREATE_PUBLIC_THREADS: { name: 'Create Public Threads', important: false }, USE_PRIVATE_THREADS: { name: 'Use Private Threads', important: false }, + CREATE_PRIVATE_THREADS: { name: 'Create Private Threads', important: false }, USE_EXTERNAL_STICKERS: { name: 'Use External Stickers', important: false }, + SEND_MESSAGES_IN_THREADS: { name: 'Send Messages In Threads', important: false }, START_EMBEDDED_ACTIVITIES: { name: 'Start Activities', important: false } }, diff --git a/src/listeners/custom/bushMute.ts b/src/listeners/custom/bushMute.ts index 615d698..d0f9e06 100644 --- a/src/listeners/custom/bushMute.ts +++ b/src/listeners/custom/bushMute.ts @@ -27,7 +27,7 @@ export default class BushMuteListener extends BushListener { .addField('**User**', `${user} (${user.tag})`) .addField('**Moderator**', `${moderator} (${moderator.tag})`) .addField('**Reason**', `${reason ?? '[No Reason Provided]'}`); - if (duration) logEmbed.addField('**Duration**', util.humanizeDuration(duration)); + if (duration) logEmbed.addField('**Duration**', `${util.humanizeDuration(duration) || duration}`); if (dmSuccess === false) logEmbed.addField('**Additional Info**', 'Could not dm user.'); return await logChannel.send({ embeds: [logEmbed] }); } diff --git a/src/listeners/guild/guildMemberAdd.ts b/src/listeners/guild/guildMemberAdd.ts index db014a8..cb8057f 100644 --- a/src/listeners/guild/guildMemberAdd.ts +++ b/src/listeners/guild/guildMemberAdd.ts @@ -25,18 +25,24 @@ export default class GuildMemberAddListener extends BushListener { if (member.guild.id !== welcome?.guild.id) throw new Error('Welcome channel must be in the guild.'); const embed = new MessageEmbed() .setDescription( - `${util.emojis.join} **${Util.escapeMarkdown( - member.user.tag + `${util.emojis.join} **${util.sanitizeWtlAndControl( + Util.escapeMarkdown(member.user.tag) )}** joined the server. There are now ${member.guild.memberCount.toLocaleString()} members.` ) .setColor(util.colors.green); await welcome .send({ embeds: [embed] }) .then(() => - client.console.info('guildMemberAdd', `Sent a message for <<${member.user.tag}>> in <<${member.guild.name}>>.`) + client.console.info( + 'guildMemberAdd', + `Sent a message for <<${util.sanitizeWtlAndControl(member.user.tag)}>> in <<${member.guild.name}>>.` + ) ) .catch(() => - client.console.warn('guildMemberAdd', `Failed to send message for <<${member.user.tag}>> in <<${member.guild.name}>>.`) + client.console.warn( + 'guildMemberAdd', + `Failed to send message for <<${util.sanitizeWtlAndControl(member.user.tag)}>> in <<${member.guild.name}>>.` + ) ); } @@ -60,12 +66,16 @@ export default class GuildMemberAddListener extends BushListener { const addedRoles = await member.roles .add(rolesArray, "Returning member's previous roles.") .catch( - () => void client.console.warn('guildMemberAdd', `There was an error returning <<${member.user.tag}>>'s roles.`) + () => + void client.console.warn( + 'guildMemberAdd', + `There was an error returning <<${util.sanitizeWtlAndControl(member.user.tag)}>>'s roles.` + ) ); if (addedRoles) { void client.console.info( 'guildMemberAdd', - `Assigned sticky roles to <<${member.user.tag}>> in <<${member.guild.name}>>.` + `Assigned sticky roles to <<${util.sanitizeWtlAndControl(member.user.tag)}>> in <<${member.guild.name}>>.` ); } else if (!addedRoles) { const failedRoles: string[] = []; @@ -75,11 +85,13 @@ export default class GuildMemberAddListener extends BushListener { .catch(() => failedRoles.push(rolesArray[i])); } if (failedRoles.length) { - void client.console.warn('guildMemberAdd', `Failed assigning the following roles on Fallback:${failedRoles}`); + void client.console.warn('guildMemberAdd', `Failed assigning the following roles on Fallback: ${failedRoles}`); } else { void client.console.info( 'guildMemberAdd', - `[Fallback] Assigned sticky roles to <<${member.user.tag}>> in <<${member.guild.name}>>.` + `[Fallback] Assigned sticky roles to <<${util.sanitizeWtlAndControl(member.user.tag)}>> in <<${ + member.guild.name + }>>.` ); } } @@ -90,13 +102,18 @@ export default class GuildMemberAddListener extends BushListener { await member.roles .add(joinRoles, 'Join roles.') .then(() => - client.console.info('guildMemberAdd', `Assigned join roles to <<${member.user.tag}>> in <<${member.guild.name}>>.`) + client.console.info( + 'guildMemberAdd', + `Assigned join roles to <<${util.sanitizeWtlAndControl(member.user.tag)}>> in <<${member.guild.name}>>.` + ) ) .catch( () => void client.console.warn( 'guildMemberAdd', - `Failed to assign join roles to <<${member.user.tag}>>, in <<${member.guild.name}>>.` + `Failed to assign join roles to <<${util.sanitizeWtlAndControl(member.user.tag)}>>, in <<${ + member.guild.name + }>>.` ) ); } diff --git a/src/listeners/guild/guildMemberRemove.ts b/src/listeners/guild/guildMemberRemove.ts index 90634d6..5f13f22 100644 --- a/src/listeners/guild/guildMemberRemove.ts +++ b/src/listeners/guild/guildMemberRemove.ts @@ -27,16 +27,24 @@ export default class GuildMemberRemoveListener extends BushListener { if (member.guild.id !== welcome?.guild.id) throw new Error('Welcome channel must be in the guild.'); const embed: MessageEmbed = new MessageEmbed() .setDescription( - `${util.emojis.leave} **${Util.escapeBold(user.tag)}** ${ - isBan ? 'banned from' : 'left' + `${util.emojis.leave} **${util.sanitizeWtlAndControl(Util.escapeBold(user.tag))}** ${ + isBan ? 'got banned from' : 'left' } the server. There are now ${welcome.guild.memberCount.toLocaleString()} members.` ) .setColor(isBan ? util.colors.orange : util.colors.red); welcome .send({ embeds: [embed] }) - .then(() => client.console.info('guildMemberRemove', `Sent a message for <<${user.tag}>> in <<${member.guild.name}>>.`)) + .then(() => + client.console.info( + 'guildMemberRemove', + `Sent a message for <<${util.sanitizeWtlAndControl(user.tag)}>> in <<${member.guild.name}>>.` + ) + ) .catch(() => - client.console.warn('guildMemberRemove', `Failed to send message for <<${user.tag}>> in <<${member.guild.name}>>.`) + client.console.warn( + 'guildMemberRemove', + `Failed to send message for <<${util.sanitizeWtlAndControl(user.tag)}>> in <<${member.guild.name}>>.` + ) ); } @@ -65,7 +73,10 @@ export default class GuildMemberRemoveListener extends BushListener { await row .save() .then(() => - client.console.info('guildMemberRemove', `${isNew ? 'Created' : 'Updated'} info for <<${member.user.tag}>>.`) + client.console.info( + 'guildMemberRemove', + `${isNew ? 'Created' : 'Updated'} info for <<${util.sanitizeWtlAndControl(member.user.tag)}>>.` + ) ); } } diff --git a/src/listeners/message/automodCreate.ts b/src/listeners/message/automodCreate.ts index c3c89ff..03c1603 100644 --- a/src/listeners/message/automodCreate.ts +++ b/src/listeners/message/automodCreate.ts @@ -41,14 +41,15 @@ export default class AutomodMessageCreateListener extends BushListener { const offences: { [key: string]: 0 | 1 | 2 | 3 } = {}; const cleanMessageContent = message.content?.toLowerCase().replace(/ /g, ''); - wordKeys.forEach((word) => { + for (const word in wordKeys) { const cleanWord = word.toLowerCase().replace(/ /g, ''); if (cleanMessageContent.includes(cleanWord)) { if (cleanWord === 'whore' && !message.content?.toLowerCase().includes(cleanWord)) return; if (!offences[word]) offences[word] = wordMap[word as keyof typeof wordMap]; } - }); + } + if (!Object.keys(offences)?.length) return; const highestOffence = Object.values(offences).sort((a, b) => b - a)[0]; |