aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arguments/contentWithDuration.ts0
-rw-r--r--src/arguments/duration.ts40
-rw-r--r--src/commands/config/muteRole.ts21
-rw-r--r--src/commands/config/prefix.ts49
-rw-r--r--src/commands/config/welcomeChannel.ts63
-rw-r--r--src/commands/dev/eval.ts19
-rw-r--r--src/commands/dev/reload.ts26
-rw-r--r--src/commands/dev/setLevel.ts22
-rw-r--r--src/commands/dev/superUser.ts6
-rw-r--r--src/commands/info/help.ts5
-rw-r--r--src/commands/info/ping.ts2
-rw-r--r--src/commands/info/pronouns.ts60
-rw-r--r--src/commands/moderation/ban.ts7
-rw-r--r--src/commands/moderation/kick.ts7
-rw-r--r--src/commands/moderation/mute.ts7
-rw-r--r--src/commands/moderation/role.ts5
-rw-r--r--src/commands/moulberry-bush/capePerms.ts3
-rw-r--r--src/commands/moulberry-bush/level.ts5
-rw-r--r--src/commands/moulberry-bush/rule.ts5
-rw-r--r--src/inhibitors/blacklist/guildBlacklist.ts2
-rw-r--r--src/inhibitors/blacklist/userBlacklist.ts2
-rw-r--r--src/inhibitors/commands/disabledCommand.ts2
-rw-r--r--src/inhibitors/noCache.ts2
-rw-r--r--src/lang/en-us.json14
-rw-r--r--src/lib/extensions/BushCommand.ts2
-rw-r--r--src/lib/extensions/BushGuild.ts20
-rw-r--r--src/lib/extensions/BushGuildMember.ts13
-rw-r--r--src/lib/extensions/BushInhibitor.ts2
-rw-r--r--src/lib/extensions/BushMessage.ts12
-rw-r--r--src/lib/extensions/BushSlashMessage.ts (renamed from src/lib/extensions/BushInteractionMessage.ts)4
-rw-r--r--src/lib/extensions/BushUser.ts17
-rw-r--r--src/lib/utils/BushConstants.ts36
-rw-r--r--src/listeners/commands/slashBlocked.ts2
-rw-r--r--src/listeners/commands/slashCommandError.ts2
-rw-r--r--src/listeners/commands/slashStarted.ts2
35 files changed, 280 insertions, 206 deletions
diff --git a/src/arguments/contentWithDuration.ts b/src/arguments/contentWithDuration.ts
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/arguments/contentWithDuration.ts
diff --git a/src/arguments/duration.ts b/src/arguments/duration.ts
index a2f7751..7b7a922 100644
--- a/src/arguments/duration.ts
+++ b/src/arguments/duration.ts
@@ -1,45 +1,11 @@
import { BushArgumentTypeCaster } from '../lib/extensions/BushArgumentTypeCaster';
import { BushMessage } from '../lib/extensions/BushMessage';
+import { BushConstants } from '../lib/utils/BushConstants';
-// Stolen from @Mzato0001 (pr to discord akairo that hasn't been merged yet)
-const TimeUnits = {
- years: {
- label: '(?:years?|y)',
- value: 1000 * 60 * 60 * 24 * 365
- },
- months: {
- label: '(?:months?|mo)',
- value: 1000 * 60 * 60 * 24 * 30
- },
- weeks: {
- label: '(?:weeks?|w)',
- value: 1000 * 60 * 60 * 24 * 7
- },
- days: {
- label: '(?:days?|d)',
- value: 1000 * 60 * 60 * 24
- },
- hours: {
- label: '(?:hours?|hrs?|h)',
- value: 1000 * 60 * 60
- },
- minutes: {
- label: '(?:minutes?|mins?|m)',
- value: 1000 * 60
- },
- seconds: {
- label: '(?:seconds?|secs?|s)',
- value: 1000
- },
- milliseconds: {
- label: '(?:milliseconds?|msecs?|ms)',
- value: 1
- }
-};
export const durationTypeCaster: BushArgumentTypeCaster = async (_message: BushMessage, phrase): Promise<number> => {
if (!phrase) return null;
- const regexString = Object.entries(TimeUnits)
+ const regexString = Object.entries(BushConstants.TimeUnits)
.map(([name, { label }]) => String.raw`(?:(?<${name}>-?(?:\d+)?\.?\d+) *${label})?`)
.join('\\s*');
const match = new RegExp(`^${regexString}$`, 'i').exec(phrase);
@@ -48,7 +14,7 @@ export const durationTypeCaster: BushArgumentTypeCaster = async (_message: BushM
let milliseconds = 0;
for (const key in match.groups) {
const value = Number(match.groups[key] || 0);
- milliseconds += value * TimeUnits[key].value;
+ milliseconds += value * BushConstants.TimeUnits[key].value;
}
return milliseconds;
diff --git a/src/commands/config/muteRole.ts b/src/commands/config/muteRole.ts
index f51c5ce..a354bcc 100644
--- a/src/commands/config/muteRole.ts
+++ b/src/commands/config/muteRole.ts
@@ -1,8 +1,8 @@
+import { ApplicationCommandOptionType } from 'discord-api-types';
import { Role } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
-import { BushSlashMessage } from '../../lib/extensions/BushInteractionMessage';
import { BushMessage } from '../../lib/extensions/BushMessage';
-import { Guild } from '../../lib/models';
+import { BushSlashMessage } from '../../lib/extensions/BushSlashMessage';
import AllowedMentions from '../../lib/utils/AllowedMentions';
export default class MuteRoleCommand extends BushCommand {
@@ -11,7 +11,7 @@ export default class MuteRoleCommand extends BushCommand {
aliases: ['muterole'],
category: 'config',
description: {
- content: 'Set the prefix of the current server (resets to default if prefix is not given)',
+ content: 'Configure what role to use when muting users.',
usage: 'prefix [prefix]',
examples: ['prefix', 'prefix +']
},
@@ -31,9 +31,9 @@ export default class MuteRoleCommand extends BushCommand {
slash: true,
slashOptions: [
{
- type: 'ROLE',
+ type: ApplicationCommandOptionType.ROLE,
name: 'role',
- description: 'The mute role for this server.',
+ description: "What would you like to set the server's mute role to?",
required: true
}
]
@@ -41,16 +41,9 @@ export default class MuteRoleCommand extends BushCommand {
}
async exec(message: BushMessage | BushSlashMessage, args: { role: Role }): Promise<void> {
- let row = await Guild.findByPk(message.guild.id);
- if (!row) {
- row = Guild.build({
- id: message.guild.id
- });
- }
- row.muteRole = args.role.id;
- await row.save();
+ await message.guild.setSetting('muteRole', args.role.id);
await message.util.send({
- content: `${this.client.util.emojis.success} Changed the mute role to <@&${args.role.id}>.`,
+ content: `${this.client.util.emojis.success} Changed the server's mute role to <@&${args.role.id}>.`,
allowedMentions: AllowedMentions.none()
});
}
diff --git a/src/commands/config/prefix.ts b/src/commands/config/prefix.ts
index 5b73a1a..fc7b3bf 100644
--- a/src/commands/config/prefix.ts
+++ b/src/commands/config/prefix.ts
@@ -1,13 +1,20 @@
+import { ApplicationCommandOptionType } from 'discord-api-types';
import { BushCommand } from '../../lib/extensions/BushCommand';
-import { BushSlashMessage } from '../../lib/extensions/BushInteractionMessage';
import { BushMessage } from '../../lib/extensions/BushMessage';
-import { Guild } from '../../lib/models';
+import { BushSlashMessage } from '../../lib/extensions/BushSlashMessage';
export default class PrefixCommand extends BushCommand {
constructor() {
super('prefix', {
aliases: ['prefix'],
category: 'config',
+ description: {
+ content: 'Set or reset the prefix for the server.',
+ usage: 'prefix [prefix]',
+ examples: ['prefix', 'prefix +']
+ },
+ clientPermissions: ['SEND_MESSAGES'],
+ userPermissions: ['SEND_MESSAGES', 'MANAGE_GUILD'],
args: [
{
id: 'prefix',
@@ -19,37 +26,31 @@ export default class PrefixCommand extends BushCommand {
}
}
],
- clientPermissions: ['SEND_MESSAGES'],
- userPermissions: ['SEND_MESSAGES', 'MANAGE_GUILD'],
- description: {
- content: 'Set the prefix of the current server (resets to default if prefix is not given)',
- usage: 'prefix [prefix]',
- examples: ['prefix', 'prefix +']
- },
+ slash: true,
slashOptions: [
{
- type: 'STRING',
+ type: ApplicationCommandOptionType.STRING,
name: 'prefix',
- description: 'The prefix to set for this server',
+ description: 'What would you like the new prefix to be?',
required: false
}
- ],
- slash: true
+ ]
});
}
- async exec(message: BushMessage | BushSlashMessage, { prefix }: { prefix?: string }): Promise<void> {
- let row = await Guild.findByPk(message.guild.id);
- if (!row) {
- row = Guild.build({
- id: message.guild.id
- });
- }
- await row.update({ prefix: prefix || this.client.config.prefix });
- if (prefix) {
- await message.util.send(`${this.client.util.emojis.success} changed prefix from \`${prefix}\` to `);
+ async exec(message: BushMessage | BushSlashMessage, args: { prefix?: string }): Promise<unknown> {
+ const oldPrefix = message.guild.getSetting('prefix');
+ await message.guild.setSetting('prefix', args.prefix ?? this.client.config.prefix);
+ if (args.prefix) {
+ return await message.util.send(
+ `${this.client.util.emojis.success} changed the server's prefix ${oldPrefix ? `from \`${oldPrefix}\`` : ''} to \`${
+ args.prefix
+ }\`.`
+ );
} else {
- await message.util.send(`${this.client.util.emojis.success} reset prefix to \`${this.client.config.prefix}\``);
+ return await message.util.send(
+ `${this.client.util.emojis.success} reset the server's prefix to \`${this.client.config.prefix}\`.`
+ );
}
}
}
diff --git a/src/commands/config/welcomeChannel.ts b/src/commands/config/welcomeChannel.ts
index 72e55f1..8cab33c 100644
--- a/src/commands/config/welcomeChannel.ts
+++ b/src/commands/config/welcomeChannel.ts
@@ -1,7 +1,8 @@
-import { User } from 'discord.js';
+import { ApplicationCommandOptionType } from 'discord-api-types';
+import { Channel } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
import { BushMessage } from '../../lib/extensions/BushMessage';
-import { Global } from '../../lib/models';
+import { BushSlashMessage } from '../../lib/extensions/BushSlashMessage';
export default class WelcomeChannelCommand extends BushCommand {
public constructor() {
@@ -9,41 +10,45 @@ export default class WelcomeChannelCommand extends BushCommand {
aliases: ['welcomechannel', 'wc'],
category: 'config',
description: {
- content: 'Configure the what channel you want the bot to send a message in when someone joins the server.',
+ content: 'Configure the what channel you want BushBot to send a message in when someone joins the server.',
usage: 'welcomechannel [channel]',
examples: ['welcomechannel #welcome']
},
clientPermissions: ['SEND_MESSAGES'],
- ownerOnly: true
+ userPermissions: ['SEND_MESSAGES', 'MANAGE_GUILD'],
+ args: [
+ {
+ id: 'channel',
+ type: 'channel',
+ prompt: {
+ start: 'What channel would you like me to send welcome messages in?',
+ retry: '{error} Choose a valid channel',
+ optional: true
+ }
+ }
+ ],
+ slash: true,
+ slashOptions: [
+ {
+ type: ApplicationCommandOptionType.CHANNEL,
+ name: 'channel',
+ description: 'What channel would you like me to send welcome messages in?',
+ required: false
+ }
+ ]
});
}
- public async exec(message: BushMessage, args: { action: 'add' | 'remove'; user: User }): Promise<unknown> {
- if (!this.client.config.owners.includes(message.author.id))
- return await message.util.reply(`${this.client.util.emojis.error} Only my developers can run this command...`);
-
- const superUsers = (await Global.findByPk(this.client.config.dev ? 'development' : 'production')).superUsers;
- let success;
- if (args.action === 'add') {
- if (superUsers.includes(args.user.id)) {
- return message.util.reply(`${this.client.util.emojis.warn} \`${args.user.tag}\` is already a superuser.`);
- }
- success = await this.client.util.insertOrRemoveFromGlobal('add', 'superUsers', args.user.id).catch(() => false);
- } else {
- if (!superUsers.includes(args.user.id)) {
- return message.util.reply(`${this.client.util.emojis.warn} \`${args.user.tag}\` is not superuser.`);
- }
- success = await this.client.util.insertOrRemoveFromGlobal('remove', 'superUsers', args.user.id).catch(() => false);
- }
- if (success) {
- const responses = [args.action == 'remove' ? `` : 'made', args.action == 'remove' ? 'is no longer' : ''];
- return message.util.reply(
- `${this.client.util.emojis.success} ${responses[0]} \`${args.user.tag}\` ${responses[1]} a superuser.`
+ public async exec(message: BushMessage | BushSlashMessage, args: { channel: Channel }): Promise<unknown> {
+ const oldChannel = await message.guild.getSetting('welcomeChannel');
+ await message.guild.setSetting('welcomeChannel', args.channel.id ?? undefined);
+ if (args.channel) {
+ return await message.util.send(
+ `${this.client.util.emojis.success} changed the server's welcome channel ${
+ oldChannel ? `from <#${oldChannel}>` : ''
+ } to <#${args.channel.id}>.`
);
} else {
- const response = [args.action == 'remove' ? `removing` : 'making', args.action == 'remove' ? `from` : 'to'];
- return message.util.reply(
- `${this.client.util.emojis.error} There was an error ${response[0]} \`${args.user.tag}\` ${response[1]} the superuser list.`
- );
+ return await message.util.send(`${this.client.util.emojis.success} removed the server's welcome channel.`);
}
}
}
diff --git a/src/commands/dev/eval.ts b/src/commands/dev/eval.ts
index 310a2c5..04c5158 100644
--- a/src/commands/dev/eval.ts
+++ b/src/commands/dev/eval.ts
@@ -1,12 +1,13 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { exec } from 'child_process';
import { Constants } from 'discord-akairo';
+import { ApplicationCommandOptionType } from 'discord-api-types';
import { CommandInteraction, MessageEmbed, MessageEmbedOptions, Util } from 'discord.js';
import { transpile } from 'typescript';
import { inspect, promisify } from 'util';
import { BushCommand } from '../../lib/extensions/BushCommand';
-import { BushSlashMessage } from '../../lib/extensions/BushInteractionMessage';
import { BushMessage } from '../../lib/extensions/BushMessage';
+import { BushSlashMessage } from '../../lib/extensions/BushSlashMessage';
const clean = (text) => {
if (typeof text === 'string') {
@@ -79,43 +80,43 @@ export default class EvalCommand extends BushCommand {
{
name: 'code',
description: 'The code you would like to evaluate.',
- type: 'STRING',
+ type: ApplicationCommandOptionType.STRING,
required: true
},
{
name: 'sel_depth',
description: 'How deep to display the output.',
- type: 'INTEGER',
+ type: ApplicationCommandOptionType.INTEGER,
required: false
},
{
name: 'sudo',
description: 'Whether or not to override checks.',
- type: 'BOOLEAN',
+ type: ApplicationCommandOptionType.BOOLEAN,
required: false
},
{
name: 'silent',
description: 'Whether or not to make the response silent',
- type: 'BOOLEAN',
+ type: ApplicationCommandOptionType.BOOLEAN,
required: false
},
{
name: 'typescript',
description: 'Whether or not to compile the code from typescript.',
- type: 'BOOLEAN',
+ type: ApplicationCommandOptionType.BOOLEAN,
required: false
},
{
name: 'hidden',
description: 'Whether or not to show hidden items.',
- type: 'BOOLEAN',
+ type: ApplicationCommandOptionType.BOOLEAN,
required: false
},
{
name: 'show_proto',
description: 'Show prototype.',
- type: 'BOOLEAN',
+ type: ApplicationCommandOptionType.BOOLEAN,
required: false
}
]
@@ -135,7 +136,7 @@ export default class EvalCommand extends BushCommand {
show_proto: boolean;
}
): Promise<unknown> {
- if (!this.client.config.owners.includes(message.author.id))
+ if (!message.author.isOwner())
return await message.util.reply(`${this.client.util.emojis.error} Only my developers can run this command.`);
if (message.util.isSlash) {
await (message as BushSlashMessage).interaction.defer({ ephemeral: args.silent });
diff --git a/src/commands/dev/reload.ts b/src/commands/dev/reload.ts
index f5fee88..07218f2 100644
--- a/src/commands/dev/reload.ts
+++ b/src/commands/dev/reload.ts
@@ -1,7 +1,7 @@
-import { stripIndent } from 'common-tags';
-import { Message } from 'discord.js';
+import { ApplicationCommandOptionType } from 'discord-api-types';
import { BushCommand } from '../../lib/extensions/BushCommand';
-import { BushSlashMessage } from '../../lib/extensions/BushInteractionMessage';
+import { BushMessage } from '../../lib/extensions/BushMessage';
+import { BushSlashMessage } from '../../lib/extensions/BushSlashMessage';
export default class ReloadCommand extends BushCommand {
constructor() {
@@ -24,7 +24,7 @@ export default class ReloadCommand extends BushCommand {
typing: true,
slashOptions: [
{
- type: 'BOOLEAN',
+ type: ApplicationCommandOptionType.BOOLEAN,
name: 'fast',
description: 'Whether to use esbuild for fast compiling or not',
required: false
@@ -34,23 +34,21 @@ export default class ReloadCommand extends BushCommand {
});
}
- private async getResponse(fast: boolean): Promise<string> {
+ public async exec(message: BushMessage | BushSlashMessage, { fast }: { fast: boolean }): Promise<unknown> {
+ if (!message.author.isOwner())
+ return await message.util.reply(`${this.client.util.emojis.error} Only my developers can run this command.`);
+
try {
const s = new Date();
await this.client.util.shell(`yarn build-${fast ? 'esbuild' : 'tsc'}`);
this.client.commandHandler.reloadAll();
this.client.listenerHandler.reloadAll();
this.client.inhibitorHandler.reloadAll();
- return `🔁 Successfully reloaded! (${new Date().getTime() - s.getTime()}ms)`;
+ return message.util.send(`🔁 Successfully reloaded! (${new Date().getTime() - s.getTime()}ms)`);
} catch (e) {
- return stripIndent`
- An error occured while reloading:
- ${await this.client.util.haste(e.stack)}
- `;
+ return message.util.send(
+ `An error occurred while reloading:\n${await this.client.util.codeblock(e.stack, 2048 - 34, 'js')}`
+ );
}
}
-
- public async exec(message: Message | BushSlashMessage, { fast }: { fast: boolean }): Promise<void> {
- await message.util.send(await this.getResponse(fast));
- }
}
diff --git a/src/commands/dev/setLevel.ts b/src/commands/dev/setLevel.ts
index f536109..7e07ce0 100644
--- a/src/commands/dev/setLevel.ts
+++ b/src/commands/dev/setLevel.ts
@@ -1,5 +1,8 @@
-import { Message, User } from 'discord.js';
+import { ApplicationCommandOptionType } from 'discord-api-types';
+import { User } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
+import { BushMessage } from '../../lib/extensions/BushMessage';
+import { BushSlashMessage } from '../../lib/extensions/BushSlashMessage';
import { Level } from '../../lib/models';
import AllowedMentions from '../../lib/utils/AllowedMentions';
@@ -34,13 +37,13 @@ export default class SetLevelCommand extends BushCommand {
ownerOnly: true,
slashOptions: [
{
- type: 'USER',
+ type: /* 'USER' */ ApplicationCommandOptionType.USER,
name: 'user',
description: 'The user to change the level of',
required: true
},
{
- type: 'INTEGER',
+ type: /* 'INTEGER' */ ApplicationCommandOptionType.INTEGER,
name: 'level',
description: 'The level to set the user to',
required: true
@@ -50,7 +53,10 @@ export default class SetLevelCommand extends BushCommand {
});
}
- private async setLevel(user: User, level: number): Promise<string> {
+ async exec(message: BushMessage | BushSlashMessage, { user, level }: { user: User; level: number }): Promise<unknown> {
+ if (!message.author.isOwner())
+ return await message.util.reply(`${this.client.util.emojis.error} Only my developers can run this command.`);
+
const [levelEntry] = await Level.findOrBuild({
where: {
id: user.id
@@ -60,12 +66,8 @@ export default class SetLevelCommand extends BushCommand {
}
});
await levelEntry.update({ xp: Level.convertLevelToXp(level) });
- return `Successfully set level of <@${user.id}> to \`${level}\` (\`${levelEntry.xp}\` XP)`;
- }
-
- async exec(message: Message, { user, level }: { user: User; level: number }): Promise<void> {
- await message.util.send({
- content: await this.setLevel(user, level),
+ return await message.util.send({
+ content: `Successfully set level of <@${user.id}> to \`${level}\` (\`${levelEntry.xp}\` XP)`,
allowedMentions: AllowedMentions.none()
});
}
diff --git a/src/commands/dev/superUser.ts b/src/commands/dev/superUser.ts
index 4562e6f..773209c 100644
--- a/src/commands/dev/superUser.ts
+++ b/src/commands/dev/superUser.ts
@@ -42,8 +42,8 @@ export default class SuperUserCommand extends BushCommand {
return { action, user };
}
public async exec(message: BushMessage, args: { action: 'add' | 'remove'; user: User }): Promise<unknown> {
- if (!this.client.config.owners.includes(message.author.id))
- return await message.util.reply(`${this.client.util.emojis.error} Only my developers can run this command...`);
+ if (!message.author.isOwner())
+ return await message.util.reply(`${this.client.util.emojis.error} Only my developers can run this command.`);
const superUsers = (await Global.findByPk(this.client.config.dev ? 'development' : 'production')).superUsers;
let success;
@@ -59,7 +59,7 @@ export default class SuperUserCommand extends BushCommand {
success = await this.client.util.insertOrRemoveFromGlobal('remove', 'superUsers', args.user.id).catch(() => false);
}
if (success) {
- const responses = [args.action == 'remove' ? `` : 'made', args.action == 'remove' ? 'is no longer' : ''];
+ const responses = [args.action == 'remove' ? '' : 'made', args.action == 'remove' ? 'is no longer' : ''];
return message.util.reply(
`${this.client.util.emojis.success} ${responses[0]} \`${args.user.tag}\` ${responses[1]} a superuser.`
);
diff --git a/src/commands/info/help.ts b/src/commands/info/help.ts
index 8969efc..30606e1 100644
--- a/src/commands/info/help.ts
+++ b/src/commands/info/help.ts
@@ -1,7 +1,8 @@
+import { ApplicationCommandOptionType } from 'discord-api-types';
import { MessageActionRow, MessageButton, MessageEmbed } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
-import { BushSlashMessage } from '../../lib/extensions/BushInteractionMessage';
import { BushMessage } from '../../lib/extensions/BushMessage';
+import { BushSlashMessage } from '../../lib/extensions/BushSlashMessage';
export default class HelpCommand extends BushCommand {
constructor() {
@@ -35,7 +36,7 @@ export default class HelpCommand extends BushCommand {
slash: true,
slashOptions: [
{
- type: 'STRING',
+ type: ApplicationCommandOptionType.STRING,
name: 'command',
description: 'The command you would like to find information about.',
required: false
diff --git a/src/commands/info/ping.ts b/src/commands/info/ping.ts
index 3038658..6584ab5 100644
--- a/src/commands/info/ping.ts
+++ b/src/commands/info/ping.ts
@@ -1,6 +1,6 @@
import { Message, MessageEmbed } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
-import { BushSlashMessage } from '../../lib/extensions/BushInteractionMessage';
+import { BushSlashMessage } from '../../lib/extensions/BushSlashMessage';
export default class PingCommand extends BushCommand {
constructor() {
diff --git a/src/commands/info/pronouns.ts b/src/commands/info/pronouns.ts
index 2175233..107af82 100644
--- a/src/commands/info/pronouns.ts
+++ b/src/commands/info/pronouns.ts
@@ -1,6 +1,8 @@
-import { CommandInteraction, Message, MessageEmbed, User } from 'discord.js';
+import { ApplicationCommandOptionType } from 'discord-api-types';
+import { Message, MessageEmbed, User } from 'discord.js';
import got, { HTTPError } from 'got';
import { BushCommand } from '../../lib/extensions/BushCommand';
+import { BushSlashMessage } from '../../lib/extensions/BushSlashMessage';
export const pronounMapping = {
unspecified: 'Unspecified',
@@ -41,13 +43,17 @@ export default class PronounsCommand extends BushCommand {
{
id: 'user',
type: 'user',
- default: null
+ prompt: {
+ start: 'Who would you like to view the pronouns of?',
+ retry: '{error} Choose a valid user to view the pronouns of.',
+ optional: true
+ }
}
],
clientPermissions: ['SEND_MESSAGES'],
slashOptions: [
{
- type: 'USER',
+ type: ApplicationCommandOptionType.USER,
name: 'user',
description: 'The user to get pronouns for',
required: false
@@ -56,52 +62,36 @@ export default class PronounsCommand extends BushCommand {
slash: true
});
}
- async sendResponse(message: Message | CommandInteraction, user: User, author: boolean): Promise<void> {
+ async exec(message: Message | BushSlashMessage, args: { user?: User }): Promise<void> {
+ const user = args.user || message.author;
+ const author = user.id === message.author.id;
try {
const apiRes: { pronouns: pronounsType } = await got
.get(`https://pronoundb.org/api/v1/lookup?platform=discord&id=${user.id}`)
.json();
- if (message instanceof Message) {
- message.reply({
- embeds: [
- new MessageEmbed({
- title: `${author ? 'Your' : `${user.tag}'s`} pronouns:`,
- description: pronounMapping[apiRes.pronouns],
- footer: {
- text: 'Data provided by https://pronoundb.org/'
- }
- })
- ]
- });
- } else {
- message.reply({
- embeds: [
- new MessageEmbed({
- title: `${author ? 'Your' : `${user.tag}'s`} pronouns:`,
- description: pronounMapping[apiRes.pronouns],
- footer: {
- text: 'Data provided by https://pronoundb.org/'
- }
- })
- ]
- });
- }
+ message.util.reply({
+ embeds: [
+ new MessageEmbed({
+ title: `${author ? 'Your' : `${user.tag}'s`} pronouns:`,
+ description: pronounMapping[apiRes.pronouns],
+ footer: {
+ text: 'Data provided by https://pronoundb.org/'
+ }
+ })
+ ]
+ });
} catch (e) {
if (e instanceof HTTPError && e.response.statusCode === 404) {
if (author) {
- await message.reply(
+ await message.util.reply(
'You do not appear to have any pronouns set. Please go to https://pronoundb.org/ and set your pronouns.'
);
} else {
- await message.reply(
+ await message.util.reply(
`${user.tag} does not appear to have any pronouns set. Please tell them to go to https://pronoundb.org/ and set their pronouns.`
);
}
} else throw e;
}
}
- async exec(message: Message, { user }: { user?: User }): Promise<void> {
- const u = user || message.author;
- await this.sendResponse(message, u, u.id === message.author.id);
- }
}
diff --git a/src/commands/moderation/ban.ts b/src/commands/moderation/ban.ts
index 7ce222a..9d7eb4d 100644
--- a/src/commands/moderation/ban.ts
+++ b/src/commands/moderation/ban.ts
@@ -1,4 +1,5 @@
import { Argument } from 'discord-akairo';
+import { ApplicationCommandOptionType } from 'discord-api-types';
import { CommandInteraction, Message, User } from 'discord.js';
import moment from 'moment';
import { BushCommand } from '../../lib/extensions/BushCommand';
@@ -52,19 +53,19 @@ export default class BanCommand extends BushCommand {
},
slashOptions: [
{
- type: 'USER',
+ type: ApplicationCommandOptionType.USER,
name: 'user',
description: 'Who would you like to ban?',
required: true
},
{
- type: 'STRING',
+ type: ApplicationCommandOptionType.STRING,
name: 'reason',
description: 'Why are they getting banned?',
required: false
},
{
- type: 'STRING',
+ type: ApplicationCommandOptionType.STRING,
name: 'time',
description: 'How long should they be banned for?',
required: false
diff --git a/src/commands/moderation/kick.ts b/src/commands/moderation/kick.ts
index eed3038..d7fdfbd 100644
--- a/src/commands/moderation/kick.ts
+++ b/src/commands/moderation/kick.ts
@@ -1,6 +1,7 @@
+import { ApplicationCommandOptionType } from 'discord-api-types';
import { CommandInteraction, GuildMember, Message } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
-import { BushSlashMessage } from '../../lib/extensions/BushInteractionMessage';
+import { BushSlashMessage } from '../../lib/extensions/BushSlashMessage';
import { Guild, ModLog, ModLogType } from '../../lib/models';
export default class KickCommand extends BushCommand {
@@ -32,13 +33,13 @@ export default class KickCommand extends BushCommand {
},
slashOptions: [
{
- type: 'USER',
+ type: ApplicationCommandOptionType.USER,
name: 'user',
description: 'The user to kick',
required: true
},
{
- type: 'STRING',
+ type: ApplicationCommandOptionType.STRING,
name: 'reason',
description: 'The reason to show in modlogs and audit log',
required: false
diff --git a/src/commands/moderation/mute.ts b/src/commands/moderation/mute.ts
index 9b6ad70..eeb2d04 100644
--- a/src/commands/moderation/mute.ts
+++ b/src/commands/moderation/mute.ts
@@ -1,4 +1,5 @@
import { Argument } from 'discord-akairo';
+import { ApplicationCommandOptionType } from 'discord-api-types';
import { CommandInteraction, Message, User } from 'discord.js';
import moment from 'moment';
import { BushCommand } from '../../lib/extensions/BushCommand';
@@ -43,19 +44,19 @@ export default class MuteCommand extends BushCommand {
},
slashOptions: [
{
- type: 'USER',
+ type: ApplicationCommandOptionType.USER,
name: 'user',
description: 'The user to mute.',
required: true
},
{
- type: 'STRING',
+ type: ApplicationCommandOptionType.STRING,
name: 'reason',
description: 'Why the user is getting muted.',
required: false
},
{
- type: 'STRING',
+ type: ApplicationCommandOptionType.STRING,
name: 'time',
description: 'How long the user should be muted for.',
required: false
diff --git a/src/commands/moderation/role.ts b/src/commands/moderation/role.ts
index f0918f0..4eb745d 100644
--- a/src/commands/moderation/role.ts
+++ b/src/commands/moderation/role.ts
@@ -1,4 +1,5 @@
/* eslint-disable @typescript-eslint/no-empty-function */
+import { ApplicationCommandOptionType } from 'discord-api-types';
import { GuildMember, Message, Role } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
import AllowedMentions from '../../lib/utils/AllowedMentions';
@@ -57,13 +58,13 @@ export default class RoleCommand extends BushCommand {
],
slashOptions: [
{
- type: 'USER',
+ type: ApplicationCommandOptionType.USER,
name: 'user',
description: 'The user to add/remove the role on',
required: true
},
{
- type: 'ROLE',
+ type: ApplicationCommandOptionType.ROLE,
name: 'role',
description: 'The role to add/remove',
required: true
diff --git a/src/commands/moulberry-bush/capePerms.ts b/src/commands/moulberry-bush/capePerms.ts
index d1850c8..49e591a 100644
--- a/src/commands/moulberry-bush/capePerms.ts
+++ b/src/commands/moulberry-bush/capePerms.ts
@@ -1,4 +1,5 @@
import { Constants } from 'discord-akairo';
+import { ApplicationCommandOptionType } from 'discord-api-types';
import { MessageEmbed } from 'discord.js';
import got from 'got';
import { BushCommand } from '../../lib/extensions/BushCommand';
@@ -61,7 +62,7 @@ export default class CapePermissionsCommand extends BushCommand {
{
name: 'ign',
description: 'The ign of the player you would like to view the capes permissions of.',
- type: 'STRING',
+ type: ApplicationCommandOptionType.STRING,
required: true
}
]
diff --git a/src/commands/moulberry-bush/level.ts b/src/commands/moulberry-bush/level.ts
index 41541e0..ea51f94 100644
--- a/src/commands/moulberry-bush/level.ts
+++ b/src/commands/moulberry-bush/level.ts
@@ -1,6 +1,7 @@
+import { ApplicationCommandOptionType } from 'discord-api-types';
import { Message, User } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
-import { BushSlashMessage } from '../../lib/extensions/BushInteractionMessage';
+import { BushSlashMessage } from '../../lib/extensions/BushSlashMessage';
import { Level } from '../../lib/models';
/*
import canvas from 'canvas';
@@ -33,7 +34,7 @@ export default class LevelCommand extends BushCommand {
],
slashOptions: [
{
- type: 'USER',
+ type: ApplicationCommandOptionType.USER,
name: 'user',
description: 'The user to get the level of',
required: false
diff --git a/src/commands/moulberry-bush/rule.ts b/src/commands/moulberry-bush/rule.ts
index 3cd9ec6..8aec247 100644
--- a/src/commands/moulberry-bush/rule.ts
+++ b/src/commands/moulberry-bush/rule.ts
@@ -1,4 +1,5 @@
import { Argument, Constants } from 'discord-akairo';
+import { ApplicationCommandOptionType } from 'discord-api-types';
import { MessageEmbed, User } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
import { BushMessage } from '../../lib/extensions/BushMessage';
@@ -94,13 +95,13 @@ export default class RuleCommand extends BushCommand {
{
name: 'rule',
description: 'The rule you would you like to have cited',
- type: 'INTEGER',
+ type: ApplicationCommandOptionType.INTEGER,
required: false
},
{
name: 'user',
description: 'The user you would like to mention.',
- type: 'USER',
+ type: ApplicationCommandOptionType.USER,
required: false
}
],
diff --git a/src/inhibitors/blacklist/guildBlacklist.ts b/src/inhibitors/blacklist/guildBlacklist.ts
index 93d8aee..4c541e8 100644
--- a/src/inhibitors/blacklist/guildBlacklist.ts
+++ b/src/inhibitors/blacklist/guildBlacklist.ts
@@ -1,6 +1,6 @@
import { BushInhibitor } from '../../lib/extensions/BushInhibitor';
-import { BushSlashMessage } from '../../lib/extensions/BushInteractionMessage';
import { BushMessage } from '../../lib/extensions/BushMessage';
+import { BushSlashMessage } from '../../lib/extensions/BushSlashMessage';
export default class GuildBlacklistInhibitor extends BushInhibitor {
constructor() {
diff --git a/src/inhibitors/blacklist/userBlacklist.ts b/src/inhibitors/blacklist/userBlacklist.ts
index bbced28..73ad846 100644
--- a/src/inhibitors/blacklist/userBlacklist.ts
+++ b/src/inhibitors/blacklist/userBlacklist.ts
@@ -1,6 +1,6 @@
import { BushInhibitor } from '../../lib/extensions/BushInhibitor';
-import { BushSlashMessage } from '../../lib/extensions/BushInteractionMessage';
import { BushMessage } from '../../lib/extensions/BushMessage';
+import { BushSlashMessage } from '../../lib/extensions/BushSlashMessage';
export default class UserBlacklistInhibitor extends BushInhibitor {
constructor() {
diff --git a/src/inhibitors/commands/disabledCommand.ts b/src/inhibitors/commands/disabledCommand.ts
index 8538858..caf7bf7 100644
--- a/src/inhibitors/commands/disabledCommand.ts
+++ b/src/inhibitors/commands/disabledCommand.ts
@@ -1,7 +1,7 @@
import { BushCommand } from '../../lib/extensions/BushCommand';
import { BushInhibitor } from '../../lib/extensions/BushInhibitor';
-import { BushSlashMessage } from '../../lib/extensions/BushInteractionMessage';
import { BushMessage } from '../../lib/extensions/BushMessage';
+import { BushSlashMessage } from '../../lib/extensions/BushSlashMessage';
export default class DisabledCommandInhibitor extends BushInhibitor {
constructor() {
diff --git a/src/inhibitors/noCache.ts b/src/inhibitors/noCache.ts
index 61f0b3e..a8f52d7 100644
--- a/src/inhibitors/noCache.ts
+++ b/src/inhibitors/noCache.ts
@@ -1,6 +1,6 @@
import { BushInhibitor } from '../lib/extensions/BushInhibitor';
-import { BushSlashMessage } from '../lib/extensions/BushInteractionMessage';
import { BushMessage } from '../lib/extensions/BushMessage';
+import { BushSlashMessage } from '../lib/extensions/BushSlashMessage';
export default class noCacheInhibitor extends BushInhibitor {
constructor() {
diff --git a/src/lang/en-us.json b/src/lang/en-us.json
new file mode 100644
index 0000000..4900abb
--- /dev/null
+++ b/src/lang/en-us.json
@@ -0,0 +1,14 @@
+{
+ "commands": {
+ "config": {
+ "muteRole": {
+ "description": ""
+ }
+ },
+ "dev": {},
+ "info": {},
+ "moderation": {},
+ "moulberry-bush": {},
+ "utilities": {}
+ }
+}
diff --git a/src/lib/extensions/BushCommand.ts b/src/lib/extensions/BushCommand.ts
index b62d26e..f22a628 100644
--- a/src/lib/extensions/BushCommand.ts
+++ b/src/lib/extensions/BushCommand.ts
@@ -4,8 +4,8 @@ import { ArgumentGenerator, ArgumentOptions, ArgumentPromptOptions, Command, Com
import { Snowflake } from 'discord.js';
import { BushClient } from './BushClient';
import { BushCommandHandler } from './BushCommandHandler';
-import { BushSlashMessage } from './BushInteractionMessage';
import { BushMessage } from './BushMessage';
+import { BushSlashMessage } from './BushSlashMessage';
export interface BushArgumentOptions extends ArgumentOptions {
id: string;
diff --git a/src/lib/extensions/BushGuild.ts b/src/lib/extensions/BushGuild.ts
new file mode 100644
index 0000000..470e93a
--- /dev/null
+++ b/src/lib/extensions/BushGuild.ts
@@ -0,0 +1,20 @@
+import { Guild } from 'discord.js';
+import { Guild as GuildDB, GuildModel } from '../models/Guild';
+import { BushClient } from './BushClient';
+
+export class BushGuild extends Guild {
+ public declare client: BushClient;
+ public constructor(client: BushClient, data: unknown) {
+ super(client, data);
+ }
+
+ public async getSetting(setting: keyof GuildModel) {
+ return ((await GuildDB.findByPk(this.id)) ?? GuildDB.build({ id: this.id })).get(setting);
+ }
+
+ public async setSetting<K extends keyof GuildModel>(setting: K, value: GuildDB[K]) {
+ const row = (await GuildDB.findByPk(this.id)) ?? GuildDB.build({ id: this.id });
+ row[setting] = value;
+ return await row.save();
+ }
+}
diff --git a/src/lib/extensions/BushGuildMember.ts b/src/lib/extensions/BushGuildMember.ts
new file mode 100644
index 0000000..d193f9e
--- /dev/null
+++ b/src/lib/extensions/BushGuildMember.ts
@@ -0,0 +1,13 @@
+import { GuildMember } from 'discord.js';
+import { BushClient } from './BushClient';
+import { BushGuild } from './BushGuild';
+import { BushUser } from './BushUser';
+
+export class BushGuildMember extends GuildMember {
+ public declare client: BushClient;
+ public declare guild: BushGuild;
+ public declare BushUser: BushUser;
+ public constructor(client: BushClient, data: unknown, guild: BushGuild) {
+ super(client, data, guild);
+ }
+}
diff --git a/src/lib/extensions/BushInhibitor.ts b/src/lib/extensions/BushInhibitor.ts
index 8a31abf..602ff65 100644
--- a/src/lib/extensions/BushInhibitor.ts
+++ b/src/lib/extensions/BushInhibitor.ts
@@ -2,8 +2,8 @@
import { Inhibitor } from 'discord-akairo';
import { BushClient } from './BushClient';
import { BushCommand } from './BushCommand';
-import { BushSlashMessage } from './BushInteractionMessage';
import { BushMessage } from './BushMessage';
+import { BushSlashMessage } from './BushSlashMessage';
export class BushInhibitor extends Inhibitor {
public declare client: BushClient;
diff --git a/src/lib/extensions/BushMessage.ts b/src/lib/extensions/BushMessage.ts
index afa6bde..7dbeeb2 100644
--- a/src/lib/extensions/BushMessage.ts
+++ b/src/lib/extensions/BushMessage.ts
@@ -1,11 +1,17 @@
import { DMChannel, Message, NewsChannel, TextChannel } from 'discord.js';
import { BushClient } from './BushClient';
import { BushCommandUtil } from './BushCommandUtil';
+import { BushGuild } from './BushGuild';
+import { BushGuildMember } from './BushGuildMember';
+import { BushUser } from './BushUser';
export class BushMessage extends Message {
- declare client: BushClient;
- declare util: BushCommandUtil;
- constructor(client: BushClient, data: unknown, channel: TextChannel | DMChannel | NewsChannel) {
+ public declare client: BushClient;
+ public declare util: BushCommandUtil;
+ public declare guild: BushGuild;
+ public declare member: BushGuildMember;
+ public declare author: BushUser;
+ public constructor(client: BushClient, data: unknown, channel: TextChannel | DMChannel | NewsChannel) {
super(client, data, channel);
this.client = client;
this.channel = channel;
diff --git a/src/lib/extensions/BushInteractionMessage.ts b/src/lib/extensions/BushSlashMessage.ts
index 62d2519..33ca11f 100644
--- a/src/lib/extensions/BushInteractionMessage.ts
+++ b/src/lib/extensions/BushSlashMessage.ts
@@ -2,10 +2,14 @@ import { AkairoMessage } from 'discord-akairo';
import { CommandInteraction } from 'discord.js';
import { BushClient } from './BushClient';
import { BushCommandUtil } from './BushCommandUtil';
+import { BushGuild } from './BushGuild';
+import { BushUser } from './BushUser';
export class BushSlashMessage extends AkairoMessage {
public declare client: BushClient;
public declare util: BushCommandUtil;
+ public declare guild: BushGuild;
+ public declare author: BushUser;
public constructor(
client: BushClient,
interaction: CommandInteraction,
diff --git a/src/lib/extensions/BushUser.ts b/src/lib/extensions/BushUser.ts
new file mode 100644
index 0000000..dd07b7d
--- /dev/null
+++ b/src/lib/extensions/BushUser.ts
@@ -0,0 +1,17 @@
+import { User } from 'discord.js';
+import { BushClient } from './BushClient';
+
+export class BushUser extends User {
+ public declare client: BushClient;
+ public constructor(client: BushClient, data: unknown) {
+ super(client, data);
+ }
+
+ public isOwner(): boolean {
+ return this.client.isOwner(this);
+ }
+
+ public isSuperUser(): boolean {
+ return this.client.isSuperUser(this);
+ }
+}
diff --git a/src/lib/utils/BushConstants.ts b/src/lib/utils/BushConstants.ts
index 1015229..0e3f6bb 100644
--- a/src/lib/utils/BushConstants.ts
+++ b/src/lib/utils/BushConstants.ts
@@ -1,4 +1,40 @@
export class BushConstants {
+ // Stolen from @Mzato0001 (pr to discord akairo that hasn't been merged yet)
+ public static TimeUnits = {
+ years: {
+ label: '(?:years?|y)',
+ value: 1000 * 60 * 60 * 24 * 365
+ },
+ months: {
+ label: '(?:months?|mon|mo?)',
+ value: 1000 * 60 * 60 * 24 * 30
+ },
+ weeks: {
+ label: '(?:weeks?|w)',
+ value: 1000 * 60 * 60 * 24 * 7
+ },
+ days: {
+ label: '(?:days?|d)',
+ value: 1000 * 60 * 60 * 24
+ },
+ hours: {
+ label: '(?:hours?|hrs?|h)',
+ value: 1000 * 60 * 60
+ },
+ minutes: {
+ label: '(?:minutes?|mins?)',
+ value: 1000 * 60
+ },
+ seconds: {
+ label: '(?:seconds?|secs?|s)',
+ value: 1000
+ },
+ milliseconds: {
+ label: '(?:milliseconds?|msecs?|ms)',
+ value: 1
+ }
+ };
+
/** A bunch of mappings */
public static mappings = {
guilds: {
diff --git a/src/listeners/commands/slashBlocked.ts b/src/listeners/commands/slashBlocked.ts
index e64253a..761bef8 100644
--- a/src/listeners/commands/slashBlocked.ts
+++ b/src/listeners/commands/slashBlocked.ts
@@ -1,6 +1,6 @@
import { BushCommand } from '../../lib/extensions/BushCommand';
-import { BushSlashMessage } from '../../lib/extensions/BushInteractionMessage';
import { BushListener } from '../../lib/extensions/BushListener';
+import { BushSlashMessage } from '../../lib/extensions/BushSlashMessage';
export default class SlashBlockedListener extends BushListener {
public constructor() {
diff --git a/src/listeners/commands/slashCommandError.ts b/src/listeners/commands/slashCommandError.ts
index 1a5f293..da00eb4 100644
--- a/src/listeners/commands/slashCommandError.ts
+++ b/src/listeners/commands/slashCommandError.ts
@@ -1,8 +1,8 @@
import { stripIndents } from 'common-tags';
import { MessageEmbed } from 'discord.js';
import { BushCommand } from '../../lib/extensions/BushCommand';
-import { BushSlashMessage } from '../../lib/extensions/BushInteractionMessage';
import { BushListener } from '../../lib/extensions/BushListener';
+import { BushSlashMessage } from '../../lib/extensions/BushSlashMessage';
export default class SlashCommandErrorListener extends BushListener {
constructor() {
diff --git a/src/listeners/commands/slashStarted.ts b/src/listeners/commands/slashStarted.ts
index c6b966a..534d89d 100644
--- a/src/listeners/commands/slashStarted.ts
+++ b/src/listeners/commands/slashStarted.ts
@@ -1,6 +1,6 @@
import { BushCommand } from '../../lib/extensions/BushCommand';
-import { BushSlashMessage } from '../../lib/extensions/BushInteractionMessage';
import { BushListener } from '../../lib/extensions/BushListener';
+import { BushSlashMessage } from '../../lib/extensions/BushSlashMessage';
export default class SlashStartedListener extends BushListener {
constructor() {