From 1f4b89700c8f82f191729736997afa2e903a2c37 Mon Sep 17 00:00:00 2001 From: Dragory Date: Thu, 16 Aug 2018 20:07:43 +0300 Subject: [PATCH] Add massban command --- package-lock.json | 6 +- package.json | 2 +- src/data/DefaultLogMessages.json | 4 +- src/data/LogType.ts | 4 +- src/plugins/ModActions.ts | 100 +++++++++++++++++++++++++++++-- 5 files changed, 106 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 27e7c343..3557ba9c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2524,9 +2524,9 @@ } }, "knub": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/knub/-/knub-10.0.0.tgz", - "integrity": "sha512-E83Sl0NjoOhFZbUPcCuYvCO37qaegvNnyzRJrYNIIQ664JDpVkE0fRvQJI08wU8tPeQ7CNEGMsyP5WaM4NoNBA==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/knub/-/knub-10.1.0.tgz", + "integrity": "sha512-W14IbTSz4iGvgKQ4QutY8s+5rZcqYmB8ll3aUQ8nYDp23VDCdm/6Do0f8j0zip5h05cmfVmVRIXabfvfFQkxmA==", "requires": { "escape-string-regexp": "^1.0.5", "js-yaml": "^3.9.1", diff --git a/package.json b/package.json index 020d636b..7bd68e9d 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "escape-string-regexp": "^1.0.5", "humanize-duration": "^3.15.0", "knex": "0.12.6", - "knub": "^10.0.0", + "knub": "^10.1.0", "lodash.at": "^4.6.0", "lodash.chunk": "^4.2.0", "lodash.difference": "^4.5.0", diff --git a/src/data/DefaultLogMessages.json b/src/data/DefaultLogMessages.json index f2e8e1cc..c2bcff01 100644 --- a/src/data/DefaultLogMessages.json +++ b/src/data/DefaultLogMessages.json @@ -40,5 +40,7 @@ "CENSOR": "🛑 **{member.user.username}#{member.user.discriminator}** (`{member.id}`) censored message in **#{channel.name}** (`{channel.id}`) {reason}:\n```{messageText}```", "CLEAN": "🚿 **{mod.username}#{mod.discriminator}** (`{mod.id}`) cleaned **{count}** message(s) in **#{channel.name}**", - "CASE_CREATE": "✏ **{member.user.username}#{member.user.discriminator}** (`{member.id}`) manually created new **{caseType}** case (#{caseNum})" + "CASE_CREATE": "✏ **{member.user.username}#{member.user.discriminator}** (`{member.id}`) manually created new **{caseType}** case (#{caseNum})", + + "MASSBAN": "⚒ **{mod.username}#{mod.discriminator}** massbanned {count} users" } diff --git a/src/data/LogType.ts b/src/data/LogType.ts index 540f9878..a7ec0e8f 100644 --- a/src/data/LogType.ts +++ b/src/data/LogType.ts @@ -38,5 +38,7 @@ export enum LogType { CENSOR, CLEAN, - CASE_CREATE + CASE_CREATE, + + MASSBAN } diff --git a/src/plugins/ModActions.ts b/src/plugins/ModActions.ts index b1ecf914..a1cb1c8f 100644 --- a/src/plugins/ModActions.ts +++ b/src/plugins/ModActions.ts @@ -1,4 +1,4 @@ -import { decorators as d, Plugin, waitForReaction } from "knub"; +import { decorators as d, Plugin, waitForReaction, waitForReply } from "knub"; import { Constants as ErisConstants, Guild, Member, Message, TextChannel, User } from "eris"; import moment from "moment-timezone"; import humanizeDuration from "humanize-duration"; @@ -92,7 +92,8 @@ export class ModActionsPlugin extends Plugin { kick: false, ban: false, view: false, - addcase: false + addcase: false, + massban: true }, overrides: [ { @@ -106,6 +107,12 @@ export class ModActionsPlugin extends Plugin { view: true, addcase: true } + }, + { + level: ">=100", + permissions: { + massban: true + } } ] }; @@ -744,6 +751,89 @@ export class ModActionsPlugin extends Plugin { }); } + @d.command("massban", "") + @d.permission("massban") + async massbanCmd(msg: Message, args: { userIds: string[] }) { + msg.channel.createMessage("Ban reason? `cancel` to cancel"); + const banReasonReply = await waitForReply(this.bot, msg.channel as TextChannel, msg.author.id); + if ( + !banReasonReply || + !banReasonReply.content || + banReasonReply.content.toLowerCase().trim() === "cancel" + ) { + msg.channel.createMessage("Cancelled"); + return; + } + + const banReason = banReasonReply.content; + + if (args.userIds.length > 100) { + msg.channel.createMessage(errorMessage(`Can only massban max 100 users at once`)); + return; + } + + for (const userId of args.userIds) { + const member = this.guild.members.get(userId); + if (member && !this.canActOn(msg.member, member)) { + msg.channel.createMessage( + errorMessage("Cannot massban one or more users: insufficient permissions") + ); + return; + } + } + + args.userIds.forEach(userId => { + this.ignoreEvent(IgnoredEventType.Ban, userId); + this.serverLogs.ignoreLog(LogType.MEMBER_BAN, userId); + }); + + const loadingMsg = await msg.channel.createMessage("Banning..."); + + const failedBans = []; + for (const userId of args.userIds) { + try { + await this.guild.banMember(userId); + await this.createCase( + userId, + msg.author.id, + CaseType.Ban, + null, + `Mass ban: ${banReason}`, + false, + false + ); + } catch (e) { + failedBans.push(userId); + } + } + + loadingMsg.delete(); + + const successfulBanCount = args.userIds.length - failedBans.length; + if (successfulBanCount === 0) { + msg.channel.createMessage(errorMessage("All bans failed. Make sure the IDs are valid.")); + } else { + this.serverLogs.log(LogType.MASSBAN, { + mod: stripObjectToScalars(msg.author), + count: successfulBanCount + }); + + if (failedBans.length) { + msg.channel.createMessage( + successMessage( + `Banned ${successfulBanCount} users, ${failedBans.length} failed: ${failedBans.join( + " " + )}` + ) + ); + } else { + msg.channel.createMessage( + successMessage(`Banned ${successfulBanCount} users successfully`) + ); + } + } + } + @d.command("addcase", " [reason:string$]") @d.permission("addcase") async addcaseCmd(msg: Message, args: any) { @@ -983,7 +1073,8 @@ export class ModActionsPlugin extends Plugin { caseType: CaseType, auditLogId: string = null, reason: string = null, - automatic = false + automatic = false, + postInCaseLogOverride = null ): Promise { const user = this.bot.users.get(userId); const userName = user ? `${user.username}#${user.discriminator}` : "Unknown#0000"; @@ -1006,7 +1097,8 @@ export class ModActionsPlugin extends Plugin { if ( this.configValue("case_log_channel") && - (!automatic || this.configValue("log_automatic_actions")) + (!automatic || this.configValue("log_automatic_actions")) && + postInCaseLogOverride !== false ) { try { await this.postCaseToCaseLog(createdId);