diff --git a/src/data/GuildActions.ts b/src/data/GuildActions.ts index 2a8ceebd..5e874419 100644 --- a/src/data/GuildActions.ts +++ b/src/data/GuildActions.ts @@ -1,24 +1,76 @@ import { BaseRepository } from "./BaseRepository"; +import { Member, TextableChannel } from "eris"; +import { CaseTypes } from "./CaseTypes"; -type ActionFn = (...args: any[]) => any | Promise; +type KnownActions = "mute" | "unmute"; + +// https://github.com/Microsoft/TypeScript/issues/4183#issuecomment-382867018 +type UnknownAction = T extends KnownActions ? never : T; + +type ActionFn = (args: T) => any | Promise; + +type MuteActionArgs = { member: Member; muteTime?: number; reason?: string }; +type UnmuteActionArgs = { member: Member; unmuteTime?: number; reason?: string }; +type CreateCaseActionArgs = { + userId: string; + modId: string; + type: CaseTypes; + auditLogId?: string; + reason?: string; + automatic?: boolean; + postInCaseLog?: boolean; + ppId?: string; +}; +type CreateCaseNoteActionArgs = { + caseId: number; + modId: string; + note: string; + automatic?: boolean; + postInCaseLog?: boolean; +}; +type PostCaseActionArgs = { + caseId: number; + channel: TextableChannel; +}; export class GuildActions extends BaseRepository { - private actions: Map; + private actions: Map>; constructor(guildId) { super(guildId); this.actions = new Map(); } - public register(actionName: string, actionFn: ActionFn) { + public register(actionName: "mute", actionFn: ActionFn): void; + public register(actionName: "unmute", actionFn: ActionFn): void; + public register(actionName: "createCase", actionFn: ActionFn): void; + public register(actionName: "createCaseNote", actionFn: ActionFn): void; + public register(actionName: "postCase", actionFn: ActionFn): void; + // https://github.com/Microsoft/TypeScript/issues/4183#issuecomment-382867018 + public register, U extends string = T>( + actionName: T, + actionFn: ActionFn, + ): void; + public register(actionName, actionFn): void { + if (this.actions.has(actionName)) { + throw new Error("Action is already registered!"); + } + this.actions.set(actionName, actionFn); } - public unregister(actionName: string) { + public unregister(actionName: string): void { this.actions.delete(actionName); } - public fire(actionName: string, ...args: any[]): Promise { - return this.actions.has(actionName) ? this.actions.get(actionName)(...args) : null; + public fire(actionName: "mute", args: MuteActionArgs): Promise; + public fire(actionName: "unmute", args: UnmuteActionArgs): Promise; + public fire(actionName: "createCase", args: CreateCaseActionArgs): Promise; + public fire(actionName: "createCaseNote", args: CreateCaseNoteActionArgs): Promise; + public fire(actionName: "postCase", args: PostCaseActionArgs): Promise; + // https://github.com/Microsoft/TypeScript/issues/4183#issuecomment-382867018 + public fire, U extends string = T>(actionName: T, args: any): Promise; + public fire(actionName, args): Promise { + return this.actions.has(actionName) ? this.actions.get(actionName)(args) : null; } } diff --git a/src/plugins/Cases.ts b/src/plugins/Cases.ts index 07ec44f3..8bdf0cbc 100644 --- a/src/plugins/Cases.ts +++ b/src/plugins/Cases.ts @@ -19,8 +19,8 @@ export class CasesPlugin extends ZeppelinPlugin { return { config: { log_automatic_actions: true, - case_log_channel: null - } + case_log_channel: null, + }, }; } @@ -38,16 +38,16 @@ export class CasesPlugin extends ZeppelinPlugin { args.reason, args.automatic, args.postInCaseLog, - args.ppId + args.ppId, ); }); - this.actions.register("createCaseNote", (caseOrCaseId, args) => { - return this.createCaseNote(caseOrCaseId, args.modId, args.note, args.automatic, args.postInCaseLog); + this.actions.register("createCaseNote", args => { + return this.createCaseNote(args.caseId, args.modId, args.note, args.automatic, args.postInCaseLog); }); this.actions.register("postCase", async args => { - const embed = await this.getCaseEmbed(args.case || args.caseId); + const embed = await this.getCaseEmbed(args.caseId); return (args.channel as TextableChannel).createMessage(embed); }); } @@ -74,7 +74,7 @@ export class CasesPlugin extends ZeppelinPlugin { reason: string = null, automatic = false, postInCaseLogOverride = null, - ppId = null + ppId = null, ): Promise { const user = this.bot.users.get(userId); const userName = user ? `${user.username}#${user.discriminator}` : "Unknown#0000"; @@ -96,7 +96,7 @@ export class CasesPlugin extends ZeppelinPlugin { mod_name: modName, audit_log_id: auditLogId, pp_id: ppId, - pp_name: ppName + pp_name: ppName, }); if (reason) { @@ -124,7 +124,7 @@ export class CasesPlugin extends ZeppelinPlugin { modId: string, body: string, automatic = false, - postInCaseLogOverride = null + postInCaseLogOverride = null, ): Promise { const mod = this.bot.users.get(modId); const modName = mod ? `${mod.username}#${mod.discriminator}` : "Unknown#0000"; @@ -137,14 +137,14 @@ export class CasesPlugin extends ZeppelinPlugin { await this.cases.createNote(theCase.id, { mod_id: modId, mod_name: modName, - body: body || "" + body: body || "", }); if (theCase.mod_id == null) { // If the case has no moderator information, assume the first one to add a note to it did the action await this.cases.update(theCase.id, { mod_id: modId, - mod_name: modName + mod_name: modName, }); } @@ -174,20 +174,20 @@ export class CasesPlugin extends ZeppelinPlugin { const embed: any = { title: `${actionTypeStr} - Case #${theCase.case_number}`, footer: { - text: `Case created at ${createdAt.format("YYYY-MM-DD [at] HH:mm")}` + text: `Case created at ${createdAt.format("YYYY-MM-DD [at] HH:mm")}`, }, fields: [ { name: "User", value: `${theCase.user_name}\n<@!${theCase.user_id}>`, - inline: true + inline: true, }, { name: "Moderator", value: `${theCase.mod_name}\n<@!${theCase.mod_id}>`, - inline: true - } - ] + inline: true, + }, + ], }; if (theCase.pp_id) { @@ -207,13 +207,13 @@ export class CasesPlugin extends ZeppelinPlugin { const noteDate = moment(note.created_at); embed.fields.push({ name: `${note.mod_name} at ${noteDate.format("YYYY-MM-DD [at] HH:mm")}:`, - value: note.body + value: note.body, }); }); } else { embed.fields.push({ name: "!!! THIS CASE HAS NO NOTES !!!", - value: "\u200B" + value: "\u200B", }); } diff --git a/src/plugins/ModActions.ts b/src/plugins/ModActions.ts index c9a81785..33d8bae5 100644 --- a/src/plugins/ModActions.ts +++ b/src/plugins/ModActions.ts @@ -12,7 +12,7 @@ import { formatTemplateString, stripObjectToScalars, successMessage, - trimLines + trimLines, } from "../utils"; import { GuildMutes } from "../data/GuildMutes"; import { CaseTypes } from "../data/CaseTypes"; @@ -27,7 +27,7 @@ import { Mute } from "../data/entities/Mute"; enum IgnoredEventType { Ban = 1, Unban, - Kick + Kick, } interface IIgnoredEvent { @@ -74,7 +74,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { kick_message: "You have been kicked from {guildName}. Reason given: {reason}", ban_message: "You have been banned from {guildName}. Reason given: {reason}", alert_on_rejoin: false, - alert_channel: null + alert_channel: null, }, permissions: { note: false, @@ -86,7 +86,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { addcase: false, massban: true, hidecase: false, - act_as_other: false + act_as_other: false, }, overrides: [ { @@ -98,18 +98,18 @@ export class ModActionsPlugin extends ZeppelinPlugin { kick: true, ban: true, view: true, - addcase: true - } + addcase: true, + }, }, { level: ">=100", permissions: { massban: true, hidecase: true, - act_as_other: true - } - } - ] + act_as_other: true, + }, + }, + ], }; } @@ -145,7 +145,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { const relevantAuditLogEntry = await findRelevantAuditLogEntry( this.guild, ErisConstants.AuditLogActions.MEMBER_BAN_ADD, - user.id + user.id, ); if (relevantAuditLogEntry) { @@ -158,12 +158,12 @@ export class ModActionsPlugin extends ZeppelinPlugin { type: CaseTypes.Ban, auditLogId, reason: relevantAuditLogEntry.reason, - automatic: true + automatic: true, }); } else { this.actions.fire("createCase", { userId: user.id, - type: CaseTypes.Ban + type: CaseTypes.Ban, }); } } @@ -183,7 +183,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { const relevantAuditLogEntry = await findRelevantAuditLogEntry( this.guild, ErisConstants.AuditLogActions.MEMBER_BAN_REMOVE, - user.id + user.id, ); if (relevantAuditLogEntry) { @@ -195,13 +195,13 @@ export class ModActionsPlugin extends ZeppelinPlugin { modId, type: CaseTypes.Unban, auditLogId, - automatic: true + automatic: true, }); } else { this.actions.fire("createCase", { userId: user.id, type: CaseTypes.Unban, - automatic: true + automatic: true, }); } } @@ -223,7 +223,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { alertChannel.send( `<@!${member.id}> (${member.user.username}#${member.user.discriminator} \`${member.id}\`) joined with ${ actions.length - } prior record(s)` + } prior record(s)`, ); } } @@ -239,7 +239,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { const kickAuditLogEntry = await findRelevantAuditLogEntry( this.guild, ErisConstants.AuditLogActions.MEMBER_KICK, - member.id + member.id, ); if (kickAuditLogEntry) { @@ -249,12 +249,12 @@ export class ModActionsPlugin extends ZeppelinPlugin { type: CaseTypes.Kick, auditLogId: kickAuditLogEntry.id, reason: kickAuditLogEntry.reason, - automatic: true + automatic: true, }); this.serverLogs.log(LogType.MEMBER_KICK, { user: stripObjectToScalars(member.user), - mod: stripObjectToScalars(kickAuditLogEntry.user) + mod: stripObjectToScalars(kickAuditLogEntry.user), }); } } @@ -271,9 +271,10 @@ export class ModActionsPlugin extends ZeppelinPlugin { return; } - await this.actions.fire("createCaseNote", theCase, { + await this.actions.fire("createCaseNote", { + caseId: theCase.id, modId: msg.author.id, - note: args.note + note: args.note, }); msg.channel.createMessage(successMessage(`Case \`#${theCase.case_number}\` updated`)); @@ -289,14 +290,14 @@ export class ModActionsPlugin extends ZeppelinPlugin { userId: args.userId, modId: msg.author.id, type: CaseTypes.Note, - reason: args.note + reason: args.note, }); msg.channel.createMessage(successMessage(`Note added on **${userName}** (Case #${createdCase.case_number})`)); } @d.command("warn", " ", { - options: [{ name: "mod", type: "member" }] + options: [{ name: "mod", type: "member" }], }) @d.permission("warn") @d.nonBlocking() @@ -326,7 +327,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { args.member.user, warnMessage, this.configValue("dm_on_warn"), - this.configValue("message_on_warn") + this.configValue("message_on_warn"), ); if (!messageSent) { @@ -343,23 +344,23 @@ export class ModActionsPlugin extends ZeppelinPlugin { modId: mod.id, type: CaseTypes.Warn, reason: args.reason, - ppId: mod.id !== msg.author.id ? msg.author.id : null + ppId: mod.id !== msg.author.id ? msg.author.id : null, }); msg.channel.createMessage( successMessage( - `Warned **${args.member.user.username}#${args.member.user.discriminator}** (Case #${createdCase.case_number})` - ) + `Warned **${args.member.user.username}#${args.member.user.discriminator}** (Case #${createdCase.case_number})`, + ), ); this.serverLogs.log(LogType.MEMBER_WARN, { mod: stripObjectToScalars(mod.user), - member: stripObjectToScalars(args.member, ["user"]) + member: stripObjectToScalars(args.member, ["user"]), }); } @d.command("mute", " [time:string] [reason:string$]", { - options: [{ name: "mod", type: "member" }] + options: [{ name: "mod", type: "member" }], }) @d.permission("mute") async muteCmd(msg: Message, args: { member: Member; time: string; reason: string; mod: Member }) { @@ -395,7 +396,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { this.serverLogs.ignoreLog(LogType.MEMBER_ROLE_ADD, args.member.id); const mute: Mute = await this.actions.fire("mute", { member: args.member, - muteTime + muteTime, }); if (!mute) { @@ -412,9 +413,10 @@ export class ModActionsPlugin extends ZeppelinPlugin { if (args.reason) { // Update old case - await this.actions.fire("createCaseNote", mute.case_id, { + await this.actions.fire("createCaseNote", { + caseId: mute.case_id, modId: mod.id, - note: args.reason + note: args.reason, }); } } else { @@ -424,7 +426,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { modId: mod.id, type: CaseTypes.Mute, reason: args.reason, - ppId: mod.id !== msg.author.id ? msg.author.id : null + ppId: mod.id !== msg.author.id ? msg.author.id : null, }); await this.mutes.setCaseId(args.member.id, theCase.id); } @@ -437,14 +439,14 @@ export class ModActionsPlugin extends ZeppelinPlugin { const muteMessage = formatTemplateString(template, { guildName: this.guild.name, reason: args.reason, - time: timeUntilUnmute + time: timeUntilUnmute, }); messageSent = await this.tryToMessageUser( args.member.user, muteMessage, this.configValue("dm_on_mute"), - this.configValue("message_on_mute") + this.configValue("message_on_mute"), ); } @@ -468,18 +470,18 @@ export class ModActionsPlugin extends ZeppelinPlugin { this.serverLogs.log(LogType.MEMBER_TIMED_MUTE, { mod: stripObjectToScalars(mod.user), member: stripObjectToScalars(args.member, ["user"]), - time: timeUntilUnmute + time: timeUntilUnmute, }); } else { this.serverLogs.log(LogType.MEMBER_MUTE, { mod: stripObjectToScalars(mod.user), - member: stripObjectToScalars(args.member, ["user"]) + member: stripObjectToScalars(args.member, ["user"]), }); } } @d.command("unmute", " [time:string] [reason:string$]", { - options: [{ name: "mod", type: "member" }] + options: [{ name: "mod", type: "member" }], }) @d.permission("mute") async unmuteCmd(msg: Message, args: any) { @@ -521,7 +523,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { modId: mod.id, type: CaseTypes.Unmute, reason: args.reason, - ppId: mod.id !== msg.author.id ? msg.author.id : null + ppId: mod.id !== msg.author.id ? msg.author.id : null, }); if (unmuteTime) { @@ -535,15 +537,15 @@ export class ModActionsPlugin extends ZeppelinPlugin { successMessage( `Unmuting **${args.member.user.username}#${args.member.user.discriminator}** in ${timeUntilUnmute} (Case #${ createdCase.case_number - })` - ) + })`, + ), ); // Log the action this.serverLogs.log(LogType.MEMBER_TIMED_UNMUTE, { mod: stripObjectToScalars(mod.user), member: stripObjectToScalars(args.member, ["user"]), - time: timeUntilUnmute + time: timeUntilUnmute, }); } else { // Otherwise remove "muted" role immediately @@ -555,26 +557,20 @@ export class ModActionsPlugin extends ZeppelinPlugin { successMessage( `Unmuted **${args.member.user.username}#${args.member.user.discriminator}** (Case #${ createdCase.case_number - })` - ) + })`, + ), ); // Log the action this.serverLogs.log(LogType.MEMBER_UNMUTE, { mod: stripObjectToScalars(msg.member.user), - member: stripObjectToScalars(args.member, ["user"]) + member: stripObjectToScalars(args.member, ["user"]), }); } } - @d.command("mutes") - @d.permission("view") - async mutesCmd(msg: Message) { - this.actions.fire("postMuteList", msg.channel); - } - @d.command("kick", " [reason:string$]", { - options: [{ name: "mod", type: "member" }] + options: [{ name: "mod", type: "member" }], }) @d.permission("kick") async kickCmd(msg, args: { member: Member; reason: string; mod: Member }) { @@ -600,14 +596,14 @@ export class ModActionsPlugin extends ZeppelinPlugin { if (args.reason) { const kickMessage = formatTemplateString(this.configValue("kick_message"), { guildName: this.guild.name, - reason: args.reason + reason: args.reason, }); messageSent = await this.tryToMessageUser( args.member.user, kickMessage, this.configValue("dm_on_kick"), - this.configValue("message_on_kick") + this.configValue("message_on_kick"), ); } @@ -622,7 +618,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { modId: mod.id, type: CaseTypes.Kick, reason: args.reason, - ppId: mod.id !== msg.author.id ? msg.author.id : null + ppId: mod.id !== msg.author.id ? msg.author.id : null, }); // Confirm the action to the moderator @@ -635,12 +631,12 @@ export class ModActionsPlugin extends ZeppelinPlugin { // Log the action this.serverLogs.log(LogType.MEMBER_KICK, { mod: stripObjectToScalars(mod.user), - user: stripObjectToScalars(args.member.user) + user: stripObjectToScalars(args.member.user), }); } @d.command("ban", " [reason:string$]", { - options: [{ name: "mod", type: "member" }] + options: [{ name: "mod", type: "member" }], }) @d.permission("ban") async banCmd(msg, args) { @@ -666,14 +662,14 @@ export class ModActionsPlugin extends ZeppelinPlugin { if (args.reason) { const banMessage = formatTemplateString(this.configValue("ban_message"), { guildName: this.guild.name, - reason: args.reason + reason: args.reason, }); messageSent = await this.tryToMessageUser( args.member.user, banMessage, this.configValue("dm_on_ban"), - this.configValue("message_on_ban") + this.configValue("message_on_ban"), ); } @@ -688,7 +684,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { modId: mod.id, type: CaseTypes.Ban, reason: args.reason, - ppId: mod.id !== msg.author.id ? msg.author.id : null + ppId: mod.id !== msg.author.id ? msg.author.id : null, }); // Confirm the action to the moderator @@ -701,12 +697,12 @@ export class ModActionsPlugin extends ZeppelinPlugin { // Log the action this.serverLogs.log(LogType.MEMBER_BAN, { mod: stripObjectToScalars(mod.user), - member: stripObjectToScalars(args.member, ["user"]) + member: stripObjectToScalars(args.member, ["user"]), }); } @d.command("softban", " [reason:string$]", { - options: [{ name: "mod", type: "member" }] + options: [{ name: "mod", type: "member" }], }) @d.permission("ban") async softbanCmd(msg, args) { @@ -742,7 +738,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { modId: mod.id, type: CaseTypes.Softban, reason: args.reason, - ppId: mod.id !== msg.author.id ? msg.author.id : null + ppId: mod.id !== msg.author.id ? msg.author.id : null, }); // Confirm the action to the moderator @@ -750,19 +746,19 @@ export class ModActionsPlugin extends ZeppelinPlugin { successMessage( `Softbanned **${args.member.user.username}#${args.member.user.discriminator}** (Case #${ createdCase.case_number - })` - ) + })`, + ), ); // Log the action this.serverLogs.log(LogType.MEMBER_SOFTBAN, { mod: stripObjectToScalars(mod.user), - member: stripObjectToScalars(args.member, ["user"]) + member: stripObjectToScalars(args.member, ["user"]), }); } @d.command("unban", " [reason:string$]", { - options: [{ name: "mod", type: "member" }] + options: [{ name: "mod", type: "member" }], }) @d.permission("ban") async unbanCmd(msg: Message, args: { userId: string; reason: string; mod: Member }) { @@ -793,7 +789,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { modId: mod.id, type: CaseTypes.Unban, reason: args.reason, - ppId: mod.id !== msg.author.id ? msg.author.id : null + ppId: mod.id !== msg.author.id ? msg.author.id : null, }); // Confirm the action @@ -802,12 +798,12 @@ export class ModActionsPlugin extends ZeppelinPlugin { // Log the action this.serverLogs.log(LogType.MEMBER_UNBAN, { mod: stripObjectToScalars(mod.user), - userId: args.userId + userId: args.userId, }); } @d.command("forceban", " [reason:string$]", { - options: [{ name: "mod", type: "member" }] + options: [{ name: "mod", type: "member" }], }) @d.permission("ban") async forcebanCmd(msg: Message, args: any) { @@ -845,7 +841,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { modId: mod.id, type: CaseTypes.Ban, reason: args.reason, - ppId: mod.id !== msg.author.id ? msg.author.id : null + ppId: mod.id !== msg.author.id ? msg.author.id : null, }); // Confirm the action @@ -854,7 +850,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { // Log the action this.serverLogs.log(LogType.MEMBER_FORCEBAN, { mod: stripObjectToScalars(mod.user), - userId: args.userId + userId: args.userId, }); } @@ -909,7 +905,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { modId: msg.author.id, type: CaseTypes.Ban, reason: `Mass ban: ${banReason}`, - postInCaseLog: false + postInCaseLog: false, }); } catch (e) { failedBans.push(userId); @@ -927,12 +923,12 @@ export class ModActionsPlugin extends ZeppelinPlugin { // Some or all bans were successful. Create a log entry for the mass ban and notify the user. this.serverLogs.log(LogType.MASSBAN, { mod: stripObjectToScalars(msg.author), - count: successfulBanCount + count: successfulBanCount, }); if (failedBans.length) { msg.channel.createMessage( - successMessage(`Banned ${successfulBanCount} users, ${failedBans.length} failed: ${failedBans.join(" ")}`) + successMessage(`Banned ${successfulBanCount} users, ${failedBans.length} failed: ${failedBans.join(" ")}`), ); } else { msg.channel.createMessage(successMessage(`Banned ${successfulBanCount} users successfully`)); @@ -941,7 +937,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { } @d.command("addcase", " [reason:string$]", { - options: [{ name: "mod", type: "member" }] + options: [{ name: "mod", type: "member" }], }) @d.permission("addcase") async addcaseCmd(msg: Message, args: any) { @@ -982,7 +978,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { modId: mod.id, type: CaseTypes[type], reason: args.reason, - ppId: mod.id !== msg.author.id ? msg.author.id : null + ppId: mod.id !== msg.author.id ? msg.author.id : null, }); msg.channel.createMessage(successMessage(`Case #${theCase.case_number} created`)); @@ -992,7 +988,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { mod: stripObjectToScalars(mod.user), userId: args.userId, caseNum: theCase.case_number, - caseType: type.toUpperCase() + caseType: type.toUpperCase(), }); } @@ -1014,7 +1010,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { await this.actions.fire("postCase", { caseId: theCase.id, - channel: msg.channel + channel: msg.channel, }); } @@ -1045,7 +1041,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { for (const theCase of casesToDisplay) { await this.actions.fire("postCase", { caseId: theCase.id, - channel: msg.channel + channel: msg.channel, }); } } else { @@ -1089,7 +1085,7 @@ export class ModActionsPlugin extends ZeppelinPlugin { await this.cases.setHidden(theCase.id, true); msg.channel.createMessage( - successMessage(`Case #${theCase.case_number} is now hidden! Use \`unhidecase\` to unhide it.`) + successMessage(`Case #${theCase.case_number} is now hidden! Use \`unhidecase\` to unhide it.`), ); } diff --git a/src/plugins/Mutes.ts b/src/plugins/Mutes.ts index 601df364..3f64de7a 100644 --- a/src/plugins/Mutes.ts +++ b/src/plugins/Mutes.ts @@ -22,19 +22,26 @@ export class MutesPlugin extends ZeppelinPlugin { getDefaultOptions() { return { config: { - mute_role: null + mute_role: null, }, permissions: { - cleanup: false + view_list: false, + cleanup: false, }, overrides: [ + { + level: ">=50", + permissions: { + view_list: true, + }, + }, { level: ">=100", permissions: { - cleanup: true - } - } - ] + cleanup: true, + }, + }, + ], }; } @@ -50,7 +57,6 @@ export class MutesPlugin extends ZeppelinPlugin { this.actions.register("unmute", args => { return this.unmuteMember(args.member, args.unmuteTime); }); - this.actions.register("postMuteList", this.postMuteList.bind(this)); // Check for expired mutes every 5s this.clearExpiredMutes(); @@ -60,7 +66,6 @@ export class MutesPlugin extends ZeppelinPlugin { onUnload() { this.actions.unregister("mute"); this.actions.unregister("unmute"); - this.actions.unregister("postMuteList"); clearInterval(this.muteClearIntervalId); } @@ -86,7 +91,9 @@ export class MutesPlugin extends ZeppelinPlugin { } } - public async postMuteList(channel: TextableChannel) { + @d.command("mutes") + @d.permission("view_list") + public async postMuteList(msg: Message) { const lines = []; // Active, logged mutes @@ -108,24 +115,25 @@ export class MutesPlugin extends ZeppelinPlugin { ...activeMutes.map(mute => { const user = this.bot.users.get(mute.user_id); const username = user ? `${user.username}#${user.discriminator}` : "Unknown#0000"; - const theCase = muteCasesById[mute.case_id] || null; + const theCase = muteCasesById.get(mute.case_id); const caseName = theCase ? `Case #${theCase.case_number}` : "No case"; - let line = `\`${caseName}\` **${username}** (\`${mute.user_id}\`)`; + let line = `**${username}** (\`${mute.user_id}\`) 📔 ${caseName}`; if (mute.expires_at) { const timeUntilExpiry = moment().diff(moment(mute.expires_at, DBDateFormat)); const humanizedTime = humanizeDuration(timeUntilExpiry, { largest: 2, round: true }); - line += ` (expires in ${humanizedTime})`; + line += ` ⏰ Expires in ${humanizedTime}`; } else { - line += ` (doesn't expire)`; + line += ` ⏰ Doesn't expire`; } - const mutedAt = moment(mute.created_at, DBDateFormat); - line += ` (muted at ${mutedAt.format("YYYY-MM-DD HH:mm:ss")})`; + const timeFromMute = moment(mute.created_at, DBDateFormat).diff(moment()); + const humanizedTimeFromMute = humanizeDuration(timeFromMute, { largest: 2, round: true }); + line += ` 🕒 Muted ${humanizedTimeFromMute} ago`; return line; - }) + }), ); // Manually added mute roles @@ -143,13 +151,13 @@ export class MutesPlugin extends ZeppelinPlugin { lines.push( ...manuallyMutedMembers.map(member => { return `\`Manual mute\` **${member.user.username}#${member.user.discriminator}** (\`${member.id}\`)`; - }) + }), ); - const message = `Active mutes:\n\n${lines.join("\n")}`; + const message = `Active mutes (${activeMutes.length} total):\n\n${lines.join("\n")}`; const chunks = chunkMessageLines(message); for (const chunk of chunks) { - channel.createMessage(chunk); + msg.channel.createMessage(chunk); } } @@ -179,7 +187,7 @@ export class MutesPlugin extends ZeppelinPlugin { const bannedIds = bans.map(b => b.user.id); await msg.channel.createMessage( - `Found ${activeMutes.length} mutes and ${bannedIds.length} bans, cross-referencing...` + `Found ${activeMutes.length} mutes and ${bannedIds.length} bans, cross-referencing...`, ); let cleared = 0; @@ -262,7 +270,7 @@ export class MutesPlugin extends ZeppelinPlugin { await this.mutes.clear(member.id); this.serverLogs.log(LogType.MEMBER_MUTE_EXPIRED, { - member: stripObjectToScalars(member, ["user"]) + member: stripObjectToScalars(member, ["user"]), }); } }