aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arguments/globalUser.ts4
-rw-r--r--src/arguments/messageLink.ts8
-rw-r--r--src/bot.ts1
-rw-r--r--src/commands/admin/channelPermissions.ts2
-rw-r--r--src/commands/config/_customAutomodPhrases.ts2
-rw-r--r--src/commands/config/blacklist.ts8
-rw-r--r--src/commands/config/config.ts10
-rw-r--r--src/commands/config/disable.ts8
-rw-r--r--src/commands/config/features.ts2
-rw-r--r--src/commands/dev/dm.ts2
-rw-r--r--src/commands/dev/eval.ts8
-rw-r--r--src/commands/dev/javascript.ts7
-rw-r--r--src/commands/dev/reload.ts27
-rw-r--r--src/commands/dev/say.ts2
-rw-r--r--src/commands/dev/servers.ts4
-rw-r--r--src/commands/dev/sh.ts13
-rw-r--r--src/commands/dev/superUser.ts15
-rw-r--r--src/commands/dev/test.ts10
-rw-r--r--src/commands/info/botInfo.ts23
-rw-r--r--src/commands/info/guildInfo.ts2
-rw-r--r--src/commands/info/help.ts13
-rw-r--r--src/commands/info/links.ts4
-rw-r--r--src/commands/info/pronouns.ts3
-rw-r--r--src/commands/info/snowflake.ts27
-rw-r--r--src/commands/info/userInfo.ts16
-rw-r--r--src/commands/leveling/leaderboard.ts3
-rw-r--r--src/commands/leveling/level.ts3
-rw-r--r--src/commands/moderation/_activePunishments.ts12
-rw-r--r--src/commands/moderation/ban.ts4
-rw-r--r--src/commands/moderation/evidence.ts2
-rw-r--r--src/commands/moderation/hideCase.ts2
-rw-r--r--src/commands/moderation/massBan.ts2
-rw-r--r--src/commands/moderation/massEvidence.ts2
-rw-r--r--src/commands/moderation/modlog.ts3
-rw-r--r--src/commands/moderation/mute.ts3
-rw-r--r--src/commands/moderation/purge.ts2
-rw-r--r--src/commands/moderation/unmute.ts3
-rw-r--r--src/commands/moulberry-bush/giveawayPing.ts35
-rw-r--r--src/commands/moulberry-bush/report.ts2
-rw-r--r--src/commands/utilities/_poll.ts2
-rw-r--r--src/commands/utilities/activity.ts2
-rw-r--r--src/commands/utilities/calculator.ts14
-rw-r--r--src/commands/utilities/decode.ts9
-rw-r--r--src/commands/utilities/highlight-add.ts2
-rw-r--r--src/commands/utilities/highlight-clear.ts2
-rw-r--r--src/commands/utilities/highlight-matches.ts2
-rw-r--r--src/commands/utilities/highlight-remove.ts2
-rw-r--r--src/commands/utilities/highlight-show.ts2
-rw-r--r--src/commands/utilities/viewRaw.ts3
-rw-r--r--src/commands/utilities/wolframAlpha.ts19
-rw-r--r--src/context-menu-commands/user/modlog.ts4
-rw-r--r--src/context-menu-commands/user/userInfo.ts2
-rw-r--r--src/inhibitors/blacklist/channelGlobalBlacklist.ts6
-rw-r--r--src/inhibitors/blacklist/channelGuildBlacklist.ts4
-rw-r--r--src/inhibitors/blacklist/guildBlacklist.ts10
-rw-r--r--src/inhibitors/blacklist/userGlobalBlacklist.ts6
-rw-r--r--src/inhibitors/blacklist/userGuildBlacklist.ts8
-rw-r--r--src/inhibitors/checks/fatal.ts9
-rw-r--r--src/inhibitors/checks/guildUnavailable.ts2
-rw-r--r--src/inhibitors/command/dm.ts2
-rw-r--r--src/inhibitors/command/globalDisabledCommand.ts4
-rw-r--r--src/inhibitors/command/guild.ts2
-rw-r--r--src/inhibitors/command/guildDisabledCommand.ts2
-rw-r--r--src/inhibitors/command/nsfw.ts2
-rw-r--r--src/inhibitors/command/owner.ts4
-rw-r--r--src/inhibitors/command/restrictedChannel.ts2
-rw-r--r--src/inhibitors/command/restrictedGuild.ts2
-rw-r--r--src/inhibitors/command/superUser.ts4
-rw-r--r--src/lib/common/AutoMod.ts30
-rw-r--r--src/lib/common/ButtonPaginator.ts2
-rw-r--r--src/lib/common/ConfirmationPrompt.ts2
-rw-r--r--src/lib/common/DeleteButton.ts2
-rw-r--r--src/lib/common/HighlightManager.ts8
-rw-r--r--src/lib/common/util/Arg.ts2
-rw-r--r--src/lib/common/util/Moderation.ts53
-rw-r--r--src/lib/extensions/discord-akairo/BushClient.ts89
-rw-r--r--src/lib/extensions/discord-akairo/BushCommand.ts8
-rw-r--r--src/lib/extensions/discord-akairo/BushCommandHandler.ts7
-rw-r--r--src/lib/extensions/discord-akairo/BushInhibitor.ts8
-rw-r--r--src/lib/extensions/discord.js/ExtendedGuild.ts48
-rw-r--r--src/lib/extensions/discord.js/ExtendedGuildMember.ts77
-rw-r--r--src/lib/extensions/discord.js/ExtendedMessage.ts2
-rw-r--r--src/lib/extensions/discord.js/ExtendedUser.ts4
-rw-r--r--src/lib/extensions/global.ts8
-rw-r--r--src/lib/models/instance/Guild.ts4
-rw-r--r--src/lib/utils/BushClientUtils.ts480
-rw-r--r--src/lib/utils/BushLogger.ts77
-rw-r--r--src/lib/utils/BushUtils.ts461
-rw-r--r--src/listeners/bush/appealListener.ts5
-rw-r--r--src/listeners/bush/joinAutoBan.ts6
-rw-r--r--src/listeners/bush/supportThread.ts8
-rw-r--r--src/listeners/bush/userUpdateAutoBan.ts8
-rw-r--r--src/listeners/client/akairoDebug.ts4
-rw-r--r--src/listeners/client/dcjsDebug.ts2
-rw-r--r--src/listeners/client/dcjsError.ts2
-rw-r--r--src/listeners/client/dcjsWarn.ts2
-rw-r--r--src/listeners/client/ready.ts12
-rw-r--r--src/listeners/commands/commandBlocked.ts11
-rw-r--r--src/listeners/commands/commandCooldown.ts2
-rw-r--r--src/listeners/commands/commandError.ts36
-rw-r--r--src/listeners/commands/commandMissingPermissions.ts5
-rw-r--r--src/listeners/commands/commandStarted.ts8
-rw-r--r--src/listeners/commands/messageBlocked.ts5
-rw-r--r--src/listeners/commands/slashBlocked.ts2
-rw-r--r--src/listeners/commands/slashCommandError.ts2
-rw-r--r--src/listeners/commands/slashMissingPermissions.ts2
-rw-r--r--src/listeners/commands/slashNotFound.ts2
-rw-r--r--src/listeners/commands/slashStarted.ts8
-rw-r--r--src/listeners/contextCommands/contextCommandBlocked.ts2
-rw-r--r--src/listeners/contextCommands/contextCommandError.ts10
-rw-r--r--src/listeners/contextCommands/contextCommandNotFound.ts2
-rw-r--r--src/listeners/contextCommands/contextCommandStarted.ts6
-rw-r--r--src/listeners/guild/guildCreate.ts11
-rw-r--r--src/listeners/guild/guildDelete.ts11
-rw-r--r--src/listeners/guild/guildMemberAdd.ts6
-rw-r--r--src/listeners/guild/guildMemberRemove.ts10
-rw-r--r--src/listeners/guild/joinRoles.ts10
-rw-r--r--src/listeners/interaction/interactionCreate.ts2
-rw-r--r--src/listeners/member-custom/bushPurge.ts4
-rw-r--r--src/listeners/member-custom/bushUpdateModlog.ts12
-rw-r--r--src/listeners/member-custom/bushUpdateSettings.ts6
-rw-r--r--src/listeners/message/autoPublisher.ts5
-rw-r--r--src/listeners/message/blacklistedFile.ts6
-rw-r--r--src/listeners/message/boosterMessage.ts2
-rw-r--r--src/listeners/message/directMessage.ts10
-rw-r--r--src/listeners/message/highlight.ts6
-rw-r--r--src/listeners/message/level.ts9
-rw-r--r--src/listeners/message/quoteCreate.ts6
-rw-r--r--src/listeners/message/verbose.ts4
-rw-r--r--src/listeners/other/consoleListener.ts5
-rw-r--r--src/listeners/other/exit.ts2
-rw-r--r--src/listeners/other/promiseRejection.ts12
-rw-r--r--src/listeners/other/uncaughtException.ts8
-rw-r--r--src/listeners/other/warning.ts8
-rw-r--r--src/listeners/rest/rateLimit.ts2
-rw-r--r--src/listeners/track-manual-punishments/modlogSyncBan.ts1
-rw-r--r--src/listeners/track-manual-punishments/modlogSyncKick.ts1
-rw-r--r--src/listeners/track-manual-punishments/modlogSyncTimeout.ts1
-rw-r--r--src/listeners/track-manual-punishments/modlogSyncUnban.ts1
-rw-r--r--src/listeners/ws/INTERACTION_CREATE.ts10
-rw-r--r--src/tasks/cpuUsage.ts6
-rw-r--r--src/tasks/handleReminders.ts7
-rw-r--r--src/tasks/memberCount.ts6
-rw-r--r--src/tasks/removeExpiredPunishements.ts16
-rw-r--r--src/tasks/updateCache.ts15
-rw-r--r--src/tasks/updateHighlightCache.ts2
-rw-r--r--src/tasks/updateStats.ts10
147 files changed, 1167 insertions, 1023 deletions
diff --git a/src/arguments/globalUser.ts b/src/arguments/globalUser.ts
index df4f5d9..4324aa9 100644
--- a/src/arguments/globalUser.ts
+++ b/src/arguments/globalUser.ts
@@ -2,6 +2,6 @@ import type { BushArgumentTypeCaster } from '#lib';
import type { User } from 'discord.js';
// resolve non-cached users
-export const globalUser: BushArgumentTypeCaster<Promise<User | null>> = async (_, phrase) => {
- return client.users.resolve(phrase) ?? (await client.users.fetch(`${phrase}`).catch(() => null));
+export const globalUser: BushArgumentTypeCaster<Promise<User | null>> = async (message, phrase) => {
+ return message.client.users.resolve(phrase) ?? (await message.client.users.fetch(`${phrase}`).catch(() => null));
};
diff --git a/src/arguments/messageLink.ts b/src/arguments/messageLink.ts
index a473485..c95e42d 100644
--- a/src/arguments/messageLink.ts
+++ b/src/arguments/messageLink.ts
@@ -1,7 +1,7 @@
import { BushArgumentTypeCaster, regex } from '#lib';
import type { Message } from 'discord.js';
-export const messageLink: BushArgumentTypeCaster<Promise<Message | null>> = async (_, phrase) => {
+export const messageLink: BushArgumentTypeCaster<Promise<Message | null>> = async (message, phrase) => {
const match = new RegExp(regex.messageLink).exec(phrase);
if (!match || !match.groups) return null;
@@ -9,12 +9,12 @@ export const messageLink: BushArgumentTypeCaster<Promise<Message | null>> = asyn
if (!guild_id || !channel_id || message_id) return null;
- const guild = client.guilds.cache.get(guild_id);
+ const guild = message.client.guilds.cache.get(guild_id);
if (!guild) return null;
const channel = guild.channels.cache.get(channel_id);
if (!channel || (!channel.isTextBased() && !channel.isThread())) return null;
- const message = await channel.messages.fetch(message_id).catch(() => null);
- return message;
+ const msg = await channel.messages.fetch(message_id).catch(() => null);
+ return msg;
};
diff --git a/src/bot.ts b/src/bot.ts
index ed0a33f..7d8327e 100644
--- a/src/bot.ts
+++ b/src/bot.ts
@@ -13,7 +13,6 @@ const isDry = process.argv.includes('dry');
if (!isDry) new Sentry(dirname(fileURLToPath(import.meta.url)) || process.cwd());
BushClient.extendStructures();
const client = new BushClient(config);
-global.client = client;
if (!isDry) await client.dbPreInit();
await client.init();
if (isDry) {
diff --git a/src/commands/admin/channelPermissions.ts b/src/commands/admin/channelPermissions.ts
index 12245a9..15a1128 100644
--- a/src/commands/admin/channelPermissions.ts
+++ b/src/commands/admin/channelPermissions.ts
@@ -89,7 +89,7 @@ export default class ChannelPermissionsCommand extends BushCommand {
{ reason: 'Changing overwrites for mass channel perms command' }
);
} catch (e) {
- void client.console.error('channelPermissions', formatError(e, false));
+ void this.client.console.error('channelPermissions', formatError(e, false));
failedChannels.push(channel);
}
}
diff --git a/src/commands/config/_customAutomodPhrases.ts b/src/commands/config/_customAutomodPhrases.ts
index d60688c..0b571e5 100644
--- a/src/commands/config/_customAutomodPhrases.ts
+++ b/src/commands/config/_customAutomodPhrases.ts
@@ -1,4 +1,4 @@
-// import { BushCommand, type ArgType, type CommandMessage, type OptArgType, type SlashMessage } from '#lib';
+// import { BushCommand, clientSendAndPermCheck, type ArgType, type CommandMessage, type OptArgType, type SlashMessage } from '#lib';
// import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js';
// export default class CustomAutomodPhrasesCommand extends BushCommand {
diff --git a/src/commands/config/blacklist.ts b/src/commands/config/blacklist.ts
index 80acd0b..6768a1c 100644
--- a/src/commands/config/blacklist.ts
+++ b/src/commands/config/blacklist.ts
@@ -6,8 +6,6 @@ import {
clientSendAndPermCheck,
emojis,
format,
- getGlobal,
- setGlobal,
type ArgType,
type CommandMessage,
type SlashMessage
@@ -83,10 +81,10 @@ export default class BlacklistCommand extends BushCommand {
if (!global) assert(message.inGuild());
const blacklistedUsers = global
- ? getGlobal('blacklistedUsers')
+ ? this.client.utils.getGlobal('blacklistedUsers')
: (await message.guild!.getSetting('blacklistedChannels')) ?? [];
const blacklistedChannels = global
- ? getGlobal('blacklistedChannels')
+ ? this.client.utils.getGlobal('blacklistedChannels')
: (await message.guild!.getSetting('blacklistedUsers')) ?? [];
if (action === 'toggle') {
action = blacklistedUsers.includes(targetID) || blacklistedChannels.includes(targetID) ? 'unblacklist' : 'blacklist';
@@ -100,7 +98,7 @@ export default class BlacklistCommand extends BushCommand {
const key = target instanceof User ? 'blacklistedUsers' : 'blacklistedChannels';
const success = await (global
- ? setGlobal(key, newValue)
+ ? this.client.utils.setGlobal(key, newValue)
: message.guild!.setSetting(key, newValue, message.member as GuildMember)
).catch(() => false);
diff --git a/src/commands/config/config.ts b/src/commands/config/config.ts
index f0db467..66e10b6 100644
--- a/src/commands/config/config.ts
+++ b/src/commands/config/config.ts
@@ -6,9 +6,7 @@ import {
emojis,
GuildNoArraySetting,
guildSettingsObj,
- inspectAndRedact,
oxford,
- prefix,
settingsArr,
type ArgType,
type CommandMessage,
@@ -284,7 +282,7 @@ export default class ConfigCommand extends BushCommand {
});
collector.on('collect', async (interaction: MessageComponentInteraction) => {
- if (interaction.user.id === message.author.id || client.config.owners.includes(interaction.user.id)) {
+ if (interaction.user.id === message.author.id || this.client.config.owners.includes(interaction.user.id)) {
assert(message.inGuild());
switch (interaction.customId) {
@@ -346,7 +344,7 @@ export default class ConfigCommand extends BushCommand {
const func = ((): ((v: string | any) => string) => {
switch (type.replace('-array', '') as BaseSettingTypes) {
case 'string':
- return (v) => inspectAndRedact(v);
+ return (v) => this.client.utils.inspectAndRedact(v);
case 'channel':
return (v) => `<#${v}>`;
case 'role':
@@ -354,7 +352,7 @@ export default class ConfigCommand extends BushCommand {
case 'user':
return (v) => `<@${v}>`;
case 'custom':
- return inspectAndRedact;
+ return this.client.utils.inspectAndRedact;
default:
return (v) => v;
}
@@ -377,7 +375,7 @@ export default class ConfigCommand extends BushCommand {
);
settingsEmbed.setFooter({
- text: `Run "${prefix(message)}${message.util.parsed?.alias ?? 'config'} ${
+ text: `Run "${this.client.utils.prefix(message)}${message.util.parsed?.alias ?? 'config'} ${
message.util.isSlash ? snakeCase(setting) : setting
} ${guildSettingsObj[setting].type.includes('-array') ? 'add/remove' : 'set'} <value>" to set this setting.`
});
diff --git a/src/commands/config/disable.ts b/src/commands/config/disable.ts
index 4f52b7c..e9866d5 100644
--- a/src/commands/config/disable.ts
+++ b/src/commands/config/disable.ts
@@ -5,8 +5,6 @@ import {
BushCommand,
clientSendAndPermCheck,
emojis,
- getGlobal,
- setGlobal,
type ArgType,
type CommandMessage,
type SlashMessage
@@ -81,12 +79,14 @@ export default class DisableCommand extends BushCommand {
if (DisableCommand.blacklistedCommands.includes(commandID))
return message.util.send(`${emojis.error} the ${commandID} command cannot be disabled.`);
- const disabledCommands = global ? getGlobal('disabledCommands') : await message.guild.getSetting('disabledCommands');
+ const disabledCommands = global
+ ? this.client.utils.getGlobal('disabledCommands')
+ : await message.guild.getSetting('disabledCommands');
if (action === 'toggle') action = disabledCommands.includes(commandID) ? 'disable' : 'enable';
const newValue = addOrRemoveFromArray(action === 'disable' ? 'add' : 'remove', disabledCommands, commandID);
const success = global
- ? await setGlobal('disabledCommands', newValue).catch(() => false)
+ ? await this.client.utils.setGlobal('disabledCommands', newValue).catch(() => false)
: await message.guild.setSetting('disabledCommands', newValue, message.member!).catch(() => false);
if (!success)
return await message.util.reply({
diff --git a/src/commands/config/features.ts b/src/commands/config/features.ts
index e88f4b7..affcde3 100644
--- a/src/commands/config/features.ts
+++ b/src/commands/config/features.ts
@@ -51,7 +51,7 @@ export default class FeaturesCommand extends BushCommand {
});
collector.on('collect', async (interaction: SelectMenuInteraction) => {
- if (interaction.user.id === message.author.id || client.config.owners.includes(interaction.user.id)) {
+ if (interaction.user.id === message.author.id || this.client.config.owners.includes(interaction.user.id)) {
assert(message.inGuild());
const [selected]: GuildFeatures[] = interaction.values as GuildFeatures[];
diff --git a/src/commands/dev/dm.ts b/src/commands/dev/dm.ts
index f1e2bce..c1340b1 100644
--- a/src/commands/dev/dm.ts
+++ b/src/commands/dev/dm.ts
@@ -41,7 +41,7 @@ export default class DMCommand extends BushCommand {
args: { user: ArgType<'user'>; content: ArgType<'string'> }
) {
try {
- await client.users.send(args.user.id, args.content);
+ await this.client.users.send(args.user.id, args.content);
} catch (e) {
return message.util.reply(`${emojis.error} There was an error sending ${format.input(args.user.tag)} a dm.`);
}
diff --git a/src/commands/dev/eval.ts b/src/commands/dev/eval.ts
index 239a06a..2be2963 100644
--- a/src/commands/dev/eval.ts
+++ b/src/commands/dev/eval.ts
@@ -11,7 +11,6 @@ import {
getMethods,
Global,
Guild,
- inspectCleanRedactCodeblock,
Level,
ModLog,
Shared,
@@ -243,10 +242,11 @@ export default class EvalCommand extends BushCommand {
/* eslint-disable @typescript-eslint/no-unused-vars */
const me = message.member,
member = message.member,
- bot = client,
+ bot = this.client,
+ client = this.client,
guild = message.guild,
channel = message.channel,
- config = client.config,
+ config = this.client.config,
members = message.guild?.members,
roles = message.guild?.roles;
/* eslint-enable @typescript-eslint/no-unused-vars */
@@ -315,7 +315,7 @@ export default class EvalCommand extends BushCommand {
options.depth ??= 1;
options.getters ??= true;
- return inspectCleanRedactCodeblock(obj, language, options);
+ return this.client.utils.inspectCleanRedactCodeblock(obj, language, options);
}
}
diff --git a/src/commands/dev/javascript.ts b/src/commands/dev/javascript.ts
index 7c47f2f..e472a5a 100644
--- a/src/commands/dev/javascript.ts
+++ b/src/commands/dev/javascript.ts
@@ -3,7 +3,6 @@ import {
clientSendAndPermCheck,
colors,
emojis,
- inspectCleanRedactCodeblock,
type ArgType,
type CommandMessage,
type OptArgType,
@@ -60,13 +59,13 @@ export default class JavascriptCommand extends BushCommand {
}
const code = args.code.replace(/[“”]/g, '"').replace(/```*(?:js)?/g, '');
const embed = new EmbedBuilder();
- const input = await inspectCleanRedactCodeblock(code, 'js');
+ const input = await this.client.utils.inspectCleanRedactCodeblock(code, 'js');
try {
const rawOutput = /^(9\s*?\+\s*?10)|(10\s*?\+\s*?9)$/.test(code)
? '21'
: new VM({ eval: true, wasm: true, timeout: 1_000, fixAsync: true }).run(`${code}`);
- const output = await inspectCleanRedactCodeblock(rawOutput, 'js', {
+ const output = await this.client.utils.inspectCleanRedactCodeblock(rawOutput, 'js', {
depth: args.sel_depth ?? 0,
getters: true,
inspectStrings: true,
@@ -82,7 +81,7 @@ export default class JavascriptCommand extends BushCommand {
embed.setTitle(`${emojis.errorFull} Unable to Evaluate Expression`).setColor(colors.error);
embed.addFields([
{ name: '📥 Input', value: input },
- { name: '📤 Error', value: await inspectCleanRedactCodeblock(e, 'js', { colors: false }) }
+ { name: '📤 Error', value: await this.client.utils.inspectCleanRedactCodeblock(e, 'js', { colors: false }) }
]);
}
diff --git a/src/commands/dev/reload.ts b/src/commands/dev/reload.ts
index 8c2000f..40d53eb 100644
--- a/src/commands/dev/reload.ts
+++ b/src/commands/dev/reload.ts
@@ -1,13 +1,4 @@
-import {
- BushCommand,
- clientSendAndPermCheck,
- codeblock,
- emojis,
- formatError,
- shell,
- type CommandMessage,
- type SlashMessage
-} from '#lib';
+import { BushCommand, clientSendAndPermCheck, emojis, formatError, shell, type CommandMessage, type SlashMessage } from '#lib';
export default class ReloadCommand extends BushCommand {
public constructor() {
@@ -44,17 +35,19 @@ export default class ReloadCommand extends BushCommand {
const s = new Date();
output = await shell(`yarn build:${/* args.fast ? 'esbuild' : */ 'tsc'}`);
await Promise.all([
- client.commandHandler.reloadAll(),
- client.listenerHandler.reloadAll(),
- client.inhibitorHandler.reloadAll(),
- client.contextMenuCommandHandler.reloadAll(),
- client.taskHandler.reloadAll()
+ this.client.commandHandler.reloadAll(),
+ this.client.listenerHandler.reloadAll(),
+ this.client.inhibitorHandler.reloadAll(),
+ this.client.contextMenuCommandHandler.reloadAll(),
+ this.client.taskHandler.reloadAll()
]);
return message.util.send(`🔁 Successfully reloaded! (${new Date().getTime() - s.getTime()}ms)`);
} catch (e) {
- if (output!) void client.logger.error('reloadCommand', output);
- return message.util.send(`An error occurred while reloading:\n${await codeblock(formatError(e), 2048 - 34, 'js', true)}`);
+ if (output!) void this.client.logger.error('reloadCommand', output);
+ return message.util.send(
+ `An error occurred while reloading:\n${await this.client.utils.codeblock(formatError(e), 2048 - 34, 'js', true)}`
+ );
}
}
}
diff --git a/src/commands/dev/say.ts b/src/commands/dev/say.ts
index 6ec52a1..2246588 100644
--- a/src/commands/dev/say.ts
+++ b/src/commands/dev/say.ts
@@ -43,7 +43,7 @@ export default class SayCommand extends BushCommand {
}
public override async execSlash(message: SlashMessage, args: { content: string }) {
- if (!client.config.owners.includes(message.author.id)) {
+ if (!this.client.config.owners.includes(message.author.id)) {
return await message.interaction.reply({
content: `${emojis.error} Only my developers can run this command.`,
ephemeral: true
diff --git a/src/commands/dev/servers.ts b/src/commands/dev/servers.ts
index 28a4e5d..ab66f1c 100644
--- a/src/commands/dev/servers.ts
+++ b/src/commands/dev/servers.ts
@@ -26,7 +26,7 @@ export default class ServersCommand extends BushCommand {
}
public override async exec(message: CommandMessage | SlashMessage) {
- const guilds = [...client.guilds.cache.sort((a, b) => (a.memberCount < b.memberCount ? 1 : -1)).values()];
+ const guilds = [...this.client.guilds.cache.sort((a, b) => (a.memberCount < b.memberCount ? 1 : -1)).values()];
const chunkedGuilds: Guild[][] = chunk(guilds, 10);
const embeds: APIEmbed[] = chunkedGuilds.map((chunk) => {
return {
@@ -36,7 +36,7 @@ export default class ServersCommand extends BushCommand {
name: format.input(guild.name),
value: stripIndent`
**ID:** ${guild.id}
- **Owner:** ${client.users.cache.has(guild.ownerId) ? client.users.cache.get(guild.ownerId)!.tag : guild.ownerId}
+ **Owner:** ${this.client.users.cache.has(guild.ownerId) ? this.client.users.cache.get(guild.ownerId)!.tag : guild.ownerId}
**Members:** ${guild.memberCount.toLocaleString()}`
}))
} as APIEmbed;
diff --git a/src/commands/dev/sh.ts b/src/commands/dev/sh.ts
index f7c17bd..7ffdf27 100644
--- a/src/commands/dev/sh.ts
+++ b/src/commands/dev/sh.ts
@@ -2,7 +2,6 @@ import {
ArgType,
BushCommand,
clientSendAndPermCheck,
- codeblock,
colors,
emojis,
formatError,
@@ -51,7 +50,7 @@ export default class ShCommand extends BushCommand {
}
public override async exec(message: CommandMessage | SlashMessage, args: { command: ArgType<'string'> }) {
- if (!client.config.owners.includes(message.author.id))
+ if (!this.client.config.owners.includes(message.author.id))
return await message.util.reply(`${emojis.error} Only my developers can run this command.`);
const input = clean(args.command);
@@ -61,7 +60,7 @@ export default class ShCommand extends BushCommand {
.setTimestamp()
.setTitle('Shell Command')
.addFields([
- { name: '📥 Input', value: await codeblock(input, 1024, 'sh', true) },
+ { name: '📥 Input', value: await this.client.utils.codeblock(input, 1024, 'sh', true) },
{ name: 'Running', value: emojis.loading }
]);
@@ -81,12 +80,14 @@ export default class ShCommand extends BushCommand {
embed.setTitle(`${emojis.successFull} Executed command successfully.`).setColor(colors.success).spliceFields(1, 1);
- if (stdout) embed.addFields([{ name: '📤 stdout', value: await codeblock(stdout, 1024, 'ansi', true) }]);
- if (stderr) embed.addFields([{ name: '📤 stderr', value: await codeblock(stderr, 1024, 'ansi', true) }]);
+ if (stdout) embed.addFields([{ name: '📤 stdout', value: await this.client.utils.codeblock(stdout, 1024, 'ansi', true) }]);
+ if (stderr) embed.addFields([{ name: '📤 stderr', value: await this.client.utils.codeblock(stderr, 1024, 'ansi', true) }]);
} catch (e) {
embed.setTitle(`${emojis.errorFull} An error occurred while executing.`).setColor(colors.error).spliceFields(1, 1);
- embed.addFields([{ name: '📤 Output', value: await codeblock(formatError(e, true), 1024, 'ansi', true) }]);
+ embed.addFields([
+ { name: '📤 Output', value: await this.client.utils.codeblock(formatError(e, true), 1024, 'ansi', true) }
+ ]);
}
await message.util.edit({ embeds: [embed] });
}
diff --git a/src/commands/dev/superUser.ts b/src/commands/dev/superUser.ts
index 3de04bf..24e8c9a 100644
--- a/src/commands/dev/superUser.ts
+++ b/src/commands/dev/superUser.ts
@@ -1,13 +1,4 @@
-import {
- BushCommand,
- clientSendAndPermCheck,
- emojis,
- format,
- getShared,
- insertOrRemoveFromShared,
- type ArgType,
- type CommandMessage
-} from '#lib';
+import { BushCommand, clientSendAndPermCheck, emojis, format, type ArgType, type CommandMessage } from '#lib';
import { type ArgumentGeneratorReturn, type ArgumentTypeCasterReturn } from 'discord-akairo';
export default class SuperUserCommand extends BushCommand {
@@ -65,14 +56,14 @@ export default class SuperUserCommand extends BushCommand {
public override async exec(message: CommandMessage, args: { action: 'add' | 'remove'; user: ArgType<'user'> }) {
if (!message.author.isOwner()) return await message.util.reply(`${emojis.error} Only my developers can run this command.`);
- const superUsers: string[] = getShared('superUsers');
+ const superUsers: string[] = this.client.utils.getShared('superUsers');
if (args.action === 'add' ? superUsers.includes(args.user.id) : !superUsers.includes(args.user.id))
return message.util.reply(
`${emojis.warn} ${format.input(args.user.tag)} is ${args.action === 'add' ? 'already' : 'not'} a superuser.`
);
- const success = await insertOrRemoveFromShared(args.action, 'superUsers', args.user.id).catch(() => false);
+ const success = await this.client.utils.insertOrRemoveFromShared(args.action, 'superUsers', args.user.id).catch(() => false);
if (success) {
return await message.util.reply(
diff --git a/src/commands/dev/test.ts b/src/commands/dev/test.ts
index 9491d19..600aeac 100644
--- a/src/commands/dev/test.ts
+++ b/src/commands/dev/test.ts
@@ -135,15 +135,15 @@ export default class TestCommand extends BushCommand {
return await message.util.reply({ content: 'this is content', components: ButtonRows, embeds });
} else if (['delete slash commands'].includes(args.feature?.toLowerCase())) {
if (!message.guild) return await message.util.reply(`${emojis.error} This test can only be run in a guild.`);
- await client.guilds.fetch();
+ await this.client.guilds.fetch();
const promises: Promise<Collection<string, ApplicationCommand>>[] = [];
- client.guilds.cache.each((guild) => {
+ this.client.guilds.cache.each((guild) => {
promises.push(guild.commands.set([]));
});
await Promise.all(promises);
- await client.application!.commands.fetch();
- await client.application!.commands.set([]);
+ await this.client.application!.commands.fetch();
+ await this.client.application!.commands.set([]);
return await message.util.reply(`${emojis.success} Removed guild commands and global commands.`);
} else if (['drop down', 'drop downs', 'select menu', 'select menus'].includes(args.feature?.toLowerCase())) {
@@ -166,7 +166,7 @@ export default class TestCommand extends BushCommand {
});
// eslint-disable-next-line @typescript-eslint/no-misused-promises
- client.ws.on(GatewayDispatchEvents.InteractionCreate, async (i: any) => {
+ this.client.ws.on(GatewayDispatchEvents.InteractionCreate, async (i: any) => {
if (i?.data?.custom_id !== 'test;modal' || i?.data?.component_type !== 2) return;
if (i?.message?.id !== m.id) return;
diff --git a/src/commands/info/botInfo.ts b/src/commands/info/botInfo.ts
index decbe04..25b860c 100644
--- a/src/commands/info/botInfo.ts
+++ b/src/commands/info/botInfo.ts
@@ -3,7 +3,6 @@ import {
clientSendAndPermCheck,
colors,
humanizeDuration,
- mapIDs,
shell,
type CommandMessage,
type SlashMessage
@@ -44,14 +43,14 @@ export default class BotInfoCommand extends BushCommand {
haiku = 'Haiku'
}
- const developers = (await mapIDs(client.config.owners)).map((u) => u?.tag).join('\n');
+ const developers = (await this.client.utils.mapIDs(this.client.config.owners)).map((u) => u?.tag).join('\n');
const currentCommit = (await shell('git rev-parse HEAD')).stdout.replace('\n', '');
let repoUrl = (await shell('git remote get-url origin')).stdout.replace('\n', '');
if (repoUrl.includes('.git')) repoUrl = repoUrl.substring(0, repoUrl.length - 4);
const embed = new EmbedBuilder()
.setTitle('Bot Info:')
.addFields([
- { name: '**Uptime**', value: humanizeDuration(client.uptime!, 2), inline: true },
+ { name: '**Uptime**', value: humanizeDuration(this.client.uptime!, 2), inline: true },
{
name: '**Memory Usage**',
value: `System: ${prettyBytes(os.totalmem() - os.freemem(), { binary: true })}/${prettyBytes(os.totalmem(), {
@@ -62,18 +61,18 @@ export default class BotInfoCommand extends BushCommand {
)}`,
inline: true
},
- { name: '**CPU Usage**', value: `${client.stats.cpu}%`, inline: true },
+ { name: '**CPU Usage**', value: `${this.client.stats.cpu}%`, inline: true },
{ name: '**Platform**', value: Platform[process.platform], inline: true },
- { name: '**Commands Used**', value: `${client.stats.commandsUsed.toLocaleString()}`, inline: true },
- { name: '**Slash Commands Used**', value: `${client.stats.slashCommandsUsed.toLocaleString()}`, inline: true },
- { name: '**Servers**', value: client.guilds.cache.size.toLocaleString(), inline: true },
- { name: '**Users**', value: client.users.cache.size.toLocaleString(), inline: true },
+ { name: '**Commands Used**', value: `${this.client.stats.commandsUsed.toLocaleString()}`, inline: true },
+ { name: '**Slash Commands Used**', value: `${this.client.stats.slashCommandsUsed.toLocaleString()}`, inline: true },
+ { name: '**Servers**', value: this.client.guilds.cache.size.toLocaleString(), inline: true },
+ { name: '**Users**', value: this.client.users.cache.size.toLocaleString(), inline: true },
{ name: '**Discord.js Version**', value: discordJSVersion, inline: true },
{ name: '**Node.js Version**', value: process.version.slice(1), inline: true },
- { name: '**Commands**', value: client.commandHandler.modules.size.toLocaleString(), inline: true },
- { name: '**Listeners**', value: client.listenerHandler.modules.size.toLocaleString(), inline: true },
- { name: '**Inhibitors**', value: client.inhibitorHandler.modules.size.toLocaleString(), inline: true },
- { name: '**Tasks**', value: client.taskHandler.modules.size.toLocaleString(), inline: true },
+ { name: '**Commands**', value: this.client.commandHandler.modules.size.toLocaleString(), inline: true },
+ { name: '**Listeners**', value: this.client.listenerHandler.modules.size.toLocaleString(), inline: true },
+ { name: '**Inhibitors**', value: this.client.inhibitorHandler.modules.size.toLocaleString(), inline: true },
+ { name: '**Tasks**', value: this.client.taskHandler.modules.size.toLocaleString(), inline: true },
{
name: '**Current Commit**',
value: `[${currentCommit.substring(0, 7)}](${repoUrl}/commit/${currentCommit})`,
diff --git a/src/commands/info/guildInfo.ts b/src/commands/info/guildInfo.ts
index 92999a5..060a439 100644
--- a/src/commands/info/guildInfo.ts
+++ b/src/commands/info/guildInfo.ts
@@ -66,7 +66,7 @@ export default class GuildInfoCommand extends BushCommand {
let guild: ArgType<'guild' | 'snowflake'> | GuildPreview = args.guild ?? message.guild!;
if (typeof guild === 'string') {
- const preview = await client.fetchGuildPreview(`${args.guild}` as Snowflake).catch(() => undefined);
+ const preview = await this.client.fetchGuildPreview(`${args.guild}` as Snowflake).catch(() => undefined);
if (preview) guild = preview;
else return await message.util.reply(`${emojis.error} That guild is not discoverable or does not exist.`);
}
diff --git a/src/commands/info/help.ts b/src/commands/info/help.ts
index 051fce5..1a19969 100644
--- a/src/commands/info/help.ts
+++ b/src/commands/info/help.ts
@@ -4,7 +4,6 @@ import {
colors,
format,
invite,
- prefix,
type ArgType,
type CommandMessage,
type OptArgType,
@@ -68,7 +67,7 @@ export default class HelpCommand extends BushCommand {
const row = this.addLinks(message);
const command = args.command
? typeof args.command === 'string'
- ? client.commandHandler.findCommand(args.command) ?? null
+ ? this.client.commandHandler.findCommand(args.command) ?? null
: args.command
: null;
@@ -82,7 +81,7 @@ export default class HelpCommand extends BushCommand {
}
private helpAll(message: CommandMessage | SlashMessage, args: HelpArgs, row: ActionRowBuilder<ButtonBuilder>) {
- const prefix_ = prefix(message);
+ const prefix_ = this.client.utils.prefix(message);
const embed = new EmbedBuilder()
.setColor(colors.default)
.setTimestamp()
@@ -211,7 +210,7 @@ export default class HelpCommand extends BushCommand {
if (command.restrictedGuilds?.length)
restrictions.push(
`__Restricted Servers__: ${command.restrictedGuilds
- .map((g) => format.inlineCode(client.guilds.cache.find((g1) => g1.id === g)?.name ?? 'Unknown'))
+ .map((g) => format.inlineCode(this.client.guilds.cache.find((g1) => g1.id === g)?.name ?? 'Unknown'))
.join(' ')}`
);
if (restrictions.length) embed.addFields([{ name: '» Restrictions', value: restrictions.join('\n') }]);
@@ -221,12 +220,12 @@ export default class HelpCommand extends BushCommand {
private addLinks(message: CommandMessage | SlashMessage) {
const row = new ActionRowBuilder<ButtonBuilder>();
- if (!client.config.isDevelopment && !client.guilds.cache.some((guild) => guild.ownerId === message.author.id)) {
+ if (!this.client.config.isDevelopment && !this.client.guilds.cache.some((guild) => guild.ownerId === message.author.id)) {
row.addComponents([new ButtonBuilder({ style: ButtonStyle.Link, label: 'Invite Me', url: invite(this.client) })]);
}
- if (!client.guilds.cache.get(client.config.supportGuild.id)?.members.cache.has(message.author.id)) {
+ if (!this.client.guilds.cache.get(this.client.config.supportGuild.id)?.members.cache.has(message.author.id)) {
row.addComponents([
- new ButtonBuilder({ style: ButtonStyle.Link, label: 'Support Server', url: client.config.supportGuild.invite })
+ new ButtonBuilder({ style: ButtonStyle.Link, label: 'Support Server', url: this.client.config.supportGuild.invite })
]);
}
if (packageDotJSON?.repository)
diff --git a/src/commands/info/links.ts b/src/commands/info/links.ts
index a7ff30e..41e5c4d 100644
--- a/src/commands/info/links.ts
+++ b/src/commands/info/links.ts
@@ -21,11 +21,11 @@ export default class LinksCommand extends BushCommand {
public override async exec(message: CommandMessage | SlashMessage) {
const buttonRow = new ActionRowBuilder<ButtonBuilder>();
- if (!client.config.isDevelopment || message.author.isOwner()) {
+ if (!this.client.config.isDevelopment || message.author.isOwner()) {
buttonRow.addComponents([new ButtonBuilder({ style: ButtonStyle.Link, label: 'Invite Me', url: invite(this.client) })]);
}
buttonRow.addComponents([
- new ButtonBuilder({ style: ButtonStyle.Link, label: 'Support Server', url: client.config.supportGuild.invite }),
+ new ButtonBuilder({ style: ButtonStyle.Link, label: 'Support Server', url: this.client.config.supportGuild.invite }),
new ButtonBuilder({ style: ButtonStyle.Link, label: 'GitHub', url: packageDotJSON.repository })
]);
return await message.util.reply({ content: 'Here are some useful links:', components: [buttonRow] });
diff --git a/src/commands/info/pronouns.ts b/src/commands/info/pronouns.ts
index e87ca1f..0063f4c 100644
--- a/src/commands/info/pronouns.ts
+++ b/src/commands/info/pronouns.ts
@@ -2,7 +2,6 @@ import {
AllowedMentions,
BushCommand,
clientSendAndPermCheck,
- getPronounsOf,
type CommandMessage,
type OptArgType,
type SlashMessage
@@ -40,7 +39,7 @@ export default class PronounsCommand extends BushCommand {
if (message.util.isSlashMessage(message)) await message.interaction.deferReply();
- const pronouns = await getPronounsOf(user);
+ const pronouns = await this.client.utils.getPronounsOf(user);
if (!pronouns) {
return await message.util.reply({
content: `${author ? 'You do' : `${escapeMarkdown(user.tag)} does`} not appear to have any pronouns set. Please${
diff --git a/src/commands/info/snowflake.ts b/src/commands/info/snowflake.ts
index a28f4c5..dba1378 100644
--- a/src/commands/info/snowflake.ts
+++ b/src/commands/info/snowflake.ts
@@ -16,10 +16,7 @@ import {
PermissionFlagsBits,
SnowflakeUtil,
type DeconstructedSnowflake,
- type Guild,
- type Role,
- type Snowflake,
- type User
+ type Snowflake
} from 'discord.js';
export default class SnowflakeCommand extends BushCommand {
@@ -51,8 +48,8 @@ export default class SnowflakeCommand extends BushCommand {
const snowflakeEmbed = new EmbedBuilder().setTitle('Unknown :snowflake:').setColor(colors.default);
// Channel
- if (client.channels.cache.has(snowflake)) {
- const channel = client.channels.resolve(snowflake)!;
+ if (this.client.channels.cache.has(snowflake)) {
+ const channel = this.client.channels.resolve(snowflake)!;
const channelInfo = [`**Type:** ${BushChannelType[channel.type] ?? ChannelType[channel.type]}`];
if (channel.type === ChannelType.DM) {
channelInfo.push(
@@ -77,11 +74,11 @@ export default class SnowflakeCommand extends BushCommand {
}
// Guild
- if (client.guilds.cache.has(snowflake)) {
- const guild: Guild = client.guilds.cache.get(snowflake)!;
+ if (this.client.guilds.cache.has(snowflake)) {
+ const guild = this.client.guilds.cache.get(snowflake)!;
const guildInfo = stripIndent`
**Name:** ${escapeMarkdown(guild.name)}
- **Owner:** ${escapeMarkdown(client.users.cache.get(guild.ownerId)?.tag ?? '¯\\_(ツ)_/¯')} (${guild.ownerId})
+ **Owner:** ${escapeMarkdown(this.client.users.cache.get(guild.ownerId)?.tag ?? '¯\\_(ツ)_/¯')} (${guild.ownerId})
**Members:** ${guild.memberCount?.toLocaleString()}`;
if (guild.icon) snowflakeEmbed.setThumbnail(guild.iconURL({ size: 2048 })!);
snowflakeEmbed.addFields([{ name: '» Server Info', value: guildInfo }]);
@@ -89,9 +86,9 @@ export default class SnowflakeCommand extends BushCommand {
}
// User
- const fetchedUser = await client.users.fetch(`${snowflake}`).catch(() => undefined);
- if (client.users.cache.has(snowflake) || fetchedUser) {
- const user: User = (client.users.cache.get(snowflake) ?? fetchedUser)!;
+ const fetchedUser = await this.client.users.fetch(`${snowflake}`).catch(() => undefined);
+ if (this.client.users.cache.has(snowflake) || fetchedUser) {
+ const user = (this.client.users.cache.get(snowflake) ?? fetchedUser)!;
const userInfo = stripIndent`
**Name:** <@${user.id}> (${escapeMarkdown(user.tag)})`;
if (user.avatar) snowflakeEmbed.setThumbnail(user.avatarURL({ size: 2048 })!);
@@ -100,8 +97,8 @@ export default class SnowflakeCommand extends BushCommand {
}
// Emoji
- if (client.emojis.cache.has(snowflake)) {
- const emoji = client.emojis.cache.get(snowflake)!;
+ if (this.client.emojis.cache.has(snowflake)) {
+ const emoji = this.client.emojis.cache.get(snowflake)!;
const emojiInfo = stripIndent`
**Name:** ${escapeMarkdown(emoji.name ?? '¯\\_(ツ)_/¯')}
**Animated:** ${emoji.animated}`;
@@ -112,7 +109,7 @@ export default class SnowflakeCommand extends BushCommand {
// Role
if (message.guild && message.guild.roles.cache.has(snowflake)) {
- const role: Role = message.guild.roles.cache.get(snowflake)!;
+ const role = message.guild.roles.cache.get(snowflake)!;
const roleInfo = stripIndent`
**Name:** <@&${role.id}> (${escapeMarkdown(role.name)})
**Members:** ${role.members.size}
diff --git a/src/commands/info/userInfo.ts b/src/commands/info/userInfo.ts
index a39e28a..73a0422 100644
--- a/src/commands/info/userInfo.ts
+++ b/src/commands/info/userInfo.ts
@@ -4,8 +4,6 @@ import {
clientSendAndPermCheck,
colors,
emojis,
- getPronounsOf,
- getShared,
mappings,
oxford,
sleep,
@@ -63,7 +61,7 @@ export default class UserInfoCommand extends BushCommand {
? message.author
: typeof args.user === 'object'
? args.user
- : await client.users.fetch(`${args.user}`).catch(() => undefined);
+ : await this.client.users.fetch(`${args.user}`).catch(() => undefined);
if (user === undefined) return message.util.reply(`${emojis.error} Invalid user.`);
const member = message.guild ? await message.guild.members.fetch(user.id).catch(() => undefined) : undefined;
await user.fetch(true); // gets banner info and accent color
@@ -75,7 +73,7 @@ export default class UserInfoCommand extends BushCommand {
public static async makeUserInfoEmbed(user: User, member?: GuildMember, guild?: Guild | null) {
const emojis = [];
- const superUsers = getShared('superUsers');
+ const superUsers = user.client.utils.getShared('superUsers');
const userEmbed = new EmbedBuilder()
.setTitle(escapeMarkdown(user.tag))
@@ -85,7 +83,7 @@ export default class UserInfoCommand extends BushCommand {
.setColor(member?.displayColor ?? colors.default);
// Flags
- if (client.config.owners.includes(user.id)) emojis.push(mappings.otherEmojis.Developer);
+ if (user.client.config.owners.includes(user.id)) emojis.push(mappings.otherEmojis.Developer);
if (superUsers.includes(user.id)) emojis.push(mappings.otherEmojis.Superuser);
const flags = user.flags?.toArray();
if (flags) {
@@ -143,7 +141,7 @@ export default class UserInfoCommand extends BushCommand {
if (user.accentColor !== null) generalInfo.push(`**Accent Color:** ${user.hexAccentColor}`);
if (user.banner) generalInfo.push(`**Banner:** [link](${user.bannerURL({ extension: 'png', size: 4096 })})`);
- const pronouns = await Promise.race([getPronounsOf(user), sleep(2 * Time.Second)]); // cut off request after 2 seconds
+ const pronouns = await Promise.race([user.client.utils.getPronounsOf(user), sleep(2 * Time.Second)]); // cut off request after 2 seconds
if (pronouns && typeof pronouns === 'string' && pronouns !== 'Unspecified') generalInfo.push(`**Pronouns:** ${pronouns}`);
@@ -211,7 +209,7 @@ export default class UserInfoCommand extends BushCommand {
}
embed.setFooter({
text: member.user.tag,
- iconURL: client.emojis.cache.get(statusEmojis[member?.presence.status])?.url ?? undefined
+ iconURL: member.client.emojis.cache.get(statusEmojis[member?.presence.status])?.url ?? undefined
});
}
@@ -258,7 +256,9 @@ export default class UserInfoCommand extends BushCommand {
public static async generateBotField(embed: EmbedBuilder, user: User, title = '» Bot Information') {
if (!user.bot) return;
- const applicationInfo = (await client.rest.get(`/applications/${user.id}/rpc`).catch(() => null)) as APIApplication | null;
+ const applicationInfo = (await user.client.rest
+ .get(`/applications/${user.id}/rpc`)
+ .catch(() => null)) as APIApplication | null;
if (!applicationInfo) return;
const flags = new ApplicationFlagsBitField(applicationInfo.flags);
diff --git a/src/commands/leveling/leaderboard.ts b/src/commands/leveling/leaderboard.ts
index d81d88b..7eef990 100644
--- a/src/commands/leveling/leaderboard.ts
+++ b/src/commands/leveling/leaderboard.ts
@@ -5,7 +5,6 @@ import {
clientSendAndPermCheck,
emojis,
Level,
- prefix,
type CommandMessage,
type OptArgType,
type SlashMessage
@@ -46,7 +45,7 @@ export default class LeaderboardCommand extends BushCommand {
return await message.util.reply(
`${emojis.error} This command can only be run in servers with the leveling feature enabled.${
message.member?.permissions.has(PermissionFlagsBits.ManageGuild)
- ? ` You can toggle features using the \`${prefix(message)}features\` command.`
+ ? ` You can toggle features using the \`${this.client.utils.prefix(message)}features\` command.`
: ''
}`
);
diff --git a/src/commands/leveling/level.ts b/src/commands/leveling/level.ts
index df3e5b2..7888695 100644
--- a/src/commands/leveling/level.ts
+++ b/src/commands/leveling/level.ts
@@ -5,7 +5,6 @@ import {
clientSendAndPermCheck,
emojis,
Level,
- prefix,
type CommandMessage,
type OptArgType,
type SlashMessage
@@ -54,7 +53,7 @@ export default class LevelCommand extends BushCommand {
return await message.util.reply(
`${emojis.error} This command can only be run in servers with the leveling feature enabled.${
message.member?.permissions.has(PermissionFlagsBits.ManageGuild)
- ? ` You can toggle features using the \`${prefix(message)}features\` command.`
+ ? ` You can toggle features using the \`${this.client.utils.prefix(message)}features\` command.`
: ''
}`
);
diff --git a/src/commands/moderation/_activePunishments.ts b/src/commands/moderation/_activePunishments.ts
index 80cecf2..06e33f2 100644
--- a/src/commands/moderation/_activePunishments.ts
+++ b/src/commands/moderation/_activePunishments.ts
@@ -1,4 +1,14 @@
-// import { BushCommand, ModLog, ModLogModel, OptArgType, type CommandMessage, type SlashMessage } from '#lib';
+// import {
+// BushCommand,
+// clientSendAndPermCheck,
+// emojis,
+// ModLog,
+// ModLogModel,
+// OptArgType,
+// userGuildPermCheck,
+// type CommandMessage,
+// type SlashMessage
+// } from '#lib';
// import { ApplicationCommandOptionType, PermissionFlagsBits } from 'discord.js';
// import { FindOptions, Op } from 'sequelize';
diff --git a/src/commands/moderation/ban.ts b/src/commands/moderation/ban.ts
index e301fb2..598fcaa 100644
--- a/src/commands/moderation/ban.ts
+++ b/src/commands/moderation/ban.ts
@@ -7,7 +7,6 @@ import {
emojis,
format,
Moderation,
- resolveNonCachedUser,
type ArgType,
type CommandMessage,
type OptArgType,
@@ -91,7 +90,8 @@ export default class BanCommand extends BushCommand {
args.days ??= message.util.parsed?.alias === 'dban' ? 1 : 0;
const member = message.guild.members.cache.get(typeof args.user === 'string' ? args.user : args.user.id);
- const user = member?.user ?? (await resolveNonCachedUser(typeof args.user === 'string' ? args.user : args.user.id));
+ const user =
+ member?.user ?? (await this.client.utils.resolveNonCachedUser(typeof args.user === 'string' ? args.user : args.user.id));
if (!user) return message.util.reply(`${emojis.error} Invalid user.`);
const useForce = args.force && message.author.isOwner();
diff --git a/src/commands/moderation/evidence.ts b/src/commands/moderation/evidence.ts
index 3c9e726..f480844 100644
--- a/src/commands/moderation/evidence.ts
+++ b/src/commands/moderation/evidence.ts
@@ -122,7 +122,7 @@ export default class EvidenceCommand extends BushCommand {
entry.evidence = _evidence.trim();
await entry.save();
- client.emit('bushUpdateModlog', message.member!, entry.id, 'evidence', oldEntry, entry.evidence);
+ this.client.emit('bushUpdateModlog', message.member!, entry.id, 'evidence', oldEntry, entry.evidence);
return message.util.reply(`${emojis.success} Successfully updated the evidence for case ${format.input(entry.id)}.`);
}
diff --git a/src/commands/moderation/hideCase.ts b/src/commands/moderation/hideCase.ts
index 0cc3de4..6724d3c 100644
--- a/src/commands/moderation/hideCase.ts
+++ b/src/commands/moderation/hideCase.ts
@@ -47,7 +47,7 @@ export default class HideCaseCommand extends BushCommand {
entry.hidden = !entry.hidden;
await entry.save();
- client.emit('bushUpdateModlog', message.member!, entry.id, 'hidden', oldEntry, entry.hidden);
+ this.client.emit('bushUpdateModlog', message.member!, entry.id, 'hidden', oldEntry, entry.hidden);
return await message.util.reply(`${emojis.success} CaseID ${format.input(caseID)} is ${action}.`);
}
diff --git a/src/commands/moderation/massBan.ts b/src/commands/moderation/massBan.ts
index ab9fbc8..0db5263 100644
--- a/src/commands/moderation/massBan.ts
+++ b/src/commands/moderation/massBan.ts
@@ -96,7 +96,7 @@ export default class MassBanCommand extends BushCommand {
const res = await Promise.all(promises);
const map = new Collection(res.map((r, i) => [ids[i], r]));
- client.emit('massBan', message.member!, message.guild!, args.reason ? args.reason.trim() : 'No reason provided.', map);
+ this.client.emit('massBan', message.member!, message.guild!, args.reason ? args.reason.trim() : 'No reason provided.', map);
const success = (res: BanResponse): boolean => [banResponse.SUCCESS, banResponse.DM_ERROR].includes(res as any);
diff --git a/src/commands/moderation/massEvidence.ts b/src/commands/moderation/massEvidence.ts
index ffe85d2..6547203 100644
--- a/src/commands/moderation/massEvidence.ts
+++ b/src/commands/moderation/massEvidence.ts
@@ -93,7 +93,7 @@ export default class MassEvidenceCommand extends BushCommand {
return `${emojis.success} ${id} - ${case_.id}`;
});
- client.emit('massEvidence', message.member!, message.guild, evidence, lines);
+ this.client.emit('massEvidence', message.member!, message.guild, evidence, lines);
const embeds = overflowEmbed(
{
diff --git a/src/commands/moderation/modlog.ts b/src/commands/moderation/modlog.ts
index 2c0e33a..2bcc54d 100644
--- a/src/commands/moderation/modlog.ts
+++ b/src/commands/moderation/modlog.ts
@@ -8,7 +8,6 @@ import {
emojis,
humanizeDuration,
ModLog,
- resolveUserAsync,
timestamp,
userGuildPermCheck,
type ArgType,
@@ -61,7 +60,7 @@ export default class ModlogCommand extends BushCommand {
) {
assert(message.inGuild());
- const foundUser = search instanceof User ? search : await resolveUserAsync(search);
+ const foundUser = search instanceof User ? search : await this.client.utils.resolveUserAsync(search);
if (foundUser) {
const logs = await ModLog.findAll({
where: {
diff --git a/src/commands/moderation/mute.ts b/src/commands/moderation/mute.ts
index 7ad023a..12b94d6 100644
--- a/src/commands/moderation/mute.ts
+++ b/src/commands/moderation/mute.ts
@@ -7,7 +7,6 @@ import {
format,
Moderation,
muteResponse,
- prefix,
userGuildPermCheck,
type ArgType,
type CommandMessage,
@@ -93,7 +92,7 @@ export default class MuteCommand extends BushCommand {
});
const responseMessage = (): string => {
- const prefix_ = prefix(message);
+ const prefix_ = this.client.utils.prefix(message);
const victim = format.input(member.user.tag);
switch (responseCode) {
case muteResponse.MISSING_PERMISSIONS:
diff --git a/src/commands/moderation/purge.ts b/src/commands/moderation/purge.ts
index acf3897..ed5d49d 100644
--- a/src/commands/moderation/purge.ts
+++ b/src/commands/moderation/purge.ts
@@ -83,7 +83,7 @@ export default class PurgeCommand extends BushCommand {
const purged = await message.channel!.bulkDelete(messages, true).catch(() => null);
if (!purged) return message.util.reply(`${emojis.error} Failed to purge messages.`).catch(() => null);
else {
- client.emit('bushPurge', message.author, message.guild, message.channel!, messages);
+ this.client.emit('bushPurge', message.author, message.guild, message.channel!, messages);
await message.util.send(`${emojis.success} Successfully purged **${purged.size}** messages.`);
/* .then(async (purgeMessage) => {
if (!message.util.isSlashMessage(message)) {
diff --git a/src/commands/moderation/unmute.ts b/src/commands/moderation/unmute.ts
index 9ac13ce..08497c7 100644
--- a/src/commands/moderation/unmute.ts
+++ b/src/commands/moderation/unmute.ts
@@ -5,7 +5,6 @@ import {
emojis,
format,
Moderation,
- prefix,
unmuteResponse,
userGuildPermCheck,
type ArgType,
@@ -84,7 +83,7 @@ export default class UnmuteCommand extends BushCommand {
});
const responseMessage = (): string => {
- const prefix_ = prefix(message);
+ const prefix_ = this.client.utils.prefix(message);
const victim = format.input(member.user.tag);
switch (responseCode) {
case unmuteResponse.MISSING_PERMISSIONS:
diff --git a/src/commands/moulberry-bush/giveawayPing.ts b/src/commands/moulberry-bush/giveawayPing.ts
index 0cadd6a..d93e0c9 100644
--- a/src/commands/moulberry-bush/giveawayPing.ts
+++ b/src/commands/moulberry-bush/giveawayPing.ts
@@ -1,4 +1,5 @@
import { AllowedMentions, BushCommand, clientSendAndPermCheck, emojis, type CommandMessage } from '#lib';
+import assert from 'assert';
import { PermissionFlagsBits } from 'discord.js';
export default class GiveawayPingCommand extends BushCommand {
@@ -29,6 +30,8 @@ export default class GiveawayPingCommand extends BushCommand {
}
public override async exec(message: CommandMessage) {
+ assert(message.inGuild());
+
if (!message.member!.permissions.has(PermissionFlagsBits.ManageGuild) && !message.member!.user.isOwner())
await message.util.reply(`${emojis.error} You are missing the **ManageGuild** permission.`);
@@ -41,21 +44,21 @@ export default class GiveawayPingCommand extends BushCommand {
});
//! Broken
- /* const webhooks = await (message.channel as TextChannel | NewsChannel).fetchWebhooks();
- let webhookClient: WebhookClient;
- if (webhooks.size < 1) {
- const webhook = await (message.channel as TextChannel | NewsChannel).createWebhook('Giveaway ping webhook');
- webhookClient = new WebhookClient(webhook.id, webhook.token);
- } else {
- const webhook = webhooks.first();
- webhookClient = new WebhookClient(webhook.id, webhook.token);
- }
- return await webhookClient.send({
- content:
- '🎉 <@&767782793261875210> Giveaway.\n\n<:mad:783046135392239626> Spamming, line breaking, gibberish etc. disqualifies you from winning. We can and will ban you from giveaways. Winners will all be checked and rerolled if needed.',
- username: `${message.member.nickname || message.author.username}`,
- avatarURL: message.author.avatarURL(),
- allowedMentions: AllowedMentions.roles()
- }); */
+ // const webhooks = await message.channel.fetchWebhooks();
+ // let webhookClient: WebhookClient;
+ // if (webhooks.size < 1) {
+ // const webhook = await message.channel.createWebhook('Giveaway ping webhook');
+ // webhookClient = new WebhookClient(webhook.id, webhook.token);
+ // } else {
+ // const webhook = webhooks.first();
+ // webhookClient = new WebhookClient(webhook.id, webhook.token);
+ // }
+ // return await webhookClient.send({
+ // content:
+ // '🎉 <@&767782793261875210> Giveaway.\n\n<:mad:783046135392239626> Spamming, line breaking, gibberish etc. disqualifies you from winning. We can and will ban you from giveaways. Winners will all be checked and rerolled if needed.',
+ // username: `${message.member?.nickname ?? message.author.username}`,
+ // avatarURL: message.author.avatarURL(),
+ // allowedMentions: AllowedMentions.roles()
+ // });
}
}
diff --git a/src/commands/moulberry-bush/report.ts b/src/commands/moulberry-bush/report.ts
index 06c1ad2..47e45f9 100644
--- a/src/commands/moulberry-bush/report.ts
+++ b/src/commands/moulberry-bush/report.ts
@@ -112,7 +112,7 @@ export default class ReportCommand extends BushCommand {
await ReportMessage.react(emojis.check);
await ReportMessage.react(emojis.cross);
} catch {
- void client.console.warn('ReportCommand', 'Could not react to report message.');
+ void this.client.console.warn('ReportCommand', 'Could not react to report message.');
}
});
return await message.util.reply('Successfully made a report.');
diff --git a/src/commands/utilities/_poll.ts b/src/commands/utilities/_poll.ts
index fdf6381..1ceb13a 100644
--- a/src/commands/utilities/_poll.ts
+++ b/src/commands/utilities/_poll.ts
@@ -1,4 +1,4 @@
-// import { BushCommand, type ArgType, type CommandMessage, type SlashMessage } from '#lib';
+// import { BushCommand, clientSendAndPermCheck, emojis, type ArgType, type CommandMessage, type SlashMessage } from '#lib';
// import { ApplicationCommandOptionType, ComponentType } from 'discord.js';
// export default class PollCommand extends BushCommand {
diff --git a/src/commands/utilities/activity.ts b/src/commands/utilities/activity.ts
index dfbccfb..e5c2cdd 100644
--- a/src/commands/utilities/activity.ts
+++ b/src/commands/utilities/activity.ts
@@ -171,7 +171,7 @@ export default class ActivityCommand extends BushCommand {
: activityTypeCaster(message, args.activity);
let response: string;
- const invite: any = await client.rest
+ const invite: any = await this.client.rest
.post(`/channels/${channel.id}/invites`, {
body: {
validate: null,
diff --git a/src/commands/utilities/calculator.ts b/src/commands/utilities/calculator.ts
index 75d63a1..2204fe6 100644
--- a/src/commands/utilities/calculator.ts
+++ b/src/commands/utilities/calculator.ts
@@ -4,7 +4,6 @@ import {
clientSendAndPermCheck,
colors,
emojis,
- inspectCleanRedactCodeblock,
type CommandMessage,
type SlashMessage
} from '#lib';
@@ -43,7 +42,7 @@ export default class CalculatorCommand extends BushCommand {
const decodedEmbed = new EmbedBuilder().addFields([
{
name: '📥 Input',
- value: await inspectCleanRedactCodeblock(args.expression, 'mma')
+ value: await this.client.utils.inspectCleanRedactCodeblock(args.expression, 'mma')
}
]);
try {
@@ -51,12 +50,19 @@ export default class CalculatorCommand extends BushCommand {
decodedEmbed
.setTitle(`${emojis.successFull} Successfully Calculated Expression`)
.setColor(colors.success)
- .addFields([{ name: '📤 Output', value: await inspectCleanRedactCodeblock(calculated.toString(), 'mma') }]);
+ .addFields([
+ { name: '📤 Output', value: await this.client.utils.inspectCleanRedactCodeblock(calculated.toString(), 'mma') }
+ ]);
} catch (error) {
decodedEmbed
.setTitle(`${emojis.errorFull} Unable to Calculate Expression`)
.setColor(colors.error)
- .addFields([{ name: `📤 Error`, value: await inspectCleanRedactCodeblock(`${error.name}: ${error.message}`, 'js') }]);
+ .addFields([
+ {
+ name: `📤 Error`,
+ value: await this.client.utils.inspectCleanRedactCodeblock(`${error.name}: ${error.message}`, 'js')
+ }
+ ]);
}
return await message.util.reply({ embeds: [decodedEmbed], allowedMentions: AllowedMentions.none() });
}
diff --git a/src/commands/utilities/decode.ts b/src/commands/utilities/decode.ts
index cc742c8..6aabeac 100644
--- a/src/commands/utilities/decode.ts
+++ b/src/commands/utilities/decode.ts
@@ -5,7 +5,6 @@ import {
clientSendAndPermCheck,
colors,
formatError,
- inspectCleanRedactCodeblock,
type CommandMessage,
type SlashMessage
} from '#lib';
@@ -64,15 +63,17 @@ export default class DecodeCommand extends BushCommand {
const encodeOrDecode = capitalize(message?.util?.parsed?.alias ?? 'decoded');
const decodedEmbed = new EmbedBuilder()
.setTitle(`${encodeOrDecode} Information`)
- .addFields([{ name: '📥 Input', value: await inspectCleanRedactCodeblock(data) }]);
+ .addFields([{ name: '📥 Input', value: await this.client.utils.inspectCleanRedactCodeblock(data) }]);
try {
const decoded = Buffer.from(data, from).toString(to);
- decodedEmbed.setColor(colors.success).addFields([{ name: '📤 Output', value: await inspectCleanRedactCodeblock(decoded) }]);
+ decodedEmbed
+ .setColor(colors.success)
+ .addFields([{ name: '📤 Output', value: await this.client.utils.inspectCleanRedactCodeblock(decoded) }]);
} catch (error) {
decodedEmbed.setColor(colors.error).addFields([
{
name: `📤 Error ${encodeOrDecode.slice(1)}ing`,
- value: await inspectCleanRedactCodeblock(formatError(error))
+ value: await this.client.utils.inspectCleanRedactCodeblock(formatError(error))
}
]);
}
diff --git a/src/commands/utilities/highlight-add.ts b/src/commands/utilities/highlight-add.ts
index 9624a7e..3547c90 100644
--- a/src/commands/utilities/highlight-add.ts
+++ b/src/commands/utilities/highlight-add.ts
@@ -59,7 +59,7 @@ export default class HighlightAddCommand extends BushCommand {
}
}
- const res = await client.highlightManager.addHighlight(message.guild.id, message.author.id, {
+ const res = await this.client.highlightManager.addHighlight(message.guild.id, message.author.id, {
word: args.word,
regex: args.regex
});
diff --git a/src/commands/utilities/highlight-clear.ts b/src/commands/utilities/highlight-clear.ts
index df9f387..9e1ed62 100644
--- a/src/commands/utilities/highlight-clear.ts
+++ b/src/commands/utilities/highlight-clear.ts
@@ -23,7 +23,7 @@ export default class HighlightClearCommand extends BushCommand {
const confirm = await ConfirmationPrompt.send(message, { content: `Are you sure you want to clear your highlight list?` });
if (!confirm) return await message.util.reply(`${emojis.warn} You decided not to clear your highlight list.`);
- const success = await client.highlightManager.removeAllHighlights(message.guild.id, message.author.id);
+ const success = await this.client.highlightManager.removeAllHighlights(message.guild.id, message.author.id);
if (!success) return await message.util.reply(`${emojis.error} There was an error clearing your highlight list.`);
return await message.util.reply(`${emojis.success} Successfully cleared your highlight list.`);
diff --git a/src/commands/utilities/highlight-matches.ts b/src/commands/utilities/highlight-matches.ts
index b458550..7bf94fd 100644
--- a/src/commands/utilities/highlight-matches.ts
+++ b/src/commands/utilities/highlight-matches.ts
@@ -34,7 +34,7 @@ export default class HighlightMatchesCommand extends BushCommand {
public override async exec(message: CommandMessage | SlashMessage, args: { phrase: ArgType<'string'> }) {
assert(message.inGuild());
- const res = await client.highlightManager.checkPhrase(message.guild.id, message.author.id, args.phrase);
+ const res = await this.client.highlightManager.checkPhrase(message.guild.id, message.author.id, args.phrase);
if (!res.size) return await message.util.reply(`${emojis.error} You are not highlighting any words`);
diff --git a/src/commands/utilities/highlight-remove.ts b/src/commands/utilities/highlight-remove.ts
index bb1300a..4dddff6 100644
--- a/src/commands/utilities/highlight-remove.ts
+++ b/src/commands/utilities/highlight-remove.ts
@@ -31,7 +31,7 @@ export default class HighlightRemoveCommand extends BushCommand {
public override async exec(message: CommandMessage | SlashMessage, args: { word: ArgType<'string'> }) {
assert(message.inGuild());
- const res = await client.highlightManager.removeHighlight(message.guild.id, message.author.id, args.word);
+ const res = await this.client.highlightManager.removeHighlight(message.guild.id, message.author.id, args.word);
if (typeof res === 'string')
return await message.util.reply({ content: `${emojis.error} ${res}`, allowedMentions: AllowedMentions.none() });
diff --git a/src/commands/utilities/highlight-show.ts b/src/commands/utilities/highlight-show.ts
index d966f3a..0558005 100644
--- a/src/commands/utilities/highlight-show.ts
+++ b/src/commands/utilities/highlight-show.ts
@@ -23,7 +23,7 @@ export default class HighlightShowCommand extends BushCommand {
where: { guild: message.guild.id, user: message.author.id }
});
- void client.highlightManager.syncCache();
+ void this.client.highlightManager.syncCache();
if (!highlight.words.length) return message.util.reply(`${emojis.error} You are not highlighting any words.`);
diff --git a/src/commands/utilities/viewRaw.ts b/src/commands/utilities/viewRaw.ts
index 8114cef..057d86d 100644
--- a/src/commands/utilities/viewRaw.ts
+++ b/src/commands/utilities/viewRaw.ts
@@ -2,7 +2,6 @@ import {
Arg,
BushCommand,
clientSendAndPermCheck,
- codeblock,
colors,
emojis,
inspect,
@@ -114,6 +113,6 @@ export default class ViewRawCommand extends BushCommand {
.setTimestamp(message.createdTimestamp)
.setColor(message.member?.roles?.color?.color ?? colors.default)
.setTitle('Raw Message Information')
- .setDescription(await codeblock(content, 2048, lang));
+ .setDescription(await message.client.utils.codeblock(content, 2048, lang));
}
}
diff --git a/src/commands/utilities/wolframAlpha.ts b/src/commands/utilities/wolframAlpha.ts
index b682c85..baf764f 100644
--- a/src/commands/utilities/wolframAlpha.ts
+++ b/src/commands/utilities/wolframAlpha.ts
@@ -4,8 +4,6 @@ import {
clientSendAndPermCheck,
colors,
emojis,
- inspectCleanRedactCodeblock,
- uploadImageToImgur,
type ArgType,
type CommandMessage,
type SlashMessage
@@ -57,12 +55,12 @@ export default class WolframAlphaCommand extends BushCommand {
if (message.util.isSlashMessage(message)) await message.interaction.deferReply();
args.image && void message.util.reply({ content: `${emojis.loading} Loading...`, embeds: [] });
- const waApi = WolframAlphaAPI(client.config.credentials.wolframAlphaAppId);
+ const waApi = WolframAlphaAPI(this.client.config.credentials.wolframAlphaAppId);
const decodedEmbed = new EmbedBuilder().addFields([
{
name: '📥 Input',
- value: await inspectCleanRedactCodeblock(args.expression)
+ value: await this.client.utils.inspectCleanRedactCodeblock(args.expression)
}
]);
const sendOptions: MessageOptions = { content: null, allowedMentions: AllowedMentions.none() };
@@ -73,16 +71,23 @@ export default class WolframAlphaCommand extends BushCommand {
decodedEmbed.setTitle(`${emojis.successFull} Successfully Queried Expression`).setColor(colors.success);
if (args.image) {
- decodedEmbed.setImage(await uploadImageToImgur(calculated.split(',')[1]));
+ decodedEmbed.setImage(await this.client.utils.uploadImageToImgur(calculated.split(',')[1]));
decodedEmbed.addFields([{ name: '📤 Output', value: '​' }]);
} else {
- decodedEmbed.addFields([{ name: '📤 Output', value: await inspectCleanRedactCodeblock(calculated.toString()) }]);
+ decodedEmbed.addFields([
+ { name: '📤 Output', value: await this.client.utils.inspectCleanRedactCodeblock(calculated.toString()) }
+ ]);
}
} catch (error) {
decodedEmbed
.setTitle(`${emojis.errorFull} Unable to Query Expression`)
.setColor(colors.error)
- .addFields([{ name: `📤 Error`, value: await inspectCleanRedactCodeblock(`${error.name}: ${error.message}`, 'js') }]);
+ .addFields([
+ {
+ name: `📤 Error`,
+ value: await this.client.utils.inspectCleanRedactCodeblock(`${error.name}: ${error.message}`, 'js')
+ }
+ ]);
}
sendOptions.embeds = [decodedEmbed];
diff --git a/src/context-menu-commands/user/modlog.ts b/src/context-menu-commands/user/modlog.ts
index 7f3103d..c78396e 100644
--- a/src/context-menu-commands/user/modlog.ts
+++ b/src/context-menu-commands/user/modlog.ts
@@ -25,8 +25,8 @@ export default class ModlogContextMenuCommand extends ContextMenuCommand {
});
await interaction.deferReply({ ephemeral: true });
- const pseudoMessage = new SlashMessage(client, interaction as any);
- pseudoMessage.util = new CommandUtil(client.commandHandler, pseudoMessage);
+ const pseudoMessage = new SlashMessage(this.client, interaction as any);
+ pseudoMessage.util = new CommandUtil(this.client.commandHandler, pseudoMessage);
void new ModlogCommand().exec(pseudoMessage, { search: interaction.targetId, hidden: false });
}
diff --git a/src/context-menu-commands/user/userInfo.ts b/src/context-menu-commands/user/userInfo.ts
index 075b681..6d7f3b6 100644
--- a/src/context-menu-commands/user/userInfo.ts
+++ b/src/context-menu-commands/user/userInfo.ts
@@ -15,7 +15,7 @@ export default class UserInfoContextMenuCommand extends ContextMenuCommand {
public override async exec(interaction: ContextMenuCommandInteraction) {
await interaction.deferReply({ ephemeral: true });
- const user = await client.users.fetch(interaction.targetId).catch(() => null);
+ const user = await this.client.users.fetch(interaction.targetId).catch(() => null);
if (!user) return interaction.reply(`⁉ I couldn't find that user`);
const guild = interaction.guild as Guild;
diff --git a/src/inhibitors/blacklist/channelGlobalBlacklist.ts b/src/inhibitors/blacklist/channelGlobalBlacklist.ts
index 86ab21f..7f23604 100644
--- a/src/inhibitors/blacklist/channelGlobalBlacklist.ts
+++ b/src/inhibitors/blacklist/channelGlobalBlacklist.ts
@@ -13,9 +13,9 @@ export default class UserGlobalBlacklistInhibitor extends BushInhibitor {
public exec(message: CommandMessage | SlashMessage, command: BushCommand): boolean {
if (!message.author || !message.inGuild()) return false;
// do not change to message.author.isOwner()
- if (client.isOwner(message.author) || client.user!.id === message.author.id) return false;
- if (client.cache.global.blacklistedChannels.includes(message.channel!.id) && !command.bypassChannelBlacklist) {
- void client.console.verbose(
+ if (this.client.isOwner(message.author) || this.client.user!.id === message.author.id) return false;
+ if (this.client.cache.global.blacklistedChannels.includes(message.channel!.id) && !command.bypassChannelBlacklist) {
+ void this.client.console.verbose(
'channelGlobalBlacklist',
`Blocked message with id <<${message.id}>> from <<${message.author.tag}>> in <<${message.guild.name}>>.`
);
diff --git a/src/inhibitors/blacklist/channelGuildBlacklist.ts b/src/inhibitors/blacklist/channelGuildBlacklist.ts
index 8cf35ec..ae087bd 100644
--- a/src/inhibitors/blacklist/channelGuildBlacklist.ts
+++ b/src/inhibitors/blacklist/channelGuildBlacklist.ts
@@ -13,7 +13,7 @@ export default class ChannelGuildBlacklistInhibitor extends BushInhibitor {
public async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> {
if (!message.author || !message.inGuild()) return false;
// do not change to message.author.isOwner()
- if (client.isOwner(message.author) || client.user!.id === message.author.id) return false;
+ if (this.client.isOwner(message.author) || this.client.user!.id === message.author.id) return false;
if (
(await message.guild.getSetting('bypassChannelBlacklist'))?.includes(message.author.id) &&
!command.bypassChannelBlacklist
@@ -24,7 +24,7 @@ export default class ChannelGuildBlacklistInhibitor extends BushInhibitor {
(await message.guild.getSetting('blacklistedChannels'))?.includes(message.channel!.id) &&
!command.bypassChannelBlacklist
) {
- void client.console.verbose(
+ void this.client.console.verbose(
'channelGuildBlacklist',
`Blocked message with id <<${message.id}>> from <<${message.author.tag}>> in <<${message.guild.name}>>.`
);
diff --git a/src/inhibitors/blacklist/guildBlacklist.ts b/src/inhibitors/blacklist/guildBlacklist.ts
index 60c5755..b7df41a 100644
--- a/src/inhibitors/blacklist/guildBlacklist.ts
+++ b/src/inhibitors/blacklist/guildBlacklist.ts
@@ -13,10 +13,14 @@ export default class GuildBlacklistInhibitor extends BushInhibitor {
public exec(message: CommandMessage | SlashMessage): boolean {
if (!message.author || !message.inGuild()) return false;
// do not change to message.author.isOwner()
- if (client.isOwner(message.author) || client.isSuperUser(message.author) || client.user!.id === message.author.id)
+ if (
+ this.client.isOwner(message.author) ||
+ this.client.isSuperUser(message.author) ||
+ this.client.user!.id === message.author.id
+ )
return false;
- if (client.cache.global.blacklistedGuilds.includes(message.guild.id)) {
- void client.console.verbose(
+ if (this.client.cache.global.blacklistedGuilds.includes(message.guild.id)) {
+ void this.client.console.verbose(
'guildBlacklist',
`Blocked message with id <<${message.id}>> from <<${message.author.tag}>> in <<${message.guild.name}>>.`
);
diff --git a/src/inhibitors/blacklist/userGlobalBlacklist.ts b/src/inhibitors/blacklist/userGlobalBlacklist.ts
index bf0d4bd..e8a1306 100644
--- a/src/inhibitors/blacklist/userGlobalBlacklist.ts
+++ b/src/inhibitors/blacklist/userGlobalBlacklist.ts
@@ -13,9 +13,9 @@ export default class UserGlobalBlacklistInhibitor extends BushInhibitor {
public exec(message: CommandMessage | SlashMessage): boolean {
if (!message.author) return false;
// do not change to message.author.isOwner()
- if (client.isOwner(message.author) || client.user!.id === message.author.id) return false;
- if (client.cache.global.blacklistedUsers.includes(message.author.id)) {
- void client.console.verbose(
+ if (this.client.isOwner(message.author) || this.client.user!.id === message.author.id) return false;
+ if (this.client.cache.global.blacklistedUsers.includes(message.author.id)) {
+ void this.client.console.verbose(
'userGlobalBlacklist',
`Blocked message with id <<${message.id}>> from <<${message.author.tag}>> in <<${
message.inGuild() ? message.guild?.name : message.author.tag
diff --git a/src/inhibitors/blacklist/userGuildBlacklist.ts b/src/inhibitors/blacklist/userGuildBlacklist.ts
index a2ac1aa..a661606 100644
--- a/src/inhibitors/blacklist/userGuildBlacklist.ts
+++ b/src/inhibitors/blacklist/userGuildBlacklist.ts
@@ -13,10 +13,14 @@ export default class UserGuildBlacklistInhibitor extends BushInhibitor {
public async exec(message: CommandMessage | SlashMessage): Promise<boolean> {
if (!message.author || !message.inGuild()) return false;
// do not change to message.author.isOwner()
- if (client.isOwner(message.author) || client.isSuperUser(message.author) || client.user!.id === message.author.id)
+ if (
+ this.client.isOwner(message.author) ||
+ this.client.isSuperUser(message.author) ||
+ this.client.user!.id === message.author.id
+ )
return false;
if ((await message.guild.getSetting('blacklistedUsers'))?.includes(message.author.id)) {
- void client.console.verbose(
+ void this.client.console.verbose(
'userGuildBlacklist',
`Blocked message with id <<${message.id}>> from <<${message.author.tag}>> in <<${message.guild.name}>>.`
);
diff --git a/src/inhibitors/checks/fatal.ts b/src/inhibitors/checks/fatal.ts
index a3601b5..9fda504 100644
--- a/src/inhibitors/checks/fatal.ts
+++ b/src/inhibitors/checks/fatal.ts
@@ -12,10 +12,11 @@ export default class FatalInhibitor extends BushInhibitor {
}
public async exec(message: Message | SlashMessage): Promise<boolean> {
- if (client.isOwner(message.author)) return false;
- for (const property in client.cache.global) {
- if (!client.cache.global[property as keyof typeof client.cache.global]) {
- void client.console.verbose(
+ if (this.client.isOwner(message.author)) return false;
+ const globalCache = this.client.cache.global;
+ for (const property in globalCache) {
+ if (!globalCache[property as keyof typeof globalCache]) {
+ void this.client.console.verbose(
'fatal',
`Blocked message with id <<${message.id}>> from <<${message.author.tag}>> in <<${message.guild?.name}>>.`
);
diff --git a/src/inhibitors/checks/guildUnavailable.ts b/src/inhibitors/checks/guildUnavailable.ts
index 6c741a1..f5b62f4 100644
--- a/src/inhibitors/checks/guildUnavailable.ts
+++ b/src/inhibitors/checks/guildUnavailable.ts
@@ -13,7 +13,7 @@ export default class GuildUnavailableInhibitor extends BushInhibitor {
public async exec(message: Message | SlashMessage): Promise<boolean> {
if (message.inGuild() && !message.guild.available) {
- void client.console.verbose(
+ void this.client.console.verbose(
'guildUnavailable',
`Blocked message with id <<${message.id}>> from <<${message.author.tag}>> in <<${message.guild.name}>>.`
);
diff --git a/src/inhibitors/command/dm.ts b/src/inhibitors/command/dm.ts
index 1fc43c6..5516c81 100644
--- a/src/inhibitors/command/dm.ts
+++ b/src/inhibitors/command/dm.ts
@@ -12,7 +12,7 @@ export default class DMInhibitor extends BushInhibitor {
public async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> {
if (command.channel === 'dm' && message.guild) {
- void client.console.verbose(
+ void this.client.console.verbose(
'dm',
`Blocked message with id <<${message.id}>> from <<${message.author.tag}>> in <<${message.guild.name}>>.`
);
diff --git a/src/inhibitors/command/globalDisabledCommand.ts b/src/inhibitors/command/globalDisabledCommand.ts
index 7e855ae..f013183 100644
--- a/src/inhibitors/command/globalDisabledCommand.ts
+++ b/src/inhibitors/command/globalDisabledCommand.ts
@@ -12,8 +12,8 @@ export default class DisabledGuildCommandInhibitor extends BushInhibitor {
public async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> {
if (message.author.isOwner()) return false;
- if (client.cache.global.disabledCommands.includes(command?.id)) {
- void client.console.verbose(
+ if (this.client.cache.global.disabledCommands.includes(command?.id)) {
+ void this.client.console.verbose(
'disabledGlobalCommand',
`Blocked message with id <<${message.id}>> from <<${message.author.tag}>> in <<${message.guild?.name}>>.`
);
diff --git a/src/inhibitors/command/guild.ts b/src/inhibitors/command/guild.ts
index 6ea4e6a..ea52d99 100644
--- a/src/inhibitors/command/guild.ts
+++ b/src/inhibitors/command/guild.ts
@@ -12,7 +12,7 @@ export default class GuildInhibitor extends BushInhibitor {
public async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> {
if (command.channel === 'guild' && !message.guild) {
- void client.console.verbose(
+ void this.client.console.verbose(
'guild',
`Blocked message with id <<${message.id}>> from <<${message.author.tag}>> in <<${message.author.tag}>>.`
);
diff --git a/src/inhibitors/command/guildDisabledCommand.ts b/src/inhibitors/command/guildDisabledCommand.ts
index 7d63093..7fef78a 100644
--- a/src/inhibitors/command/guildDisabledCommand.ts
+++ b/src/inhibitors/command/guildDisabledCommand.ts
@@ -15,7 +15,7 @@ export default class DisabledGuildCommandInhibitor extends BushInhibitor {
if (message.author.isOwner() || message.author.isSuperUser()) return false; // super users bypass guild disabled commands
if ((await message.guild.getSetting('disabledCommands'))?.includes(command?.id)) {
- void client.console.verbose(
+ void this.client.console.verbose(
'disabledGuildCommand',
`Blocked message with id <<${message.id}>> from <<${message.author.tag}>> in <<${message.guild.name}>>.`
);
diff --git a/src/inhibitors/command/nsfw.ts b/src/inhibitors/command/nsfw.ts
index f8f2180..ed55b00 100644
--- a/src/inhibitors/command/nsfw.ts
+++ b/src/inhibitors/command/nsfw.ts
@@ -13,7 +13,7 @@ export default class NsfwInhibitor extends BushInhibitor {
public async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> {
if (command.onlyNsfw && !(message.channel as TextChannel).nsfw) {
- void client.console.verbose(
+ void this.client.console.verbose(
'notNsfw',
`Blocked message with id <<${message.id}>> from <<${message.author.tag}>> in <<${message.guild?.name}>>.`
);
diff --git a/src/inhibitors/command/owner.ts b/src/inhibitors/command/owner.ts
index 3769d84..7a39063 100644
--- a/src/inhibitors/command/owner.ts
+++ b/src/inhibitors/command/owner.ts
@@ -12,8 +12,8 @@ export default class OwnerInhibitor extends BushInhibitor {
public async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> {
if (command.ownerOnly) {
- if (!client.isOwner(message.author)) {
- void client.console.verbose(
+ if (!this.client.isOwner(message.author)) {
+ void this.client.console.verbose(
'owner',
`Blocked message with id <<${message.id}>> from <<${message.author.tag}>> in <<${message.guild?.name}>>.`
);
diff --git a/src/inhibitors/command/restrictedChannel.ts b/src/inhibitors/command/restrictedChannel.ts
index 867756d..849166a 100644
--- a/src/inhibitors/command/restrictedChannel.ts
+++ b/src/inhibitors/command/restrictedChannel.ts
@@ -13,7 +13,7 @@ export default class RestrictedChannelInhibitor extends BushInhibitor {
public async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> {
if (command.restrictedChannels?.length && message.channel) {
if (!command.restrictedChannels.includes(message.channel.id)) {
- void client.console.verbose(
+ void this.client.console.verbose(
'restrictedChannel',
`Blocked message with id <<${message.id}>> from <<${message.author.tag}>> in <<${message.guild?.name}>>.`
);
diff --git a/src/inhibitors/command/restrictedGuild.ts b/src/inhibitors/command/restrictedGuild.ts
index 4d43c21..1e2d1b2 100644
--- a/src/inhibitors/command/restrictedGuild.ts
+++ b/src/inhibitors/command/restrictedGuild.ts
@@ -13,7 +13,7 @@ export default class RestrictedGuildInhibitor extends BushInhibitor {
public async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> {
if (command.restrictedChannels?.length && message.channel) {
if (!command.restrictedChannels.includes(message.channel.id)) {
- void client.console.verbose(
+ void this.client.console.verbose(
'restrictedGuild',
`Blocked message with id <<${message.id}>> from <<${message.author.tag}>> in <<${message.guild?.name}>>.`
);
diff --git a/src/inhibitors/command/superUser.ts b/src/inhibitors/command/superUser.ts
index 2e44b67..69e95a2 100644
--- a/src/inhibitors/command/superUser.ts
+++ b/src/inhibitors/command/superUser.ts
@@ -12,8 +12,8 @@ export default class SuperUserInhibitor extends BushInhibitor {
public async exec(message: CommandMessage | SlashMessage, command: BushCommand): Promise<boolean> {
if (command.superUserOnly) {
- if (!client.isSuperUser(message.author)) {
- void client.console.verbose(
+ if (!this.client.isSuperUser(message.author)) {
+ void this.client.console.verbose(
'superUser',
`Blocked message with id <<${message.id}>> from <<${message.author.tag}>> in <<${message.guild?.name}>>.`
);
diff --git a/src/lib/common/AutoMod.ts b/src/lib/common/AutoMod.ts
index 7f19e63..0910352 100644
--- a/src/lib/common/AutoMod.ts
+++ b/src/lib/common/AutoMod.ts
@@ -1,4 +1,4 @@
-import { banResponse, codeblock, colors, emojis, format, formatError, getShared, Moderation, resolveNonCachedUser } from '#lib';
+import { banResponse, colors, emojis, format, formatError, Moderation } from '#lib';
import assert from 'assert';
import chalk from 'chalk';
import {
@@ -31,7 +31,7 @@ export class AutoMod {
*/
private message: Message
) {
- if (message.author.id === client.user?.id) return;
+ if (message.author.id === message.client.user?.id) return;
void this.handle();
}
@@ -56,9 +56,9 @@ export class AutoMod {
traditional: {
if (this.isImmune) break traditional;
- const badLinksArray = getShared('badLinks');
- const badLinksSecretArray = getShared('badLinksSecret');
- const badWordsRaw = getShared('badWords');
+ const badLinksArray = this.message.client.utils.getShared('badLinks');
+ const badLinksSecretArray = this.message.client.utils.getShared('badLinksSecret');
+ const badWordsRaw = this.message.client.utils.getShared('badWords');
const customAutomodPhrases = (await this.message.guild.getSetting('autoModPhases')) ?? [];
const uniqueLinks = [...new Set([...badLinksArray, ...badLinksSecretArray])];
@@ -167,7 +167,9 @@ export class AutoMod {
.setDescription(
`**User:** ${this.message.author} (${this.message.author.tag})\n**Sent From:** <#${this.message.channel.id}> [Jump to context](${this.message.url})`
)
- .addFields([{ name: 'Message Content', value: `${await codeblock(this.message.content, 1024)}` }])
+ .addFields([
+ { name: 'Message Content', value: `${await this.message.client.utils.codeblock(this.message.content, 1024)}` }
+ ])
.setColor(color)
.setTimestamp()
],
@@ -186,12 +188,12 @@ export class AutoMod {
private async checkPerspectiveApi() {
return;
- if (!client.config.isDevelopment) return;
+ if (!this.message.client.config.isDevelopment) return;
if (!this.message.content) return;
- client.perspective.comments.analyze(
+ this.message.client.perspective.comments.analyze(
{
- key: client.config.credentials.perspectiveApiKey,
+ key: this.message.client.config.credentials.perspectiveApiKey,
resource: {
comment: {
text: this.message.content
@@ -301,7 +303,7 @@ export class AutoMod {
{
title: 'AutoMod Error',
description: `Unable to delete triggered message.`,
- fields: [{ name: 'Error', value: await codeblock(`${formatError(e)}`, 1024, 'js', true) }],
+ fields: [{ name: 'Error', value: await this.message.client.utils.codeblock(`${formatError(e)}`, 1024, 'js', true) }],
color: colors.error
}
]
@@ -316,7 +318,7 @@ export class AutoMod {
* @param offences The other offences that were also matched in the message
*/
private async log(highestOffence: BadWordDetails, color: number, offences: BadWordDetails[]) {
- void client.console.info(
+ void this.message.client.console.info(
'autoMod',
`Severity <<${highestOffence.severity}>> action performed on <<${this.message.author.tag}>> (<<${
this.message.author.id
@@ -332,7 +334,9 @@ export class AutoMod {
this.message.channel.id
}> [Jump to context](${this.message.url})\n**Blacklisted Words:** ${offences.map((o) => `\`${o.match}\``).join(', ')}`
)
- .addFields([{ name: 'Message Content', value: `${await codeblock(this.message.content, 1024)}` }])
+ .addFields([
+ { name: 'Message Content', value: `${await this.message.client.utils.codeblock(this.message.content, 1024)}` }
+ ])
.setColor(color)
.setTimestamp()
.setAuthor({ name: this.message.author.tag, url: this.message.author.displayAvatarURL() })
@@ -386,7 +390,7 @@ export class AutoMod {
evidence: (interaction.message as Message).url ?? undefined
});
- const victimUserFormatted = (await resolveNonCachedUser(userId))?.tag ?? userId;
+ const victimUserFormatted = (await interaction.client.utils.resolveNonCachedUser(userId))?.tag ?? userId;
if (result === banResponse.SUCCESS)
return interaction.reply({
content: `${emojis.success} Successfully banned **${victimUserFormatted}**.`,
diff --git a/src/lib/common/ButtonPaginator.ts b/src/lib/common/ButtonPaginator.ts
index 9560247..708b374 100644
--- a/src/lib/common/ButtonPaginator.ts
+++ b/src/lib/common/ButtonPaginator.ts
@@ -97,7 +97,7 @@ export class ButtonPaginator {
* @param interaction The interaction received
*/
protected async collect(interaction: MessageComponentInteraction) {
- if (interaction.user.id !== this.message.author.id && !client.config.owners.includes(interaction.user.id))
+ if (interaction.user.id !== this.message.author.id && !this.message.client.config.owners.includes(interaction.user.id))
return await interaction?.deferUpdate().catch(() => null);
switch (interaction.customId) {
diff --git a/src/lib/common/ConfirmationPrompt.ts b/src/lib/common/ConfirmationPrompt.ts
index 4593d24..38d078a 100644
--- a/src/lib/common/ConfirmationPrompt.ts
+++ b/src/lib/common/ConfirmationPrompt.ts
@@ -43,7 +43,7 @@ export class ConfirmationPrompt {
collector.on('collect', async (interaction: MessageComponentInteraction) => {
await interaction.deferUpdate().catch(() => undefined);
- if (interaction.user.id == this.message.author.id || client.config.owners.includes(interaction.user.id)) {
+ if (interaction.user.id == this.message.author.id || this.message.client.config.owners.includes(interaction.user.id)) {
if (interaction.customId === 'confirmationPrompt_confirm') {
responded = true;
collector.stop();
diff --git a/src/lib/common/DeleteButton.ts b/src/lib/common/DeleteButton.ts
index b561d94..bc0da17 100644
--- a/src/lib/common/DeleteButton.ts
+++ b/src/lib/common/DeleteButton.ts
@@ -45,7 +45,7 @@ export class DeleteButton {
collector.on('collect', async (interaction: MessageComponentInteraction) => {
await interaction.deferUpdate().catch(() => undefined);
- if (interaction.user.id == this.message.author.id || client.config.owners.includes(interaction.user.id)) {
+ if (interaction.user.id == this.message.author.id || this.message.client.config.owners.includes(interaction.user.id)) {
if (msg.deletable && !CommandUtil.deletedMessages.has(msg.id)) await msg.delete();
}
});
diff --git a/src/lib/common/HighlightManager.ts b/src/lib/common/HighlightManager.ts
index caaa6a5..cd89c89 100644
--- a/src/lib/common/HighlightManager.ts
+++ b/src/lib/common/HighlightManager.ts
@@ -232,10 +232,10 @@ export class HighlightManager {
const lastDM = this.lastedDMedUserCooldown.get(user);
if (!lastDM) break dmCooldown;
- const cooldown = client.ownerID.includes(user) ? OWNER_NOTIFY_COOLDOWN : NOTIFY_COOLDOWN;
+ const cooldown = message.client.ownerID.includes(user) ? OWNER_NOTIFY_COOLDOWN : NOTIFY_COOLDOWN;
if (new Date().getTime() - lastDM.getTime() < cooldown) {
- void client.console.verbose('Highlight', `User <<${user}>> has been dmed recently.`);
+ void message.client.console.verbose('Highlight', `User <<${user}>> has been dmed recently.`);
return false;
}
}
@@ -248,7 +248,7 @@ export class HighlightManager {
const talked = lastTalked.getTime();
if (now - talked < LAST_MESSAGE_COOLDOWN) {
- void client.console.verbose('Highlight', `User <<${user}>> has talked too recently.`);
+ void message.client.console.verbose('Highlight', `User <<${user}>> has talked too recently.`);
setTimeout(() => {
const newTalked = this.userLastTalkedCooldown.get(message.guildId)?.get(user)?.getTime();
@@ -268,7 +268,7 @@ export class HighlightManager {
.first(4)
.reverse();
- return client.users
+ return message.client.users
.send(user, {
// eslint-disable-next-line @typescript-eslint/no-base-to-string
content: `In ${format.input(message.guild.name)} ${message.channel}, your highlight "${hl.word}" was matched:`,
diff --git a/src/lib/common/util/Arg.ts b/src/lib/common/util/Arg.ts
index a7795b1..325f821 100644
--- a/src/lib/common/util/Arg.ts
+++ b/src/lib/common/util/Arg.ts
@@ -18,7 +18,7 @@ export async function cast<T extends ATC>(type: T, message: CommandMessage | Sla
export async function cast<T extends KBAT>(type: T, message: CommandMessage | SlashMessage, phrase: string): Promise<BAT[T]>;
export async function cast(type: AT | ATC, message: CommandMessage | SlashMessage, phrase: string): Promise<any>;
export async function cast(type: ATC | AT, message: CommandMessage | SlashMessage, phrase: string): Promise<any> {
- return Argument.cast(type as any, client.commandHandler.resolver, message as Message, phrase);
+ return Argument.cast(type as any, message.client.commandHandler.resolver, message as Message, phrase);
}
/**
diff --git a/src/lib/common/util/Moderation.ts b/src/lib/common/util/Moderation.ts
index a08dfa4..cb6b4db 100644
--- a/src/lib/common/util/Moderation.ts
+++ b/src/lib/common/util/Moderation.ts
@@ -5,10 +5,8 @@ import {
emojis,
format,
Guild as GuildDB,
- handleError,
humanizeDuration,
ModLog,
- resolveNonCachedUser,
type ModLogType
} from '#lib';
import assert from 'assert';
@@ -16,6 +14,7 @@ import {
ActionRowBuilder,
ButtonBuilder,
ButtonStyle,
+ Client,
EmbedBuilder,
PermissionFlagsBits,
type Guild,
@@ -129,9 +128,9 @@ export async function createModLogEntry(
options: CreateModLogEntryOptions,
getCaseNumber = false
): Promise<{ log: ModLog | null; caseNum: number | null }> {
- const user = (await resolveNonCachedUser(options.user))!.id;
- const moderator = (await resolveNonCachedUser(options.moderator))!.id;
- const guild = client.guilds.resolveId(options.guild)!;
+ const user = (await options.client.utils.resolveNonCachedUser(options.user))!.id;
+ const moderator = (await options.client.utils.resolveNonCachedUser(options.moderator))!.id;
+ const guild = options.client.guilds.resolveId(options.guild)!;
return createModLogEntrySimple(
{
@@ -172,7 +171,7 @@ export async function createModLogEntrySimple(
hidden: options.hidden ?? false
});
const saveResult: ModLog | null = await modLogEntry.save().catch(async (e) => {
- await handleError('createModLogEntry', e);
+ await options.client.utils.handleError('createModLogEntry', e);
return null;
});
@@ -191,8 +190,8 @@ export async function createModLogEntrySimple(
*/
export async function createPunishmentEntry(options: CreatePunishmentEntryOptions): Promise<ActivePunishment | null> {
const expires = options.duration ? new Date(+new Date() + options.duration ?? 0) : undefined;
- const user = (await resolveNonCachedUser(options.user))!.id;
- const guild = client.guilds.resolveId(options.guild)!;
+ const user = (await options.client.utils.resolveNonCachedUser(options.user))!.id;
+ const guild = options.client.guilds.resolveId(options.guild)!;
const type = findTypeEnum(options.type)!;
const entry = ActivePunishment.build(
@@ -201,7 +200,7 @@ export async function createPunishmentEntry(options: CreatePunishmentEntryOption
: { user, type, guild, expires, modlog: options.modlog }
);
return await entry.save().catch(async (e) => {
- await handleError('createPunishmentEntry', e);
+ await options.client.utils.handleError('createPunishmentEntry', e);
return null;
});
}
@@ -212,8 +211,8 @@ export async function createPunishmentEntry(options: CreatePunishmentEntryOption
* @returns Whether or not the entry was destroyed.
*/
export async function removePunishmentEntry(options: RemovePunishmentEntryOptions): Promise<boolean> {
- const user = await resolveNonCachedUser(options.user);
- const guild = client.guilds.resolveId(options.guild);
+ const user = await options.client.utils.resolveNonCachedUser(options.user);
+ const guild = options.client.guilds.resolveId(options.guild);
const type = findTypeEnum(options.type);
if (!user || !guild) return false;
@@ -226,13 +225,13 @@ export async function removePunishmentEntry(options: RemovePunishmentEntryOption
? { user: user.id, guild: guild, type, extraInfo: options.extraInfo }
: { user: user.id, guild: guild, type }
}).catch(async (e) => {
- await handleError('removePunishmentEntry', e);
+ await options.client.utils.handleError('removePunishmentEntry', e);
success = false;
});
if (entries) {
const promises = entries.map(async (entry) =>
entry.destroy().catch(async (e) => {
- await handleError('removePunishmentEntry', e);
+ await options.client.utils.handleError('removePunishmentEntry', e);
success = false;
})
);
@@ -298,9 +297,9 @@ export async function punishDM(options: PunishDMOptions): Promise<boolean> {
new ActionRowBuilder<ButtonBuilder>({
components: [
new ButtonBuilder({
- customId: `appeal;${punishmentToPresentTense(options.punishment)};${options.guild.id};${client.users.resolveId(
- options.user
- )};${options.modlog}`,
+ customId: `appeal;${punishmentToPresentTense(options.punishment)};${
+ options.guild.id
+ };${options.client.users.resolveId(options.user)};${options.modlog}`,
style: ButtonStyle.Primary,
label: 'Appeal'
}).toJSON()
@@ -308,7 +307,7 @@ export async function punishDM(options: PunishDMOptions): Promise<boolean> {
})
];
- const dmSuccess = await client.users
+ const dmSuccess = await options.client.users
.send(options.user, {
content,
embeds: dmEmbed ? [dmEmbed] : undefined,
@@ -318,7 +317,7 @@ export async function punishDM(options: PunishDMOptions): Promise<boolean> {
return !!dmSuccess;
}
-interface BaseCreateModLogEntryOptions {
+interface BaseCreateModLogEntryOptions extends BaseOptions {
/**
* The type of modlog entry.
*/
@@ -355,6 +354,11 @@ interface BaseCreateModLogEntryOptions {
*/
export interface CreateModLogEntryOptions extends BaseCreateModLogEntryOptions {
/**
+ * The client.
+ */
+ client: Client;
+
+ /**
* The user that a modlog entry is created for.
*/
user: GuildMemberResolvable;
@@ -393,7 +397,7 @@ export interface SimpleCreateModLogEntryOptions extends BaseCreateModLogEntryOpt
/**
* Options for creating a punishment entry.
*/
-export interface CreatePunishmentEntryOptions {
+export interface CreatePunishmentEntryOptions extends BaseOptions {
/**
* The type of punishment.
*/
@@ -428,7 +432,7 @@ export interface CreatePunishmentEntryOptions {
/**
* Options for removing a punishment entry.
*/
-export interface RemovePunishmentEntryOptions {
+export interface RemovePunishmentEntryOptions extends BaseOptions {
/**
* The type of punishment.
*/
@@ -453,7 +457,7 @@ export interface RemovePunishmentEntryOptions {
/**
* Options for sending a user a punishment dm.
*/
-export interface PunishDMOptions {
+export interface PunishDMOptions extends BaseOptions {
/**
* The modlog case id so the user can make an appeal.
*/
@@ -496,6 +500,13 @@ export interface PunishDMOptions {
channel?: Snowflake;
}
+interface BaseOptions {
+ /**
+ * The client.
+ */
+ client: Client;
+}
+
export type PunishmentTypeDM =
| 'warned'
| 'muted'
diff --git a/src/lib/extensions/discord-akairo/BushClient.ts b/src/lib/extensions/discord-akairo/BushClient.ts
index b382121..68b2599 100644
--- a/src/lib/extensions/discord-akairo/BushClient.ts
+++ b/src/lib/extensions/discord-akairo/BushClient.ts
@@ -63,7 +63,8 @@ import { Shared } from '../../models/shared/Shared.js';
import { Stat } from '../../models/shared/Stat.js';
import { AllowedMentions } from '../../utils/AllowedMentions.js';
import { BushCache } from '../../utils/BushCache.js';
-import BushLogger from '../../utils/BushLogger.js';
+import { BushClientUtils } from '../../utils/BushClientUtils.js';
+import { BushLogger } from '../../utils/BushLogger.js';
import { ExtendedGuild } from '../discord.js/ExtendedGuild.js';
import { ExtendedGuildMember } from '../discord.js/ExtendedGuildMember.js';
import { ExtendedMessage } from '../discord.js/ExtendedMessage.js';
@@ -76,14 +77,44 @@ const { Sequelize } = (await import('sequelize')).default;
declare module 'discord.js' {
export interface Client extends EventEmitter {
- /**
- * The ID of the owner(s).
- */
+ /** The ID of the owner(s). */
ownerID: Snowflake | Snowflake[];
- /**
- * The ID of the superUser(s).
- */
+ /** The ID of the superUser(s). */
superUserID: Snowflake | Snowflake[];
+ /** Whether or not the client is ready. */
+ customReady: boolean;
+ /** The configuration for the client. */
+ config: Config;
+ /** Stats for the client. */
+ stats: BushStats;
+ /** The handler for the bot's listeners. */
+ listenerHandler: BushListenerHandler;
+ /** The handler for the bot's command inhibitors. */
+ inhibitorHandler: BushInhibitorHandler;
+ /** The handler for the bot's commands. */
+ commandHandler: BushCommandHandler;
+ /** The handler for the bot's tasks. */
+ taskHandler: BushTaskHandler;
+ /** The handler for the bot's context menu commands. */
+ contextMenuCommandHandler: ContextMenuCommandHandler;
+ /** The database connection for this instance of the bot (production, beta, or development). */
+ instanceDB: SequelizeType;
+ /** The database connection that is shared between all instances of the bot. */
+ sharedDB: SequelizeType;
+ /** A custom logging system for the bot. */
+ logger: BushLogger;
+ /** Cached global and guild database data. */
+ cache: BushCache;
+ /** Sentry error reporting for the bot. */
+ sentry: typeof Sentry;
+ /** Manages most aspects of the highlight command */
+ highlightManager: HighlightManager;
+ /** The perspective api */
+ perspective: any;
+ /** Client utilities. */
+ utils: BushClientUtils;
+ /** A custom logging system for the bot. */
+ get console(): BushLogger;
on<K extends keyof BushClientEvents>(event: K, listener: (...args: BushClientEvents[K]) => Awaitable<void>): this;
once<K extends keyof BushClientEvents>(event: K, listener: (...args: BushClientEvents[K]) => Awaitable<void>): this;
emit<K extends keyof BushClientEvents>(event: K, ...args: BushClientEvents[K]): boolean;
@@ -126,72 +157,77 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re
/**
* Whether or not the client is ready.
*/
- public customReady = false;
+ public override customReady = false;
/**
* Stats for the client.
*/
- public stats: BushStats = { cpu: undefined, commandsUsed: 0n, slashCommandsUsed: 0n };
+ public override stats: BushStats = { cpu: undefined, commandsUsed: 0n, slashCommandsUsed: 0n };
/**
* The handler for the bot's listeners.
*/
- public listenerHandler: BushListenerHandler;
+ public override listenerHandler: BushListenerHandler;
/**
* The handler for the bot's command inhibitors.
*/
- public inhibitorHandler: BushInhibitorHandler;
+ public override inhibitorHandler: BushInhibitorHandler;
/**
* The handler for the bot's commands.
*/
- public commandHandler: BushCommandHandler;
+ public override commandHandler: BushCommandHandler;
/**
* The handler for the bot's tasks.
*/
- public taskHandler: BushTaskHandler;
+ public override taskHandler: BushTaskHandler;
/**
* The handler for the bot's context menu commands.
*/
- public contextMenuCommandHandler: ContextMenuCommandHandler;
+ public override contextMenuCommandHandler: ContextMenuCommandHandler;
/**
* The database connection for this instance of the bot (production, beta, or development).
*/
- public instanceDB: SequelizeType;
+ public override instanceDB: SequelizeType;
/**
* The database connection that is shared between all instances of the bot.
*/
- public sharedDB: SequelizeType;
+ public override sharedDB: SequelizeType;
/**
* A custom logging system for the bot.
*/
- public logger = BushLogger;
+ public override logger: BushLogger;
/**
* Cached global and guild database data.
*/
- public cache = new BushCache();
+ public override cache = new BushCache();
/**
* Sentry error reporting for the bot.
*/
- public sentry!: typeof Sentry;
+ public override sentry!: typeof Sentry;
/**
* Manages most aspects of the highlight command
*/
- public highlightManager = new HighlightManager();
+ public override highlightManager = new HighlightManager();
/**
* The perspective api
*/
- public perspective: any;
+ public override perspective: any;
+
+ /**
+ * Client utilities.
+ */
+ public override utils: BushClientUtils;
/**
* @param config The configuration for the bot.
@@ -200,7 +236,7 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re
/**
* The configuration for the client.
*/
- public config: Config
+ public override config: Config
) {
super({
ownerID: config.owners,
@@ -220,7 +256,8 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re
patch(this);
this.token = config.token as If<Ready, string, string | null>;
- this.config = config;
+ this.logger = new BushLogger(this);
+ this.utils = new BushClientUtils(this);
/* =-=-= handlers =-=-= */
this.listenerHandler = new BushListenerHandler(this, {
@@ -320,7 +357,7 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re
/**
* A custom logging system for the bot.
*/
- public get console(): typeof BushLogger {
+ public override get console(): BushLogger {
return this.logger;
}
@@ -474,7 +511,7 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re
await this.highlightManager.syncCache();
await UpdateCacheTask.init(this);
void this.console.success('startup', `Successfully created <<cache>>.`, false);
- const stats = await UpdateStatsTask.init();
+ const stats = await UpdateStatsTask.init(this);
this.stats.commandsUsed = stats.commandsUsed;
this.stats.slashCommandsUsed = stats.slashCommandsUsed;
await this.login(this.token!);
@@ -500,7 +537,7 @@ export class BushClient<Ready extends boolean = boolean> extends AkairoClient<Re
public override isSuperUser(user: UserResolvable): boolean {
const userID = this.users.resolveId(user)!;
- return client.cache.shared.superUsers.includes(userID) || this.config.owners.includes(userID);
+ return this.cache.shared.superUsers.includes(userID) || this.config.owners.includes(userID);
}
}
diff --git a/src/lib/extensions/discord-akairo/BushCommand.ts b/src/lib/extensions/discord-akairo/BushCommand.ts
index 5fb4e06..414da09 100644
--- a/src/lib/extensions/discord-akairo/BushCommand.ts
+++ b/src/lib/extensions/discord-akairo/BushCommand.ts
@@ -34,6 +34,8 @@ import {
Message,
User,
type ApplicationCommandOptionChoiceData,
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ type ApplicationCommandOptionType,
type PermissionResolvable,
type PermissionsString,
type Snowflake
@@ -93,7 +95,7 @@ interface BaseBushArgumentOptions extends Omit<ArgumentOptions, 'type' | 'prompt
/**
* Allows you to get a discord resolved object
*
- * ex. get the resolved member object when the type is `USER`
+ * ex. get the resolved member object when the type is {@link ApplicationCommandOptionType.User User}
*/
slashResolve?: SlashResolveType;
@@ -113,12 +115,12 @@ interface BaseBushArgumentOptions extends Omit<ArgumentOptions, 'type' | 'prompt
channelTypes?: AkairoApplicationCommandChannelOptionData['channelTypes'];
/**
- * The minimum value for an `INTEGER` or `NUMBER` option
+ * The minimum value for an {@link ApplicationCommandOptionType.Integer Integer} or {@link ApplicationCommandOptionType.Number Number} option
*/
minValue?: number;
/**
- * The maximum value for an `INTEGER` or `NUMBER` option
+ * The maximum value for an {@link ApplicationCommandOptionType.Integer Integer} or {@link ApplicationCommandOptionType.Number Number} option
*/
maxValue?: number;
}
diff --git a/src/lib/extensions/discord-akairo/BushCommandHandler.ts b/src/lib/extensions/discord-akairo/BushCommandHandler.ts
index f095356..da49af9 100644
--- a/src/lib/extensions/discord-akairo/BushCommandHandler.ts
+++ b/src/lib/extensions/discord-akairo/BushCommandHandler.ts
@@ -1,4 +1,4 @@
-import { type BushClient, type BushCommand, type CommandMessage, type SlashMessage } from '#lib';
+import { type BushCommand, type CommandMessage, type SlashMessage } from '#lib';
import { CommandHandler, type Category, type CommandHandlerEvents, type CommandHandlerOptions } from 'discord-akairo';
import { type Collection, type Message, type PermissionsString } from 'discord.js';
@@ -28,13 +28,8 @@ export interface BushCommandHandlerEvents extends CommandHandlerEvents {
}
export class BushCommandHandler extends CommandHandler {
- public declare client: BushClient;
public declare modules: Collection<string, BushCommand>;
public declare categories: Collection<string, Category<string, BushCommand>>;
-
- public constructor(client: BushClient, options: CommandHandlerOptions) {
- super(client, options);
- }
}
export interface BushCommandHandler extends CommandHandler {
diff --git a/src/lib/extensions/discord-akairo/BushInhibitor.ts b/src/lib/extensions/discord-akairo/BushInhibitor.ts
index b4e6797..be396cf 100644
--- a/src/lib/extensions/discord-akairo/BushInhibitor.ts
+++ b/src/lib/extensions/discord-akairo/BushInhibitor.ts
@@ -1,15 +1,15 @@
-import { type BushClient, type BushCommand, type CommandMessage, type SlashMessage } from '#lib';
+import { type BushCommand, type CommandMessage, type SlashMessage } from '#lib';
import { Inhibitor } from 'discord-akairo';
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+import { Message } from 'discord.js';
export abstract class BushInhibitor extends Inhibitor {
- public declare client: BushClient;
-
/**
* Checks if message should be blocked.
* A return value of true will block the message.
* If returning a Promise, a resolved value of true will block the message.
*
- * **Note:** `all` type inhibitors do not have `message.util` defined.
+ * **Note:** `'all'` type inhibitors do not have {@link Message.util} defined.
*
* @param message - Message being handled.
* @param command - Command to check.
diff --git a/src/lib/extensions/discord.js/ExtendedGuild.ts b/src/lib/extensions/discord.js/ExtendedGuild.ts
index c199899..c58916c 100644
--- a/src/lib/extensions/discord.js/ExtendedGuild.ts
+++ b/src/lib/extensions/discord.js/ExtendedGuild.ts
@@ -41,7 +41,7 @@ import _ from 'lodash';
import * as Moderation from '../../common/util/Moderation.js';
import { Guild as GuildDB } from '../../models/instance/Guild.js';
import { ModLogType } from '../../models/instance/ModLog.js';
-import { addOrRemoveFromArray, resolveNonCachedUser } from '../../utils/BushUtils.js';
+import { addOrRemoveFromArray } from '../../utils/BushUtils.js';
declare module 'discord.js' {
export interface Guild {
@@ -187,7 +187,7 @@ export class ExtendedGuild extends Guild {
*/
public override async getSetting<K extends keyof GuildModel>(setting: K): Promise<GuildModel[K]> {
return (
- client.cache.guilds.get(this.id)?.[setting] ??
+ this.client.cache.guilds.get(this.id)?.[setting] ??
((await GuildDB.findByPk(this.id)) ?? GuildDB.build({ id: this.id }))[setting]
);
}
@@ -206,8 +206,8 @@ export class ExtendedGuild extends Guild {
const row = (await GuildDB.findByPk(this.id)) ?? GuildDB.build({ id: this.id });
const oldValue = row[setting] as GuildDB[K];
row[setting] = value;
- client.cache.guilds.set(this.id, row.toJSON() as GuildDB);
- client.emit('bushUpdateSettings', setting, this, oldValue, row[setting], moderator);
+ this.client.cache.guilds.set(this.id, row.toJSON() as GuildDB);
+ this.client.emit('bushUpdateSettings', setting, this, oldValue, row[setting], moderator);
return await row.save();
}
@@ -253,7 +253,7 @@ export class ExtendedGuild extends Guild {
* @param message The description of the error embed
*/
public override async error(title: string, message: string): Promise<void> {
- void client.console.info(_.camelCase(title), message.replace(/\*\*(.*?)\*\*/g, '<<$1>>'));
+ void this.client.console.info(_.camelCase(title), message.replace(/\*\*(.*?)\*\*/g, '<<$1>>'));
void this.sendLogChannel('error', { embeds: [{ title: title, description: message, color: colors.error }] });
}
@@ -268,8 +268,8 @@ export class ExtendedGuild extends Guild {
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
- const user = await resolveNonCachedUser(options.user);
- const moderator = client.users.resolve(options.moderator ?? client.user!);
+ const user = await this.client.utils.resolveNonCachedUser(options.user);
+ const moderator = this.client.users.resolve(options.moderator ?? this.client.user!);
if (!user || !moderator) return banResponse.CANNOT_RESOLVE_USER;
if ((await this.bans.fetch()).has(user.id)) return banResponse.ALREADY_BANNED;
@@ -277,6 +277,7 @@ export class ExtendedGuild extends Guild {
const ret = await (async () => {
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
+ client: this.client,
type: options.duration ? ModLogType.TEMP_BAN : ModLogType.PERM_BAN,
user: user,
moderator: moderator.id,
@@ -290,6 +291,7 @@ export class ExtendedGuild extends Guild {
// dm user
dmSuccessEvent = await Moderation.punishDM({
+ client: this.client,
modlog: modlog.id,
guild: this,
user: user,
@@ -310,6 +312,7 @@ export class ExtendedGuild extends Guild {
// add punishment entry so they can be unbanned later
const punishmentEntrySuccess = await Moderation.createPunishmentEntry({
+ client: this.client,
type: 'ban',
user: user,
guild: this,
@@ -323,7 +326,7 @@ export class ExtendedGuild extends Guild {
})();
if (!([banResponse.ACTION_ERROR, banResponse.MODLOG_ERROR, banResponse.PUNISHMENT_ENTRY_ADD_ERROR] as const).includes(ret))
- client.emit(
+ this.client.emit(
'bushBan',
user,
moderator,
@@ -352,6 +355,7 @@ export class ExtendedGuild extends Guild {
const ret = await (async () => {
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntrySimple({
+ client: this.client,
type: ModLogType.PERM_BAN,
user: options.user,
moderator: options.moderator,
@@ -365,6 +369,7 @@ export class ExtendedGuild extends Guild {
// dm user
if (this.members.cache.has(options.user)) {
dmSuccessEvent = await Moderation.punishDM({
+ client: this.client,
modlog: modlog.id,
guild: this,
user: options.user,
@@ -386,6 +391,7 @@ export class ExtendedGuild extends Guild {
// add punishment entry so they can be unbanned later
const punishmentEntrySuccess = await Moderation.createPunishmentEntry({
+ client: this.client,
type: 'ban',
user: options.user,
guild: this,
@@ -411,8 +417,8 @@ export class ExtendedGuild extends Guild {
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
- const user = await resolveNonCachedUser(options.user);
- const moderator = client.users.resolve(options.moderator ?? client.user!);
+ const user = await this.client.utils.resolveNonCachedUser(options.user);
+ const moderator = this.client.users.resolve(options.moderator ?? this.client.user!);
if (!user || !moderator) return unbanResponse.CANNOT_RESOLVE_USER;
const ret = await (async () => {
@@ -435,6 +441,7 @@ export class ExtendedGuild extends Guild {
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
+ client: this.client,
type: ModLogType.UNBAN,
user: user.id,
moderator: moderator.id,
@@ -447,6 +454,7 @@ export class ExtendedGuild extends Guild {
// remove punishment entry
const removePunishmentEntrySuccess = await Moderation.removePunishmentEntry({
+ client: this.client,
type: 'ban',
user: user.id,
guild: this
@@ -455,6 +463,7 @@ export class ExtendedGuild extends Guild {
// dm user
dmSuccessEvent = await Moderation.punishDM({
+ client: this.client,
guild: this,
user: user,
punishment: 'unbanned',
@@ -470,7 +479,16 @@ export class ExtendedGuild extends Guild {
ret
)
)
- client.emit('bushUnban', user, moderator, this, options.reason ?? undefined, caseID!, dmSuccessEvent!, options.evidence);
+ this.client.emit(
+ 'bushUnban',
+ user,
+ moderator,
+ this,
+ options.reason ?? undefined,
+ caseID!,
+ dmSuccessEvent!,
+ options.evidence
+ );
return ret;
}
@@ -549,7 +567,7 @@ export class ExtendedGuild extends Guild {
else return `success: ${success.filter((c) => c === true).size}`;
})();
- client.emit(options.unlock ? 'bushUnlockdown' : 'bushLockdown', moderator, options.reason, success, options.all);
+ this.client.emit(options.unlock ? 'bushUnlockdown' : 'bushLockdown', moderator, options.reason, success, options.all);
return ret;
}
@@ -557,7 +575,7 @@ export class ExtendedGuild extends Guild {
if (!channel.isTextBased() || channel.isDMBased() || channel.guildId !== this.id || !this.members.me) return null;
if (!channel.permissionsFor(this.members.me).has('ManageWebhooks')) return null;
- const quote = new Message(client, rawQuote);
+ const quote = new Message(this.client, rawQuote);
const target = channel instanceof ThreadChannel ? channel.parent : channel;
if (!target) return null;
@@ -570,8 +588,8 @@ export class ExtendedGuild extends Guild {
if (!webhook)
webhook = await target
.createWebhook({
- name: `${client.user!.username} Quotes #${target.name}`,
- avatar: client.user!.displayAvatarURL({ size: 2048 }),
+ name: `${this.client.user!.username} Quotes #${target.name}`,
+ avatar: this.client.user!.displayAvatarURL({ size: 2048 }),
reason: 'Creating a webhook for quoting'
})
.catch(() => null);
diff --git a/src/lib/extensions/discord.js/ExtendedGuildMember.ts b/src/lib/extensions/discord.js/ExtendedGuildMember.ts
index ad29236..947f9cd 100644
--- a/src/lib/extensions/discord.js/ExtendedGuildMember.ts
+++ b/src/lib/extensions/discord.js/ExtendedGuildMember.ts
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
-import { BushClientEvents, formatError, Moderation, ModLogType, PunishmentTypeDM, resolveNonCachedUser, Time } from '#lib';
+import { BushClientEvents, formatError, Moderation, ModLogType, PunishmentTypeDM, Time } from '#lib';
import {
ChannelType,
GuildChannelResolvable,
@@ -129,6 +129,7 @@ export class ExtendedGuildMember extends GuildMember {
sendFooter = true
): Promise<boolean> {
return Moderation.punishDM({
+ client: this.client,
modlog,
guild: this.guild,
user: this,
@@ -148,13 +149,14 @@ export class ExtendedGuildMember extends GuildMember {
public override async bushWarn(options: BushPunishmentOptions): Promise<{ result: WarnResponse; caseNum: number | null }> {
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
- const moderator = await resolveNonCachedUser(options.moderator ?? this.guild.members.me);
+ const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
if (!moderator) return { result: warnResponse.CANNOT_RESOLVE_USER, caseNum: null };
const ret = await (async (): Promise<{ result: WarnResponse; caseNum: number | null }> => {
// add modlog entry
const result = await Moderation.createModLogEntry(
{
+ client: this.client,
type: ModLogType.WARN,
user: this,
moderator: moderator.id,
@@ -178,7 +180,7 @@ export class ExtendedGuildMember extends GuildMember {
return { result: warnResponse.SUCCESS, caseNum: result.caseNum };
})();
if (!([warnResponse.MODLOG_ERROR] as const).includes(ret.result) && !options.silent)
- client.emit('bushWarn', this, moderator, this.guild, options.reason ?? undefined, caseID!, dmSuccessEvent!);
+ this.client.emit('bushWarn', this, moderator, this.guild, options.reason ?? undefined, caseID!, dmSuccessEvent!);
return ret;
}
@@ -195,12 +197,13 @@ export class ExtendedGuildMember extends GuildMember {
if (ifShouldAddRole !== true) return ifShouldAddRole;
let caseID: string | undefined = undefined;
- const moderator = await resolveNonCachedUser(options.moderator ?? this.guild.members.me);
+ const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
if (!moderator) return addRoleResponse.CANNOT_RESOLVE_USER;
const ret = await (async () => {
if (options.addToModlog || options.duration) {
const { log: modlog } = await Moderation.createModLogEntry({
+ client: this.client,
type: options.duration ? ModLogType.TEMP_PUNISHMENT_ROLE : ModLogType.PERM_PUNISHMENT_ROLE,
guild: this.guild,
moderator: moderator.id,
@@ -216,6 +219,7 @@ export class ExtendedGuildMember extends GuildMember {
if (options.addToModlog || options.duration) {
const punishmentEntrySuccess = await Moderation.createPunishmentEntry({
+ client: this.client,
type: 'role',
user: this,
guild: this.guild,
@@ -239,7 +243,7 @@ export class ExtendedGuildMember extends GuildMember {
options.addToModlog &&
!options.silent
)
- client.emit(
+ this.client.emit(
'bushPunishRole',
this,
moderator,
@@ -266,12 +270,13 @@ export class ExtendedGuildMember extends GuildMember {
if (ifShouldAddRole !== true) return ifShouldAddRole;
let caseID: string | undefined = undefined;
- const moderator = await resolveNonCachedUser(options.moderator ?? this.guild.members.me);
+ const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
if (!moderator) return removeRoleResponse.CANNOT_RESOLVE_USER;
const ret = await (async () => {
if (options.addToModlog) {
const { log: modlog } = await Moderation.createModLogEntry({
+ client: this.client,
type: ModLogType.REMOVE_PUNISHMENT_ROLE,
guild: this.guild,
moderator: moderator.id,
@@ -285,6 +290,7 @@ export class ExtendedGuildMember extends GuildMember {
caseID = modlog.id;
const punishmentEntrySuccess = await Moderation.removePunishmentEntry({
+ client: this.client,
type: 'role',
user: this,
guild: this.guild,
@@ -311,7 +317,7 @@ export class ExtendedGuildMember extends GuildMember {
options.addToModlog &&
!options.silent
)
- client.emit(
+ this.client.emit(
'bushPunishRoleRemove',
this,
moderator,
@@ -362,7 +368,7 @@ export class ExtendedGuildMember extends GuildMember {
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
- const moderator = await resolveNonCachedUser(options.moderator ?? this.guild.members.me);
+ const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
if (!moderator) return muteResponse.CANNOT_RESOLVE_USER;
const ret = await (async () => {
@@ -370,14 +376,15 @@ export class ExtendedGuildMember extends GuildMember {
const muteSuccess = await this.roles
.add(muteRole, `[Mute] ${moderator.tag} | ${options.reason ?? 'No reason provided.'}`)
.catch(async (e) => {
- await client.console.warn('muteRoleAddError', e);
- client.console.debug(e);
+ await this.client.console.warn('muteRoleAddError', e);
+ this.client.console.debug(e);
return false;
});
if (!muteSuccess) return muteResponse.ACTION_ERROR;
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
+ client: this.client,
type: options.duration ? ModLogType.TEMP_MUTE : ModLogType.PERM_MUTE,
user: this,
moderator: moderator.id,
@@ -393,6 +400,7 @@ export class ExtendedGuildMember extends GuildMember {
// add punishment entry so they can be unmuted later
const punishmentEntrySuccess = await Moderation.createPunishmentEntry({
+ client: this.client,
type: 'mute',
user: this,
guild: this.guild,
@@ -416,7 +424,7 @@ export class ExtendedGuildMember extends GuildMember {
!([muteResponse.ACTION_ERROR, muteResponse.MODLOG_ERROR, muteResponse.PUNISHMENT_ENTRY_ADD_ERROR] as const).includes(ret) &&
!options.silent
)
- client.emit(
+ this.client.emit(
'bushMute',
this,
moderator,
@@ -448,7 +456,7 @@ export class ExtendedGuildMember extends GuildMember {
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
- const moderator = await resolveNonCachedUser(options.moderator ?? this.guild.members.me);
+ const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
if (!moderator) return unmuteResponse.CANNOT_RESOLVE_USER;
const ret = await (async () => {
@@ -456,13 +464,14 @@ export class ExtendedGuildMember extends GuildMember {
const muteSuccess = await this.roles
.remove(muteRole, `[Unmute] ${moderator.tag} | ${options.reason ?? 'No reason provided.'}`)
.catch(async (e) => {
- await client.console.warn('muteRoleAddError', formatError(e, true));
+ await this.client.console.warn('muteRoleAddError', formatError(e, true));
return false;
});
if (!muteSuccess) return unmuteResponse.ACTION_ERROR;
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
+ client: this.client,
type: ModLogType.UNMUTE,
user: this,
moderator: moderator.id,
@@ -477,6 +486,7 @@ export class ExtendedGuildMember extends GuildMember {
// remove mute entry
const removePunishmentEntrySuccess = await Moderation.removePunishmentEntry({
+ client: this.client,
type: 'mute',
user: this,
guild: this.guild
@@ -500,7 +510,7 @@ export class ExtendedGuildMember extends GuildMember {
).includes(ret) &&
!options.silent
)
- client.emit(
+ this.client.emit(
'bushUnmute',
this,
moderator,
@@ -526,11 +536,12 @@ export class ExtendedGuildMember extends GuildMember {
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
- const moderator = await resolveNonCachedUser(options.moderator ?? this.guild.members.me);
+ const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
if (!moderator) return kickResponse.CANNOT_RESOLVE_USER;
const ret = await (async () => {
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
+ client: this.client,
type: ModLogType.KICK,
user: this,
moderator: moderator.id,
@@ -554,7 +565,7 @@ export class ExtendedGuildMember extends GuildMember {
return kickResponse.SUCCESS;
})();
if (!([kickResponse.ACTION_ERROR, kickResponse.MODLOG_ERROR] as const).includes(ret) && !options.silent)
- client.emit(
+ this.client.emit(
'bushKick',
this,
moderator,
@@ -580,7 +591,7 @@ export class ExtendedGuildMember extends GuildMember {
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
- const moderator = await resolveNonCachedUser(options.moderator ?? this.guild.members.me);
+ const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
if (!moderator) return banResponse.CANNOT_RESOLVE_USER;
// ignore result, they should still be banned even if their mute cannot be removed
@@ -593,6 +604,7 @@ export class ExtendedGuildMember extends GuildMember {
const ret = await (async () => {
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
+ client: this.client,
type: options.duration ? ModLogType.TEMP_BAN : ModLogType.PERM_BAN,
user: this,
moderator: moderator.id,
@@ -620,6 +632,7 @@ export class ExtendedGuildMember extends GuildMember {
// add punishment entry so they can be unbanned later
const punishmentEntrySuccess = await Moderation.createPunishmentEntry({
+ client: this.client,
type: 'ban',
user: this,
guild: this.guild,
@@ -635,7 +648,7 @@ export class ExtendedGuildMember extends GuildMember {
!([banResponse.ACTION_ERROR, banResponse.MODLOG_ERROR, banResponse.PUNISHMENT_ENTRY_ADD_ERROR] as const).includes(ret) &&
!options.silent
)
- client.emit(
+ this.client.emit(
'bushBan',
this,
moderator,
@@ -663,7 +676,7 @@ export class ExtendedGuildMember extends GuildMember {
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
- const moderator = await resolveNonCachedUser(options.moderator ?? this.guild.members.me);
+ const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
if (!moderator) return blockResponse.CANNOT_RESOLVE_USER;
const ret = await (async () => {
@@ -677,6 +690,7 @@ export class ExtendedGuildMember extends GuildMember {
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
+ client: this.client,
type: options.duration ? ModLogType.TEMP_CHANNEL_BLOCK : ModLogType.PERM_CHANNEL_BLOCK,
user: this,
moderator: moderator.id,
@@ -690,6 +704,7 @@ export class ExtendedGuildMember extends GuildMember {
// add punishment entry so they can be unblocked later
const punishmentEntrySuccess = await Moderation.createPunishmentEntry({
+ client: this.client,
type: 'block',
user: this,
guild: this.guild,
@@ -703,6 +718,7 @@ export class ExtendedGuildMember extends GuildMember {
const dmSuccess = options.silent
? null
: await Moderation.punishDM({
+ client: this.client,
punishment: 'blocked',
reason: options.reason ?? undefined,
duration: options.duration ?? 0,
@@ -724,7 +740,7 @@ export class ExtendedGuildMember extends GuildMember {
) &&
!options.silent
)
- client.emit(
+ this.client.emit(
'bushBlock',
this,
moderator,
@@ -754,7 +770,7 @@ export class ExtendedGuildMember extends GuildMember {
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
- const moderator = await resolveNonCachedUser(options.moderator ?? this.guild.members.me);
+ const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
if (!moderator) return unblockResponse.CANNOT_RESOLVE_USER;
const ret = await (async () => {
@@ -768,6 +784,7 @@ export class ExtendedGuildMember extends GuildMember {
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
+ client: this.client,
type: ModLogType.CHANNEL_UNBLOCK,
user: this,
moderator: moderator.id,
@@ -781,6 +798,7 @@ export class ExtendedGuildMember extends GuildMember {
// remove punishment entry
const punishmentEntrySuccess = await Moderation.removePunishmentEntry({
+ client: this.client,
type: 'block',
user: this,
guild: this.guild,
@@ -792,6 +810,7 @@ export class ExtendedGuildMember extends GuildMember {
const dmSuccess = options.silent
? null
: await Moderation.punishDM({
+ client: this.client,
punishment: 'unblocked',
reason: options.reason ?? undefined,
guild: this.guild,
@@ -812,7 +831,7 @@ export class ExtendedGuildMember extends GuildMember {
!([unblockResponse.ACTION_ERROR, unblockResponse.MODLOG_ERROR, unblockResponse.ACTION_ERROR] as const).includes(ret) &&
!options.silent
)
- client.emit(
+ this.client.emit(
'bushUnblock',
this,
moderator,
@@ -839,7 +858,7 @@ export class ExtendedGuildMember extends GuildMember {
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
- const moderator = await resolveNonCachedUser(options.moderator ?? this.guild.members.me);
+ const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
if (!moderator) return timeoutResponse.CANNOT_RESOLVE_USER;
const ret = await (async () => {
@@ -852,6 +871,7 @@ export class ExtendedGuildMember extends GuildMember {
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
+ client: this.client,
type: ModLogType.TIMEOUT,
user: this,
moderator: moderator.id,
@@ -876,7 +896,7 @@ export class ExtendedGuildMember extends GuildMember {
})();
if (!([timeoutResponse.ACTION_ERROR, timeoutResponse.MODLOG_ERROR] as const).includes(ret) && !options.silent)
- client.emit(
+ this.client.emit(
'bushTimeout',
this,
moderator,
@@ -901,7 +921,7 @@ export class ExtendedGuildMember extends GuildMember {
let caseID: string | undefined = undefined;
let dmSuccessEvent: boolean | undefined = undefined;
- const moderator = await resolveNonCachedUser(options.moderator ?? this.guild.members.me);
+ const moderator = await this.client.utils.resolveNonCachedUser(options.moderator ?? this.guild.members.me);
if (!moderator) return removeTimeoutResponse.CANNOT_RESOLVE_USER;
const ret = await (async () => {
@@ -913,6 +933,7 @@ export class ExtendedGuildMember extends GuildMember {
// add modlog entry
const { log: modlog } = await Moderation.createModLogEntry({
+ client: this.client,
type: ModLogType.REMOVE_TIMEOUT,
user: this,
moderator: moderator.id,
@@ -936,7 +957,7 @@ export class ExtendedGuildMember extends GuildMember {
})();
if (!([removeTimeoutResponse.ACTION_ERROR, removeTimeoutResponse.MODLOG_ERROR] as const).includes(ret) && !options.silent)
- client.emit(
+ this.client.emit(
'bushRemoveTimeout',
this,
moderator,
@@ -953,14 +974,14 @@ export class ExtendedGuildMember extends GuildMember {
* Whether or not the user is an owner of the bot.
*/
public override isOwner(): boolean {
- return client.isOwner(this);
+ return this.client.isOwner(this);
}
/**
* Whether or not the user is a super user of the bot.
*/
public override isSuperUser(): boolean {
- return client.isSuperUser(this);
+ return this.client.isSuperUser(this);
}
}
diff --git a/src/lib/extensions/discord.js/ExtendedMessage.ts b/src/lib/extensions/discord.js/ExtendedMessage.ts
index 4431077..0d8ce37 100644
--- a/src/lib/extensions/discord.js/ExtendedMessage.ts
+++ b/src/lib/extensions/discord.js/ExtendedMessage.ts
@@ -7,6 +7,6 @@ export class ExtendedMessage<Cached extends boolean = boolean> extends Message<C
public constructor(client_: Client, data: RawMessageData) {
super(client_, data);
- this.util = new CommandUtil(client.commandHandler, this);
+ this.util = new CommandUtil(this.client.commandHandler, this);
}
}
diff --git a/src/lib/extensions/discord.js/ExtendedUser.ts b/src/lib/extensions/discord.js/ExtendedUser.ts
index 556ab85..23de523 100644
--- a/src/lib/extensions/discord.js/ExtendedUser.ts
+++ b/src/lib/extensions/discord.js/ExtendedUser.ts
@@ -23,13 +23,13 @@ export class ExtendedUser extends User {
* Indicates whether the user is an owner of the bot.
*/
public override isOwner(): boolean {
- return client.isOwner(this);
+ return this.client.isOwner(this);
}
/**
* Indicates whether the user is a superuser of the bot.
*/
public override isSuperUser(): boolean {
- return client.isSuperUser(this);
+ return this.client.isSuperUser(this);
}
}
diff --git a/src/lib/extensions/global.ts b/src/lib/extensions/global.ts
index d9cfaec..a9020d7 100644
--- a/src/lib/extensions/global.ts
+++ b/src/lib/extensions/global.ts
@@ -1,11 +1,5 @@
/* eslint-disable no-var */
-import type { BushClient } from '#lib';
declare global {
- /**
- * The bushbot client.
- */
- var client: BushClient;
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface ReadonlyArray<T> {
includes<S, R extends `${Extract<S, string>}`>(
@@ -15,3 +9,5 @@ declare global {
): searchElement is R & S;
}
}
+
+export {};
diff --git a/src/lib/models/instance/Guild.ts b/src/lib/models/instance/Guild.ts
index 49bf822..7a19b72 100644
--- a/src/lib/models/instance/Guild.ts
+++ b/src/lib/models/instance/Guild.ts
@@ -199,12 +199,14 @@ const asGuildSetting = <T>(et: { [K in keyof T]: PartialBy<GuildSetting, 'config
return et as { [K in keyof T]: GuildSetting };
};
+const { default: config } = await import('../../../../config/options.js');
+
export const guildSettingsObj = asGuildSetting({
prefix: {
name: 'Prefix',
description: 'The phrase required to trigger text commands in this server.',
type: 'string',
- replaceNullWith: () => client.config.prefix
+ replaceNullWith: () => config.prefix
},
autoPublishChannels: {
name: 'Auto Publish Channels',
diff --git a/src/lib/utils/BushClientUtils.ts b/src/lib/utils/BushClientUtils.ts
new file mode 100644
index 0000000..44a08ef
--- /dev/null
+++ b/src/lib/utils/BushClientUtils.ts
@@ -0,0 +1,480 @@
+import assert from 'assert';
+import {
+ cleanCodeBlockContent,
+ escapeCodeBlock,
+ GuildMember,
+ Message,
+ Routes,
+ TextChannel,
+ ThreadMember,
+ User,
+ type APIMessage,
+ type Client,
+ type Snowflake,
+ type UserResolvable
+} from 'discord.js';
+import got from 'got';
+import _ from 'lodash';
+import CommandErrorListener from '../../listeners/commands/commandError.js';
+import { BushInspectOptions } from '../common/typings/BushInspectOptions.js';
+import { CodeBlockLang } from '../common/typings/CodeBlockLang.js';
+import { CommandMessage } from '../extensions/discord-akairo/BushCommand.js';
+import { SlashMessage } from '../extensions/discord-akairo/SlashMessage.js';
+import { Global } from '../models/shared/Global.js';
+import { Shared } from '../models/shared/Shared.js';
+import { GlobalCache, SharedCache } from './BushCache.js';
+import { emojis, Pronoun, PronounCode, pronounMapping, regex } from './BushConstants.js';
+import { addOrRemoveFromArray, formatError, inspect } from './BushUtils.js';
+
+/**
+ * Utilities that require access to the client.
+ */
+export class BushClientUtils {
+ /**
+ * The hastebin urls used to post to hastebin, attempts to post in order
+ */
+ #hasteURLs: string[] = [
+ 'https://hst.sh',
+ // 'https://hasteb.in',
+ 'https://hastebin.com',
+ 'https://mystb.in',
+ 'https://haste.clicksminuteper.net',
+ 'https://paste.pythondiscord.com',
+ 'https://haste.unbelievaboat.com'
+ // 'https://haste.tyman.tech'
+ ];
+
+ public constructor(private readonly client: Client) {}
+
+ /**
+ * Maps an array of user ids to user objects.
+ * @param ids The list of IDs to map
+ * @returns The list of users mapped
+ */
+ public async mapIDs(ids: Snowflake[]): Promise<User[]> {
+ return await Promise.all(ids.map((id) => this.client.users.fetch(id)));
+ }
+
+ /**
+ * Posts text to hastebin
+ * @param content The text to post
+ * @returns The url of the posted text
+ */
+ public async haste(content: string, substr = false): Promise<HasteResults> {
+ let isSubstr = false;
+ if (content.length > 400_000 && !substr) {
+ void this.handleError('haste', new Error(`content over 400,000 characters (${content.length.toLocaleString()})`));
+ return { error: 'content too long' };
+ } else if (content.length > 400_000) {
+ content = content.substring(0, 400_000);
+ isSubstr = true;
+ }
+ for (const url of this.#hasteURLs) {
+ try {
+ const res: HastebinRes = await got.post(`${url}/documents`, { body: content }).json();
+ return { url: `${url}/${res.key}`, error: isSubstr ? 'substr' : undefined };
+ } catch {
+ void this.client.console.error('haste', `Unable to upload haste to ${url}`);
+ }
+ }
+ return { error: 'unable to post' };
+ }
+
+ /**
+ * Resolves a user-provided string into a user object, if possible
+ * @param text The text to try and resolve
+ * @returns The user resolved or null
+ */
+ public async resolveUserAsync(text: string): Promise<User | null> {
+ const idReg = /\d{17,19}/;
+ const idMatch = text.match(idReg);
+ if (idMatch) {
+ try {
+ return await this.client.users.fetch(text as Snowflake);
+ } catch {}
+ }
+ const mentionReg = /<@!?(?<id>\d{17,19})>/;
+ const mentionMatch = text.match(mentionReg);
+ if (mentionMatch) {
+ try {
+ return await this.client.users.fetch(mentionMatch.groups!.id as Snowflake);
+ } catch {}
+ }
+ const user = this.client.users.cache.find((u) => u.username === text);
+ if (user) return user;
+ return null;
+ }
+
+ /**
+ * Surrounds text in a code block with the specified language and puts it in a hastebin if its too long.
+ * * Embed Description Limit = 4096 characters
+ * * Embed Field Limit = 1024 characters
+ * @param code The content of the code block.
+ * @param length The maximum length of the code block.
+ * @param language The language of the code.
+ * @param substr Whether or not to substring the code if it is too long.
+ * @returns The generated code block
+ */
+ public async codeblock(code: string, length: number, language: CodeBlockLang | '' = '', substr = false): Promise<string> {
+ let hasteOut = '';
+ code = escapeCodeBlock(code);
+ const prefix = `\`\`\`${language}\n`;
+ const suffix = '\n```';
+ if (code.length + (prefix + suffix).length >= length) {
+ const haste_ = await this.haste(code, substr);
+ hasteOut = `Too large to display. ${
+ haste_.url
+ ? `Hastebin: ${haste_.url}${language ? `.${language}` : ''}${haste_.error ? ` - ${haste_.error}` : ''}`
+ : `${emojis.error} Hastebin: ${haste_.error}`
+ }`;
+ }
+
+ const FormattedHaste = hasteOut.length ? `\n${hasteOut}` : '';
+ const shortenedCode = hasteOut ? code.substring(0, length - (prefix + FormattedHaste + suffix).length) : code;
+ const code3 = code.length ? prefix + shortenedCode + suffix + FormattedHaste : prefix + suffix;
+ if (code3.length > length) {
+ void this.client.console.warn(`codeblockError`, `Required Length: ${length}. Actual Length: ${code3.length}`, true);
+ void this.client.console.warn(`codeblockError`, code3, true);
+ throw new Error('code too long');
+ }
+ return code3;
+ }
+
+ /**
+ * Maps the key of a credential with a readable version when redacting.
+ * @param key The key of the credential.
+ * @returns The readable version of the key or the original key if there isn't a mapping.
+ */
+ #mapCredential(key: string): string {
+ const mapping = {
+ token: 'Main Token',
+ devToken: 'Dev Token',
+ betaToken: 'Beta Token',
+ hypixelApiKey: 'Hypixel Api Key',
+ wolframAlphaAppId: 'Wolfram|Alpha App ID',
+ dbPassword: 'Database Password'
+ };
+ return mapping[key as keyof typeof mapping] || key;
+ }
+
+ /**
+ * Redacts credentials from a string.
+ * @param text The text to redact credentials from.
+ * @returns The redacted text.
+ */
+ public redact(text: string) {
+ for (const credentialName in { ...this.client.config.credentials, dbPassword: this.client.config.db.password }) {
+ const credential = { ...this.client.config.credentials, dbPassword: this.client.config.db.password }[
+ credentialName as keyof typeof this.client.config.credentials
+ ];
+ const replacement = this.#mapCredential(credentialName);
+ const escapeRegex = /[.*+?^${}()|[\]\\]/g;
+ text = text.replace(new RegExp(credential.toString().replace(escapeRegex, '\\$&'), 'g'), `[${replacement} Omitted]`);
+ text = text.replace(
+ new RegExp([...credential.toString()].reverse().join('').replace(escapeRegex, '\\$&'), 'g'),
+ `[${replacement} Omitted]`
+ );
+ }
+ return text;
+ }
+
+ /**
+ * Takes an any value, inspects it, redacts credentials, and puts it in a codeblock
+ * (and uploads to hast if the content is too long).
+ * @param input The object to be inspect, redacted, and put into a codeblock.
+ * @param language The language to make the codeblock.
+ * @param inspectOptions The options for {@link BushClientUtil.inspect}.
+ * @param length The maximum length that the codeblock can be.
+ * @returns The generated codeblock.
+ */
+ public async inspectCleanRedactCodeblock(
+ input: any,
+ language?: CodeBlockLang | '',
+ inspectOptions?: BushInspectOptions,
+ length = 1024
+ ) {
+ input = inspect(input, inspectOptions ?? undefined);
+ if (inspectOptions) inspectOptions.inspectStrings = undefined;
+ input = cleanCodeBlockContent(input);
+ input = this.redact(input);
+ return this.codeblock(input, length, language, true);
+ }
+
+ /**
+ * Takes an any value, inspects it, redacts credentials, and uploads it to haste.
+ * @param input The object to be inspect, redacted, and upload.
+ * @param inspectOptions The options for {@link BushClientUtil.inspect}.
+ * @returns The {@link HasteResults}.
+ */
+ public async inspectCleanRedactHaste(input: any, inspectOptions?: BushInspectOptions): Promise<HasteResults> {
+ input = inspect(input, inspectOptions ?? undefined);
+ input = this.redact(input);
+ return this.haste(input, true);
+ }
+
+ /**
+ * Takes an any value, inspects it and redacts credentials.
+ * @param input The object to be inspect and redacted.
+ * @param inspectOptions The options for {@link BushClientUtil.inspect}.
+ * @returns The redacted and inspected object.
+ */
+ public inspectAndRedact(input: any, inspectOptions?: BushInspectOptions): string {
+ input = inspect(input, inspectOptions ?? undefined);
+ return this.redact(input);
+ }
+
+ /**
+ * Get the global cache.
+ */
+ public getGlobal(): GlobalCache;
+ /**
+ * Get a key from the global cache.
+ * @param key The key to get in the global cache.
+ */
+ public getGlobal<K extends keyof GlobalCache>(key: K): GlobalCache[K];
+ public getGlobal(key?: keyof GlobalCache) {
+ return key ? this.client.cache.global[key] : this.client.cache.global;
+ }
+
+ /**
+ * Get the shared cache.
+ */
+ public getShared(): SharedCache;
+ /**
+ * Get a key from the shared cache.
+ * @param key The key to get in the shared cache.
+ */
+ public getShared<K extends keyof SharedCache>(key: K): SharedCache[K];
+ public getShared(key?: keyof SharedCache) {
+ return key ? this.client.cache.shared[key] : this.client.cache.shared;
+ }
+
+ /**
+ * Add or remove an element from an array stored in the Globals database.
+ * @param action Either `add` or `remove` an element.
+ * @param key The key of the element in the global cache to update.
+ * @param value The value to add/remove from the array.
+ */
+ public async insertOrRemoveFromGlobal<K extends keyof Client['cache']['global']>(
+ action: 'add' | 'remove',
+ key: K,
+ value: Client['cache']['global'][K][0]
+ ): Promise<Global | void> {
+ const row =
+ (await Global.findByPk(this.client.config.environment)) ??
+ (await Global.create({ environment: this.client.config.environment }));
+ const oldValue: any[] = row[key];
+ const newValue = addOrRemoveFromArray(action, oldValue, value);
+ row[key] = newValue;
+ this.client.cache.global[key] = newValue;
+ return await row.save().catch((e) => this.handleError('insertOrRemoveFromGlobal', e));
+ }
+
+ /**
+ * Add or remove an element from an array stored in the Shared database.
+ * @param action Either `add` or `remove` an element.
+ * @param key The key of the element in the shared cache to update.
+ * @param value The value to add/remove from the array.
+ */
+ public async insertOrRemoveFromShared<K extends Exclude<keyof Client['cache']['shared'], 'badWords' | 'autoBanCode'>>(
+ action: 'add' | 'remove',
+ key: K,
+ value: Client['cache']['shared'][K][0]
+ ): Promise<Shared | void> {
+ const row = (await Shared.findByPk(0)) ?? (await Shared.create());
+ const oldValue: any[] = row[key];
+ const newValue = addOrRemoveFromArray(action, oldValue, value);
+ row[key] = newValue;
+ this.client.cache.shared[key] = newValue;
+ return await row.save().catch((e) => this.handleError('insertOrRemoveFromShared', e));
+ }
+
+ /**
+ * Updates an element in the Globals database.
+ * @param key The key in the global cache to update.
+ * @param value The value to set the key to.
+ */
+ public async setGlobal<K extends keyof Client['cache']['global']>(
+ key: K,
+ value: Client['cache']['global'][K]
+ ): Promise<Global | void> {
+ const row =
+ (await Global.findByPk(this.client.config.environment)) ??
+ (await Global.create({ environment: this.client.config.environment }));
+ row[key] = value;
+ this.client.cache.global[key] = value;
+ return await row.save().catch((e) => this.handleError('setGlobal', e));
+ }
+
+ /**
+ * Updates an element in the Shared database.
+ * @param key The key in the shared cache to update.
+ * @param value The value to set the key to.
+ */
+ public async setShared<K extends Exclude<keyof Client['cache']['shared'], 'badWords' | 'autoBanCode'>>(
+ key: K,
+ value: Client['cache']['shared'][K]
+ ): Promise<Shared | void> {
+ const row = (await Shared.findByPk(0)) ?? (await Shared.create());
+ row[key] = value;
+ this.client.cache.shared[key] = value;
+ return await row.save().catch((e) => this.handleError('setShared', e));
+ }
+
+ /**
+ * Send a message in the error logging channel and console for an error.
+ * @param context
+ * @param error
+ */
+ public async handleError(context: string, error: Error) {
+ await this.client.console.error(_.camelCase(context), `An error occurred:\n${formatError(error, false)}`, false);
+ await this.client.console.channelError({
+ embeds: await CommandErrorListener.generateErrorEmbed(this.client, { type: 'unhandledRejection', error: error, context })
+ });
+ }
+
+ /**
+ * Fetches a user from discord.
+ * @param user The user to fetch
+ * @returns Undefined if the user is not found, otherwise the user.
+ */
+ public async resolveNonCachedUser(user: UserResolvable | undefined | null): Promise<User | undefined> {
+ if (user == null) return undefined;
+ const resolvedUser =
+ user instanceof User
+ ? user
+ : user instanceof GuildMember
+ ? user.user
+ : user instanceof ThreadMember
+ ? user.user
+ : user instanceof Message
+ ? user.author
+ : undefined;
+
+ return resolvedUser ?? (await this.client.users.fetch(user as Snowflake).catch(() => undefined));
+ }
+
+ /**
+ * Get the pronouns of a discord user from pronoundb.org
+ * @param user The user to retrieve the promises of.
+ * @returns The human readable pronouns of the user, or undefined if they do not have any.
+ */
+ public async getPronounsOf(user: User | Snowflake): Promise<Pronoun | undefined> {
+ const _user = await this.resolveNonCachedUser(user);
+ if (!_user) throw new Error(`Cannot find user ${user}`);
+ const apiRes = (await got
+ .get(`https://pronoundb.org/api/v1/lookup?platform=discord&id=${_user.id}`)
+ .json()
+ .catch(() => undefined)) as { pronouns: PronounCode } | undefined;
+
+ if (!apiRes) return undefined;
+ assert(apiRes.pronouns);
+
+ return pronounMapping[apiRes.pronouns!]!;
+ }
+
+ /**
+ * Uploads an image to imgur.
+ * @param image The image to upload.
+ * @returns The url of the imgur.
+ */
+ public async uploadImageToImgur(image: string) {
+ const clientId = this.client.config.credentials.imgurClientId;
+
+ const resp = (await got
+ .post('https://api.imgur.com/3/upload', {
+ headers: {
+ Authorization: `Client-ID ${clientId}`,
+ Accept: 'application/json'
+ },
+ form: {
+ image: image,
+ type: 'base64'
+ },
+ followRedirect: true
+ })
+ .json()) as { data: { link: string } };
+
+ return resp.data.link;
+ }
+
+ /**
+ * Gets the prefix based off of the message.
+ * @param message The message to get the prefix from.
+ * @returns The prefix.
+ */
+ public prefix(message: CommandMessage | SlashMessage): string {
+ return message.util.isSlash
+ ? '/'
+ : this.client.config.isDevelopment
+ ? 'dev '
+ : message.util.parsed?.prefix ?? this.client.config.prefix;
+ }
+
+ public async resolveMessageLinks(content: string | null): Promise<MessageLinkParts[]> {
+ const res: MessageLinkParts[] = [];
+
+ if (!content) return res;
+
+ const regex_ = new RegExp(regex.messageLink);
+ let match: RegExpExecArray | null;
+ while (((match = regex_.exec(content)), match !== null)) {
+ const input = match.input;
+ if (!match.groups || !input) continue;
+ if (input.startsWith('<') && input.endsWith('>')) continue;
+
+ const { guild_id, channel_id, message_id } = match.groups;
+ if (!guild_id || !channel_id || !message_id) continue;
+
+ res.push({ guild_id, channel_id, message_id });
+ }
+
+ return res;
+ }
+
+ public async resolveMessagesFromLinks(content: string): Promise<APIMessage[]> {
+ const res: APIMessage[] = [];
+
+ const links = await this.resolveMessageLinks(content);
+ if (!links.length) return [];
+
+ for (const { guild_id, channel_id, message_id } of links) {
+ const guild = this.client.guilds.cache.get(guild_id);
+ if (!guild) continue;
+ const channel = guild.channels.cache.get(channel_id);
+ if (!channel || (!channel.isTextBased() && !channel.isThread())) continue;
+
+ const message = (await this.client.rest
+ .get(Routes.channelMessage(channel_id, message_id))
+ .catch(() => null)) as APIMessage | null;
+ if (!message) continue;
+
+ res.push(message);
+ }
+
+ return res;
+ }
+
+ /**
+ * Gets a a configured channel as a TextChannel.
+ * @channel The channel to retrieve.
+ */
+ public async getConfigChannel(channel: keyof Client['config']['channels']): Promise<TextChannel> {
+ return (await this.client.channels.fetch(this.client.config.channels[channel])) as unknown as TextChannel;
+ }
+}
+
+interface HastebinRes {
+ key: string;
+}
+
+export interface HasteResults {
+ url?: string;
+ error?: 'content too long' | 'substr' | 'unable to post';
+}
+
+export interface MessageLinkParts {
+ guild_id: Snowflake;
+ channel_id: Snowflake;
+ message_id: Snowflake;
+}
diff --git a/src/lib/utils/BushLogger.ts b/src/lib/utils/BushLogger.ts
index 7d42574..1be58a4 100644
--- a/src/lib/utils/BushLogger.ts
+++ b/src/lib/utils/BushLogger.ts
@@ -1,11 +1,11 @@
import chalk from 'chalk';
// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import { EmbedBuilder, escapeMarkdown, PartialTextBasedChannelFields, type Message } from 'discord.js';
+import { Client, EmbedBuilder, escapeMarkdown, PartialTextBasedChannelFields, type Message } from 'discord.js';
import repl, { REPLServer, REPL_MODE_STRICT } from 'repl';
import { WriteStream } from 'tty';
import { type SendMessageType } from '../extensions/discord-akairo/BushClient.js';
import { colors } from './BushConstants.js';
-import { getConfigChannel, inspect } from './BushUtils.js';
+import { inspect } from './BushUtils.js';
let REPL: REPLServer;
let replGone = false;
@@ -131,7 +131,14 @@ function getTimeStamp(): string {
/**
* Custom logging utility for the bot.
*/
-export default {
+export class BushLogger {
+ public constructor(
+ /**
+ * The client.
+ */
+ public client: Client
+ ) {}
+
/**
* Logs information. Highlight information by surrounding it in `<<>>`.
* @param header The header displayed before the content, displayed in cyan.
@@ -139,27 +146,27 @@ export default {
* @param sendChannel Should this also be logged to discord? Defaults to false.
* @param depth The depth the content will inspected. Defaults to 0.
*/
- get log() {
+ public get log() {
return this.info;
- },
+ }
/**
* Sends a message to the log channel.
* @param message The parameter to pass to {@link PartialTextBasedChannelFields.send}.
* @returns The message sent.
*/
- async channelLog(message: SendMessageType): Promise<Message | null> {
- const channel = await getConfigChannel('log');
+ public async channelLog(message: SendMessageType): Promise<Message | null> {
+ const channel = await this.client.utils.getConfigChannel('log');
return await channel.send(message).catch(() => null);
- },
+ }
/**
* Sends a message to the error channel.
* @param message The parameter to pass to {@link PartialTextBasedChannelFields.send}.
* @returns The message sent.
*/
- async channelError(message: SendMessageType): Promise<Message | null> {
- const channel = await getConfigChannel('error');
+ public async channelError(message: SendMessageType): Promise<Message | null> {
+ const channel = await this.client.utils.getConfigChannel('error');
if (!channel) {
void this.error(
'BushLogger',
@@ -171,27 +178,27 @@ export default {
return null;
}
return await channel.send(message);
- },
+ }
/**
* Logs debug information. Only works in dev is enabled in the config.
* @param content The content to log.
* @param depth The depth the content will inspected. Defaults to `0`.
*/
- debug(content: any, depth = 0): void {
- if (!client.config.isDevelopment) return;
+ public debug(content: any, depth = 0): void {
+ if (!this.client.config.isDevelopment) return;
const newContent = inspectContent(content, depth, true);
console.log(`${chalk.bgMagenta(getTimeStamp())} ${chalk.magenta('[Debug]')} ${newContent}`);
- },
+ }
/**
* Logs raw debug information. Only works in dev is enabled in the config.
* @param content The content to log.
*/
- debugRaw(...content: any): void {
- if (!client.config.isDevelopment) return;
+ public debugRaw(...content: any): void {
+ if (!this.client.config.isDevelopment) return;
console.log(`${chalk.bgMagenta(getTimeStamp())} ${chalk.magenta('[Debug]')}`, ...content);
- },
+ }
/**
* Logs verbose information. Highlight information by surrounding it in `<<>>`.
@@ -200,8 +207,8 @@ export default {
* @param sendChannel Should this also be logged to discord? Defaults to `false`.
* @param depth The depth the content will inspected. Defaults to `0`.
*/
- async verbose(header: string, content: any, sendChannel = false, depth = 0): Promise<void> {
- if (!client.config.logging.verbose) return;
+ public async verbose(header: string, content: any, sendChannel = false, depth = 0): Promise<void> {
+ if (!this.client.config.logging.verbose) return;
const newContent = inspectContent(content, depth, true);
console.log(`${chalk.bgGrey(getTimeStamp())} ${chalk.grey(`[${header}]`)} ${parseFormatting(newContent, 'blackBright')}`);
if (!sendChannel) return;
@@ -210,7 +217,7 @@ export default {
.setColor(colors.gray)
.setTimestamp();
await this.channelLog({ embeds: [embed] });
- },
+ }
/**
* Logs very verbose information. Highlight information by surrounding it in `<<>>`.
@@ -218,23 +225,23 @@ export default {
* @param content The content to log, highlights displayed in bright black.
* @param depth The depth the content will inspected. Defaults to `0`.
*/
- async superVerbose(header: string, content: any, depth = 0): Promise<void> {
- if (!client.config.logging.verbose) return;
+ public async superVerbose(header: string, content: any, depth = 0): Promise<void> {
+ if (!this.client.config.logging.verbose) return;
const newContent = inspectContent(content, depth, true);
console.log(
`${chalk.bgHex('#949494')(getTimeStamp())} ${chalk.hex('#949494')(`[${header}]`)} ${chalk.hex('#b3b3b3')(newContent)}`
);
- },
+ }
/**
* Logs raw very verbose information.
* @param header The header printed before the content, displayed in purple.
* @param content The content to log.
*/
- async superVerboseRaw(header: string, ...content: any[]): Promise<void> {
- if (!client.config.logging.verbose) return;
+ public async superVerboseRaw(header: string, ...content: any[]): Promise<void> {
+ if (!this.client.config.logging.verbose) return;
console.log(`${chalk.bgHex('#a3a3a3')(getTimeStamp())} ${chalk.hex('#a3a3a3')(`[${header}]`)}`, ...content);
- },
+ }
/**
* Logs information. Highlight information by surrounding it in `<<>>`.
@@ -243,8 +250,8 @@ export default {
* @param sendChannel Should this also be logged to discord? Defaults to `false`.
* @param depth The depth the content will inspected. Defaults to `0`.
*/
- async info(header: string, content: any, sendChannel = true, depth = 0): Promise<void> {
- if (!client.config.logging.info) return;
+ public async info(header: string, content: any, sendChannel = true, depth = 0): Promise<void> {
+ if (!this.client.config.logging.info) return;
const newContent = inspectContent(content, depth, true);
console.log(`${chalk.bgCyan(getTimeStamp())} ${chalk.cyan(`[${header}]`)} ${parseFormatting(newContent, 'blueBright')}`);
if (!sendChannel) return;
@@ -253,7 +260,7 @@ export default {
.setColor(colors.info)
.setTimestamp();
await this.channelLog({ embeds: [embed] });
- },
+ }
/**
* Logs warnings. Highlight information by surrounding it in `<<>>`.
@@ -262,7 +269,7 @@ export default {
* @param sendChannel Should this also be logged to discord? Defaults to `false`.
* @param depth The depth the content will inspected. Defaults to `0`.
*/
- async warn(header: string, content: any, sendChannel = true, depth = 0): Promise<void> {
+ public async warn(header: string, content: any, sendChannel = true, depth = 0): Promise<void> {
const newContent = inspectContent(content, depth, true);
console.warn(
`${chalk.bgYellow(getTimeStamp())} ${chalk.yellow(`[${header}]`)} ${parseFormatting(newContent, 'yellowBright')}`
@@ -274,7 +281,7 @@ export default {
.setColor(colors.warn)
.setTimestamp();
await this.channelError({ embeds: [embed] });
- },
+ }
/**
* Logs errors. Highlight information by surrounding it in `<<>>`.
@@ -283,7 +290,7 @@ export default {
* @param sendChannel Should this also be logged to discord? Defaults to `false`.
* @param depth The depth the content will inspected. Defaults to `0`.
*/
- async error(header: string, content: any, sendChannel = true, depth = 0): Promise<void> {
+ public async error(header: string, content: any, sendChannel = true, depth = 0): Promise<void> {
const newContent = inspectContent(content, depth, true);
console.warn(
`${chalk.bgRedBright(getTimeStamp())} ${chalk.redBright(`[${header}]`)} ${parseFormatting(newContent, 'redBright')}`
@@ -295,7 +302,7 @@ export default {
.setTimestamp();
await this.channelError({ embeds: [embed] });
return;
- },
+ }
/**
* Logs successes. Highlight information by surrounding it in `<<>>`.
@@ -304,7 +311,7 @@ export default {
* @param sendChannel Should this also be logged to discord? Defaults to `false`.
* @param depth The depth the content will inspected. Defaults to `0`.
*/
- async success(header: string, content: any, sendChannel = true, depth = 0): Promise<void> {
+ public async success(header: string, content: any, sendChannel = true, depth = 0): Promise<void> {
const newContent = inspectContent(content, depth, true);
console.log(
`${chalk.bgGreen(getTimeStamp())} ${chalk.greenBright(`[${header}]`)} ${parseFormatting(newContent, 'greenBright')}`
@@ -316,6 +323,6 @@ export default {
.setTimestamp();
await this.channelLog({ embeds: [embed] }).catch(() => {});
}
-};
+}
/** @typedef {PartialTextBasedChannelFields} vscodeDontDeleteMyImportTy */
diff --git a/src/lib/utils/BushUtils.ts b/src/lib/utils/BushUtils.ts
index 8a84d80..a6463cf 100644
--- a/src/lib/utils/BushUtils.ts
+++ b/src/lib/utils/BushUtils.ts
@@ -1,22 +1,12 @@
import {
Arg,
BushClient,
- CodeBlockLang,
CommandMessage,
- emojis,
- Global,
- Pronoun,
- pronounMapping,
- regex,
- Shared,
SlashEditMessageType,
SlashSendMessageType,
timeUnits,
type BaseBushArgumentType,
type BushInspectOptions,
- type GlobalCache,
- type PronounCode,
- type SharedCache,
type SlashMessage
} from '#lib';
import { humanizeDuration as humanizeDurationMod } from '@notenoughupdates/humanize-duration';
@@ -25,59 +15,25 @@ import { exec } from 'child_process';
import deepLock from 'deep-lock';
import { Util as AkairoUtil } from 'discord-akairo';
import {
- cleanCodeBlockContent,
Constants as DiscordConstants,
EmbedBuilder,
- escapeCodeBlock,
- GuildMember,
Message,
OAuth2Scopes,
PermissionFlagsBits,
PermissionsBitField,
- Routes,
- ThreadMember,
- User,
- UserResolvable,
type APIEmbed,
type APIMessage,
type CommandInteraction,
type InteractionReplyOptions,
- type PermissionsString,
- type Snowflake,
- type TextChannel
+ type PermissionsString
} from 'discord.js';
import got from 'got';
-import _ from 'lodash';
import { inspect as inspectUtil, promisify } from 'util';
-import CommandErrorListener from '../../listeners/commands/commandError.js';
import * as Format from '../common/util/Format.js';
export type StripPrivate<T> = { [K in keyof T]: T[K] extends Record<string, any> ? StripPrivate<T[K]> : T[K] };
/**
- * The hastebin urls used to post to hastebin, attempts to post in order
- */
-const hasteURLs: string[] = [
- 'https://hst.sh',
- // 'https://hasteb.in',
- 'https://hastebin.com',
- 'https://mystb.in',
- 'https://haste.clicksminuteper.net',
- 'https://paste.pythondiscord.com',
- 'https://haste.unbelievaboat.com'
- // 'https://haste.tyman.tech'
-];
-
-/**
- * Maps an array of user ids to user objects.
- * @param ids The list of IDs to map
- * @returns The list of users mapped
- */
-export async function mapIDs(ids: Snowflake[]): Promise<User[]> {
- return await Promise.all(ids.map((id) => client.users.fetch(id)));
-}
-
-/**
* Capitalizes the first letter of the given text
* @param text The text to capitalize
* @returns The capitalized text
@@ -96,60 +52,6 @@ export async function shell(command: string): Promise<{ stdout: string; stderr:
}
/**
- * Posts text to hastebin
- * @param content The text to post
- * @returns The url of the posted text
- */
-export async function haste(content: string, substr = false): Promise<HasteResults> {
- let isSubstr = false;
- if (content.length > 400_000 && !substr) {
- void handleError('haste', new Error(`content over 400,000 characters (${content.length.toLocaleString()})`));
- return { error: 'content too long' };
- } else if (content.length > 400_000) {
- content = content.substring(0, 400_000);
- isSubstr = true;
- }
- for (const url of hasteURLs) {
- try {
- const res: HastebinRes = await got.post(`${url}/documents`, { body: content }).json();
- return { url: `${url}/${res.key}`, error: isSubstr ? 'substr' : undefined };
- } catch {
- void client.console.error('haste', `Unable to upload haste to ${url}`);
- }
- }
- return { error: 'unable to post' };
-}
-
-/**
- * Resolves a user-provided string into a user object, if possible
- * @param text The text to try and resolve
- * @returns The user resolved or null
- */
-export async function resolveUserAsync(text: string): Promise<User | null> {
- const idReg = /\d{17,19}/;
- const idMatch = text.match(idReg);
- if (idMatch) {
- try {
- return await client.users.fetch(text as Snowflake);
- } catch {
- // pass
- }
- }
- const mentionReg = /<@!?(?<id>\d{17,19})>/;
- const mentionMatch = text.match(mentionReg);
- if (mentionMatch) {
- try {
- return await client.users.fetch(mentionMatch.groups!.id as Snowflake);
- } catch {
- // pass
- }
- }
- const user = client.users.cache.find((u) => u.username === text);
- if (user) return user;
- return null;
-}
-
-/**
* Appends the correct ordinal to the given number
* @param n The number to append an ordinal to
* @returns The number with the ordinal
@@ -185,46 +87,6 @@ export async function mcUUID(username: string, dashed = false): Promise<string>
}
/**
- * Surrounds text in a code block with the specified language and puts it in a hastebin if its too long.
- * * Embed Description Limit = 4096 characters
- * * Embed Field Limit = 1024 characters
- * @param code The content of the code block.
- * @param length The maximum length of the code block.
- * @param language The language of the code.
- * @param substr Whether or not to substring the code if it is too long.
- * @returns The generated code block
- */
-export async function codeblock(
- code: string,
- length: number,
- language: CodeBlockLang | '' = '',
- substr = false
-): Promise<string> {
- let hasteOut = '';
- code = escapeCodeBlock(code);
- const prefix = `\`\`\`${language}\n`;
- const suffix = '\n```';
- if (code.length + (prefix + suffix).length >= length) {
- const haste_ = await haste(code, substr);
- hasteOut = `Too large to display. ${
- haste_.url
- ? `Hastebin: ${haste_.url}${language ? `.${language}` : ''}${haste_.error ? ` - ${haste_.error}` : ''}`
- : `${emojis.error} Hastebin: ${haste_.error}`
- }`;
- }
-
- const FormattedHaste = hasteOut.length ? `\n${hasteOut}` : '';
- const shortenedCode = hasteOut ? code.substring(0, length - (prefix + FormattedHaste + suffix).length) : code;
- const code3 = code.length ? prefix + shortenedCode + suffix + FormattedHaste : prefix + suffix;
- if (code3.length > length) {
- void client.console.warn(`codeblockError`, `Required Length: ${length}. Actual Length: ${code3.length}`, true);
- void client.console.warn(`codeblockError`, code3, true);
- throw new Error('code too long');
- }
- return code3;
-}
-
-/**
* Generate defaults for {@link inspect}.
* @param options The options to create defaults with.
* @returns The default options combined with the specified options.
@@ -246,44 +108,6 @@ function getDefaultInspectOptions(options?: BushInspectOptions): BushInspectOpti
}
/**
- * Maps the key of a credential with a readable version when redacting.
- * @param key The key of the credential.
- * @returns The readable version of the key or the original key if there isn't a mapping.
- */
-function mapCredential(key: string): string {
- const mapping = {
- token: 'Main Token',
- devToken: 'Dev Token',
- betaToken: 'Beta Token',
- hypixelApiKey: 'Hypixel Api Key',
- wolframAlphaAppId: 'Wolfram|Alpha App ID',
- dbPassword: 'Database Password'
- };
- return mapping[key as keyof typeof mapping] || key;
-}
-
-/**
- * Redacts credentials from a string.
- * @param text The text to redact credentials from.
- * @returns The redacted text.
- */
-export function redact(text: string) {
- for (const credentialName in { ...client.config.credentials, dbPassword: client.config.db.password }) {
- const credential = { ...client.config.credentials, dbPassword: client.config.db.password }[
- credentialName as keyof typeof client.config.credentials
- ];
- const replacement = mapCredential(credentialName);
- const escapeRegex = /[.*+?^${}()|[\]\\]/g;
- text = text.replace(new RegExp(credential.toString().replace(escapeRegex, '\\$&'), 'g'), `[${replacement} Omitted]`);
- text = text.replace(
- new RegExp([...credential.toString()].reverse().join('').replace(escapeRegex, '\\$&'), 'g'),
- `[${replacement} Omitted]`
- );
- }
- return text;
-}
-
-/**
* Uses {@link inspect} with custom defaults.
* @param object - The object you would like to inspect.
* @param options - The options you would like to use to inspect the object.
@@ -298,51 +122,6 @@ export function inspect(object: any, options?: BushInspectOptions): string {
}
/**
- * Takes an any value, inspects it, redacts credentials, and puts it in a codeblock
- * (and uploads to hast if the content is too long).
- * @param input The object to be inspect, redacted, and put into a codeblock.
- * @param language The language to make the codeblock.
- * @param inspectOptions The options for {@link BushClientUtil.inspect}.
- * @param length The maximum length that the codeblock can be.
- * @returns The generated codeblock.
- */
-export async function inspectCleanRedactCodeblock(
- input: any,
- language?: CodeBlockLang | '',
- inspectOptions?: BushInspectOptions,
- length = 1024
-) {
- input = inspect(input, inspectOptions ?? undefined);
- if (inspectOptions) inspectOptions.inspectStrings = undefined;
- input = cleanCodeBlockContent(input);
- input = redact(input);
- return codeblock(input, length, language, true);
-}
-
-/**
- * Takes an any value, inspects it, redacts credentials, and uploads it to haste.
- * @param input The object to be inspect, redacted, and upload.
- * @param inspectOptions The options for {@link BushClientUtil.inspect}.
- * @returns The {@link HasteResults}.
- */
-export async function inspectCleanRedactHaste(input: any, inspectOptions?: BushInspectOptions): Promise<HasteResults> {
- input = inspect(input, inspectOptions ?? undefined);
- input = redact(input);
- return haste(input, true);
-}
-
-/**
- * Takes an any value, inspects it and redacts credentials.
- * @param input The object to be inspect and redacted.
- * @param inspectOptions The options for {@link BushClientUtil.inspect}.
- * @returns The redacted and inspected object.
- */
-export function inspectAndRedact(input: any, inspectOptions?: BushInspectOptions): string {
- input = inspect(input, inspectOptions ?? undefined);
- return redact(input);
-}
-
-/**
* Responds to a slash command interaction.
* @param interaction The interaction to respond to.
* @param responseOptions The options for the response.
@@ -363,14 +142,6 @@ export async function slashRespond(
}
/**
- * Gets a a configured channel as a TextChannel.
- * @channel The channel to retrieve.
- */
-export async function getConfigChannel(channel: keyof typeof client['config']['channels']): Promise<TextChannel> {
- return (await client.channels.fetch(client.config.channels[channel])) as unknown as TextChannel;
-}
-
-/**
* Takes an array and combines the elements using the supplied conjunction.
* @param array The array to combine.
* @param conjunction The conjunction to use.
@@ -392,93 +163,6 @@ export function oxford(array: string[], conjunction: string, ifEmpty?: string):
}
/**
- * Get the global cache.
- */
-export function getGlobal(): GlobalCache;
-/**
- * Get a key from the global cache.
- * @param key The key to get in the global cache.
- */
-export function getGlobal<K extends keyof GlobalCache>(key: K): GlobalCache[K];
-export function getGlobal(key?: keyof GlobalCache) {
- return key ? client.cache.global[key] : client.cache.global;
-}
-
-export function getShared(): SharedCache;
-export function getShared<K extends keyof SharedCache>(key: K): SharedCache[K];
-export function getShared(key?: keyof SharedCache) {
- return key ? client.cache.shared[key] : client.cache.shared;
-}
-
-/**
- * Add or remove an element from an array stored in the Globals database.
- * @param action Either `add` or `remove` an element.
- * @param key The key of the element in the global cache to update.
- * @param value The value to add/remove from the array.
- */
-export async function insertOrRemoveFromGlobal<K extends keyof typeof client['cache']['global']>(
- action: 'add' | 'remove',
- key: K,
- value: typeof client['cache']['global'][K][0]
-): Promise<Global | void> {
- const row =
- (await Global.findByPk(client.config.environment)) ?? (await Global.create({ environment: client.config.environment }));
- const oldValue: any[] = row[key];
- const newValue = addOrRemoveFromArray(action, oldValue, value);
- row[key] = newValue;
- client.cache.global[key] = newValue;
- return await row.save().catch((e) => handleError('insertOrRemoveFromGlobal', e));
-}
-
-/**
- * Add or remove an element from an array stored in the Shared database.
- * @param action Either `add` or `remove` an element.
- * @param key The key of the element in the shared cache to update.
- * @param value The value to add/remove from the array.
- */
-export async function insertOrRemoveFromShared<
- K extends Exclude<keyof typeof client['cache']['shared'], 'badWords' | 'autoBanCode'>
->(action: 'add' | 'remove', key: K, value: typeof client['cache']['shared'][K][0]): Promise<Shared | void> {
- const row = (await Shared.findByPk(0)) ?? (await Shared.create());
- const oldValue: any[] = row[key];
- const newValue = addOrRemoveFromArray(action, oldValue, value);
- row[key] = newValue;
- client.cache.shared[key] = newValue;
- return await row.save().catch((e) => handleError('insertOrRemoveFromShared', e));
-}
-
-/**
- * Updates an element in the Globals database.
- * @param key The key in the global cache to update.
- * @param value The value to set the key to.
- */
-export async function setGlobal<K extends keyof typeof client['cache']['global']>(
- key: K,
- value: typeof client['cache']['global'][K]
-): Promise<Global | void> {
- const row =
- (await Global.findByPk(client.config.environment)) ?? (await Global.create({ environment: client.config.environment }));
- row[key] = value;
- client.cache.global[key] = value;
- return await row.save().catch((e) => handleError('setGlobal', e));
-}
-
-/**
- * Updates an element in the Shared database.
- * @param key The key in the shared cache to update.
- * @param value The value to set the key to.
- */
-export async function setShared<K extends Exclude<keyof typeof client['cache']['shared'], 'badWords' | 'autoBanCode'>>(
- key: K,
- value: typeof client['cache']['shared'][K]
-): Promise<Shared | void> {
- const row = (await Shared.findByPk(0)) ?? (await Shared.create());
- row[key] = value;
- client.cache.shared[key] = value;
- return await row.save().catch((e) => handleError('setShared', e));
-}
-
-/**
* Add or remove an item from an array. All duplicates will be removed.
* @param action Either `add` or `remove` an element.
* @param array The array to add/remove an element from.
@@ -643,58 +327,6 @@ export function hexToRgb(hex: string): string {
export const sleep = promisify(setTimeout);
/**
- * Send a message in the error logging channel and console for an error.
- * @param context
- * @param error
- */
-export async function handleError(context: string, error: Error) {
- await client.console.error(_.camelCase(context), `An error occurred:\n${formatError(error, false)}`, false);
- await client.console.channelError({
- embeds: await CommandErrorListener.generateErrorEmbed({ type: 'unhandledRejection', error: error, context })
- });
-}
-
-/**
- * Fetches a user from discord.
- * @param user The user to fetch
- * @returns Undefined if the user is not found, otherwise the user.
- */
-export async function resolveNonCachedUser(user: UserResolvable | undefined | null): Promise<User | undefined> {
- if (user == null) return undefined;
- const resolvedUser =
- user instanceof User
- ? user
- : user instanceof GuildMember
- ? user.user
- : user instanceof ThreadMember
- ? user.user
- : user instanceof Message
- ? user.author
- : undefined;
-
- return resolvedUser ?? (await client.users.fetch(user as Snowflake).catch(() => undefined));
-}
-
-/**
- * Get the pronouns of a discord user from pronoundb.org
- * @param user The user to retrieve the promises of.
- * @returns The human readable pronouns of the user, or undefined if they do not have any.
- */
-export async function getPronounsOf(user: User | Snowflake): Promise<Pronoun | undefined> {
- const _user = await resolveNonCachedUser(user);
- if (!_user) throw new Error(`Cannot find user ${user}`);
- const apiRes = (await got
- .get(`https://pronoundb.org/api/v1/lookup?platform=discord&id=${_user.id}`)
- .json()
- .catch(() => undefined)) as { pronouns: PronounCode } | undefined;
-
- if (!apiRes) return undefined;
- assert(apiRes.pronouns);
-
- return pronounMapping[apiRes.pronouns!]!;
-}
-
-/**
* List the methods of an object.
* @param obj The object to get the methods of.
* @returns A string with each method on a new line.
@@ -763,31 +395,6 @@ export function getSymbols(obj: Record<string, any>): symbol[] {
}
/**
- * Uploads an image to imgur.
- * @param image The image to upload.
- * @returns The url of the imgur.
- */
-export async function uploadImageToImgur(image: string) {
- const clientId = client.config.credentials.imgurClientId;
-
- const resp = (await got
- .post('https://api.imgur.com/3/upload', {
- headers: {
- Authorization: `Client-ID ${clientId}`,
- Accept: 'application/json'
- },
- form: {
- image: image,
- type: 'base64'
- },
- followRedirect: true
- })
- .json()) as { data: { link: string } };
-
- return resp.data.link;
-}
-
-/**
* Checks if a user has a certain guild permission (doesn't check channel permissions).
* @param message The message to check the user from.
* @param permissions The permissions to check for.
@@ -843,15 +450,6 @@ export function clientSendAndPermCheck(
return missing.length ? missing : null;
}
-/**
- * Gets the prefix based off of the message.
- * @param message The message to get the prefix from.
- * @returns The prefix.
- */
-export function prefix(message: CommandMessage | SlashMessage): string {
- return message.util.isSlash ? '/' : client.config.isDevelopment ? 'dev ' : message.util.parsed?.prefix ?? client.config.prefix;
-}
-
export { deepLock as deepFreeze };
export { Arg as arg };
export { Format as format };
@@ -950,48 +548,6 @@ export function overflowEmbed(embed: Omit<APIEmbed, 'description'>, lines: strin
return embeds;
}
-export async function resolveMessageLinks(content: string | null): Promise<MessageLinkParts[]> {
- const res: MessageLinkParts[] = [];
-
- if (!content) return res;
-
- const regex_ = new RegExp(regex.messageLink);
- let match: RegExpExecArray | null;
- while (((match = regex_.exec(content)), match !== null)) {
- const input = match.input;
- if (!match.groups || !input) continue;
- if (input.startsWith('<') && input.endsWith('>')) continue;
-
- const { guild_id, channel_id, message_id } = match.groups;
- if (!guild_id || !channel_id || !message_id) continue;
-
- res.push({ guild_id, channel_id, message_id });
- }
-
- return res;
-}
-
-export async function resolveMessagesFromLinks(content: string): Promise<APIMessage[]> {
- const res: APIMessage[] = [];
-
- const links = await resolveMessageLinks(content);
- if (!links.length) return [];
-
- for (const { guild_id, channel_id, message_id } of links) {
- const guild = client.guilds.cache.get(guild_id);
- if (!guild) continue;
- const channel = guild.channels.cache.get(channel_id);
- if (!channel || (!channel.isTextBased() && !channel.isThread())) continue;
-
- const message = (await client.rest.get(Routes.channelMessage(channel_id, message_id)).catch(() => null)) as APIMessage | null;
- if (!message) continue;
-
- res.push(message);
- }
-
- return res;
-}
-
/**
* Formats an error into a string.
* @param error The error to format.
@@ -1011,10 +567,6 @@ export function formatError(error: Error | any, colors = false): string {
return error.stack;
}
-interface HastebinRes {
- key: string;
-}
-
export interface UuidRes {
uuid: string;
username: string;
@@ -1034,11 +586,6 @@ export interface UuidRes {
created_at: string;
}
-export interface HasteResults {
- url?: string;
- error?: 'content too long' | 'substr' | 'unable to post';
-}
-
export interface ParsedDuration {
duration: number | null;
content: string | null;
@@ -1050,9 +597,3 @@ export interface ParsedDurationRes {
}
export type TimestampStyle = 't' | 'T' | 'd' | 'D' | 'f' | 'F' | 'R';
-
-export interface MessageLinkParts {
- guild_id: Snowflake;
- channel_id: Snowflake;
- message_id: Snowflake;
-}
diff --git a/src/listeners/bush/appealListener.ts b/src/listeners/bush/appealListener.ts
index 06eb245..b62031d 100644
--- a/src/listeners/bush/appealListener.ts
+++ b/src/listeners/bush/appealListener.ts
@@ -1,4 +1,3 @@
-/* eslint-disable no-control-regex */
import { BushListener, colors, mappings, ModLog, type BushClientEvents } from '#lib';
import assert from 'assert';
import { EmbedBuilder } from 'discord.js';
@@ -15,7 +14,7 @@ export default class AppealListener extends BushListener {
}
public async exec(...[message]: BushClientEvents['messageCreate']): Promise<any> {
- if (!client.config.isProduction || !message.inGuild() || message.guildId !== mappings.guilds.bush) return;
+ if (!this.client.config.isProduction || !message.inGuild() || message.guildId !== mappings.guilds.bush) return;
if (message.author.id !== '855446927688335370' || message.embeds.length < 1) return;
const userId = message.embeds[0].fields?.find?.((f) => f.name === 'What is your discord ID?')?.value;
@@ -26,7 +25,7 @@ export default class AppealListener extends BushListener {
name: `${message.embeds[0].fields.find((f) => f.name === 'What type of punishment are you appealing?')?.value} appeal`
});
- const user = await client.users.fetch(userId, { force: true }).catch(() => null);
+ const user = await this.client.users.fetch(userId, { force: true }).catch(() => null);
if (!user)
return await thread.send({
embeds: [
diff --git a/src/listeners/bush/joinAutoBan.ts b/src/listeners/bush/joinAutoBan.ts
index eae18d3..082a925 100644
--- a/src/listeners/bush/joinAutoBan.ts
+++ b/src/listeners/bush/joinAutoBan.ts
@@ -1,4 +1,4 @@
-import { AllowedMentions, BushListener, colors, emojis, format, getShared, mappings, type BushClientEvents } from '#lib';
+import { AllowedMentions, BushListener, colors, emojis, format, mappings, type BushClientEvents } from '#lib';
import { TextChannel } from 'discord.js';
export default class JoinAutoBanListener extends BushListener {
@@ -11,13 +11,13 @@ export default class JoinAutoBanListener extends BushListener {
}
public async exec(...[member]: BushClientEvents['guildMemberAdd']): Promise<void> {
- if (!client.config.isProduction) return;
+ if (!this.client.config.isProduction) return;
if (member.guild.id !== mappings.guilds.bush) return;
const guild = member.guild;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const user = member.user;
- const code = getShared('autoBanCode');
+ const code = this.client.utils.getShared('autoBanCode');
if (!code) return;
if (eval(code)) {
const res = await member.bushBan({
diff --git a/src/listeners/bush/supportThread.ts b/src/listeners/bush/supportThread.ts
index 3651409..1dadecb 100644
--- a/src/listeners/bush/supportThread.ts
+++ b/src/listeners/bush/supportThread.ts
@@ -13,7 +13,7 @@ export default class SupportThreadListener extends BushListener {
}
public async exec(...[message]: BushClientEvents['messageCreate']): Promise<void | undefined> {
- if (!client.config.isProduction || !message.inGuild()) return;
+ if (!this.client.config.isProduction || !message.inGuild()) return;
if (![MessageType.Default, MessageType.Reply].includes(message.type)) return;
if (message.thread) return;
if (message.author.bot && (message.author.id !== '444871677176709141' || !message.content.includes('uploaded a log,')))
@@ -23,10 +23,10 @@ export default class SupportThreadListener extends BushListener {
if (message.channel.id !== '714332750156660756') return; // neu-support
if (
- [await message.guild.getSetting('prefix'), `<@!${client.user!.id}>`, `<@${client.user!.id}>`].some((v) =>
+ [await message.guild.getSetting('prefix'), `<@!${this.client.user!.id}>`, `<@${this.client.user!.id}>`].some((v) =>
message.content.trim().startsWith(v)
) &&
- client.commandHandler.aliases.some((alias) => message.content.includes(alias))
+ this.client.commandHandler.aliases.some((alias) => message.content.includes(alias))
)
return;
@@ -54,7 +54,7 @@ export default class SupportThreadListener extends BushListener {
void thread
.send({ embeds: [embed] })
.then(() =>
- client.console.info(
+ this.client.console.info(
'supportThread',
`opened a support thread for <<${message.author.tag}>> in <<${message.channel.name}>> in <<${message.guild!.name}>>.`
)
diff --git a/src/listeners/bush/userUpdateAutoBan.ts b/src/listeners/bush/userUpdateAutoBan.ts
index 07381e0..54051b2 100644
--- a/src/listeners/bush/userUpdateAutoBan.ts
+++ b/src/listeners/bush/userUpdateAutoBan.ts
@@ -1,4 +1,4 @@
-import { AllowedMentions, BushListener, colors, emojis, format, getShared, mappings, type BushClientEvents } from '#lib';
+import { AllowedMentions, BushListener, colors, emojis, format, mappings, type BushClientEvents } from '#lib';
import { GuildMember, type TextChannel } from 'discord.js';
export default class UserUpdateAutoBanListener extends BushListener {
@@ -11,14 +11,14 @@ export default class UserUpdateAutoBanListener extends BushListener {
}
public async exec(...[_oldUser, newUser]: BushClientEvents['userUpdate']): Promise<void> {
- if (!client.config.isProduction) return;
+ if (!this.client.config.isProduction) return;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const user = newUser;
- const code = getShared('autoBanCode');
+ const code = this.client.utils.getShared('autoBanCode');
if (!code) return;
if (eval(code)) {
- const member = await client.guilds.cache
+ const member = await this.client.guilds.cache
.get(mappings.guilds.bush)
?.members.fetch(newUser.id)
.catch(() => undefined);
diff --git a/src/listeners/client/akairoDebug.ts b/src/listeners/client/akairoDebug.ts
index 208e289..3fa7977 100644
--- a/src/listeners/client/akairoDebug.ts
+++ b/src/listeners/client/akairoDebug.ts
@@ -11,7 +11,7 @@ export default class DiscordJsDebugListener extends BushListener {
public async exec(...[message, ...other]: BushClientEvents['debug']): Promise<void> {
if (other.length && !message.includes('[registerInteractionCommands]'))
- void client.console.superVerboseRaw('akairoDebug', message, ...other);
- else void client.console.superVerbose('akairoDebug', message);
+ void this.client.console.superVerboseRaw('akairoDebug', message, ...other);
+ else void this.client.console.superVerbose('akairoDebug', message);
}
}
diff --git a/src/listeners/client/dcjsDebug.ts b/src/listeners/client/dcjsDebug.ts
index 56a9eab..4b80c65 100644
--- a/src/listeners/client/dcjsDebug.ts
+++ b/src/listeners/client/dcjsDebug.ts
@@ -10,6 +10,6 @@ export default class DiscordJsDebugListener extends BushListener {
}
public async exec(...[message]: BushClientEvents['debug']): Promise<void> {
- void client.console.superVerbose('dc.js-debug', message);
+ void this.client.console.superVerbose('dc.js-debug', message);
}
}
diff --git a/src/listeners/client/dcjsError.ts b/src/listeners/client/dcjsError.ts
index c3cf8f0..a39a92d 100644
--- a/src/listeners/client/dcjsError.ts
+++ b/src/listeners/client/dcjsError.ts
@@ -10,6 +10,6 @@ export default class DiscordJsErrorListener extends BushListener {
}
public async exec(...[error]: BushClientEvents['error']): Promise<void> {
- void client.console.superVerbose('dc.js-error', error);
+ void this.client.console.superVerbose('dc.js-error', error);
}
}
diff --git a/src/listeners/client/dcjsWarn.ts b/src/listeners/client/dcjsWarn.ts
index 6c13630..b187f0c 100644
--- a/src/listeners/client/dcjsWarn.ts
+++ b/src/listeners/client/dcjsWarn.ts
@@ -10,6 +10,6 @@ export default class DiscordJsWarnListener extends BushListener {
}
public async exec(...[message]: BushClientEvents['warn']): Promise<void> {
- void client.console.superVerbose('dc.js-warn', message);
+ void this.client.console.superVerbose('dc.js-warn', message);
}
}
diff --git a/src/listeners/client/ready.ts b/src/listeners/client/ready.ts
index ae9919c..a6a289c 100644
--- a/src/listeners/client/ready.ts
+++ b/src/listeners/client/ready.ts
@@ -14,22 +14,22 @@ export default class ReadyListener extends BushListener {
public async exec(...[]: BushClientEvents['ready']) {
process.emit('ready' as any);
- const tag = `<<${client.user?.tag}>>`,
- guildCount = `<<${client.guilds.cache.size.toLocaleString()}>>`,
- userCount = `<<${client.users.cache.size.toLocaleString()}>>`;
+ const tag = `<<${this.client.user?.tag}>>`,
+ guildCount = `<<${this.client.guilds.cache.size.toLocaleString()}>>`,
+ userCount = `<<${this.client.users.cache.size.toLocaleString()}>>`;
- void client.logger.success('ready', `Logged in to ${tag} serving ${guildCount} guilds and ${userCount} users.`);
+ void this.client.logger.success('ready', `Logged in to ${tag} serving ${guildCount} guilds and ${userCount} users.`);
console.log(
chalk.blue(
`------------------------------------------------------------------------------${
- client.config.isDevelopment ? '---' : client.config.isBeta ? '----' : ''
+ this.client.config.isDevelopment ? '---' : this.client.config.isBeta ? '----' : ''
}`
)
);
const guilds = await Guild.findAll();
const needToCreate = [];
- for (const [, guild] of client.guilds.cache) {
+ for (const [, guild] of this.client.guilds.cache) {
const find = guilds.find((g) => guild.id === g.id);
if (!find) needToCreate.push(guild.id);
}
diff --git a/src/listeners/commands/commandBlocked.ts b/src/listeners/commands/commandBlocked.ts
index 8a05d39..e9d1394 100644
--- a/src/listeners/commands/commandBlocked.ts
+++ b/src/listeners/commands/commandBlocked.ts
@@ -9,7 +9,7 @@ import {
type CommandMessage,
type SlashMessage
} from '#lib';
-import { type InteractionReplyOptions, type MessagePayload, type ReplyMessageOptions } from 'discord.js';
+import { type Client, type InteractionReplyOptions, type MessagePayload, type ReplyMessageOptions } from 'discord.js';
export default class CommandBlockedListener extends BushListener {
public constructor() {
@@ -21,10 +21,15 @@ export default class CommandBlockedListener extends BushListener {
}
public async exec(...[message, command, reason]: BushCommandHandlerEvents['commandBlocked']) {
- return await CommandBlockedListener.handleBlocked(message, command, reason);
+ return await CommandBlockedListener.handleBlocked(this.client, message, command, reason);
}
- public static async handleBlocked(message: CommandMessage | SlashMessage, command: BushCommand | null, reason?: string) {
+ public static async handleBlocked(
+ client: Client,
+ message: CommandMessage | SlashMessage,
+ command: BushCommand | null,
+ reason?: string
+ ) {
const isSlash = !!command && !!message.util?.isSlash;
void client.console.info(
diff --git a/src/listeners/commands/commandCooldown.ts b/src/listeners/commands/commandCooldown.ts
index 74dd4eb..5f4d70e 100644
--- a/src/listeners/commands/commandCooldown.ts
+++ b/src/listeners/commands/commandCooldown.ts
@@ -10,7 +10,7 @@ export default class CommandCooldownListener extends BushListener {
}
public async exec(...[message, command, remaining]: BushCommandHandlerEvents['cooldown']) {
- void client.console.info(
+ void this.client.console.info(
'commandCooldown',
`<<${message.author.tag}>> tried to run <<${
command ?? message.util!.parsed?.command
diff --git a/src/listeners/commands/commandError.ts b/src/listeners/commands/commandError.ts
index ca6565e..04ea517 100644
--- a/src/listeners/commands/commandError.ts
+++ b/src/listeners/commands/commandError.ts
@@ -1,16 +1,6 @@
-import {
- capitalize,
- colors,
- format,
- formatError,
- inspectAndRedact,
- inspectCleanRedactCodeblock,
- inspectCleanRedactHaste,
- SlashMessage,
- type BushCommandHandlerEvents
-} from '#lib';
+import { capitalize, colors, format, formatError, SlashMessage, type BushCommandHandlerEvents } from '#lib';
import { type AkairoMessage, type Command } from 'discord-akairo';
-import { ChannelType, EmbedBuilder, escapeInlineCode, Formatters, GuildTextBasedChannel, type Message } from 'discord.js';
+import { ChannelType, Client, EmbedBuilder, escapeInlineCode, Formatters, GuildTextBasedChannel, type Message } from 'discord.js';
import { BushListener } from '../../lib/extensions/discord-akairo/BushListener.js';
export default class CommandErrorListener extends BushListener {
@@ -23,10 +13,11 @@ export default class CommandErrorListener extends BushListener {
}
public exec(...[error, message, command]: BushCommandHandlerEvents['error']) {
- return CommandErrorListener.handleError(error, message, command);
+ return CommandErrorListener.handleError(this.client, error, message, command);
}
public static async handleError(
+ client: Client,
...[error, message, _command]: BushCommandHandlerEvents['error'] | BushCommandHandlerEvents['slashError']
) {
try {
@@ -63,8 +54,8 @@ export default class CommandErrorListener extends BushListener {
false
);
- const _haste = CommandErrorListener.getErrorHaste(error);
- const _stack = CommandErrorListener.getErrorStack(error);
+ const _haste = CommandErrorListener.getErrorHaste(client, error);
+ const _stack = CommandErrorListener.getErrorStack(client, error);
const [haste, stack] = await Promise.all([_haste, _stack]);
const options = { message, error, isSlash, errorNum, command, channel, haste, stack };
@@ -97,6 +88,7 @@ export default class CommandErrorListener extends BushListener {
}
public static async generateErrorEmbed(
+ client: Client,
options:
| {
message: Message | AkairoMessage;
@@ -109,8 +101,8 @@ export default class CommandErrorListener extends BushListener {
}
| { error: Error | any; type: 'uncaughtException' | 'unhandledRejection'; context?: string }
): Promise<EmbedBuilder[]> {
- const _haste = CommandErrorListener.getErrorHaste(options.error);
- const _stack = CommandErrorListener.getErrorStack(options.error);
+ const _haste = CommandErrorListener.getErrorHaste(client, options.error);
+ const _stack = CommandErrorListener.getErrorStack(client, options.error);
const [haste, stack] = await Promise.all([_haste, _stack]);
return CommandErrorListener._generateErrorEmbed({ ...options, haste, stack });
@@ -179,7 +171,7 @@ export default class CommandErrorListener extends BushListener {
return embeds;
}
- public static async getErrorHaste(error: Error | any): Promise<string[]> {
+ public static async getErrorHaste(client: Client, error: Error | any): Promise<string[]> {
const inspectOptions = {
showHidden: false,
depth: 9,
@@ -209,7 +201,7 @@ export default class CommandErrorListener extends BushListener {
for (const element in error) {
if (['stack', 'name', 'message'].includes(element)) continue;
else if (typeof (error as any)[element] === 'object') {
- promises.push(inspectCleanRedactHaste((error as any)[element], inspectOptions));
+ promises.push(client.utils.inspectCleanRedactHaste((error as any)[element], inspectOptions));
}
}
@@ -235,7 +227,7 @@ export default class CommandErrorListener extends BushListener {
? `[haste](${pair[element].url})${pair[element].error ? ` - ${pair[element].error}` : ''}`
: pair[element].error
}`
- : `\`${escapeInlineCode(inspectAndRedact((error as any)[element], inspectOptions))}\``
+ : `\`${escapeInlineCode(client.utils.inspectAndRedact((error as any)[element], inspectOptions))}\``
}`
);
}
@@ -243,8 +235,8 @@ export default class CommandErrorListener extends BushListener {
return ret;
}
- public static async getErrorStack(error: Error | any): Promise<string> {
- return await inspectCleanRedactCodeblock(error, 'js', { colors: false }, 4000);
+ public static async getErrorStack(client: Client, error: Error | any): Promise<string> {
+ return await client.utils.inspectCleanRedactCodeblock(error, 'js', { colors: false }, 4000);
}
}
diff --git a/src/listeners/commands/commandMissingPermissions.ts b/src/listeners/commands/commandMissingPermissions.ts
index 352899d..4d39264 100644
--- a/src/listeners/commands/commandMissingPermissions.ts
+++ b/src/listeners/commands/commandMissingPermissions.ts
@@ -1,5 +1,5 @@
import { BushListener, emojis, format, mappings, oxford, surroundArray, type BushCommandHandlerEvents } from '#lib';
-import { type PermissionsString } from 'discord.js';
+import { Client, type PermissionsString } from 'discord.js';
export default class CommandMissingPermissionsListener extends BushListener {
public constructor() {
@@ -11,10 +11,11 @@ export default class CommandMissingPermissionsListener extends BushListener {
}
public async exec(...[message, command, type, missing]: BushCommandHandlerEvents['missingPermissions']) {
- return await CommandMissingPermissionsListener.handleMissing(message, command, type, missing);
+ return await CommandMissingPermissionsListener.handleMissing(this.client, message, command, type, missing);
}
public static async handleMissing(
+ client: Client,
...[message, command, type, missing]:
| BushCommandHandlerEvents['missingPermissions']
| BushCommandHandlerEvents['slashMissingPermissions']
diff --git a/src/listeners/commands/commandStarted.ts b/src/listeners/commands/commandStarted.ts
index 89fea28..9d0e4cb 100644
--- a/src/listeners/commands/commandStarted.ts
+++ b/src/listeners/commands/commandStarted.ts
@@ -11,7 +11,7 @@ export default class CommandStartedListener extends BushListener {
}
public exec(...[message, command]: BushCommandHandlerEvents['commandStarted']): void {
- client.sentry.addBreadcrumb({
+ this.client.sentry.addBreadcrumb({
message: `[commandStarted] The ${command.id} was started by ${message.author.tag}.`,
level: 'info',
timestamp: Date.now(),
@@ -25,11 +25,11 @@ export default class CommandStartedListener extends BushListener {
(message.channel.isDMBased() ? message.channel.recipient?.tag : (<any>message.channel)?.name) ?? '¯\\_(ツ)_/¯',
'guild.id': message.guild?.id ?? '¯\\_(ツ)_/¯',
'guild.name': message.guild?.name ?? '¯\\_(ツ)_/¯',
- 'environment': client.config.environment
+ 'environment': this.client.config.environment
}
});
- void client.logger.info(
+ void this.client.logger.info(
'commandStarted',
`The <<${command.id}>> command was used by <<${message.author.tag}>> in ${
message.channel.type === ChannelType.DM ? `their <<DMs>>` : `<<#${message.channel.name}>> in <<${message.guild?.name}>>`
@@ -37,6 +37,6 @@ export default class CommandStartedListener extends BushListener {
true
);
- client.stats.commandsUsed = client.stats.commandsUsed + 1n;
+ this.client.stats.commandsUsed = this.client.stats.commandsUsed + 1n;
}
}
diff --git a/src/listeners/commands/messageBlocked.ts b/src/listeners/commands/messageBlocked.ts
index 997579c..d73cff1 100644
--- a/src/listeners/commands/messageBlocked.ts
+++ b/src/listeners/commands/messageBlocked.ts
@@ -12,6 +12,9 @@ export default class MessageBlockedListener extends BushListener {
public async exec(...[message, reason]: BushCommandHandlerEvents['messageBlocked']) {
if (['client', 'bot'].includes(reason)) return;
// return await CommandBlockedListener.handleBlocked(message as Message, null, reason);
- return void client.console.verbose(`messageBlocked`, `<<${message.author.tag}>>'s message was blocked because ${reason}`);
+ return void this.client.console.verbose(
+ `messageBlocked`,
+ `<<${message.author.tag}>>'s message was blocked because ${reason}`
+ );
}
}
diff --git a/src/listeners/commands/slashBlocked.ts b/src/listeners/commands/slashBlocked.ts
index 915b953..c877708 100644
--- a/src/listeners/commands/slashBlocked.ts
+++ b/src/listeners/commands/slashBlocked.ts
@@ -11,6 +11,6 @@ export default class SlashBlockedListener extends BushListener {
}
public async exec(...[message, command, reason]: BushCommandHandlerEvents['slashBlocked']) {
- return await CommandBlockedListener.handleBlocked(message, command, reason);
+ return await CommandBlockedListener.handleBlocked(this.client, message, command, reason);
}
}
diff --git a/src/listeners/commands/slashCommandError.ts b/src/listeners/commands/slashCommandError.ts
index f851f4f..7c0d52c 100644
--- a/src/listeners/commands/slashCommandError.ts
+++ b/src/listeners/commands/slashCommandError.ts
@@ -11,6 +11,6 @@ export default class SlashCommandErrorListener extends BushListener {
}
public async exec(...[error, message, command]: BushCommandHandlerEvents['slashError']) {
- return await CommandErrorListener.handleError(error, message, command);
+ return await CommandErrorListener.handleError(this.client, error, message, command);
}
}
diff --git a/src/listeners/commands/slashMissingPermissions.ts b/src/listeners/commands/slashMissingPermissions.ts
index 3ae03e3..0a1383b 100644
--- a/src/listeners/commands/slashMissingPermissions.ts
+++ b/src/listeners/commands/slashMissingPermissions.ts
@@ -11,6 +11,6 @@ export default class SlashMissingPermissionsListener extends BushListener {
}
public async exec(...[message, command, type, missing]: BushCommandHandlerEvents['slashMissingPermissions']) {
- return await CommandMissingPermissionsListener.handleMissing(message, command, type, missing);
+ return await CommandMissingPermissionsListener.handleMissing(this.client, message, command, type, missing);
}
}
diff --git a/src/listeners/commands/slashNotFound.ts b/src/listeners/commands/slashNotFound.ts
index 8c6d2d4..cc14969 100644
--- a/src/listeners/commands/slashNotFound.ts
+++ b/src/listeners/commands/slashNotFound.ts
@@ -10,6 +10,6 @@ export default class SlashNotFoundListener extends BushListener {
}
public async exec(...[interaction]: BushCommandHandlerEvents['slashNotFound']) {
- void client.console.info('slashNotFound', `<<${interaction?.commandName}>> could not be found.`);
+ void this.client.console.info('slashNotFound', `<<${interaction?.commandName}>> could not be found.`);
}
}
diff --git a/src/listeners/commands/slashStarted.ts b/src/listeners/commands/slashStarted.ts
index e2c8a47..400920f 100644
--- a/src/listeners/commands/slashStarted.ts
+++ b/src/listeners/commands/slashStarted.ts
@@ -11,7 +11,7 @@ export default class SlashStartedListener extends BushListener {
}
public async exec(...[message, command]: BushCommandHandlerEvents['slashStarted']) {
- client.sentry.addBreadcrumb({
+ this.client.sentry.addBreadcrumb({
message: `[slashStarted] The ${command.id} was started by ${message.author.tag}.`,
level: 'info',
timestamp: Date.now(),
@@ -25,11 +25,11 @@ export default class SlashStartedListener extends BushListener {
(message.channel?.isDMBased() ? message.channel.recipient?.tag : (<any>message.channel)?.name) ?? '¯\\_(ツ)_/¯',
'guild.id': message.guild?.id ?? '¯\\_(ツ)_/¯',
'guild.name': message.guild?.name ?? '¯\\_(ツ)_/¯',
- 'environment': client.config.environment
+ 'environment': this.client.config.environment
}
});
- void client.logger.info(
+ void this.client.logger.info(
'slashStarted',
`The <<${command.id}>> command was used by <<${message.author.tag}>> in ${
message.channel
@@ -41,6 +41,6 @@ export default class SlashStartedListener extends BushListener {
true
);
- client.stats.commandsUsed = client.stats.commandsUsed + 1n;
+ this.client.stats.commandsUsed = this.client.stats.commandsUsed + 1n;
}
}
diff --git a/src/listeners/contextCommands/contextCommandBlocked.ts b/src/listeners/contextCommands/contextCommandBlocked.ts
index a9397b6..bb237a0 100644
--- a/src/listeners/contextCommands/contextCommandBlocked.ts
+++ b/src/listeners/contextCommands/contextCommandBlocked.ts
@@ -11,7 +11,7 @@ export default class ContextCommandBlockedListener extends BushListener {
}
public async exec(...[interaction, command, reason]: ContextMenuCommandHandlerEvents['blocked']) {
- void client.console.info(
+ void this.client.console.info(
`ContextCommandBlocked`,
`<<${interaction.user.tag}>> tried to run <<${command}>> but was blocked because <<${reason}>>.`,
true
diff --git a/src/listeners/contextCommands/contextCommandError.ts b/src/listeners/contextCommands/contextCommandError.ts
index e69ed4e..4b1ea52 100644
--- a/src/listeners/contextCommands/contextCommandError.ts
+++ b/src/listeners/contextCommands/contextCommandError.ts
@@ -1,6 +1,6 @@
import { BushListener, colors, format, formatError } from '#lib';
import { type ContextMenuCommand, type ContextMenuCommandHandlerEvents } from 'discord-akairo';
-import { ChannelType, ContextMenuCommandInteraction, EmbedBuilder, GuildTextBasedChannel } from 'discord.js';
+import { ChannelType, Client, ContextMenuCommandInteraction, EmbedBuilder, GuildTextBasedChannel } from 'discord.js';
import CommandErrorListener, { IFuckedUpError } from '../commands/commandError.js';
export default class ContextCommandErrorListener extends BushListener {
@@ -13,10 +13,10 @@ export default class ContextCommandErrorListener extends BushListener {
}
public exec(...[error, interaction, command]: ContextMenuCommandHandlerEvents['error']) {
- return ContextCommandErrorListener.handleError(error, interaction, command);
+ return ContextCommandErrorListener.handleError(this.client, error, interaction, command);
}
- public static async handleError(...[error, interaction, command]: ContextMenuCommandHandlerEvents['error']) {
+ public static async handleError(client: Client, ...[error, interaction, command]: ContextMenuCommandHandlerEvents['error']) {
try {
const errorNum = Math.floor(Math.random() * 6969696969) + 69; // hehe funny number
const channel =
@@ -49,8 +49,8 @@ export default class ContextCommandErrorListener extends BushListener {
false
);
- const _haste = CommandErrorListener.getErrorHaste(error);
- const _stack = CommandErrorListener.getErrorStack(error);
+ const _haste = CommandErrorListener.getErrorHaste(client, error);
+ const _stack = CommandErrorListener.getErrorStack(client, error);
const [haste, stack] = await Promise.all([_haste, _stack]);
const options = { interaction, error, errorNum, command, channel, haste, stack };
diff --git a/src/listeners/contextCommands/contextCommandNotFound.ts b/src/listeners/contextCommands/contextCommandNotFound.ts
index 65954a2..f5097f3 100644
--- a/src/listeners/contextCommands/contextCommandNotFound.ts
+++ b/src/listeners/contextCommands/contextCommandNotFound.ts
@@ -11,6 +11,6 @@ export default class ContextCommandNotFoundListener extends BushListener {
}
public async exec(...[interaction]: ContextMenuCommandHandlerEvents['notFound']) {
- void client.console.info('contextCommandNotFound', `<<${interaction?.commandName}>> could not be found.`);
+ void this.client.console.info('contextCommandNotFound', `<<${interaction?.commandName}>> could not be found.`);
}
}
diff --git a/src/listeners/contextCommands/contextCommandStarted.ts b/src/listeners/contextCommands/contextCommandStarted.ts
index 3aab07a..2d1e9ef 100644
--- a/src/listeners/contextCommands/contextCommandStarted.ts
+++ b/src/listeners/contextCommands/contextCommandStarted.ts
@@ -12,7 +12,7 @@ export default class ContextCommandStartedListener extends BushListener {
}
public async exec(...[interaction, command]: ContextMenuCommandHandlerEvents['started']) {
- client.sentry.addBreadcrumb({
+ this.client.sentry.addBreadcrumb({
message: `[contextCommandStarted] The ${command.id} was started by ${interaction.user.tag}.`,
level: 'info',
timestamp: Date.now(),
@@ -28,11 +28,11 @@ export default class ContextCommandStartedListener extends BushListener {
'¯\\_(ツ)_/¯',
'guild.id': interaction.guild?.id ?? '¯\\_(ツ)_/¯',
'guild.name': interaction.guild?.name ?? '¯\\_(ツ)_/¯',
- 'environment': client.config.environment
+ 'environment': this.client.config.environment
}
});
- return void client.logger.info(
+ return void this.client.logger.info(
'contextCommandStarted',
`The <<${command.id}>> command was used by <<${interaction.user.tag}>> in ${
interaction.channel
diff --git a/src/listeners/guild/guildCreate.ts b/src/listeners/guild/guildCreate.ts
index fe23979..9f5f56c 100644
--- a/src/listeners/guild/guildCreate.ts
+++ b/src/listeners/guild/guildCreate.ts
@@ -1,4 +1,4 @@
-import { BushListener, colors, emojis, format, getConfigChannel, Guild, type BushClientEvents } from '#lib';
+import { BushListener, colors, emojis, format, Guild, type BushClientEvents } from '#lib';
export default class GuildCreateListener extends BushListener {
public constructor() {
@@ -10,11 +10,14 @@ export default class GuildCreateListener extends BushListener {
}
public async exec(...[guild]: BushClientEvents['guildCreate']) {
- void client.console.info('guildCreate', `Joined <<${guild.name}>> with <<${guild.memberCount?.toLocaleString()}>> members.`);
+ void this.client.console.info(
+ 'guildCreate',
+ `Joined <<${guild.name}>> with <<${guild.memberCount?.toLocaleString()}>> members.`
+ );
const g = await Guild.findByPk(guild.id);
if (!g) void Guild.create({ id: guild.id });
- const channel = await getConfigChannel('servers');
+ const channel = await this.client.utils.getConfigChannel('servers');
if (!channel) return;
return await channel.send({
embeds: [
@@ -22,7 +25,7 @@ export default class GuildCreateListener extends BushListener {
color: colors.Green,
description: `${emojis.join} Joined ${format.input(
guild.name
- )} with **${guild.memberCount?.toLocaleString()}** members. I am now in **${client.guilds.cache.size}** guilds.`,
+ )} with **${guild.memberCount?.toLocaleString()}** members. I am now in **${this.client.guilds.cache.size}** guilds.`,
timestamp: new Date().toISOString(),
footer: { text: `${guild.id}`, icon_url: guild.iconURL() ?? undefined }
}
diff --git a/src/listeners/guild/guildDelete.ts b/src/listeners/guild/guildDelete.ts
index 5efbe9b..62d98e3 100644
--- a/src/listeners/guild/guildDelete.ts
+++ b/src/listeners/guild/guildDelete.ts
@@ -1,4 +1,4 @@
-import { BushListener, colors, emojis, format, getConfigChannel, type BushClientEvents } from '#lib';
+import { BushListener, colors, emojis, format, type BushClientEvents } from '#lib';
export default class GuildDeleteListener extends BushListener {
public constructor() {
@@ -10,9 +10,12 @@ export default class GuildDeleteListener extends BushListener {
}
public async exec(...[guild]: BushClientEvents['guildDelete']) {
- void client.console.info('guildDelete', `Left <<${guild.name}>> with <<${guild.memberCount?.toLocaleString()}>> members.`);
+ void this.client.console.info(
+ 'guildDelete',
+ `Left <<${guild.name}>> with <<${guild.memberCount?.toLocaleString()}>> members.`
+ );
- const channel = await getConfigChannel('servers');
+ const channel = await this.client.utils.getConfigChannel('servers');
if (!channel) return;
return await channel.send({
embeds: [
@@ -20,7 +23,7 @@ export default class GuildDeleteListener extends BushListener {
color: colors.Red,
description: `${emojis.leave} Left ${format.input(
guild.name
- )} with **${guild.memberCount?.toLocaleString()}** members. I am now in **${client.guilds.cache.size}** guilds.`,
+ )} with **${guild.memberCount?.toLocaleString()}** members. I am now in **${this.client.guilds.cache.size}** guilds.`,
timestamp: new Date().toISOString(),
footer: { text: `${guild.id}`, icon_url: guild.iconURL() ?? undefined }
}
diff --git a/src/listeners/guild/guildMemberAdd.ts b/src/listeners/guild/guildMemberAdd.ts
index 004a2c2..f1f90af 100644
--- a/src/listeners/guild/guildMemberAdd.ts
+++ b/src/listeners/guild/guildMemberAdd.ts
@@ -15,10 +15,10 @@ export default class GuildMemberAddListener extends BushListener {
}
private async sendWelcomeMessage(member: GuildMember) {
- if (client.config.isDevelopment) return;
+ if (this.client.config.isDevelopment) return;
const welcomeChannel = await member.guild.getSetting('welcomeChannel');
if (!welcomeChannel) return;
- const welcome = client.channels.cache.get(welcomeChannel) as TextChannel | undefined;
+ const welcome = this.client.channels.cache.get(welcomeChannel) as TextChannel | undefined;
if (!welcome) return;
if (member.guild.id !== welcome?.guild.id) throw new Error('Welcome channel must be in the guild.');
@@ -39,7 +39,7 @@ export default class GuildMemberAddListener extends BushListener {
await welcome
.send({ embeds: [embed] })
.then(() =>
- client.console.info(
+ this.client.console.info(
'guildMemberAdd',
`Sent a message for ${format.inputLog(member.user.tag)} in ${format.inputLog(member.guild.name)}.`
)
diff --git a/src/listeners/guild/guildMemberRemove.ts b/src/listeners/guild/guildMemberRemove.ts
index 80e9ee8..39bab24 100644
--- a/src/listeners/guild/guildMemberRemove.ts
+++ b/src/listeners/guild/guildMemberRemove.ts
@@ -16,13 +16,13 @@ export default class GuildMemberRemoveListener extends BushListener {
}
private async sendWelcomeMessage(member: GuildMember | PartialGuildMember) {
- if (client.config.isDevelopment) return;
- const user = member.partial ? await client.users.fetch(member.id) : member.user;
+ if (this.client.config.isDevelopment) return;
+ const user = member.partial ? await this.client.users.fetch(member.id) : member.user;
await sleep(50 * Time.Millisecond); // ban usually triggers after member leave
const isBan = member.guild.bans.cache.has(member.id);
const welcomeChannel = await member.guild.getSetting('welcomeChannel');
if (!welcomeChannel) return;
- const welcome = client.channels.cache.get(welcomeChannel) as TextChannel | undefined;
+ const welcome = this.client.channels.cache.get(welcomeChannel) as TextChannel | undefined;
if (member.guild.id !== welcome?.guild.id) throw new Error('Welcome channel must be in the guild.');
const embed: EmbedBuilder = new EmbedBuilder()
.setDescription(
@@ -34,7 +34,7 @@ export default class GuildMemberRemoveListener extends BushListener {
welcome
.send({ embeds: [embed] })
.then(() =>
- client.console.info(
+ this.client.console.info(
'guildMemberRemove',
`Sent a message for ${format.inputLog(user.tag)} in ${format.inputLog(member.guild.name)}.`
)
@@ -72,7 +72,7 @@ export default class GuildMemberRemoveListener extends BushListener {
await row
.save()
.then(() =>
- client.console.info(
+ this.client.console.info(
'guildMemberRemove',
`${isNew ? 'Created' : 'Updated'} info for ${format.inputLog(member.user.tag)}.`
)
diff --git a/src/listeners/guild/joinRoles.ts b/src/listeners/guild/joinRoles.ts
index f2922c8..539fa71 100644
--- a/src/listeners/guild/joinRoles.ts
+++ b/src/listeners/guild/joinRoles.ts
@@ -11,7 +11,7 @@ export default class JoinRolesListener extends BushListener {
}
public async exec(...[oldMember, newMember]: BushClientEvents['guildMemberUpdate']) {
- if (client.config.isDevelopment) return;
+ if (this.client.config.isDevelopment) return;
if (oldMember.pending && !newMember.pending) {
const feat = {
stickyRoles: await newMember.guild.hasFeature('stickyRoles'),
@@ -66,7 +66,7 @@ export default class JoinRolesListener extends BushListener {
return false as const;
});
if (addedRoles) {
- void client.console.info(
+ void this.client.console.info(
'guildMemberAdd',
`Assigned sticky roles to ${format.inputLog(member.user.tag)} in ${format.inputLog(member.guild.name)}.`
);
@@ -78,9 +78,9 @@ export default class JoinRolesListener extends BushListener {
.catch(() => failedRoles.push(rolesArray[i]));
}
if (failedRoles.length) {
- void client.console.warn('guildMemberAdd', `Failed assigning the following roles on Fallback: ${failedRoles}`);
+ void this.client.console.warn('guildMemberAdd', `Failed assigning the following roles on Fallback: ${failedRoles}`);
} else {
- void client.console.info(
+ void this.client.console.info(
'guildMemberAdd',
`[Fallback] Assigned sticky roles to ${format.inputLog(member.user.tag)} in ${format.inputLog(member.guild.name)}.`
);
@@ -102,7 +102,7 @@ export default class JoinRolesListener extends BushListener {
await member.roles
.add(joinRoles, 'Join roles.')
.then(() =>
- client.console.info(
+ this.client.console.info(
'guildMemberAdd',
`Assigned join roles to ${format.inputLog(member.user.tag)} in ${format.inputLog(member.guild.name)}.`
)
diff --git a/src/listeners/interaction/interactionCreate.ts b/src/listeners/interaction/interactionCreate.ts
index 6c421d1..91bcae6 100644
--- a/src/listeners/interaction/interactionCreate.ts
+++ b/src/listeners/interaction/interactionCreate.ts
@@ -13,7 +13,7 @@ export default class InteractionCreateListener extends BushListener {
public async exec(...[interaction]: BushClientEvents['interactionCreate']) {
if (!interaction) return;
if ('customId' in interaction && (interaction as any)['customId'].startsWith('test')) return;
- void client.console.verbose(
+ void this.client.console.verbose(
'interactionVerbose',
`An interaction of type <<${InteractionType[interaction.type]}>> was received from <<${interaction.user.tag}>>.`
);
diff --git a/src/listeners/member-custom/bushPurge.ts b/src/listeners/member-custom/bushPurge.ts
index ea30bc5..61a65e1 100644
--- a/src/listeners/member-custom/bushPurge.ts
+++ b/src/listeners/member-custom/bushPurge.ts
@@ -1,4 +1,4 @@
-import { BushListener, colors, emojis, inspectCleanRedactHaste, type BushClientEvents } from '#lib';
+import { BushListener, colors, emojis, type BushClientEvents } from '#lib';
import { EmbedBuilder } from 'discord.js';
export default class BushPurgeListener extends BushListener {
@@ -21,7 +21,7 @@ export default class BushPurgeListener extends BushListener {
embeds: m.embeds,
attachments: [...m.attachments.values()]
}));
- const haste = await inspectCleanRedactHaste(mappedMessages);
+ const haste = await this.client.utils.inspectCleanRedactHaste(mappedMessages);
const logEmbed = new EmbedBuilder()
.setColor(colors.DarkPurple)
diff --git a/src/listeners/member-custom/bushUpdateModlog.ts b/src/listeners/member-custom/bushUpdateModlog.ts
index 5e29b9a..893bec6 100644
--- a/src/listeners/member-custom/bushUpdateModlog.ts
+++ b/src/listeners/member-custom/bushUpdateModlog.ts
@@ -1,4 +1,4 @@
-import { BushListener, colors, inspectCleanRedactCodeblock, type BushClientEvents } from '#lib';
+import { BushListener, colors, type BushClientEvents } from '#lib';
import { EmbedBuilder } from 'discord.js';
export default class BushUpdateModlogListener extends BushListener {
@@ -26,8 +26,14 @@ export default class BushUpdateModlogListener extends BushListener {
{ name: '**Moderator**', value: `${moderator} (${moderator.user.tag})` },
{ name: '**ModLog Changed**', value: modlogID },
{ name: '**Value Changed**', value: key },
- { name: '**Old Value**', value: await inspectCleanRedactCodeblock(oldModlog, undefined, undefined, 1024) },
- { name: '**New Value**', value: await inspectCleanRedactCodeblock(newModlog, undefined, undefined, 1024) }
+ {
+ name: '**Old Value**',
+ value: await this.client.utils.inspectCleanRedactCodeblock(oldModlog, undefined, undefined, 1024)
+ },
+ {
+ name: '**New Value**',
+ value: await this.client.utils.inspectCleanRedactCodeblock(newModlog, undefined, undefined, 1024)
+ }
]);
return await logChannel.send({ embeds: [logEmbed] });
diff --git a/src/listeners/member-custom/bushUpdateSettings.ts b/src/listeners/member-custom/bushUpdateSettings.ts
index e367c4e..3781a8b 100644
--- a/src/listeners/member-custom/bushUpdateSettings.ts
+++ b/src/listeners/member-custom/bushUpdateSettings.ts
@@ -1,4 +1,4 @@
-import { BushListener, colors, inspectCleanRedactCodeblock, type BushClientEvents } from '#lib';
+import { BushListener, colors, type BushClientEvents } from '#lib';
import { EmbedBuilder } from 'discord.js';
export default class BushUpdateSettingsListener extends BushListener {
@@ -25,8 +25,8 @@ export default class BushUpdateSettingsListener extends BushListener {
if (moderator) logEmbed.addFields([{ name: '**Moderator**', value: `${moderator} (${moderator.user.tag})` }]);
logEmbed.addFields([
{ name: '**Setting Changed**', value: setting },
- { name: '**Old Value**', value: await inspectCleanRedactCodeblock(oldSettings, 'js', undefined, 1024) },
- { name: '**New Value**', value: await inspectCleanRedactCodeblock(newSettings, 'js', undefined, 1024) }
+ { name: '**Old Value**', value: await this.client.utils.inspectCleanRedactCodeblock(oldSettings, 'js', undefined, 1024) },
+ { name: '**New Value**', value: await this.client.utils.inspectCleanRedactCodeblock(newSettings, 'js', undefined, 1024) }
]);
return await logChannel.send({ embeds: [logEmbed] });
diff --git a/src/listeners/message/autoPublisher.ts b/src/listeners/message/autoPublisher.ts
index c669930..a6fb7e0 100644
--- a/src/listeners/message/autoPublisher.ts
+++ b/src/listeners/message/autoPublisher.ts
@@ -18,10 +18,11 @@ export default class autoPublisherListener extends BushListener {
await message
.crosspost()
.then(
- () => void client.logger.log('autoPublisher', `Published message <<${message.id}>> in <<${message.guild!.name}>>.`)
+ () =>
+ void this.client.logger.log('autoPublisher', `Published message <<${message.id}>> in <<${message.guild!.name}>>.`)
)
.catch(() => {
- void client.console.log('autoPublisher', `Failed to publish <<${message.id}>> in <<${message.guild!.name}>>.`);
+ void this.client.console.log('autoPublisher', `Failed to publish <<${message.id}>> in <<${message.guild!.name}>>.`);
void message.guild?.error('autoPublisher', `Unable to publish message id ${message.id} in <#${message.channel.id}>.`);
});
}
diff --git a/src/listeners/message/blacklistedFile.ts b/src/listeners/message/blacklistedFile.ts
index 15d97e3..3d66f38 100644
--- a/src/listeners/message/blacklistedFile.ts
+++ b/src/listeners/message/blacklistedFile.ts
@@ -122,7 +122,7 @@ export default class BlacklistedFileListener extends BushListener {
if (foundFiles.length > 0) {
try {
for (let i = 0; i < foundFiles.length; i++) {
- if (foundFiles[i].name === 'Discord crash video' && !client.ownerID.includes(message.author.id)) {
+ if (foundFiles[i].name === 'Discord crash video' && !this.client.ownerID.includes(message.author.id)) {
await message.member?.roles.add('748912426581229690');
}
}
@@ -132,7 +132,7 @@ export default class BlacklistedFileListener extends BushListener {
`<@!${message.author.id}>, please do not send ${foundFiles.map((f) => f.description).join(' or ')}.`
);
if (message.channel.type === ChannelType.DM) return;
- void client.console.info(
+ void this.client.console.info(
'blacklistedFile',
`Deleted <<${foundFiles.map((f) => f.description).join(' and ')}>> sent by <<${message.author.tag}>> in ${
message.channel.name
@@ -142,7 +142,7 @@ export default class BlacklistedFileListener extends BushListener {
void message.util!.send(
`<@!${message.author.id}>, please do not send ${foundFiles.map((f) => f.description).join(' or ')}.`
);
- void client.console.warn(
+ void this.client.console.warn(
'blacklistedFile',
`Failed to delete <<${foundFiles.map((f) => f.description).join(' and ')}>> sent by <<${message.author.tag}>> in <<${
message.channel.type === ChannelType.DM ? `${message.channel.recipient?.tag}'s DMs` : message.channel.name
diff --git a/src/listeners/message/boosterMessage.ts b/src/listeners/message/boosterMessage.ts
index e33abfb..1a4d3c3 100644
--- a/src/listeners/message/boosterMessage.ts
+++ b/src/listeners/message/boosterMessage.ts
@@ -14,7 +14,7 @@ export default class BoosterMessageListener extends BushListener {
if (!message.guild || !(await message.guild?.hasFeature('boosterMessageReact'))) return;
if (message.type === MessageType.UserPremiumGuildSubscription) {
return await message.react('<:nitroboost:785160348885975062>').catch(() => {
- void client.console.warn('boosterMessage', `Failed to react to <<${message.id}>>.`);
+ void this.client.console.warn('boosterMessage', `Failed to react to <<${message.id}>>.`);
});
}
}
diff --git a/src/listeners/message/directMessage.ts b/src/listeners/message/directMessage.ts
index 463e4d8..7b599d9 100644
--- a/src/listeners/message/directMessage.ts
+++ b/src/listeners/message/directMessage.ts
@@ -1,4 +1,4 @@
-import { BushListener, colors, getConfigChannel, type BushClientEvents } from '#lib';
+import { BushListener, colors, type BushClientEvents } from '#lib';
import { ChannelType, EmbedBuilder } from 'discord.js';
export default class DirectMessageListener extends BushListener {
@@ -12,11 +12,11 @@ export default class DirectMessageListener extends BushListener {
public async exec(...[message]: BushClientEvents['messageCreate']) {
if (message.channel.type === ChannelType.DM) {
- if (!(message.author.id == client.user!.id) && message.author.bot) return;
- if (client.cache.global.blacklistedUsers.includes(message.author.id)) return;
+ if (!(message.author.id == this.client.user!.id) && message.author.bot) return;
+ if (this.client.cache.global.blacklistedUsers.includes(message.author.id)) return;
const dmLogEmbed = new EmbedBuilder().setTimestamp().setFooter({ text: `User ID • ${message.channel.recipientId}` });
- if (message.author.id != client.user!.id) {
+ if (message.author.id != this.client.user!.id) {
dmLogEmbed
.setAuthor({
name: `From: ${message.author.username}`,
@@ -39,7 +39,7 @@ export default class DirectMessageListener extends BushListener {
} else if (message.attachments.size > 0) {
dmLogEmbed.addFields([{ name: 'Attachments', value: message.attachments.map((a) => a.proxyURL).join('\n') }]);
}
- const dmChannel = await getConfigChannel('dm');
+ const dmChannel = await this.client.utils.getConfigChannel('dm');
await dmChannel.send({ embeds: [dmLogEmbed] });
}
}
diff --git a/src/listeners/message/highlight.ts b/src/listeners/message/highlight.ts
index d68337c..d9d3c0b 100644
--- a/src/listeners/message/highlight.ts
+++ b/src/listeners/message/highlight.ts
@@ -14,12 +14,12 @@ export default class HighlightListener extends BushListener {
if (message.author.bot || message.system) return;
if (!(await message.guild.hasFeature('highlight'))) return; // allows highlighting to be disabled on a guild-by-guild basis
- client.highlightManager.updateLastTalked(message);
- const res = client.highlightManager.checkMessage(message);
+ this.client.highlightManager.updateLastTalked(message);
+ const res = this.client.highlightManager.checkMessage(message);
for (const [user, hl] of res.entries()) {
if (message.author.id === user) continue;
- void client.highlightManager.notify(message, user, hl);
+ void this.client.highlightManager.notify(message, user, hl);
}
}
}
diff --git a/src/listeners/message/level.ts b/src/listeners/message/level.ts
index a72ae02..526dac9 100644
--- a/src/listeners/message/level.ts
+++ b/src/listeners/message/level.ts
@@ -1,4 +1,4 @@
-import { BushListener, handleError, Level, type BushCommandHandlerEvents } from '#lib';
+import { BushListener, Level, type BushCommandHandlerEvents } from '#lib';
import { MessageType } from 'discord.js';
export default class LevelListener extends BushListener {
@@ -33,13 +33,14 @@ export default class LevelListener extends BushListener {
const xpToGive = Level.genRandomizedXp();
user.xp = user.xp + xpToGive;
const success = await user.save().catch((e) => {
- void handleError('level', e);
+ void this.client.utils.handleError('level', e);
return false;
});
const newLevel = Level.convertXpToLevel(user.xp);
- if (previousLevel !== newLevel) client.emit('bushLevelUpdate', message.member!, previousLevel, newLevel, user.xp, message);
+ if (previousLevel !== newLevel)
+ this.client.emit('bushLevelUpdate', message.member!, previousLevel, newLevel, user.xp, message);
if (success)
- void client.logger.verbose(`level`, `Gave <<${xpToGive}>> XP to <<${message.author.tag}>> in <<${message.guild}>>.`);
+ void this.client.logger.verbose(`level`, `Gave <<${xpToGive}>> XP to <<${message.author.tag}>> in <<${message.guild}>>.`);
this.#levelCooldowns.add(`${message.guildId}-${message.author.id}`);
setTimeout(() => this.#levelCooldowns.delete(`${message.guildId}-${message.author.id}`), 60_000);
}
diff --git a/src/listeners/message/quoteCreate.ts b/src/listeners/message/quoteCreate.ts
index d43eef7..0478bcf 100644
--- a/src/listeners/message/quoteCreate.ts
+++ b/src/listeners/message/quoteCreate.ts
@@ -1,4 +1,4 @@
-import { BushListener, resolveMessagesFromLinks, type BushClientEvents } from '#lib';
+import { BushListener, type BushClientEvents } from '#lib';
export default class QuoteCreateListener extends BushListener {
public constructor() {
@@ -10,10 +10,10 @@ export default class QuoteCreateListener extends BushListener {
}
public async exec(...[message]: BushClientEvents['messageCreate']) {
- if (message.author.id !== '322862723090219008' || !client.config.isProduction) return;
+ if (message.author.id !== '322862723090219008' || !this.client.config.isProduction) return;
if (!message.inGuild()) return;
- const messages = await resolveMessagesFromLinks(message.content);
+ const messages = await this.client.utils.resolveMessagesFromLinks(message.content);
if (!messages.length) return;
for (const msg of messages) {
diff --git a/src/listeners/message/verbose.ts b/src/listeners/message/verbose.ts
index e3ef04f..f5e94de 100644
--- a/src/listeners/message/verbose.ts
+++ b/src/listeners/message/verbose.ts
@@ -11,9 +11,9 @@ export default class MessageVerboseListener extends BushListener {
}
public exec(...[message]: BushClientEvents['messageCreate']): void {
- if (client.customReady) {
+ if (this.client.customReady) {
if (message.channel?.type === ChannelType.DM) return;
- void client.console.verbose(
+ void this.client.console.verbose(
'messageVerbose',
`A message was sent by <<${message.author.tag}>> in <<${message.channel.name}>> in <<${message.guild!.name}>>.`
);
diff --git a/src/listeners/other/consoleListener.ts b/src/listeners/other/consoleListener.ts
index 543f459..3e72e9e 100644
--- a/src/listeners/other/consoleListener.ts
+++ b/src/listeners/other/consoleListener.ts
@@ -15,8 +15,9 @@ import { promisify } from 'util';
if (line.startsWith('eval ') || line.startsWith('ev ')) {
/* eslint-disable @typescript-eslint/no-unused-vars */
const sh = promisify(exec),
- bot = client,
- config = client.config,
+ bot = this.client,
+ client = this.client,
+ config = this.client.config,
{ ActivePunishment, Global, Guild, Level, ModLog, StickyRole } = await import('#lib'),
{
ButtonInteraction,
diff --git a/src/listeners/other/exit.ts b/src/listeners/other/exit.ts
index e16aeb7..ac074df 100644
--- a/src/listeners/other/exit.ts
+++ b/src/listeners/other/exit.ts
@@ -9,6 +9,6 @@ export default class ExitListener extends BushListener {
}
public async exec(code: number) {
- await client.console.error('processExit', `Process ended with code <<${code}>>.`);
+ await this.client.console.error('processExit', `Process ended with code <<${code}>>.`);
}
}
diff --git a/src/listeners/other/promiseRejection.ts b/src/listeners/other/promiseRejection.ts
index 79bf5de..ab67ad4 100644
--- a/src/listeners/other/promiseRejection.ts
+++ b/src/listeners/other/promiseRejection.ts
@@ -16,14 +16,18 @@ export default class PromiseRejectionListener extends BushListener {
process.removeListener('unhandledRejection', listener);
});
- client.sentry.captureException(error, {
+ this.client.sentry.captureException(error, {
level: 'error'
});
- void client.console.error('promiseRejection', `An unhanded promise rejection occurred:\n${formatError(error, true)}`, false);
+ void this.client.console.error(
+ 'promiseRejection',
+ `An unhanded promise rejection occurred:\n${formatError(error, true)}`,
+ false
+ );
if (!error.message.includes('reason: getaddrinfo ENOTFOUND canary.discord.com'))
- void client.console.channelError({
- embeds: await CommandErrorListener.generateErrorEmbed({ type: 'unhandledRejection', error: error })
+ void this.client.console.channelError({
+ embeds: await CommandErrorListener.generateErrorEmbed(this.client, { type: 'unhandledRejection', error: error })
});
}
}
diff --git a/src/listeners/other/uncaughtException.ts b/src/listeners/other/uncaughtException.ts
index 3e80feb..e06a3b8 100644
--- a/src/listeners/other/uncaughtException.ts
+++ b/src/listeners/other/uncaughtException.ts
@@ -15,13 +15,13 @@ export default class UncaughtExceptionListener extends BushListener {
if (listener.toString() === this.exec.toString()) return;
process.removeListener('uncaughtException', listener);
});
- client.sentry.captureException(error, {
+ this.client.sentry.captureException(error, {
level: 'error'
});
- void client.console.error('uncaughtException', `An uncaught exception occurred:\n${formatError(error, true)}`, false);
- void client.console.channelError({
- embeds: await CommandErrorListener.generateErrorEmbed({ type: 'uncaughtException', error: error })
+ void this.client.console.error('uncaughtException', `An uncaught exception occurred:\n${formatError(error, true)}`, false);
+ void this.client.console.channelError({
+ embeds: await CommandErrorListener.generateErrorEmbed(this.client, { type: 'uncaughtException', error: error })
});
}
}
diff --git a/src/listeners/other/warning.ts b/src/listeners/other/warning.ts
index ba38f5f..b427e4c 100644
--- a/src/listeners/other/warning.ts
+++ b/src/listeners/other/warning.ts
@@ -12,15 +12,15 @@ export default class WarningListener extends BushListener {
public async exec(error: Error) {
if (error.name === 'ExperimentalWarning') return;
- client.sentry.captureException(error, {
+ this.client.sentry.captureException(error, {
level: 'warning'
});
- void client.console.warn('warning', `A warning occurred:\n${formatError(error, true)}`, false);
+ void this.client.console.warn('warning', `A warning occurred:\n${formatError(error, true)}`, false);
- const embeds = await CommandErrorListener.generateErrorEmbed({ type: 'unhandledRejection', error: error });
+ const embeds = await CommandErrorListener.generateErrorEmbed(this.client, { type: 'unhandledRejection', error: error });
embeds[0].setColor(colors.warn).setTitle('A Warning Occurred');
- void client.console.channelError({ embeds });
+ void this.client.console.channelError({ embeds });
}
}
diff --git a/src/listeners/rest/rateLimit.ts b/src/listeners/rest/rateLimit.ts
index 5878d81..9071416 100644
--- a/src/listeners/rest/rateLimit.ts
+++ b/src/listeners/rest/rateLimit.ts
@@ -11,6 +11,6 @@ export default class RateLimitedListener extends BushListener {
}
public async exec(...[message]: RestEvents['rateLimited']): Promise<void> {
- void client.console.superVerboseRaw('rateLimited', message);
+ void this.client.console.superVerboseRaw('rateLimited', message);
}
}
diff --git a/src/listeners/track-manual-punishments/modlogSyncBan.ts b/src/listeners/track-manual-punishments/modlogSyncBan.ts
index 45d6f51..a387897 100644
--- a/src/listeners/track-manual-punishments/modlogSyncBan.ts
+++ b/src/listeners/track-manual-punishments/modlogSyncBan.ts
@@ -37,6 +37,7 @@ export default class ModlogSyncBanListener extends BushListener {
}
const { log } = await Moderation.createModLogEntry({
+ client: this.client,
type: ModLogType.PERM_BAN,
user: ban.user,
moderator: first.executor,
diff --git a/src/listeners/track-manual-punishments/modlogSyncKick.ts b/src/listeners/track-manual-punishments/modlogSyncKick.ts
index d901f5f..51d3dd8 100644
--- a/src/listeners/track-manual-punishments/modlogSyncKick.ts
+++ b/src/listeners/track-manual-punishments/modlogSyncKick.ts
@@ -37,6 +37,7 @@ export default class ModlogSyncKickListener extends BushListener {
}
const { log } = await Moderation.createModLogEntry({
+ client: this.client,
type: ModLogType.KICK,
user: member.user,
moderator: first.executor,
diff --git a/src/listeners/track-manual-punishments/modlogSyncTimeout.ts b/src/listeners/track-manual-punishments/modlogSyncTimeout.ts
index 4619edd..2ce3db2 100644
--- a/src/listeners/track-manual-punishments/modlogSyncTimeout.ts
+++ b/src/listeners/track-manual-punishments/modlogSyncTimeout.ts
@@ -41,6 +41,7 @@ export default class ModlogSyncTimeoutListener extends BushListener {
const newTime = <string | null>timeOut.new ? new Date(<string>timeOut.new) : null;
const { log } = await Moderation.createModLogEntry({
+ client: this.client,
type: newTime ? ModLogType.TIMEOUT : ModLogType.REMOVE_TIMEOUT,
user: newMember.user,
moderator: first.executor,
diff --git a/src/listeners/track-manual-punishments/modlogSyncUnban.ts b/src/listeners/track-manual-punishments/modlogSyncUnban.ts
index 34979a5..2207e78 100644
--- a/src/listeners/track-manual-punishments/modlogSyncUnban.ts
+++ b/src/listeners/track-manual-punishments/modlogSyncUnban.ts
@@ -36,6 +36,7 @@ export default class ModlogSyncUnbanListener extends BushListener {
}
const { log } = await Moderation.createModLogEntry({
+ client: this.client,
type: ModLogType.UNBAN,
user: ban.user,
moderator: first.executor,
diff --git a/src/listeners/ws/INTERACTION_CREATE.ts b/src/listeners/ws/INTERACTION_CREATE.ts
index 5f479ad..0e8ee7c 100644
--- a/src/listeners/ws/INTERACTION_CREATE.ts
+++ b/src/listeners/ws/INTERACTION_CREATE.ts
@@ -62,7 +62,7 @@ export default class WsInteractionCreateListener extends BushListener {
string
];
- const guild = client.guilds.resolve(guildId);
+ const guild = this.client.guilds.resolve(guildId);
if (!guild)
return respond({
type: InteractionResponseType.ChannelMessageWithSource,
@@ -137,8 +137,8 @@ export default class WsInteractionCreateListener extends BushListener {
];
if (action === 'appeal_deny') {
- await client.users
- .send(userId, `Your ${punishment} appeal has been denied in ${client.guilds.resolve(guildId)!}.`)
+ await this.client.users
+ .send(userId, `Your ${punishment} appeal has been denied in ${this.client.guilds.resolve(guildId)!}.`)
.catch(() => {});
void respond({
@@ -172,7 +172,7 @@ export default class WsInteractionCreateListener extends BushListener {
string
];
- const guild = client.guilds.resolve(guildId);
+ const guild = this.client.guilds.resolve(guildId);
if (!guild)
return respond({
type: InteractionResponseType.ChannelMessageWithSource,
@@ -191,7 +191,7 @@ export default class WsInteractionCreateListener extends BushListener {
});
assert(interaction.user);
- const user = new User(client, interaction.user);
+ const user = new User(this.client, interaction.user);
assert(user);
// const caseId = await ModLog.findOne({ where: { user: userId, guild: guildId, id: modlogCase } });
diff --git a/src/tasks/cpuUsage.ts b/src/tasks/cpuUsage.ts
index 6ce6671..f456c31 100644
--- a/src/tasks/cpuUsage.ts
+++ b/src/tasks/cpuUsage.ts
@@ -1,5 +1,5 @@
import { BushTask, Time } from '#lib';
-import { cpu } from 'node-os-utils';
+import osu from 'node-os-utils';
export default class CpuUsageTask extends BushTask {
public constructor() {
@@ -10,7 +10,7 @@ export default class CpuUsageTask extends BushTask {
}
public async exec() {
- const cpuStats = await cpu.usage(client.stats.cpu === undefined ? 100 * Time.Millisecond : Time.Minute);
- client.stats.cpu = cpuStats;
+ const cpuStats = await osu.cpu.usage(this.client.stats.cpu === undefined ? 100 * Time.Millisecond : Time.Minute);
+ this.client.stats.cpu = cpuStats;
}
}
diff --git a/src/tasks/handleReminders.ts b/src/tasks/handleReminders.ts
index 79693f5..7863c9a 100644
--- a/src/tasks/handleReminders.ts
+++ b/src/tasks/handleReminders.ts
@@ -19,11 +19,14 @@ export default class HandlerRemindersTask extends BushTask {
}
});
- void client.logger.verbose(`handlerReminders`, `Queried reminders, found <<${expiredEntries.length}>> expired reminders.`);
+ void this.client.logger.verbose(
+ `handlerReminders`,
+ `Queried reminders, found <<${expiredEntries.length}>> expired reminders.`
+ );
for (const entry of expiredEntries) {
setTimeout(() => {
- void client.users
+ void this.client.users
.send(
entry.user,
`The reminder you set ${dateDelta(entry.created)} ago has expired: ${format.bold(entry.content)}\n${entry.messageUrl}`
diff --git a/src/tasks/memberCount.ts b/src/tasks/memberCount.ts
index fa51080..ea422fa 100644
--- a/src/tasks/memberCount.ts
+++ b/src/tasks/memberCount.ts
@@ -10,10 +10,10 @@ export default class MemberCountTask extends BushTask {
}
public override async exec() {
- if (!client.config.isProduction) return;
+ if (!this.client.config.isProduction) return;
const res = await Promise.allSettled(
- client.guilds.cache
+ this.client.guilds.cache
.filter((g) => g.memberCount >= 100)
.map((g) => MemberCount.create({ guildId: g.id, memberCount: g.memberCount }))
);
@@ -22,7 +22,7 @@ export default class MemberCountTask extends BushTask {
.filter((r) => r.status === 'rejected')
.forEach((r) => {
assert(r.status === 'rejected');
- void client.console.error('memberCount', r.status);
+ void this.client.console.error('memberCount', r.status);
});
}
}
diff --git a/src/tasks/removeExpiredPunishements.ts b/src/tasks/removeExpiredPunishements.ts
index 3f6f6dd..0b20a27 100644
--- a/src/tasks/removeExpiredPunishements.ts
+++ b/src/tasks/removeExpiredPunishements.ts
@@ -1,4 +1,4 @@
-import { ActivePunishment, ActivePunishmentType, BushTask, resolveNonCachedUser, Time } from '#lib';
+import { ActivePunishment, ActivePunishmentType, BushTask, Time } from '#lib';
import assert from 'assert';
const { Op } = (await import('sequelize')).default;
@@ -19,19 +19,19 @@ export default class RemoveExpiredPunishmentsTask extends BushTask {
}
});
- void client.logger.verbose(
+ void this.client.logger.verbose(
`removeExpiredPunishments`,
`Queried punishments, found <<${expiredEntries.length}>> expired punishments.`
);
for (const entry of expiredEntries) {
- const guild = client.guilds.cache.get(entry.guild);
+ const guild = this.client.guilds.cache.get(entry.guild);
if (!guild) continue;
// eslint-disable-next-line @typescript-eslint/no-misused-promises
setTimeout(async () => {
const member = guild.members.cache.get(entry.user);
- const user = await resolveNonCachedUser(entry.user);
+ const user = await this.client.utils.resolveNonCachedUser(entry.user);
assert(guild);
switch (entry.type) {
@@ -40,7 +40,7 @@ export default class RemoveExpiredPunishmentsTask extends BushTask {
const result = await guild.bushUnban({ user: user, reason: 'Punishment expired' });
if (['success', 'user not banned', 'cannot resolve user'].includes(result)) await entry.destroy();
else throw new Error(result);
- void client.logger.verbose(`removeExpiredPunishments`, `Unbanned ${entry.user}.`);
+ void this.client.logger.verbose(`removeExpiredPunishments`, `Unbanned ${entry.user}.`);
break;
}
case ActivePunishmentType.BLOCK: {
@@ -51,7 +51,7 @@ export default class RemoveExpiredPunishmentsTask extends BushTask {
const result = await member.bushUnblock({ reason: 'Punishment expired', channel: entry.extraInfo });
if (['success', 'user not blocked'].includes(result)) await entry.destroy();
else throw new Error(result);
- void client.logger.verbose(`removeExpiredPunishments`, `Unblocked ${entry.user}.`);
+ void this.client.logger.verbose(`removeExpiredPunishments`, `Unblocked ${entry.user}.`);
break;
}
case ActivePunishmentType.MUTE: {
@@ -59,7 +59,7 @@ export default class RemoveExpiredPunishmentsTask extends BushTask {
const result = await member.bushUnmute({ reason: 'Punishment expired' });
if (['success', 'failed to dm'].includes(result)) await entry.destroy();
else throw new Error(result);
- void client.logger.verbose(`removeExpiredPunishments`, `Unmuted ${entry.user}.`);
+ void this.client.logger.verbose(`removeExpiredPunishments`, `Unmuted ${entry.user}.`);
break;
}
case ActivePunishmentType.ROLE: {
@@ -74,7 +74,7 @@ export default class RemoveExpiredPunishmentsTask extends BushTask {
if (['success', 'failed to dm'].includes(result)) await entry.destroy();
else throw new Error(result);
- void client.logger.verbose(`removeExpiredPunishments`, `Removed a punishment role from ${entry.user}.`);
+ void this.client.logger.verbose(`removeExpiredPunishments`, `Removed a punishment role from ${entry.user}.`);
break;
}
}
diff --git a/src/tasks/updateCache.ts b/src/tasks/updateCache.ts
index 487b9bc..0dc49df 100644
--- a/src/tasks/updateCache.ts
+++ b/src/tasks/updateCache.ts
@@ -1,5 +1,6 @@
import { Time } from '#constants';
import { Global, Guild, Shared, type BushClient } from '#lib';
+import { Client } from 'discord.js';
import config from '../../config/options.js';
import { BushTask } from '../lib/extensions/discord-akairo/BushTask.js';
@@ -13,11 +14,11 @@ export default class UpdateCacheTask extends BushTask {
public async exec() {
await Promise.all([
- UpdateCacheTask.#updateGlobalCache(client),
- UpdateCacheTask.#updateSharedCache(client),
- UpdateCacheTask.#updateGuildCache(client)
+ UpdateCacheTask.#updateGlobalCache(this.client),
+ UpdateCacheTask.#updateSharedCache(this.client),
+ UpdateCacheTask.#updateGuildCache(this.client)
]);
- void client.logger.verbose(`UpdateCache`, `Updated cache.`);
+ void this.client.logger.verbose(`UpdateCache`, `Updated cache.`);
}
public static async init(client: BushClient) {
@@ -28,7 +29,7 @@ export default class UpdateCacheTask extends BushTask {
]);
}
- static async #updateGlobalCache(client: BushClient) {
+ static async #updateGlobalCache(client: Client) {
const environment = config.environment;
const row: { [x: string]: any } = ((await Global.findByPk(environment)) ?? (await Global.create({ environment }))).toJSON();
@@ -39,7 +40,7 @@ export default class UpdateCacheTask extends BushTask {
}
}
- static async #updateSharedCache(client: BushClient) {
+ static async #updateSharedCache(client: Client) {
const row: { [x: string]: any } = ((await Shared.findByPk(0)) ?? (await Shared.create())).toJSON();
for (const option in row) {
@@ -50,7 +51,7 @@ export default class UpdateCacheTask extends BushTask {
}
}
- static async #updateGuildCache(client: BushClient) {
+ static async #updateGuildCache(client: Client) {
const rows = await Guild.findAll();
for (const row of rows) {
client.cache.guilds.set(row.id, row.toJSON() as Guild);
diff --git a/src/tasks/updateHighlightCache.ts b/src/tasks/updateHighlightCache.ts
index d4fca71..4677ea7 100644
--- a/src/tasks/updateHighlightCache.ts
+++ b/src/tasks/updateHighlightCache.ts
@@ -10,6 +10,6 @@ export default class UpdateHighlightCacheTask extends BushTask {
}
public async exec() {
- return client.highlightManager.syncCache();
+ return this.client.highlightManager.syncCache();
}
}
diff --git a/src/tasks/updateStats.ts b/src/tasks/updateStats.ts
index 0e50c23..0d0e661 100644
--- a/src/tasks/updateStats.ts
+++ b/src/tasks/updateStats.ts
@@ -1,4 +1,5 @@
import { BushTask, Stat, Time } from '#lib';
+import { Client } from 'discord.js';
export default class UpdateStatsTask extends BushTask {
public constructor() {
@@ -10,13 +11,14 @@ export default class UpdateStatsTask extends BushTask {
public async exec() {
const row =
- (await Stat.findByPk(client.config.environment)) ?? (await Stat.create({ environment: client.config.environment }));
- row.commandsUsed = client.stats.commandsUsed;
- row.slashCommandsUsed = client.stats.slashCommandsUsed;
+ (await Stat.findByPk(this.client.config.environment)) ??
+ (await Stat.create({ environment: this.client.config.environment }));
+ row.commandsUsed = this.client.stats.commandsUsed;
+ row.slashCommandsUsed = this.client.stats.slashCommandsUsed;
await row.save();
}
- public static async init(): Promise<{ commandsUsed: bigint; slashCommandsUsed: bigint }> {
+ public static async init(client: Client): Promise<{ commandsUsed: bigint; slashCommandsUsed: bigint }> {
const temp =
(await Stat.findByPk(client.config.environment)) ?? (await Stat.create({ environment: client.config.environment }));
return { commandsUsed: temp.commandsUsed, slashCommandsUsed: temp.slashCommandsUsed };