From 4c269f9e7aea54ccc008b65104c70ced20ddd6b7 Mon Sep 17 00:00:00 2001 From: nolan Date: Sun, 19 Jul 2020 15:42:21 -0700 Subject: [PATCH] full commit --- .../en_us/commands/en_us_moderation.lang | 44 ++++++++++++++++++- language/languages/en_us/en_us_general.lang | 2 +- structure/client/Resolver.js | 2 +- .../components/commands/moderation/Addrole.js | 4 +- .../components/commands/moderation/Ban.js | 6 ++- .../components/commands/moderation/Kick.js | 6 ++- .../components/commands/moderation/Mute.js | 12 +++-- .../commands/moderation/Nickname.js | 6 ++- .../components/commands/moderation/Note.js | 6 ++- .../commands/moderation/Removerole.js | 10 ++++- .../commands/moderation/Slowmode.js | 6 ++- .../components/commands/moderation/Softban.js | 6 ++- .../components/commands/moderation/Unban.js | 6 ++- .../components/commands/moderation/Unmute.js | 6 ++- .../components/commands/moderation/Vckick.js | 6 ++- .../components/commands/moderation/Warn.js | 6 ++- .../settings/moderation/AutoModeration.js | 43 ++++++++++++++++++ .../settings/moderation/DmInfraction.js | 2 +- structure/extensions/Guild.js | 30 ++++++++++++- structure/extensions/GuildMember.js | 2 +- structure/moderation/ModerationManager.js | 16 ++++--- structure/moderation/infractions/Addrole.js | 6 ++- structure/moderation/infractions/Kick.js | 7 ++- structure/moderation/infractions/Mute.js | 5 +++ structure/moderation/infractions/Nickname.js | 5 +++ structure/moderation/infractions/Prune.js | 11 +++++ .../moderation/infractions/Removerole.js | 6 ++- structure/moderation/infractions/Slowmode.js | 11 +++++ structure/moderation/infractions/Softban.js | 7 ++- structure/moderation/infractions/Unban.js | 6 +++ structure/moderation/infractions/Unmute.js | 19 ++++++-- structure/moderation/infractions/Vckick.js | 8 +++- structure/moderation/interfaces/Infraction.js | 10 +++-- util/Util.js | 2 +- 34 files changed, 286 insertions(+), 44 deletions(-) create mode 100644 structure/client/components/settings/moderation/AutoModeration.js diff --git a/language/languages/en_us/commands/en_us_moderation.lang b/language/languages/en_us/commands/en_us_moderation.lang index 5e736e6..689bf35 100644 --- a/language/languages/en_us/commands/en_us_moderation.lang +++ b/language/languages/en_us/commands/en_us_moderation.lang @@ -20,6 +20,9 @@ Unmute members from the server. [C_UNMUTE_MISSINGMEMBERS] You must provide members to unmute. +[C_UNMUTE_INSUFFICIENTPERMISSIONS] +I don't have permission to manage roles + [C_UNMUTE_CANNOTFINDMUTE] they were not previously muted @@ -45,6 +48,9 @@ You must provide members to mute. [C_MUTE_DURATIONEXCEPTION] The duration must be more than `1 minute` and less than `1 month`. +[C_MUTE_INSUFFICIENTPERMISSIONS] +I don't have permission to manage roles + [C_MUTE_NOMUTEROLE] You don't have a mute role set in your server, use the command `-set mute` for more information. @@ -68,6 +74,9 @@ Kick provided members from the server. You must provide members to kick. [C_KICK_INSUFFICIENTPERMISSIONS] +I don't have permission to kick members + +[C_KICK_CANNOTBEKICKED] they are unable to be kicked //Softban Command @@ -79,6 +88,9 @@ Primarily used to prune the member's messages in all channels. You must provide members to softban. [C_SOFTBAN_INSUFFICIENTPERMISSIONS] +I don't have permission to ban members + +[C_SOFTBAN_CANNOTBESOFTBANNED] they are unable to be softbanned //Ban Command @@ -111,6 +123,9 @@ Unban provided users from the server. [C_UNBAN_MISSINGMEMBERS] You must provide users to unban. +[C_UNBAN_INSUFFICIENTPERMISSIONS] +I don't have permission to unban members + [C_UNBAN_NOTBANNED] they are not banned @@ -124,6 +139,9 @@ You must provide an amount to prune. [C_PRUNE_INTEGEREXCEPTION] The amount must be more than `1` and less than `300`. +[C_PRUNE_INSUFFICIENTPERMISSIONS] +I don't have permission to manage messages + [C_PRUNE_NOTFETCHED] I was unable to fetch any messages @@ -140,6 +158,9 @@ I had issues deleting those messages [C_VCKICK_DESCRIPTION] Kick provided members from their connected voice-channel. +[C_VCKICK_INSUFFICIENTPERMISSIONS] +I don't have permission to move members + [C_VCKICK_NOCHANNEL] they are not in a voice-channel @@ -153,6 +174,9 @@ You must provide a duration to set the slowmode to. [C_SLOWMODE_SECONDEXCEPTION] The duration must be `0 seconds` or more, and less than `6 hours`. +[C_SLOWMODE_INSUFFICIENTPERMISSIONS] +I don't have permission to manage channels + [C_SLOWMODE_NOCHANGE] the slowmode was already set to that @@ -169,12 +193,28 @@ You must provide arguments to change their nickname to. [C_NICKNAME_NOCHARACTERS] they had no hoisted characters in their nickname +[C_NICKNAME_INSUFFICIENTPERMISSIONS] +I don't have permission to manage nicknames + [C_NICKNAME_MISSINGPERMSSIONS] they have a higher role than I do //Addrole Command [C_ADDROLE_DESCRIPTION] -Add roles to a specified member, as long as +Add roles to provided members. The added roles cannot be a higher position than the executor's highest role. + +[C_ADDROLE_INSUFFICIENTPERMISSIONS] +I don't have permission to manage roles + +[C_ADDROLE_ROLEHIERARCHY] +the provided role(s) have a higher position than yours //Removerole Command -[C_REMOVEROLE_DESCRIPTION] \ No newline at end of file +[C_REMOVEROLE_DESCRIPTION] +Remove roles to provided members. The removes roles cannot be a higher position than the executor's highest role. + +[C_REMOVEROLE_INSUFFICIENTPERMISSIONS] +I don't have permission to manage roles + +[C_REMOVEROLE_ROLEHIERARCHY] +the provided role(s) have a higher position than yours \ No newline at end of file diff --git a/language/languages/en_us/en_us_general.lang b/language/languages/en_us/en_us_general.lang index bbb1d74..6400d56 100644 --- a/language/languages/en_us/en_us_general.lang +++ b/language/languages/en_us/en_us_general.lang @@ -187,7 +187,7 @@ they have hierarchy over you This action was automatically escalated by auto-moderation. [INFRACTION_ESCALATIONREASON] -because auto-moderation escalated this infraction. +auto-moderation escalated this infraction. [INFRACTION_SUCCESS] Successfully {infraction} {targetType} {target}{text} diff --git a/structure/client/Resolver.js b/structure/client/Resolver.js index b3382d3..8cf3ed2 100644 --- a/structure/client/Resolver.js +++ b/structure/client/Resolver.js @@ -362,7 +362,7 @@ class Resolver { const match = resolveable.match(id); const [, ch] = match; - const channel = await this.client.channels.fetch(ch); + const channel = await this.client.channels.fetch(ch).catch((e) => {}); //eslint-disable-line no-empty, no-empty-function, no-unused-vars if (channel && filter(channel)) resolved.push(channel); diff --git a/structure/client/components/commands/moderation/Addrole.js b/structure/client/components/commands/moderation/Addrole.js index d89cbba..1852d34 100644 --- a/structure/client/components/commands/moderation/Addrole.js +++ b/structure/client/components/commands/moderation/Addrole.js @@ -9,7 +9,9 @@ class AddroleCommand extends Command { name: 'addrole', module: 'moderation', aliases: [ - 'roleadd' + 'roleadd', + 'addroles', + 'rolesadd' ], usage: " [reason]", clientPermissions: ['MANAGE_ROLES'], diff --git a/structure/client/components/commands/moderation/Ban.js b/structure/client/components/commands/moderation/Ban.js index 3ecd42a..ef17faf 100644 --- a/structure/client/components/commands/moderation/Ban.js +++ b/structure/client/components/commands/moderation/Ban.js @@ -67,7 +67,11 @@ class BanCommand extends Command { } ], guildOnly: true, - showUsage: true + showUsage: true, + throttling: { + usages: 2, + duration: 5 + } }); this.client = client; diff --git a/structure/client/components/commands/moderation/Kick.js b/structure/client/components/commands/moderation/Kick.js index fb7d859..5707733 100644 --- a/structure/client/components/commands/moderation/Kick.js +++ b/structure/client/components/commands/moderation/Kick.js @@ -63,7 +63,11 @@ class KickCommand extends Command { } ], guildOnly: true, - showUsage: true + showUsage: true, + throttling: { + usages: 2, + duration: 5 + } }); this.client = client; diff --git a/structure/client/components/commands/moderation/Mute.js b/structure/client/components/commands/moderation/Mute.js index 36525ff..0f76781 100644 --- a/structure/client/components/commands/moderation/Mute.js +++ b/structure/client/components/commands/moderation/Mute.js @@ -66,7 +66,11 @@ class MuteCommand extends Command { } ], guildOnly: true, - showUsage: true + showUsage: true, + throttling: { + usages: 2, + duration: 5 + } }); } @@ -98,9 +102,9 @@ class MuteCommand extends Command { } if(time !== 0) { - if(time < 60 || time > 2629801) { // approx. over 1 month (according to resolveTime) - return message.respond(message.format('C_MUTE_DURATIONEXCEPTION'), { emoji: 'failure' }); - } + // if(time < 60 || time > 2629801) { // approx. over 1 month (according to resolveTime) + // return message.respond(message.format('C_MUTE_DURATIONEXCEPTION'), { emoji: 'failure' }); + // } } return this.client.moderationManager diff --git a/structure/client/components/commands/moderation/Nickname.js b/structure/client/components/commands/moderation/Nickname.js index f81ca10..25af141 100644 --- a/structure/client/components/commands/moderation/Nickname.js +++ b/structure/client/components/commands/moderation/Nickname.js @@ -68,7 +68,11 @@ class NicknameCommand extends Command { } ], guildOnly: true, - showUsage: true + showUsage: true, + throttling: { + usages: 2, + duration: 5 + } }); } diff --git a/structure/client/components/commands/moderation/Note.js b/structure/client/components/commands/moderation/Note.js index cfb9a30..47b24b6 100644 --- a/structure/client/components/commands/moderation/Note.js +++ b/structure/client/components/commands/moderation/Note.js @@ -23,7 +23,11 @@ class NoteCommand extends Command { } ], guildOnly: true, - showUsage: true + showUsage: true, + throttling: { + usages: 2, + duration: 5 + } }); } diff --git a/structure/client/components/commands/moderation/Removerole.js b/structure/client/components/commands/moderation/Removerole.js index d3bfa49..69292ac 100644 --- a/structure/client/components/commands/moderation/Removerole.js +++ b/structure/client/components/commands/moderation/Removerole.js @@ -9,7 +9,9 @@ class RemoveroleCommand extends Command { name: 'removerole', module: 'moderation', aliases: [ - 'roleremove' + 'roleremove', + 'removeroles', + 'rolesremove' ], usage: " [reason]", clientPermissions: ['MANAGE_ROLES'], @@ -24,7 +26,11 @@ class RemoveroleCommand extends Command { } ], guildOnly: true, - showUsage: true + showUsage: true, + throttling: { + usages: 2, + duration: 10 + } }); } diff --git a/structure/client/components/commands/moderation/Slowmode.js b/structure/client/components/commands/moderation/Slowmode.js index 24cb2b1..d507856 100644 --- a/structure/client/components/commands/moderation/Slowmode.js +++ b/structure/client/components/commands/moderation/Slowmode.js @@ -25,7 +25,11 @@ class SlowmodeCommand extends Command { } ], guildOnly: true, - showUsage: true + showUsage: true, + throttling: { + usages: 2, + duration: 10 + } }); this.client = client; diff --git a/structure/client/components/commands/moderation/Softban.js b/structure/client/components/commands/moderation/Softban.js index 164b672..d5e3366 100644 --- a/structure/client/components/commands/moderation/Softban.js +++ b/structure/client/components/commands/moderation/Softban.js @@ -63,7 +63,11 @@ class SoftbanCommand extends Command { } ], guildOnly: true, - showUsage: true + showUsage: true, + throttling: { + usages: 2, + duration: 10 + } }); this.client = client; diff --git a/structure/client/components/commands/moderation/Unban.js b/structure/client/components/commands/moderation/Unban.js index a6a12d5..4149f00 100644 --- a/structure/client/components/commands/moderation/Unban.js +++ b/structure/client/components/commands/moderation/Unban.js @@ -28,7 +28,11 @@ class UnbanCommand extends Command { } ], guildOnly: true, - showUsage: true + showUsage: true, + throttling: { + usages: 2, + duration: 5 + } }); this.client = client; diff --git a/structure/client/components/commands/moderation/Unmute.js b/structure/client/components/commands/moderation/Unmute.js index e183ac3..ff19f3c 100644 --- a/structure/client/components/commands/moderation/Unmute.js +++ b/structure/client/components/commands/moderation/Unmute.js @@ -27,7 +27,11 @@ class UnmuteCommand extends Command { } ], guildOnly: true, - showUsage: true + showUsage: true, + throttling: { + usages: 2, + duration: 5 + } }); } diff --git a/structure/client/components/commands/moderation/Vckick.js b/structure/client/components/commands/moderation/Vckick.js index ff78a4c..6f91be7 100644 --- a/structure/client/components/commands/moderation/Vckick.js +++ b/structure/client/components/commands/moderation/Vckick.js @@ -63,7 +63,11 @@ class VckickCommand extends Command { } ], guildOnly: true, - showUsage: true + showUsage: true, + throttling: { + usages: 2, + duration: 5 + } }); this.client = client; diff --git a/structure/client/components/commands/moderation/Warn.js b/structure/client/components/commands/moderation/Warn.js index 6a4a759..e67786d 100644 --- a/structure/client/components/commands/moderation/Warn.js +++ b/structure/client/components/commands/moderation/Warn.js @@ -62,7 +62,11 @@ class WarnCommand extends Command { } ], guildOnly: true, - showUsage: true + showUsage: true, + throttling: { + usages: 2, + duration: 5 + } }); } diff --git a/structure/client/components/settings/moderation/AutoModeration.js b/structure/client/components/settings/moderation/AutoModeration.js new file mode 100644 index 0000000..3429517 --- /dev/null +++ b/structure/client/components/settings/moderation/AutoModeration.js @@ -0,0 +1,43 @@ +const { Setting } = require('../../../../interfaces/'); + +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: 3600 + } + } + } + } + }); + } + + async handle(message) { + + return { + msg: message.format('S_SILENT_SUCCESS', { value: "fuck yourself" }), + error: false + }; + + } + + fields(guild) { + return { + name: "》Enabled", + value: `\`${guild._settings.silent}\`` + }; + } + +} + +module.exports = AutoModerationSetting; \ No newline at end of file diff --git a/structure/client/components/settings/moderation/DmInfraction.js b/structure/client/components/settings/moderation/DmInfraction.js index ff9145b..8dd3fa7 100644 --- a/structure/client/components/settings/moderation/DmInfraction.js +++ b/structure/client/components/settings/moderation/DmInfraction.js @@ -17,7 +17,7 @@ class DmInfractionSetting extends Setting { enabled: true, onRemoved: true, //only Kick, Softban, and Ban custom: { - default: "You were **{infraction}** on the server `{server}`, your infraction details are below." + default: "You were **{infraction}** {from|on} the server `{server}`, your infraction details are below." //BAN: etc } } diff --git a/structure/extensions/Guild.js b/structure/extensions/Guild.js index 3cbf295..f953d54 100644 --- a/structure/extensions/Guild.js +++ b/structure/extensions/Guild.js @@ -54,7 +54,7 @@ const Guild = Structures.extend('Guild', (Guild) => { } } }); - this._settings = { ...{}, ...this.client.defaultConfig }; + this._settings = { ...{}, ...this.client.defaultConfig }; //Create a new object so settings that change the _settings value won't replicate it towards the defaultConfig. this._storageLog(`Database Delete (guild:${this.id}).`); } catch(error) { this._storageError(error); @@ -62,6 +62,34 @@ const Guild = Structures.extend('Guild', (Guild) => { return true; } + async _resetSettings() { + if(!this._settings) await this.settings(); + try { + await this.client.transactionHandler.send({ + provider: 'mongodb', + request: { + type: 'updateOne', + collection: 'guilds', + query: { + guildId: this.id + }, + data: { + caseId: this._settings.caseId, + guildId: this.id + }, + upsert: false + } + }); + this._settings = { + ...this.client.defaultConfig, + caseId: this._settings.caseId + }; + this._storageLog(`Database Reset (guild:${this.id}).`); + } catch(error) { + this._storageError(error); + } + } + async _updateSettings(data) { //Update property (upsert true) - updateOne if(!this._settings) await this.settings(); try { diff --git a/structure/extensions/GuildMember.js b/structure/extensions/GuildMember.js index 46818f7..2ede9e9 100644 --- a/structure/extensions/GuildMember.js +++ b/structure/extensions/GuildMember.js @@ -18,7 +18,7 @@ const GuildMember = Structures.extend('GuildMember', (GuildMember) => { const filtered = callbacks.filter((e) => e.infraction.type === type && e.infraction.target === this.id); - if(filtered.length > 0) return filtered.first(); + if(filtered.size > 0) return filtered.first(); const result = await this.client.transactionHandler.send({ //Checking for permanent mutes, won't show up in expirations. provider: 'mongodb', request: { diff --git a/structure/moderation/ModerationManager.js b/structure/moderation/ModerationManager.js index 5d12eef..0f932d3 100644 --- a/structure/moderation/ModerationManager.js +++ b/structure/moderation/ModerationManager.js @@ -130,11 +130,11 @@ class ModerationManager { } if(result && Constants.Hierarchy[infraction.type] <= Constants.Hierarchy[result.type]) { const escalation = new Constants.Infractions[result.type](this.client, { - executor: message.guild.me, + executor: message.member, guild: message.guild, channel: message.channel, - reason: stripIndents`${message.format('INFRACTION_AUTOMODESCALATION')} - ${reason}`, + reason: stripIndents`${reason} + *${message.format('INFRACTION_AUTOMODESCALATION')}*`, message, target, duration: result.length, @@ -201,6 +201,9 @@ class ModerationManager { } } + const succeededTargets = succeeded.map((s) => s.infraction.target); + const actions = await this._handleArguments(message, succeededTargets); //eslint-disable-line no-unused-vars + let string = ""; for(const [ type, data ] of Object.entries(successes)) { if(silent) continue; @@ -210,7 +213,7 @@ class ModerationManager { infraction: dictionary.past, targetType: `${targetType}${data.targets.length === 1 ? '' : 's'}`, target: data.targets.map((t) => `**${Util.escapeMarkdown(t)}**`).join(' '), - text: ` ${reason.length > 120 ? `for: \`${reason.substring(0, 117)}...\`` : `\`${reason}\``}` + text: type === original ? ` ${reason.length > 120 ? `for: \`${reason.substring(0, 117)}...\`` : `for: \`${reason}\``}` : ` because \`${reason}\`` })}`; type === original //eslint-disable-line ? string = `${str}\n${string}` @@ -249,7 +252,9 @@ class ModerationManager { let messages = await message.channel.messages.fetch({ limit: argument.value }); - messages = messages.filter((m) => users.includes(m.author.id) && m.deleteable); + messages = messages.filter((m) => { + return users.includes(m.author.id) && m.deletable; + }); try { await message.channel.bulkDelete(messages, true); } catch(err) {} //eslint-disable-line no-empty @@ -259,6 +264,7 @@ class ModerationManager { const responses = {}; for(const arg of Object.values(message.arguments)) { + // console.log(arg, targets); if(actions[arg.name]) { let action = actions[arg.name](message, arg, targets); if(action instanceof Promise) action = await action; diff --git a/structure/moderation/infractions/Addrole.js b/structure/moderation/infractions/Addrole.js index b618765..7ba5a14 100644 --- a/structure/moderation/infractions/Addrole.js +++ b/structure/moderation/infractions/Addrole.js @@ -10,7 +10,7 @@ class AddroleInfraction extends Infraction { targetType: 'user', message: opts.message, executor: opts.executor.user, - target: opts.target, + target: opts.target.user, reason: opts.reason || 'N/A', guild: opts.guild, channel: opts.channel, @@ -28,6 +28,8 @@ class AddroleInfraction extends Infraction { }); this.client = client; + this.member = opts.target; + this.executorMember = opts.executor; } @@ -51,7 +53,7 @@ class AddroleInfraction extends Infraction { return super._fail('C_ADDROLE_INSUFFICIENTPERMISSIONS'); } - const { highest } = this.executor.roles; + const { highest } = this.executorMember.roles; const filtered = this.data.roles.filter((r) => r.comparePositionTo(highest) < 0); if(filtered.length === 0) { return super._fail('C_ADDROLE_ROLEHIERARCHY'); diff --git a/structure/moderation/infractions/Kick.js b/structure/moderation/infractions/Kick.js index 73701e7..5199920 100644 --- a/structure/moderation/infractions/Kick.js +++ b/structure/moderation/infractions/Kick.js @@ -45,7 +45,12 @@ class Kick extends Infraction { verify() { - if(!this.member.kickable) return this._fail('C_KICK_INSUFFICIENTPERMISSIONS'); + const missing = this.channel.permissionsFor(this.guild.me).missing(['KICK_MEMBERS']); + if(missing.length > 0) { + return super._fail('C_KICK_INSUFFICIENTPERMISSIONS'); + } + + if(!this.member.kickable) return this._fail('C_KICK_CANNOTBEKICKED'); return super._verify(); } diff --git a/structure/moderation/infractions/Mute.js b/structure/moderation/infractions/Mute.js index 4daef0a..20c94e4 100644 --- a/structure/moderation/infractions/Mute.js +++ b/structure/moderation/infractions/Mute.js @@ -91,6 +91,11 @@ class Mute extends Infraction { async verify() { + const missing = this.channel.permissionsFor(this.guild.me).missing(['MANAGE_ROLES']); + if(missing.length > 0) { + return super._fail('C_MUTE_INSUFFICIENTPERMISSIONS'); + } + if(this.guild._settings.mute.type !== 2) { if(!this.guild._settings.mute.role) return this._fail('C_MUTE_NOMUTEROLE'); diff --git a/structure/moderation/infractions/Nickname.js b/structure/moderation/infractions/Nickname.js index 33473b1..f35a002 100644 --- a/structure/moderation/infractions/Nickname.js +++ b/structure/moderation/infractions/Nickname.js @@ -71,6 +71,11 @@ class Nickname extends Infraction { verify() { + const missing = this.channel.permissionsFor(this.guild.me).missing(['MANAGE_NICKNAMES']); + if(missing.length > 0) { + return super._fail('C_NICKNAME_INSUFFICIENTPERMISSIONS'); + } + const { highest } = this.member.roles; if(highest.comparePositionTo(this.guild.me.roles.highest) > 0) { return this._fail('C_NICKNAME_MISSINGPERMISSIONS'); diff --git a/structure/moderation/infractions/Prune.js b/structure/moderation/infractions/Prune.js index b1e96b3..6d48888 100644 --- a/structure/moderation/infractions/Prune.js +++ b/structure/moderation/infractions/Prune.js @@ -172,6 +172,17 @@ class Prune extends Infraction { description() { return `\n${this.guild.format('INFRACTION_DESCRIPTIONAMOUNT', { amount: this.data.amount })}`; } + + verify() { + + const missing = this.channel.permissionsFor(this.guild.me).missing(['MANAGE_MESSAGES']); + if(missing.length > 0) { + return super._fail('C_PRUNE_INSUFFICIENTPERMISSIONS'); + } + + return super._verify(); + + } } diff --git a/structure/moderation/infractions/Removerole.js b/structure/moderation/infractions/Removerole.js index be87bf5..ec72878 100644 --- a/structure/moderation/infractions/Removerole.js +++ b/structure/moderation/infractions/Removerole.js @@ -28,6 +28,8 @@ class RemoveroleInfraction extends Infraction { }); this.client = client; + this.member = opts.target; + this.executorMember = opts.executor; } @@ -51,10 +53,10 @@ class RemoveroleInfraction extends Infraction { return super._fail('C_REMOVEROLE_INSUFFICIENTPERMISSIONS'); } - const { highest } = this.executor.roles; + const { highest } = this.executorMember.roles; const filtered = this.data.roles.filter((r) => r.comparePositionTo(highest) < 0); if(filtered.length === 0) { - return super._fail('C_REMOVEROLE_ROLEHIERARCHY'); + return super._fail('C_REMOVEROLE_ROLEHIERARCHY', { plural: filtered.length === 1 ? '' : 's' }); } this.data.roles = filtered; diff --git a/structure/moderation/infractions/Slowmode.js b/structure/moderation/infractions/Slowmode.js index 45c2fce..762a1b4 100644 --- a/structure/moderation/infractions/Slowmode.js +++ b/structure/moderation/infractions/Slowmode.js @@ -54,6 +54,17 @@ class Slowmode extends Infraction { return `\n${this.guild.format('INFRACTION_DESCRIPTIONDURATION', { duration: Util.duration(this.data.seconds) })}`; } + verify() { + + const missing = this.channel.permissionsFor(this.guild.me).missing(['MANAGE_CHANNELS']); + if(missing.length > 0) { + return super._fail('C_SLOWMODE_INSUFFICIENTPERMISSIONS'); + } + + return super._verify(); + + } + } module.exports = Slowmode; \ No newline at end of file diff --git a/structure/moderation/infractions/Softban.js b/structure/moderation/infractions/Softban.js index 4b7e3c0..a0b741a 100644 --- a/structure/moderation/infractions/Softban.js +++ b/structure/moderation/infractions/Softban.js @@ -52,9 +52,14 @@ class Softban extends Infraction { } verify() { + + const missing = this.channel.permissionsFor(this.guild.me).missing(['BAN_MEMBERS']); + if(missing.length > 0) { + return super._fail('C_SOFTBAN_INSUFFICIENTPERMISSIONS'); + } if(this.member instanceof GuildMember) { - if(!this.member.bannable) return this._fail('C_SOFTBAN_INSUFFICIENTPERMISSIONS'); + if(!this.member.bannable) return this._fail('C_SOFTBAN_CANNOTBESOFTBANNED'); } return super._verify(); diff --git a/structure/moderation/infractions/Unban.js b/structure/moderation/infractions/Unban.js index 75124b1..35f731b 100644 --- a/structure/moderation/infractions/Unban.js +++ b/structure/moderation/infractions/Unban.js @@ -51,6 +51,12 @@ class Unban extends Infraction { } async verify() { + + const missing = this.channel.permissionsFor(this.guild.me).missing(['BAN_MEMBERS']); + if(missing.length > 0) { + return super._fail('C_UNBAN_INSUFFICIENTPERMISSIONS'); + } + let ban = null; try { ban = await this.guild.fetchBan(this.member.id); diff --git a/structure/moderation/infractions/Unmute.js b/structure/moderation/infractions/Unmute.js index c26e60e..39ecbfa 100644 --- a/structure/moderation/infractions/Unmute.js +++ b/structure/moderation/infractions/Unmute.js @@ -47,9 +47,9 @@ class Mute extends Infraction { } else { mute = await this.member._getExpiration('MUTE'); if(mute) { - removedRoles = mute.data.removedRoles; //eslint-disable-line prefer-destructuring - muteType = mute.data.muteType; //eslint-disable-line prefer-destructuring - role = mute.data.muteRole; //eslint-disable-line prefer-destructuring + removedRoles = mute.infraction.data.removedRoles; //eslint-disable-line prefer-destructuring + muteType = mute.infraction.data.muteType; //eslint-disable-line prefer-destructuring + role = mute.infraction.data.muteRole; //eslint-disable-line prefer-destructuring } } @@ -104,6 +104,19 @@ class Mute extends Infraction { } + async verify() { + + const missing = this.channel.permissionsFor(this.guild.me).missing(['MANAGE_ROLES']); + if(missing.length > 0) { + return super._fail('C_UNMUTE_INSUFFICIENTPERMISSIONS'); + } + + return super._verify(); + + } + + + } module.exports = Mute; \ No newline at end of file diff --git a/structure/moderation/infractions/Vckick.js b/structure/moderation/infractions/Vckick.js index 2ebda3a..37f355c 100644 --- a/structure/moderation/infractions/Vckick.js +++ b/structure/moderation/infractions/Vckick.js @@ -44,9 +44,15 @@ class Vckick extends Infraction { } verify() { - if(!this.member.voice.channel) return this._fail('C_VCKICK_NOCHANNEL'); + const missing = this.channel.permissionsFor(this.guild.me).missing(['MOVE_MEMBERS']); + if(missing.length > 0) { + return super._fail('C_VCKICK_INSUFFICIENTPERMISSIONS'); + } + + if(!this.member.voice.channel) return this._fail('C_VCKICK_NOCHANNEL'); return super._verify(); + } } diff --git a/structure/moderation/interfaces/Infraction.js b/structure/moderation/interfaces/Infraction.js index 532931c..6fc24e0 100644 --- a/structure/moderation/interfaces/Infraction.js +++ b/structure/moderation/interfaces/Infraction.js @@ -1,7 +1,8 @@ const { Util } = require('../../../util/'); const Constants = { - MaxCharacters: 1024 // Max embed description is 2048 characters, however some of those description characters are going to usernames, types, filler text, etc. + MaxCharacters: 1024, // Max embed description is 2048 characters, however some of those description characters are going to usernames, types, filler text, etc. + RemovedInfractions: ['BAN', 'SOFTBAN', 'KICK'] }; class Infraction { @@ -75,7 +76,8 @@ class Infraction { message = message .replace(/\{(guild|server)\}/ugim, this.guild.name) .replace(/\{user\}/ugim, this.target.tag) - .replace(/\{infraction\}/ugim, this.dictionary.past); //add more if you want i should probably add a better system for this... + .replace(/\{infraction\}/ugim, this.dictionary.past) + .replace(/\{from\|on\}/ugim, Constants.RemovedInfractions.includes(this.type) ? 'from' : 'on'); //add more if you want i should probably add a better system for this... try { this.target.send(message, { embed: this.embed(true) @@ -129,7 +131,7 @@ class Infraction { description += this.description(dm); } - if(!this.silent && (this.message || this.hyperlink)) { + if((!this.silent && (this.message || this.hyperlink)) && (dm && !Constants.RemovedInfractions.includes(this.type))) { description += `\n${this.guild.format('INFRACTION_DESCRIPTIONJUMPTO', { name: this.hyperlink ? 'Case' : 'Message', link: this.hyperlink ? this.hyperlink : `https://discord.com/channels/${this.guild.id}/${this.channel.id}/${this.message.id}` })}`; } @@ -220,7 +222,7 @@ class Infraction { } _verify() { - if(this.guild && this.guild._settings.protection) { + if(this.guild && this.guild._settings.protection.enabled) { const executorHighest = this.executor.roles.highest; const targetHighest = this.member.roles.highest; if(executorHighest.comparePositionTo(targetHighest) > 0) { diff --git a/util/Util.js b/util/Util.js index a0ab802..a863248 100644 --- a/util/Util.js +++ b/util/Util.js @@ -13,7 +13,7 @@ class Util { static downloadAsBuffer(source) { return new Promise((resolve, reject) => { - fetch(source).then(res => { + fetch(source).then((res) => { if(res.ok) resolve(res.buffer()); else reject(res.statusText); });