aboutsummaryrefslogtreecommitdiff
path: root/src/lib/extensions
diff options
context:
space:
mode:
authorIRONM00N <64110067+IRONM00N@users.noreply.github.com>2021-06-14 22:51:48 -0400
committerIRONM00N <64110067+IRONM00N@users.noreply.github.com>2021-06-14 22:51:48 -0400
commitd055e0dbb86ef7fd4ee96a1531b51181e825fb4b (patch)
treee2ed9e956f2d8167e7f225383f9917e66d2a2803 /src/lib/extensions
parent335f7c30994fc8c4e787f407dfd4c2de63b400e3 (diff)
downloadtanzanite-d055e0dbb86ef7fd4ee96a1531b51181e825fb4b.tar.gz
tanzanite-d055e0dbb86ef7fd4ee96a1531b51181e825fb4b.tar.bz2
tanzanite-d055e0dbb86ef7fd4ee96a1531b51181e825fb4b.zip
made a few changes
Diffstat (limited to 'src/lib/extensions')
-rw-r--r--src/lib/extensions/BushClient.ts37
-rw-r--r--src/lib/extensions/BushCommand.ts1
-rw-r--r--src/lib/extensions/BushCommandHandler.ts15
-rw-r--r--src/lib/extensions/BushInteractionMessage.ts15
-rw-r--r--src/lib/extensions/BushListenerHandler.ts6
-rw-r--r--src/lib/extensions/BushMessage.ts11
-rw-r--r--src/lib/extensions/BushTaskHandler.ts12
-rw-r--r--src/lib/extensions/Util.ts256
8 files changed, 299 insertions, 54 deletions
diff --git a/src/lib/extensions/BushClient.ts b/src/lib/extensions/BushClient.ts
index 8a0fc8c..e2e889b 100644
--- a/src/lib/extensions/BushClient.ts
+++ b/src/lib/extensions/BushClient.ts
@@ -1,14 +1,15 @@
-import { AkairoClient, CommandHandler, InhibitorHandler, ListenerHandler, TaskHandler } from 'discord-akairo';
-import { Guild } from 'discord.js';
+import chalk from 'chalk';
+import { AkairoClient, InhibitorHandler, ListenerHandler, TaskHandler } from 'discord-akairo';
+import { Guild, Intents, Snowflake } from 'discord.js';
import * as path from 'path';
-import { Sequelize } from 'sequelize';
-import * as Models from '../models';
-import { Util } from './Util';
import { exit } from 'process';
-import { Intents } from 'discord.js';
+import { Sequelize } from 'sequelize';
import * as config from '../../config/options';
-import { Logger } from '../utils/Logger';
-import chalk from 'chalk';
+import * as Models from '../models';
+import AllowedMentions from '../utils/AllowedMentions';
+import { BushLogger } from '../utils/Logger';
+import { BushCommandHandler } from './BushCommandHandler';
+import { BushUtil } from './Util';
export type BotConfig = typeof config;
@@ -16,21 +17,21 @@ export class BushClient extends AkairoClient {
public config: BotConfig;
public listenerHandler: ListenerHandler;
public inhibitorHandler: InhibitorHandler;
- public commandHandler: CommandHandler;
+ public commandHandler: BushCommandHandler;
public taskHandler: TaskHandler;
- public util: Util;
- public ownerID: string[];
+ public util: BushUtil;
+ public ownerID: Snowflake[];
public db: Sequelize;
- public logger: Logger;
+ public logger: BushLogger;
constructor(config: BotConfig) {
super(
{
ownerID: config.owners,
- intents: Intents.NON_PRIVILEGED
+ intents: Intents.ALL
},
{
- allowedMentions: { parse: ['users'] }, // No everyone or role mentions by default
- intents: Intents.NON_PRIVILEGED
+ allowedMentions: AllowedMentions.users(), // No everyone or role mentions by default
+ intents: Intents.ALL
}
);
@@ -58,7 +59,7 @@ export class BushClient extends AkairoClient {
});
// Create command handler
- this.commandHandler = new CommandHandler(this, {
+ this.commandHandler = new BushCommandHandler(this, {
directory: path.join(__dirname, '..', '..', 'commands'),
prefix: async ({ guild }: { guild: Guild }) => {
const row = await Models.Guild.findByPk(guild.id);
@@ -82,14 +83,14 @@ export class BushClient extends AkairoClient {
automateCategories: true
});
- this.util = new Util(this);
+ this.util = new BushUtil(this);
this.db = new Sequelize(this.config.dev ? 'bushbot-dev' : 'bushbot', this.config.db.username, this.config.db.password, {
dialect: 'postgres',
host: this.config.db.host,
port: this.config.db.port,
logging: false
});
- this.logger = new Logger(this);
+ this.logger = new BushLogger(this);
}
// Initialize everything
diff --git a/src/lib/extensions/BushCommand.ts b/src/lib/extensions/BushCommand.ts
index 4f9dc6e..2b34c69 100644
--- a/src/lib/extensions/BushCommand.ts
+++ b/src/lib/extensions/BushCommand.ts
@@ -13,6 +13,7 @@ export interface BushCommandOptions extends CommandOptions {
export class BushCommand extends Command {
public client: BushClient;
+ options: BushCommandOptions;
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
new file mode 100644
index 0000000..6ef44d7
--- /dev/null
+++ b/src/lib/extensions/BushCommandHandler.ts
@@ -0,0 +1,15 @@
+import { CommandHandler, CommandHandlerOptions } from 'discord-akairo';
+import { Collection } from 'discord.js';
+import { BushClient } from './BushClient';
+import { BushCommand } from './BushCommand';
+
+export interface BushCommandHandlerOptions extends CommandHandlerOptions {}
+
+export class BushCommandHandler extends CommandHandler {
+ public constructor(client: BushClient, options: BushCommandHandlerOptions) {
+ super(client, options);
+ this.client = client;
+ }
+
+ declare modules: Collection<string, BushCommand>;
+}
diff --git a/src/lib/extensions/BushInteractionMessage.ts b/src/lib/extensions/BushInteractionMessage.ts
new file mode 100644
index 0000000..9bdc291
--- /dev/null
+++ b/src/lib/extensions/BushInteractionMessage.ts
@@ -0,0 +1,15 @@
+import { AkairoMessage } from 'discord-akairo';
+import { CommandInteraction } from 'discord.js';
+import { BushClient } from './BushClient';
+
+export class BushInteractionMessage extends AkairoMessage {
+ 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/BushListenerHandler.ts b/src/lib/extensions/BushListenerHandler.ts
new file mode 100644
index 0000000..28615fc
--- /dev/null
+++ b/src/lib/extensions/BushListenerHandler.ts
@@ -0,0 +1,6 @@
+import { ListenerHandler } from 'discord-akairo';
+import { BushClient } from './BushClient';
+
+export class BushListenerHandler extends ListenerHandler {
+ declare client: BushClient;
+}
diff --git a/src/lib/extensions/BushMessage.ts b/src/lib/extensions/BushMessage.ts
new file mode 100644
index 0000000..e7146f6
--- /dev/null
+++ b/src/lib/extensions/BushMessage.ts
@@ -0,0 +1,11 @@
+import { DMChannel, Message, NewsChannel, TextChannel } from 'discord.js';
+import { BushClient } from './BushClient';
+
+export class BushMessage extends Message {
+ declare client: BushClient;
+ constructor(client: BushClient, data: unknown, channel: TextChannel | DMChannel | NewsChannel) {
+ super(client, data, channel);
+ this.client = client;
+ this.channel = channel;
+ }
+}
diff --git a/src/lib/extensions/BushTaskHandler.ts b/src/lib/extensions/BushTaskHandler.ts
new file mode 100644
index 0000000..f783eb3
--- /dev/null
+++ b/src/lib/extensions/BushTaskHandler.ts
@@ -0,0 +1,12 @@
+import { AkairoHandlerOptions, TaskHandler } from 'discord-akairo';
+import { BushClient } from './BushClient';
+
+export interface BushTaskHandlerOptions extends 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/extensions/Util.ts b/src/lib/extensions/Util.ts
index 78fba12..3913437 100644
--- a/src/lib/extensions/Util.ts
+++ b/src/lib/extensions/Util.ts
@@ -1,20 +1,33 @@
-import { ClientUtil } from 'discord-akairo';
-import { BushClient } from './BushClient';
-import { promisify } from 'util';
+import chalk from 'chalk';
import { exec } from 'child_process';
-import got from 'got';
-import { MessageEmbed, GuildMember, User } from 'discord.js';
-import { CommandInteractionOption } from 'discord.js';
+import { ClientUtil, Command } from 'discord-akairo';
import {
- ApplicationCommandOptionType,
- APIInteractionDataResolvedGuildMember,
APIInteractionDataResolvedChannel,
- APIRole
+ APIInteractionDataResolvedGuildMember,
+ APIRole,
+ ApplicationCommandOptionType
} from 'discord-api-types';
-import { GuildChannel } from 'discord.js';
-import { Role } from 'discord.js';
-import chalk from 'chalk';
-import { Guild } from 'discord.js';
+import {
+ ButtonInteraction,
+ CommandInteractionOption,
+ Constants,
+ Guild,
+ GuildChannel,
+ GuildMember,
+ MessageActionRow,
+ MessageButton,
+ MessageComponentInteraction,
+ MessageEmbed,
+ MessageOptions,
+ Role,
+ Snowflake,
+ User,
+ Util
+} from 'discord.js';
+import got from 'got';
+import { promisify } from 'util';
+import { BushClient } from './BushClient';
+import { BushMessage } from './BushMessage';
interface hastebinRes {
key: string;
@@ -23,11 +36,7 @@ interface hastebinRes {
export interface uuidRes {
uuid: string;
username: string;
- username_history?:
- | {
- username: string;
- }[]
- | null;
+ username_history?: { username: string }[] | null;
textures: {
custom: boolean;
slim: boolean;
@@ -54,7 +63,7 @@ export interface SlashCommandOption<T> {
role?: Role | APIRole;
}
-export class Util extends ClientUtil {
+export class BushUtil extends ClientUtil {
/**
* The client of this ClientUtil
* @type {BushClient}
@@ -92,7 +101,7 @@ export class Util extends ClientUtil {
* @param ids The list of IDs to map
* @returns The list of users mapped
*/
- public async mapIDs(ids: string[]): Promise<User[]> {
+ public async mapIDs(ids: Snowflake[]): Promise<User[]> {
return await Promise.all(ids.map((id) => this.client.users.fetch(id)));
}
@@ -144,7 +153,7 @@ export class Util extends ClientUtil {
const idMatch = text.match(idReg);
if (idMatch) {
try {
- const user = await this.client.users.fetch(text);
+ const user = await this.client.users.fetch(text as Snowflake);
return user;
} catch {
// pass
@@ -154,7 +163,7 @@ export class Util extends ClientUtil {
const mentionMatch = text.match(mentionReg);
if (mentionMatch) {
try {
- const user = await this.client.users.fetch(mentionMatch.groups.id);
+ const user = await this.client.users.fetch(mentionMatch.groups.id as Snowflake);
return user;
} catch {
// pass
@@ -195,24 +204,37 @@ export class Util extends ClientUtil {
*/
public colors = {
default: '#1FD8F1',
- error: '#ff0000',
- success: '#00ff02',
+ error: '#EF4947',
+ warn: '#FEBA12',
+ success: '#3BB681',
red: '#ff0000',
- blue: '#0055ff',
+ orange: '#E86100',
+ gold: '#b59400',
+ yellow: '#ffff00',
+ green: '#00ff1e',
+ darkGreen: '#008f11',
aqua: '#00bbff',
- purple: '#8400ff',
+ blue: '#0055ff',
blurple: '#5440cd',
+ purple: '#8400ff',
pink: '#ff00e6',
- green: '#00ff1e',
- darkgreen: '#008f11',
- gold: '#b59400',
- yellow: '#ffff00',
white: '#ffffff',
gray: '#a6a6a6',
- lightgray: '#cfcfcf',
- darkgray: '#7a7a7a',
- black: '#000000',
- orange: '#E86100'
+ lightGray: '#cfcfcf',
+ darkGray: '#7a7a7a',
+ black: '#000000'
+ };
+
+ public emojis = {
+ success: '<:checkmark:837109864101707807>',
+ warn: '<:warn:848726900876247050> ',
+ error: '<:error:837123021016924261>',
+ successFull: '<:checkmark_full:850118767576088646>',
+ warnFull: '<:warn_full:850118767391539312>',
+ errorFull: '<:error_full:850118767295201350>',
+ mad: '<:mad:783046135392239626>',
+ join: '<:join:850198029809614858>',
+ leave: '<:leave:850198048205307919>'
};
/**
@@ -238,7 +260,7 @@ export class Util extends ClientUtil {
return apiRes.uuid.replace(/-/g, '');
}
- public async syncSlashCommands(force = false, guild?: string): Promise<void> {
+ public async syncSlashCommands(force = false, guild?: Snowflake): Promise<void> {
let fetchedGuild: Guild;
if (guild) fetchedGuild = this.client.guilds.cache.get(guild);
try {
@@ -260,7 +282,7 @@ export class Util extends ClientUtil {
for (const [, botCommand] of this.client.commandHandler.modules) {
if (botCommand.execSlash) {
const found = registered.find((i) => i.name == botCommand.id);
-
+ Command;
const slashdata = {
name: botCommand.id,
description: botCommand.description.content,
@@ -332,6 +354,168 @@ export class Util extends ClientUtil {
{ name: 'No Giveaways', id: '808265422334984203' },
{ name: 'No Support', id: '790247359824396319' }
];
+
+ private paginateEmojis = {
+ begging: '853667381335162910',
+ back: '853667410203770881',
+ stop: '853667471110570034',
+ forward: '853667492680564747',
+ end: '853667514915225640'
+ };
+
+ public async buttonPaginate(
+ message: BushMessage,
+ embeds: MessageEmbed[],
+ text: string | null = null,
+ deleteOnExit?: boolean
+ ): Promise<void> {
+ if (deleteOnExit === undefined) deleteOnExit = true;
+ embeds.forEach((_e, i) => {
+ embeds[i] = embeds[i].setFooter(`Page ${i + 1}/${embeds.length}`);
+ });
+
+ const style = Constants.MessageButtonStyles.PRIMARY;
+ let curPage = 0;
+ if (typeof embeds !== 'object') throw 'embeds must be an object';
+ const msg = await message.util.reply({ content: text, embeds: [embeds[curPage]], components: [getPaginationRow()] });
+ const filter = (interaction: ButtonInteraction) =>
+ interaction.customID.startsWith('paginate_') && interaction.message == msg;
+ const collector = msg.createMessageComponentInteractionCollector(filter, { time: 300000 });
+ collector.on('collect', async (interaction: MessageComponentInteraction) => {
+ if (interaction.user.id == message.author.id || message.client.config.owners.includes(interaction.user.id)) {
+ switch (interaction.customID) {
+ case 'paginate_beginning': {
+ curPage = 0;
+ await edit(interaction);
+ break;
+ }
+ case 'paginate_back': {
+ curPage--;
+ await edit(interaction);
+ break;
+ }
+ case 'paginate_stop': {
+ if (deleteOnExit) {
+ await interaction.deferUpdate();
+ await msg.delete();
+ } else {
+ await interaction?.update({
+ content: `${text ? text + '\n' : ''}Command closed by user.`,
+ embeds: [],
+ components: []
+ });
+ }
+ return;
+ }
+ case 'paginate_next': {
+ curPage++;
+ await edit(interaction);
+ break;
+ }
+ case 'paginate_end': {
+ curPage = embeds.length - 1;
+ await edit(interaction);
+ break;
+ }
+ }
+ } else {
+ return await interaction?.deferUpdate();
+ }
+ });
+
+ collector.on('end', async () => {
+ await msg.edit({ content: text, embeds: [embeds[curPage]], components: [getPaginationRow(true)] }).catch(() => {});
+ });
+
+ async function edit(interaction: MessageComponentInteraction): Promise<void> {
+ return await interaction?.update({ content: text, embeds: [embeds[curPage]], components: [getPaginationRow()] });
+ }
+ function getPaginationRow(disableAll = false): MessageActionRow {
+ return new MessageActionRow().addComponents(
+ new MessageButton({
+ style,
+ customID: 'paginate_beginning',
+ emoji: this.paginateEmojis.begging,
+ disabled: disableAll || curPage == 0
+ }),
+ new MessageButton({
+ style,
+ customID: 'paginate_back',
+ emoji: this.paginateEmojis.back,
+ disabled: disableAll || curPage == 0
+ }),
+ new MessageButton({ style, customID: 'paginate_stop', emoji: this.paginateEmojis.stop, disabled: disableAll }),
+ new MessageButton({
+ style,
+ customID: 'paginate_next',
+ emoji: this.paginateEmojis.forward,
+ disabled: disableAll || curPage == embeds.length - 1
+ }),
+ new MessageButton({
+ style,
+ customID: 'paginate_end',
+ emoji: this.paginateEmojis.end,
+ disabled: disableAll || curPage == embeds.length - 1
+ })
+ );
+ }
+ }
+
+ public async sendWithDeleteButton(message: BushMessage, options: MessageOptions): Promise<void> {
+ updateOptions();
+ const msg = await message.util.reply(options as MessageOptions & { split?: false });
+ const filter = (interaction: ButtonInteraction) => interaction.customID == 'paginate__stop' && interaction.message == msg;
+ const collector = msg.createMessageComponentInteractionCollector(filter, { time: 300000 });
+ collector.on('collect', async (interaction: MessageComponentInteraction) => {
+ if (interaction.user.id == message.author.id || message.client.config.owners.includes(interaction.user.id)) {
+ await interaction.deferUpdate();
+ await msg.delete();
+ return;
+ } else {
+ return await interaction?.deferUpdate();
+ }
+ });
+
+ collector.on('end', async () => {
+ updateOptions(true, true);
+ await msg.edit(options);
+ });
+
+ function updateOptions(edit?: boolean, disable?: boolean) {
+ if (edit == undefined) edit = false;
+ if (disable == undefined) disable = false;
+ options.components = [
+ new MessageActionRow().addComponents(
+ new MessageButton({
+ style: Constants.MessageButtonStyles.PRIMARY,
+ customID: 'paginate__stop',
+ emoji: this.paginateEmojis.stop,
+ disabled: disable
+ })
+ )
+ ];
+ if (edit) {
+ options.reply = undefined;
+ }
+ }
+ }
+ /**
+ * Surrounds text in a code block with the specified language and puts it in a haste bin if it too long.
+ *
+ * * Embed Description Limit = 2048 characters
+ * * Embed Field Limit = 1024 characters
+ */
+ public async codeblock(code: string, length: number, language: 'ts' | 'js' | 'sh' | 'json' | '' = ''): Promise<string> {
+ let hasteOut = '';
+ const tildes = '```';
+ const formattingLength = 2 * tildes.length + language.length + 2 * '\n'.length;
+ if (code.length + formattingLength > length) hasteOut = 'Too large to display. Hastebin: ' + (await this.haste(code));
+
+ const code2 = code.length > length ? code.substring(0, length - (hasteOut.length + '\n'.length + formattingLength)) : code;
+ return (
+ tildes + language + '\n' + Util.cleanCodeBlockContent(code2) + '\n' + tildes + (hasteOut.length ? '\n' + hasteOut : '')
+ );
+ }
}
// I just copy pasted this code from stackoverflow don't yell at me if there is issues for it