const { Setting } = require('../../../../interfaces/'); const CONSTANTS = { INFRACTIONS: ['WARN', 'MUTE', 'KICK', 'SOFTBAN', 'BAN', 'VCMUTE', 'VCKICK', 'VCBAN'] }; class AutoModerationSetting extends Setting { constructor(client) { super(client, { name: 'autoModeration', module: 'moderation', aliases: ['automod'], resolve: 'GUILD', default: { autoModeration: { enabled: true, thresholds: { '10': { type: 'MUTE', length: 60 }, '20': { type: 'KICK' } }, usePrevious: false // use previous threshold if no new threshold is exceeded } }, archivable: true }); } async handle(message, args) { 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) { 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') } ]; } } module.exports = AutoModerationSetting;