aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/commands/dev/eval.ts2
-rw-r--r--src/commands/dev/servers.ts4
-rw-r--r--src/commands/moderation/removeReactionEmoji.ts2
-rw-r--r--src/lib/extensions/discord-akairo/BushClient.ts56
-rw-r--r--src/lib/extensions/discord-akairo/BushClientUtil.ts88
-rw-r--r--src/lib/extensions/discord-akairo/BushCommandHandler.ts41
-rw-r--r--src/lib/extensions/discord-akairo/BushListener.ts5
-rw-r--r--src/lib/extensions/discord.js/BushButtonInteraction.ts2
-rw-r--r--src/lib/extensions/discord.js/BushCommandInteraction.ts2
-rw-r--r--src/lib/extensions/discord.js/BushGuildMember.ts2
-rw-r--r--src/lib/extensions/discord.js/BushSelectMenuInteraction.ts2
-rw-r--r--src/lib/index.ts4
-rw-r--r--src/lib/models/ActivePunishment.ts (renamed from src/lib/models/PunishmentRole.ts)53
-rw-r--r--src/lib/models/Ban.ts80
-rw-r--r--src/lib/models/ModLog.ts5
-rw-r--r--src/lib/models/Mute.ts80
-rw-r--r--src/listeners/client/interactionCreate.ts4
-rw-r--r--src/listeners/commands/commandBlocked.ts4
-rw-r--r--src/listeners/commands/commandError.ts5
-rw-r--r--src/listeners/commands/commandMissingPermissions.ts10
-rw-r--r--src/listeners/commands/commandStarted.ts10
-rw-r--r--src/listeners/commands/slashBlocked.ts7
-rw-r--r--src/listeners/commands/slashCommandError.ts7
-rw-r--r--src/listeners/commands/slashMissingPermissions.ts25
-rw-r--r--src/listeners/commands/slashStarted.ts11
-rw-r--r--src/listeners/guild/syncUnban.ts13
-rw-r--r--src/listeners/message/level.ts5
-rw-r--r--src/listeners/other/consoleListener.ts16
-rw-r--r--src/tasks/removeExpiredPunishements.ts74
-rw-r--r--src/tasks/removePunishmentRole.ts37
-rw-r--r--src/tasks/unban.ts27
-rw-r--r--src/tasks/unmute.ts39
32 files changed, 254 insertions, 468 deletions
diff --git a/src/commands/dev/eval.ts b/src/commands/dev/eval.ts
index 0de0aa1..f8ba7e1 100644
--- a/src/commands/dev/eval.ts
+++ b/src/commands/dev/eval.ts
@@ -181,7 +181,7 @@ export default class EvalCommand extends BushCommand {
members = message.guild?.members,
roles = message.guild?.roles,
client = this.client,
- { Ban, Global, Guild, Level, ModLog, StickyRole } = await import('@lib'),
+ { ActivePunishment, Global, Guild, Level, ModLog, StickyRole } = await import('@lib'),
{
ButtonInteraction,
Collector,
diff --git a/src/commands/dev/servers.ts b/src/commands/dev/servers.ts
index 08f74e8..3986451 100644
--- a/src/commands/dev/servers.ts
+++ b/src/commands/dev/servers.ts
@@ -4,7 +4,7 @@ import { BushCommand, BushMessage, BushSlashMessage } from '../../lib';
export default class ServersCommand extends BushCommand {
public constructor() {
super('servers', {
- aliases: ['servers'],
+ aliases: ['servers', 'guilds'],
category: 'dev',
description: {
content: 'Displays all the severs the bot is in',
@@ -37,7 +37,7 @@ export default class ServersCommand extends BushCommand {
`**ID:** ${g.id}\n**Owner:** ${owner ? owner : g.ownerId}\n**Members:** ${g.memberCount.toLocaleString()}`,
false
)
- .setTitle('Server List')
+ .setTitle(`Server List [${this.client.guilds.cache.size}]`)
.setColor(this.client.util.colors.default);
});
embeds.push(embed);
diff --git a/src/commands/moderation/removeReactionEmoji.ts b/src/commands/moderation/removeReactionEmoji.ts
index 3d274e1..b0079c6 100644
--- a/src/commands/moderation/removeReactionEmoji.ts
+++ b/src/commands/moderation/removeReactionEmoji.ts
@@ -13,7 +13,7 @@ export default class RemoveReactionEmojiCommand extends BushCommand {
examples: ['removereactionemoji 791413052347252786 <:omegaclown:782630946435366942>']
},
clientPermissions: ['MANAGE_MESSAGES', 'SEND_MESSAGES', 'EMBED_LINKS'],
- userPermissions: ['MANAGE_MESSAGES', 'MANAGE_EMOJIS'], // Can't undo the removal of 1000s of reactions
+ userPermissions: ['MANAGE_MESSAGES', 'MANAGE_EMOJIS_AND_STICKERS'], // Can't undo the removal of 1000s of reactions
args: [
{
id: 'messageToRemoveFrom',
diff --git a/src/lib/extensions/discord-akairo/BushClient.ts b/src/lib/extensions/discord-akairo/BushClient.ts
index 66204ac..8eec3ce 100644
--- a/src/lib/extensions/discord-akairo/BushClient.ts
+++ b/src/lib/extensions/discord-akairo/BushClient.ts
@@ -18,13 +18,11 @@ import { Sequelize } from 'sequelize';
import { contentWithDurationTypeCaster } from '../../../arguments/contentWithDuration';
import { durationTypeCaster } from '../../../arguments/duration';
import { UpdateCacheTask } from '../../../tasks/updateCache';
-import { Ban } from '../../models/Ban';
+import { ActivePunishment } from '../../models/ActivePunishment';
import { Global } from '../../models/Global';
import { Guild as GuildModel } from '../../models/Guild';
import { Level } from '../../models/Level';
import { ModLog } from '../../models/ModLog';
-import { Mute } from '../../models/Mute';
-import { PunishmentRole } from '../../models/PunishmentRole';
import { StickyRole } from '../../models/StickyRole';
import { AllowedMentions } from '../../utils/AllowedMentions';
import { BushCache } from '../../utils/BushCache';
@@ -107,39 +105,23 @@ export class BushClient extends AkairoClient {
public constants = BushConstants;
public cache = BushCache;
public constructor(config: Config) {
- super(
- {
- ownerID: config.owners,
- intents: Object.values(Intents.FLAGS).reduce((acc, p) => acc | p, 0),
- presence: {
- activities: [
- {
- name: 'Beep Boop',
- type: 'WATCHING'
- }
- ],
- status: 'online'
- }
+ super({
+ ownerID: config.owners,
+ intents: Object.values(Intents.FLAGS).reduce((acc, p) => acc | p, 0),
+ presence: {
+ activities: [
+ {
+ name: 'Beep Boop',
+ type: 'WATCHING'
+ }
+ ],
+ status: 'online'
},
- {
- allowedMentions: AllowedMentions.users(), // No everyone or role mentions by default
- intents: Object.values(Intents.FLAGS).reduce((acc, p) => acc | p, 0),
- presence: {
- activities: [
- {
- name: 'Beep Boop',
- type: 'WATCHING'
- }
- ],
- status: 'online'
- }
- }
- );
+ http: { api: 'https://canary.discord.com/api' },
+ allowedMentions: AllowedMentions.users() // No everyone or role mentions by default
+ });
- // Set token
this.token = config.token;
-
- // Set config
this.config = config;
// Create listener handler
@@ -170,7 +152,7 @@ export class BushClient extends AkairoClient {
allowMention: true,
handleEdits: true,
commandUtil: true,
- commandUtilLifetime: 300_000,
+ commandUtilLifetime: 300_000, // 5 minutes
argumentDefaults: {
prompt: {
start: 'Placeholder argument prompt. If you see this please tell my developers.',
@@ -259,11 +241,9 @@ export class BushClient extends AkairoClient {
Global.initModel(this.db);
GuildModel.initModel(this.db, this);
ModLog.initModel(this.db);
- Ban.initModel(this.db);
- Mute.initModel(this.db);
+ ActivePunishment.initModel(this.db);
Level.initModel(this.db);
StickyRole.initModel(this.db);
- PunishmentRole.initModel(this.db);
await this.db.sync({ alter: true }); // Sync all tables to fix everything if updated
await this.console.success('Startup', `Successfully connected to <<database>>.`, false);
} catch (e) {
@@ -277,7 +257,7 @@ export class BushClient extends AkairoClient {
/** Starts the bot */
public async start(): Promise<void> {
- global.client = this;
+ global.client = this; // makes the client a global object
try {
await this._init();
diff --git a/src/lib/extensions/discord-akairo/BushClientUtil.ts b/src/lib/extensions/discord-akairo/BushClientUtil.ts
index 0e3a904..306e049 100644
--- a/src/lib/extensions/discord-akairo/BushClientUtil.ts
+++ b/src/lib/extensions/discord-akairo/BushClientUtil.ts
@@ -2,7 +2,6 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import {
- Ban,
BushCache,
BushClient,
BushConstants,
@@ -14,9 +13,7 @@ import {
Global,
Guild,
ModLog,
- ModLogType,
- Mute,
- PunishmentRole
+ ModLogType
} from '@lib';
import { exec } from 'child_process';
import { ClientUtil } from 'discord-akairo';
@@ -43,8 +40,8 @@ import {
} from 'discord.js';
import got from 'got';
import humanizeDuration from 'humanize-duration';
-import { Op } from 'sequelize';
import { promisify } from 'util';
+import { ActivePunishment, ActivePunishmentType } from '../../models/ActivePunishment';
import { BushNewsChannel } from '../discord.js/BushNewsChannel';
import { BushTextChannel } from '../discord.js/BushTextChannel';
import { BushUserResolvable } from './BushClient';
@@ -96,12 +93,6 @@ interface bushColors {
orange: '#E86100';
}
-interface punishmentModels {
- mute: Mute;
- ban: Ban;
- role: PunishmentRole;
-}
-
interface MojangProfile {
username: string;
uuid: string;
@@ -664,22 +655,21 @@ export class BushClientUtil extends ClientUtil {
}
public async createPunishmentEntry(options: {
- type: 'mute' | 'ban' | 'role';
+ type: 'mute' | 'ban' | 'role' | 'block';
user: BushGuildMemberResolvable;
duration: number;
guild: BushGuildResolvable;
modlog: string;
- role?: Snowflake;
- }): Promise<Mute | Ban | PunishmentRole> {
- const dbModel = this.findPunishmentModel(options.type);
+ extraInfo?: Snowflake;
+ }): Promise<ActivePunishment> {
const expires = options.duration ? new Date(new Date().getTime() + options.duration) : null;
const user = this.client.users.resolveId(options.user);
const guild = this.client.guilds.resolveId(options.guild);
+ const type = this.findTypeEnum(options.type);
- const entry =
- options.type === 'role'
- ? (dbModel as typeof PunishmentRole).build({ user, guild, expires, modlog: options.modlog, role: options.role })
- : dbModel.build({ user, guild, expires, modlog: options.modlog });
+ const entry = options.extraInfo
+ ? ActivePunishment.build({ user, type, guild, expires, modlog: options.modlog, extraInfo: options.extraInfo })
+ : ActivePunishment.build({ user, type, guild, expires, modlog: options.modlog });
return await entry.save().catch((e) => {
this.client.console.error('createPunishmentEntry', e?.stack || e);
return null;
@@ -687,28 +677,23 @@ export class BushClientUtil extends ClientUtil {
}
public async removePunishmentEntry(options: {
- type: 'mute' | 'ban' | 'role';
+ type: 'mute' | 'ban' | 'role' | 'block';
user: BushGuildMemberResolvable;
guild: BushGuildResolvable;
}): Promise<boolean> {
- const dbModel = this.findPunishmentModel(options.type);
const user = this.client.users.resolveId(options.user);
const guild = this.client.guilds.resolveId(options.guild);
+ const type = this.findTypeEnum(options.type);
let success = true;
- const entries = await dbModel
- .findAll({
- // finding all cases of a certain type incase there were duplicates or something
- where: {
- user,
- guild
- }
- })
- .catch((e) => {
- this.client.console.error('removePunishmentEntry', e?.stack || e);
- success = false;
- });
+ const entries = await ActivePunishment.findAll({
+ // finding all cases of a certain type incase there were duplicates or something
+ where: { user, guild, type }
+ }).catch((e) => {
+ this.client.console.error('removePunishmentEntry', e?.stack || e);
+ success = false;
+ });
if (entries) {
entries.forEach(async (entry) => {
await entry.destroy().catch((e) => {
@@ -720,33 +705,14 @@ export class BushClientUtil extends ClientUtil {
return success;
}
- public async findExpiredEntries<K extends keyof punishmentModels>(type: K): Promise<punishmentModels[K][]> {
- const dbModel = this.findPunishmentModel(type);
- //@ts-ignore: stfu idc
- return await dbModel.findAll({
- where: {
- [Op.and]: [
- {
- expires: {
- [Op.lt]: new Date() // Find all rows with an expiry date before now
- }
- }
- ]
- }
- });
- }
-
- private findPunishmentModel<K extends keyof punishmentModels>(type: K): typeof Mute | typeof Ban | typeof PunishmentRole {
- switch (type) {
- case 'mute':
- return Mute;
- case 'ban':
- return Ban;
- case 'role':
- return PunishmentRole;
- default:
- throw 'choose a valid punishment entry type';
- }
+ private findTypeEnum(type: 'mute' | 'ban' | 'role' | 'block') {
+ const typeMap = {
+ ['mute']: ActivePunishmentType.MUTE,
+ ['ban']: ActivePunishmentType.BAN,
+ ['role']: ActivePunishmentType.ROLE,
+ ['block']: ActivePunishmentType.BLOCK
+ };
+ return typeMap[type];
}
public humanizeDuration(duration: number): string {
@@ -782,5 +748,7 @@ export class BushClientUtil extends ClientUtil {
return arrByte[1] + ', ' + arrByte[2] + ', ' + arrByte[3];
}
+ /* eslint-disable @typescript-eslint/no-unused-vars */
public async lockdownChannel(options: { channel: BushTextChannel | BushNewsChannel; moderator: BushUserResolvable }) {}
+ /* eslint-enable @typescript-eslint/no-unused-vars */
}
diff --git a/src/lib/extensions/discord-akairo/BushCommandHandler.ts b/src/lib/extensions/discord-akairo/BushCommandHandler.ts
index 09baf2e..dacd17f 100644
--- a/src/lib/extensions/discord-akairo/BushCommandHandler.ts
+++ b/src/lib/extensions/discord-akairo/BushCommandHandler.ts
@@ -1,15 +1,26 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
-import { Category, CommandHandler, CommandHandlerOptions } from 'discord-akairo';
-import { Collection } from 'discord.js';
+import { Category, CommandHandler, CommandHandlerEvents, CommandHandlerOptions } from 'discord-akairo';
+import { Collection, PermissionString } from 'discord.js';
import { BushConstants } from '../../utils/BushConstants';
import { BushMessage } from '../discord.js/BushMessage';
import { BushClient } from './BushClient';
import { BushCommand } from './BushCommand';
+import { BushSlashMessage } from './BushSlashMessage';
export type BushCommandHandlerOptions = CommandHandlerOptions;
-const CommandHandlerEvents = BushConstants.CommandHandlerEvents;
-const BlockedReasons = BushConstants.BlockedReasons;
+const commandHandlerEvents = BushConstants.CommandHandlerEvents;
+const blockedReasons = BushConstants.BlockedReasons;
+
+export interface BushCommandHandlerEvents extends CommandHandlerEvents {
+ commandBlocked: [message: BushMessage, command: BushCommand, reason: string];
+
+ missingPermissions: [message: BushMessage, command: BushCommand, type: 'client' | 'user', missing: Array<PermissionString>];
+
+ slashBlocked: [message: BushSlashMessage, command: BushCommand, reason: string];
+
+ slashMissingPermissions: [message: BushSlashMessage, command: BushCommand, type: 'client' | 'user', missing: Array<PermissionString>];
+}
export class BushCommandHandler extends CommandHandler {
public declare client: BushClient;
@@ -24,10 +35,10 @@ export class BushCommandHandler extends CommandHandler {
const isOwner = this.client.isOwner(message.author);
if (!isOwner) {
this.emit(
- slash ? CommandHandlerEvents.SLASH_BLOCKED : CommandHandlerEvents.COMMAND_BLOCKED,
+ slash ? commandHandlerEvents.SLASH_BLOCKED : commandHandlerEvents.COMMAND_BLOCKED,
message,
command,
- BlockedReasons.OWNER
+ blockedReasons.OWNER
);
return true;
}
@@ -37,10 +48,10 @@ export class BushCommandHandler extends CommandHandler {
const isSuperUser = this.client.isSuperUser(message.author);
if (!isSuperUser) {
this.emit(
- slash ? CommandHandlerEvents.SLASH_BLOCKED : CommandHandlerEvents.COMMAND_BLOCKED,
+ slash ? commandHandlerEvents.SLASH_BLOCKED : commandHandlerEvents.COMMAND_BLOCKED,
message,
command,
- BlockedReasons.OWNER
+ blockedReasons.OWNER
);
return true;
}
@@ -48,32 +59,32 @@ export class BushCommandHandler extends CommandHandler {
if (command.channel === 'guild' && !message.guild) {
this.emit(
- slash ? CommandHandlerEvents.SLASH_BLOCKED : CommandHandlerEvents.COMMAND_BLOCKED,
+ slash ? commandHandlerEvents.SLASH_BLOCKED : commandHandlerEvents.COMMAND_BLOCKED,
message,
command,
- BlockedReasons.GUILD
+ blockedReasons.GUILD
);
return true;
}
if (command.channel === 'dm' && message.guild) {
this.emit(
- slash ? CommandHandlerEvents.SLASH_BLOCKED : CommandHandlerEvents.COMMAND_BLOCKED,
+ slash ? commandHandlerEvents.SLASH_BLOCKED : commandHandlerEvents.COMMAND_BLOCKED,
message,
command,
- BlockedReasons.DM
+ blockedReasons.DM
);
return true;
}
if (command.restrictedChannels?.length && message.channel) {
if (!command.restrictedChannels.includes(message.channel.id)) {
- this.emit(CommandHandlerEvents.COMMAND_BLOCKED, message, command, BlockedReasons.RESTRICTED_CHANNEL);
+ this.emit(commandHandlerEvents.COMMAND_BLOCKED, message, command, blockedReasons.RESTRICTED_CHANNEL);
return true;
}
}
if (command.restrictedGuilds?.length && message.guild) {
if (!command.restrictedGuilds.includes(message.guild.id)) {
- this.emit(CommandHandlerEvents.COMMAND_BLOCKED, message, command, BlockedReasons.RESTRICTED_GUILD);
+ this.emit(commandHandlerEvents.COMMAND_BLOCKED, message, command, blockedReasons.RESTRICTED_GUILD);
return true;
}
}
@@ -82,7 +93,7 @@ export class BushCommandHandler extends CommandHandler {
}
const reason = this.inhibitorHandler ? await this.inhibitorHandler.test('post', message, command) : null;
if (reason != null) {
- this.emit(CommandHandlerEvents.COMMAND_BLOCKED, message, command, reason);
+ this.emit(commandHandlerEvents.COMMAND_BLOCKED, message, command, reason);
return true;
}
return !!this.runCooldowns(message, command);
diff --git a/src/lib/extensions/discord-akairo/BushListener.ts b/src/lib/extensions/discord-akairo/BushListener.ts
index e555e89..2583e85 100644
--- a/src/lib/extensions/discord-akairo/BushListener.ts
+++ b/src/lib/extensions/discord-akairo/BushListener.ts
@@ -1,6 +1,9 @@
import { Listener } from 'discord-akairo';
+import EventEmitter from 'events';
import { BushClient } from './BushClient';
-
export class BushListener extends Listener {
public declare client: BushClient;
+ public constructor(id: string, options?:{emitter: string|EventEmitter, event: string, type?: 'on'|'once', category?: string}){
+ super(id, options)
+ }
}
diff --git a/src/lib/extensions/discord.js/BushButtonInteraction.ts b/src/lib/extensions/discord.js/BushButtonInteraction.ts
index 3a54f61..846786c 100644
--- a/src/lib/extensions/discord.js/BushButtonInteraction.ts
+++ b/src/lib/extensions/discord.js/BushButtonInteraction.ts
@@ -1,4 +1,4 @@
-import { APIInteractionGuildMember } from 'discord-api-types/v8';
+import { APIInteractionGuildMember } from 'discord-api-types/v9';
import { ButtonInteraction, PartialDMChannel } from 'discord.js';
import { BushClient } from '../discord-akairo/BushClient';
import { BushDMChannel } from './BushDMChannel';
diff --git a/src/lib/extensions/discord.js/BushCommandInteraction.ts b/src/lib/extensions/discord.js/BushCommandInteraction.ts
index 84c0707..e4fdb53 100644
--- a/src/lib/extensions/discord.js/BushCommandInteraction.ts
+++ b/src/lib/extensions/discord.js/BushCommandInteraction.ts
@@ -1,4 +1,4 @@
-import { APIInteractionGuildMember } from 'discord-api-types/v8';
+import { APIInteractionGuildMember } from 'discord-api-types/v9';
import {
ApplicationCommand,
CommandInteraction,
diff --git a/src/lib/extensions/discord.js/BushGuildMember.ts b/src/lib/extensions/discord.js/BushGuildMember.ts
index 40e4a3a..50875cc 100644
--- a/src/lib/extensions/discord.js/BushGuildMember.ts
+++ b/src/lib/extensions/discord.js/BushGuildMember.ts
@@ -137,7 +137,7 @@ export class BushGuildMember extends GuildMember {
guild: this.guild,
duration: options.duration,
modlog: modlog.id,
- role: options.role.id
+ extraInfo: options.role.id
})
.catch(() => null);
if (!punishmentEntrySuccess) return 'error creating role entry';
diff --git a/src/lib/extensions/discord.js/BushSelectMenuInteraction.ts b/src/lib/extensions/discord.js/BushSelectMenuInteraction.ts
index 1dd1638..18db8ef 100644
--- a/src/lib/extensions/discord.js/BushSelectMenuInteraction.ts
+++ b/src/lib/extensions/discord.js/BushSelectMenuInteraction.ts
@@ -1,4 +1,4 @@
-import { APIInteractionGuildMember } from 'discord-api-types/v8';
+import { APIInteractionGuildMember } from 'discord-api-types/v9';
import { PartialDMChannel, SelectMenuInteraction } from 'discord.js';
import { BushClient } from '../discord-akairo/BushClient';
import { BushDMChannel } from './BushDMChannel';
diff --git a/src/lib/index.ts b/src/lib/index.ts
index 1059e2b..73cee56 100644
--- a/src/lib/index.ts
+++ b/src/lib/index.ts
@@ -46,14 +46,12 @@ export * from './extensions/discord.js/BushThreadMemberManager';
export * from './extensions/discord.js/BushUser';
export * from './extensions/discord.js/BushVoiceChannel';
export * from './extensions/discord.js/BushVoiceState';
-export * from './models/Ban';
+export * from './models/ActivePunishment';
export * from './models/BaseModel';
export * from './models/Global';
export * from './models/Guild';
export * from './models/Level';
export * from './models/ModLog';
-export * from './models/Mute';
-export * from './models/PunishmentRole';
export * from './models/StickyRole';
export * from './utils/AllowedMentions';
export * from './utils/BushCache';
diff --git a/src/lib/models/PunishmentRole.ts b/src/lib/models/ActivePunishment.ts
index 0b54f31..9fcafbe 100644
--- a/src/lib/models/PunishmentRole.ts
+++ b/src/lib/models/ActivePunishment.ts
@@ -3,54 +3,67 @@ import { DataTypes, Sequelize } from 'sequelize';
import { v4 as uuidv4 } from 'uuid';
import { BaseModel } from './BaseModel';
-export interface PunishmentRoleModel {
+export enum ActivePunishmentType {
+ BAN = 'BAN',
+ MUTE = 'MUTE',
+ ROLE = 'ROLE',
+ BLOCK = 'BLOCK'
+}
+
+export interface ActivePunishmentModel {
id: string;
+ type: ActivePunishmentType;
user: Snowflake;
- role: Snowflake;
guild: Snowflake;
+ extraInfo: Snowflake;
expires: Date;
modlog: string;
}
-export interface PunishmentRoleModelCreationAttributes {
+export interface ActivePunishmentModelCreationAttributes {
id?: string;
+ type: ActivePunishmentType;
user: Snowflake;
- role?: Snowflake;
guild: Snowflake;
+ extraInfo?: Snowflake;
expires?: Date;
modlog: string;
}
-export class PunishmentRole
- extends BaseModel<PunishmentRoleModel, PunishmentRoleModelCreationAttributes>
- implements PunishmentRoleModel
+export class ActivePunishment
+ extends BaseModel<ActivePunishmentModel, ActivePunishmentModelCreationAttributes>
+ implements ActivePunishmentModel
{
/**
- * The ID of this punishment role (no real use just for a primary key)
+ * The ID of this punishment (no real use just for a primary key)
*/
id: string;
/**
- * The user who received a role
+ * The type of punishment.
*/
- user: Snowflake;
+ type: ActivePunishmentType;
/**
- * The role added to the user.
+ * The user who is punished.
*/
- role: Snowflake;
+ user: Snowflake;
/**
- * The guild they received a role in
+ * The guild they are punished in.
*/
guild: Snowflake;
/**
- * The date at which this role expires and should be removed (optional)
+ * Additional info about the punishment if applicable. The channel id for channel blocks and role for punishment roles.
+ */
+ extraInfo: Snowflake;
+ /**
+ * The date when this punishment expires (optional).
*/
expires: Date | null;
/**
- * The ref to the modlog entry
+ * The reference to the modlog entry.
*/
modlog: string;
static initModel(sequelize: Sequelize): void {
- PunishmentRole.init(
+ ActivePunishment.init(
{
id: {
type: DataTypes.STRING,
@@ -58,11 +71,11 @@ export class PunishmentRole
allowNull: false,
defaultValue: uuidv4
},
- user: {
+ type: {
type: DataTypes.STRING,
allowNull: false
},
- role: {
+ user: {
type: DataTypes.STRING,
allowNull: false
},
@@ -74,6 +87,10 @@ export class PunishmentRole
key: 'id'
}
},
+ extraInfo: {
+ type: DataTypes.DATE,
+ allowNull: true
+ },
expires: {
type: DataTypes.DATE,
allowNull: true
diff --git a/src/lib/models/Ban.ts b/src/lib/models/Ban.ts
deleted file mode 100644
index 1bdda6f..0000000
--- a/src/lib/models/Ban.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-import { Snowflake } from 'discord.js';
-import { DataTypes, Sequelize } from 'sequelize';
-import { v4 as uuidv4 } from 'uuid';
-import { BaseModel } from './BaseModel';
-
-export interface BanModel {
- id: string;
- user: Snowflake;
- guild: Snowflake;
- expires: Date;
- modlog: string;
-}
-export interface BanModelCreationAttributes {
- id?: string;
- user: Snowflake;
- guild: Snowflake;
- expires?: Date;
- modlog: string;
-}
-
-export class Ban extends BaseModel<BanModel, BanModelCreationAttributes> implements BanModel {
- /**
- * The ID of this ban (no real use just for a primary key)
- */
- id: string;
- /**
- * The user who is banned
- */
- user: Snowflake;
- /**
- * The guild they are banned from
- */
- guild: Snowflake;
- /**
- * The date at which this ban expires and should be unbanned (optional)
- */
- expires: Date | null;
- /**
- * The ref to the modlog entry
- */
- modlog: string;
-
- static initModel(sequelize: Sequelize): void {
- Ban.init(
- {
- id: {
- type: DataTypes.STRING,
- primaryKey: true,
- allowNull: false,
- defaultValue: uuidv4
- },
- user: {
- type: DataTypes.STRING,
- allowNull: false
- },
- guild: {
- type: DataTypes.STRING,
- allowNull: false,
- references: {
- model: 'Guilds',
- key: 'id'
- }
- },
- expires: {
- type: DataTypes.DATE,
- allowNull: true
- },
- modlog: {
- type: DataTypes.STRING,
- allowNull: false,
- references: {
- model: 'ModLogs',
- key: 'id'
- }
- }
- },
- { sequelize: sequelize }
- );
- }
-}
diff --git a/src/lib/models/ModLog.ts b/src/lib/models/ModLog.ts
index 40dc86d..3375751 100644
--- a/src/lib/models/ModLog.ts
+++ b/src/lib/models/ModLog.ts
@@ -14,7 +14,10 @@ export enum ModLogType {
WARN = 'WARN',
PERM_PUNISHMENT_ROLE = 'PERM_PUNISHMENT_ROLE',
TEMP_PUNISHMENT_ROLE = 'TEMP_PUNISHMENT_ROLE',
- REMOVE_PUNISHMENT_ROLE = 'REMOVE_PUNISHMENT_ROLE'
+ REMOVE_PUNISHMENT_ROLE = 'REMOVE_PUNISHMENT_ROLE',
+ PERM_CHANNEL_BLOCK = 'PERM_CHANNEL_BLOCK',
+ TEMP_CHANNEL_BLOCK = 'TEMP_CHANNEL_BLOCK',
+ CHANNEL_UNBLOCK = 'CHANNEL_UNBLOCK'
}
export interface ModLogModel {
diff --git a/src/lib/models/Mute.ts b/src/lib/models/Mute.ts
deleted file mode 100644
index 4208d02..0000000
--- a/src/lib/models/Mute.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-import { Snowflake } from 'discord.js';
-import { DataTypes, Sequelize } from 'sequelize';
-import { v4 as uuidv4 } from 'uuid';
-import { BaseModel } from './BaseModel';
-
-export interface MuteModel {
- id: string;
- user: Snowflake;
- guild: Snowflake;
- expires: Date;
- modlog: string;
-}
-export interface MuteModelCreationAttributes {
- id?: string;
- user: Snowflake;
- guild: Snowflake;
- expires?: Date;
- modlog: string;
-}
-
-export class Mute extends BaseModel<MuteModel, MuteModelCreationAttributes> implements MuteModel {
- /**
- * The ID of this mute (no real use just for a primary key)
- */
- id: string;
- /**
- * The user who is muted
- */
- user: Snowflake;
- /**
- * The guild they are muted in
- */
- guild: Snowflake;
- /**
- * The date at which this Mute expires and should be unmuted (optional)
- */
- expires: Date | null;
- /**
- * The ref to the modlog entry
- */
- modlog: string;
-
- static initModel(sequelize: Sequelize): void {
- Mute.init(
- {
- id: {
- type: DataTypes.STRING,
- primaryKey: true,
- allowNull: false,
- defaultValue: uuidv4
- },
- user: {
- type: DataTypes.STRING,
- allowNull: false
- },
- guild: {
- type: DataTypes.STRING,
- allowNull: false,
- references: {
- model: 'Guilds',
- key: 'id'
- }
- },
- expires: {
- type: DataTypes.DATE,
- allowNull: true
- },
- modlog: {
- type: DataTypes.STRING,
- allowNull: false,
- references: {
- model: 'ModLogs',
- key: 'id'
- }
- }
- },
- { sequelize: sequelize }
- );
- }
-}
diff --git a/src/listeners/client/interactionCreate.ts b/src/listeners/client/interactionCreate.ts
index 1183004..0e77fea 100644
--- a/src/listeners/client/interactionCreate.ts
+++ b/src/listeners/client/interactionCreate.ts
@@ -1,5 +1,5 @@
import { BushListener } from '@lib';
-import { ButtonInteraction, CommandInteraction, Interaction, SelectMenuInteraction } from 'discord.js';
+import { ClientEvents } from 'discord.js';
export default class InteractionCreateListener extends BushListener {
public constructor() {
@@ -10,7 +10,7 @@ export default class InteractionCreateListener extends BushListener {
});
}
- async exec(interaction: Interaction | CommandInteraction | ButtonInteraction | SelectMenuInteraction): Promise<unknown> {
+ async exec([interaction]: ClientEvents['interactionCreate']): Promise<unknown> {
if (!interaction) return;
if (interaction.isCommand()) {
this.client.console.info(
diff --git a/src/listeners/commands/commandBlocked.ts b/src/listeners/commands/commandBlocked.ts
index 24d46af..c02f21c 100644
--- a/src/listeners/commands/commandBlocked.ts
+++ b/src/listeners/commands/commandBlocked.ts
@@ -1,4 +1,4 @@
-import { BushCommand, BushListener, BushMessage } from '@lib';
+import { BushCommandHandlerEvents, BushListener } from '@lib';
export default class CommandBlockedListener extends BushListener {
public constructor() {
@@ -8,7 +8,7 @@ export default class CommandBlockedListener extends BushListener {
});
}
- public async exec(message: BushMessage, command: BushCommand, reason: string): Promise<unknown> {
+ public async exec([message, command, reason]: BushCommandHandlerEvents['commandBlocked']): Promise<unknown> {
this.client.console.info(
'CommandBlocked',
`<<${message.author.tag}>> tried to run <<${message.util.parsed.command}>> but was blocked because <<${reason}>>.`,
diff --git a/src/listeners/commands/commandError.ts b/src/listeners/commands/commandError.ts
index 696b59b..1aaefad 100644
--- a/src/listeners/commands/commandError.ts
+++ b/src/listeners/commands/commandError.ts
@@ -1,6 +1,5 @@
-import { BushListener, BushMessage } from '@lib';
+import { BushCommandHandlerEvents, BushListener } from '@lib';
import { stripIndents } from 'common-tags';
-import { Command } from 'discord-akairo';
import { MessageEmbed } from 'discord.js';
export default class CommandErrorListener extends BushListener {
@@ -11,7 +10,7 @@ export default class CommandErrorListener extends BushListener {
});
}
- public async exec(error: Error, message: BushMessage, command: Command | null | undefined): Promise<void> {
+ public async exec([error, message, command]: BushCommandHandlerEvents['error']): Promise<void> {
const errorNo = Math.floor(Math.random() * 6969696969) + 69; // hehe funny number
const errorEmbed: MessageEmbed = new MessageEmbed()
.setTitle(`Error # \`${errorNo}\`: An error occurred`)
diff --git a/src/listeners/commands/commandMissingPermissions.ts b/src/listeners/commands/commandMissingPermissions.ts
index f3d2218..765bc72 100644
--- a/src/listeners/commands/commandMissingPermissions.ts
+++ b/src/listeners/commands/commandMissingPermissions.ts
@@ -1,5 +1,4 @@
-import { BushCommand, BushListener, BushMessage } from '@lib';
-import { PermissionString } from 'discord.js';
+import { BushCommandHandlerEvents, BushListener } from '@lib';
export default class CommandMissingPermissionsListener extends BushListener {
public constructor() {
@@ -10,12 +9,7 @@ export default class CommandMissingPermissionsListener extends BushListener {
});
}
- public async exec(
- message: BushMessage,
- command: BushCommand | null | undefined,
- type: 'client' | 'user',
- missing: Array<PermissionString>
- ): Promise<void> {
+ public async exec([message, command, type, missing]: BushCommandHandlerEvents['missingPermissions']): Promise<void> {
const niceMissing = [];
missing.forEach((missing) => {
if (this.client.consts.mappings.permissions[missing]) {
diff --git a/src/listeners/commands/commandStarted.ts b/src/listeners/commands/commandStarted.ts
index 24bb041..dcc1d83 100644
--- a/src/listeners/commands/commandStarted.ts
+++ b/src/listeners/commands/commandStarted.ts
@@ -1,20 +1,20 @@
-import { BushCommand, BushListener } from '@lib';
-import { Message } from 'discord.js';
+import { BushCommandHandlerEvents, BushListener } from '@lib';
export default class CommandStartedListener extends BushListener {
public constructor() {
super('commandStarted', {
emitter: 'commandHandler',
- event: 'commandStarted'
+ event: 'commandStarted',
+ category: 'commands'
});
}
- exec(message: Message, command: BushCommand): void {
+ exec([message, command]: BushCommandHandlerEvents['commandStarted']): void {
this.client.logger.info(
'Command',
`The <<${command.id}>> command was used by <<${message.author.tag}>> in ${
message.channel.type === 'DM' ? `their <<DMs>>` : `<<#${message.channel.name}>> in <<${message.guild?.name}>>`
}.`,
- true //// I don't want to spam the log channel when people use commands
+ true
);
}
}
diff --git a/src/listeners/commands/slashBlocked.ts b/src/listeners/commands/slashBlocked.ts
index 2443efb..ecbe863 100644
--- a/src/listeners/commands/slashBlocked.ts
+++ b/src/listeners/commands/slashBlocked.ts
@@ -1,14 +1,15 @@
-import { BushCommand, BushListener, BushSlashMessage } from '@lib';
+import { BushCommandHandlerEvents, BushListener } from '@lib';
export default class SlashBlockedListener extends BushListener {
public constructor() {
super('slashBlocked', {
emitter: 'commandHandler',
- event: 'slashBlocked'
+ event: 'slashBlocked',
+ category: 'commands'
});
}
- public async exec(message: BushSlashMessage, command: BushCommand, reason: string): Promise<unknown> {
+ public async exec([message, command, reason]: BushCommandHandlerEvents['slashBlocked']): Promise<unknown> {
this.client.console.info(
'SlashBlocked',
`<<${message.author.tag}>> tried to run <<${message.util.parsed.command}>> but was blocked because <<${reason}>>.`,
diff --git a/src/listeners/commands/slashCommandError.ts b/src/listeners/commands/slashCommandError.ts
index 8abe788..4eaf293 100644
--- a/src/listeners/commands/slashCommandError.ts
+++ b/src/listeners/commands/slashCommandError.ts
@@ -1,4 +1,4 @@
-import { BushCommand, BushListener, BushSlashMessage } from '@lib';
+import { BushCommandHandlerEvents, BushListener } from '@lib';
import { stripIndents } from 'common-tags';
import { GuildChannel, MessageEmbed } from 'discord.js';
@@ -6,10 +6,11 @@ export default class SlashCommandErrorListener extends BushListener {
public constructor() {
super('slashError', {
emitter: 'commandHandler',
- event: 'slashError'
+ event: 'slashError',
+ category: 'commands'
});
}
- async exec(error: Error, message: BushSlashMessage, command: BushCommand): Promise<void> {
+ async exec([error, message, command]: BushCommandHandlerEvents['slashError']): Promise<void> {
const errorNo = Math.floor(Math.random() * 6969696969) + 69; // hehe funny number
const errorEmbed: MessageEmbed = new MessageEmbed()
.setTitle(`Slash Error # \`${errorNo}\`: An error occurred`)
diff --git a/src/listeners/commands/slashMissingPermissions.ts b/src/listeners/commands/slashMissingPermissions.ts
index a410bef..45966bb 100644
--- a/src/listeners/commands/slashMissingPermissions.ts
+++ b/src/listeners/commands/slashMissingPermissions.ts
@@ -1,22 +1,15 @@
-import { BushListener } from '@lib';
-import { Command } from 'discord-akairo';
-import { CommandInteraction } from 'discord.js';
+import { BushCommandHandlerEvents, BushListener } from '@lib';
export default class SlashMissingPermissionsListener extends BushListener {
public constructor() {
super('slashMissingPermissions', {
emitter: 'commandHandler',
event: 'slashMissingPermissions',
- category: 'slashCommands'
+ category: 'commands'
});
}
- public async exec(
- interaction: CommandInteraction,
- command: Command,
- type: 'user' | 'client',
- missing?: string[]
- ): Promise<void> {
+ public async exec([message, command, type, missing]: BushCommandHandlerEvents['slashMissingPermissions']): Promise<void> {
const niceMissing = [];
missing.forEach((missing) => {
if (this.client.consts.mappings.permissions[missing]) {
@@ -30,24 +23,22 @@ export default class SlashMissingPermissionsListener extends BushListener {
const consoleFormat = this.client.util.oxford(this.client.util.surroundArray(niceMissing, '<<', '>>'), 'and', '');
this.client.console.info(
'CommandMissingPermissions',
- `<<${interaction.user.tag}>> tried to run <<${
+ `<<${message.author.tag}>> tried to run <<${
command?.id
}>> but could not because <<${type}>> is missing the ${consoleFormat} permissions${missing.length ? 's' : ''}.`,
true
);
if (type == 'client') {
- await this.client.util
- .slashRespond(
- interaction,
+ await message.util
+ .reply(
`${this.client.util.emojis.error} I am missing the ${discordFormat} permission${
missing.length ? 's' : ''
} required for the \`${command?.id}\` command.`
)
.catch(() => {});
} else if (type == 'user') {
- await this.client.util
- .slashRespond(
- interaction,
+ await message.util
+ .reply(
`${this.client.util.emojis.error} You are missing the ${discordFormat} permission${
missing.length ? 's' : ''
} required for the \`${command?.id}\` command.`
diff --git a/src/listeners/commands/slashStarted.ts b/src/listeners/commands/slashStarted.ts
index a0201c5..6ff3c6e 100644
--- a/src/listeners/commands/slashStarted.ts
+++ b/src/listeners/commands/slashStarted.ts
@@ -1,19 +1,20 @@
-import { BushCommand, BushListener, BushSlashMessage } from '@lib';
+import { BushCommandHandlerEvents, BushListener } from '@lib';
export default class SlashStartedListener extends BushListener {
public constructor() {
super('slashStarted', {
emitter: 'commandHandler',
- event: 'slashStarted'
+ event: 'slashStarted',
+ category: 'commands'
});
}
- exec(message: BushSlashMessage, command: BushCommand): void {
- this.client.logger.info(
+ async exec([message, command]: BushCommandHandlerEvents['slashStarted']): Promise<unknown> {
+ return await this.client.logger.info(
'SlashCommand',
`The <<${command.id}>> command was used by <<${message.author.tag}>> in ${
message.channel.type === 'DM' ? `their <<DMs>>` : `<<#${message.channel.name}>> in <<${message.guild?.name}>>`
}.`,
- true //// I don't want to spam the log channel when people use commands
+ true
);
}
}
diff --git a/src/listeners/guild/syncUnban.ts b/src/listeners/guild/syncUnban.ts
index aa148f9..c9ba0cb 100644
--- a/src/listeners/guild/syncUnban.ts
+++ b/src/listeners/guild/syncUnban.ts
@@ -1,5 +1,5 @@
-import { Ban, BushListener } from '@lib';
-import { Guild, User } from 'discord.js';
+import { ActivePunishment, ActivePunishmentType, BushListener } from '@lib';
+import { ClientEvents } from 'discord.js';
export default class SyncUnbanListener extends BushListener {
public constructor() {
@@ -9,11 +9,12 @@ export default class SyncUnbanListener extends BushListener {
});
}
- public async exec(guild: Guild, user: User): Promise<void> {
- const bans = await Ban.findAll({
+ public async exec([ban]: ClientEvents['guildBanRemove']): Promise<void> {
+ const bans = await ActivePunishment.findAll({
where: {
- user: user.id,
- guild: guild.id
+ user: ban.user,
+ guild: ban.guild,
+ type: ActivePunishmentType.BAN
}
});
for (const dbBan of bans) {
diff --git a/src/listeners/message/level.ts b/src/listeners/message/level.ts
index 1f57930..b06fdd2 100644
--- a/src/listeners/message/level.ts
+++ b/src/listeners/message/level.ts
@@ -1,5 +1,5 @@
import { BushListener, Level } from '@lib';
-import { Message } from 'discord.js';
+import { Message, MessageType } from 'discord.js';
export default class LevelListener extends BushListener {
private levelCooldowns: Set<string> = new Set();
@@ -17,7 +17,8 @@ export default class LevelListener extends BushListener {
if (message.util?.parsed?.command) return;
if (this.levelCooldowns.has(`${message.guild.id}-${message.author.id}`)) return;
if (this.blacklistedChannels.includes(message.channel.id)) return;
- if (!['DEFAULT', 'REPLY'].includes(message.type)) return; //checks for join messages, slash commands, booster messages etc
+ const allowedMessageTypes: MessageType[] = ['DEFAULT', 'REPLY']; // this is so ts will yell at me when discord.js makes some unnecessary breaking change
+ if (!allowedMessageTypes.includes(message.type)) return; //checks for join messages, slash commands, booster messages etc
const [user] = await Level.findOrBuild({
where: {
user: message.author.id,
diff --git a/src/listeners/other/consoleListener.ts b/src/listeners/other/consoleListener.ts
index ef1efd5..90f9871 100644
--- a/src/listeners/other/consoleListener.ts
+++ b/src/listeners/other/consoleListener.ts
@@ -1,6 +1,8 @@
/* eslint-disable @typescript-eslint/no-var-requires */
/* eslint-disable @typescript-eslint/no-unused-vars */
import { BushListener } from '@lib';
+import { exec } from 'child_process';
+import { promisify } from 'util';
export default class ConsoleListener extends BushListener {
public constructor() {
@@ -12,10 +14,12 @@ export default class ConsoleListener extends BushListener {
public async exec(line: string): Promise<void> {
if (line.startsWith('eval ') || line.startsWith('ev ')) {
- const bot = this.client,
+ const
+ sh = promisify(exec),
+ bot = this.client,
config = this.client.config,
client = this.client,
- { Ban, Global, Guild, Level, ModLog, StickyRole } = await import('@lib'),
+ { ActivePunishment, Global, Guild, Level, ModLog, StickyRole } = await import('@lib'),
{
ButtonInteraction,
Collector,
@@ -26,12 +30,14 @@ export default class ConsoleListener extends BushListener {
MessageAttachment,
MessageButton,
MessageCollector,
- MessageComponentInteractionCollector,
+ InteractionCollector,
MessageEmbed,
MessageSelectMenu,
ReactionCollector,
- Util
- } = require('discord.js');
+ Util,
+ Collection
+ } = await import('discord.js'),
+ { Canvas } = await import('node-canvas');
try {
const input = line.replace('eval ', '').replace('ev ', '');
let output = eval(input);
diff --git a/src/tasks/removeExpiredPunishements.ts b/src/tasks/removeExpiredPunishements.ts
new file mode 100644
index 0000000..d0220ba
--- /dev/null
+++ b/src/tasks/removeExpiredPunishements.ts
@@ -0,0 +1,74 @@
+import { BushGuild, BushGuildMember, BushTask } from '@lib';
+import { Op } from 'sequelize';
+import { ActivePunishment, ActivePunishmentType } from '../lib/models/ActivePunishment';
+
+export default class RemoveExpiredPunishmentsTask extends BushTask {
+ public constructor() {
+ super('removeExpiredPunishments', {
+ delay: 15_000, // 15 seconds
+ runOnStart: true
+ });
+ }
+ async exec(): Promise<void> {
+ const expiredEntries = await ActivePunishment.findAll({
+ where: {
+ [Op.and]: [
+ {
+ expires: {
+ [Op.lt]: new Date() // Find all rows with an expiry date before now
+ }
+ }
+ ]
+ }
+ });
+
+ this.client.logger.verbose(
+ `removeExpiredPunishments`,
+ `Queried punishments, found <<${expiredEntries.length}>> expired punishments.`
+ );
+
+ for (const entry of expiredEntries) {
+ const guild = this.client.guilds.cache.get(entry.guild) as BushGuild;
+ const member = guild.members.cache.get(entry.user) as BushGuildMember;
+
+ if (!guild) {
+ await entry.destroy();
+ continue;
+ }
+
+ switch (entry.type) {
+ case ActivePunishmentType.BAN: {
+ const result = await guild.unban({ user: entry.user, reason: 'Punishment expired.' });
+ if (['success', 'user not banned'].includes(result)) await entry.destroy();
+ else throw result;
+ this.client.logger.verbose(`removeExpiredPunishments`, `Unbanned ${entry.user}.`);
+ break;
+ }
+ case ActivePunishmentType.BLOCK: {
+ //todo
+ break;
+ }
+ case ActivePunishmentType.MUTE: {
+ const result = await member.unmute({ reason: 'Punishment expired.' });
+ if (['success', 'failed to dm'].includes(result)) await entry.destroy();
+ else throw result;
+ this.client.logger.verbose(`removeExpiredPunishments`, `Unmuted ${entry.user}.`);
+ break;
+ }
+ case ActivePunishmentType.ROLE: {
+ const role = guild?.roles?.cache?.get(entry.extraInfo);
+ const result = await member.removeRole({
+ reason: 'Punishment expired.',
+ role: role,
+ addToModlog: true
+ });
+
+ if (['success', 'failed to dm'].includes(result)) await entry.destroy();
+ else throw result;
+ this.client.logger.verbose(`removeExpiredPunishments`, `Removed a punishment role from ${entry.user}.`);
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/src/tasks/removePunishmentRole.ts b/src/tasks/removePunishmentRole.ts
deleted file mode 100644
index 9830338..0000000
--- a/src/tasks/removePunishmentRole.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { BushGuildMember, BushTask } from '@lib';
-
-export default class RemovePunishmentRole extends BushTask {
- public constructor() {
- super('removePunishmentRole', {
- delay: 30_000, // 1/2 min
- runOnStart: true
- });
- }
- async exec(): Promise<void> {
- const expiredEntries = await this.client.util.findExpiredEntries('role');
- this.client.logger.verbose(
- `RemovePunishmentRoleTask`,
- `Queried punishment roles, found <<${expiredEntries.length}>> expired punishment roles.`
- );
-
- for (const entry of expiredEntries) {
- const guild = this.client.guilds.cache.get(entry.guild);
- const role = guild?.roles?.cache?.get(entry.role);
- if (!guild || !role) {
- await entry.destroy();
- continue;
- }
-
- const member = guild.members.cache.get(entry.user) as BushGuildMember;
- const result = await member.removeRole({
- reason: 'Punishment expired.',
- role: role,
- addToModlog: true
- });
- if (['success', 'failed to dm'].includes(result)) await entry.destroy();
- else throw result;
-
- this.client.logger.verbose(`RemovePunishmentRoleTask`, `Removed a punishment role from ${entry.user}.`);
- }
- }
-}
diff --git a/src/tasks/unban.ts b/src/tasks/unban.ts
deleted file mode 100644
index 136e6c2..0000000
--- a/src/tasks/unban.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { BushGuild, BushTask } from '@lib';
-
-export default class UnbanTask extends BushTask {
- public constructor() {
- super('unban', {
- delay: 30_000, // 1/2 min
- runOnStart: true
- });
- }
- async exec(): Promise<void> {
- const rows = await this.client.util.findExpiredEntries('mute');
- this.client.logger.verbose(`UnbanTask`, `Queried bans, found <<${rows.length}>> expired bans.`);
-
- for (const row of rows) {
- const guild = this.client.guilds.cache.get(row.guild) as BushGuild;
- if (!guild) {
- await row.destroy();
- continue;
- }
-
- const result = await guild.unban({ user: row.user, reason: 'Punishment expired.' });
- if (['success', 'user not banned'].includes(result)) await row.destroy();
- else throw result;
- this.client.logger.verbose(`UnbanTask`, `Unbanned ${row.user}`);
- }
- }
-}
diff --git a/src/tasks/unmute.ts b/src/tasks/unmute.ts
deleted file mode 100644
index c61c6e9..0000000
--- a/src/tasks/unmute.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import { BushGuildMember, BushTask, Mute } from '@lib';
-import { Op } from 'sequelize';
-
-export default class UnmuteTask extends BushTask {
- public constructor() {
- super('unmute', {
- delay: 30_000, // 1/2 min
- runOnStart: true
- });
- }
- async exec(): Promise<void> {
- const rows = await Mute.findAll({
- where: {
- [Op.and]: [
- {
- expires: {
- [Op.lt]: new Date() // Find all rows with an expiry date before now
- }
- }
- ]
- }
- });
- this.client.logger.verbose(`UnmuteTask`, `Queried mutes, found <<${rows.length}>> expired mutes.`);
- for (const row of rows) {
- const guild = this.client.guilds.cache.get(row.guild);
- if (!guild) {
- await row.destroy();
- continue;
- }
-
- const member = guild.members.cache.get(row.user) as BushGuildMember;
- const result = await member.unmute({ reason: 'Punishment expired.' });
- if (['success', 'failed to dm'].includes(result)) await row.destroy();
- else throw result;
-
- this.client.logger.verbose(`UnmuteTask`, `Unmuted ${row.user}`);
- }
- }
-}