From 3bdd8c0d491e943bec346eb268f9f31aeb5aa542 Mon Sep 17 00:00:00 2001 From: Navy Date: Tue, 1 Sep 2020 18:46:01 +0300 Subject: [PATCH] automod configuration --- .../settings/moderation/AutoModeration.js | 114 ++++++++++++++++-- .../languages/en_us/en_us_general.lang | 6 + .../languages/en_us/en_us_settings.lang | 34 ++++++ 3 files changed, 143 insertions(+), 11 deletions(-) diff --git a/structure/client/components/settings/moderation/AutoModeration.js b/structure/client/components/settings/moderation/AutoModeration.js index 5be8a90..9c5d17d 100644 --- a/structure/client/components/settings/moderation/AutoModeration.js +++ b/structure/client/components/settings/moderation/AutoModeration.js @@ -1,5 +1,9 @@ const { Setting } = require('../../../../interfaces/'); +const CONSTANTS = { + INFRACTIONS: ['WARN', 'MUTE', 'KICK', 'SOFTBAN', 'BAN', 'VCMUTE', 'VCKICK', 'VCBAN'] +}; + class AutoModerationSetting extends Setting { constructor(client) { @@ -19,27 +23,115 @@ class AutoModerationSetting extends Setting { '20': { type: 'KICK' } - } + }, + usePrevious: false // use previous threshold if no new threshold is exceeded } }, - archivable: false + archivable: true }); } - async handle(message) { + async handle(message, args) { - return { - msg: message.format('S_SILENT_SUCCESS', { value: "fuck yourself" }), - error: false - }; + const setting = message.guild._settings[this.index]; + + const [method, ...params] = args; + let index = null, + langParams = {}; + + const { resolver } = this.client; + + if (resolver.resolveBoolean(method)) { + setting.enabled = true; + index = 'S_AUTOMOD_TOGGLE'; + langParams = { toggle: message.format('ON_OFF_TOGGLE', { toggle: true }, true) }; + } else if (resolver.resolveBoolean(method) === false) { + setting.enabled = false; + index = 'S_AUTOMOD_TOGGLE'; + langParams = { toggle: message.format('ON_OFF_TOGGLE', { toggle: false }, true) }; + } else if (method.toLowerCase() === 'threshold') { + + const action = params.shift()?.toLowerCase(); + if (!action) return { error: true, msg: message.format('S_AUTOMOD_NOARG') }; + + const points = parseInt(params.shift()); + if (isNaN(points) || points < 0 || points > 100) return { error: true, msg: message.format('S_AUTOMOD_INVALID_POINTS', {}) }; + + if (['delete', 'remove'].includes(action)) { + const old = setting.thresholds[points]; + if (old) { + index = 'S_AUTOMOD_REMOVE_POINTS'; + langParams = { type: old.type, points }; + delete setting.thresholds[points]; + } else { + return { error: true, msg: message.format('S_AUTOMOD_REMOVE_NOPOINTS', { points }) }; + } + } else { + const infraction = resolver.resolveInfraction(action); + if (!CONSTANTS.INFRACTIONS.includes(infraction)) return { error: true, msg: message.format('S_AUTOMOD_INVALID_TYPE', { infraction }) }; + const old = setting.thresholds[points]; + if (old) { + index = 'S_AUTOMOD_OVERWRITE_POINTS'; + langParams = { type: infraction, points, oldType: old.type }; + } else { + index = 'S_AUTOMOD_ADD_POINTS'; + langParams = { type: infraction, points }; + } + setting.thresholds[points] = { type: infraction }; + } + + } else if (method.toLowerCase() === 'length') { + + const points = parseInt(params.shift()); + if (isNaN(points) || points < 0 || points > 100) return { error: true, msg: message.format('S_AUTOMOD_INVALID_POINTS', {}) }; + + const action = params.shift()?.toLowerCase(); + if (!action) return { error: true, msg: message.format('S_AUTOMOD_NOARG') }; + + if (!setting.thresholds[points]) return { error: true, msg: message.format('S_AUTOMOD_NOACTION') }; + + if (['delete', 'remove'].includes(action)) { + delete setting.thresholds[points].length; + index = 'S_AUTOMOD_REMOVE_LENGTH'; + langParams = { type: setting.thresholds[points].type, points }; + } else { + const [, , ..._time] = args; + const time = resolver.resolveTime(_time.join(' ')); + if (!time) return { error: true, msg: message.format('ERR_INVALID_TIMESTRING') }; + setting.thresholds[points].length = time; + index = 'S_AUTOMOD_LENGTH_SUCCESS'; + } + + } + + await message.guild._updateSettings({ [this.index]: setting }); + return { msg: message.format(index, langParams), error: false }; } fields(guild) { - return { - name: "》 Status", - value: guild.format('SETTING_STATUS', { bool: Boolean(guild._settings.autoModeration.enabled) }, true) - }; + const setting = guild._settings[this.index]; + const { resolver } = this.client; + + return [ + { + name: "》 Status", + value: guild.format('SETTING_STATUS', { bool: Boolean(setting.enabled) }, true), + inline: true + }, + { + name: '》 Use previous threshold', + value: guild.format('SETTING_STATUS', { bool: Boolean(setting.usePrevious) }, true), + inline: true + }, + { + name: '》 Thresholds', + value: Object.entries(setting.thresholds).reduce((acc, [points, action]) => { + acc.push(`**${points}:** \`${action.type}\`${action.length ? ', ' + resolver.timeAgo(action.length) : ''}`); + return acc; + }, []).join('\n') + } + ]; } } diff --git a/structure/language/languages/en_us/en_us_general.lang b/structure/language/languages/en_us/en_us_general.lang index 78b3842..57c3111 100644 --- a/structure/language/languages/en_us/en_us_general.lang +++ b/structure/language/languages/en_us/en_us_general.lang @@ -127,6 +127,12 @@ Cannot use a channel of type {type}. [ERR_CHANNEL_PERMS] Missing `{perms}` permission(s) in {emoji_text-channel}**{channel}**. +[ERR_INVALID_TIMESTRING] +Invalid timestring provided. Must be `INT unit [INT unit..]`. + +[S_AUTOMOD_LENGTH_SUCCESS] +Successfully set the action duration. + //Command Handler [COMMANDHANDLER_COMMAND_MISSINGPERMISSIONS] diff --git a/structure/language/languages/en_us/en_us_settings.lang b/structure/language/languages/en_us/en_us_settings.lang index d18728b..97574eb 100644 --- a/structure/language/languages/en_us/en_us_settings.lang +++ b/structure/language/languages/en_us/en_us_settings.lang @@ -67,6 +67,40 @@ Set the protected list to `{changes}`. The following roles are protected. {list} +//Automod +[S_AUTOMODERATION_DESCRIPTION] +Configure automatic infraction escalation & other automated moderation behaviour. + +[S_AUTOMOD_TOGGLE] +Successfully toggled automatic infraction escalation **{toggle}**. + +[S_AUTOMOD_NOARG] +Missing arguments. + +[S_AUTOMOD_INVALID_TYPE] +Cannot set **{infraction}** as a threshold. + +[S_AUTOMOD_INVALID_POINTS] +Invalid points supplied, must be an integer between 0 and 100. + +[S_AUTOMOD_REMOVE_POINTS] +Successfully removed **{type}** at **{points} points**. + +[S_AUTOMOD_REMOVE_NOPOINTS] +No points to remove. + +[S_AUTOMOD_ADD_POINTS] +Successfully added action **{type}** at **{points} points**. + +[S_AUTOMOD_OVERWRITE_POINTS] +Successfully overwrote **{oldType}** with **{type}** at **{points} points**. + +[S_AUTOMOD_NOACTION] +No action set at that threshold. + +[S_AUTOMOD_REMOVE_LENGTH] +Successfully removed length for **{type}** at **{points} points**. + //moderationPoints Setting [S_MODERATIONPOINTS_DESCRIPTION] Configure points and point expiration for infractions. Utilized by auto-moderation.