diff options
Diffstat (limited to 'src/commands/moderation')
-rw-r--r-- | src/commands/moderation/_block.ts (renamed from src/commands/moderation/block.ts) | 0 | ||||
-rw-r--r-- | src/commands/moderation/_unban.ts (renamed from src/commands/moderation/unban.ts) | 0 | ||||
-rw-r--r-- | src/commands/moderation/_unblock.ts (renamed from src/commands/moderation/unblock.ts) | 0 | ||||
-rw-r--r-- | src/commands/moderation/_unmute.ts (renamed from src/commands/moderation/unmute.ts) | 0 | ||||
-rw-r--r-- | src/commands/moderation/ban.ts | 6 | ||||
-rw-r--r-- | src/commands/moderation/kick.ts | 93 | ||||
-rw-r--r-- | src/commands/moderation/modlog.ts | 4 | ||||
-rw-r--r-- | src/commands/moderation/mute.ts | 35 | ||||
-rw-r--r-- | src/commands/moderation/role.ts | 177 | ||||
-rw-r--r-- | src/commands/moderation/warn.ts | 110 |
10 files changed, 214 insertions, 211 deletions
diff --git a/src/commands/moderation/block.ts b/src/commands/moderation/_block.ts index e69de29..e69de29 100644 --- a/src/commands/moderation/block.ts +++ b/src/commands/moderation/_block.ts diff --git a/src/commands/moderation/unban.ts b/src/commands/moderation/_unban.ts index e69de29..e69de29 100644 --- a/src/commands/moderation/unban.ts +++ b/src/commands/moderation/_unban.ts diff --git a/src/commands/moderation/unblock.ts b/src/commands/moderation/_unblock.ts index e69de29..e69de29 100644 --- a/src/commands/moderation/unblock.ts +++ b/src/commands/moderation/_unblock.ts diff --git a/src/commands/moderation/unmute.ts b/src/commands/moderation/_unmute.ts index e69de29..e69de29 100644 --- a/src/commands/moderation/unmute.ts +++ b/src/commands/moderation/_unmute.ts diff --git a/src/commands/moderation/ban.ts b/src/commands/moderation/ban.ts index 0c68497..244014b 100644 --- a/src/commands/moderation/ban.ts +++ b/src/commands/moderation/ban.ts @@ -1,5 +1,5 @@ -import { Message, User } from 'discord.js'; -import { BushCommand } from '../../lib'; +import { User } from 'discord.js'; +import { BushCommand, BushMessage, BushSlashMessage } from '../../lib'; export default class BanCommand extends BushCommand { public constructor() { @@ -140,7 +140,7 @@ export default class BanCommand extends BushCommand { // } // } async exec( - message: Message, + message: BushMessage | BushSlashMessage, { user, reason, time }: { user: User; reason?: string; time?: number | string } ): Promise<unknown> { return message.util.reply(`${this.client.util.emojis.error} This command is not finished.`); diff --git a/src/commands/moderation/kick.ts b/src/commands/moderation/kick.ts index 8375198..919c14b 100644 --- a/src/commands/moderation/kick.ts +++ b/src/commands/moderation/kick.ts @@ -1,15 +1,19 @@ -import { GuildMember, Message } from 'discord.js'; -import { BushCommand } from '../../lib'; +import { BushCommand, BushGuildMember, BushMessage, BushSlashMessage, BushUser } from '../../lib'; export default class KickCommand extends BushCommand { public constructor() { super('kick', { aliases: ['kick'], category: 'moderation', + description: { + content: 'Kick a user.', + usage: 'kick <member> <reason>', + examples: ['kick @user bad'] + }, args: [ { id: 'user', - type: 'member', + type: 'user', prompt: { start: 'What user would you like to kick?', retry: '{error} Choose a valid user to kick.' @@ -20,19 +24,13 @@ export default class KickCommand extends BushCommand { type: 'string', match: 'restContent', prompt: { - start: 'Why would you like to kick this user?', - retry: '{error} Choose a valid user to kick.', + start: 'Why should this user be kicked?', + retry: '{error} Choose a valid kick reason.', optional: true } } ], - clientPermissions: ['KICK_MEMBERS'], - userPermissions: ['KICK_MEMBERS'], - description: { - content: 'Kick a member from the server.', - usage: 'kick <member> <reason>', - examples: ['kick @user bad'] - }, + slash: true, slashOptions: [ { type: 'USER', @@ -43,67 +41,30 @@ export default class KickCommand extends BushCommand { { type: 'STRING', name: 'reason', - description: 'Why would you like to kick this user?', + description: 'Why should this user be kicked?', required: false } ], - slash: true + clientPermissions: ['SEND_MESSAGES', 'KICK_MEMBERS'], + userPermissions: ['KICK_MEMBERS'] }); } - // private async *genResponses( - // message: Message | CommandInteraction, - // user: GuildMember, - // reason?: string - // ): AsyncIterable<string> { - // let modlogEnry: ModLog; - // // 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 { - // modlogEnry = ModLog.build({ - // user: user.id, - // guild: message.guild.id, - // moderator: message instanceof Message ? message.author.id : message.user.id, - // type: ModLogType.KICK, - // reason - // }); - // await modlogEnry.save(); - // } catch (e) { - // this.client.console.error(`KickCommand`, `Error saving to database. ${e?.stack || e}`); - // yield `${this.client.util.emojis.error} Error saving to database. Please report this to a developer.`; - // return; - // } - // try { - // await user.send(`You were kicked in ${message.guild.name} with reason \`${reason || 'No reason given'}\``); - // } catch { - // yield `${this.client.util.emojis.warn} Unable to dm user`; - // } - // try { - // await user.kick( - // `Kicked by ${message instanceof Message ? message.author.tag : message.user.tag} with ${ - // reason ? `reason ${reason}` : 'no reason' - // }` - // ); - // } catch { - // yield `${this.client.util.emojis.error} Error kicking :/`; - // await modlogEnry.destroy(); - // return; - // } - // yield `${this.client.util.emojis.success} Kicked <@!${user.id}> with reason \`${reason || 'No reason given'}\``; - // } + async exec(message: BushMessage | BushSlashMessage, { user, reason }: { user: BushUser; reason?: string }): Promise<unknown> { + const member = message.guild.members.cache.get(user.id) as BushGuildMember; + const canModerateResponse = this.client.util.moderationPermissionCheck(message.member, member, 'kick'); + // const victimBoldTag = `**${member.user.tag}**`; + + if (typeof canModerateResponse !== 'boolean') { + return message.util.reply(canModerateResponse); + } - async exec(message: Message, { user, reason }: { user: GuildMember; reason?: string }): Promise<unknown> { - return message.util.reply(`${this.client.util.emojis.error} This command is not finished.`); - // for await (const response of this.genResponses(message, user, reason)) { - // await message.util.send(response); - // } + const response = await member.bushKick({ + reason, + moderator: message.author + }); + + } } diff --git a/src/commands/moderation/modlog.ts b/src/commands/moderation/modlog.ts index 5be50a4..36f72fc 100644 --- a/src/commands/moderation/modlog.ts +++ b/src/commands/moderation/modlog.ts @@ -1,7 +1,7 @@ import { Argument } from 'discord-akairo'; import { MessageEmbed } from 'discord.js'; import moment from 'moment'; -import { BushCommand, BushMessage, ModLog } from '../../lib'; +import { BushCommand, BushMessage, BushSlashMessage, ModLog } from '../../lib'; export default class ModlogCommand extends BushCommand { public constructor() { @@ -48,7 +48,7 @@ export default class ModlogCommand extends BushCommand { return modLog.join(`\n`); } - async exec(message: BushMessage, { search }: { search: string }): Promise<unknown> { + async exec(message: BushMessage | BushSlashMessage, { search }: { search: string }): Promise<unknown> { const foundUser = await this.client.util.resolveUserAsync(search); if (foundUser) { const logs = await ModLog.findAll({ diff --git a/src/commands/moderation/mute.ts b/src/commands/moderation/mute.ts index 33c0e32..bc3abf2 100644 --- a/src/commands/moderation/mute.ts +++ b/src/commands/moderation/mute.ts @@ -1,5 +1,5 @@ import { Argument } from 'discord-akairo'; -import { BushCommand, BushGuildMember, BushMessage, BushUser } from '../../lib'; +import { BushCommand, BushGuildMember, BushMessage, BushSlashMessage, BushUser } from '../../lib'; export default class MuteCommand extends BushCommand { public constructor() { @@ -8,8 +8,8 @@ export default class MuteCommand extends BushCommand { category: 'moderation', description: { content: 'Mute a user.', - usage: 'mute <member> <reason> [--time]', - examples: ['mute @user bad boi --time 1h'] + usage: 'mute <member> [reason] [duration]', + examples: ['mute 322862723090219008 1 day commands in #general'] }, args: [ { @@ -31,8 +31,7 @@ export default class MuteCommand extends BushCommand { } } ], - clientPermissions: ['MANAGE_ROLES'], - userPermissions: ['MANAGE_MESSAGES'], + slash: true, slashOptions: [ { type: 'USER', @@ -47,37 +46,29 @@ export default class MuteCommand extends BushCommand { required: false } ], - slash: true + channel: 'guild', + clientPermissions: ['SEND_MESSAGES', 'MANAGE_ROLES'], + userPermissions: ['MANAGE_MESSAGES'] }); } async exec( - message: BushMessage, + message: BushMessage | BushSlashMessage, { user, reason }: { user: BushUser; reason?: { duration: number; contentWithoutTime: 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); + const canModerateResponse = this.client.util.moderationPermissionCheck(message.member, member, 'mute'); const victimBoldTag = `**${member.user.tag}**`; - switch (canModerateResponse) { - case 'moderator': - return message.util.reply(`${error} You cannot mute ${victimBoldTag} because they are a moderator.`); - case 'user hierarchy': - return message.util.reply( - `${error} You cannot mute ${victimBoldTag} because they have higher or equal role hierarchy as you do.` - ); - case 'client hierarchy': - return message.util.reply( - `${error} You cannot mute ${victimBoldTag} because they have higher or equal role hierarchy as I do.` - ); - case 'self': - return message.util.reply(`${error} You cannot mute yourself.`); + + if (typeof canModerateResponse !== 'boolean') { + return message.util.reply(canModerateResponse); } let time: number; if (reason) { time = typeof reason === 'string' - ? await Argument.cast('duration', this.client.commandHandler.resolver, message, reason) + ? await Argument.cast('duration', this.client.commandHandler.resolver, message as BushMessage, reason) : reason.duration; } const parsedReason = reason.contentWithoutTime; diff --git a/src/commands/moderation/role.ts b/src/commands/moderation/role.ts index 83e85e0..6bac9e8 100644 --- a/src/commands/moderation/role.ts +++ b/src/commands/moderation/role.ts @@ -1,28 +1,7 @@ /* eslint-disable @typescript-eslint/no-empty-function */ -import { GuildMember, Message, Role } from 'discord.js'; -import { AllowedMentions, BushCommand } from '../../lib'; +import { AllowedMentions, BushCommand, BushGuildMember, BushMessage, BushRole, BushSlashMessage } from '../../lib'; export default class RoleCommand extends BushCommand { - private roleWhitelist: Record<string, string[]> = { - 'Partner': ['*', 'Admin Perms', 'Sr. Moderator', 'Moderator'], - 'Suggester': ['*', 'Admin Perms', 'Sr. Moderator', 'Moderator', 'Helper', 'Trial Helper', 'Contributor'], - 'Level Locked': ['*', 'Admin Perms', 'Sr. Moderator', 'Moderator'], - 'No Files': ['*', 'Admin Perms', 'Sr. Moderator', 'Moderator'], - 'No Reactions': ['*', 'Admin Perms', 'Sr. Moderator', 'Moderator'], - 'No Links': ['*', 'Admin Perms', 'Sr. Moderator', 'Moderator'], - 'No Bots': ['*', 'Admin Perms', 'Sr. Moderator', 'Moderator'], - 'No VC': ['*', 'Admin Perms', 'Sr. Moderator', 'Moderator'], - 'No Giveaways': ['*', 'Admin Perms', 'Sr. Moderator', 'Moderator', 'Helper'], - 'No Support': ['*', 'Admin Perms', 'Sr. Moderator', 'Moderator'], - 'Giveaway Donor': ['*', 'Admin Perms', 'Sr. Moderator', 'Moderator'], - 'Giveaway (200m)': ['*', 'Admin Perms', 'Sr. Moderator', 'Moderator'], - 'Giveaway (100m)': ['*', 'Admin Perms', 'Sr. Moderator', 'Moderator'], - 'Giveaway (50m)': ['*', 'Admin Perms', 'Sr. Moderator', 'Moderator'], - 'Giveaway (25m)': ['*', 'Admin Perms', 'Sr. Moderator', 'Moderator'], - 'Giveaway (10m)': ['*', 'Admin Perms', 'Sr. Moderator', 'Moderator'], - 'Giveaway (5m)': ['*', 'Admin Perms', 'Sr. Moderator', 'Moderator'], - 'Giveaway (1m)': ['*', 'Admin Perms', 'Sr. Moderator', 'Moderator'] - }; public constructor() { super('role', { aliases: ['role', 'addrole', 'removerole'], @@ -32,59 +11,103 @@ export default class RoleCommand extends BushCommand { usage: 'role <add|remove> <user> <role>', examples: ['role add tyman adminperms'] }, - clientPermissions: ['MANAGE_ROLES', 'EMBED_LINKS', 'SEND_MESSAGES'], - channel: 'guild', - typing: true, - args: [ + slash: true, + slashOptions: [ { - id: 'user', - type: 'member', - prompt: { - start: `What user do you want to add/remove the role on?`, - retry: `{error} Choose a valid user to add/remove the role on.` - } + name: 'action', + description: 'Would you like to add or remove a role?', + type: 'STRING', + choices: [ + { + name: 'add', + value: 'add' + }, + { + name: 'remove', + value: 'remove' + } + ], + required: true }, { - id: 'role', - type: 'role', - match: 'restContent', - prompt: { - start: `What role do you want to add/remove?`, - retry: `{error} Choose a valid role to add/remove.` - } - } - ], - slashOptions: [ - { - type: 'USER', name: 'user', - description: 'The user to add/remove the role on', + description: 'The user you would like to add/remove the role from.', + type: 'USER', required: true }, { - type: 'ROLE', name: 'role', - description: 'The role to add/remove', + description: 'The role you would like to add/remove from the user.', + type: 'ROLE', required: true } - ] + ], + channel: 'guild', + typing: true, + clientPermissions: ['MANAGE_ROLES', 'EMBED_LINKS', 'SEND_MESSAGES'], + userPermissions: ['SEND_MESSAGES'] }); } - public async exec(message: Message, { user, role }: { user: GuildMember; role: Role }): Promise<unknown> { + *args(): unknown { + const action: 'add' | 'remove' = yield { + id: 'action', + type: [['add'], ['remove']], + prompt: { + start: 'Would you like to `add` or `remove` a role?', + retry: '{error} Choose whether you would you like to `add` or `remove` a role.' + } + }; + let action2: 'to' | 'from'; + if (action === 'add') action2 = 'to'; + else if (action === 'remove') action2 = 'from'; + else return; + const user = yield { + id: 'user', + type: 'member', + prompt: { + 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', + type: 'role', + match: 'restContent', + prompt: { + start: `What role do you want to ${action}?`, + retry: `{error} Choose a valid role to ${action}.` + } + }; + return { action, user, role }; + } + + public async exec( + 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)) { - const mappedRole = this.client.consts.moulberryBushRoleMap.find((m) => m.id === role.id); - if (!mappedRole || !this.roleWhitelist[mappedRole.name]) { - return message.util.reply({ + const mappings = this.client.consts.mappings; + let mappedRole: { name: string; id: string }; + for (let i = 0; i < mappings.roleMap.length; i++) { + const a = mappings.roleMap[i]; + if (a.id == role.id) mappedRole = a; + } + if (!mappedRole || !mappings.roleWhitelist[mappedRole.name]) { + return await message.util.reply({ content: `${this.client.util.emojis.error} <@&${role.id}> is not whitelisted, and you do not have manage roles permission.`, allowedMentions: AllowedMentions.none() }); } - const allowedRoles = this.roleWhitelist[mappedRole.name].map((r) => { - return this.client.consts.moulberryBushRoleMap.find((m) => m.name === r).id; + const allowedRoles = mappings.roleWhitelist[mappedRole.name].map((r) => { + for (let i = 0; i < mappings.roleMap.length; i++) { + if (mappings.roleMap[i].name == r) return mappings.roleMap[i].id; + } + return; }); if (!message.member.roles.cache.some((role) => allowedRoles.includes(role.id))) { - return message.util.reply({ + return await message.util.reply({ content: `${this.client.util.emojis.error} <@&${role.id}> is whitelisted, but you do not have any of the roles required to manage it.`, allowedMentions: AllowedMentions.none() }); @@ -92,51 +115,51 @@ export default class RoleCommand extends BushCommand { } if (!this.client.ownerID.includes(message.author.id)) { if (role.comparePositionTo(message.member.roles.highest) >= 0) { - return message.util.reply({ + return await message.util.reply({ content: `${this.client.util.emojis.error} <@&${role.id}> is higher or equal to your highest role.`, allowedMentions: AllowedMentions.none() }); } if (role.comparePositionTo(message.guild.me.roles.highest) >= 0) { - return message.util.reply({ + return await message.util.reply({ content: `${this.client.util.emojis.error} <@&${role.id}> is higher or equal to my highest role.`, allowedMentions: AllowedMentions.none() }); } if (role.managed) { - await message.util.reply({ + await await message.util.reply({ content: `${this.client.util.emojis.error} <@&${role.id}> is managed by an integration and cannot be managed.`, allowedMentions: AllowedMentions.none() }); } } - // No checks if the user has MANAGE_ROLES - if (user.roles.cache.has(role.id)) { - try { - await user.roles.remove(role.id); - } catch { - return message.util.reply({ + // no checks if the user has MANAGE_ROLES + if (action == 'remove') { + 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}>!`, + allowedMentions: AllowedMentions.none() + }); + } else { + return await message.util.reply({ content: `${this.client.util.emojis.error} Could not remove <@&${role.id}> from <@${user.id}>.`, allowedMentions: AllowedMentions.none() }); } - return message.util.reply({ - content: `${this.client.util.emojis.success} Successfully removed <@&${role.id}> from <@${user.id}>!`, - allowedMentions: AllowedMentions.none() - }); - } else { - try { - await user.roles.add(role.id); - } catch { - return message.util.reply({ + } else if (action == 'add') { + const success = await user.roles.add(role.id).catch(() => {}); + if (success) { + return await message.util.reply({ + content: `${this.client.util.emojis.success} Successfully added <@&${role.id}> to <@${user.id}>!`, + allowedMentions: AllowedMentions.none() + }); + } else { + return await message.util.reply({ content: `${this.client.util.emojis.error} Could not add <@&${role.id}> to <@${user.id}>.`, allowedMentions: AllowedMentions.none() }); } - return message.util.reply({ - content: `${this.client.util.emojis.success} Successfully added <@&${role.id}> to <@${user.id}>!`, - allowedMentions: AllowedMentions.none() - }); } } } diff --git a/src/commands/moderation/warn.ts b/src/commands/moderation/warn.ts index f2b9142..d1c17d4 100644 --- a/src/commands/moderation/warn.ts +++ b/src/commands/moderation/warn.ts @@ -1,61 +1,89 @@ -import { GuildMember, Message } from 'discord.js'; -import { BushCommand, Guild, ModLog, ModLogType } from '../../lib'; +import { BushCommand, BushGuildMember, BushMessage, BushSlashMessage, BushUser } from '../../lib'; export default class WarnCommand extends BushCommand { public constructor() { super('warn', { aliases: ['warn'], category: 'moderation', - userPermissions: ['MANAGE_MESSAGES'], + description: { + content: 'Warn a user.', + usage: 'warn <member> [reason]', + examples: ['warn @Tyman being cool'] + }, args: [ { - id: 'member', - type: 'member' + id: 'user', + type: 'user', + prompt: { + start: 'What user would you like to warn?', + retry: '{error} Choose a valid user to warn.' + } }, { id: 'reason', - type: 'contentWithDuration', - match: 'rest' + type: 'content', + match: 'rest', + prompt: { + start: 'Why should this user be warned?', + retry: '{error} Choose a valid warn reason.', + optional: true + } } ], - description: { - content: 'Warn a member and log it in modlogs', - usage: 'warn <member> <reason>', - examples: ['warn @Tyman being cool'] - } + slash: true, + slashOptions: [ + { + type: 'USER', + name: 'user', + description: 'What user would you like to warn?', + required: true + }, + { + type: 'STRING', + name: 'reason', + description: 'Why should this user be warned?', + required: false + } + ], + channel: 'guild', + clientPermissions: ['SEND_MESSAGES'], + userPermissions: ['MANAGE_MESSAGES'] }); } - public async exec(message: Message, { member, reason }: { member: GuildMember; reason: string }): Promise<unknown> { - return message.util.reply(`${this.client.util.emojis.error} This command is not finished.`); + public async exec( + message: BushMessage | BushSlashMessage, + { user, reason }: { user: BushUser; reason: string } + ): Promise<unknown> { + const member = message.guild.members.cache.get(user.id) as BushGuildMember; + const canModerateResponse = this.client.util.moderationPermissionCheck(message.member, member, 'warn'); + const victimBoldTag = `**${member.user.tag}**`; - // 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 { - const entry = ModLog.build({ - user: member.id, - guild: message.guild.id, - moderator: message.author.id, - type: ModLogType.WARN, - reason - }); - await entry.save(); - } catch { - await message.util.send('Error saving to database, please contact the developers'); - return; + if (typeof canModerateResponse !== 'boolean') { + return message.util.reply(canModerateResponse); } - try { - await member.send(`You were warned in ${message.guild.name} for reason "${reason}".`); - } catch { - await message.util.send('Error messaging user, warning still saved.'); - return; + + const { result: response, caseNum } = await member.warn({ + reason, + moderator: message.author + }); + + switch (response) { + case 'error creating modlog entry': + return message.util.reply( + `${this.client.util.emojis.error} While warning ${victimBoldTag}, 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} **${member.user.tag}** has been warned for the ${this.client.util.ordinal( + caseNum + )} time, however I could not send them a dm.` + ); + case 'success': + return message.util.reply( + `${this.client.util.emojis.success} Successfully warned **${member.user.tag}** for the ${this.client.util.ordinal( + caseNum + )} time.` + ); } - await message.util.send(`${member.user.tag} was warned for reason "${reason}".`); } } |