diff options
author | IRONM00N <64110067+IRONM00N@users.noreply.github.com> | 2021-06-24 00:56:16 -0400 |
---|---|---|
committer | IRONM00N <64110067+IRONM00N@users.noreply.github.com> | 2021-06-24 00:56:16 -0400 |
commit | 4176b6258e44e4a095376aaf0f4c687244243a69 (patch) | |
tree | 3b9144be9a2045483c90d92fff05b3ca0b288e52 /src/commands/moderation | |
parent | e80446e23060c0325bbd6db620920d86694ec3ce (diff) | |
download | tanzanite-4176b6258e44e4a095376aaf0f4c687244243a69.tar.gz tanzanite-4176b6258e44e4a095376aaf0f4c687244243a69.tar.bz2 tanzanite-4176b6258e44e4a095376aaf0f4c687244243a69.zip |
feat(*): Began working on other punishment commands etc
Diffstat (limited to 'src/commands/moderation')
-rw-r--r-- | src/commands/moderation/ban.ts | 148 | ||||
-rw-r--r-- | src/commands/moderation/block.ts | 0 | ||||
-rw-r--r-- | src/commands/moderation/kick.ts | 18 | ||||
-rw-r--r-- | src/commands/moderation/modlog.ts | 36 | ||||
-rw-r--r-- | src/commands/moderation/mute.ts | 166 | ||||
-rw-r--r-- | src/commands/moderation/unban.ts | 0 | ||||
-rw-r--r-- | src/commands/moderation/unblock.ts | 0 | ||||
-rw-r--r-- | src/commands/moderation/unmute.ts | 0 | ||||
-rw-r--r-- | src/commands/moderation/warn.ts | 6 |
9 files changed, 266 insertions, 108 deletions
diff --git a/src/commands/moderation/ban.ts b/src/commands/moderation/ban.ts index 692691e..7ce222a 100644 --- a/src/commands/moderation/ban.ts +++ b/src/commands/moderation/ban.ts @@ -1,18 +1,17 @@ +import { Argument } from 'discord-akairo'; import { CommandInteraction, Message, User } from 'discord.js'; import moment from 'moment'; -import { SlashCommandOption } from '../../lib/extensions/BushClientUtil'; import { BushCommand } from '../../lib/extensions/BushCommand'; -import { BushSlashMessage } from '../../lib/extensions/BushInteractionMessage'; -import { Ban, Guild, Modlog, ModlogType } from '../../lib/models'; +import { Ban, Guild, ModLog, ModLogType } from '../../lib/models'; -const durationAliases: Record<string, string[]> = { +/* const durationAliases: Record<string, string[]> = { weeks: ['w', 'weeks', 'week', 'wk', 'wks'], days: ['d', 'days', 'day'], hours: ['h', 'hours', 'hour', 'hr', 'hrs'], minutes: ['m', 'min', 'mins', 'minutes', 'minute'], months: ['mo', 'month', 'months'] }; -const durationRegex = /(?:(\d+)(d(?:ays?)?|h(?:ours?|rs?)?|m(?:inutes?|ins?)?|mo(?:nths?)?|w(?:eeks?|ks?)?)(?: |$))/g; +const durationRegex = /(?:(\d+)(d(?:ays?)?|h(?:ours?|rs?)?|m(?:inutes?|ins?)?|mo(?:nths?)?|w(?:eeks?|ks?)?)(?: |$))/g; */ export default class BanCommand extends BushCommand { constructor() { @@ -25,15 +24,21 @@ export default class BanCommand extends BushCommand { type: 'user', prompt: { start: 'What user would you like to ban?', - retry: 'Invalid response. What user would you like to ban?' + retry: '{error} Choose a valid user to ban.' } }, { id: 'reason', - match: 'rest' + match: 'restContent', + prompt: { + start: 'Why would you like to ban this user?', + retry: '{error} Choose a ban reason.', + optional: true + } }, { id: 'time', + type: 'duration', match: 'option', flag: '--time' } @@ -41,27 +46,27 @@ export default class BanCommand extends BushCommand { clientPermissions: ['BAN_MEMBERS'], userPermissions: ['BAN_MEMBERS'], description: { - content: 'Ban a member and log it in modlogs (with optional time to unban)', + content: 'Ban a member from the server.', usage: 'ban <member> <reason> [--time]', - examples: ['ban @Tyman being cool', 'ban @Tyman being cool --time 7days'] + examples: ['ban @user bad --time 69d'] }, slashOptions: [ { type: 'USER', name: 'user', - description: 'The user to ban', + description: 'Who would you like to ban?', required: true }, { type: 'STRING', name: 'reason', - description: 'The reason to show in modlogs and audit log', + description: 'Why are they getting banned?', required: false }, { type: 'STRING', name: 'time', - description: 'The time the user should be banned for (default permanent)', + description: 'How long should they be banned for?', required: false } ], @@ -72,12 +77,12 @@ export default class BanCommand extends BushCommand { message: Message | CommandInteraction, user: User, reason?: string, - time?: string + time?: number ): AsyncIterable<string> { const duration = moment.duration(); - let modlogEnry: Modlog; + let modLogEntry: ModLog; let banEntry: Ban; - const translatedTime: string[] = []; + // const translatedTime: string[] = []; // Create guild entry so postgres doesn't get mad when I try and add a modlog entry await Guild.findOrCreate({ where: { @@ -88,62 +93,58 @@ export default class BanCommand extends BushCommand { } }); try { - try { - if (time) { - const parsed = [...time.matchAll(durationRegex)]; + if (time) { + duration.add(time); + /* const parsed = [...time.matchAll(durationRegex)]; if (parsed.length < 1) { - yield 'Invalid time.'; + 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'); - } - modlogEnry = Modlog.build({ - user: user.id, - guild: message.guild.id, - reason, - type: ModlogType.TEMPBAN, - 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: modlogEnry.id - }); - } else { - modlogEnry = 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: modlogEnry.id - }); - } - await modlogEnry.save(); - await banEntry.save(); - } catch (e) { - this.client.console.error(`BanCommand`, `Error saving to database. ${e?.stack}`); - yield `${this.client.util.emojis.error} Error saving to database. Please report this to a developer.`; - return; + } */ + 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} ${ - translatedTime.length >= 1 ? `for ${translatedTime.join(', ')}` : 'permanently' - } with reason \`${reason || 'No reason given'}\`` + `You were banned in ${message.guild.name} ${duration ? duration.humanize() : 'permanently'} with reason \`${ + reason || 'No reason given' + }\`` ); - } catch (e) { + } catch { yield `${this.client.util.emojis.warn} Unable to dm user`; } await message.guild.members.ban(user, { @@ -152,35 +153,22 @@ export default class BanCommand extends BushCommand { }` }); yield `${this.client.util.emojis.success} Banned <@!${user.id}> ${ - translatedTime.length >= 1 ? `for ${translatedTime.join(', ')}` : 'permanently' + duration ? duration.humanize() : 'permanently' } with reason \`${reason || 'No reason given'}\``; } catch { yield `${this.client.util.emojis.error} Error banning :/`; await banEntry.destroy(); - await modlogEnry.destroy(); + await modLogEntry.destroy(); return; } } - async exec(message: Message, { user, reason, time }: { user: User; reason?: string; time?: string }): Promise<void> { + async exec(message: Message, { user, reason, time }: { user: User; reason?: string; time?: number | string }): Promise<void> { + 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); } } - - async execSlash( - message: BushSlashMessage, - { - user, - reason, - time - }: { - user: SlashCommandOption<undefined>; - reason: SlashCommandOption<string>; - time: SlashCommandOption<string>; - } - ): Promise<void> { - for await (const response of this.genResponses(message.interaction, user.user, reason?.value, time?.value)) { - await message.reply(response); - } - } } diff --git a/src/commands/moderation/block.ts b/src/commands/moderation/block.ts new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/commands/moderation/block.ts diff --git a/src/commands/moderation/kick.ts b/src/commands/moderation/kick.ts index d00ae55..eed3038 100644 --- a/src/commands/moderation/kick.ts +++ b/src/commands/moderation/kick.ts @@ -1,7 +1,7 @@ import { CommandInteraction, GuildMember, Message } from 'discord.js'; import { BushCommand } from '../../lib/extensions/BushCommand'; import { BushSlashMessage } from '../../lib/extensions/BushInteractionMessage'; -import { Guild, Modlog, ModlogType } from '../../lib/models'; +import { Guild, ModLog, ModLogType } from '../../lib/models'; export default class KickCommand extends BushCommand { constructor() { @@ -14,17 +14,19 @@ export default class KickCommand extends BushCommand { type: 'member', prompt: { start: 'What user would you like to kick?', - retry: 'Invalid response. What user would you like to kick?' + retry: '{error} Choose a valid user to kick.' } }, { - id: 'reason' + id: 'reason', + type: 'string', + match: 'restContent' } ], clientPermissions: ['KICK_MEMBERS'], userPermissions: ['KICK_MEMBERS'], description: { - content: 'Kick a member and log it in modlogs', + content: 'Kick a member from the server.', usage: 'kick <member> <reason>', examples: ['kick @Tyman being cool'] }, @@ -51,7 +53,7 @@ export default class KickCommand extends BushCommand { user: GuildMember, reason?: string ): AsyncIterable<string> { - let modlogEnry: Modlog; + let modlogEnry: ModLog; // Create guild entry so postgres doesn't get mad when I try and add a modlog entry await Guild.findOrCreate({ where: { @@ -62,16 +64,16 @@ export default class KickCommand extends BushCommand { } }); try { - modlogEnry = Modlog.build({ + modlogEnry = ModLog.build({ user: user.id, guild: message.guild.id, moderator: message instanceof Message ? message.author.id : message.user.id, - type: ModlogType.KICK, + type: ModLogType.KICK, reason }); await modlogEnry.save(); } catch (e) { - this.client.console.error(`BanCommand`, `Error saving to database. ${e?.stack}`); + this.client.console.error(`KickCommand`, `Error saving to database. ${e?.stack}`); yield `${this.client.util.emojis.error} Error saving to database. Please report this to a developer.`; return; } diff --git a/src/commands/moderation/modlog.ts b/src/commands/moderation/modlog.ts index 862a26d..e32df42 100644 --- a/src/commands/moderation/modlog.ts +++ b/src/commands/moderation/modlog.ts @@ -3,7 +3,7 @@ import { Argument } from 'discord-akairo'; import { Message, MessageEmbed } from 'discord.js'; import moment from 'moment'; import { BushCommand } from '../../lib/extensions/BushCommand'; -import { Modlog } from '../../lib/models'; +import { ModLog } from '../../lib/models'; export default class ModlogCommand extends BushCommand { constructor() { @@ -35,7 +35,8 @@ export default class ModlogCommand extends BushCommand { id: 'search', type: Argument.union('user', 'string'), prompt: { - start: 'What modlog id or user would you like to see?' + start: 'What modlog id or user would you like to see?', + retry: '{error} Choose a valid modlog id or user.' } }; if (typeof search === 'string') return { search, page: null }; @@ -45,7 +46,7 @@ export default class ModlogCommand extends BushCommand { type: 'number', prompt: { start: 'What page?', - retry: 'Not a number. What page?', + retry: '{error} Choose a valid page to view.', optional: true } }; @@ -55,7 +56,7 @@ export default class ModlogCommand extends BushCommand { async exec(message: Message, { search, page }: { search: string; page: number }): Promise<void> { const foundUser = await this.client.util.resolveUserAsync(search); if (foundUser) { - const logs = await Modlog.findAll({ + const logs = await ModLog.findAll({ where: { guild: message.guild.id, user: foundUser.id @@ -65,24 +66,25 @@ export default class ModlogCommand extends BushCommand { const niceLogs: string[] = []; for (const log of logs) { niceLogs.push(stripIndent` - ID: ${log.id} - Type: ${log.type.toLowerCase()} - User: <@!${log.user}> (${log.user}) - Moderator: <@!${log.moderator}> (${log.moderator}) - Duration: ${log.duration ? moment.duration(log.duration, 'milliseconds').humanize() : 'N/A'} - Reason: ${log.reason || 'None given'} - ${this.client.util.ordinal(logs.indexOf(log) + 1)} action + **Case ID**: ${log.id} + **Type**: ${log.type.toLowerCase()} + **User**: <@!${log.user}> (${log.user}) + **Moderator**: <@!${log.moderator}> (${log.moderator}) + **Duration**: ${log.duration ? moment.duration(log.duration, 'milliseconds').humanize() : 'N/A'} + **Reason**: ${log.reason || 'None given'} + **${this.client.util.ordinal(logs.indexOf(log) + 1)}** action `); } const chunked: string[][] = this.client.util.chunk(niceLogs, 3); const embedPages = chunked.map( (e, i) => new MessageEmbed({ - title: `Modlogs page ${i + 1}`, - description: e.join('\n-------------------------------------------------------\n'), + title: foundUser.tag, + description: e.join('\n**---------------------------**\n'), footer: { text: `Page ${i + 1}/${chunked.length}` - } + }, + color: this.client.util.colors.default }) ); if (page) { @@ -93,15 +95,15 @@ export default class ModlogCommand extends BushCommand { return; } } else if (search) { - const entry = await Modlog.findByPk(search); + const entry = await ModLog.findByPk(search); if (!entry) { - await message.util.send('That modlog does not exist.'); + await message.util.send(`${this.client.util.emojis.error} That modlog does not exist.`); return; } await message.util.send({ embeds: [ new MessageEmbed({ - title: `Modlog ${entry.id}`, + title: `${entry.id}`, fields: [ { name: 'Type', diff --git a/src/commands/moderation/mute.ts b/src/commands/moderation/mute.ts new file mode 100644 index 0000000..9b6ad70 --- /dev/null +++ b/src/commands/moderation/mute.ts @@ -0,0 +1,166 @@ +import { Argument } from 'discord-akairo'; +import { CommandInteraction, Message, User } from 'discord.js'; +import moment from 'moment'; +import { BushCommand } from '../../lib/extensions/BushCommand'; +import { Guild, ModLog, ModLogType, Mute } from '../../lib/models'; + +export default class MuteCommand extends BushCommand { + constructor() { + super('mute', { + aliases: ['mute'], + category: 'moderation', + args: [ + { + id: 'user', + type: 'user', + prompt: { + start: 'What user would you like to mute?', + retry: '{error} Choose a valid user to mute.' + } + }, + { + id: 'reason', + match: 'separate', + prompt: { + start: 'Why would you like to mute this user?', + retry: '{error} Choose a mute reason.', + optional: true + } + }, + { + id: 'time', + type: 'duration', + match: 'option', + flag: '--time' + } + ], + clientPermissions: ['MANAGE_ROLES'], + userPermissions: ['MANAGE_MESSAGES'], + description: { + content: 'Mute a user.', + usage: 'mute <member> <reason> [--time]', + examples: ['mute @user bad boi --time 1h'] + }, + slashOptions: [ + { + type: 'USER', + name: 'user', + description: 'The user to mute.', + required: true + }, + { + type: 'STRING', + name: 'reason', + description: 'Why the user is getting muted.', + required: false + }, + { + type: 'STRING', + name: 'time', + description: 'How long the user should be muted for.', + required: false + } + ], + slash: true + }); + } + async *genResponses( + message: Message | CommandInteraction, + user: User, + reason?: string, + time?: number + ): AsyncIterable<string> { + const duration = moment.duration(time); + let modlogEnry: ModLog; + let muteEntry: Mute; + // 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 muteRole = (await Guild.findByPk(message.guild.id)).get('muteRole'); + try { + if (time) { + modlogEnry = ModLog.build({ + user: user.id, + guild: message.guild.id, + reason, + type: ModLogType.TEMP_MUTE, + duration: duration.asMilliseconds(), + moderator: message instanceof CommandInteraction ? message.user.id : message.author.id + }); + muteEntry = Mute.build({ + user: user.id, + guild: message.guild.id, + reason, + expires: new Date(new Date().getTime() + duration.asMilliseconds()), + modlog: modlogEnry.id + }); + } else { + modlogEnry = ModLog.build({ + user: user.id, + guild: message.guild.id, + reason, + type: ModLogType.MUTE, + moderator: message instanceof CommandInteraction ? message.user.id : message.author.id + }); + muteEntry = Mute.build({ + user: user.id, + guild: message.guild.id, + reason, + modlog: modlogEnry.id + }); + } + await modlogEnry.save(); + await muteEntry.save(); + } catch (e) { + this.client.console.error(`MuteCommand`, `Error saving to database. ${e?.stack}`); + yield `${this.client.util.emojis.error} Error saving to database. Please report this to a developer.`; + return; + } + try { + await user.send( + `You were muted in ${message.guild.name} ${time ? `for ${duration.humanize()}` : 'permanently'} with reason \`${ + reason || 'No reason given' + }\`` + ); + } catch (e) { + yield `${this.client.util.emojis.warn} Unable to dm user`; + } + await ( + await message.guild.members.fetch(user) + ).roles.add( + muteRole, + `Muted by ${message instanceof CommandInteraction ? message.user.tag : message.author.tag} with ${ + reason ? `reason ${reason}` : 'no reason' + }` + ); + yield `${this.client.util.emojis.success} muted <@!${user.id}> ${ + time ? `for ${duration.humanize()}` : 'permanently' + } with reason \`${reason || 'No reason given'}\``; + } catch { + yield `${this.client.util.emojis.error} Error muting :/`; + await muteEntry.destroy(); + await modlogEnry.destroy(); + return; + } + } + async exec( + message: Message, + { user, reason, time }: { user: User; reason?: string[]; time?: string | number } + ): Promise<void> { + this.client.console.debug(reason); + + if (typeof time === 'string') { + time = (await Argument.cast('duration', this.client.commandHandler.resolver, message, time)) as number; + } + for await (const response of this.genResponses(message, user, reason.join(' '), time)) { + await message.util.sendNew(response); + } + } +} diff --git a/src/commands/moderation/unban.ts b/src/commands/moderation/unban.ts new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/commands/moderation/unban.ts diff --git a/src/commands/moderation/unblock.ts b/src/commands/moderation/unblock.ts new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/commands/moderation/unblock.ts diff --git a/src/commands/moderation/unmute.ts b/src/commands/moderation/unmute.ts new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/commands/moderation/unmute.ts diff --git a/src/commands/moderation/warn.ts b/src/commands/moderation/warn.ts index 3410d81..d48049b 100644 --- a/src/commands/moderation/warn.ts +++ b/src/commands/moderation/warn.ts @@ -1,6 +1,6 @@ import { GuildMember, Message } from 'discord.js'; import { BushCommand } from '../../lib/extensions/BushCommand'; -import { Guild, Modlog, ModlogType } from '../../lib/models'; +import { Guild, ModLog, ModLogType } from '../../lib/models'; export default class WarnCommand extends BushCommand { public constructor() { @@ -36,11 +36,11 @@ export default class WarnCommand extends BushCommand { } }); try { - const entry = Modlog.build({ + const entry = ModLog.build({ user: member.id, guild: message.guild.id, moderator: message.author.id, - type: ModlogType.WARN, + type: ModLogType.WARN, reason }); await entry.save(); |