From 166d7fdf24440db71311c2cda95697c06e7b8b36 Mon Sep 17 00:00:00 2001 From: IRONM00N <64110067+IRONM00N@users.noreply.github.com> Date: Thu, 21 Oct 2021 00:05:53 -0400 Subject: Refactoring, rewrote ButtonPaginator, better permission handling + support for send messages in threads, optimizations, another scam link --- src/commands/_fake-command/ironmoon.ts | 4 +- src/commands/admin/channelPermissions.ts | 7 +- src/commands/admin/roleAll.ts | 2 +- src/commands/config/blacklist.ts | 4 +- src/commands/config/config.ts | 61 +++++------- src/commands/config/customAutomodPhrases.ts | 4 +- src/commands/config/disable.ts | 11 +-- src/commands/config/features.ts | 4 +- src/commands/config/levelRoles.ts | 126 ++++++++++++------------- src/commands/config/log.ts | 4 +- src/commands/dev/__template.ts | 4 +- src/commands/dev/eval.ts | 4 +- src/commands/dev/reload.ts | 4 +- src/commands/dev/say.ts | 13 +-- src/commands/dev/servers.ts | 45 ++++----- src/commands/dev/sh.ts | 4 +- src/commands/dev/superUser.ts | 3 +- src/commands/dev/test.ts | 9 +- src/commands/fun/coinflip.ts | 5 +- src/commands/fun/dice.ts | 3 +- src/commands/fun/eightBall.ts | 4 +- src/commands/fun/minesweeper.ts | 68 +++---------- src/commands/info/avatar.ts | 3 +- src/commands/info/botInfo.ts | 4 +- src/commands/info/color.ts | 3 +- src/commands/info/guildInfo.ts | 4 +- src/commands/info/help.ts | 4 +- src/commands/info/icon.ts | 3 +- src/commands/info/links.ts | 3 +- src/commands/info/ping.ts | 4 +- src/commands/info/pronouns.ts | 17 ++-- src/commands/info/snowflake.ts | 3 +- src/commands/info/userInfo.ts | 4 +- src/commands/leveling/leaderboard.ts | 7 +- src/commands/leveling/level.ts | 66 ++++++------- src/commands/leveling/setLevel.ts | 4 +- src/commands/leveling/setXp.ts | 4 +- src/commands/moderation/_lockdown.ts | 8 +- src/commands/moderation/ban.ts | 2 +- src/commands/moderation/evidence.ts | 4 +- src/commands/moderation/hideCase.ts | 6 +- src/commands/moderation/kick.ts | 8 +- src/commands/moderation/modlog.ts | 12 +-- src/commands/moderation/mute.ts | 8 +- src/commands/moderation/purge.ts | 2 +- src/commands/moderation/removeReactionEmoji.ts | 6 +- src/commands/moderation/role.ts | 4 +- src/commands/moderation/slowmode.ts | 4 +- src/commands/moderation/unban.ts | 7 +- src/commands/moderation/unmute.ts | 6 +- src/commands/moderation/warn.ts | 6 +- src/commands/moulberry-bush/capePerms.ts | 21 +++-- src/commands/moulberry-bush/capes.ts | 49 +++++----- src/commands/moulberry-bush/giveawayPing.ts | 4 +- src/commands/moulberry-bush/moulHammer.ts | 6 +- src/commands/moulberry-bush/report.ts | 8 +- src/commands/moulberry-bush/rule.ts | 9 +- src/commands/moulberry-bush/serverStatus.ts | 3 +- src/commands/utilities/activity.ts | 4 +- src/commands/utilities/calculator.ts | 4 +- src/commands/utilities/decode.ts | 33 ++----- src/commands/utilities/hash.ts | 3 +- src/commands/utilities/price.ts | 11 ++- src/commands/utilities/steal.ts | 4 +- src/commands/utilities/suicide.ts | 22 +++-- src/commands/utilities/uuid.ts | 6 +- src/commands/utilities/viewraw.ts | 38 +++++++- src/commands/utilities/whoHasRole.ts | 7 +- src/commands/utilities/wolframAlpha.ts | 40 ++++++-- 69 files changed, 435 insertions(+), 446 deletions(-) (limited to 'src/commands') diff --git a/src/commands/_fake-command/ironmoon.ts b/src/commands/_fake-command/ironmoon.ts index ddc6ced..d7e737f 100644 --- a/src/commands/_fake-command/ironmoon.ts +++ b/src/commands/_fake-command/ironmoon.ts @@ -5,7 +5,9 @@ export default class IronmoonCommand extends BushCommand { super('ironmoon', { category: 'fake-commands', description: { content: '', examples: '', usage: '' }, - pseudo: true + pseudo: true, + clientPermissions: [], + userPermissions: [] }); } public override condition(message: BushMessage): boolean { diff --git a/src/commands/admin/channelPermissions.ts b/src/commands/admin/channelPermissions.ts index f313a8f..f8c97a9 100644 --- a/src/commands/admin/channelPermissions.ts +++ b/src/commands/admin/channelPermissions.ts @@ -1,5 +1,6 @@ import { GuildMember, MessageEmbed, Role } from 'discord.js'; import { BushCommand, BushMessage } from '../../lib'; +import { ButtonPaginator } from '../../lib/common/ButtonPaginator'; export default class ChannelPermissionsCommand extends BushCommand { public constructor() { @@ -42,9 +43,7 @@ export default class ChannelPermissionsCommand extends BushCommand { } } ], - ratelimit: 4, - cooldown: 4000, - clientPermissions: ['MANAGE_CHANNELS', 'SEND_MESSAGES'], + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['MANAGE_CHANNELS']), userPermissions: ['ADMINISTRATOR'], channel: 'guild' }); @@ -85,7 +84,7 @@ export default class ChannelPermissionsCommand extends BushCommand { paginate.push(new MessageEmbed().setDescription(failure.substring(i, Math.min(failure.length, i + 4000)))); } const normalMessage = `Finished changing perms! Failed channels:`; - return await client.util.buttonPaginate(message, paginate, normalMessage); + return await ButtonPaginator.send(message, paginate, normalMessage); } else { return await message.util.reply({ content: `Finished changing perms! Failed channels:`, diff --git a/src/commands/admin/roleAll.ts b/src/commands/admin/roleAll.ts index d965239..ec1f2b5 100644 --- a/src/commands/admin/roleAll.ts +++ b/src/commands/admin/roleAll.ts @@ -28,7 +28,7 @@ export default class RoleAllCommand extends BushCommand { } ], channel: 'guild', - clientPermissions: ['MANAGE_ROLES', 'SEND_MESSAGES'], + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['MANAGE_ROLES']), userPermissions: ['ADMINISTRATOR'], typing: true }); diff --git a/src/commands/config/blacklist.ts b/src/commands/config/blacklist.ts index 5dea36a..9f3737d 100644 --- a/src/commands/config/blacklist.ts +++ b/src/commands/config/blacklist.ts @@ -54,8 +54,8 @@ export default class BlacklistCommand extends BushCommand { } ], channel: 'guild', - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES', 'MANAGE_GUILD'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: ['MANAGE_GUILD'] }); } diff --git a/src/commands/config/config.ts b/src/commands/config/config.ts index 2075531..72ba566 100644 --- a/src/commands/config/config.ts +++ b/src/commands/config/config.ts @@ -12,6 +12,7 @@ import { MessageOptions, MessageSelectMenu, Role, + Snowflake, User } from 'discord.js'; import _ from 'lodash'; @@ -51,11 +52,7 @@ export default class SettingsCommand extends BushCommand { description: `What would you like to add to the server's ${guildSettingsObj[ setting ].name.toLowerCase()}?'`, - type: guildSettingsObj[setting].type.replace('-array', '').toUpperCase() as - | 'ROLE' - | 'STRING' - | 'CHANNEL' - | 'USER', + type: guildSettingsObj[setting].type.replace('-array', '').toUpperCase() as SlashArgType, required: true } ] @@ -70,11 +67,7 @@ export default class SettingsCommand extends BushCommand { description: `What would you like to remove from the server's ${guildSettingsObj[ setting ].name.toLowerCase()}?'`, - type: guildSettingsObj[setting].type.replace('-array', '').toUpperCase() as - | 'ROLE' - | 'STRING' - | 'CHANNEL' - | 'USER', + type: guildSettingsObj[setting].type.replace('-array', '').toUpperCase() as SlashArgType, required: true } ] @@ -96,7 +89,7 @@ export default class SettingsCommand extends BushCommand { description: `What would you like to set the server's ${guildSettingsObj[ setting ].name.toLowerCase()} to?'`, - type: guildSettingsObj[setting].type.toUpperCase() as 'ROLE' | 'STRING' | 'CHANNEL' | 'USER', + type: guildSettingsObj[setting].type.toUpperCase() as SlashArgType, required: true } ] @@ -105,13 +98,13 @@ export default class SettingsCommand extends BushCommand { }; }), channel: 'guild', - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES', 'MANAGE_GUILD'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: ['MANAGE_GUILD'] }); } // I make very readable code :) - override *args(message: BushMessage): IterableIterator { + override *args(message: BushMessage): Generator { const optional = message.util.parsed!.alias === 'settings'; const setting = yield { id: 'setting', @@ -126,7 +119,7 @@ export default class SettingsCommand extends BushCommand { }; const actionType = setting - ? guildSettingsObj[setting as unknown as GuildSettings]?.type.includes('-array') + ? guildSettingsObj[setting as GuildSettings]?.type.includes('-array') ? ['view', 'add', 'remove'] : ['view', 'set'] : undefined; @@ -151,13 +144,13 @@ export default class SettingsCommand extends BushCommand { const valueType = setting && action && action !== 'view' - ? (guildSettingsObj[setting as unknown as GuildSettings].type.replace('-array', '') as 'string' | 'channel' | 'role') + ? (guildSettingsObj[setting as GuildSettings].type.replace('-array', '') as 'string' | 'channel' | 'role') : undefined; const grammar = setting && action && action !== 'view' - ? (action as unknown as 'add' | 'remove' | 'set') === 'add' + ? (action as 'add' | 'remove' | 'set') === 'add' ? `to the ${setting} setting` - : (action as unknown as 'remove' | 'set') === 'remove' + : (action as 'remove' | 'set') === 'remove' ? `from the ${setting} setting` : `the ${setting} setting to` : undefined; @@ -184,8 +177,8 @@ export default class SettingsCommand extends BushCommand { args: { setting?: GuildSettings; subcommandGroup?: GuildSettings; - action?: 'view' | 'add' | 'remove' | 'set'; - subcommand?: 'view' | 'add' | 'remove' | 'set'; + action?: Action; + subcommand?: Action; value: string | Channel | Role; } ): Promise { @@ -214,9 +207,9 @@ export default class SettingsCommand extends BushCommand { if (!value) return await message.util.reply( `${util.emojis.error} You must choose a value to ${action} ${ - (action as unknown as 'add' | 'remove' | 'set') === 'add' + action === 'add' ? `to the ${setting} setting` - : (action as unknown as 'remove' | 'set') === 'remove' + : action === 'remove' ? `from the ${setting} setting` : `the ${setting} setting to` }` @@ -295,12 +288,10 @@ export default class SettingsCommand extends BushCommand { return { embeds: [settingsEmbed], components: [selMenu] }; } else { settingsEmbed.setTitle(guildSettingsObj[setting].name); - const generateCurrentValue = async ( - type: 'string' | 'channel' | 'channel-array' | 'role' | 'role-array' | 'user' | 'user-array' | 'custom' - ): Promise => { + const generateCurrentValue = async (type: SettingTypes): Promise => { const feat = await message.guild!.getSetting(setting); - switch (type.replace('-array', '') as 'string' | 'channel' | 'role' | 'user' | 'custom') { + switch (type.replace('-array', '') as BaseSettingTypes) { case 'string': { return Array.isArray(feat) ? feat.length @@ -315,21 +306,21 @@ export default class SettingsCommand extends BushCommand { ? feat.length ? feat.map((feat) => `<#${feat}>`).join('\n') : '[Empty Array]' - : `<#${feat as string}>`; + : `<#${feat as Snowflake}>`; } case 'role': { return Array.isArray(feat) ? feat.length ? feat.map((feat) => `<@&${feat}>`).join('\n') : '[Empty Array]' - : `<@&${feat as string}>`; + : `<@&${feat as Snowflake}>`; } case 'user': { return Array.isArray(feat) ? feat.length ? feat.map((feat) => `<@${feat}>`).join('\n') : '[Empty Array]' - : `<@${feat as string}>`; + : `<@${feat as Snowflake}>`; } case 'custom': { return util.inspectAndRedact(feat); @@ -355,13 +346,13 @@ export default class SettingsCommand extends BushCommand { guildSettingsObj[setting].type.includes('-array') ? 'add/remove' : 'set' } " to set this setting.` ); - settingsEmbed.addField( - 'value', - (await generateCurrentValue( - guildSettingsObj[setting].type as 'string' | 'channel' | 'channel-array' | 'role' | 'role-array' - )) || '[No Value Set]' - ); + settingsEmbed.addField('value', (await generateCurrentValue(guildSettingsObj[setting].type)) || '[No Value Set]'); return { embeds: [settingsEmbed], components: [components] }; } } } + +type SlashArgType = 'ROLE' | 'STRING' | 'CHANNEL' | 'USER'; +type BaseSettingTypes = 'string' | 'channel' | 'role' | 'user' | 'custom'; +type SettingTypes = 'string' | 'channel' | 'channel-array' | 'role' | 'role-array' | 'user' | 'user-array' | 'custom'; +type Action = 'view' | 'add' | 'remove' | 'set'; diff --git a/src/commands/config/customAutomodPhrases.ts b/src/commands/config/customAutomodPhrases.ts index 2cbe874..51e219a 100644 --- a/src/commands/config/customAutomodPhrases.ts +++ b/src/commands/config/customAutomodPhrases.ts @@ -49,8 +49,8 @@ // ownerOnly: true, // channel: 'guild', // hidden: true, -// clientPermissions: ['SEND_MESSAGES'], -// userPermissions: ['SEND_MESSAGES'] +// clientPermissions: (m) => util.clientSendAndPermCheck(m), +// userPermissions: [] // }); // } diff --git a/src/commands/config/disable.ts b/src/commands/config/disable.ts index db4909a..bca1207 100644 --- a/src/commands/config/disable.ts +++ b/src/commands/config/disable.ts @@ -52,8 +52,8 @@ export default class DisableCommand extends BushCommand { } ], channel: 'guild', - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES', 'MANAGE_GUILD'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: ['MANAGE_GUILD'] }); } @@ -63,13 +63,12 @@ export default class DisableCommand extends BushCommand { message: BushMessage | BushSlashMessage, args: { action: 'enable' | 'disable'; command: BushCommand | string; global: boolean } ): Promise { - let action: 'disable' | 'enable' | 'toggle' = - args.action ?? (message?.util?.parsed?.alias as 'disable' | 'enable') ?? 'toggle'; + let action = (args.action ?? message?.util?.parsed?.alias ?? 'toggle') as 'disable' | 'enable' | 'toggle'; const global = args.global && message.author.isOwner(); const commandID = (args.command as BushCommand).id; if (global) { - if ((action as 'disable' | 'enable' | 'toggle') === 'toggle') { + if (action === 'toggle') { const disabledCommands = ( (await Global.findByPk(client.config.environment)) ?? (await Global.create({ environment: client.config.environment })) @@ -99,7 +98,7 @@ export default class DisableCommand extends BushCommand { // guild disable } else { const disabledCommands = await message.guild!.getSetting('disabledCommands'); - if ((action as 'disable' | 'enable' | 'toggle') === 'toggle') { + if (action === 'toggle') { action = disabledCommands.includes(commandID) ? 'disable' : 'enable'; } const newValue = util.addOrRemoveFromArray(action === 'disable' ? 'remove' : 'add', disabledCommands, commandID); diff --git a/src/commands/config/features.ts b/src/commands/config/features.ts index 076d469..3c3075c 100644 --- a/src/commands/config/features.ts +++ b/src/commands/config/features.ts @@ -13,8 +13,8 @@ export default class FeaturesCommand extends BushCommand { }, slash: true, channel: 'guild', - clientPermissions: ['SEND_MESSAGES', 'EMBED_LINKS'], - userPermissions: ['SEND_MESSAGES', 'MANAGE_GUILD'] + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: ['MANAGE_GUILD'] }); } diff --git a/src/commands/config/levelRoles.ts b/src/commands/config/levelRoles.ts index 36dc50c..ee5f255 100644 --- a/src/commands/config/levelRoles.ts +++ b/src/commands/config/levelRoles.ts @@ -1,65 +1,65 @@ -import { BushCommand, BushMessage, BushSlashMessage } from '@lib'; +// import { BushCommand, BushMessage, BushSlashMessage } from '@lib'; -export default class LevelRolesCommand extends BushCommand { - public constructor() { - super('levelRole', { - aliases: ['level-role', 'level-roles', 'lr'], - category: 'config', - description: { - content: 'Configure roles to be assigned to users upon reaching certain levels.', - usage: ['level-role add ', 'level-role remove '], - examples: ['level-role 1 2'] - }, - args: [ - { - id: 'action', - customType: ['add', 'remove'] - }, - { - id: 'role', - type: 'role', - prompt: { - start: 'What would you like to set your first argument to be?', - retry: '{error} Pick a valid argument.', - optional: false - } - }, - { - id: 'level', - type: 'integer', - prompt: { - start: 'What would you like to set your second argument to be?', - retry: '{error} Pick a valid argument.', - optional: false - } - } - ], - slash: true, - slashOptions: [ - { - name: 'role', - description: 'What would you like to set your first argument to be?', - type: 'STRING', - required: true - }, - { - name: 'level', - description: 'What would you like to set your second argument to be?', - type: 'STRING', - required: true - } - ], - channel: 'guild', - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES', 'MANAGE_GUILD', 'MANAGE_ROLES'] - }); - } +// export default class LevelRolesCommand extends BushCommand { +// public constructor() { +// super('levelRole', { +// aliases: ['level-role', 'level-roles', 'lr'], +// category: 'config', +// description: { +// content: 'Configure roles to be assigned to users upon reaching certain levels.', +// usage: ['level-role add ', 'level-role remove '], +// examples: ['level-role 1 2'] +// }, +// args: [ +// { +// id: 'action', +// customType: ['add', 'remove'] +// }, +// { +// id: 'role', +// type: 'role', +// prompt: { +// start: 'What would you like to set your first argument to be?', +// retry: '{error} Pick a valid argument.', +// optional: false +// } +// }, +// { +// id: 'level', +// type: 'integer', +// prompt: { +// start: 'What would you like to set your second argument to be?', +// retry: '{error} Pick a valid argument.', +// optional: false +// } +// } +// ], +// slash: true, +// slashOptions: [ +// { +// name: 'role', +// description: 'What would you like to set your first argument to be?', +// type: 'STRING', +// required: true +// }, +// { +// name: 'level', +// description: 'What would you like to set your second argument to be?', +// type: 'STRING', +// required: true +// } +// ], +// channel: 'guild', +// clientPermissions: (m) => util.clientSendAndPermCheck(m), +// userPermissions: ['MANAGE_GUILD', 'MANAGE_ROLES'] +// }); +// } - public override async exec( - message: BushMessage | BushSlashMessage, - args: { required_argument: string; optional_argument: string } - ): Promise { - return await message.util.reply(`${util.emojis.error} Do not use the template command.`); - args; - } -} +// public override async exec( +// message: BushMessage | BushSlashMessage, +// args: { required_argument: string; optional_argument: string } +// ): Promise { +// return await message.util.reply(`${util.emojis.error} Do not use the template command.`); +// args; +// } +// } diff --git a/src/commands/config/log.ts b/src/commands/config/log.ts index 03e3582..363620a 100644 --- a/src/commands/config/log.ts +++ b/src/commands/config/log.ts @@ -29,8 +29,8 @@ export default class LogCommand extends BushCommand { } ], channel: 'guild', - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES', 'MANAGE_GUILD'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: ['MANAGE_GUILD'] }); } diff --git a/src/commands/dev/__template.ts b/src/commands/dev/__template.ts index 49549af..b9d9114 100644 --- a/src/commands/dev/__template.ts +++ b/src/commands/dev/__template.ts @@ -49,8 +49,8 @@ export default class TemplateCommand extends BushCommand { ownerOnly: true, channel: 'guild', hidden: true, - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [] }); } diff --git a/src/commands/dev/eval.ts b/src/commands/dev/eval.ts index 2f61822..c4a6e8f 100644 --- a/src/commands/dev/eval.ts +++ b/src/commands/dev/eval.ts @@ -45,7 +45,9 @@ export default class EvalCommand extends BushCommand { { name: 'show_proto', description: 'Show prototype.', type: 'BOOLEAN', required: false }, { name: 'show_methods', description: 'Show class functions.', type: 'BOOLEAN', required: false } ], - ownerOnly: true + ownerOnly: true, + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [] }); } diff --git a/src/commands/dev/reload.ts b/src/commands/dev/reload.ts index 987cd01..43b8ab6 100644 --- a/src/commands/dev/reload.ts +++ b/src/commands/dev/reload.ts @@ -19,6 +19,7 @@ export default class ReloadCommand extends BushCommand { // ], ownerOnly: true, typing: true, + slash: true, // slashOptions: [ // { // name: 'fast', @@ -27,7 +28,8 @@ export default class ReloadCommand extends BushCommand { // required: false // } // ], - slash: true + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [] }); } diff --git a/src/commands/dev/say.ts b/src/commands/dev/say.ts index 1c797ea..a7e9943 100644 --- a/src/commands/dev/say.ts +++ b/src/commands/dev/say.ts @@ -13,7 +13,7 @@ export default class SayCommand extends BushCommand { }, args: [ { - id: 'say', + id: 'content', type: 'string', match: 'rest', prompt: { start: 'What would you like the bot to say?', retry: '{error} Choose something valid to say.' } @@ -21,20 +21,21 @@ export default class SayCommand extends BushCommand { ], slashOptions: [{ name: 'content', description: 'What would you like the bot to say?', type: 'STRING' }], ownerOnly: true, - clientPermissions: ['SEND_MESSAGES'], + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [], slash: true }); } - public override async exec(message: BushMessage, { say }: { say: string }): Promise { + public override async exec(message: BushMessage, args: { content: string }): Promise { if (!message.author.isOwner()) return await message.util.reply(`${util.emojis.error} Only my developers can run this command.`); await message.delete().catch(() => {}); - await message.util.send({ content: say, allowedMentions: AllowedMentions.none() }); + await message.util.send({ content: args.content, allowedMentions: AllowedMentions.none() }); } - public override async execSlash(message: AkairoMessage, { content }: { content: string }): Promise { + public override async execSlash(message: AkairoMessage, args: { content: string }): Promise { if (!client.config.owners.includes(message.author.id)) { return await message.interaction.reply({ content: `${util.emojis.error} Only my developers can run this command.`, @@ -42,6 +43,6 @@ export default class SayCommand extends BushCommand { }); } await message.interaction.reply({ content: 'Attempting to send message.', ephemeral: true }); - return message.channel!.send({ content, allowedMentions: AllowedMentions.none() }); + return message.channel!.send({ content: args.content, allowedMentions: AllowedMentions.none() }); } } diff --git a/src/commands/dev/servers.ts b/src/commands/dev/servers.ts index c86e889..e366a64 100644 --- a/src/commands/dev/servers.ts +++ b/src/commands/dev/servers.ts @@ -1,5 +1,6 @@ -import { Guild, MessageEmbed } from 'discord.js'; +import { Guild, MessageEmbedOptions } from 'discord.js'; import { BushCommand, BushMessage, BushSlashMessage } from '../../lib'; +import { ButtonPaginator } from '../../lib/common/ButtonPaginator'; export default class ServersCommand extends BushCommand { public constructor() { @@ -11,38 +12,30 @@ export default class ServersCommand extends BushCommand { usage: 'servers', examples: ['servers'] }, - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'], + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [], ownerOnly: true }); } public override async exec(message: BushMessage | BushSlashMessage): Promise { - const maxLength = 10; const guilds = [...client.guilds.cache.sort((a, b) => (a.memberCount < b.memberCount ? 1 : -1)).values()]; - const chunkedGuilds: Guild[][] = []; - const embeds: MessageEmbed[] = []; - - for (let i = 0, j = guilds.length; i < j; i += maxLength) { - chunkedGuilds.push(guilds.slice(i, i + maxLength)); - } - - chunkedGuilds.forEach((c: Guild[]) => { - const embed = new MessageEmbed(); - c.forEach((g: Guild) => { - const owner = client.users.cache.get(g.ownerId)?.tag; - embed - .addField( - `**${g.name}**`, - `**ID:** ${g.id}\n**Owner:** ${owner ? owner : g.ownerId}\n**Members:** ${g.memberCount.toLocaleString()}`, - false - ) - .setTitle(`Server List [\`${client.guilds.cache.size.toLocaleString()}\`]`) - .setColor(util.colors.default); - }); - embeds.push(embed); + const chunkedGuilds: Guild[][] = util.chunk(guilds, 10); + const embeds: MessageEmbedOptions[] = chunkedGuilds.map((chunk) => { + return { + title: `Server List [\`${guilds.length.toLocaleString()}\`]`, + color: util.colors.default, + fields: chunk.map((guild) => ({ + name: util.format.bold(guild.name), + value: [ + `**ID:** ${guild.id}`, + `**Owner:** ${client.users.cache.has(guild.ownerId) ? client.users.cache.get(guild.ownerId)!.tag : guild.ownerId}`, + `**Members:** ${guild.memberCount.toLocaleString()}` + ].join('\n') + })) + } as MessageEmbedOptions; }); - return await util.buttonPaginate(message, embeds); + return await ButtonPaginator.send(message, embeds); } } diff --git a/src/commands/dev/sh.ts b/src/commands/dev/sh.ts index 067a0e6..3fca2b2 100644 --- a/src/commands/dev/sh.ts +++ b/src/commands/dev/sh.ts @@ -33,7 +33,9 @@ export default class ShCommand extends BushCommand { } } ], - ownerOnly: true + ownerOnly: true, + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [] }); } diff --git a/src/commands/dev/superUser.ts b/src/commands/dev/superUser.ts index 4dc4584..fcdec53 100644 --- a/src/commands/dev/superUser.ts +++ b/src/commands/dev/superUser.ts @@ -12,7 +12,8 @@ export default class SuperUserCommand extends BushCommand { usage: 'superuser ', examples: ['superuser add IRONM00N'] }, - clientPermissions: ['SEND_MESSAGES'], + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [], ownerOnly: true }); } diff --git a/src/commands/dev/test.ts b/src/commands/dev/test.ts index c77d7ec..a1e5052 100644 --- a/src/commands/dev/test.ts +++ b/src/commands/dev/test.ts @@ -7,6 +7,7 @@ import { MessageButton, MessageEmbed } from 'discord.js'; +import { ButtonPaginator } from '../../lib/common/ButtonPaginator'; export default class TestCommand extends BushCommand { public constructor() { @@ -18,8 +19,6 @@ export default class TestCommand extends BushCommand { usage: 'test [feature]', examples: ['test lots of buttons', 'test buttons'] }, - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'], args: [ { id: 'feature', @@ -32,7 +31,9 @@ export default class TestCommand extends BushCommand { } } ], - superUserOnly: true + superUserOnly: true, + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [] }); } @@ -95,7 +96,7 @@ export default class TestCommand extends BushCommand { for (let i = 1; i <= 5; i++) { embeds.push(new MessageEmbed().setDescription(i.toString())); } - return await util.buttonPaginate(message, embeds); + return await ButtonPaginator.send(message, embeds); } else if (['lots of embeds'].includes(args?.feature?.toLowerCase())) { const description = 'This is a description.'; const _avatar = message.author.avatarURL({ dynamic: true }) ?? undefined; diff --git a/src/commands/fun/coinflip.ts b/src/commands/fun/coinflip.ts index e0892b7..42e7167 100644 --- a/src/commands/fun/coinflip.ts +++ b/src/commands/fun/coinflip.ts @@ -10,14 +10,15 @@ export default class CoinFlipCommand extends BushCommand { usage: 'coinflip', examples: ['coinflip'] }, - clientPermissions: ['SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [] }); } public override async exec(message: BushMessage | BushSlashMessage): Promise { const random = Math.random(); let result: string; - const fall = message.author.id === '322862723090219008' ? 0.1 : 0.001; + const fall = message.author.id === '322862723090219008' ? 0.1 : 0.001; //dw about it if (random < fall) result = 'The coin fell off the table :('; else if (random <= 0.5 + fall / 2) result = 'Heads'; else result = 'Tails'; diff --git a/src/commands/fun/dice.ts b/src/commands/fun/dice.ts index 241f1d2..9f18657 100644 --- a/src/commands/fun/dice.ts +++ b/src/commands/fun/dice.ts @@ -10,7 +10,8 @@ export default class EightBallCommand extends BushCommand { usage: 'dice', examples: ['dice'] }, - clientPermissions: ['SEND_MESSAGES'], + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [], slash: true }); } diff --git a/src/commands/fun/eightBall.ts b/src/commands/fun/eightBall.ts index efaaff5..b3c56da 100644 --- a/src/commands/fun/eightBall.ts +++ b/src/commands/fun/eightBall.ts @@ -30,8 +30,8 @@ export default class EightBallCommand extends BushCommand { required: true } ], - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [] }); } diff --git a/src/commands/fun/minesweeper.ts b/src/commands/fun/minesweeper.ts index 57909a2..b45dcda 100644 --- a/src/commands/fun/minesweeper.ts +++ b/src/commands/fun/minesweeper.ts @@ -42,43 +42,15 @@ export default class MinesweeperCommand extends BushCommand { }, default: 10 }, - { - id: 'spaces', - match: 'flag', - flag: '--spaces' - }, - { - id: 'reveal_first_cell', - match: 'flag', - flag: '--revealFirstCell' - } + { id: 'spaces', match: 'flag', flag: '--spaces' }, + { id: 'reveal_first_cell', match: 'flag', flag: '--revealFirstCell' } ], slash: true, slashOptions: [ - { - name: 'rows', - description: 'How many rows would you like?', - type: 'INTEGER', - required: false - }, - { - name: 'columns', - description: 'How many rows would you like?', - type: 'INTEGER', - required: false - }, - { - name: 'mines', - description: 'How many rows would you like?', - type: 'INTEGER', - required: false - }, - { - name: 'spaces', - description: 'Would you like there to be spaces?', - type: 'BOOLEAN', - required: false - }, + { name: 'rows', description: 'How many rows would you like?', type: 'INTEGER', required: false }, + { name: 'columns', description: 'How many rows would you like?', type: 'INTEGER', required: false }, + { name: 'mines', description: 'How many rows would you like?', type: 'INTEGER', required: false }, + { name: 'spaces', description: 'Would you like there to be spaces?', type: 'BOOLEAN', required: false }, { name: 'reveal_first_cell', description: 'Would you like to automatically reveal the first cell?', @@ -86,35 +58,23 @@ export default class MinesweeperCommand extends BushCommand { required: false } ], - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [] }); } public override async exec( message: BushMessage | BushSlashMessage, - { - rows, - columns, - mines, - spaces, - reveal_first_cell - }: { - rows: number; - columns: number; - mines: number; - spaces: boolean; - reveal_first_cell: boolean; - } + args: { rows: number; columns: number; mines: number; spaces: boolean; reveal_first_cell: boolean } ): Promise { const minesweeper = new Minesweeper({ - rows: rows ?? 9, - columns: columns ?? 9, - mines: mines ?? 10, + rows: args.rows ?? 9, + columns: args.columns ?? 9, + mines: args.mines ?? 10, emote: 'boom', - revealFirstCell: reveal_first_cell ?? false, + revealFirstCell: args.reveal_first_cell ?? false, zeroFirstCell: true, - spaces: spaces ?? false, + spaces: args.spaces ?? false, returnType: 'emoji' }); const matrix = minesweeper.start(); diff --git a/src/commands/info/avatar.ts b/src/commands/info/avatar.ts index 1e6496a..7625b61 100644 --- a/src/commands/info/avatar.ts +++ b/src/commands/info/avatar.ts @@ -22,7 +22,8 @@ export default class AvatarCommand extends BushCommand { } } ], - clientPermissions: ['SEND_MESSAGES', 'EMBED_LINKS'], + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: [], slash: true, slashOptions: [ { diff --git a/src/commands/info/botInfo.ts b/src/commands/info/botInfo.ts index 257dc90..ffb785c 100644 --- a/src/commands/info/botInfo.ts +++ b/src/commands/info/botInfo.ts @@ -14,8 +14,8 @@ export default class BotInfoCommand extends BushCommand { examples: ['botinfo'] }, slash: true, - clientPermissions: ['SEND_MESSAGES', 'EMBED_LINKS'], - userPermissions: ['SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: [] }); } diff --git a/src/commands/info/color.ts b/src/commands/info/color.ts index d641fd7..958aadd 100644 --- a/src/commands/info/color.ts +++ b/src/commands/info/color.ts @@ -31,7 +31,8 @@ export default class ColorCommand extends BushCommand { } ], channel: 'guild', - clientPermissions: ['EMBED_LINKS', 'SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: [] }); } diff --git a/src/commands/info/guildInfo.ts b/src/commands/info/guildInfo.ts index f1db783..4a79918 100644 --- a/src/commands/info/guildInfo.ts +++ b/src/commands/info/guildInfo.ts @@ -31,8 +31,8 @@ export default class GuildInfoCommand extends BushCommand { required: false } ], - clientPermissions: ['EMBED_LINKS', 'SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: [] }); } diff --git a/src/commands/info/help.ts b/src/commands/info/help.ts index ce171c9..5e80199 100644 --- a/src/commands/info/help.ts +++ b/src/commands/info/help.ts @@ -37,8 +37,8 @@ export default class HelpCommand extends BushCommand { required: false } ], - clientPermissions: ['EMBED_LINKS', 'SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: [] }); } diff --git a/src/commands/info/icon.ts b/src/commands/info/icon.ts index 677fdaf..ce27cc0 100644 --- a/src/commands/info/icon.ts +++ b/src/commands/info/icon.ts @@ -11,7 +11,8 @@ export default class IconCommand extends BushCommand { usage: 'icon', examples: 'icon' }, - clientPermissions: ['SEND_MESSAGES', 'EMBED_LINKS'], + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: [], channel: 'guild', slash: true }); diff --git a/src/commands/info/links.ts b/src/commands/info/links.ts index b3a762a..569b959 100644 --- a/src/commands/info/links.ts +++ b/src/commands/info/links.ts @@ -14,7 +14,8 @@ export default class LinksCommand extends BushCommand { }, ratelimit: 4, cooldown: 4000, - clientPermissions: ['SEND_MESSAGES'], + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [], slash: true }); } diff --git a/src/commands/info/ping.ts b/src/commands/info/ping.ts index 5f2220c..82db2ff 100644 --- a/src/commands/info/ping.ts +++ b/src/commands/info/ping.ts @@ -12,8 +12,8 @@ export default class PingCommand extends BushCommand { examples: ['ping'] }, slash: true, - clientPermissions: ['SEND_MESSAGES', 'EMBED_LINKS'], - userPermissions: ['SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: [] }); } diff --git a/src/commands/info/pronouns.ts b/src/commands/info/pronouns.ts index 77612da..cd66530 100644 --- a/src/commands/info/pronouns.ts +++ b/src/commands/info/pronouns.ts @@ -1,5 +1,4 @@ import { BushCommand, BushMessage, BushSlashMessage } from '@lib'; -import { Snowflake } from 'discord-api-types'; import { MessageEmbed, User } from 'discord.js'; export default class PronounsCommand extends BushCommand { @@ -15,7 +14,7 @@ export default class PronounsCommand extends BushCommand { args: [ { id: 'user', - customType: util.arg.union('user', 'snowflake'), + type: 'globalUser', prompt: { start: 'Who would you like to view the pronouns of?', retry: '{error} Choose a valid user to view the pronouns of.', @@ -23,7 +22,8 @@ export default class PronounsCommand extends BushCommand { } } ], - clientPermissions: ['SEND_MESSAGES'], + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: [], slashOptions: [ { name: 'user', @@ -35,18 +35,15 @@ export default class PronounsCommand extends BushCommand { slash: true }); } - override async exec(message: BushMessage | BushSlashMessage, args: { user?: User | Snowflake }): Promise { - const user = (await util.resolveNonCachedUser(args.user)) ?? message.author; - - if (!user) return message.util.reply(`${util.emojis.error} Invalid user.`); - + override async exec(message: BushMessage | BushSlashMessage, args: { user?: User }): Promise { + const user = args.user ?? message.author; const author = user.id === message.author.id; const pronouns = await util.getPronounsOf(user); if (!pronouns) { return await message.util.reply( - `${author ? 'You do' : `${user.tag} does`} not appear to have any pronouns set. Please ${ - author ? '' : 'tell them to' + `${author ? 'You do' : `${user.tag} does`} not appear to have any pronouns set. Please${ + author ? '' : ' tell them to' } go to https://pronoundb.org/ and set ${author ? 'your' : 'their'} pronouns.` ); } else { diff --git a/src/commands/info/snowflake.ts b/src/commands/info/snowflake.ts index df11bce..81b3f9d 100644 --- a/src/commands/info/snowflake.ts +++ b/src/commands/info/snowflake.ts @@ -40,7 +40,8 @@ export default class SnowflakeCommand extends BushCommand { } } ], - clientPermissions: ['EMBED_LINKS', 'SEND_MESSAGES'], + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: [], slash: true, slashOptions: [ { diff --git a/src/commands/info/userInfo.ts b/src/commands/info/userInfo.ts index b55bbcf..353d844 100644 --- a/src/commands/info/userInfo.ts +++ b/src/commands/info/userInfo.ts @@ -33,8 +33,8 @@ export default class UserInfoCommand extends BushCommand { required: false } ], - clientPermissions: ['EMBED_LINKS', 'SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: [] }); } diff --git a/src/commands/leveling/leaderboard.ts b/src/commands/leveling/leaderboard.ts index 432fc60..e3344a0 100644 --- a/src/commands/leveling/leaderboard.ts +++ b/src/commands/leveling/leaderboard.ts @@ -1,5 +1,6 @@ import { BushCommand, BushMessage, BushSlashMessage, Level } from '@lib'; import { MessageEmbed } from 'discord.js'; +import { ButtonPaginator } from '../../lib/common/ButtonPaginator'; export default class LeaderboardCommand extends BushCommand { public constructor() { @@ -32,8 +33,8 @@ export default class LeaderboardCommand extends BushCommand { } ], channel: 'guild', - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [] }); } @@ -62,6 +63,6 @@ export default class LeaderboardCommand extends BushCommand { const embeds = chunked.map((c) => new MessageEmbed().setTitle(`${message.guild!.name}'s Leaderboard`).setDescription(c.join('\n')) ); - return await util.buttonPaginate(message, embeds, undefined, true, args?.page ?? undefined); + return await ButtonPaginator.send(message, embeds, undefined, true, args?.page ?? undefined); } } diff --git a/src/commands/leveling/level.ts b/src/commands/leveling/level.ts index 2073e1a..4d7adb3 100644 --- a/src/commands/leveling/level.ts +++ b/src/commands/leveling/level.ts @@ -45,11 +45,42 @@ export default class LevelCommand extends BushCommand { } ], channel: 'guild', - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [] }); } + public override async exec(message: BushMessage | BushSlashMessage, args: { user?: BushUser }): Promise { + if (!message.guild) return await message.util.reply(`${util.emojis.error} This command can only be run in a server.`); + if (!(await message.guild.hasFeature('leveling'))) + return await message.util.reply( + `${util.emojis.error} This command can only be run in servers with the leveling feature enabled.${ + message.member?.permissions.has('MANAGE_GUILD') + ? ` You can toggle features using the \`${ + message.util.isSlash + ? '/' + : client.config.isDevelopment + ? 'dev ' + : message.util.parsed?.prefix ?? client.config.prefix + }features\` command.` + : '' + }` + ); + const user = args.user ?? message.author; + try { + return await message.util.reply({ + files: [new MessageAttachment(await this.getImage(user, message.guild!), 'level.png')] + }); + } catch (e) { + if (e instanceof Error && e.message === 'User does not have a level') { + return await message.util.reply({ + content: `${util.emojis.error} ${user} does not have a level.`, + allowedMentions: AllowedMentions.none() + }); + } else throw e; + } + } + private async getImage(user: BushUser, guild: BushGuild): Promise { const guildRows = await Level.findAll({ where: { guild: guild.id } }); const rank = guildRows.sort((a, b) => b.xp - a.xp); @@ -111,35 +142,4 @@ export default class LevelCommand extends BushCommand { // Return image in buffer form return levelCard.toBuffer(); } - - public override async exec(message: BushMessage | BushSlashMessage, args: { user?: BushUser }): Promise { - if (!message.guild) return await message.util.reply(`${util.emojis.error} This command can only be run in a server.`); - if (!(await message.guild.hasFeature('leveling'))) - return await message.util.reply( - `${util.emojis.error} This command can only be run in servers with the leveling feature enabled.${ - message.member?.permissions.has('MANAGE_GUILD') - ? ` You can toggle features using the \`${ - message.util.isSlash - ? '/' - : client.config.isDevelopment - ? 'dev ' - : message.util.parsed?.prefix ?? client.config.prefix - }features\` command.` - : '' - }` - ); - const user = args.user ?? message.author; - try { - return await message.util.reply({ - files: [new MessageAttachment(await this.getImage(user, message.guild!), 'level.png')] - }); - } catch (e) { - if (e instanceof Error && e.message === 'User does not have a level') { - return await message.util.reply({ - content: `${util.emojis.error} ${user} does not have a level.`, - allowedMentions: AllowedMentions.none() - }); - } else throw e; - } - } } diff --git a/src/commands/leveling/setLevel.ts b/src/commands/leveling/setLevel.ts index b98b488..9a7337a 100644 --- a/src/commands/leveling/setLevel.ts +++ b/src/commands/leveling/setLevel.ts @@ -45,8 +45,8 @@ export default class SetLevelCommand extends BushCommand { ], slash: true, channel: 'guild', - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES', 'ADMINISTRATOR'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: ['ADMINISTRATOR'] }); } diff --git a/src/commands/leveling/setXp.ts b/src/commands/leveling/setXp.ts index 3e00ea2..a73ae58 100644 --- a/src/commands/leveling/setXp.ts +++ b/src/commands/leveling/setXp.ts @@ -48,8 +48,8 @@ export default class SetXpCommand extends BushCommand { ], slash: true, channel: 'guild', - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES', 'ADMINISTRATOR'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: ['ADMINISTRATOR'] }); } diff --git a/src/commands/moderation/_lockdown.ts b/src/commands/moderation/_lockdown.ts index 5df9f18..0086ff6 100644 --- a/src/commands/moderation/_lockdown.ts +++ b/src/commands/moderation/_lockdown.ts @@ -27,15 +27,15 @@ export default class LockdownCommand extends BushCommand { } ], channel: 'guild', - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'], + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [], hidden: true }); } - public override async exec(message: BushMessage | BushSlashMessage, { all }: { all: boolean }): Promise { + public override async exec(message: BushMessage | BushSlashMessage, args: { all: boolean }): Promise { return await message.util.reply('Unfortunately my developer is too lazy to implement this command.'); - if (!all) { + if (!args.all) { if (!['GUILD_TEXT', 'GUILD_NEWS'].includes(message.channel!.type)) return message.util.reply(`${util.emojis.error} You can only lock down text and announcement channels.`); diff --git a/src/commands/moderation/ban.ts b/src/commands/moderation/ban.ts index 4c2b3d3..b3d97d2 100644 --- a/src/commands/moderation/ban.ts +++ b/src/commands/moderation/ban.ts @@ -1,6 +1,6 @@ import { AllowedMentions, BushCommand, BushMessage, BushSlashMessage } from '@lib'; import { Snowflake, User } from 'discord.js'; -import { Moderation } from '../../lib/common/moderation'; +import { Moderation } from '../../lib/common/Moderation'; export default class BanCommand extends BushCommand { public constructor() { diff --git a/src/commands/moderation/evidence.ts b/src/commands/moderation/evidence.ts index 250df24..a681bc1 100644 --- a/src/commands/moderation/evidence.ts +++ b/src/commands/moderation/evidence.ts @@ -27,8 +27,8 @@ export default class EvidenceCommand extends BushCommand { } ], channel: 'guild', - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES', 'MANAGE_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: (m) => util.userGuildPermCheck(m, ['MANAGE_MESSAGES']) }); } diff --git a/src/commands/moderation/hideCase.ts b/src/commands/moderation/hideCase.ts index 2ed788a..38cfe31 100644 --- a/src/commands/moderation/hideCase.ts +++ b/src/commands/moderation/hideCase.ts @@ -20,10 +20,8 @@ export default class HideCaseCommand extends BushCommand { } } ], - userPermissions: (message) => { - return message.member?.permissions.has('MANAGE_MESSAGES') ? null : ['MANAGE_MESSAGES']; - }, - clientPermissions: ['SEND_MESSAGES'], + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: (m) => util.userGuildPermCheck(m, ['MANAGE_MESSAGES']), slash: true, slashOptions: [ { diff --git a/src/commands/moderation/kick.ts b/src/commands/moderation/kick.ts index 715483a..9bd5658 100644 --- a/src/commands/moderation/kick.ts +++ b/src/commands/moderation/kick.ts @@ -1,5 +1,5 @@ -import { AllowedMentions, BushCommand, BushGuildMember, BushMessage, BushSlashMessage, BushUser } from '@lib'; -import { Moderation } from '../../lib/common/moderation'; +import { AllowedMentions, BushCommand, BushMessage, BushSlashMessage, BushUser } from '@lib'; +import { Moderation } from '../../lib/common/Moderation'; export default class KickCommand extends BushCommand { public constructor() { @@ -51,7 +51,7 @@ export default class KickCommand extends BushCommand { required: false } ], - clientPermissions: ['SEND_MESSAGES', 'KICK_MEMBERS'], + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['KICK_MEMBERS']), userPermissions: ['KICK_MEMBERS'] }); } @@ -60,7 +60,7 @@ export default class KickCommand extends BushCommand { message: BushMessage | BushSlashMessage, { user, reason, force }: { user: BushUser; reason?: string; force: boolean } ): Promise { - const member = message.guild!.members.cache.get(user.id) as BushGuildMember; + const member = await message.guild!.members.fetch(user.id); if (!member) return await message.util.reply( diff --git a/src/commands/moderation/modlog.ts b/src/commands/moderation/modlog.ts index d5c6f91..eb37681 100644 --- a/src/commands/moderation/modlog.ts +++ b/src/commands/moderation/modlog.ts @@ -1,5 +1,6 @@ import { BushCommand, BushMessage, BushSlashMessage, BushUser, ModLog } from '@lib'; import { MessageEmbed, User } from 'discord.js'; +import { ButtonPaginator } from '../../lib/common/ButtonPaginator'; export default class ModlogCommand extends BushCommand { public constructor() { @@ -27,7 +28,8 @@ export default class ModlogCommand extends BushCommand { default: false } ], - userPermissions: [], + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: (m) => util.userGuildPermCheck(m, ['MANAGE_MESSAGES']), slash: true, slashOptions: [ { @@ -62,10 +64,6 @@ export default class ModlogCommand extends BushCommand { message: BushMessage | BushSlashMessage, { search, hidden }: { search: BushUser | string; hidden: boolean } ): Promise { - if (!message.member?.permissions.has('MANAGE_MESSAGES')) - return await message.util.reply( - `${util.emojis.error} You must have the **Manage Message** permission to use this command.` - ); const foundUser = search instanceof User ? search : await util.resolveUserAsync(search); if (foundUser) { const logs = await ModLog.findAll({ @@ -90,7 +88,7 @@ export default class ModlogCommand extends BushCommand { color: util.colors.default }) ); - return await util.buttonPaginate(message, embedPages, undefined, true); + return await ButtonPaginator.send(message, embedPages, undefined, true); } else if (search) { const entry = await ModLog.findByPk(search as string); if (!entry || entry.pseudo || (entry.hidden && !hidden)) @@ -102,7 +100,7 @@ export default class ModlogCommand extends BushCommand { description: this.#generateModlogInfo(entry, true), color: util.colors.default }; - return await util.buttonPaginate(message, [embed]); + return await ButtonPaginator.send(message, [embed]); } } } diff --git a/src/commands/moderation/mute.ts b/src/commands/moderation/mute.ts index 942c0b0..03ecf2a 100644 --- a/src/commands/moderation/mute.ts +++ b/src/commands/moderation/mute.ts @@ -1,5 +1,5 @@ import { AllowedMentions, BushCommand, BushMessage, BushSlashMessage, BushUser } from '@lib'; -import { Moderation } from '../../lib/common/moderation'; +import { Moderation } from '../../lib/common/Moderation'; export default class MuteCommand extends BushCommand { public constructor() { @@ -52,8 +52,8 @@ export default class MuteCommand extends BushCommand { } ], channel: 'guild', - clientPermissions: ['SEND_MESSAGES', 'MANAGE_ROLES'], - userPermissions: ['MANAGE_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['MANAGE_ROLES']), + userPermissions: (m) => util.userGuildPermCheck(m, ['MANAGE_MESSAGES']) }); } @@ -66,7 +66,7 @@ export default class MuteCommand extends BushCommand { }: { user: BushUser; reason?: { duration: number | null; contentWithoutTime: string }; force: boolean } ): Promise { if (reason?.duration === null) reason.duration = 0; - const member = message.guild!.members.cache.get(user.id); + const member = await message.guild!.members.fetch(user.id).catch(() => null); if (!member) return await message.util.reply( `${util.emojis.error} The user you selected is not in the server or is not a valid user.` diff --git a/src/commands/moderation/purge.ts b/src/commands/moderation/purge.ts index 062dad0..a77e46a 100644 --- a/src/commands/moderation/purge.ts +++ b/src/commands/moderation/purge.ts @@ -37,7 +37,7 @@ export default class PurgeCommand extends BushCommand { required: false } ], - clientPermissions: ['MANAGE_MESSAGES', 'SEND_MESSAGES', 'EMBED_LINKS'], + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['MANAGE_MESSAGES', 'EMBED_LINKS'], true), userPermissions: ['MANAGE_MESSAGES'], channel: 'guild' }); diff --git a/src/commands/moderation/removeReactionEmoji.ts b/src/commands/moderation/removeReactionEmoji.ts index dc05883..63e20bd 100644 --- a/src/commands/moderation/removeReactionEmoji.ts +++ b/src/commands/moderation/removeReactionEmoji.ts @@ -11,8 +11,6 @@ export default class RemoveReactionEmojiCommand extends BushCommand { usage: 'remove-reaction-emoji ', examples: ['remove-reaction-emoji 791413052347252786 <:omegaclown:782630946435366942>'] }, - clientPermissions: ['MANAGE_MESSAGES', 'SEND_MESSAGES', 'EMBED_LINKS'], - userPermissions: ['MANAGE_MESSAGES', 'MANAGE_EMOJIS_AND_STICKERS'], // Can't undo the removal of 1000s of reactions args: [ { id: 'messageToRemoveFrom', @@ -32,7 +30,9 @@ export default class RemoveReactionEmojiCommand extends BushCommand { } } ], - channel: 'guild' + channel: 'guild', + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['MANAGE_MESSAGES', 'EMBED_LINKS'], true), + userPermissions: ['MANAGE_MESSAGES', 'MANAGE_EMOJIS_AND_STICKERS'] // Can't undo the removal of 1000s of reactions }); } diff --git a/src/commands/moderation/role.ts b/src/commands/moderation/role.ts index c39864b..fe34d75 100644 --- a/src/commands/moderation/role.ts +++ b/src/commands/moderation/role.ts @@ -50,8 +50,8 @@ export default class RoleCommand extends BushCommand { ], channel: 'guild', typing: true, - clientPermissions: ['MANAGE_ROLES', 'EMBED_LINKS', 'SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['MANAGE_ROLES', 'EMBED_LINKS'], true), + userPermissions: [] }); } diff --git a/src/commands/moderation/slowmode.ts b/src/commands/moderation/slowmode.ts index 94e40ca..d90f122 100644 --- a/src/commands/moderation/slowmode.ts +++ b/src/commands/moderation/slowmode.ts @@ -42,8 +42,8 @@ export default class SlowModeCommand extends BushCommand { } ], channel: 'guild', - clientPermissions: ['MANAGE_CHANNELS', 'SEND_MESSAGES', 'EMBED_LINKS'], - userPermissions: ['MANAGE_MESSAGES', 'SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['MANAGE_CHANNELS', 'EMBED_LINKS'], true), + userPermissions: (m) => util.userGuildPermCheck(m, ['MANAGE_MESSAGES']) }); } diff --git a/src/commands/moderation/unban.ts b/src/commands/moderation/unban.ts index a319ff9..61e27cf 100644 --- a/src/commands/moderation/unban.ts +++ b/src/commands/moderation/unban.ts @@ -1,5 +1,4 @@ import { AllowedMentions, BushCommand, BushMessage, BushSlashMessage, BushUser } from '@lib'; -import { User } from 'discord.js'; export default class UnbanCommand extends BushCommand { public constructor() { @@ -14,7 +13,7 @@ export default class UnbanCommand extends BushCommand { args: [ { id: 'user', - type: 'user', + type: 'globalUser', prompt: { start: 'What user would you like to unban?', retry: '{error} Choose a valid user to unban.' @@ -55,10 +54,6 @@ export default class UnbanCommand extends BushCommand { message: BushMessage | BushSlashMessage, { user, reason }: { user: BushUser; reason?: string } ): Promise { - if (!(user instanceof User)) { - user = util.resolveUser(user, client.users.cache) as BushUser; - } - const responseCode = await message.guild!.bushUnban({ user, moderator: message.author, diff --git a/src/commands/moderation/unmute.ts b/src/commands/moderation/unmute.ts index 3d592b7..e430b83 100644 --- a/src/commands/moderation/unmute.ts +++ b/src/commands/moderation/unmute.ts @@ -1,5 +1,5 @@ import { AllowedMentions, BushCommand, BushGuildMember, BushMessage, BushSlashMessage, BushUser } from '@lib'; -import { Moderation } from '../../lib/common/moderation'; +import { Moderation } from '../../lib/common/Moderation'; export default class UnmuteCommand extends BushCommand { public constructor() { @@ -52,8 +52,8 @@ export default class UnmuteCommand extends BushCommand { } ], channel: 'guild', - clientPermissions: ['SEND_MESSAGES', 'MANAGE_ROLES'], - userPermissions: ['MANAGE_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['MANAGE_ROLES']), + userPermissions: (m) => util.userGuildPermCheck(m, ['MANAGE_MESSAGES']) }); } diff --git a/src/commands/moderation/warn.ts b/src/commands/moderation/warn.ts index 3df4b3b..6ae8442 100644 --- a/src/commands/moderation/warn.ts +++ b/src/commands/moderation/warn.ts @@ -1,5 +1,5 @@ import { BushCommand, BushGuildMember, BushMessage, BushSlashMessage, BushUser } from '@lib'; -import { Moderation } from '../../lib/common/moderation'; +import { Moderation } from '../../lib/common/Moderation'; export default class WarnCommand extends BushCommand { public constructor() { @@ -51,8 +51,8 @@ export default class WarnCommand extends BushCommand { } ], channel: 'guild', - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['MANAGE_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: (m) => util.userGuildPermCheck(m, ['MANAGE_MESSAGES']) }); } diff --git a/src/commands/moulberry-bush/capePerms.ts b/src/commands/moulberry-bush/capePerms.ts index 978d8e5..e26a5a4 100644 --- a/src/commands/moulberry-bush/capePerms.ts +++ b/src/commands/moulberry-bush/capePerms.ts @@ -23,7 +23,8 @@ export default class CapePermissionsCommand extends BushCommand { } } ], - clientPermissions: ['EMBED_LINKS', 'SEND_MESSAGES'], + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: [], channel: 'guild', slash: true, slashOptions: [ @@ -38,7 +39,7 @@ export default class CapePermissionsCommand extends BushCommand { } public override async exec(message: BushMessage | BushSlashMessage, args: { ign: string }): Promise { - interface Capeperms { + interface CapePerms { success: boolean; perms: User[]; } @@ -48,7 +49,7 @@ export default class CapePermissionsCommand extends BushCommand { perms: string[]; } - let capeperms: Capeperms | null, uuid: string; + let capePerms: CapePerms | null, uuid: string; try { uuid = await util.findUUID(args.ign); } catch (e) { @@ -56,18 +57,18 @@ export default class CapePermissionsCommand extends BushCommand { } try { - capeperms = await got.get('http://moulberry.codes/permscapes.json').json(); + capePerms = await got.get('http://moulberry.codes/permscapes.json').json(); } catch (error) { - capeperms = null; + capePerms = null; } - if (capeperms == null) { + if (capePerms == null) { return await message.util.reply(`${util.emojis.error} There was an error finding cape perms for \`${args.ign}\`.`); } else { - if (capeperms?.perms) { + if (capePerms?.perms) { let index = null; - for (let i = 0; i < capeperms.perms.length; i++) { - if (capeperms.perms[i]._id == uuid) { + for (let i = 0; i < capePerms.perms.length; i++) { + if (capePerms.perms[i]._id == uuid) { index = i; break; } @@ -75,7 +76,7 @@ export default class CapePermissionsCommand extends BushCommand { } if (index == null) return await message.util.reply(`${util.emojis.error} \`${args.ign}\` does not appear to have any capes.`); - const userPerm: string[] = capeperms.perms[index].perms; + const userPerm: string[] = capePerms.perms[index].perms; const embed = new MessageEmbed() .setTitle(`${args.ign}'s Capes`) .setDescription(userPerm.join('\n')) diff --git a/src/commands/moulberry-bush/capes.ts b/src/commands/moulberry-bush/capes.ts index 14a972e..1a09eb0 100644 --- a/src/commands/moulberry-bush/capes.ts +++ b/src/commands/moulberry-bush/capes.ts @@ -1,6 +1,8 @@ -import { MessageEmbed } from 'discord.js'; +import { MessageEmbedOptions } from 'discord.js'; import got from 'got'; import { BushCommand, BushMessage } from '../../lib'; +import { ButtonPaginator } from '../../lib/common/ButtonPaginator'; +import { DeleteButton } from '../../lib/common/DeleteButton'; export interface GithubFile { path: string; @@ -58,8 +60,8 @@ export default class CapesCommand extends BushCommand { required: false } ], - clientPermissions: ['EMBED_LINKS', 'SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: [] }); } @@ -102,30 +104,33 @@ export default class CapesCommand extends BushCommand { } return 0; }); + if (args.cape) { - const capeObj = sortedCapes.find((s_cape) => s_cape.name === args.cape); - if (capeObj) { - const embed = new MessageEmbed({ - title: `${capeObj.name} cape`, - color: util.colors.default - }).setTimestamp(); - embed.setImage(capeObj.url); - await util.sendWithDeleteButton(message, { embeds: [embed] }); + const cape = sortedCapes.find((s_cape) => s_cape.name === args.cape); + if (cape) { + const embed = this.makeEmbed(cape); + await DeleteButton.send(message, { embeds: [embed] }); } else { await message.util.reply(`${util.emojis.error} Cannot find a cape called \`${args.cape}\`.`); } } else { - const embeds = []; - for (const capeObj of sortedCapes) { - const embed = new MessageEmbed({ - title: `${capeObj.name} cape`, - color: util.colors.default - }).setTimestamp(); - embed.setImage(capeObj.url); - if (capeObj.purchasable) embed.setDescription(':money_with_wings: **purchasable** :money_with_wings:'); - embeds.push(embed); - } - await util.buttonPaginate(message, embeds, null); + const embeds: MessageEmbedOptions[] = sortedCapes.map(this.makeEmbed); + await ButtonPaginator.send(message, embeds, null); } } + + private makeEmbed(cape: { + name: string; + url: string; + index: number; + purchasable?: boolean | undefined; + }): MessageEmbedOptions { + return { + title: `${cape.name} cape`, + color: util.colors.default, + timestamp: Date.now(), + image: { url: cape.url }, + description: cape.purchasable ? ':money_with_wings: **purchasable** :money_with_wings:' : undefined + }; + } } diff --git a/src/commands/moulberry-bush/giveawayPing.ts b/src/commands/moulberry-bush/giveawayPing.ts index 18f4acf..d6005b0 100644 --- a/src/commands/moulberry-bush/giveawayPing.ts +++ b/src/commands/moulberry-bush/giveawayPing.ts @@ -10,8 +10,8 @@ export default class GiveawayPingCommand extends BushCommand { usage: 'giveaway-ping', examples: ['giveaway-ping'] }, - clientPermissions: ['MANAGE_MESSAGES'], - userPermissions: ['SEND_MESSAGES', 'MANAGE_GUILD', 'MANAGE_MESSAGES', 'BAN_MEMBERS', 'KICK_MEMBERS', 'VIEW_CHANNEL'], + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['MANAGE_MESSAGES'], true), + userPermissions: ['MANAGE_GUILD', 'MANAGE_MESSAGES', 'BAN_MEMBERS', 'KICK_MEMBERS', 'VIEW_CHANNEL'], channel: 'guild', ignoreCooldown: [], ignorePermissions: [], diff --git a/src/commands/moulberry-bush/moulHammer.ts b/src/commands/moulberry-bush/moulHammer.ts index d5930b5..129eb84 100644 --- a/src/commands/moulberry-bush/moulHammer.ts +++ b/src/commands/moulberry-bush/moulHammer.ts @@ -11,8 +11,6 @@ export default class MoulHammerCommand extends BushCommand { usage: 'moulHammer ', examples: ['moulHammer @IRONM00N'] }, - clientPermissions: ['EMBED_LINKS', 'SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'], args: [ { id: 'user', @@ -23,7 +21,9 @@ export default class MoulHammerCommand extends BushCommand { } } ], - restrictedGuilds: ['516977525906341928'] + restrictedGuilds: ['516977525906341928'], + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: [] }); } diff --git a/src/commands/moulberry-bush/report.ts b/src/commands/moulberry-bush/report.ts index a5c4cb2..13976bb 100644 --- a/src/commands/moulberry-bush/report.ts +++ b/src/commands/moulberry-bush/report.ts @@ -33,8 +33,6 @@ export default class ReportCommand extends BushCommand { } } ], - clientPermissions: ['EMBED_LINKS', 'SEND_MESSAGES'], - channel: 'guild', slash: true, slashOptions: [ { @@ -49,7 +47,10 @@ export default class ReportCommand extends BushCommand { type: 'STRING', required: false } - ] + ], + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: [], + channel: 'guild' }); } @@ -102,7 +103,6 @@ export default class ReportCommand extends BushCommand { true ); - //reusing code pog if (message.attachments.size > 0) { const fileName = message.attachments.first()!.name!.toLowerCase(); if (fileName.endsWith('.png') || fileName.endsWith('.jpg') || fileName.endsWith('.gif') || fileName.endsWith('.webp')) { diff --git a/src/commands/moulberry-bush/rule.ts b/src/commands/moulberry-bush/rule.ts index 0c1e435..59c9e43 100644 --- a/src/commands/moulberry-bush/rule.ts +++ b/src/commands/moulberry-bush/rule.ts @@ -81,9 +81,6 @@ export default class RuleCommand extends BushCommand { } } ], - clientPermissions: ['EMBED_LINKS', 'SEND_MESSAGES'], - channel: 'guild', - restrictedGuilds: ['516977525906341928'], slash: true, slashOptions: [ { @@ -99,7 +96,11 @@ export default class RuleCommand extends BushCommand { required: false } ], - slashGuilds: ['516977525906341928'] + slashGuilds: ['516977525906341928'], + channel: 'guild', + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: [], + restrictedGuilds: ['516977525906341928'] }); } diff --git a/src/commands/moulberry-bush/serverStatus.ts b/src/commands/moulberry-bush/serverStatus.ts index 8ff9803..f4a80d4 100644 --- a/src/commands/moulberry-bush/serverStatus.ts +++ b/src/commands/moulberry-bush/serverStatus.ts @@ -14,7 +14,8 @@ export default class ServerStatusCommand extends BushCommand { }, ratelimit: 4, cooldown: 4000, - clientPermissions: ['EMBED_LINKS', 'SEND_MESSAGES'], + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: [], slash: true }); } diff --git a/src/commands/utilities/activity.ts b/src/commands/utilities/activity.ts index de7e79f..c3839e5 100644 --- a/src/commands/utilities/activity.ts +++ b/src/commands/utilities/activity.ts @@ -100,8 +100,8 @@ export default class YouTubeCommand extends BushCommand { choices: Object.keys(activityMap).map((key) => ({ name: key, value: activityMap[key as keyof typeof activityMap] })) } ], - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [] }); } diff --git a/src/commands/utilities/calculator.ts b/src/commands/utilities/calculator.ts index a2c91e4..743e9b2 100644 --- a/src/commands/utilities/calculator.ts +++ b/src/commands/utilities/calculator.ts @@ -33,8 +33,8 @@ export default class CalculatorCommand extends BushCommand { required: true } ], - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [] }); } public override async exec(message: BushMessage | BushSlashMessage, args: { expression: string }): Promise { diff --git a/src/commands/utilities/decode.ts b/src/commands/utilities/decode.ts index e48c644..c497183 100644 --- a/src/commands/utilities/decode.ts +++ b/src/commands/utilities/decode.ts @@ -3,7 +3,7 @@ import { AkairoMessage } from 'discord-akairo'; import { MessageEmbed } from 'discord.js'; const encodingTypesArray = ['ascii', 'utf8', 'utf-8', 'utf16le', 'ucs2', 'ucs-2', 'base64', 'latin1', 'binary', 'hex']; -const encodingTypesString = '`ascii`, `utf8`, `utf-8`, `utf16le`, `ucs2`, `ucs-2`, `base64`, `latin1`, `binary`, `hex`'; +const encodingTypesString = encodingTypesArray.map((e) => `\`${e}\``).join(', '); export default class DecodeCommand extends BushCommand { public constructor() { @@ -42,43 +42,20 @@ export default class DecodeCommand extends BushCommand { } } ], - clientPermissions: ['SEND_MESSAGES'], slash: true, slashOptions: [ { name: 'from', description: 'The type of data you are inputting.', type: 'STRING', - choices: [ - { name: 'ascii', value: 'ascii' }, - { name: 'utf8', value: 'utf8' }, - { name: 'utf-8', value: 'utf-8' }, - { name: 'utf16le', value: 'utf16le' }, - { name: 'ucs2', value: 'ucs2' }, - { name: 'ucs-2', value: 'ucs-2' }, - { name: 'base64', value: 'base64' }, - { name: 'latin1', value: 'latin1' }, - { name: 'binary', value: 'binary' }, - { name: 'hex', value: 'hex' } - ], + choices: encodingTypesArray.map((e) => ({ name: e, value: e })), required: true }, { name: 'to', description: 'The type of data you want the output to be.', type: 'STRING', - choices: [ - { name: 'ascii', value: 'ascii' }, - { name: 'utf8', value: 'utf8' }, - { name: 'utf-8', value: 'utf-8' }, - { name: 'utf16le', value: 'utf16le' }, - { name: 'ucs2', value: 'ucs2' }, - { name: 'ucs-2', value: 'ucs-2' }, - { name: 'base64', value: 'base64' }, - { name: 'latin1', value: 'latin1' }, - { name: 'binary', value: 'binary' }, - { name: 'hex', value: 'hex' } - ], + choices: encodingTypesArray.map((e) => ({ name: e, value: e })), required: true }, { @@ -87,7 +64,9 @@ export default class DecodeCommand extends BushCommand { type: 'STRING', required: true } - ] + ], + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [] }); } diff --git a/src/commands/utilities/hash.ts b/src/commands/utilities/hash.ts index 16ace93..df604c8 100644 --- a/src/commands/utilities/hash.ts +++ b/src/commands/utilities/hash.ts @@ -22,7 +22,8 @@ export default class HashCommand extends BushCommand { } } ], - clientPermissions: ['SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [] }); } diff --git a/src/commands/utilities/price.ts b/src/commands/utilities/price.ts index 497935a..a012501 100644 --- a/src/commands/utilities/price.ts +++ b/src/commands/utilities/price.ts @@ -51,15 +51,11 @@ export default class PriceCommand extends BushCommand { super('price', { aliases: ['price'], category: 'utilities', - clientPermissions: ['EMBED_LINKS', 'SEND_MESSAGES'], description: { usage: 'price ', examples: ['price ASPECT_OF_THE_END'], content: 'Finds the price information of an item.' }, - ratelimit: 4, - cooldown: 4000, - typing: true, args: [ { id: 'item', @@ -91,7 +87,12 @@ export default class PriceCommand extends BushCommand { type: 'BOOLEAN', required: false } - ] + ], + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: [], + ratelimit: 4, + cooldown: 4000, + typing: true }); } diff --git a/src/commands/utilities/steal.ts b/src/commands/utilities/steal.ts index 7d61016..767534e 100644 --- a/src/commands/utilities/steal.ts +++ b/src/commands/utilities/steal.ts @@ -27,8 +27,8 @@ export default class StealCommand extends BushCommand { ], slash: false, channel: 'guild', - clientPermissions: ['SEND_MESSAGES', 'MANAGE_EMOJIS_AND_STICKERS'], - userPermissions: ['SEND_MESSAGES', 'MANAGE_EMOJIS_AND_STICKERS'] + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['MANAGE_EMOJIS_AND_STICKERS']), + userPermissions: ['MANAGE_EMOJIS_AND_STICKERS'] }); } public override async exec( diff --git a/src/commands/utilities/suicide.ts b/src/commands/utilities/suicide.ts index 58119ef..9289b1c 100644 --- a/src/commands/utilities/suicide.ts +++ b/src/commands/utilities/suicide.ts @@ -12,8 +12,8 @@ export default class TemplateCommand extends BushCommand { examples: ['suicide'] }, slash: true, - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'], + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [], bypassChannelBlacklist: true }); } @@ -29,16 +29,20 @@ export default class TemplateCommand extends BushCommand { ) .addField( '**National Suicide Prevention Hotline (U.S.):**', - `**Call:** 1-800-273-8255, available 24/7 for emotional support -**Text: HOME** to 741741 -https://suicidepreventionlifeline.org/chat/ - -**Outside the U.S**: Find a supportive resource on [this Wikipedia list of worldwide crisis hotlines](https://en.wikipedia.org/wiki/List_of_suicide_crisis_lines)` + [ + '**Call:** 1-800-273-8255, available 24/7 for emotional support', + '**Text: HOME** to 741741', + 'https://suicidepreventionlifeline.org/chat/', + '', + '**Outside the U.S**: Find a supportive resource on [this Wikipedia list of worldwide crisis hotlines](https://en.wikipedia.org/wiki/List_of_suicide_crisis_lines)' + ].join('\n') ) .addField( '**More Support**', - `For Substance Abuse Support, Eating Disorder Support & Child Abuse and Domestic Violence: -[Click to go to Discord's Health & Safety Page](https://discord.com/safety/360044103771-Mental-health-on-Discord#h_01EGRGT08QSZ5BNCH2E9HN0NYV)` + [ + 'For Substance Abuse Support, Eating Disorder Support & Child Abuse and Domestic Violence:', + "[Click to go to Discord's Health & Safety Page](https://discord.com/safety/360044103771-Mental-health-on-Discord#h_01EGRGT08QSZ5BNCH2E9HN0NYV)" + ].join('\n') ); return ( diff --git a/src/commands/utilities/uuid.ts b/src/commands/utilities/uuid.ts index 50280a0..9484729 100644 --- a/src/commands/utilities/uuid.ts +++ b/src/commands/utilities/uuid.ts @@ -14,7 +14,6 @@ export default class UuidCommand extends BushCommand { { id: 'ign', customType: /\w{1,16}/im, - prompt: { start: 'What ign would you like to find the uuid of?', retry: '{error} Choose a valid ign.', @@ -22,9 +21,8 @@ export default class UuidCommand extends BushCommand { } } ], - cooldown: 4000, - ratelimit: 1, - clientPermissions: ['SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [] }); } diff --git a/src/commands/utilities/viewraw.ts b/src/commands/utilities/viewraw.ts index bd185d4..b7017c6 100644 --- a/src/commands/utilities/viewraw.ts +++ b/src/commands/utilities/viewraw.ts @@ -3,11 +3,9 @@ import { BushCommand, BushMessage, BushSlashMessage } from '../../lib'; export default class ViewRawCommand extends BushCommand { public constructor() { - super('viewraw', { - aliases: ['viewraw'], + super('view-raw', { + aliases: ['view-raw', 'vr'], category: 'utilities', - clientPermissions: ['EMBED_LINKS'], - channel: 'guild', description: { usage: 'viewraw ', examples: ['viewraw 322862723090219008'], @@ -42,7 +40,37 @@ export default class ViewRawCommand extends BushCommand { match: 'flag', flag: '--js' } - ] + ], + slash: true, + slashOptions: [ + { + name: 'message', + description: 'What message would you like to view?', + type: 'STRING', + required: true + }, + { + name: 'channel', + description: 'What channel is the message in?', + type: 'CHANNEL', + required: false + }, + { + name: 'json', + description: 'Would you like to view the raw JSON message data?', + type: 'BOOLEAN', + required: false + }, + { + name: 'js', + description: 'Would you like to view the raw message data?', + type: 'BOOLEAN', + required: false + } + ], + channel: 'guild', + clientPermissions: (m) => util.clientSendAndPermCheck(m, ['EMBED_LINKS'], true), + userPermissions: [] }); } diff --git a/src/commands/utilities/whoHasRole.ts b/src/commands/utilities/whoHasRole.ts index 1b72d65..bce88d6 100644 --- a/src/commands/utilities/whoHasRole.ts +++ b/src/commands/utilities/whoHasRole.ts @@ -1,5 +1,6 @@ import { BushCommand, BushMessage, BushSlashMessage } from '@lib'; import { CommandInteraction, Role, Util } from 'discord.js'; +import { ButtonPaginator } from '../../lib/common/ButtonPaginator'; export default class WhoHasRoleCommand extends BushCommand { public constructor() { @@ -32,8 +33,8 @@ export default class WhoHasRoleCommand extends BushCommand { } ], channel: 'guild', - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'], + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [], typing: true }); } @@ -51,6 +52,6 @@ export default class WhoHasRoleCommand extends BushCommand { color })); - return await util.buttonPaginate(message, embedPages, null, true); + return await ButtonPaginator.send(message, embedPages, null, true); } } diff --git a/src/commands/utilities/wolframAlpha.ts b/src/commands/utilities/wolframAlpha.ts index 4a357b8..049dd60 100644 --- a/src/commands/utilities/wolframAlpha.ts +++ b/src/commands/utilities/wolframAlpha.ts @@ -1,5 +1,5 @@ import { AllowedMentions, BushCommand, BushMessage, BushSlashMessage } from '@lib'; -import { CommandInteraction, MessageEmbed } from 'discord.js'; +import { CommandInteraction, MessageEmbed, MessageOptions } from 'discord.js'; import WolframAlphaAPI from 'wolfram-alpha-api'; export default class WolframAlphaCommand extends BushCommand { @@ -13,6 +13,7 @@ export default class WolframAlphaCommand extends BushCommand { examples: ['wolfram-alpha what is the population of france'] }, args: [ + { id: 'image', match: 'flag', flag: '--image' }, { id: 'expression', type: 'string', @@ -31,30 +32,49 @@ export default class WolframAlphaCommand extends BushCommand { description: 'What would you like to look up?', type: 'STRING', required: true + }, + { + name: 'image', + description: 'Would you like to use the Simple API instead of the Short Answers API?', + type: 'BOOLEAN', + required: false } ], - clientPermissions: ['SEND_MESSAGES'], - userPermissions: ['SEND_MESSAGES'] + clientPermissions: (m) => util.clientSendAndPermCheck(m), + userPermissions: [] }); } - public override async exec(message: BushMessage | BushSlashMessage, args: { expression: string }): Promise { + public override async exec( + message: BushMessage | BushSlashMessage, + args: { expression: string; image: boolean } + ): Promise { if (message.util.isSlash) await (message.interaction as CommandInteraction).deferReply(); + args.image && void message.util.reply({ content: `${util.emojis.loading} Loading...`, embeds: [] }); const waApi = WolframAlphaAPI(client.config.credentials.wolframAlphaAppId); const decodedEmbed = new MessageEmbed().addField('📥 Input', await util.inspectCleanRedactCodeblock(args.expression)); + const sendOptions: MessageOptions = { content: null, allowedMentions: AllowedMentions.none() }; try { - const calculated = await waApi.getShort(args.expression); - decodedEmbed - .setTitle(`${util.emojis.successFull} Successfully Queried Expression`) - .setColor(util.colors.success) - .addField('📤 Output', await util.inspectCleanRedactCodeblock(calculated.toString())); + const calculated = await (args.image + ? waApi.getSimple({ i: args.expression, timeout: 1, background: '2C2F33', foreground: 'white' }) + : waApi.getShort(args.expression)); + decodedEmbed.setTitle(`${util.emojis.successFull} Successfully Queried Expression`).setColor(util.colors.success); + + if (args.image) { + decodedEmbed.setImage(await util.uploadImageToImgur(calculated.split(',')[1])); + decodedEmbed.addField('📤 Output', '​'); + } else { + decodedEmbed.addField('📤 Output', await util.inspectCleanRedactCodeblock(calculated.toString())); + } } catch (error) { decodedEmbed .setTitle(`${util.emojis.errorFull} Unable to Query Expression`) .setColor(util.colors.error) .addField(`📤 Error`, await util.inspectCleanRedactCodeblock(`${error.name}: ${error.message}`, 'js')); } - return await message.util.reply({ embeds: [decodedEmbed], allowedMentions: AllowedMentions.none() }); + sendOptions.embeds = [decodedEmbed]; + + return await message.util.reply(sendOptions); } } -- cgit