diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/extensions/discord.js/BushClientEvents.d.ts | 34 | ||||
-rw-r--r-- | src/lib/extensions/discord.js/BushGuild.ts | 68 | ||||
-rw-r--r-- | src/listeners/guild-custom/bushLockdown.ts | 27 | ||||
-rw-r--r-- | src/listeners/guild-custom/bushUnlockdown.ts | 27 | ||||
-rw-r--r-- | src/listeners/guild/syncUnbanPunishmentModel.ts (renamed from src/listeners/guild/syncUnban.ts) | 2 | ||||
-rw-r--r-- | src/listeners/member-custom/bushBan.ts (renamed from src/listeners/custom/bushBan.ts) | 2 | ||||
-rw-r--r-- | src/listeners/member-custom/bushBlock.ts | 36 | ||||
-rw-r--r-- | src/listeners/member-custom/bushKick.ts (renamed from src/listeners/custom/bushKick.ts) | 2 | ||||
-rw-r--r-- | src/listeners/member-custom/bushLevelUpdate.ts (renamed from src/listeners/custom/bushLevelUpdate.ts) | 2 | ||||
-rw-r--r-- | src/listeners/member-custom/bushMute.ts (renamed from src/listeners/custom/bushMute.ts) | 2 | ||||
-rw-r--r-- | src/listeners/member-custom/bushPunishRole.ts (renamed from src/listeners/custom/bushPunishRole.ts) | 2 | ||||
-rw-r--r-- | src/listeners/member-custom/bushPunishRoleRemove.ts (renamed from src/listeners/custom/bushPunishRoleRemove.ts) | 2 | ||||
-rw-r--r-- | src/listeners/member-custom/bushPurge.ts (renamed from src/listeners/custom/bushPurge.ts) | 2 | ||||
-rw-r--r-- | src/listeners/member-custom/bushUnban.ts (renamed from src/listeners/custom/bushUnban.ts) | 2 | ||||
-rw-r--r-- | src/listeners/member-custom/bushUnblock.ts | 32 | ||||
-rw-r--r-- | src/listeners/member-custom/bushUnmute.ts (renamed from src/listeners/custom/bushUnmute.ts) | 2 | ||||
-rw-r--r-- | src/listeners/member-custom/bushUpdateModlog.ts (renamed from src/listeners/custom/bushUpdateModlog.ts) | 2 | ||||
-rw-r--r-- | src/listeners/member-custom/bushUpdateSettings.ts (renamed from src/listeners/custom/bushUpdateSettings.ts) | 2 | ||||
-rw-r--r-- | src/listeners/member-custom/bushWarn.ts (renamed from src/listeners/custom/bushWarn.ts) | 2 | ||||
-rw-r--r-- | src/tasks/removeExpiredPunishements.ts | 12 |
20 files changed, 216 insertions, 46 deletions
diff --git a/src/lib/extensions/discord.js/BushClientEvents.d.ts b/src/lib/extensions/discord.js/BushClientEvents.d.ts index 10d70f9..b779991 100644 --- a/src/lib/extensions/discord.js/BushClientEvents.d.ts +++ b/src/lib/extensions/discord.js/BushClientEvents.d.ts @@ -6,6 +6,7 @@ import type { BushGuildBan, BushGuildEmoji, BushGuildMember, + BushGuildTextBasedChannel, BushMessage, BushMessageReaction, BushNewsChannel, @@ -171,6 +172,17 @@ export interface BushClientEvents extends AkairoClientEvents { dmSuccess?: boolean, evidence?: string ]; + bushBlock: [ + victim: BushGuildMember | BushUser, + moderator: BushUser, + guild: BushGuild, + reason: string | undefined, + caseID: string, + duration: number, + dmSuccess: boolean, + channel: BushGuildTextBasedChannel, + evidence?: string + ]; bushKick: [ victim: BushGuildMember, moderator: BushUser, @@ -224,6 +236,16 @@ export interface BushClientEvents extends AkairoClientEvents { dmSuccess: boolean, evidence?: string ]; + bushUnblock: [ + victim: BushGuildMember | BushUser, + moderator: BushUser, + guild: BushGuild, + reason: string | undefined, + caseID: string, + dmSuccess: boolean, + channel: BushGuildTextBasedChannel, + evidence?: string + ]; bushUnmute: [ victim: BushGuildMember, moderator: BushUser, @@ -263,6 +285,18 @@ export interface BushClientEvents extends AkairoClientEvents { currentXp: number, message: BushMessage & { guild: BushGuild } ]; + bushLockdown: [ + moderator: BushGuildMember, + reason?: string | undefined, + channel?: BushGuildTextBasedChannel, + all?: boolean + ]; + bushUnlockdown: [ + moderator: BushGuildMember, + reason?: string | undefined, + channel?: BushGuildTextBasedChannel, + all?: boolean + ]; } type Setting = diff --git a/src/lib/extensions/discord.js/BushGuild.ts b/src/lib/extensions/discord.js/BushGuild.ts index 299fdbc..b67c71b 100644 --- a/src/lib/extensions/discord.js/BushGuild.ts +++ b/src/lib/extensions/discord.js/BushGuild.ts @@ -290,40 +290,46 @@ export class BushGuild extends Guild { const moderator = this.members.resolve(options.moderator); if (!moderator) return 'moderator not found'; - const errors = new Collection<Snowflake, Error>(); - let successCount = 0; - - for (const _channel of mappedChannels) { - const channel = _channel!; - if (!channel.permissionsFor(this.me!.id)?.has(['MANAGE_CHANNELS'])) { - errors.set(channel.id, new Error('client no permission')); - continue; - } else if (!channel.permissionsFor(options.moderator)?.has(['MANAGE_CHANNELS'])) { - errors.set(channel.id, new Error('moderator no permission')); - continue; - } - const reason = `${options.unlock ? 'Unlocking' : 'Locking Down'} Channel | ${moderator.user.tag} | ${ - options.reason ?? 'No reason provided' - }`; - - if (channel.isThread()) { - const lockdownSuccess = await channel.parent?.permissionOverwrites - .edit(this.id, { SEND_MESSAGES_IN_THREADS: options.unlock ? null : false }, { reason }) - .catch((e) => e); - if (lockdownSuccess instanceof Error) errors.set(channel.id, lockdownSuccess); - else successCount++; - } else { - const lockdownSuccess = await channel.permissionOverwrites - .edit(this.id, { SEND_MESSAGES: options.unlock ? null : false }, { reason }) - .catch((e) => e); - if (lockdownSuccess instanceof Error) errors.set(channel.id, lockdownSuccess); - else successCount++; + const ret = await (async (): Promise<LockdownResponse> => { + const errors = new Collection<Snowflake, Error>(); + let successCount = 0; + + for (const _channel of mappedChannels) { + const channel = _channel!; + if (!channel.permissionsFor(this.me!.id)?.has(['MANAGE_CHANNELS'])) { + errors.set(channel.id, new Error('client no permission')); + continue; + } else if (!channel.permissionsFor(options.moderator)?.has(['MANAGE_CHANNELS'])) { + errors.set(channel.id, new Error('moderator no permission')); + continue; + } + + const reason = `[${options.unlock ? 'Unlockdown' : 'Lockdown'}] ${moderator.user.tag} | ${ + options.reason ?? 'No reason provided' + }`; + + if (channel.isThread()) { + const lockdownSuccess = await channel.parent?.permissionOverwrites + .edit(this.id, { SEND_MESSAGES_IN_THREADS: options.unlock ? null : false }, { reason }) + .catch((e) => e); + if (lockdownSuccess instanceof Error) errors.set(channel.id, lockdownSuccess); + else successCount++; + } else { + const lockdownSuccess = await channel.permissionOverwrites + .edit(this.id, { SEND_MESSAGES: options.unlock ? null : false }, { reason }) + .catch((e) => e); + if (lockdownSuccess instanceof Error) errors.set(channel.id, lockdownSuccess); + else successCount++; + } } - } - if (errors.size) return errors; - else return `success: ${successCount}`; + if (errors.size) return errors; + else return `success: ${successCount}`; + })(); + + client.emit(options.unlock ? 'bushUnlockdown' : 'bushLockdown', moderator, options.reason, options.channel); + return ret; } } diff --git a/src/listeners/guild-custom/bushLockdown.ts b/src/listeners/guild-custom/bushLockdown.ts new file mode 100644 index 0000000..be55a07 --- /dev/null +++ b/src/listeners/guild-custom/bushLockdown.ts @@ -0,0 +1,27 @@ +import { BushListener, type BushClientEvents } from '#lib'; +import { MessageEmbed } from 'discord.js'; + +export default class BushLockdownListener extends BushListener { + public constructor() { + super('bushLockdown', { + emitter: 'client', + event: 'bushLockdown', + category: 'guild-custom' + }); + } + + public override async exec(...[moderator, reason, channel, _all]: BushClientEvents['bushLockdown']) { + const logChannel = await moderator.guild.getLogChannel('moderation'); + if (!logChannel) return; + + const logEmbed = new MessageEmbed() + .setColor(util.colors.discord.BLURPLE) + .setTimestamp() + .addField('**Action**', `${'Lockdown'}`) + .addField('**Moderator**', `${moderator} (${moderator.user.tag})`) + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + .addField('**Reason**', `${reason || '[No Reason Provided]'}`) + .addField('**Channel**', `${channel?.id ? `<#${channel.id}>` : '[All Configured Channels]'}`); + return await logChannel.send({ embeds: [logEmbed] }); + } +} diff --git a/src/listeners/guild-custom/bushUnlockdown.ts b/src/listeners/guild-custom/bushUnlockdown.ts new file mode 100644 index 0000000..d5831c6 --- /dev/null +++ b/src/listeners/guild-custom/bushUnlockdown.ts @@ -0,0 +1,27 @@ +import { BushListener, type BushClientEvents } from '#lib'; +import { MessageEmbed } from 'discord.js'; + +export default class BushUnlockdownListener extends BushListener { + public constructor() { + super('bushUnlockdown', { + emitter: 'client', + event: 'bushUnlockdown', + category: 'guild-custom' + }); + } + + public override async exec(...[moderator, reason, channel, _all]: BushClientEvents['bushUnlockdown']) { + const logChannel = await moderator.guild.getLogChannel('moderation'); + if (!logChannel) return; + + const logEmbed = new MessageEmbed() + .setColor(util.colors.discord.BLURPLE) + .setTimestamp() + .addField('**Action**', `${'Unlockdown'}`) + .addField('**Moderator**', `${moderator} (${moderator.user.tag})`) + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + .addField('**Reason**', `${reason || '[No Reason Provided]'}`) + .addField('**Channel**', `${channel?.id ? `<#${channel.id}>` : '[All Configured Channels]'}`); + return await logChannel.send({ embeds: [logEmbed] }); + } +} diff --git a/src/listeners/guild/syncUnban.ts b/src/listeners/guild/syncUnbanPunishmentModel.ts index 01b2679..44f5bb4 100644 --- a/src/listeners/guild/syncUnban.ts +++ b/src/listeners/guild/syncUnbanPunishmentModel.ts @@ -2,7 +2,7 @@ import { ActivePunishment, ActivePunishmentType, BushListener, type BushClientEv export default class SyncUnbanListener extends BushListener { public constructor() { - super('guildBanRemove', { + super('syncUnbanPunishmentModel', { emitter: 'client', event: 'guildBanRemove', category: 'guild' diff --git a/src/listeners/custom/bushBan.ts b/src/listeners/member-custom/bushBan.ts index 59e010e..1243071 100644 --- a/src/listeners/custom/bushBan.ts +++ b/src/listeners/member-custom/bushBan.ts @@ -6,7 +6,7 @@ export default class BushBanListener extends BushListener { super('bushBan', { emitter: 'client', event: 'bushBan', - category: 'custom' + category: 'member-custom' }); } diff --git a/src/listeners/member-custom/bushBlock.ts b/src/listeners/member-custom/bushBlock.ts new file mode 100644 index 0000000..8e8adb6 --- /dev/null +++ b/src/listeners/member-custom/bushBlock.ts @@ -0,0 +1,36 @@ +import { BushListener, type BushClientEvents } from '#lib'; +import { GuildMember, MessageEmbed } from 'discord.js'; + +export default class BushBlockListener extends BushListener { + public constructor() { + super('bushBlock', { + emitter: 'client', + event: 'bushBlock', + category: 'member-custom' + }); + } + + public override async exec( + ...[victim, moderator, guild, reason, caseID, duration, dmSuccess, channel]: BushClientEvents['bushBlock'] + ) { + const logChannel = await guild.getLogChannel('moderation'); + if (!logChannel) return; + const user = victim instanceof GuildMember ? victim.user : victim; + + const logEmbed = new MessageEmbed() + .setColor(util.colors.discord.PURPLE) + .setTimestamp() + .setFooter({ text: `CaseID: ${caseID}` }) + .setAuthor({ name: user.tag, iconURL: user.avatarURL({ dynamic: true, format: 'png', size: 4096 }) ?? undefined }) + .addField('**Action**', `${duration ? 'Temp Block' : 'Perm Block'}`) + .addField('**Channel**', `<#${channel.id}>`) + .addField('**User**', `${user} (${user.tag})`) + .addField('**Moderator**', `${moderator} (${moderator.tag})`) + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + .addField('**Reason**', `${reason || '[No Reason Provided]'}`); + + if (duration) logEmbed.addField('**Duration**', `${util.humanizeDuration(duration) || duration}`); + if (dmSuccess === false) logEmbed.addField('**Additional Info**', 'Could not dm user.'); + return await logChannel.send({ embeds: [logEmbed] }); + } +} diff --git a/src/listeners/custom/bushKick.ts b/src/listeners/member-custom/bushKick.ts index 866aba4..26e9617 100644 --- a/src/listeners/custom/bushKick.ts +++ b/src/listeners/member-custom/bushKick.ts @@ -6,7 +6,7 @@ export default class BushKickListener extends BushListener { super('bushKick', { emitter: 'client', event: 'bushKick', - category: 'custom' + category: 'member-custom' }); } diff --git a/src/listeners/custom/bushLevelUpdate.ts b/src/listeners/member-custom/bushLevelUpdate.ts index 4504c45..18b0fc2 100644 --- a/src/listeners/custom/bushLevelUpdate.ts +++ b/src/listeners/member-custom/bushLevelUpdate.ts @@ -6,7 +6,7 @@ export default class BushLevelUpdateListener extends BushListener { super('bushLevelUpdate', { emitter: 'client', event: 'bushLevelUpdate', - category: 'custom' + category: 'member-custom' }); } diff --git a/src/listeners/custom/bushMute.ts b/src/listeners/member-custom/bushMute.ts index c25bd69..a8637fd 100644 --- a/src/listeners/custom/bushMute.ts +++ b/src/listeners/member-custom/bushMute.ts @@ -6,7 +6,7 @@ export default class BushMuteListener extends BushListener { super('bushMute', { emitter: 'client', event: 'bushMute', - category: 'custom' + category: 'member-custom' }); } diff --git a/src/listeners/custom/bushPunishRole.ts b/src/listeners/member-custom/bushPunishRole.ts index 3491166..731403b 100644 --- a/src/listeners/custom/bushPunishRole.ts +++ b/src/listeners/member-custom/bushPunishRole.ts @@ -6,7 +6,7 @@ export default class BushPunishRoleListener extends BushListener { super('bushPunishRole', { emitter: 'client', event: 'bushPunishRole', - category: 'custom' + category: 'member-custom' }); } diff --git a/src/listeners/custom/bushPunishRoleRemove.ts b/src/listeners/member-custom/bushPunishRoleRemove.ts index eb1ae71..7d88ec8 100644 --- a/src/listeners/custom/bushPunishRoleRemove.ts +++ b/src/listeners/member-custom/bushPunishRoleRemove.ts @@ -6,7 +6,7 @@ export default class BushPunishRoleRemoveListener extends BushListener { super('bushPunishRoleRemove', { emitter: 'client', event: 'bushPunishRoleRemove', - category: 'custom' + category: 'member-custom' }); } diff --git a/src/listeners/custom/bushPurge.ts b/src/listeners/member-custom/bushPurge.ts index 97824a4..8a1e0c5 100644 --- a/src/listeners/custom/bushPurge.ts +++ b/src/listeners/member-custom/bushPurge.ts @@ -6,7 +6,7 @@ export default class BushPurgeListener extends BushListener { super('bushPurge', { emitter: 'client', event: 'bushPurge', - category: 'custom' + category: 'member-custom' }); } diff --git a/src/listeners/custom/bushUnban.ts b/src/listeners/member-custom/bushUnban.ts index a59bcf0..e7024ef 100644 --- a/src/listeners/custom/bushUnban.ts +++ b/src/listeners/member-custom/bushUnban.ts @@ -6,7 +6,7 @@ export default class BushUnbanListener extends BushListener { super('bushUnban', { emitter: 'client', event: 'bushUnban', - category: 'custom' + category: 'member-custom' }); } diff --git a/src/listeners/member-custom/bushUnblock.ts b/src/listeners/member-custom/bushUnblock.ts new file mode 100644 index 0000000..e313025 --- /dev/null +++ b/src/listeners/member-custom/bushUnblock.ts @@ -0,0 +1,32 @@ +import { BushListener, type BushClientEvents } from '#lib'; +import { GuildMember, MessageEmbed } from 'discord.js'; + +export default class BushUnblockListener extends BushListener { + public constructor() { + super('bushUnblock', { + emitter: 'client', + event: 'bushUnblock', + category: 'member-custom' + }); + } + + public override async exec(...[victim, moderator, guild, reason, caseID, dmSuccess, channel]: BushClientEvents['bushUnblock']) { + const logChannel = await guild.getLogChannel('moderation'); + if (!logChannel) return; + const user = victim instanceof GuildMember ? victim.user : victim; + + const logEmbed = new MessageEmbed() + .setColor(util.colors.discord.GREEN) + .setTimestamp() + .setFooter({ text: `CaseID: ${caseID}` }) + .setAuthor({ name: user.tag, iconURL: user.avatarURL({ dynamic: true, format: 'png', size: 4096 }) ?? undefined }) + .addField('**Action**', `${'Unblock'}`) + .addField('**Channel**', `<#${channel.id}>`) + .addField('**User**', `${user} (${user.tag})`) + .addField('**Moderator**', `${moderator} (${moderator.tag})`) + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + .addField('**Reason**', `${reason || '[No Reason Provided]'}`); + if (dmSuccess === false) logEmbed.addField('**Additional Info**', 'Could not dm user.'); + return await logChannel.send({ embeds: [logEmbed] }); + } +} diff --git a/src/listeners/custom/bushUnmute.ts b/src/listeners/member-custom/bushUnmute.ts index bd14fcd..4fa808f 100644 --- a/src/listeners/custom/bushUnmute.ts +++ b/src/listeners/member-custom/bushUnmute.ts @@ -6,7 +6,7 @@ export default class BushUnmuteListener extends BushListener { super('bushUnmute', { emitter: 'client', event: 'bushUnmute', - category: 'custom' + category: 'member-custom' }); } diff --git a/src/listeners/custom/bushUpdateModlog.ts b/src/listeners/member-custom/bushUpdateModlog.ts index fa82dba..46910b9 100644 --- a/src/listeners/custom/bushUpdateModlog.ts +++ b/src/listeners/member-custom/bushUpdateModlog.ts @@ -6,7 +6,7 @@ export default class BushUpdateModlogListener extends BushListener { super('bushUpdateModlog', { emitter: 'client', event: 'bushUpdateModlog', - category: 'custom' + category: 'member-custom' }); } diff --git a/src/listeners/custom/bushUpdateSettings.ts b/src/listeners/member-custom/bushUpdateSettings.ts index c350bde..6a9c3d8 100644 --- a/src/listeners/custom/bushUpdateSettings.ts +++ b/src/listeners/member-custom/bushUpdateSettings.ts @@ -6,7 +6,7 @@ export default class BushUpdateSettingsListener extends BushListener { super('bushUpdateSettings', { emitter: 'client', event: 'bushUpdateSettings', - category: 'custom' + category: 'member-custom' }); } diff --git a/src/listeners/custom/bushWarn.ts b/src/listeners/member-custom/bushWarn.ts index 1554aa4..dba9fd8 100644 --- a/src/listeners/custom/bushWarn.ts +++ b/src/listeners/member-custom/bushWarn.ts @@ -6,7 +6,7 @@ export default class BushWarnListener extends BushListener { super('bushWarn', { emitter: 'client', event: 'bushWarn', - category: 'custom' + category: 'member-custom' }); } diff --git a/src/tasks/removeExpiredPunishements.ts b/src/tasks/removeExpiredPunishements.ts index 2b89f3d..3c18ebc 100644 --- a/src/tasks/removeExpiredPunishements.ts +++ b/src/tasks/removeExpiredPunishements.ts @@ -1,4 +1,5 @@ import { ActivePunishment, ActivePunishmentType, BushTask, type BushGuild, type BushUser } from '#lib'; +import assert from 'assert'; const { Op } = (await import('sequelize')).default; export default class RemoveExpiredPunishmentsTask extends BushTask { @@ -32,7 +33,7 @@ export default class RemoveExpiredPunishmentsTask extends BushTask { switch (entry.type) { case ActivePunishmentType.BAN: { - if (!user) throw new Error(`user is undefined`); + assert(user); const result = await guild.bushUnban({ user: user, reason: 'Punishment expired.' }); if (['success', 'user not banned'].includes(result)) await entry.destroy(); else throw new Error(result); @@ -40,7 +41,14 @@ export default class RemoveExpiredPunishmentsTask extends BushTask { break; } case ActivePunishmentType.BLOCK: { - //todo once blocks are added + if (!member) { + await entry.destroy(); // channel overrides are removed when the member leaves the guild + continue; + } + const result = await member.unblock({ reason: 'Punishment expired.', channel: entry.extraInfo }); + if (['success', 'user not blocked'].includes(result)) await entry.destroy(); + else throw new Error(result); + void client.logger.verbose(`removeExpiredPunishments`, `Unblocked ${entry.user}.`); break; } case ActivePunishmentType.MUTE: { |