aboutsummaryrefslogtreecommitdiff
path: root/src/commands
diff options
context:
space:
mode:
Diffstat (limited to 'src/commands')
-rw-r--r--src/commands/config/muteRole.ts2
-rw-r--r--src/commands/config/prefix.ts2
-rw-r--r--src/commands/config/welcomeChannel.ts2
-rw-r--r--src/commands/dev/reload.ts2
-rw-r--r--src/commands/dev/setLevel.ts4
-rw-r--r--src/commands/dev/testDuration.ts2
-rw-r--r--src/commands/info/botInfo.ts38
-rw-r--r--src/commands/info/help.ts2
-rw-r--r--src/commands/info/ping.ts8
-rw-r--r--src/commands/info/pronouns.ts2
-rw-r--r--src/commands/moderation/_unmute.ts0
-rw-r--r--src/commands/moderation/ban.ts204
-rw-r--r--src/commands/moderation/kick.ts29
-rw-r--r--src/commands/moderation/mute.ts6
-rw-r--r--src/commands/moderation/role.ts12
-rw-r--r--src/commands/moderation/unban.ts85
-rw-r--r--src/commands/moderation/unmute.ts109
-rw-r--r--src/commands/moderation/warn.ts6
-rw-r--r--src/commands/moulberry-bush/level.ts2
-rw-r--r--src/commands/utilities/whoHasRole.ts (renamed from src/commands/moderation/_unban.ts)0
20 files changed, 350 insertions, 167 deletions
diff --git a/src/commands/config/muteRole.ts b/src/commands/config/muteRole.ts
index 6fda0b8..9a172be 100644
--- a/src/commands/config/muteRole.ts
+++ b/src/commands/config/muteRole.ts
@@ -27,9 +27,9 @@ export default class MuteRoleCommand extends BushCommand {
slash: true,
slashOptions: [
{
- type: 'ROLE',
name: 'role',
description: "What would you like to set the server's mute role to?",
+ type: 'ROLE',
required: true
}
]
diff --git a/src/commands/config/prefix.ts b/src/commands/config/prefix.ts
index c7a1a9f..dc51671 100644
--- a/src/commands/config/prefix.ts
+++ b/src/commands/config/prefix.ts
@@ -26,9 +26,9 @@ export default class PrefixCommand extends BushCommand {
slash: true,
slashOptions: [
{
- type: 'STRING',
name: 'prefix',
description: 'What would you like the new prefix to be?',
+ type: 'STRING',
required: false
}
]
diff --git a/src/commands/config/welcomeChannel.ts b/src/commands/config/welcomeChannel.ts
index f15e07d..71d59f8 100644
--- a/src/commands/config/welcomeChannel.ts
+++ b/src/commands/config/welcomeChannel.ts
@@ -27,9 +27,9 @@ export default class WelcomeChannelCommand extends BushCommand {
slash: true,
slashOptions: [
{
- type: 'CHANNEL',
name: 'channel',
description: 'What channel would you like me to send welcome messages in?',
+ type: 'CHANNEL',
required: false
}
]
diff --git a/src/commands/dev/reload.ts b/src/commands/dev/reload.ts
index c6a2140..928632c 100644
--- a/src/commands/dev/reload.ts
+++ b/src/commands/dev/reload.ts
@@ -21,9 +21,9 @@ export default class ReloadCommand extends BushCommand {
typing: true,
slashOptions: [
{
- type: 'BOOLEAN',
name: 'fast',
description: 'Whether to use esbuild for fast compiling or not',
+ type: 'BOOLEAN',
required: false
}
],
diff --git a/src/commands/dev/setLevel.ts b/src/commands/dev/setLevel.ts
index 9c7daeb..db0cfab 100644
--- a/src/commands/dev/setLevel.ts
+++ b/src/commands/dev/setLevel.ts
@@ -32,15 +32,15 @@ export default class SetLevelCommand extends BushCommand {
ownerOnly: true,
slashOptions: [
{
- type: 'USER',
name: 'user',
description: 'The user to change the level of',
+ type: 'USER',
required: true
},
{
- type: 'INTEGER',
name: 'level',
description: 'The level to set the user to',
+ type: 'INTEGER',
required: true
}
],
diff --git a/src/commands/dev/testDuration.ts b/src/commands/dev/testDuration.ts
index 719292e..2d636d2 100644
--- a/src/commands/dev/testDuration.ts
+++ b/src/commands/dev/testDuration.ts
@@ -27,9 +27,9 @@ export default class TestDurationCommand extends BushCommand {
slash: true,
slashOptions: [
{
- type: 'STRING',
name: 'reason',
description: 'Enter text and a duration here.',
+ type: 'STRING',
required: false
}
],
diff --git a/src/commands/info/botInfo.ts b/src/commands/info/botInfo.ts
index d9961af..d5941b2 100644
--- a/src/commands/info/botInfo.ts
+++ b/src/commands/info/botInfo.ts
@@ -1,5 +1,5 @@
import { BushCommand, BushMessage, BushSlashMessage } from '@lib';
-import { MessageEmbed } from 'discord.js';
+import { MessageEmbed, version as discordJSVersion } from 'discord.js';
export default class BotInfoCommand extends BushCommand {
public constructor() {
@@ -18,32 +18,24 @@ export default class BotInfoCommand extends BushCommand {
}
public async exec(message: BushMessage | BushSlashMessage): Promise<void> {
- const owners = (await this.client.util.mapIDs(this.client.ownerID)).map((u) => u.tag).join('\n');
+ const developers = (await this.client.util.mapIDs(this.client.config.owners)).map((u) => u?.tag).join('\n');
const currentCommit = (await this.client.util.shell('git rev-parse HEAD')).stdout.replace('\n', '');
const repoUrl = (await this.client.util.shell('git remote get-url origin')).stdout.replace('\n', '');
const embed = new MessageEmbed()
.setTitle('Bot Info:')
- .addFields([
- {
- name: 'Owners',
- value: owners,
- inline: true
- },
- {
- name: 'Uptime',
- value: this.client.util.capitalize(this.client.util.humanizeDuration(this.client.uptime))
- },
- {
- name: 'User count',
- value: this.client.users.cache.size.toLocaleString(),
- inline: true
- },
- {
- name: 'Current commit',
- value: `[${currentCommit.substring(0, 7)}](${repoUrl}/commit/${currentCommit})`
- }
- ])
- .setTimestamp();
+ .addField('**Uptime**', this.client.util.humanizeDuration(this.client.uptime), true)
+ .addField('**Servers**', this.client.guilds.cache.size.toLocaleString(), true)
+ .addField('**Users**', this.client.users.cache.size.toLocaleString(), true)
+ .addField('**Discord.js Version**', discordJSVersion, true)
+ .addField('**Node.js Version**', process.version.slice(1), true)
+ .addField('**Commands**', this.client.commandHandler.modules.size.toLocaleString(), true)
+ .addField('**Listeners**', this.client.listenerHandler.modules.size.toLocaleString(), true)
+ .addField('**Inhibitors**', this.client.inhibitorHandler.modules.size.toLocaleString(), true)
+ .addField('**Tasks**', this.client.taskHandler.modules.size.toLocaleString(), true)
+ .addField('**Current Commit**', `[${currentCommit.substring(0, 7)}](${repoUrl}/commit/${currentCommit})`, true)
+ .addField('**Developers**', developers, true)
+ .setTimestamp()
+ .setColor(this.client.util.colors.default);
await message.util.reply({ embeds: [embed] });
}
}
diff --git a/src/commands/info/help.ts b/src/commands/info/help.ts
index 439f0ef..e061453 100644
--- a/src/commands/info/help.ts
+++ b/src/commands/info/help.ts
@@ -33,9 +33,9 @@ export default class HelpCommand extends BushCommand {
slash: true,
slashOptions: [
{
- type: 'STRING',
name: 'command',
description: 'The command you would like to find information about.',
+ type: 'STRING',
required: false
}
]
diff --git a/src/commands/info/ping.ts b/src/commands/info/ping.ts
index 4638aa9..59f475f 100644
--- a/src/commands/info/ping.ts
+++ b/src/commands/info/ping.ts
@@ -20,8 +20,8 @@ export default class PingCommand extends BushCommand {
public async exec(message: BushMessage): Promise<void> {
const sentMessage = (await message.util.send('Pong!')) as Message;
const timestamp: number = message.editedTimestamp ? message.editedTimestamp : message.createdTimestamp;
- const botLatency = `\`\`\`\n ${Math.floor(sentMessage.createdTimestamp - timestamp)}ms \`\`\``;
- const apiLatency = `\`\`\`\n ${Math.round(message.client.ws.ping)}ms \`\`\``;
+ const botLatency = `${'```'}\n ${Math.round(sentMessage.createdTimestamp - timestamp)}ms ${'```'}`;
+ const apiLatency = `${'```'}\n ${Math.round(message.client.ws.ping)}ms ${'```'}`;
const embed = new MessageEmbed()
.setTitle('Pong! 🏓')
.addField('Bot Latency', botLatency, true)
@@ -39,8 +39,8 @@ export default class PingCommand extends BushCommand {
const timestamp1 = message.interaction.createdTimestamp;
await message.interaction.reply('Pong!');
const timestamp2 = await message.interaction.fetchReply().then((m) => (m as Message).createdTimestamp);
- const botLatency = `\`\`\`\n ${Math.floor(timestamp2 - timestamp1)}ms \`\`\``;
- const apiLatency = `\`\`\`\n ${Math.round(this.client.ws.ping)}ms \`\`\``;
+ const botLatency = `${'```'}\n ${Math.round(timestamp2 - timestamp1)}ms ${'```'}`;
+ const apiLatency = `${'```'}\n ${Math.round(this.client.ws.ping)}ms ${'```'}`;
const embed = new MessageEmbed()
.setTitle('Pong! 🏓')
.addField('Bot Latency', botLatency, true)
diff --git a/src/commands/info/pronouns.ts b/src/commands/info/pronouns.ts
index 60701d1..0a5c0bc 100644
--- a/src/commands/info/pronouns.ts
+++ b/src/commands/info/pronouns.ts
@@ -51,9 +51,9 @@ export default class PronounsCommand extends BushCommand {
clientPermissions: ['SEND_MESSAGES'],
slashOptions: [
{
- type: 'USER',
name: 'user',
description: 'The user to get pronouns for',
+ type: 'USER',
required: false
}
],
diff --git a/src/commands/moderation/_unmute.ts b/src/commands/moderation/_unmute.ts
deleted file mode 100644
index e69de29..0000000
--- a/src/commands/moderation/_unmute.ts
+++ /dev/null
diff --git a/src/commands/moderation/ban.ts b/src/commands/moderation/ban.ts
index be7a51f..d713a15 100644
--- a/src/commands/moderation/ban.ts
+++ b/src/commands/moderation/ban.ts
@@ -1,4 +1,5 @@
-import { BushCommand, BushMessage, BushSlashMessage } from '@lib';
+import { BushCommand, BushGuildMember, BushMessage, BushSlashMessage } from '@lib';
+import { Argument } from 'discord-akairo';
import { User } from 'discord.js';
export default class BanCommand extends BushCommand {
@@ -6,6 +7,11 @@ export default class BanCommand extends BushCommand {
super('ban', {
aliases: ['ban'],
category: 'moderation',
+ description: {
+ content: 'Ban a member from the server.',
+ usage: 'ban <member> <reason> [--delete ]',
+ examples: ['ban 322862723090219008 1 day commands in #general --delete 7']
+ },
args: [
{
id: 'user',
@@ -20,137 +26,109 @@ export default class BanCommand extends BushCommand {
type: 'contentWithDuration',
match: 'restContent',
prompt: {
- start: 'Why would you like to ban this user?',
- retry: '{error} Choose a ban reason.',
+ start: 'Why should this user be banned and for how long?',
+ retry: '{error} Choose a valid ban reason and duration.',
optional: true
}
+ },
+ {
+ id: 'days',
+ flag: '--days',
+ match: 'option',
+ type: Argument.range('integer', 0, 7, true),
+ default: 0
}
],
- clientPermissions: ['BAN_MEMBERS'],
- userPermissions: ['BAN_MEMBERS'],
- description: {
- content: 'Ban a member from the server.',
- usage: 'ban <member> <reason> [--time]',
- examples: ['ban @user bad --time 69d']
- },
+ slash: true,
slashOptions: [
{
- type: 'USER',
name: 'user',
- description: 'Who would you like to ban?',
+ description: 'What user would you like to ban?',
+ type: 'USER',
required: true
},
{
- type: 'STRING',
name: 'reason',
- description: 'Why are they getting banned?',
+ description: 'Why should this user be banned and for how long?',
+ type: 'STRING',
required: false
+ },
+ {
+ name: 'days',
+ description: "How many days of the user's messages would you like to delete?",
+ type: 'INTEGER',
+ required: false,
+ choices: [
+ { name: '0', value: 0 },
+ { name: '1', value: 1 },
+ { name: '2', value: 2 },
+ { name: '3', value: 3 },
+ { name: '4', value: 4 },
+ { name: '5', value: 5 },
+ { name: '6', value: 6 },
+ { name: '7', value: 7 }
+ ]
}
],
- slash: true
+ channel: 'guild',
+ clientPermissions: ['BAN_MEMBERS'],
+ userPermissions: ['BAN_MEMBERS']
});
}
- // async *genResponses(
- // message: Message | CommandInteraction,
- // user: User,
- // reason?: string,
- // time?: number
- // ): AsyncIterable<string> {
- // const duration = moment.duration();
- // let modLogEntry: ModLog;
- // let banEntry: Ban;
- // // const translatedTime: string[] = [];
- // // Create guild entry so postgres doesn't get mad when I try and add a modlog entry
- // await Guild.findOrCreate({
- // where: {
- // id: message.guild.id
- // },
- // defaults: {
- // id: message.guild.id
- // }
- // });
- // try {
- // if (time) {
- // duration.add(time);
- // /* const parsed = [...time.matchAll(durationRegex)];
- // if (parsed.length < 1) {
- // yield `${this.client.util.emojis.error} Invalid time.`;
- // return;
- // }
- // for (const part of parsed) {
- // const translated = Object.keys(durationAliases).find((k) => durationAliases[k].includes(part[2]));
- // translatedTime.push(part[1] + ' ' + translated);
- // duration.add(Number(part[1]), translated as 'weeks' | 'days' | 'hours' | 'months' | 'minutes');
- // } */
- // modLogEntry = ModLog.build({
- // user: user.id,
- // guild: message.guild.id,
- // reason,
- // type: ModLogType.TEMP_BAN,
- // duration: duration.asMilliseconds(),
- // moderator: message instanceof CommandInteraction ? message.user.id : message.author.id
- // });
- // banEntry = Ban.build({
- // user: user.id,
- // guild: message.guild.id,
- // reason,
- // expires: new Date(new Date().getTime() + duration.asMilliseconds()),
- // modlog: modLogEntry.id
- // });
- // } else {
- // modLogEntry = ModLog.build({
- // user: user.id,
- // guild: message.guild.id,
- // reason,
- // type: ModLogType.BAN,
- // moderator: message instanceof CommandInteraction ? message.user.id : message.author.id
- // });
- // banEntry = Ban.build({
- // user: user.id,
- // guild: message.guild.id,
- // reason,
- // modlog: modLogEntry.id
- // });
- // }
- // await modLogEntry.save();
- // await banEntry.save();
-
- // try {
- // await user.send(
- // `You were banned in ${message.guild.name} ${duration ? duration.humanize() : 'permanently'} with reason \`${
- // reason || 'No reason given'
- // }\``
- // );
- // } catch {
- // yield `${this.client.util.emojis.warn} Unable to dm user`;
- // }
- // await message.guild.members.ban(user, {
- // reason: `Banned by ${message instanceof CommandInteraction ? message.user.tag : message.author.tag} with ${
- // reason ? `reason ${reason}` : 'no reason'
- // }`
- // });
- // yield `${this.client.util.emojis.success} Banned <@!${user.id}> ${
- // duration ? duration.humanize() : 'permanently'
- // } with reason \`${reason || 'No reason given'}\``;
- // } catch {
- // yield `${this.client.util.emojis.error} Error banning :/`;
- // await banEntry.destroy();
- // await modLogEntry.destroy();
- // return;
- // }
- // }
async exec(
message: BushMessage | BushSlashMessage,
- { user, reason, time }: { user: User; reason?: string; time?: number | string }
+ { user, reason, days }: { user: User; reason?: { duration: number; contentWithoutTime: string }; days?: number }
): Promise<unknown> {
- return message.util.reply(`${this.client.util.emojis.error} This command is not finished.`);
+ const member = message.guild.members.cache.get(user.id) as BushGuildMember;
+ const canModerateResponse = this.client.util.moderationPermissionCheck(message.member, member, 'ban');
+
+ if (canModerateResponse !== true) {
+ return message.util.reply(canModerateResponse);
+ }
+
+ if (!Number.isInteger(days) || days < 0 || days > 7) {
+ return message.util.reply(`${this.client.util.emojis.error} The delete days must be an integer between 0 and 7.`);
+ }
+
+ let time: number;
+ if (reason) {
+ time =
+ typeof reason === 'string'
+ ? await Argument.cast('duration', this.client.commandHandler.resolver, message as BushMessage, reason)
+ : reason.duration;
+ }
+ const parsedReason = reason.contentWithoutTime;
+
+ const response = await member.bushBan({
+ reason: parsedReason,
+ moderator: message.author,
+ duration: time,
+ deleteDays: days ?? 0
+ });
- // if (typeof time === 'string') {
- // time = (await Argument.cast('duration', this.client.commandHandler.resolver, message, time)) as number;
- // //// time = this.client.commandHandler.resolver.type('duration')
- // }
- // for await (const response of this.genResponses(message, user, reason, time)) {
- // await message.util.send(response);
- // }
+ switch (response) {
+ case 'missing permissions':
+ return message.util.reply(
+ `${this.client.util.emojis.error} Could not ban **${member.user.tag}** because I do not have permissions`
+ );
+ case 'error banning':
+ return message.util.reply(
+ `${this.client.util.emojis.error} An error occurred while trying to ban **${member.user.tag}**.`
+ );
+ case 'error creating ban entry':
+ return message.util.reply(
+ `${this.client.util.emojis.error} While banning **${member.user.tag}**, there was an error creating a ban entry, please report this to my developers.`
+ );
+ case 'error creating modlog entry':
+ return message.util.reply(
+ `${this.client.util.emojis.error} While banning **${member.user.tag}**, there was an error creating a modlog entry, please report this to my developers.`
+ );
+ case 'failed to dm':
+ return message.util.reply(
+ `${this.client.util.emojis.warn} Banned **${member.user.tag}** however I could not send them a dm.`
+ );
+ case 'success':
+ return message.util.reply(`${this.client.util.emojis.success} Successfully banned **${member.user.tag}**.`);
+ }
}
}
diff --git a/src/commands/moderation/kick.ts b/src/commands/moderation/kick.ts
index f960488..d70bbfb 100644
--- a/src/commands/moderation/kick.ts
+++ b/src/commands/moderation/kick.ts
@@ -22,7 +22,7 @@ export default class KickCommand extends BushCommand {
{
id: 'reason',
type: 'string',
- match: 'restContent',
+ match: 'rest',
prompt: {
start: 'Why should this user be kicked?',
retry: '{error} Choose a valid kick reason.',
@@ -33,15 +33,15 @@ export default class KickCommand extends BushCommand {
slash: true,
slashOptions: [
{
- type: 'USER',
name: 'user',
description: 'What user would you like to kick?',
+ type: 'USER',
required: true
},
{
- type: 'STRING',
name: 'reason',
description: 'Why should this user be kicked?',
+ type: 'STRING',
required: false
}
],
@@ -55,7 +55,7 @@ export default class KickCommand extends BushCommand {
const canModerateResponse = this.client.util.moderationPermissionCheck(message.member, member, 'kick');
// const victimBoldTag = `**${member.user.tag}**`;
- if (typeof canModerateResponse !== 'boolean') {
+ if (canModerateResponse !== true) {
return message.util.reply(canModerateResponse);
}
@@ -63,5 +63,26 @@ export default class KickCommand extends BushCommand {
reason,
moderator: message.author
});
+
+ switch (response) {
+ case 'missing permissions':
+ return message.util.reply(
+ `${this.client.util.emojis.error} Could not kick **${member.user.tag}** because I am missing the \`Kick Members\` permission.`
+ );
+ case 'error kicking':
+ return message.util.reply(
+ `${this.client.util.emojis.error} An error occurred while trying to kick **${member.user.tag}**.`
+ );
+ case 'error creating modlog entry':
+ return message.util.reply(
+ `${this.client.util.emojis.error} While muting **${member.user.tag}**, there was an error creating a modlog entry, please report this to my developers.`
+ );
+ case 'failed to dm':
+ return message.util.reply(
+ `${this.client.util.emojis.warn} Kicked **${member.user.tag}** however I could not send them a dm.`
+ );
+ case 'success':
+ return message.util.reply(`${this.client.util.emojis.success} Successfully kicked **${member.user.tag}**.`);
+ }
}
}
diff --git a/src/commands/moderation/mute.ts b/src/commands/moderation/mute.ts
index 26ccb21..0eae547 100644
--- a/src/commands/moderation/mute.ts
+++ b/src/commands/moderation/mute.ts
@@ -34,15 +34,15 @@ export default class MuteCommand extends BushCommand {
slash: true,
slashOptions: [
{
- type: 'USER',
name: 'user',
description: 'What user would you like to mute?',
+ type: 'USER',
required: true
},
{
- type: 'STRING',
name: 'reason',
description: 'Why should this user be muted and for how long?',
+ type: 'STRING',
required: false
}
],
@@ -60,7 +60,7 @@ export default class MuteCommand extends BushCommand {
const canModerateResponse = this.client.util.moderationPermissionCheck(message.member, member, 'mute');
const victimBoldTag = `**${member.user.tag}**`;
- if (typeof canModerateResponse !== 'boolean') {
+ if (canModerateResponse !== true) {
return message.util.reply(canModerateResponse);
}
diff --git a/src/commands/moderation/role.ts b/src/commands/moderation/role.ts
index 33f474e..29913d5 100644
--- a/src/commands/moderation/role.ts
+++ b/src/commands/moderation/role.ts
@@ -4,7 +4,7 @@ import { AllowedMentions, BushCommand, BushGuildMember, BushMessage, BushRole, B
export default class RoleCommand extends BushCommand {
public constructor() {
super('role', {
- aliases: ['role', 'addrole', 'removerole'],
+ aliases: ['role'],
category: 'moderation',
description: {
content: "Manages users' roles.",
@@ -69,7 +69,6 @@ export default class RoleCommand extends BushCommand {
start: `What user do you want to ${action} the role ${action2}?`,
retry: `{error} Choose a valid user to ${action} the role ${action2}.`
}
- //unordered: true
};
const role = yield {
id: 'role',
@@ -87,7 +86,7 @@ export default class RoleCommand extends BushCommand {
message: BushMessage | BushSlashMessage,
{ action, user, role }: { action: 'add' | 'remove'; user: BushGuildMember; role: BushRole }
): Promise<unknown> {
- if (!message.member.permissions.has('MANAGE_ROLES') && !this.client.ownerID.includes(message.author.id)) {
+ if (!message.member.permissions.has('MANAGE_ROLES') && !message.author.isOwner()) {
const mappings = this.client.consts.mappings;
let mappedRole: { name: string; id: string };
for (let i = 0; i < mappings.roleMap.length; i++) {
@@ -112,8 +111,7 @@ export default class RoleCommand extends BushCommand {
allowedMentions: AllowedMentions.none()
});
}
- }
- if (!this.client.ownerID.includes(message.author.id)) {
+ } else if (!message.author.isOwner()) {
if (role.comparePositionTo(message.member.roles.highest) >= 0) {
return await message.util.reply({
content: `${this.client.util.emojis.error} <@&${role.id}> is higher or equal to your highest role.`,
@@ -127,7 +125,7 @@ export default class RoleCommand extends BushCommand {
});
}
if (role.managed) {
- await await message.util.reply({
+ return await message.util.reply({
content: `${this.client.util.emojis.error} <@&${role.id}> is managed by an integration and cannot be managed.`,
allowedMentions: AllowedMentions.none()
});
@@ -138,7 +136,7 @@ export default class RoleCommand extends BushCommand {
const success = await user.roles.remove(role.id).catch(() => {});
if (success) {
return await message.util.reply({
- content: `${this.client.util.emojis.success}Successfully removed <@&${role.id}> from <@${user.id}>!`,
+ content: `${this.client.util.emojis.success} Successfully removed <@&${role.id}> from <@${user.id}>!`,
allowedMentions: AllowedMentions.none()
});
} else {
diff --git a/src/commands/moderation/unban.ts b/src/commands/moderation/unban.ts
new file mode 100644
index 0000000..4f52666
--- /dev/null
+++ b/src/commands/moderation/unban.ts
@@ -0,0 +1,85 @@
+import { BushCommand, BushMessage, BushSlashMessage } from '@lib';
+import { User } from 'discord.js';
+
+export default class UnbanCommand extends BushCommand {
+ public constructor() {
+ super('unban', {
+ aliases: ['unban'],
+ category: 'moderation',
+ description: {
+ content: 'Unban a member from the server.',
+ usage: 'unban <member> <reason> [--delete ]',
+ examples: ['unban 322862723090219008 I changed my mind, commands are allowed in #general']
+ },
+ args: [
+ {
+ id: 'user',
+ type: 'user',
+ prompt: {
+ start: 'What user would you like to unban?',
+ retry: '{error} Choose a valid user to unban.'
+ }
+ },
+ {
+ id: 'reason',
+ type: 'string',
+ match: 'restContent',
+ prompt: {
+ start: 'Why should this user be unbanned?',
+ retry: '{error} Choose a valid unban reason.',
+ optional: true
+ }
+ }
+ ],
+ slash: true,
+ slashOptions: [
+ {
+ name: 'user',
+ description: 'What user would you like to unban?',
+ type: 'USER',
+ required: true
+ },
+ {
+ name: 'reason',
+ description: 'Why should this user be unbanned?',
+ type: 'STRING',
+ required: false
+ }
+ ],
+ channel: 'guild',
+ clientPermissions: ['BAN_MEMBERS'],
+ userPermissions: ['BAN_MEMBERS']
+ });
+ }
+ async exec(message: BushMessage | BushSlashMessage, { user, reason }: { user: User; reason?: string }): Promise<unknown> {
+ if (!(user instanceof User)) {
+ user = this.client.util.resolveUser(user, this.client.users.cache);
+ }
+ const response = await message.guild.unban({
+ user,
+ moderator: message.author,
+ reason
+ });
+
+ switch (response) {
+ case 'missing permissions':
+ return message.util.reply(
+ `${this.client.util.emojis.error} Could not unban **${user.tag}** because I do not have permissions`
+ );
+ case 'error unbanning':
+ return message.util.reply(`${this.client.util.emojis.error} An error occurred while trying to unban **${user.tag}**.`);
+ case 'error removing ban entry':
+ return message.util.reply(
+ `${this.client.util.emojis.error} While unbanning **${user.tag}**, there was an error removing their ban entry, please report this to my developers.`
+ );
+ case 'error creating modlog entry':
+ return message.util.reply(
+ `${this.client.util.emojis.error} While unbanning **${user.tag}**, there was an error creating a modlog entry, please report this to my developers.`
+ );
+ case 'user not banned':
+ return message.util.reply(`${this.client.util.emojis.warn} **${user.tag}** but I tried to unban them anyways.`);
+ case 'success':
+ return message.util.reply(`${this.client.util.emojis.success} Successfully unbanned **${user.tag}**.`);
+ }
+ }
+}
diff --git a/src/commands/moderation/unmute.ts b/src/commands/moderation/unmute.ts
new file mode 100644
index 0000000..4030fb7
--- /dev/null
+++ b/src/commands/moderation/unmute.ts
@@ -0,0 +1,109 @@
+import { BushCommand, BushGuildMember, BushMessage, BushSlashMessage, BushUser } from '@lib';
+
+export default class UnmuteCommand extends BushCommand {
+ public constructor() {
+ super('unmute', {
+ aliases: ['unmute'],
+ category: 'moderation',
+ description: {
+ content: 'unmute a user.',
+ usage: 'unmute <member> [reason] [duration]',
+ examples: ['unmute 322862723090219008 1 day commands in #general']
+ },
+ args: [
+ {
+ id: 'user',
+ type: 'user',
+ prompt: {
+ start: 'What user would you like to unmute?',
+ retry: '{error} Choose a valid user to unmute.'
+ }
+ },
+ {
+ id: 'reason',
+ type: 'string',
+ match: 'rest',
+ prompt: {
+ start: 'Why should this user be unmuted?',
+ retry: '{error} Choose a valid unmute reason.',
+ optional: true
+ }
+ }
+ ],
+ slash: true,
+ slashOptions: [
+ {
+ name: 'user',
+ description: 'What user would you like to unmute?',
+ type: 'USER',
+ required: true
+ },
+ {
+ name: 'reason',
+ description: 'Why should this user be unmuted?',
+ type: 'STRING',
+ required: false
+ }
+ ],
+ channel: 'guild',
+ clientPermissions: ['SEND_MESSAGES', 'MANAGE_ROLES'],
+ userPermissions: ['MANAGE_MESSAGES']
+ });
+ }
+ async exec(message: BushMessage | BushSlashMessage, { user, reason }: { user: BushUser; reason?: string }): Promise<unknown> {
+ const error = this.client.util.emojis.error;
+ const member = message.guild.members.cache.get(user.id) as BushGuildMember;
+ const canModerateResponse = this.client.util.moderationPermissionCheck(message.member, member, 'unmute');
+ const victimBoldTag = `**${member.user.tag}**`;
+
+ if (canModerateResponse !== true) {
+ return message.util.reply(canModerateResponse);
+ }
+
+ const response = await member.unmute({
+ reason,
+ moderator: message.author
+ });
+
+ switch (response) {
+ case 'missing permissions':
+ return message.util.reply(
+ `${error} Could not unmute ${victimBoldTag} because I am missing the \`Manage Roles\` permission.`
+ );
+ case 'no mute role':
+ return message.util.reply(
+ `${error} Could not unmute ${victimBoldTag}, you must set a mute role with \`${message.guild.getSetting(
+ 'prefix'
+ )}muterole\`.`
+ );
+ case 'invalid mute role':
+ return message.util.reply(
+ `${error} Could not unmute ${victimBoldTag} because the current mute role no longer exists. Please set a new mute role with \`${message.guild.getSetting(
+ 'prefix'
+ )}muterole\`.`
+ );
+ case 'mute role not manageable':
+ return message.util.reply(
+ `${error} Could not unmute ${victimBoldTag} because I cannot assign the current mute role, either change the role's position or set a new mute role with \`${message.guild.getSetting(
+ 'prefix'
+ )}muterole\`.`
+ );
+ case 'error removing mute role':
+ return message.util.reply(`${error} Could not unmute ${victimBoldTag}, there was an error removing their mute role.`);
+ case 'error creating modlog entry':
+ return message.util.reply(
+ `${error} While muting ${victimBoldTag}, there was an error creating a modlog entry, please report this to my developers.`
+ );
+ case 'error removing mute entry':
+ return message.util.reply(
+ `${error} While muting ${victimBoldTag}, there was an error removing their mute entry, please report this to my developers.`
+ );
+ case 'failed to dm':
+ return message.util.reply(
+ `${this.client.util.emojis.warn} unmuted **${member.user.tag}** however I could not send them a dm.`
+ );
+ case 'success':
+ return message.util.reply(`${this.client.util.emojis.success} Successfully unmuted **${member.user.tag}**.`);
+ }
+ }
+}
diff --git a/src/commands/moderation/warn.ts b/src/commands/moderation/warn.ts
index 5d679ab..3d353ca 100644
--- a/src/commands/moderation/warn.ts
+++ b/src/commands/moderation/warn.ts
@@ -33,15 +33,15 @@ export default class WarnCommand extends BushCommand {
slash: true,
slashOptions: [
{
- type: 'USER',
name: 'user',
description: 'What user would you like to warn?',
+ type: 'USER',
required: true
},
{
- type: 'STRING',
name: 'reason',
description: 'Why should this user be warned?',
+ type: 'STRING',
required: false
}
],
@@ -58,7 +58,7 @@ export default class WarnCommand extends BushCommand {
const canModerateResponse = this.client.util.moderationPermissionCheck(message.member, member, 'warn');
const victimBoldTag = `**${member.user.tag}**`;
- if (typeof canModerateResponse !== 'boolean') {
+ if (canModerateResponse !== true) {
return message.util.reply(canModerateResponse);
}
diff --git a/src/commands/moulberry-bush/level.ts b/src/commands/moulberry-bush/level.ts
index 7f3509f..fc1e93e 100644
--- a/src/commands/moulberry-bush/level.ts
+++ b/src/commands/moulberry-bush/level.ts
@@ -30,9 +30,9 @@ export default class LevelCommand extends BushCommand {
],
slashOptions: [
{
- type: 'USER',
name: 'user',
description: 'The user to get the level of',
+ type: 'USER',
required: false
}
],
diff --git a/src/commands/moderation/_unban.ts b/src/commands/utilities/whoHasRole.ts
index e69de29..e69de29 100644
--- a/src/commands/moderation/_unban.ts
+++ b/src/commands/utilities/whoHasRole.ts