3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-05-10 12:25:02 +00:00

GuildActions: create overloads for known actions; refactor certain actions, using only 1 args object; mutes: move !mutes to the Mutes plugin, fix case number not showing in mute list, make mute list prettier

This commit is contained in:
Dragory 2019-02-15 05:07:28 +02:00
parent bdc8b85955
commit 0b0bb05eed
4 changed files with 183 additions and 127 deletions

View file

@ -1,24 +1,76 @@
import { BaseRepository } from "./BaseRepository"; import { BaseRepository } from "./BaseRepository";
import { Member, TextableChannel } from "eris";
import { CaseTypes } from "./CaseTypes";
type ActionFn = (...args: any[]) => any | Promise<any>; type KnownActions = "mute" | "unmute";
// https://github.com/Microsoft/TypeScript/issues/4183#issuecomment-382867018
type UnknownAction<T extends string> = T extends KnownActions ? never : T;
type ActionFn<T> = (args: T) => any | Promise<any>;
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 { export class GuildActions extends BaseRepository {
private actions: Map<string, ActionFn>; private actions: Map<string, ActionFn<any>>;
constructor(guildId) { constructor(guildId) {
super(guildId); super(guildId);
this.actions = new Map(); this.actions = new Map();
} }
public register(actionName: string, actionFn: ActionFn) { public register(actionName: "mute", actionFn: ActionFn<MuteActionArgs>): void;
public register(actionName: "unmute", actionFn: ActionFn<UnmuteActionArgs>): void;
public register(actionName: "createCase", actionFn: ActionFn<CreateCaseActionArgs>): void;
public register(actionName: "createCaseNote", actionFn: ActionFn<CreateCaseNoteActionArgs>): void;
public register(actionName: "postCase", actionFn: ActionFn<PostCaseActionArgs>): void;
// https://github.com/Microsoft/TypeScript/issues/4183#issuecomment-382867018
public register<T extends string & UnknownAction<U>, U extends string = T>(
actionName: T,
actionFn: ActionFn<any>,
): void;
public register(actionName, actionFn): void {
if (this.actions.has(actionName)) {
throw new Error("Action is already registered!");
}
this.actions.set(actionName, actionFn); this.actions.set(actionName, actionFn);
} }
public unregister(actionName: string) { public unregister(actionName: string): void {
this.actions.delete(actionName); this.actions.delete(actionName);
} }
public fire(actionName: string, ...args: any[]): Promise<any> { public fire(actionName: "mute", args: MuteActionArgs): Promise<any>;
return this.actions.has(actionName) ? this.actions.get(actionName)(...args) : null; public fire(actionName: "unmute", args: UnmuteActionArgs): Promise<any>;
public fire(actionName: "createCase", args: CreateCaseActionArgs): Promise<any>;
public fire(actionName: "createCaseNote", args: CreateCaseNoteActionArgs): Promise<any>;
public fire(actionName: "postCase", args: PostCaseActionArgs): Promise<any>;
// https://github.com/Microsoft/TypeScript/issues/4183#issuecomment-382867018
public fire<T extends string & UnknownAction<U>, U extends string = T>(actionName: T, args: any): Promise<any>;
public fire(actionName, args): Promise<any> {
return this.actions.has(actionName) ? this.actions.get(actionName)(args) : null;
} }
} }

View file

@ -19,8 +19,8 @@ export class CasesPlugin extends ZeppelinPlugin {
return { return {
config: { config: {
log_automatic_actions: true, log_automatic_actions: true,
case_log_channel: null case_log_channel: null,
} },
}; };
} }
@ -38,16 +38,16 @@ export class CasesPlugin extends ZeppelinPlugin {
args.reason, args.reason,
args.automatic, args.automatic,
args.postInCaseLog, args.postInCaseLog,
args.ppId args.ppId,
); );
}); });
this.actions.register("createCaseNote", (caseOrCaseId, args) => { this.actions.register("createCaseNote", args => {
return this.createCaseNote(caseOrCaseId, args.modId, args.note, args.automatic, args.postInCaseLog); return this.createCaseNote(args.caseId, args.modId, args.note, args.automatic, args.postInCaseLog);
}); });
this.actions.register("postCase", async args => { 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); return (args.channel as TextableChannel).createMessage(embed);
}); });
} }
@ -74,7 +74,7 @@ export class CasesPlugin extends ZeppelinPlugin {
reason: string = null, reason: string = null,
automatic = false, automatic = false,
postInCaseLogOverride = null, postInCaseLogOverride = null,
ppId = null ppId = null,
): Promise<Case> { ): Promise<Case> {
const user = this.bot.users.get(userId); const user = this.bot.users.get(userId);
const userName = user ? `${user.username}#${user.discriminator}` : "Unknown#0000"; const userName = user ? `${user.username}#${user.discriminator}` : "Unknown#0000";
@ -96,7 +96,7 @@ export class CasesPlugin extends ZeppelinPlugin {
mod_name: modName, mod_name: modName,
audit_log_id: auditLogId, audit_log_id: auditLogId,
pp_id: ppId, pp_id: ppId,
pp_name: ppName pp_name: ppName,
}); });
if (reason) { if (reason) {
@ -124,7 +124,7 @@ export class CasesPlugin extends ZeppelinPlugin {
modId: string, modId: string,
body: string, body: string,
automatic = false, automatic = false,
postInCaseLogOverride = null postInCaseLogOverride = null,
): Promise<void> { ): Promise<void> {
const mod = this.bot.users.get(modId); const mod = this.bot.users.get(modId);
const modName = mod ? `${mod.username}#${mod.discriminator}` : "Unknown#0000"; const modName = mod ? `${mod.username}#${mod.discriminator}` : "Unknown#0000";
@ -137,14 +137,14 @@ export class CasesPlugin extends ZeppelinPlugin {
await this.cases.createNote(theCase.id, { await this.cases.createNote(theCase.id, {
mod_id: modId, mod_id: modId,
mod_name: modName, mod_name: modName,
body: body || "" body: body || "",
}); });
if (theCase.mod_id == null) { 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 // 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, { await this.cases.update(theCase.id, {
mod_id: modId, mod_id: modId,
mod_name: modName mod_name: modName,
}); });
} }
@ -174,20 +174,20 @@ export class CasesPlugin extends ZeppelinPlugin {
const embed: any = { const embed: any = {
title: `${actionTypeStr} - Case #${theCase.case_number}`, title: `${actionTypeStr} - Case #${theCase.case_number}`,
footer: { 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: [ fields: [
{ {
name: "User", name: "User",
value: `${theCase.user_name}\n<@!${theCase.user_id}>`, value: `${theCase.user_name}\n<@!${theCase.user_id}>`,
inline: true inline: true,
}, },
{ {
name: "Moderator", name: "Moderator",
value: `${theCase.mod_name}\n<@!${theCase.mod_id}>`, value: `${theCase.mod_name}\n<@!${theCase.mod_id}>`,
inline: true inline: true,
} },
] ],
}; };
if (theCase.pp_id) { if (theCase.pp_id) {
@ -207,13 +207,13 @@ export class CasesPlugin extends ZeppelinPlugin {
const noteDate = moment(note.created_at); const noteDate = moment(note.created_at);
embed.fields.push({ embed.fields.push({
name: `${note.mod_name} at ${noteDate.format("YYYY-MM-DD [at] HH:mm")}:`, name: `${note.mod_name} at ${noteDate.format("YYYY-MM-DD [at] HH:mm")}:`,
value: note.body value: note.body,
}); });
}); });
} else { } else {
embed.fields.push({ embed.fields.push({
name: "!!! THIS CASE HAS NO NOTES !!!", name: "!!! THIS CASE HAS NO NOTES !!!",
value: "\u200B" value: "\u200B",
}); });
} }

View file

@ -12,7 +12,7 @@ import {
formatTemplateString, formatTemplateString,
stripObjectToScalars, stripObjectToScalars,
successMessage, successMessage,
trimLines trimLines,
} from "../utils"; } from "../utils";
import { GuildMutes } from "../data/GuildMutes"; import { GuildMutes } from "../data/GuildMutes";
import { CaseTypes } from "../data/CaseTypes"; import { CaseTypes } from "../data/CaseTypes";
@ -27,7 +27,7 @@ import { Mute } from "../data/entities/Mute";
enum IgnoredEventType { enum IgnoredEventType {
Ban = 1, Ban = 1,
Unban, Unban,
Kick Kick,
} }
interface IIgnoredEvent { interface IIgnoredEvent {
@ -74,7 +74,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
kick_message: "You have been kicked from {guildName}. Reason given: {reason}", kick_message: "You have been kicked from {guildName}. Reason given: {reason}",
ban_message: "You have been banned from {guildName}. Reason given: {reason}", ban_message: "You have been banned from {guildName}. Reason given: {reason}",
alert_on_rejoin: false, alert_on_rejoin: false,
alert_channel: null alert_channel: null,
}, },
permissions: { permissions: {
note: false, note: false,
@ -86,7 +86,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
addcase: false, addcase: false,
massban: true, massban: true,
hidecase: false, hidecase: false,
act_as_other: false act_as_other: false,
}, },
overrides: [ overrides: [
{ {
@ -98,18 +98,18 @@ export class ModActionsPlugin extends ZeppelinPlugin {
kick: true, kick: true,
ban: true, ban: true,
view: true, view: true,
addcase: true addcase: true,
} },
}, },
{ {
level: ">=100", level: ">=100",
permissions: { permissions: {
massban: true, massban: true,
hidecase: true, hidecase: true,
act_as_other: true act_as_other: true,
} },
} },
] ],
}; };
} }
@ -145,7 +145,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
const relevantAuditLogEntry = await findRelevantAuditLogEntry( const relevantAuditLogEntry = await findRelevantAuditLogEntry(
this.guild, this.guild,
ErisConstants.AuditLogActions.MEMBER_BAN_ADD, ErisConstants.AuditLogActions.MEMBER_BAN_ADD,
user.id user.id,
); );
if (relevantAuditLogEntry) { if (relevantAuditLogEntry) {
@ -158,12 +158,12 @@ export class ModActionsPlugin extends ZeppelinPlugin {
type: CaseTypes.Ban, type: CaseTypes.Ban,
auditLogId, auditLogId,
reason: relevantAuditLogEntry.reason, reason: relevantAuditLogEntry.reason,
automatic: true automatic: true,
}); });
} else { } else {
this.actions.fire("createCase", { this.actions.fire("createCase", {
userId: user.id, userId: user.id,
type: CaseTypes.Ban type: CaseTypes.Ban,
}); });
} }
} }
@ -183,7 +183,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
const relevantAuditLogEntry = await findRelevantAuditLogEntry( const relevantAuditLogEntry = await findRelevantAuditLogEntry(
this.guild, this.guild,
ErisConstants.AuditLogActions.MEMBER_BAN_REMOVE, ErisConstants.AuditLogActions.MEMBER_BAN_REMOVE,
user.id user.id,
); );
if (relevantAuditLogEntry) { if (relevantAuditLogEntry) {
@ -195,13 +195,13 @@ export class ModActionsPlugin extends ZeppelinPlugin {
modId, modId,
type: CaseTypes.Unban, type: CaseTypes.Unban,
auditLogId, auditLogId,
automatic: true automatic: true,
}); });
} else { } else {
this.actions.fire("createCase", { this.actions.fire("createCase", {
userId: user.id, userId: user.id,
type: CaseTypes.Unban, type: CaseTypes.Unban,
automatic: true automatic: true,
}); });
} }
} }
@ -223,7 +223,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
alertChannel.send( alertChannel.send(
`<@!${member.id}> (${member.user.username}#${member.user.discriminator} \`${member.id}\`) joined with ${ `<@!${member.id}> (${member.user.username}#${member.user.discriminator} \`${member.id}\`) joined with ${
actions.length actions.length
} prior record(s)` } prior record(s)`,
); );
} }
} }
@ -239,7 +239,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
const kickAuditLogEntry = await findRelevantAuditLogEntry( const kickAuditLogEntry = await findRelevantAuditLogEntry(
this.guild, this.guild,
ErisConstants.AuditLogActions.MEMBER_KICK, ErisConstants.AuditLogActions.MEMBER_KICK,
member.id member.id,
); );
if (kickAuditLogEntry) { if (kickAuditLogEntry) {
@ -249,12 +249,12 @@ export class ModActionsPlugin extends ZeppelinPlugin {
type: CaseTypes.Kick, type: CaseTypes.Kick,
auditLogId: kickAuditLogEntry.id, auditLogId: kickAuditLogEntry.id,
reason: kickAuditLogEntry.reason, reason: kickAuditLogEntry.reason,
automatic: true automatic: true,
}); });
this.serverLogs.log(LogType.MEMBER_KICK, { this.serverLogs.log(LogType.MEMBER_KICK, {
user: stripObjectToScalars(member.user), user: stripObjectToScalars(member.user),
mod: stripObjectToScalars(kickAuditLogEntry.user) mod: stripObjectToScalars(kickAuditLogEntry.user),
}); });
} }
} }
@ -271,9 +271,10 @@ export class ModActionsPlugin extends ZeppelinPlugin {
return; return;
} }
await this.actions.fire("createCaseNote", theCase, { await this.actions.fire("createCaseNote", {
caseId: theCase.id,
modId: msg.author.id, modId: msg.author.id,
note: args.note note: args.note,
}); });
msg.channel.createMessage(successMessage(`Case \`#${theCase.case_number}\` updated`)); msg.channel.createMessage(successMessage(`Case \`#${theCase.case_number}\` updated`));
@ -289,14 +290,14 @@ export class ModActionsPlugin extends ZeppelinPlugin {
userId: args.userId, userId: args.userId,
modId: msg.author.id, modId: msg.author.id,
type: CaseTypes.Note, type: CaseTypes.Note,
reason: args.note reason: args.note,
}); });
msg.channel.createMessage(successMessage(`Note added on **${userName}** (Case #${createdCase.case_number})`)); msg.channel.createMessage(successMessage(`Note added on **${userName}** (Case #${createdCase.case_number})`));
} }
@d.command("warn", "<member:Member> <reason:string$>", { @d.command("warn", "<member:Member> <reason:string$>", {
options: [{ name: "mod", type: "member" }] options: [{ name: "mod", type: "member" }],
}) })
@d.permission("warn") @d.permission("warn")
@d.nonBlocking() @d.nonBlocking()
@ -326,7 +327,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
args.member.user, args.member.user,
warnMessage, warnMessage,
this.configValue("dm_on_warn"), this.configValue("dm_on_warn"),
this.configValue("message_on_warn") this.configValue("message_on_warn"),
); );
if (!messageSent) { if (!messageSent) {
@ -343,23 +344,23 @@ export class ModActionsPlugin extends ZeppelinPlugin {
modId: mod.id, modId: mod.id,
type: CaseTypes.Warn, type: CaseTypes.Warn,
reason: args.reason, 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( msg.channel.createMessage(
successMessage( 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, { this.serverLogs.log(LogType.MEMBER_WARN, {
mod: stripObjectToScalars(mod.user), mod: stripObjectToScalars(mod.user),
member: stripObjectToScalars(args.member, ["user"]) member: stripObjectToScalars(args.member, ["user"]),
}); });
} }
@d.command("mute", "<member:Member> [time:string] [reason:string$]", { @d.command("mute", "<member:Member> [time:string] [reason:string$]", {
options: [{ name: "mod", type: "member" }] options: [{ name: "mod", type: "member" }],
}) })
@d.permission("mute") @d.permission("mute")
async muteCmd(msg: Message, args: { member: Member; time: string; reason: string; mod: Member }) { 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); this.serverLogs.ignoreLog(LogType.MEMBER_ROLE_ADD, args.member.id);
const mute: Mute = await this.actions.fire("mute", { const mute: Mute = await this.actions.fire("mute", {
member: args.member, member: args.member,
muteTime muteTime,
}); });
if (!mute) { if (!mute) {
@ -412,9 +413,10 @@ export class ModActionsPlugin extends ZeppelinPlugin {
if (args.reason) { if (args.reason) {
// Update old case // Update old case
await this.actions.fire("createCaseNote", mute.case_id, { await this.actions.fire("createCaseNote", {
caseId: mute.case_id,
modId: mod.id, modId: mod.id,
note: args.reason note: args.reason,
}); });
} }
} else { } else {
@ -424,7 +426,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
modId: mod.id, modId: mod.id,
type: CaseTypes.Mute, type: CaseTypes.Mute,
reason: args.reason, 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); await this.mutes.setCaseId(args.member.id, theCase.id);
} }
@ -437,14 +439,14 @@ export class ModActionsPlugin extends ZeppelinPlugin {
const muteMessage = formatTemplateString(template, { const muteMessage = formatTemplateString(template, {
guildName: this.guild.name, guildName: this.guild.name,
reason: args.reason, reason: args.reason,
time: timeUntilUnmute time: timeUntilUnmute,
}); });
messageSent = await this.tryToMessageUser( messageSent = await this.tryToMessageUser(
args.member.user, args.member.user,
muteMessage, muteMessage,
this.configValue("dm_on_mute"), 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, { this.serverLogs.log(LogType.MEMBER_TIMED_MUTE, {
mod: stripObjectToScalars(mod.user), mod: stripObjectToScalars(mod.user),
member: stripObjectToScalars(args.member, ["user"]), member: stripObjectToScalars(args.member, ["user"]),
time: timeUntilUnmute time: timeUntilUnmute,
}); });
} else { } else {
this.serverLogs.log(LogType.MEMBER_MUTE, { this.serverLogs.log(LogType.MEMBER_MUTE, {
mod: stripObjectToScalars(mod.user), mod: stripObjectToScalars(mod.user),
member: stripObjectToScalars(args.member, ["user"]) member: stripObjectToScalars(args.member, ["user"]),
}); });
} }
} }
@d.command("unmute", "<member:Member> [time:string] [reason:string$]", { @d.command("unmute", "<member:Member> [time:string] [reason:string$]", {
options: [{ name: "mod", type: "member" }] options: [{ name: "mod", type: "member" }],
}) })
@d.permission("mute") @d.permission("mute")
async unmuteCmd(msg: Message, args: any) { async unmuteCmd(msg: Message, args: any) {
@ -521,7 +523,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
modId: mod.id, modId: mod.id,
type: CaseTypes.Unmute, type: CaseTypes.Unmute,
reason: args.reason, 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) { if (unmuteTime) {
@ -535,15 +537,15 @@ export class ModActionsPlugin extends ZeppelinPlugin {
successMessage( successMessage(
`Unmuting **${args.member.user.username}#${args.member.user.discriminator}** in ${timeUntilUnmute} (Case #${ `Unmuting **${args.member.user.username}#${args.member.user.discriminator}** in ${timeUntilUnmute} (Case #${
createdCase.case_number createdCase.case_number
})` })`,
) ),
); );
// Log the action // Log the action
this.serverLogs.log(LogType.MEMBER_TIMED_UNMUTE, { this.serverLogs.log(LogType.MEMBER_TIMED_UNMUTE, {
mod: stripObjectToScalars(mod.user), mod: stripObjectToScalars(mod.user),
member: stripObjectToScalars(args.member, ["user"]), member: stripObjectToScalars(args.member, ["user"]),
time: timeUntilUnmute time: timeUntilUnmute,
}); });
} else { } else {
// Otherwise remove "muted" role immediately // Otherwise remove "muted" role immediately
@ -555,26 +557,20 @@ export class ModActionsPlugin extends ZeppelinPlugin {
successMessage( successMessage(
`Unmuted **${args.member.user.username}#${args.member.user.discriminator}** (Case #${ `Unmuted **${args.member.user.username}#${args.member.user.discriminator}** (Case #${
createdCase.case_number createdCase.case_number
})` })`,
) ),
); );
// Log the action // Log the action
this.serverLogs.log(LogType.MEMBER_UNMUTE, { this.serverLogs.log(LogType.MEMBER_UNMUTE, {
mod: stripObjectToScalars(msg.member.user), 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", "<member:Member> [reason:string$]", { @d.command("kick", "<member:Member> [reason:string$]", {
options: [{ name: "mod", type: "member" }] options: [{ name: "mod", type: "member" }],
}) })
@d.permission("kick") @d.permission("kick")
async kickCmd(msg, args: { member: Member; reason: string; mod: Member }) { async kickCmd(msg, args: { member: Member; reason: string; mod: Member }) {
@ -600,14 +596,14 @@ export class ModActionsPlugin extends ZeppelinPlugin {
if (args.reason) { if (args.reason) {
const kickMessage = formatTemplateString(this.configValue("kick_message"), { const kickMessage = formatTemplateString(this.configValue("kick_message"), {
guildName: this.guild.name, guildName: this.guild.name,
reason: args.reason reason: args.reason,
}); });
messageSent = await this.tryToMessageUser( messageSent = await this.tryToMessageUser(
args.member.user, args.member.user,
kickMessage, kickMessage,
this.configValue("dm_on_kick"), 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, modId: mod.id,
type: CaseTypes.Kick, type: CaseTypes.Kick,
reason: args.reason, 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 // Confirm the action to the moderator
@ -635,12 +631,12 @@ export class ModActionsPlugin extends ZeppelinPlugin {
// Log the action // Log the action
this.serverLogs.log(LogType.MEMBER_KICK, { this.serverLogs.log(LogType.MEMBER_KICK, {
mod: stripObjectToScalars(mod.user), mod: stripObjectToScalars(mod.user),
user: stripObjectToScalars(args.member.user) user: stripObjectToScalars(args.member.user),
}); });
} }
@d.command("ban", "<member:Member> [reason:string$]", { @d.command("ban", "<member:Member> [reason:string$]", {
options: [{ name: "mod", type: "member" }] options: [{ name: "mod", type: "member" }],
}) })
@d.permission("ban") @d.permission("ban")
async banCmd(msg, args) { async banCmd(msg, args) {
@ -666,14 +662,14 @@ export class ModActionsPlugin extends ZeppelinPlugin {
if (args.reason) { if (args.reason) {
const banMessage = formatTemplateString(this.configValue("ban_message"), { const banMessage = formatTemplateString(this.configValue("ban_message"), {
guildName: this.guild.name, guildName: this.guild.name,
reason: args.reason reason: args.reason,
}); });
messageSent = await this.tryToMessageUser( messageSent = await this.tryToMessageUser(
args.member.user, args.member.user,
banMessage, banMessage,
this.configValue("dm_on_ban"), 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, modId: mod.id,
type: CaseTypes.Ban, type: CaseTypes.Ban,
reason: args.reason, 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 // Confirm the action to the moderator
@ -701,12 +697,12 @@ export class ModActionsPlugin extends ZeppelinPlugin {
// Log the action // Log the action
this.serverLogs.log(LogType.MEMBER_BAN, { this.serverLogs.log(LogType.MEMBER_BAN, {
mod: stripObjectToScalars(mod.user), mod: stripObjectToScalars(mod.user),
member: stripObjectToScalars(args.member, ["user"]) member: stripObjectToScalars(args.member, ["user"]),
}); });
} }
@d.command("softban", "<member:Member> [reason:string$]", { @d.command("softban", "<member:Member> [reason:string$]", {
options: [{ name: "mod", type: "member" }] options: [{ name: "mod", type: "member" }],
}) })
@d.permission("ban") @d.permission("ban")
async softbanCmd(msg, args) { async softbanCmd(msg, args) {
@ -742,7 +738,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
modId: mod.id, modId: mod.id,
type: CaseTypes.Softban, type: CaseTypes.Softban,
reason: args.reason, 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 // Confirm the action to the moderator
@ -750,19 +746,19 @@ export class ModActionsPlugin extends ZeppelinPlugin {
successMessage( successMessage(
`Softbanned **${args.member.user.username}#${args.member.user.discriminator}** (Case #${ `Softbanned **${args.member.user.username}#${args.member.user.discriminator}** (Case #${
createdCase.case_number createdCase.case_number
})` })`,
) ),
); );
// Log the action // Log the action
this.serverLogs.log(LogType.MEMBER_SOFTBAN, { this.serverLogs.log(LogType.MEMBER_SOFTBAN, {
mod: stripObjectToScalars(mod.user), mod: stripObjectToScalars(mod.user),
member: stripObjectToScalars(args.member, ["user"]) member: stripObjectToScalars(args.member, ["user"]),
}); });
} }
@d.command("unban", "<userId:userId> [reason:string$]", { @d.command("unban", "<userId:userId> [reason:string$]", {
options: [{ name: "mod", type: "member" }] options: [{ name: "mod", type: "member" }],
}) })
@d.permission("ban") @d.permission("ban")
async unbanCmd(msg: Message, args: { userId: string; reason: string; mod: Member }) { async unbanCmd(msg: Message, args: { userId: string; reason: string; mod: Member }) {
@ -793,7 +789,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
modId: mod.id, modId: mod.id,
type: CaseTypes.Unban, type: CaseTypes.Unban,
reason: args.reason, 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 // Confirm the action
@ -802,12 +798,12 @@ export class ModActionsPlugin extends ZeppelinPlugin {
// Log the action // Log the action
this.serverLogs.log(LogType.MEMBER_UNBAN, { this.serverLogs.log(LogType.MEMBER_UNBAN, {
mod: stripObjectToScalars(mod.user), mod: stripObjectToScalars(mod.user),
userId: args.userId userId: args.userId,
}); });
} }
@d.command("forceban", "<userId:userId> [reason:string$]", { @d.command("forceban", "<userId:userId> [reason:string$]", {
options: [{ name: "mod", type: "member" }] options: [{ name: "mod", type: "member" }],
}) })
@d.permission("ban") @d.permission("ban")
async forcebanCmd(msg: Message, args: any) { async forcebanCmd(msg: Message, args: any) {
@ -845,7 +841,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
modId: mod.id, modId: mod.id,
type: CaseTypes.Ban, type: CaseTypes.Ban,
reason: args.reason, 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 // Confirm the action
@ -854,7 +850,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
// Log the action // Log the action
this.serverLogs.log(LogType.MEMBER_FORCEBAN, { this.serverLogs.log(LogType.MEMBER_FORCEBAN, {
mod: stripObjectToScalars(mod.user), mod: stripObjectToScalars(mod.user),
userId: args.userId userId: args.userId,
}); });
} }
@ -909,7 +905,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
modId: msg.author.id, modId: msg.author.id,
type: CaseTypes.Ban, type: CaseTypes.Ban,
reason: `Mass ban: ${banReason}`, reason: `Mass ban: ${banReason}`,
postInCaseLog: false postInCaseLog: false,
}); });
} catch (e) { } catch (e) {
failedBans.push(userId); 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. // Some or all bans were successful. Create a log entry for the mass ban and notify the user.
this.serverLogs.log(LogType.MASSBAN, { this.serverLogs.log(LogType.MASSBAN, {
mod: stripObjectToScalars(msg.author), mod: stripObjectToScalars(msg.author),
count: successfulBanCount count: successfulBanCount,
}); });
if (failedBans.length) { if (failedBans.length) {
msg.channel.createMessage( msg.channel.createMessage(
successMessage(`Banned ${successfulBanCount} users, ${failedBans.length} failed: ${failedBans.join(" ")}`) successMessage(`Banned ${successfulBanCount} users, ${failedBans.length} failed: ${failedBans.join(" ")}`),
); );
} else { } else {
msg.channel.createMessage(successMessage(`Banned ${successfulBanCount} users successfully`)); msg.channel.createMessage(successMessage(`Banned ${successfulBanCount} users successfully`));
@ -941,7 +937,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
} }
@d.command("addcase", "<type:string> <target:userId> [reason:string$]", { @d.command("addcase", "<type:string> <target:userId> [reason:string$]", {
options: [{ name: "mod", type: "member" }] options: [{ name: "mod", type: "member" }],
}) })
@d.permission("addcase") @d.permission("addcase")
async addcaseCmd(msg: Message, args: any) { async addcaseCmd(msg: Message, args: any) {
@ -982,7 +978,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
modId: mod.id, modId: mod.id,
type: CaseTypes[type], type: CaseTypes[type],
reason: args.reason, 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`)); msg.channel.createMessage(successMessage(`Case #${theCase.case_number} created`));
@ -992,7 +988,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
mod: stripObjectToScalars(mod.user), mod: stripObjectToScalars(mod.user),
userId: args.userId, userId: args.userId,
caseNum: theCase.case_number, caseNum: theCase.case_number,
caseType: type.toUpperCase() caseType: type.toUpperCase(),
}); });
} }
@ -1014,7 +1010,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
await this.actions.fire("postCase", { await this.actions.fire("postCase", {
caseId: theCase.id, caseId: theCase.id,
channel: msg.channel channel: msg.channel,
}); });
} }
@ -1045,7 +1041,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
for (const theCase of casesToDisplay) { for (const theCase of casesToDisplay) {
await this.actions.fire("postCase", { await this.actions.fire("postCase", {
caseId: theCase.id, caseId: theCase.id,
channel: msg.channel channel: msg.channel,
}); });
} }
} else { } else {
@ -1089,7 +1085,7 @@ export class ModActionsPlugin extends ZeppelinPlugin {
await this.cases.setHidden(theCase.id, true); await this.cases.setHidden(theCase.id, true);
msg.channel.createMessage( 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.`),
); );
} }

View file

@ -22,19 +22,26 @@ export class MutesPlugin extends ZeppelinPlugin {
getDefaultOptions() { getDefaultOptions() {
return { return {
config: { config: {
mute_role: null mute_role: null,
}, },
permissions: { permissions: {
cleanup: false view_list: false,
cleanup: false,
}, },
overrides: [ overrides: [
{
level: ">=50",
permissions: {
view_list: true,
},
},
{ {
level: ">=100", level: ">=100",
permissions: { permissions: {
cleanup: true cleanup: true,
} },
} },
] ],
}; };
} }
@ -50,7 +57,6 @@ export class MutesPlugin extends ZeppelinPlugin {
this.actions.register("unmute", args => { this.actions.register("unmute", args => {
return this.unmuteMember(args.member, args.unmuteTime); return this.unmuteMember(args.member, args.unmuteTime);
}); });
this.actions.register("postMuteList", this.postMuteList.bind(this));
// Check for expired mutes every 5s // Check for expired mutes every 5s
this.clearExpiredMutes(); this.clearExpiredMutes();
@ -60,7 +66,6 @@ export class MutesPlugin extends ZeppelinPlugin {
onUnload() { onUnload() {
this.actions.unregister("mute"); this.actions.unregister("mute");
this.actions.unregister("unmute"); this.actions.unregister("unmute");
this.actions.unregister("postMuteList");
clearInterval(this.muteClearIntervalId); 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 = []; const lines = [];
// Active, logged mutes // Active, logged mutes
@ -108,24 +115,25 @@ export class MutesPlugin extends ZeppelinPlugin {
...activeMutes.map(mute => { ...activeMutes.map(mute => {
const user = this.bot.users.get(mute.user_id); const user = this.bot.users.get(mute.user_id);
const username = user ? `${user.username}#${user.discriminator}` : "Unknown#0000"; 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"; 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) { if (mute.expires_at) {
const timeUntilExpiry = moment().diff(moment(mute.expires_at, DBDateFormat)); const timeUntilExpiry = moment().diff(moment(mute.expires_at, DBDateFormat));
const humanizedTime = humanizeDuration(timeUntilExpiry, { largest: 2, round: true }); const humanizedTime = humanizeDuration(timeUntilExpiry, { largest: 2, round: true });
line += ` (expires in ${humanizedTime})`; line += ` ⏰ Expires in ${humanizedTime}`;
} else { } else {
line += ` (doesn't expire)`; line += ` ⏰ Doesn't expire`;
} }
const mutedAt = moment(mute.created_at, DBDateFormat); const timeFromMute = moment(mute.created_at, DBDateFormat).diff(moment());
line += ` (muted at ${mutedAt.format("YYYY-MM-DD HH:mm:ss")})`; const humanizedTimeFromMute = humanizeDuration(timeFromMute, { largest: 2, round: true });
line += ` 🕒 Muted ${humanizedTimeFromMute} ago`;
return line; return line;
}) }),
); );
// Manually added mute roles // Manually added mute roles
@ -143,13 +151,13 @@ export class MutesPlugin extends ZeppelinPlugin {
lines.push( lines.push(
...manuallyMutedMembers.map(member => { ...manuallyMutedMembers.map(member => {
return `\`Manual mute\` **${member.user.username}#${member.user.discriminator}** (\`${member.id}\`)`; 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); const chunks = chunkMessageLines(message);
for (const chunk of chunks) { 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); const bannedIds = bans.map(b => b.user.id);
await msg.channel.createMessage( 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; let cleared = 0;
@ -262,7 +270,7 @@ export class MutesPlugin extends ZeppelinPlugin {
await this.mutes.clear(member.id); await this.mutes.clear(member.id);
this.serverLogs.log(LogType.MEMBER_MUTE_EXPIRED, { this.serverLogs.log(LogType.MEMBER_MUTE_EXPIRED, {
member: stripObjectToScalars(member, ["user"]) member: stripObjectToScalars(member, ["user"]),
}); });
} }
} }