aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.pnp.cjs33
-rw-r--r--.vscode/extensions.json6
-rw-r--r--package.json6
-rw-r--r--src/commands/_fake-command/test.ts18
-rw-r--r--src/commands/admin/channelPermissions.ts97
-rw-r--r--src/commands/config/autoPublishChannel.ts21
-rw-r--r--src/commands/config/blacklist.ts132
-rw-r--r--src/commands/config/disable.ts128
-rw-r--r--src/commands/config/prefix.ts20
-rw-r--r--src/commands/dev/__template.ts61
-rw-r--r--src/commands/dev/eval.ts10
-rw-r--r--src/commands/dev/servers.ts48
-rw-r--r--src/commands/dev/setLevel.ts6
-rw-r--r--src/commands/dev/sh.ts84
-rw-r--r--src/commands/info/color.ts47
-rw-r--r--src/commands/info/help.ts42
-rw-r--r--src/commands/info/userInfo.ts2
-rw-r--r--src/commands/moderation/ban.ts15
-rw-r--r--src/commands/moderation/kick.ts13
-rw-r--r--src/commands/moderation/lockdown.ts45
-rw-r--r--src/commands/moderation/modlog.ts2
-rw-r--r--src/commands/moderation/mute.ts10
-rw-r--r--src/commands/moderation/warn.ts10
-rw-r--r--src/commands/moulberry-bush/capePerms.ts33
-rw-r--r--src/commands/moulberry-bush/level.ts8
-rw-r--r--src/commands/moulberry-bush/report.ts121
-rw-r--r--src/commands/moulberry-bush/rule.ts25
-rw-r--r--src/commands/skyblock-reborn/chooseColorCommand.ts (renamed from src/commands/skyblockReborn/chooseColorCommand.ts)0
-rw-r--r--src/commands/utilities/_whoHasRole.ts0
-rw-r--r--src/commands/utilities/hash.ts42
-rw-r--r--src/commands/utilities/price.ts220
-rw-r--r--src/commands/utilities/viewraw.ts2
-rw-r--r--src/commands/utilities/whoHasRole.ts53
-rw-r--r--src/config/example-options.ts3
-rw-r--r--src/inhibitors/blacklist/channelGlobalBlacklist.ts25
-rw-r--r--src/inhibitors/blacklist/channelGuildBlacklist.ts25
-rw-r--r--src/inhibitors/blacklist/guildBlacklist.ts8
-rw-r--r--src/inhibitors/blacklist/userBlacklist.ts20
-rw-r--r--src/inhibitors/blacklist/userGlobalBlacklist.ts25
-rw-r--r--src/inhibitors/blacklist/userGuildBlacklist.ts25
-rw-r--r--src/inhibitors/commands/disabledCommand.ts19
-rw-r--r--src/inhibitors/commands/globalDisabledCommand.ts19
-rw-r--r--src/inhibitors/commands/guildDisabledCommand.ts21
-rw-r--r--src/lib/extensions/discord-akairo/BushClientUtil.ts30
-rw-r--r--src/lib/extensions/discord-akairo/BushCommand.ts5
-rw-r--r--src/lib/extensions/discord.js/BushGuild.ts2
-rw-r--r--src/lib/models/Global.ts15
-rw-r--r--src/lib/models/Guild.ts48
-rw-r--r--src/lib/models/Level.ts19
-rw-r--r--src/lib/utils/BushConstants.ts6
-rw-r--r--src/listeners/client/interactionCreate.ts (renamed from src/listeners/client/interaction.ts)6
-rw-r--r--src/listeners/commands/commandBlocked.ts10
-rw-r--r--src/listeners/commands/commandError.ts8
-rw-r--r--src/listeners/commands/slashBlocked.ts10
-rw-r--r--src/listeners/commands/slashCommandError.ts8
-rw-r--r--src/listeners/message/level.ts24
-rw-r--r--yarn.lock24
57 files changed, 1551 insertions, 214 deletions
diff --git a/.pnp.cjs b/.pnp.cjs
index f02a88a..7a9fd13 100755
--- a/.pnp.cjs
+++ b/.pnp.cjs
@@ -41,6 +41,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["@types/humanize-duration", "npm:3.25.1"],
["@types/module-alias", "npm:2.0.1"],
["@types/node", "npm:14.17.5"],
+ ["@types/tinycolor2", "npm:1.4.3"],
["@types/uuid", "npm:8.3.1"],
["@typescript-eslint/eslint-plugin", "virtual:d7ae587dddcefd495158f5c047acecbca3203324d75e681c7d8657c07f901f74e152f0b39978f7428d3a91daad7b5020c47ece28de69c22fcbd49d04707bf15c#npm:4.28.2"],
["@typescript-eslint/parser", "virtual:d7ae587dddcefd495158f5c047acecbca3203324d75e681c7d8657c07f901f74e152f0b39978f7428d3a91daad7b5020c47ece28de69c22fcbd49d04707bf15c#npm:4.28.2"],
@@ -54,6 +55,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["esbuild", "npm:0.12.15"],
["eslint", "npm:7.30.0"],
["eslint-config-prettier", "virtual:d7ae587dddcefd495158f5c047acecbca3203324d75e681c7d8657c07f901f74e152f0b39978f7428d3a91daad7b5020c47ece28de69c22fcbd49d04707bf15c#npm:8.3.0"],
+ ["fuse.js", "npm:6.4.6"],
["got", "npm:11.8.2"],
["humanize-duration", "npm:3.27.0"],
["madge", "npm:5.0.1"],
@@ -65,6 +67,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["rimraf", "npm:3.0.2"],
["sequelize", "virtual:d7ae587dddcefd495158f5c047acecbca3203324d75e681c7d8657c07f901f74e152f0b39978f7428d3a91daad7b5020c47ece28de69c22fcbd49d04707bf15c#npm:6.6.5"],
["source-map-support", "npm:0.5.19"],
+ ["tinycolor2", "npm:1.4.2"],
["typescript", "patch:typescript@npm%3A4.2.4#~builtin<compat/typescript>::version=4.2.4&hash=d8b4e7"],
["uuid", "npm:8.3.2"]
],
@@ -445,6 +448,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD",
}]
]],
+ ["@types/tinycolor2", [
+ ["npm:1.4.3", {
+ "packageLocation": "./.yarn/cache/@types-tinycolor2-npm-1.4.3-90e6bf0ed8-61984b2825.zip/node_modules/@types/tinycolor2/",
+ "packageDependencies": [
+ ["@types/tinycolor2", "npm:1.4.3"]
+ ],
+ "linkType": "HARD",
+ }]
+ ]],
["@types/uuid", [
["npm:8.3.1", {
"packageLocation": "./.yarn/cache/@types-uuid-npm-8.3.1-4239b14bac-b41bdc5e86.zip/node_modules/@types/uuid/",
@@ -924,6 +936,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["@types/humanize-duration", "npm:3.25.1"],
["@types/module-alias", "npm:2.0.1"],
["@types/node", "npm:14.17.5"],
+ ["@types/tinycolor2", "npm:1.4.3"],
["@types/uuid", "npm:8.3.1"],
["@typescript-eslint/eslint-plugin", "virtual:d7ae587dddcefd495158f5c047acecbca3203324d75e681c7d8657c07f901f74e152f0b39978f7428d3a91daad7b5020c47ece28de69c22fcbd49d04707bf15c#npm:4.28.2"],
["@typescript-eslint/parser", "virtual:d7ae587dddcefd495158f5c047acecbca3203324d75e681c7d8657c07f901f74e152f0b39978f7428d3a91daad7b5020c47ece28de69c22fcbd49d04707bf15c#npm:4.28.2"],
@@ -937,6 +950,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["esbuild", "npm:0.12.15"],
["eslint", "npm:7.30.0"],
["eslint-config-prettier", "virtual:d7ae587dddcefd495158f5c047acecbca3203324d75e681c7d8657c07f901f74e152f0b39978f7428d3a91daad7b5020c47ece28de69c22fcbd49d04707bf15c#npm:8.3.0"],
+ ["fuse.js", "npm:6.4.6"],
["got", "npm:11.8.2"],
["humanize-duration", "npm:3.27.0"],
["madge", "npm:5.0.1"],
@@ -948,6 +962,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["rimraf", "npm:3.0.2"],
["sequelize", "virtual:d7ae587dddcefd495158f5c047acecbca3203324d75e681c7d8657c07f901f74e152f0b39978f7428d3a91daad7b5020c47ece28de69c22fcbd49d04707bf15c#npm:6.6.5"],
["source-map-support", "npm:0.5.19"],
+ ["tinycolor2", "npm:1.4.2"],
["typescript", "patch:typescript@npm%3A4.2.4#~builtin<compat/typescript>::version=4.2.4&hash=d8b4e7"],
["uuid", "npm:8.3.2"]
],
@@ -1940,6 +1955,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD",
}]
]],
+ ["fuse.js", [
+ ["npm:6.4.6", {
+ "packageLocation": "./.yarn/cache/fuse.js-npm-6.4.6-0fa81ef443-012dfacdc9.zip/node_modules/fuse.js/",
+ "packageDependencies": [
+ ["fuse.js", "npm:6.4.6"]
+ ],
+ "linkType": "HARD",
+ }]
+ ]],
["get-amd-module-type", [
["npm:3.0.0", {
"packageLocation": "./.yarn/cache/get-amd-module-type-npm-3.0.0-2fcd610976-a2df61d329.zip/node_modules/get-amd-module-type/",
@@ -3792,6 +3816,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD",
}]
]],
+ ["tinycolor2", [
+ ["npm:1.4.2", {
+ "packageLocation": "./.yarn/cache/tinycolor2-npm-1.4.2-462ba30c26-57ed262e08.zip/node_modules/tinycolor2/",
+ "packageDependencies": [
+ ["tinycolor2", "npm:1.4.2"]
+ ],
+ "linkType": "HARD",
+ }]
+ ]],
["to-fast-properties", [
["npm:2.0.0", {
"packageLocation": "./.yarn/cache/to-fast-properties-npm-2.0.0-0dc60cc481-be2de62fe5.zip/node_modules/to-fast-properties/",
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
index d3de569..d56ae08 100644
--- a/.vscode/extensions.json
+++ b/.vscode/extensions.json
@@ -5,6 +5,8 @@
"dbaeumer.vscode-eslint",
"eamodio.gitlens",
"esbenp.prettier-vscode",
- "streetsidesoftware.code-spell-checker"
+ "streetsidesoftware.code-spell-checker",
+ "github.vscode-pull-request-github",
+ "ckolkman.vscode-postgres"
]
-}
+} \ No newline at end of file
diff --git a/package.json b/package.json
index ba908f8..2a4b4a1 100644
--- a/package.json
+++ b/package.json
@@ -12,7 +12,8 @@
"scripts": {
"build-esbuild": "yarn rimraf dist && yarn esbuild --sourcemap=inline --minify-whitespace --minify-syntax --outdir=dist --platform=node --target=es2020 --format=cjs --log-level=warning src/**/*.ts",
"build-tsc": "yarn rimraf dist && yarn tsc",
- "start": "yarn build-esbuild && node --trace-warnings -r source-map-support/register dist/bot.js",
+ "_start": "yarn build-esbuild && node --trace-warnings -r source-map-support/register dist/bot.js",
+ "start": "yarn build-tsc && node --trace-warnings -r source-map-support/register dist/bot.js",
"dev": "yarn build-tsc && node --trace-warnings -r source-map-support/register dist/bot.js",
"test": "yarn lint && yarn tsc --noEmit",
"format": "yarn prettier . --write",
@@ -26,6 +27,7 @@
"@types/humanize-duration": "^3",
"@types/module-alias": "^2",
"@types/node": "^14.14.22",
+ "@types/tinycolor2": "^1",
"@types/uuid": "^8.3.0",
"@typescript-eslint/eslint-plugin": "^4.14.1",
"@typescript-eslint/parser": "^4.14.1",
@@ -46,6 +48,7 @@
"discord-api-types": "0.19.0-next.f393ba520d7d6d2aacaca7b3ca5d355fab614f6e",
"discord.js": "NotEnoughUpdates/discord.js",
"discord.js-minesweeper": "^1.0.6",
+ "fuse.js": "^6.4.6",
"got": "^11.8.2",
"humanize-duration": "^3.27.0",
"madge": "^5.0.1",
@@ -54,6 +57,7 @@
"pg": "^8.5.1",
"pg-hstore": "^2.3.3",
"sequelize": "^6.5.0",
+ "tinycolor2": "^1.4.2",
"uuid": "^8.3.2"
},
"eslintConfig": {
diff --git a/src/commands/_fake-command/test.ts b/src/commands/_fake-command/test.ts
new file mode 100644
index 0000000..8eeca9e
--- /dev/null
+++ b/src/commands/_fake-command/test.ts
@@ -0,0 +1,18 @@
+import { BushCommand, BushMessage, BushSlashMessage } from '@lib';
+
+export default class TestCommand extends BushCommand {
+ public constructor() {
+ super('test', {
+ category: 'fake-commands',
+ description: { content: '', examples: '', usage: '' },
+ condition: (message: BushMessage) => {
+ if (message.content.toLowerCase().includes('ironmoon')) return true;
+ else return false;
+ },
+ completelyHide: true
+ });
+ }
+ public async exec(message: BushMessage | BushSlashMessage): Promise<unknown> {
+ return await message.util.reply('Your message included the word ironmoon.');
+ }
+}
diff --git a/src/commands/admin/channelPermissions.ts b/src/commands/admin/channelPermissions.ts
new file mode 100644
index 0000000..249789d
--- /dev/null
+++ b/src/commands/admin/channelPermissions.ts
@@ -0,0 +1,97 @@
+import { Argument, Constants } from 'discord-akairo';
+import { GuildChannel, GuildMember, MessageEmbed, Role } from 'discord.js';
+import { BushCommand, BushMessage } from '../../lib';
+
+export default class ChannelPermissionsCommand extends BushCommand {
+ public constructor() {
+ super('channelpermissions', {
+ aliases: ['channelperms', 'cperms', 'cperm', 'chanperms', 'chanperm', 'channelpermissions'],
+ category: 'admin',
+ typing: true,
+ description: {
+ content: 'Use to mass change the channel ',
+ usage: 'ChannelPerms <role_id> <perm> <state>',
+ examples: ['ChannelPerms 783794633129197589 read_messages deny']
+ },
+ args: [
+ {
+ id: 'target',
+ type: Argument.union(Constants.ArgumentTypes.ROLE, Constants.ArgumentTypes.MEMBER),
+ match: Constants.ArgumentMatches.PHRASE,
+ prompt: {
+ start: 'What user/role would you like to change?',
+ retry: 'Invalid response. What user/role would you like to change?'
+ }
+ },
+ {
+ id: 'permission',
+ type: 'permission',
+ match: Constants.ArgumentMatches.PHRASE,
+ prompt: {
+ start: 'What permission would you like to change?',
+ retry: '{error} Choose a valid permission.'
+ }
+ },
+ {
+ id: 'state',
+ type: [
+ ['true', '1', 'yes', 'enable', 'allow'],
+ ['false', '0', 'no', 'disable', 'disallow', 'deny'],
+ ['neutral', 'remove', 'none']
+ ],
+ match: Constants.ArgumentMatches.PHRASE,
+ prompt: {
+ start: 'What should that permission be set to?',
+ retry: '{error} Set the state to either `enable`, `disable`, or `remove`.'
+ }
+ }
+ ],
+ ratelimit: 4,
+ cooldown: 4000,
+ clientPermissions: ['MANAGE_CHANNELS', 'SEND_MESSAGES'],
+ userPermissions: ['ADMINISTRATOR'],
+ channel: 'guild'
+ });
+ }
+
+ public async exec(
+ message: BushMessage,
+ {
+ target,
+ permission,
+ state
+ }: {
+ target: Role | GuildMember;
+ permission: string;
+ state: 'true' | 'false' | 'neutral';
+ }
+ ): Promise<void> {
+ const failedChannels = [];
+ for (const channel of message.guild.channels.cache.array()) {
+ try {
+ if (channel.isThread()) return;
+ if (channel.permissionsLocked) return;
+ const permissionState = state === 'true' ? true : state === 'false' ? false : null;
+ await channel.permissionOverwrites.create(
+ target.id,
+ { [permission]: permissionState },
+ { reason: 'Changing overwrites for mass channel channel perms command' }
+ );
+ } catch (e) {
+ this.client.console.debug(e.stack);
+ failedChannels.push(channel);
+ }
+ }
+ const failure = failedChannels.map((e: GuildChannel) => `<#${e.id}>`).join(' ');
+ if (failure.length > 2000) {
+ const paginate: MessageEmbed[] = [];
+ for (let i = 0; i < failure.length; i += 2000) {
+ paginate.push(new MessageEmbed().setDescription(failure.substring(i, Math.min(failure.length, i + 2000))));
+ }
+ const normalMessage = `Finished changing perms! Failed channels:`;
+ this.client.util.buttonPaginate(message, paginate, normalMessage);
+ } else {
+ await message.util.reply({ content: `Finished changing perms! Failed channels:`, embeds: [{ description: failure }] });
+ }
+ }
+}
diff --git a/src/commands/config/autoPublishChannel.ts b/src/commands/config/autoPublishChannel.ts
index 421e030..a2692e2 100644
--- a/src/commands/config/autoPublishChannel.ts
+++ b/src/commands/config/autoPublishChannel.ts
@@ -1,4 +1,4 @@
-import { BushCommand, BushMessage } from '@lib';
+import { AllowedMentions, BushCommand, BushMessage } from '@lib';
import { Channel } from 'discord.js';
export default class AutoPublishChannelCommand extends BushCommand {
@@ -40,14 +40,17 @@ export default class AutoPublishChannelCommand extends BushCommand {
public async exec(message: BushMessage, { channel }: { channel: Channel }): Promise<unknown> {
const autoPublishChannels = await message.guild.getSetting('autoPublishChannels');
- autoPublishChannels.includes(channel.id)
- ? autoPublishChannels.splice(autoPublishChannels.indexOf(channel.id), 1)
- : autoPublishChannels.push(channel.id);
- await message.guild.setSetting('autoPublishChannels', autoPublishChannels);
- return await message.util.reply(
- `${this.client.util.emojis.success} Successfully ${
- autoPublishChannels.includes(channel.id) ? 'disabled' : 'enabled'
- } auto publishing in <#${channel.id}>.`
+ const newValue = this.client.util.addOrRemoveFromArray(
+ autoPublishChannels.includes(channel.id) ? 'remove' : 'add',
+ autoPublishChannels,
+ channel.id
);
+ await message.guild.setSetting('autoPublishChannels', newValue);
+ return await message.util.reply({
+ content: `${this.client.util.emojis.success} Successfully ${
+ autoPublishChannels.includes(channel.id) ? 'disabled' : 'enabled'
+ } auto publishing in <#${channel.id}>.`,
+ allowedMentions: AllowedMentions.none()
+ });
}
}
diff --git a/src/commands/config/blacklist.ts b/src/commands/config/blacklist.ts
new file mode 100644
index 0000000..4706041
--- /dev/null
+++ b/src/commands/config/blacklist.ts
@@ -0,0 +1,132 @@
+import { AllowedMentions, BushCommand, BushMessage, BushSlashMessage, Global } from '@lib';
+import { Argument } from 'discord-akairo';
+import { Channel, User } from 'discord.js';
+
+export default class BlacklistCommand extends BushCommand {
+ public constructor() {
+ super('blacklist', {
+ aliases: ['blacklist', 'unblacklist'],
+ category: 'config',
+ description: {
+ content: 'A command to blacklist users and channels.',
+ usage: 'blacklist|unblacklist <user|channel>',
+ examples: ['blacklist @user', 'unblacklist #channel']
+ },
+ args: [
+ {
+ id: 'target',
+ type: Argument.union('channel', 'user'),
+ match: 'phrase',
+ prompt: {
+ start: 'What channel or user that you would like to blacklist/unblacklist?',
+ retry: '{error} Pick a valid command.',
+ optional: false
+ }
+ },
+ {
+ id: 'global',
+ match: 'flag',
+ flag: '--global'
+ }
+ ],
+ slash: true,
+ slashOptions: [
+ {
+ name: 'action',
+ description: 'Would you like to add or remove someone or something from/to the blacklist?',
+ type: 'STRING',
+ choices: [
+ {
+ name: 'blacklist',
+ value: 'blacklist'
+ },
+ {
+ name: 'unblacklist',
+ value: 'unblacklist'
+ }
+ ],
+ required: true
+ },
+ {
+ name: 'target',
+ description: 'What channel or user that you would like to blacklist/unblacklist?',
+ type: 'STRING',
+ required: true
+ }
+ ],
+ channel: 'guild',
+ clientPermissions: ['SEND_MESSAGES'],
+ userPermissions: ['SEND_MESSAGES', 'MANAGE_GUILD']
+ });
+ }
+
+ public async exec(
+ message: BushMessage | BushSlashMessage,
+ args: { action: 'blacklist' | 'unblacklist'; target: Channel | User | string; global: boolean }
+ ): Promise<unknown> {
+ let action: 'blacklist' | 'unblacklist' | 'toggle' =
+ args.action ?? (message?.util?.parsed?.alias as 'blacklist' | 'unblacklist') ?? 'toggle';
+ const global = args.global && message.author.isOwner();
+ const target =
+ typeof args.target === 'string'
+ ? (await Argument.cast('channel', this.client.commandHandler.resolver, message as BushMessage, args.target)) ??
+ (await Argument.cast('user', this.client.commandHandler.resolver, message as BushMessage, args.target))
+ : args.target;
+ if (!target) return await message.util.reply(`${this.client.util.emojis.error} Choose a valid channel or user.`);
+ const targetID = target.id;
+
+ if (global) {
+ if (action === 'toggle') {
+ const blacklistedUsers = (await Global.findByPk(this.client.config.dev ? 'development' : 'production'))
+ .blacklistedUsers;
+ const blacklistedChannels = (await Global.findByPk(this.client.config.dev ? 'development' : 'production'))
+ .blacklistedChannels;
+ action = blacklistedUsers.includes(targetID) || blacklistedChannels.includes(targetID) ? 'unblacklist' : 'blacklist';
+ }
+ const success = await this.client.util
+ .insertOrRemoveFromGlobal(
+ action === 'blacklist' ? 'add' : 'remove',
+ target instanceof User ? 'blacklistedUsers' : 'blacklistedChannels',
+ targetID
+ )
+ .catch(() => false);
+ if (!success)
+ return await message.util.reply({
+ content: `${this.client.util.emojis.error} There was an error globally **${action}ing** ${
+ target?.tag ?? target.name
+ }.`,
+ allowedMentions: AllowedMentions.none()
+ });
+ else
+ return await message.util.reply({
+ content: `${this.client.util.emojis.success} Successfully **${action}ed** ${target?.tag ?? target.name} globally.`,
+ allowedMentions: AllowedMentions.none()
+ });
+ // guild disable
+ } else {
+ const blacklistedChannels = await message.guild.getSetting('blacklistedChannels');
+ const blacklistedUsers = await message.guild.getSetting('blacklistedUsers');
+ if (action === 'toggle') {
+ action = blacklistedChannels.includes(targetID) ?? blacklistedUsers.includes(targetID) ? 'unblacklist' : 'blacklist';
+ }
+ const newValue = this.client.util.addOrRemoveFromArray(
+ action === 'blacklist' ? 'add' : 'remove',
+ target instanceof User ? blacklistedUsers : blacklistedChannels,
+ targetID
+ );
+ const success = await message.guild
+ .setSetting(target instanceof User ? 'blacklistedUsers' : 'blacklistedChannels', newValue)
+ .catch(() => false);
+ if (!success)
+ return await message.util.reply({
+ content: `${this.client.util.emojis.error} There was an error **${action}ing** ${target?.tag ?? target.name}.`,
+ allowedMentions: AllowedMentions.none()
+ });
+ else
+ return await message.util.reply({
+ content: `${this.client.util.emojis.success} Successfully **${action}ed** ${target?.tag ?? target.name}.`,
+ allowedMentions: AllowedMentions.none()
+ });
+ }
+ }
+}
diff --git a/src/commands/config/disable.ts b/src/commands/config/disable.ts
new file mode 100644
index 0000000..007cdb1
--- /dev/null
+++ b/src/commands/config/disable.ts
@@ -0,0 +1,128 @@
+import { AllowedMentions, BushCommand, BushMessage, BushSlashMessage, Global } from '@lib';
+
+export default class DisableCommand extends BushCommand {
+ public constructor() {
+ super('disable', {
+ aliases: ['disable', 'enable'],
+ category: 'config',
+ description: {
+ content: 'A command to disable and enable commands.',
+ usage: 'disable|enable <command>',
+ examples: ['enable ban', 'disable kick']
+ },
+ args: [
+ {
+ id: 'command',
+ type: 'commandAlias',
+ match: 'phrase',
+ prompt: {
+ start: 'What command would you like to enable/disable?',
+ retry: '{error} Pick a valid command.',
+ optional: false
+ }
+ },
+ {
+ id: 'global',
+ match: 'flag',
+ flag: '--global'
+ }
+ ],
+ slash: true,
+ slashOptions: [
+ {
+ name: 'action',
+ description: 'Would you like to disable or enable a command?',
+ type: 'STRING',
+ choices: [
+ {
+ name: 'enable',
+ value: 'enable'
+ },
+ {
+ name: 'disable',
+ value: 'disable'
+ }
+ ],
+ required: true
+ },
+ {
+ name: 'command',
+ description: 'What command would you like to enable/disable?',
+ type: 'STRING',
+ required: true
+ }
+ ],
+ channel: 'guild',
+ clientPermissions: ['SEND_MESSAGES'],
+ userPermissions: ['SEND_MESSAGES', 'MANAGE_GUILD']
+ });
+ }
+
+ blacklistedCommands = ['eval', 'disable'];
+
+ public async exec(
+ message: BushMessage | BushSlashMessage,
+ args: { action: 'enable' | 'disable'; command: BushCommand | string; global: boolean }
+ ): Promise<unknown> {
+ let action: 'disable' | 'enable' | 'toggle' =
+ args.action ?? (message?.util?.parsed?.alias as 'disable' | 'enable') ?? 'toggle';
+ const global = args.global && message.author.isOwner();
+ const commandID = (args.command as BushCommand).id;
+
+ if (global) {
+ if (action === 'toggle') {
+ const disabledCommands = (await Global.findByPk(this.client.config.dev ? 'development' : 'production'))
+ .disabledCommands;
+ action = disabledCommands.includes(commandID) ? 'disable' : 'enable';
+ }
+ const success = await this.client.util
+ .insertOrRemoveFromGlobal(action === 'disable' ? 'remove' : 'add', 'disabledCommands', commandID)
+ .catch(() => false);
+ if (!success)
+ return await message.util.reply({
+ content: `${this.client.util.emojis.error} There was an error globally **${action.substr(
+ 0,
+ action.length - 2
+ )}ing** the **${commandID}** command.`,
+ allowedMentions: AllowedMentions.none()
+ });
+ else
+ return await message.util.reply({
+ content: `${this.client.util.emojis.success} Successfully **${action.substr(
+ 0,
+ action.length - 2
+ )}ed** the **${commandID}** command globally.`,
+ allowedMentions: AllowedMentions.none()
+ });
+
+ // guild disable
+ } else {
+ const disabledCommands = await message.guild.getSetting('disabledCommands');
+ if (action === 'toggle') {
+ action = disabledCommands.includes(commandID) ? 'disable' : 'enable';
+ }
+ const newValue = this.client.util.addOrRemoveFromArray(
+ action === 'disable' ? 'remove' : 'add',
+ disabledCommands,
+ commandID
+ );
+ const success = await message.guild.setSetting('disabledCommands', newValue).catch(() => false);
+ if (!success)
+ return await message.util.reply({
+ content: `${this.client.util.emojis.error} There was an error **${action.substr(
+ 0,
+ action.length - 2