aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/extensions/discord.js/BushClientEvents.d.ts34
-rw-r--r--src/lib/extensions/discord.js/BushGuild.ts68
-rw-r--r--src/listeners/guild-custom/bushLockdown.ts27
-rw-r--r--src/listeners/guild-custom/bushUnlockdown.ts27
-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.ts36
-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.ts32
-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.ts12
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: {