From b1612824dd02164d7c09864f0add5ad708dd17cd Mon Sep 17 00:00:00 2001 From: janderedev Date: Sat, 9 Apr 2022 17:42:59 +0200 Subject: [PATCH] disable sudo alert on antispam rules, add trycatch --- bot/src/bot/modules/antispam.ts | 130 +++++++++--------- bot/src/bot/modules/command_handler.ts | 2 +- .../bot/modules/custom_rules/custom_rules.ts | 72 +++++----- bot/src/bot/util.ts | 16 ++- 4 files changed, 114 insertions(+), 106 deletions(-) diff --git a/bot/src/bot/modules/antispam.ts b/bot/src/bot/modules/antispam.ts index e91c836..5cc5956 100644 --- a/bot/src/bot/modules/antispam.ts +++ b/bot/src/bot/modules/antispam.ts @@ -1,11 +1,10 @@ import { Message } from "@janderedev/revolt.js/dist/maps/Messages"; import { ulid } from "ulid"; -import { client, dbs } from "../.."; +import { dbs } from "../.."; import AntispamRule from "../../struct/antispam/AntispamRule"; import Infraction from "../../struct/antispam/Infraction"; import InfractionType from "../../struct/antispam/InfractionType"; import ModerationAction from "../../struct/antispam/ModerationAction"; -import ServerConfig from "../../struct/ServerConfig"; import logger from "../logger"; import { isModerator, storeInfraction } from "../util"; @@ -17,81 +16,86 @@ let msgCountStore: Map = new Map(); * @returns true if ok, false if spam rule triggered */ async function antispam(message: Message): Promise { - let serverRules = await dbs.SERVERS.findOne({ id: message.channel!.server_id! }); - if (!serverRules?.automodSettings) return true; + try { + let serverRules = await dbs.SERVERS.findOne({ id: message.channel!.server_id! }); + if (!serverRules?.automodSettings) return true; - let ruleTriggered = false; + let ruleTriggered = false; - for (const rule of serverRules.automodSettings.spam) { - if (msgCountStore.get(rule.id) == null) { - msgCountStore.set(rule.id, { users: {} }); - } + for (const rule of serverRules.automodSettings.spam) { + if (msgCountStore.get(rule.id) == null) { + msgCountStore.set(rule.id, { users: {} }); + } - if (message.author?.bot != null) break; - if (serverRules.whitelist?.users?.includes(message.author_id)) break; - if (message.member?.roles?.filter(r => serverRules!.whitelist?.roles?.includes(r)).length) break; - if (serverRules.whitelist?.managers !== false && await isModerator(message)) break; - if (rule.channels?.length && rule.channels.indexOf(message.channel_id) == -1) break; + if (message.author?.bot != null) break; + if (serverRules.whitelist?.users?.includes(message.author_id)) break; + if (message.member?.roles?.filter(r => serverRules!.whitelist?.roles?.includes(r)).length) break; + if (serverRules.whitelist?.managers !== false && await isModerator(message, false)) break; + if (rule.channels?.length && rule.channels.indexOf(message.channel_id) == -1) break; - let store = msgCountStore.get(rule.id)!; - if (!store.users[message.channel_id]) store.users[message.channel_id] = {} - let userStore = store.users[message.channel_id]; + let store = msgCountStore.get(rule.id)!; + if (!store.users[message.channel_id]) store.users[message.channel_id] = {} + let userStore = store.users[message.channel_id]; - if (!userStore.count) userStore.count = 1; - else userStore.count++; + if (!userStore.count) userStore.count = 1; + else userStore.count++; - setTimeout(() => userStore.count--, rule.timeframe * 1000); + setTimeout(() => userStore.count--, rule.timeframe * 1000); - if (userStore.count > rule.max_msg) { - logger.info(`Antispam rule triggered: ${rule.max_msg}/${rule.timeframe} -> ${ModerationAction[rule.action]}`); - ruleTriggered = true; + if (userStore.count > rule.max_msg) { + logger.info(`Antispam rule triggered: ${rule.max_msg}/${rule.timeframe} -> ${ModerationAction[rule.action]}`); + ruleTriggered = true; - switch(Number(rule.action)) { - case ModerationAction.Delete: - message.delete() - .catch(() => logger.warn('Antispam: Failed to delete message') ); - break; - case ModerationAction.Message: - if (!userStore.warnTriggered) { - userStore.warnTriggered = true; - setTimeout(() => userStore.warnTriggered = false, 5000); - message.channel?.sendMessage(getWarnMsg(rule, message)) - .catch(() => logger.warn('Antispam: Failed to send message')); - } - break; - case ModerationAction.Warn: - if (!userStore.warnTriggered) { - userStore.warnTriggered = true; - setTimeout(() => userStore.warnTriggered = false, 5000); + switch(Number(rule.action)) { + case ModerationAction.Delete: + message.delete() + .catch(() => logger.warn('Antispam: Failed to delete message') ); + break; + case ModerationAction.Message: + if (!userStore.warnTriggered) { + userStore.warnTriggered = true; + setTimeout(() => userStore.warnTriggered = false, 5000); + message.channel?.sendMessage(getWarnMsg(rule, message)) + .catch(() => logger.warn('Antispam: Failed to send message')); + } + break; + case ModerationAction.Warn: + if (!userStore.warnTriggered) { + userStore.warnTriggered = true; + setTimeout(() => userStore.warnTriggered = false, 5000); - let inf = { - _id: ulid(), - createdBy: null, - date: Date.now(), - reason: `Automatic moderation rule triggered: More than ${rule.max_msg} messages per ${rule.timeframe} seconds.`, - server: message.channel?.server_id, - type: InfractionType.Automatic, - user: message.author_id, - } as Infraction; + let inf = { + _id: ulid(), + createdBy: null, + date: Date.now(), + reason: `Automatic moderation rule triggered: More than ${rule.max_msg} messages per ${rule.timeframe} seconds.`, + server: message.channel?.server_id, + type: InfractionType.Automatic, + user: message.author_id, + } as Infraction; - message.channel?.sendMessage('## User has been warned.\n\u200b\n' + getWarnMsg(rule, message)) - .catch(() => logger.warn('Antispam: Failed to send warn message')); + message.channel?.sendMessage('## User has been warned.\n\u200b\n' + getWarnMsg(rule, message)) + .catch(() => logger.warn('Antispam: Failed to send warn message')); - await storeInfraction(inf); - } - break; - case ModerationAction.Kick: - message.reply('(Kick user)'); - break; - case ModerationAction.Ban: - message.reply('(Ban user)'); - break; - default: logger.warn(`Unknown Moderation Action: ${rule.action}`); + await storeInfraction(inf); + } + break; + case ModerationAction.Kick: + message.reply('(Kick user)'); + break; + case ModerationAction.Ban: + message.reply('(Ban user)'); + break; + default: logger.warn(`Unknown Moderation Action: ${rule.action}`); + } } } - } - return !ruleTriggered; + return !ruleTriggered; + } catch(e) { + console.error(''+e); + return true; + } } function getWarnMsg(rule: AntispamRule, message: Message) { diff --git a/bot/src/bot/modules/command_handler.ts b/bot/src/bot/modules/command_handler.ts index 44a57ee..5c2ad2a 100644 --- a/bot/src/bot/modules/command_handler.ts +++ b/bot/src/bot/modules/command_handler.ts @@ -109,7 +109,7 @@ let commands: SimpleCommand[]; logger.info(`Command: ${message.author?.username} (${message.author?._id}) in ${message.channel?.server?.name} (${message.channel?.server?._id}): ${message.content}`); // Create document for server in DB, if not already present - if (JSON.stringify(config) == '{}') await dbs.SERVERS.insert({ id: message.channel!.server_id! }); + if (JSON.stringify(config) == '{}' || !config) await dbs.SERVERS.insert({ id: message.channel!.server_id! }); if (cmd.removeEmptyArgs !== false) { args = args.filter(a => a.length > 0); diff --git a/bot/src/bot/modules/custom_rules/custom_rules.ts b/bot/src/bot/modules/custom_rules/custom_rules.ts index e5e18aa..ba9d149 100644 --- a/bot/src/bot/modules/custom_rules/custom_rules.ts +++ b/bot/src/bot/modules/custom_rules/custom_rules.ts @@ -1,6 +1,5 @@ import { Message } from "@janderedev/revolt.js/dist/maps/Messages"; -import { client } from "../../.."; -import ServerConfig from "../../../struct/ServerConfig"; +import { dbs } from "../../.."; import logger from "../../logger"; import messageContentTrigger from "./message_content_trigger"; @@ -8,47 +7,50 @@ import custom_sendMessage from "./actions/sendMessage"; import custom_delete from "./actions/delete"; import custom_warn from "./actions/warn"; import { getOwnMemberInServer, hasPermForChannel } from "../../util"; -import MessageCommandContext from "../../../struct/MessageCommandContext"; async function checkCustomRules(message: Message, isEdit: boolean = false) { - let serverConfig: ServerConfig = await client.db.get('servers').findOne({ id: message.channel?.server_id }) ?? {}; - let rules = serverConfig?.automodSettings?.custom; - if (!rules) return; + try { + let serverConfig = await dbs.SERVERS.findOne({ id: message.channel!.server_id! }); + let rules = serverConfig?.automodSettings?.custom; + if (!rules) return; - for (let rule of rules) { - if (!rule?.trigger?.on) continue; - let onEdit = rule.trigger.on.includes('message/update'); - let onNew = rule.trigger.on.includes('message/create'); + for (let rule of rules) { + if (!rule?.trigger?.on) continue; + let onEdit = rule.trigger.on.includes('message/update'); + let onNew = rule.trigger.on.includes('message/create'); - // tired - if (!((onEdit && isEdit) || (onNew && !isEdit) || (onNew && onEdit))) break; + // tired + if (!((onEdit && isEdit) || (onNew && !isEdit) || (onNew && onEdit))) break; - if (await messageContentTrigger(message, rule.trigger)) { - for (const action of rule.action) { - switch(action.action) { - case 'sendMessage': - if (hasPermForChannel(await getOwnMemberInServer(message.channel!.server!), message.channel!, 'SendMessage')) - await custom_sendMessage(message, action); - else - logger.warn(`Custom rule ${rule._id}: 'sendMessage' action lacks permission`); - break; - case 'delete': - if (hasPermForChannel(await getOwnMemberInServer(message.channel!.server!), message.channel!, 'ManageMessages')) - await custom_delete(message, action); - else - logger.warn(`Custom rule ${rule._id}: 'delete' action lacks permission`); - break; - case 'warn': - if (hasPermForChannel(await getOwnMemberInServer(message.channel!.server!), message.channel!, 'SendMessage')) - await custom_warn(message, action); - else - logger.warn(`Custom rule ${rule._id}: 'warn' action lacks permission`); - break; - default: - logger.warn(`Unknown action ${action.action} in custom rule ${rule._id} in server ${message.channel?.server_id}`); + if (await messageContentTrigger(message, rule.trigger)) { + for (const action of rule.action) { + switch(action.action) { + case 'sendMessage': + if (hasPermForChannel(await getOwnMemberInServer(message.channel!.server!), message.channel!, 'SendMessage')) + await custom_sendMessage(message, action); + else + logger.warn(`Custom rule ${rule._id}: 'sendMessage' action lacks permission`); + break; + case 'delete': + if (hasPermForChannel(await getOwnMemberInServer(message.channel!.server!), message.channel!, 'ManageMessages')) + await custom_delete(message, action); + else + logger.warn(`Custom rule ${rule._id}: 'delete' action lacks permission`); + break; + case 'warn': + if (hasPermForChannel(await getOwnMemberInServer(message.channel!.server!), message.channel!, 'SendMessage')) + await custom_warn(message, action); + else + logger.warn(`Custom rule ${rule._id}: 'warn' action lacks permission`); + break; + default: + logger.warn(`Unknown action ${action.action} in custom rule ${rule._id} in server ${message.channel?.server_id}`); + } } } } + } catch(e) { + console.error(''+e); } } diff --git a/bot/src/bot/util.ts b/bot/src/bot/util.ts index c1113b3..6c7fb4c 100644 --- a/bot/src/bot/util.ts +++ b/bot/src/bot/util.ts @@ -75,7 +75,7 @@ async function parseUserOrId(text: string): Promise { return null; } -async function isModerator(message: Message) { +async function isModerator(message: Message, announceSudo?: boolean) { let member = message.member!, server = message.channel!.server!; if (hasPerm(member, 'KickMembers')) return true; @@ -83,32 +83,34 @@ async function isModerator(message: Message) { const [ isManager, mods, isSudo ] = await Promise.all([ isBotManager(message), dbs.SERVERS.findOne({ id: server._id }), - checkSudoPermission(message), + checkSudoPermission(message, announceSudo), ]); return isManager || (mods?.moderators?.indexOf(member.user?._id!) ?? -1) > -1 || isSudo; } -async function isBotManager(message: Message) { +async function isBotManager(message: Message, announceSudo?: boolean) { let member = message.member!, server = message.channel!.server!; if (hasPerm(member, 'ManageServer')) return true; const [ managers, isSudo ] = await Promise.all([ dbs.SERVERS.findOne({ id: server._id }), - checkSudoPermission(message), + checkSudoPermission(message, announceSudo), ]); return (managers?.botManagers?.indexOf(member.user?._id!) ?? -1) > -1 || isSudo; } -async function checkSudoPermission(message: Message): Promise { +async function checkSudoPermission(message: Message, announce?: boolean): Promise { const hasPerm = isSudo(message.author!); if (!hasPerm) return false; else { - await message.reply(`# :unlock: Bypassed permission check\n` - + `Sudo mode is enabled for @${message.author!.username}.\n`); + if (announce !== false) { + await message.reply(`# :unlock: Bypassed permission check\n` + + `Sudo mode is enabled for @${message.author!.username}.\n`); + } return true; } }