diff --git a/src/localization/en_gb/commands/en_gb_moderation.lang b/src/localization/en_gb/commands/en_gb_moderation.lang index 4215c0f..52b4261 100644 --- a/src/localization/en_gb/commands/en_gb_moderation.lang +++ b/src/localization/en_gb/commands/en_gb_moderation.lang @@ -194,6 +194,9 @@ The amount must be more than `1` and less than `300`. [C_PRUNE_INSUFFICIENTPERMISSIONS] I don't have permission to manage messages +[C_PRUNE_NON_TEXTCHANNEL] +Cannot prune a non-text based channel + [C_PRUNE_NOTFETCHED] I was unable to fetch any messages diff --git a/src/middleware/Logger.js b/src/middleware/Logger.js index 7d5e717..4400dc2 100644 --- a/src/middleware/Logger.js +++ b/src/middleware/Logger.js @@ -61,6 +61,8 @@ class Logger { write(type = 'info', string = '', shard = null, api = false, broadcast = false) { + if (string.includes('ECONNRESET')) return; + type = type.toLowerCase(); let color = Constants.Colors[type]; diff --git a/src/structure/client/ModerationManager.js b/src/structure/client/ModerationManager.js index 09b7bb2..50093c5 100644 --- a/src/structure/client/ModerationManager.js +++ b/src/structure/client/ModerationManager.js @@ -303,6 +303,14 @@ class ModerationManager { }; + if (target instanceof GuildMember) { + // The cached member is sometimes outdated, ensure we get the latest member so the perm checks don't fail + // Would help if members had a cached timestamp, might have to change this to work with a wrapper + target = await guild.members.fetch({ user: target, force: true }); + } else if (!(target instanceof User)) { + target = await wrapper.channels.fetch(target.id, { force: true }); + } + const infraction = new Infraction(this.client, { target, type, diff --git a/src/structure/components/commands/moderation/Case.js b/src/structure/components/commands/moderation/Case.js index 74a2ff5..1cb3a7f 100644 --- a/src/structure/components/commands/moderation/Case.js +++ b/src/structure/components/commands/moderation/Case.js @@ -90,7 +90,7 @@ class CaseCommand extends SlashCommand { if (guild._settings.modpoints.enabled) description += '\n' + invoker.format('COMMAND_CASE_MODPOINTS', { points: infraction.points, - expires: `` + expires: infraction.expiration ? `` : false }); description += '\n\n' + invoker.format('COMMAND_CASE_REASON', { reason: infraction.reason }); @@ -137,7 +137,7 @@ class CaseCommand extends SlashCommand { })); embed.footer = { - text: invoker.format('COMMAND_CASE_CHANGES_AMOUNT', { changes: infraction.changes.length }) + text: invoker.format('COMMAND_CASE_CHANGES_AMOUNT', { changes: infraction.changes?.length || 0 }) }; return embed; diff --git a/src/structure/components/commands/moderation/History.js b/src/structure/components/commands/moderation/History.js index 21c2a0b..6d0e0f4 100644 --- a/src/structure/components/commands/moderation/History.js +++ b/src/structure/components/commands/moderation/History.js @@ -161,14 +161,14 @@ class HistoryCommand extends SlashCommand { const infraction = results[i]; let target = null; if (infraction.targetType === 'USER') { - target = await this.client.resolver.resolveUser(infraction.target); + target = await this.client.users.fetch(infraction.target); } else { target = await guild.resolveChannel(infraction.target); } const executor = await this.client.resolver.resolveUser(infraction.executor); - let string = stripIndents`**Target:** ${Util.escapeMarkdown(target.tag || target.name)}${verbose?.value ? ` (${target.id})` : ''} + let string = stripIndents`**Target:** ${target ? Util.escapeMarkdown(target.tag || target.name) : 'Missing Target'}${verbose?.value ? ` (${target?.id})` : ''} **Moderator:** ${executor ? `${Util.escapeMarkdown(executor.tag)}${verbose?.value ? ` (${infraction.executor})` : ''}` : infraction.executor}`; if (infraction.data?.roleIds) { diff --git a/src/structure/components/observers/CommandHandler.js b/src/structure/components/observers/CommandHandler.js index 21abe1d..b595c58 100644 --- a/src/structure/components/observers/CommandHandler.js +++ b/src/structure/components/observers/CommandHandler.js @@ -192,7 +192,7 @@ class CommandHandler extends Observer { this._generateError(invoker, { error, type: 'command' }); } else { if (!(invoker.command instanceof SettingsCommand)) invoker.command.error(now); - this.logger.error(`Command ${debugstr} errored:\nGuild: ${invoker.guild?.name || 'dms'} (${invoker.guild?.id || ''})\nOptions:\n${Object.keys(options).map((key) => `[${key}: ${options[key]._rawValue}]`).join('\n')}\n${error.stack || error}`); + this.logger.error(`\n[${invoker.type.toUpperCase()}] Command ${debugstr} errored:\nGuild: ${invoker.guild?.name || 'dms'} (${invoker.guild?.id || ''})\nOptions:\n${Object.keys(options).map((key) => `[${key}: ${options[key].value} (${options[key]._rawValue})]`).join('\n')}\n${error.stack || error}`); this._generateError(invoker, { type: 'commandHandler' }); } return; diff --git a/src/structure/infractions/Mute.js b/src/structure/infractions/Mute.js index b93abfe..e8da4f2 100644 --- a/src/structure/infractions/Mute.js +++ b/src/structure/infractions/Mute.js @@ -161,7 +161,9 @@ class MuteInfraction extends Infraction { let message = null, error = false; - const { removedRoles, muteType, muteRole } = this.data; + const settings = await this.guild.settings(); + + const { removedRoles = [], muteType = settings.mute.type, muteRole = settings.mute.role } = this.data || {}; const member = await this.guild.memberWrapper(this.targetId).catch(() => null); const callback = await member.getCallback(this.type); if (callback) this.client.moderationManager.removeCallback(callback.infraction); diff --git a/src/structure/infractions/Prune.js b/src/structure/infractions/Prune.js index ca0a1b3..e9dc69b 100644 --- a/src/structure/infractions/Prune.js +++ b/src/structure/infractions/Prune.js @@ -172,11 +172,14 @@ class PruneInfraction extends Infraction { async fetchMessages(message, amount) { let fetched = new Collection(); + const msgMgr = this.channel.messages; + const after = this.arguments.after?.value || null; + const fetch = async (lastMessage, amount) => { - const messages = await this.target.messages.fetch({ + const messages = await msgMgr.fetch({ limit: amount > 100 ? 100 : amount, before: lastMessage, - after: this.arguments.after ? this.arguments.after.value : null + after }); fetched = fetched.concat(messages); @@ -198,9 +201,10 @@ class PruneInfraction extends Infraction { async verify() { const me = await this.guild.resolveMember(this.client.user); - const perms = this.target.permissionsFor(me); - if (perms.missing('ViewChannel', 'ReadMessageHistory').length) return this._fail('C_PRUNE_MISSING_ACCESS', true); - if (perms.missing('ManageMessages').length) return this._fail('C_PRUNE_INSUFFICIENTPERMISSIONS', true); + const perms = this.channel.permissionsFor(me); + if (perms.missing('ViewChannel', 'ReadMessageHistory').length) return this._fail('C_PRUNE_MISSING_ACCESS'); + if (perms.missing('ManageMessages').length) return this._fail('C_PRUNE_INSUFFICIENTPERMISSIONS'); + if (!this.channel.messages) return this._fail('C_PRUNE_NON_TEXTCHANNEL'); return super._verify();