diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/extensions/BushArgumentOptions.ts | 59 | ||||
-rw-r--r-- | src/lib/extensions/BushArgumentTypeCaster.ts | 4 | ||||
-rw-r--r-- | src/lib/extensions/BushClient.ts | 44 | ||||
-rw-r--r-- | src/lib/extensions/BushClientUtil.ts | 66 | ||||
-rw-r--r-- | src/lib/extensions/BushCommand.ts | 20 | ||||
-rw-r--r-- | src/lib/extensions/BushCommandHandler.ts | 5 | ||||
-rw-r--r-- | src/lib/extensions/BushInhibitor.ts | 9 | ||||
-rw-r--r-- | src/lib/extensions/BushInteractionMessage.ts | 5 | ||||
-rw-r--r-- | src/lib/extensions/BushTaskHandler.ts | 1 | ||||
-rw-r--r-- | src/lib/models/Ban.ts | 13 | ||||
-rw-r--r-- | src/lib/models/Global.ts | 2 | ||||
-rw-r--r-- | src/lib/models/Guild.ts | 22 | ||||
-rw-r--r-- | src/lib/models/Level.ts | 1 | ||||
-rw-r--r-- | src/lib/models/Modlog.ts | 38 | ||||
-rw-r--r-- | src/lib/models/Mute.ts | 90 | ||||
-rw-r--r-- | src/lib/models/PunishmentRole.ts | 93 | ||||
-rw-r--r-- | src/lib/models/index.ts | 4 | ||||
-rw-r--r-- | src/lib/utils/BushCache.ts | 6 | ||||
-rw-r--r-- | src/lib/utils/BushLogger.ts | 8 | ||||
-rw-r--r-- | src/lib/utils/CanvasProgressBar.ts | 10 |
20 files changed, 401 insertions, 99 deletions
diff --git a/src/lib/extensions/BushArgumentOptions.ts b/src/lib/extensions/BushArgumentOptions.ts new file mode 100644 index 0000000..bbbc04b --- /dev/null +++ b/src/lib/extensions/BushArgumentOptions.ts @@ -0,0 +1,59 @@ +import { ArgumentOptions, ArgumentTypeCaster } from 'discord-akairo'; + +type BushArgumentType = + | 'string' + | 'lowercase' + | 'uppercase' + | 'charCodes' + | 'number' + | 'integer' + | 'bigint' + | 'emojint' + | 'url' + | 'date' + | 'color' + | 'user' + | 'users' + | 'member' + | 'members' + | 'relevant' + | 'relevants' + | 'channel' + | 'channels' + | 'textChannel' + | 'textChannels' + | 'voiceChannel' + | 'voiceChannels' + | 'categoryChannel' + | 'categoryChannels' + | 'newsChannel' + | 'newsChannels' + | 'storeChannel' + | 'storeChannels' + | 'role' + | 'roles' + | 'emoji' + | 'emojis' + | 'guild' + | 'guilds' + | 'message' + | 'guildMessage' + | 'relevantMessage' + | 'invite' + | 'userMention' + | 'memberMention' + | 'channelMention' + | 'roleMention' + | 'emojiMention' + | 'commandAlias' + | 'command' + | 'inhibitor' + | 'listener' + | 'duration' + | (string | string[])[] + | RegExp + | string; + +export interface BushArgumentOptions extends ArgumentOptions { + type?: BushArgumentType | ArgumentTypeCaster; +} diff --git a/src/lib/extensions/BushArgumentTypeCaster.ts b/src/lib/extensions/BushArgumentTypeCaster.ts new file mode 100644 index 0000000..e000063 --- /dev/null +++ b/src/lib/extensions/BushArgumentTypeCaster.ts @@ -0,0 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { BushMessage } from './BushMessage'; + +export type BushArgumentTypeCaster = (message: BushMessage, phrase: string) => any; diff --git a/src/lib/extensions/BushClient.ts b/src/lib/extensions/BushClient.ts index b12fd52..73b0864 100644 --- a/src/lib/extensions/BushClient.ts +++ b/src/lib/extensions/BushClient.ts @@ -1,11 +1,13 @@ import chalk from 'chalk'; -import { AkairoClient, TaskHandler } from 'discord-akairo'; +import { AkairoClient } from 'discord-akairo'; import { APIMessage, Guild, Intents, Message, MessageOptions, Snowflake, UserResolvable } from 'discord.js'; import * as path from 'path'; import { exit } from 'process'; import readline from 'readline'; import { Sequelize } from 'sequelize'; +import { durationTypeCaster } from '../../arguments/duration'; import * as config from '../../config/options'; +import UpdateCacheTask from '../../tasks/updateCache'; import * as Models from '../models'; import AllowedMentions from '../utils/AllowedMentions'; import { BushCache } from '../utils/BushCache'; @@ -15,6 +17,7 @@ import { BushClientUtil } from './BushClientUtil'; import { BushCommandHandler } from './BushCommandHandler'; import { BushInhibitorHandler } from './BushInhinitorHandler'; import { BushListenerHandler } from './BushListenerHandler'; +import { BushTaskHandler } from './BushTaskHandler'; export type BotConfig = typeof config; export type BushMessageType = string | APIMessage | (MessageOptions & { split?: false }); @@ -30,7 +33,7 @@ export class BushClient extends AkairoClient { public listenerHandler: BushListenerHandler; public inhibitorHandler: BushInhibitorHandler; public commandHandler: BushCommandHandler; - public taskHandler: TaskHandler; + public taskHandler: BushTaskHandler; public declare util: BushClientUtil; public declare ownerID: Snowflake[]; public db: Sequelize; @@ -68,7 +71,7 @@ export class BushClient extends AkairoClient { }); // Create task handler - this.taskHandler = new TaskHandler(this, { + this.taskHandler = new BushTaskHandler(this, { directory: path.join(__dirname, '..', '..', 'tasks') }); @@ -76,14 +79,14 @@ export class BushClient extends AkairoClient { this.commandHandler = new BushCommandHandler(this, { directory: path.join(__dirname, '..', '..', 'commands'), prefix: async ({ guild }: { guild: Guild }) => { - if (this.config.dev) return 'dev'; + if (this.config.dev) return 'dev '; const row = await Models.Guild.findByPk(guild.id); return (row?.prefix || this.config.prefix) as string; }, allowMention: true, handleEdits: true, commandUtil: true, - commandUtilLifetime: 3e5, + commandUtilLifetime: 300_000, argumentDefaults: { prompt: { start: 'Placeholder argument prompt. If you see this please tell the devs.', @@ -99,9 +102,8 @@ export class BushClient extends AkairoClient { }, otherwise: '' }, - ignorePermissions: this.config.owners, - ignoreCooldown: this.config.owners, - automateCategories: true, + + automateCategories: false, autoRegisterSlashCommands: true }); @@ -110,7 +112,7 @@ export class BushClient extends AkairoClient { dialect: 'postgres', host: this.config.db.host, port: this.config.db.port, - logging: this.config.logging ? (a) => this.logger.debug(a) : false + logging: this.config.logging.db ? (a) => this.logger.debug(a) : false }); this.logger = new BushLogger(this); } @@ -127,6 +129,8 @@ export class BushClient extends AkairoClient { private async _init(): Promise<void> { this.commandHandler.useListenerHandler(this.listenerHandler); this.commandHandler.useInhibitorHandler(this.inhibitorHandler); + this.commandHandler.ignorePermissions = this.config.owners; + this.commandHandler.ignoreCooldown = this.config.owners.concat(this.cache.global.superUsers); this.listenerHandler.setEmitters({ client: this, commandHandler: this.commandHandler, @@ -137,6 +141,9 @@ export class BushClient extends AkairoClient { stdin: rl, gateway: this.ws }); + this.commandHandler.resolver.addTypes({ + duration: durationTypeCaster + }); // loads all the handlers const loaders = { commands: this.commandHandler, @@ -147,13 +154,15 @@ export class BushClient extends AkairoClient { for (const loader of Object.keys(loaders)) { try { loaders[loader].loadAll(); - this.logger.success('Startup', `Successfully loaded <<${loader}>>.`, false); + await this.logger.success('Startup', `Successfully loaded <<${loader}>>.`, false); } catch (e) { - this.logger.error('Startup', `Unable to load loader <<${loader}>> with error:\n${e?.stack}`, false); + await this.logger.error('Startup', `Unable to load loader <<${loader}>> with error:\n${e?.stack}`, false); } } - this.taskHandler.startAll(); await this.dbPreInit(); + await new UpdateCacheTask().init(this); + this.console.success('Startup', `Successfully created <<global cache>>.`, false); + this.taskHandler.startAll(); } public async dbPreInit(): Promise<void> { @@ -161,14 +170,15 @@ export class BushClient extends AkairoClient { await this.db.authenticate(); Models.Global.initModel(this.db); Models.Guild.initModel(this.db, this); - Models.Modlog.initModel(this.db); + Models.ModLog.initModel(this.db); Models.Ban.initModel(this.db); + Models.Mute.initModel(this.db); Models.Level.initModel(this.db); Models.StickyRole.initModel(this.db); await this.db.sync({ alter: true }); // Sync all tables to fix everything if updated - this.console.success('Startup', `Successfully connected to <<database>>.`, false); + await this.console.success('Startup', `Successfully connected to <<database>>.`, false); } catch (error) { - this.console.error('Startup', `Failed to connect to <<database>> with error:\n` + error?.stack, false); + await this.console.error('Startup', `Failed to connect to <<database>> with error:\n` + error?.stack, false); } } @@ -178,7 +188,7 @@ export class BushClient extends AkairoClient { await this._init(); await this.login(this.token); } catch (e) { - this.console.error('Start', chalk.red(e.stack), false); + await this.console.error('Start', chalk.red(e.stack), false); exit(2); } } @@ -196,6 +206,6 @@ export class BushClient extends AkairoClient { } public isSuperUser(user: UserResolvable): boolean { const userID = this.users.resolveID(user); - return !!BushCache?.superUsers?.includes(userID) || this.config.owners.includes(userID); + return !!BushCache?.global?.superUsers?.includes(userID) || this.config.owners.includes(userID); } } diff --git a/src/lib/extensions/BushClientUtil.ts b/src/lib/extensions/BushClientUtil.ts index a6b049a..34a9e83 100644 --- a/src/lib/extensions/BushClientUtil.ts +++ b/src/lib/extensions/BushClientUtil.ts @@ -2,19 +2,11 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { exec } from 'child_process'; import { ClientUtil } from 'discord-akairo'; -import { - APIInteractionDataResolvedChannel, - APIInteractionDataResolvedGuildMember, - APIMessage, - APIRole, - ApplicationCommandOptionType -} from 'discord-api-types'; +import { APIMessage } from 'discord-api-types'; import { ButtonInteraction, CommandInteraction, - CommandInteractionOption, Constants, - GuildChannel, GuildMember, InteractionReplyOptions, Message, @@ -24,7 +16,6 @@ import { MessageEditOptions, MessageEmbed, MessageOptions, - Role, Snowflake, TextChannel, User, @@ -33,7 +24,7 @@ import { } from 'discord.js'; import got from 'got'; import { promisify } from 'util'; -import { Global } from '../models/Global'; +import { Global } from '../models'; import { BushCache } from '../utils/BushCache'; import { BushClient } from './BushClient'; import { BushMessage } from './BushMessage'; @@ -61,17 +52,6 @@ export interface uuidRes { created_at: string; } -export interface SlashCommandOption<T> { - name: string; - type: ApplicationCommandOptionType; - value?: T; - options?: CommandInteractionOption[]; - user?: User; - member?: GuildMember | APIInteractionDataResolvedGuildMember; - channel?: GuildChannel | APIInteractionDataResolvedChannel; - role?: Role | APIRole; -} - export class BushClientUtil extends ClientUtil { /** The client of this ClientUtil */ public declare client: BushClient; @@ -147,7 +127,6 @@ export class BushClientUtil extends ClientUtil { return `${url}/${res.key}`; } catch (e) { this.client.console.error('Haste', `Unable to upload haste to ${url}`); - continue; } } return 'Unable to post'; @@ -163,8 +142,7 @@ export class BushClientUtil extends ClientUtil { const idMatch = text.match(idReg); if (idMatch) { try { - const user = await this.client.users.fetch(text as Snowflake); - return user; + return await this.client.users.fetch(text as Snowflake); } catch { // pass } @@ -173,8 +151,7 @@ export class BushClientUtil extends ClientUtil { const mentionMatch = text.match(mentionReg); if (mentionMatch) { try { - const user = await this.client.users.fetch(mentionMatch.groups.id as Snowflake); - return user; + return await this.client.users.fetch(mentionMatch.groups.id as Snowflake); } catch { // pass } @@ -460,8 +437,8 @@ export class BushClientUtil extends ClientUtil { } /** Gets the channel configs as a TextChannel */ - public getConfigChannel(channel: 'log' | 'error' | 'dm'): Promise<TextChannel> { - return this.client.channels.fetch(this.client.config.channels[channel]) as Promise<TextChannel>; + public async getConfigChannel(channel: 'log' | 'error' | 'dm'): Promise<TextChannel> { + return (await this.client.channels.fetch(this.client.config.channels[channel])) as TextChannel; } /** @@ -488,7 +465,7 @@ export class BushClientUtil extends ClientUtil { public async insertOrRemoveFromGlobal( action: 'add' | 'remove', - key: keyof typeof BushCache, + key: keyof typeof BushCache['global'], value: any ): Promise<Global | void> { const environment = this.client.config.dev ? 'development' : 'production'; @@ -502,7 +479,34 @@ export class BushClientUtil extends ClientUtil { newValue = oldValue.filter((ae) => ae !== value); } row[key] = newValue; - this.client.cache[key] = newValue; + this.client.cache.global[key] = newValue; return await row.save().catch((e) => this.client.logger.error('insertOrRemoveFromGlobal', e)); } + + /** + * Surrounds a string to the begging an end of each element in an array. + * + * @param {string[]} array The array you want to surround. + * @param {string} surroundChar1 The character placed in the beginning of the element (or end if surroundChar2 isn't supplied). + * @param {string} [surroundChar2=surroundChar1] The character placed in the end of the element. + * @returns {string[]} + */ + public surroundArray(array: string[], surroundChar1: string, surroundChar2?: string): string[] { + const newArray = []; + array.forEach((a) => { + newArray.push(`${surroundChar1}${a}${surroundChar2 || surroundChar1}`); + }); + return newArray; + } + + // public createModLogEntry( + // user: User | Snowflake, + // guild: Guild | Snowflake, + // reason?: string, + // type?: ModLogType, + // duration?: number, + // moderator: User | Snowflake + // ): ModLog { + + // } } diff --git a/src/lib/extensions/BushCommand.ts b/src/lib/extensions/BushCommand.ts index bc6ff68..b62d26e 100644 --- a/src/lib/extensions/BushCommand.ts +++ b/src/lib/extensions/BushCommand.ts @@ -1,33 +1,47 @@ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { Command, CommandOptions } from 'discord-akairo'; +import { ArgumentGenerator, ArgumentOptions, ArgumentPromptOptions, Command, CommandOptions } from 'discord-akairo'; import { Snowflake } from 'discord.js'; import { BushClient } from './BushClient'; import { BushCommandHandler } from './BushCommandHandler'; import { BushSlashMessage } from './BushInteractionMessage'; import { BushMessage } from './BushMessage'; +export interface BushArgumentOptions extends ArgumentOptions { + id: string; + description?: string; + prompt?: ArgumentPromptOptions; +} + export interface BushCommandOptions extends CommandOptions { hidden?: boolean; restrictedChannels?: Snowflake[]; restrictedGuilds?: Snowflake[]; description: { content: string; - usage: string; - examples: string[]; + usage: string | string[]; + examples: string | string[]; }; + args?: BushArgumentOptions[] | ArgumentGenerator; + category: string; } export class BushCommand extends Command { public declare client: BushClient; + public declare handler: BushCommandHandler; + public options: BushCommandOptions; + /** The channels the command is limited to run in. */ public restrictedChannels: Snowflake[]; + /** The guilds the command is limited to run in. */ public restrictedGuilds: Snowflake[]; + /** Whether the command is hidden from the help command. */ public hidden: boolean; + constructor(id: string, options?: BushCommandOptions) { super(id, options); this.options = options; diff --git a/src/lib/extensions/BushCommandHandler.ts b/src/lib/extensions/BushCommandHandler.ts index 8e8936e..aeea101 100644 --- a/src/lib/extensions/BushCommandHandler.ts +++ b/src/lib/extensions/BushCommandHandler.ts @@ -86,9 +86,6 @@ export class BushCommandHandler extends CommandHandler { this.emit(CommandHandlerEvents.COMMAND_BLOCKED, message, command, reason); return true; } - if (this.runCooldowns(message, command)) { - return true; - } - return false; + return !!this.runCooldowns(message, command); } } diff --git a/src/lib/extensions/BushInhibitor.ts b/src/lib/extensions/BushInhibitor.ts index 85d6de8..8a31abf 100644 --- a/src/lib/extensions/BushInhibitor.ts +++ b/src/lib/extensions/BushInhibitor.ts @@ -1,6 +1,15 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { Inhibitor } from 'discord-akairo'; import { BushClient } from './BushClient'; +import { BushCommand } from './BushCommand'; +import { BushSlashMessage } from './BushInteractionMessage'; +import { BushMessage } from './BushMessage'; export class BushInhibitor extends Inhibitor { public declare client: BushClient; + + public exec(message: BushMessage, command: BushCommand): any; + public exec(message: BushMessage | BushSlashMessage, command: BushCommand): any { + super.exec(message, command); + } } diff --git a/src/lib/extensions/BushInteractionMessage.ts b/src/lib/extensions/BushInteractionMessage.ts index ade11ea..62d2519 100644 --- a/src/lib/extensions/BushInteractionMessage.ts +++ b/src/lib/extensions/BushInteractionMessage.ts @@ -1,15 +1,16 @@ import { AkairoMessage } from 'discord-akairo'; import { CommandInteraction } from 'discord.js'; import { BushClient } from './BushClient'; +import { BushCommandUtil } from './BushCommandUtil'; export class BushSlashMessage extends AkairoMessage { + public declare client: BushClient; + public declare util: BushCommandUtil; public constructor( client: BushClient, interaction: CommandInteraction, { slash, replied }: { slash?: boolean; replied?: boolean } ) { super(client, interaction, { slash, replied }); - this.client = client; - this.interaction = interaction; } } diff --git a/src/lib/extensions/BushTaskHandler.ts b/src/lib/extensions/BushTaskHandler.ts index 923e42b..588988d 100644 --- a/src/lib/extensions/BushTaskHandler.ts +++ b/src/lib/extensions/BushTaskHandler.ts @@ -6,7 +6,6 @@ export type BushTaskHandlerOptions = AkairoHandlerOptions; export class BushTaskHandler extends TaskHandler { public constructor(client: BushClient, options: BushTaskHandlerOptions) { super(client, options); - this.client; } declare client: BushClient; } diff --git a/src/lib/models/Ban.ts b/src/lib/models/Ban.ts index 8ba55ec..f4463b8 100644 --- a/src/lib/models/Ban.ts +++ b/src/lib/models/Ban.ts @@ -1,7 +1,6 @@ import { Snowflake } from 'discord.js'; import { DataTypes, Sequelize } from 'sequelize'; import { v4 as uuidv4 } from 'uuid'; -import * as Models from './'; import { BaseModel } from './BaseModel'; export interface BanModel { @@ -64,7 +63,7 @@ export class Ban extends BaseModel<BanModel, BanModelCreationAttributes> impleme type: DataTypes.STRING, allowNull: false, references: { - model: Models.Guild, + model: 'Guilds', key: 'id' } }, @@ -78,11 +77,11 @@ export class Ban extends BaseModel<BanModel, BanModelCreationAttributes> impleme }, modlog: { type: DataTypes.STRING, - allowNull: false - // references: { - // model: Models.Modlog, - // key: 'id' - // } + allowNull: false, + references: { + model: 'ModLogs', + key: 'id' + } } }, { sequelize: sequelize } diff --git a/src/lib/models/Global.ts b/src/lib/models/Global.ts index abe0ab3..842f14b 100644 --- a/src/lib/models/Global.ts +++ b/src/lib/models/Global.ts @@ -80,7 +80,7 @@ export class Global extends BaseModel<GlobalModel, GlobalModelCreationAttributes allowNull: true } }, - { sequelize } + { sequelize: sequelize } ); } } diff --git a/src/lib/models/Guild.ts b/src/lib/models/Guild.ts index c4ae53e..480cc60 100644 --- a/src/lib/models/Guild.ts +++ b/src/lib/models/Guild.ts @@ -8,16 +8,24 @@ export interface GuildModel { prefix: string; autoPublishChannels: string[]; blacklistedChannels: Snowflake[]; + welcomeChannel: Snowflake; + muteRole: Snowflake; } -export type GuildModelCreationAttributes = Optional<GuildModel, 'prefix' | 'autoPublishChannels' | 'blacklistedChannels'>; +export type GuildModelCreationAttributes = Optional< + GuildModel, + 'prefix' | 'autoPublishChannels' | 'blacklistedChannels' | 'welcomeChannel' | 'muteRole' +>; export class Guild extends BaseModel<GuildModel, GuildModelCreationAttributes> implements GuildModel { id: string; prefix: string; autoPublishChannels: string[]; blacklistedChannels: Snowflake[]; - static initModel(seqeulize: Sequelize, client: BushClient): void { + welcomeChannel: Snowflake; + muteRole: Snowflake; + + static initModel(sequelize: Sequelize, client: BushClient): void { Guild.init( { id: { @@ -48,9 +56,17 @@ export class Guild extends BaseModel<GuildModel, GuildModelCreationAttributes> i return this.setDataValue('blacklistedChannels', JSON.stringify(val) as unknown as Snowflake[]); }, allowNull: true + }, + welcomeChannel: { + type: DataTypes.STRING, + allowNull: true + }, + muteRole: { + type: DataTypes.STRING, + allowNull: true } }, - { sequelize: seqeulize } + { sequelize: sequelize } ); } } diff --git a/src/lib/models/Level.ts b/src/lib/models/Level.ts index 426ec1a..e1f30f4 100644 --- a/src/lib/models/Level.ts +++ b/src/lib/models/Level.ts @@ -46,7 +46,6 @@ export class Level extends BaseModel<LevelModel, LevelModelCreationAttributes> { break; } else { i++; - continue; } } return lvl - 1; // I have to do this don't question it ok diff --git a/src/lib/models/Modlog.ts b/src/lib/models/Modlog.ts index 15c5030..94c464d 100644 --- a/src/lib/models/Modlog.ts +++ b/src/lib/models/Modlog.ts @@ -2,18 +2,20 @@ import { DataTypes, Sequelize } from 'sequelize'; import { v4 as uuidv4 } from 'uuid'; import { BaseModel } from './BaseModel'; -export enum ModlogType { +export enum ModLogType { BAN = 'BAN', - TEMPBAN = 'TEMPBAN', + TEMP_BAN = 'TEMP_BAN', KICK = 'KICK', MUTE = 'MUTE', - TEMPMUTE = 'TEMPMUTE', - WARN = 'WARN' + TEMP_MUTE = 'TEMP_MUTE', + WARN = 'WARN', + PUNISHMENT_ROLE = 'PUNISHMENT_ROLE', + TEMP_PUNISHMENT_ROLE = 'TEMP_PUNISHMENT_ROLE' } -export interface ModlogModel { +export interface ModLogModel { id: string; - type: ModlogType; + type: ModLogType; user: string; moderator: string; reason: string; @@ -21,9 +23,9 @@ export interface ModlogModel { guild: string; } -export interface ModlogModelCreationAttributes { +export interface ModLogModelCreationAttributes { id?: string; - type: ModlogType; + type: ModLogType; user: string; moderator: string; reason?: string; @@ -31,9 +33,9 @@ export interface ModlogModelCreationAttributes { guild: string; } -export class Modlog extends BaseModel<ModlogModel, ModlogModelCreationAttributes> implements ModlogModel { +export class ModLog extends BaseModel<ModLogModel, ModLogModelCreationAttributes> implements ModLogModel { id: string; - type: ModlogType; + type: ModLogType; user: string; moderator: string; guild: string; @@ -41,7 +43,7 @@ export class Modlog extends BaseModel<ModlogModel, ModlogModelCreationAttributes duration: number | null; static initModel(sequelize: Sequelize): void { - Modlog.init( + ModLog.init( { id: { type: DataTypes.STRING, @@ -50,7 +52,7 @@ export class Modlog extends BaseModel<ModlogModel, ModlogModelCreationAttributes defaultValue: uuidv4 }, type: { - type: new DataTypes.ENUM('BAN', 'TEMPBAN', 'MUTE', 'TEMPMUTE', 'KICK', 'WARN'), + type: DataTypes.STRING, //# This is not an enum because of a sequelize issue: https://github.com/sequelize/sequelize/issues/2554 allowNull: false }, user: { @@ -70,14 +72,14 @@ export class Modlog extends BaseModel<ModlogModel, ModlogModelCreationAttributes allowNull: true }, guild: { - type: DataTypes.STRING - // references: { - // model: Models.Guild, - // key: 'id' - // } + type: DataTypes.STRING, + references: { + model: 'Guilds', + key: 'id' + } } }, - { sequelize } + { sequelize: sequelize } ); } } diff --git a/src/lib/models/Mute.ts b/src/lib/models/Mute.ts new file mode 100644 index 0000000..273d5b1 --- /dev/null +++ b/src/lib/models/Mute.ts @@ -0,0 +1,90 @@ +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: string; + guild: string; + reason: string; + expires: Date; + modlog: string; +} +export interface MuteModelCreationAttributes { + id?: string; + user: string; + guild: string; + reason?: string; + 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 reason they are muted (optional) + */ + reason: string | null; + /** + * 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 + }, + reason: { + type: DataTypes.STRING, + allowNull: true + }, + modlog: { + type: DataTypes.STRING, + allowNull: false, + references: { + model: 'ModLogs', + key: 'id' + } + } + }, + { sequelize: sequelize } + ); + } +} diff --git a/src/lib/models/PunishmentRole.ts b/src/lib/models/PunishmentRole.ts new file mode 100644 index 0000000..3326dca --- /dev/null +++ b/src/lib/models/PunishmentRole.ts @@ -0,0 +1,93 @@ +import { Snowflake } from 'discord.js'; +import { DataTypes, Sequelize } from 'sequelize'; +import { v4 as uuidv4 } from 'uuid'; +import { BaseModel } from './BaseModel'; + +export interface PunishmentRoleModel { + id: string; + user: string; + guild: string; + reason: string; + expires: Date; + modlog: string; +} +export interface PunishmentRoleModelCreationAttributes { + id?: string; + user: string; + guild: string; + reason?: string; + expires?: Date; + modlog: string; +} + +export class PunishmentRole + extends BaseModel<PunishmentRoleModel, PunishmentRoleModelCreationAttributes> + implements PunishmentRoleModel +{ + /** + * The ID of this punishment role (no real use just for a primary key) + */ + id: string; + /** + * The user who received a role + */ + user: Snowflake; + /** + * The guild they received a role in + */ + guild: Snowflake; + /** + * The reason they received a role (optional) + */ + reason: string | null; + /** + * The date at which this role expires and should be removed (optional) + */ + expires: Date | null; + /** + * The ref to the modlog entry + */ + modlog: string; + + static initModel(sequelize: Sequelize): void { + PunishmentRole.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 + }, + reason: { + type: DataTypes.STRING, + allowNull: true + }, + modlog: { + type: DataTypes.STRING, + allowNull: false, + references: { + model: 'ModLogs', + key: 'id' + } + } + }, + { sequelize: sequelize } + ); + } +} diff --git a/src/lib/models/index.ts b/src/lib/models/index.ts index e38ad69..794c335 100644 --- a/src/lib/models/index.ts +++ b/src/lib/models/index.ts @@ -3,5 +3,7 @@ export * from './BaseModel'; export * from './Global'; export * from './Guild'; export * from './Level'; -export * from './Modlog'; +export * from './ModLog'; +export * from './Mute'; +export * from './PunishmentRole'; export * from './StickyRole'; diff --git a/src/lib/utils/BushCache.ts b/src/lib/utils/BushCache.ts index 947b15d..ffef470 100644 --- a/src/lib/utils/BushCache.ts +++ b/src/lib/utils/BushCache.ts @@ -1,9 +1,13 @@ import { Snowflake } from 'discord.js'; -export class BushCache { +class GlobalCache { public static superUsers = new Array<Snowflake>(); public static disabledCommands = new Array<string>(); public static blacklistedChannels = new Array<Snowflake>(); public static blacklistedGuilds = new Array<Snowflake>(); public static blacklistedUsers = new Array<Snowflake>(); } + +export class BushCache { + public static global = GlobalCache; +} diff --git a/src/lib/utils/BushLogger.ts b/src/lib/utils/BushLogger.ts index 2225bde..6adacfd 100644 --- a/src/lib/utils/BushLogger.ts +++ b/src/lib/utils/BushLogger.ts @@ -105,7 +105,7 @@ export class BushLogger { .setDescription(`**[${header}]** ${this.parseFormatting(this.stripColor(newContent), '', true)}`) .setColor(this.client.util.colors.gray) .setTimestamp(); - this.channelLog({ embeds: [embed] }); + await this.channelLog({ embeds: [embed] }); } /** @@ -125,7 +125,7 @@ export class BushLogger { .setDescription(`**[${header}]** ${this.parseFormatting(this.stripColor(newContent), '', true)}`) .setColor(this.client.util.colors.info) .setTimestamp(); - this.channelLog({ embeds: [embed] }); + await this.channelLog({ embeds: [embed] }); } /** @@ -146,7 +146,7 @@ export class BushLogger { .setDescription(`**[${header}]** ${this.parseFormatting(this.stripColor(newContent), '', true)}`) .setColor(this.client.util.colors.warn) .setTimestamp(); - this.channelLog({ embeds: [embed] }); + await this.channelLog({ embeds: [embed] }); } /** @@ -166,7 +166,7 @@ export class BushLogger { .setDescription(`**[${header}]** ${this.parseFormatting(this.stripColor(newContent), '', true)}`) .setColor(this.client.util.colors.error) .setTimestamp(); - this.channelError({ embeds: [embed] }); + await this.channelError({ embeds: [embed] }); } /** diff --git a/src/lib/utils/CanvasProgressBar.ts b/src/lib/utils/CanvasProgressBar.ts index aa8630a..d870bf9 100644 --- a/src/lib/utils/CanvasProgressBar.ts +++ b/src/lib/utils/CanvasProgressBar.ts @@ -1,10 +1,10 @@ // I just copy pasted this code from stackoverflow don't yell at me if there is issues for it export class CanvasProgressBar { - private x: number; - private y: number; - private w: number; - private h: number; - private color: string; + private readonly x: number; + private readonly y: number; + private readonly w: number; + private readonly h: number; + private readonly color: string; private percentage: number; private p: number; private ctx: CanvasRenderingContext2D; |