Command registration (for mini)

pull/17/head
PineaFan 3 years ago
parent 64486c49fb
commit 752af46e5e
No known key found for this signature in database
GPG Key ID: 0AEF25BAA0FB1C74

@ -19,6 +19,7 @@
"immutable": "^4.1.0",
"mongodb": "^4.7.0",
"node-cron": "^3.0.0",
"node-fetch": "^3.3.0",
"node-tesseract-ocr": "^2.2.1",
"pastebin-api": "^5.1.1",
"structured-clone": "^0.2.2",

@ -1,7 +1,9 @@
import { CommandInteraction } from "discord.js";
import type { CommandInteraction } from "discord.js";
import { SlashCommandBuilder } from "@discordjs/builders";
const command = new SlashCommandBuilder().setName("help").setDescription("Shows help for commands");
const command = new SlashCommandBuilder()
.setName("help")
.setDescription("Shows help for commands");
const callback = async (interaction: CommandInteraction): Promise<void> => {
interaction.reply("hel p D:"); // TODO: FINISH THIS FOR RELEASE

@ -5,6 +5,7 @@ import verify from "../reflex/verify.js";
const command = new SlashCommandBuilder().setName("verify").setDescription("Get verified in the server");
const callback = async (interaction: CommandInteraction): Promise<void> => {
interaction.reply("boo")
verify(interaction);
};

@ -50,6 +50,7 @@
}
},
"verify": {
"enabled": false,
"role": null
},
"tickets": {

@ -1,6 +1,6 @@
import type { GuildAuditLogsEntry } from "discord.js";
import type { GuildBasedChannel } from "discord.js";
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
export const event = "channelCreate";
export async function callback(client: NucleusClient, channel: GuildBasedChannel) {

@ -6,12 +6,12 @@ import {
ThreadChannel,
VoiceChannel
} from "discord.js";
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
import getEmojiByName from "../utils/getEmojiByName.js";
export const event = "channelDelete";
export async function callback(client: HaikuClient, channel: GuildBasedChannel) {
export async function callback(client: NucleusClient, channel: GuildBasedChannel) {
const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser } = client.logger;
const auditLog = await getAuditLog(channel.guild, "CHANNEL_DELETE");

@ -1,11 +1,11 @@
import type { GuildAuditLogsEntry, GuildBan } from "discord.js";
import { purgeByUser } from "../actions/tickets/delete.js";
import { callback as statsChannelRemove } from "../reflex/statsChannelUpdate.js";
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
export const event = "guildBanAdd";
export async function callback(client: HaikuClient, ban: GuildBan) {
export async function callback(client: NucleusClient, ban: GuildBan) {
await statsChannelRemove(client, undefined, ban.guild, ban.user);
purgeByUser(ban.user.id, ban.guild);
const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = client.logger;

@ -1,10 +1,10 @@
import type { GuildAuditLogsEntry, GuildBan } from "discord.js";
import { purgeByUser } from "../actions/tickets/delete.js";
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
export const event = "guildBanRemove";
export async function callback(client: HaikuClient, ban: GuildBan) {
export async function callback(client: NucleusClient, ban: GuildBan) {
purgeByUser(ban.user.id, ban.guild);
const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = client.logger;
const auditLog = await getAuditLog(ban.guild, "MEMBER_BAN_REMOVE");

@ -1,9 +1,9 @@
import type { Guild } from "discord.js";
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
import guide from "../reflex/guide.js";
export const event = "guildCreate";
export async function callback(_client: HaikuClient, guild: Guild) {
export async function callback(_client: NucleusClient, guild: Guild) {
guide(guild);
}

@ -1,9 +1,9 @@
import type { GuildAuditLogsEntry, GuildMember } from "discord.js";
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
export const event = "guildMemberUpdate";
export async function callback(client: HaikuClient, before: GuildMember, after: GuildMember) {
export async function callback(client: NucleusClient, before: GuildMember, after: GuildMember) {
try {
const { log, NucleusColors, entry, renderUser, renderDelta, getAuditLog } = client.logger;
const auditLog = await getAuditLog(after.guild, "MEMBER_UPDATE");

@ -1,10 +1,10 @@
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
import type { Guild, GuildAuditLogsEntry } from "discord.js";
import { callback as statsChannelUpdate } from "../reflex/statsChannelUpdate.js";
export const event = "guildUpdate";
export async function callback(client: HaikuClient, before: Guild, after: Guild) {
export async function callback(client: NucleusClient, before: Guild, after: Guild) {
await statsChannelUpdate(client, after.me!);
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
const auditLog = await getAuditLog(after, "GUILD_UPDATE");

@ -6,7 +6,7 @@ import createTranscript from "../premium/createTranscript.js";
import Fuse from "fuse.js";
import { autocomplete as tagAutocomplete } from "../commands/tag.js";
import type { AutocompleteInteraction, Interaction, MessageComponentInteraction } from "discord.js";
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
export const event = "interactionCreate";
@ -102,6 +102,6 @@ async function interactionCreate(interaction: Interaction) {
}
}
export async function callback(_client: HaikuClient, interaction: Interaction) {
export async function callback(_client: NucleusClient, interaction: Interaction) {
await interactionCreate(interaction);
}

@ -1,11 +1,11 @@
import type { GuildAuditLogsEntry, Invite } from "discord.js";
// @ts-expect-error
import humanizeDuration from "humanize-duration";
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
export const event = "inviteCreate";
export async function callback(client: HaikuClient, invite: Invite) {
export async function callback(client: NucleusClient, invite: Invite) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
const auditLog = await getAuditLog(invite.guild, "INVITE_CREATE");
const audit = auditLog.entries

@ -1,11 +1,11 @@
import type { GuildAuditLogsEntry, Invite } from "discord.js";
// @ts-expect-error
import humanizeDuration from "humanize-duration";
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
export const event = "inviteDelete";
export async function callback(client: HaikuClient, invite: Invite) {
export async function callback(client: NucleusClient, invite: Invite) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
const auditLog = await getAuditLog(invite.guild, "INVITE_DELETE");
const audit = auditLog.entries

@ -1,11 +1,11 @@
import type { GuildMember } from "discord.js";
import { callback as statsChannelAdd } from "../reflex/statsChannelUpdate.js";
import { callback as welcome } from "../reflex/welcome.js";
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
export const event = "guildMemberAdd";
export async function callback(client: HaikuClient, member: GuildMember) {
export async function callback(client: NucleusClient, member: GuildMember) {
welcome(client, member);
statsChannelAdd(client, member);
const { log, NucleusColors, entry, renderUser, renderDelta } = client.logger;

@ -1,12 +1,12 @@
import type { GuildAuditLogsEntry, GuildMember } from "discord.js";
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
import { purgeByUser } from "../actions/tickets/delete.js";
import { callback as statsChannelRemove } from "../reflex/statsChannelUpdate.js";
export const event = "guildMemberRemove";
export async function callback(client: HaikuClient, member: GuildMember) {
export async function callback(client: NucleusClient, member: GuildMember) {
purgeByUser(member.id, member.guild);
await statsChannelRemove(client, member);
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = client.logger;

@ -1,4 +1,4 @@
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
import { LinkCheck, MalwareCheck, NSFWCheck, SizeCheck, TestString, TestImage } from "../reflex/scanners.js";
import logAttachment from "../premium/attachmentLogs.js";
import createLogException from "../utils/createLogException.js";
@ -9,7 +9,7 @@ import { Message, ThreadChannel } from "discord.js";
export const event = "messageCreate";
export async function callback(_client: HaikuClient, message: Message) {
export async function callback(_client: NucleusClient, message: Message) {
if (!message.guild) return;
if (message.author.bot) return;
if (message.channel.type === "DM") return;

@ -1,9 +1,9 @@
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
import type { GuildAuditLogsEntry, Message } from "discord.js";
export const event = "messageDelete";
export async function callback(client: HaikuClient, message: Message) {
export async function callback(client: NucleusClient, message: Message) {
try {
if (message.author.id === client.user.id) return;
if (client.noLog.includes(`${message.id}/${message.channel.id}/${message.id}`)) return;

@ -1,9 +1,9 @@
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
import type { Message, MessageReference } from "discord.js";
export const event = "messageUpdate";
export async function callback(client: HaikuClient, oldMessage: Message, newMessage: Message) {
export async function callback(client: NucleusClient, oldMessage: Message, newMessage: Message) {
if (newMessage.author.id === client.user.id) return;
if (!newMessage.guild) return;
const { log, NucleusColors, entry, renderUser, renderDelta, renderNumberDelta, renderChannel } = client.logger;

@ -1,9 +1,9 @@
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
import type { GuildAuditLogsEntry, Role } from "discord.js";
export const event = "roleCreate";
export async function callback(client: HaikuClient, role: Role) {
export async function callback(client: NucleusClient, role: Role) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderRole } = client.logger;
if (role.managed) return;
const auditLog = await getAuditLog(role.guild, "ROLE_CREATE");

@ -1,10 +1,10 @@
import getEmojiByName from "../utils/getEmojiByName.js";
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
import type { GuildAuditLogsEntry, Role } from "discord.js";
export const event = "roleDelete";
export async function callback(client: HaikuClient, role: Role) {
export async function callback(client: NucleusClient, role: Role) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
if (role.managed) return;
const auditLog = await getAuditLog(role.guild, "ROLE_DELETE");

@ -1,10 +1,10 @@
import type { Role } from "discord.js";
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
import getEmojiByName from "../utils/getEmojiByName.js";
export const event = "roleUpdate";
export async function callback(client: HaikuClient, or: Role, nr: Role) {
export async function callback(client: NucleusClient, or: Role, nr: Role) {
const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser, renderRole } = client.logger;
const auditLog = await getAuditLog(nr.guild, "ROLE_UPDATE");

@ -1,9 +1,9 @@
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
import type { GuildAuditLogsEntry, Sticker } from "discord.js";
export const event = "stickerDelete";
export async function callback(client: HaikuClient, emoji: Sticker) {
export async function callback(client: NucleusClient, emoji: Sticker) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
const auditLog = await getAuditLog(emoji.guild, "STICKER_CREATE");
const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === emoji.id).first();

@ -1,9 +1,9 @@
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
import type { GuildAuditLogsEntry, Sticker } from "discord.js";
export const event = "stickerDelete";
export async function callback(client: HaikuClient, emoji: Sticker) {
export async function callback(client: NucleusClient, emoji: Sticker) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta } = client.logger;
const auditLog = await getAuditLog(emoji.guild, "STICKER_DELETE");
const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === emoji.id).first();

@ -1,9 +1,9 @@
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
import type { Sticker } from "discord.js";
export const event = "stickerUpdate";
export async function callback(client: HaikuClient, oe: Sticker, ne: Sticker) {
export async function callback(client: NucleusClient, oe: Sticker, ne: Sticker) {
const { getAuditLog, log, NucleusColors, entry, renderDelta, renderUser } = client.logger;
if (oe.name === ne.name) return;

@ -1,10 +1,10 @@
import type { GuildAuditLogsEntry, ThreadChannel } from "discord.js";
// @ts-expect-error
import humanizeDuration from "humanize-duration";
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
export const event = "threadCreate";
export async function callback(client: HaikuClient, thread: ThreadChannel) {
export async function callback(client: NucleusClient, thread: ThreadChannel) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
const auditLog = await getAuditLog(thread.guild, "THREAD_CREATE");
const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === thread.id).first();

@ -1,10 +1,10 @@
import type { GuildAuditLogsEntry, ThreadChannel } from "discord.js";
// @ts-expect-error
import humanizeDuration from "humanize-duration";
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
export const event = "threadDelete";
export async function callback(client: HaikuClient, thread: ThreadChannel) {
export async function callback(client: NucleusClient, thread: ThreadChannel) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
const auditLog = await getAuditLog(thread.guild, "THREAD_UPDATE");
const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === thread.id).first();

@ -1,11 +1,11 @@
import type { GuildAuditLogsEntry, ThreadChannel } from "discord.js";
// @ts-expect-error
import humanizeDuration from "humanize-duration";
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
export const event = "threadUpdate";
export async function callback(client: HaikuClient, before: ThreadChannel, after: ThreadChannel) {
export async function callback(client: NucleusClient, before: ThreadChannel, after: ThreadChannel) {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderDelta, renderChannel } = client.logger;
const auditLog = await getAuditLog(after.guild, "THREAD_UPDATE");
const audit = auditLog.entries.filter((entry: GuildAuditLogsEntry) => entry.target!.id === after.id).first();

@ -1,9 +1,9 @@
import type { GuildAuditLogsEntry, Webhook } from "discord.js";
import type Discord from "discord.js";
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
export const event = "webhookUpdate";
export async function callback(client: HaikuClient, channel: Discord.GuildChannel) {
export async function callback(client: NucleusClient, channel: Discord.GuildChannel) {
try {
const { getAuditLog, log, NucleusColors, entry, renderUser, renderChannel, renderDelta } = client.logger;
let auditLogCreate = getAuditLog(channel.guild, "WEBHOOK_CREATE");

@ -11,10 +11,9 @@ import {
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import getEmojiByName from "../utils/getEmojiByName.js";
import { PasteClient, Publicity, ExpireDate } from "pastebin-api";
import config from "../config/main.json" assert { type: "json" };
import client from "../utils/client.js";
const pbClient = new PasteClient(config.pastebinApiKey);
const pbClient = new PasteClient(client.config.pastebinApiKey);
export default async function (interaction: CommandInteraction | MessageComponentInteraction) {
if (interaction.channel === null) return;

@ -1,5 +1,5 @@
import type { Guild, User } from "discord.js";
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
import type { GuildMember } from "discord.js";
import convertCurlyBracketString from "../utils/convertCurlyBracketString.js";
import singleNotify from "../utils/singleNotify.js";
@ -9,7 +9,7 @@ interface PropSchema {
name: string;
}
export async function callback(client: HaikuClient, member?: GuildMember, guild?: Guild, user?: User) {
export async function callback(client: NucleusClient, member?: GuildMember, guild?: Guild, user?: User) {
if (!member && !guild) return;
guild = await client.guilds.fetch(member ? member.guild.id : guild!.id);
if (!guild) return;

@ -2,11 +2,10 @@ import { LoadingEmbed } from "./../utils/defaultEmbeds.js";
import Discord, {
CommandInteraction,
GuildMember,
Interaction,
MessageComponentInteraction,
Permissions,
Role,
ButtonStyle
ButtonStyle,
PermissionsBitField
} from "discord.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import fetch from "node-fetch";
@ -22,7 +21,7 @@ export interface VerifySchema {
uName: string;
gName: string;
gIcon: string;
interaction: Interaction;
interaction: Discord.MessageComponentInteraction;
}
function step(i: number) {
@ -44,7 +43,7 @@ export default async function (interaction: CommandInteraction | MessageComponen
.setTitle("Verify")
.setDescription("Verify is not enabled on this server")
.setFooter({
text: (interaction.member!.permissions as Permissions).has("MANAGE_GUILD")
text: (interaction.member!.permissions as PermissionsBitField).has("ManageGuild")
? "You can enable it by running /settings verify"
: ""
})
@ -95,7 +94,7 @@ export default async function (interaction: CommandInteraction | MessageComponen
.setEmoji("CONTROL.BLOCKCROSS")
],
components: [
new Discord.ActionRowBuilder().addComponents([
new Discord.ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
new Discord.ButtonBuilder()
.setLabel("Check webpage")
.setStyle(ButtonStyle.Link)
@ -120,9 +119,7 @@ export default async function (interaction: CommandInteraction | MessageComponen
});
if (
await NSFWCheck(
(interaction.member as GuildMember).user.displayAvatarURL({
format: "png"
})
(interaction.member as GuildMember).user.displayAvatarURL({extension: "png", forceStatic: true})
)
) {
return await interaction.editReply({
@ -139,7 +136,7 @@ export default async function (interaction: CommandInteraction | MessageComponen
});
}
}
if (config.filters.wordFilter) {
if (config.filters.wordFilter.enabled) {
await interaction.editReply({
embeds: [
new EmojiEmbed()
@ -217,8 +214,8 @@ export default async function (interaction: CommandInteraction | MessageComponen
rName: role.name,
uName: interaction.member!.user.username,
gName: interaction.guild!.name,
gIcon: interaction.guild!.iconURL({ format: "png" }),
interaction: interaction
gIcon: interaction.guild!.iconURL({ extension: "png", size: 256 }) ?? "https://assets-global.website-files.com/6257adef93867e50d84d30e2/636e0a6a49cf127bf92de1e2_icon_clyde_blurple_RGB.png",
interaction: interaction as MessageComponentInteraction
};
await interaction.editReply({
embeds: [
@ -229,7 +226,7 @@ export default async function (interaction: CommandInteraction | MessageComponen
.setEmoji("MEMBER.JOIN")
],
components: [
new Discord.ActionRowBuilder().addComponents([
new Discord.ActionRowBuilder<Discord.ButtonBuilder>().addComponents([
new Discord.ButtonBuilder()
.setLabel("Verify")
.setStyle(ButtonStyle.Link)

@ -1,10 +1,10 @@
import type { HaikuClient } from "../utils/haiku/index.js";
import type { NucleusClient } from "../utils/client.js";
import convertCurlyBracketString from "../utils/convertCurlyBracketString.js";
import client from "../utils/client.js";
import EmojiEmbed from "../utils/generateEmojiEmbed.js";
import { GuildChannel, GuildMember, BaseGuildTextChannel } from "discord.js";
export async function callback(_client: HaikuClient, member: GuildMember) {
export async function callback(_client: NucleusClient, member: GuildMember) {
if (member.user.bot) return;
const config = await client.database.guilds.read(member.guild.id);
if (!config.welcome.enabled) return;

@ -1,14 +1,16 @@
import { Client } from 'discord.js';
import Discord, { Client, Interaction } from 'discord.js';
import { Logger } from "../utils/log.js";
import Memory from "../utils/memory.js";
import type { VerifySchema } from "../reflex/verify.js";
import { Guilds, History, ModNotes, Premium } from "../utils/database.js";
import EventScheduler from "../utils/eventScheduler.js";
import type { RoleMenuSchema } from "../actions/roleMenu.js";
import config from "../config/main.json" assert { type: "json" };
class NucleusClient extends Client {
logger = Logger;
config: typeof config = config;
verify: Record<string, VerifySchema> = {};
roleMenu: Record<string, RoleMenuSchema> = {};
memory: Memory = new Memory() as Memory;
@ -20,6 +22,14 @@ class NucleusClient extends Client {
premium: Premium;
eventScheduler: EventScheduler;
};
// commands: Record<string, {
// command: Discord.SlashCommandBuilder |
// ((builder: Discord.SlashCommandBuilder) => Discord.SlashCommandBuilder) |
// Discord.SlashCommandSubcommandBuilder | ((builder: Discord.SlashCommandSubcommandBuilder) => Discord.SlashCommandSubcommandBuilder) | Discord.SlashCommandSubcommandGroupBuilder | ((builder: Discord.SlashCommandSubcommandGroupBuilder) => Discord.SlashCommandSubcommandGroupBuilder),
// callback: (interaction: Interaction) => Promise<void>,
// check: (interaction: Interaction) => Promise<boolean> | boolean
// }> = {};
commands: Discord.Collection<string, [Function, Function]> = new Discord.Collection();
constructor(database: typeof NucleusClient.prototype.database) {
super({ intents: 32767 });

@ -1,23 +1,27 @@
import fs from "fs";
export default async function getSubcommandsInFolder(path: string) {
export default async function getSubcommandsInFolder(path: string, indent: string = "") {
const files = fs.readdirSync(path, { withFileTypes: true }).filter(
file => !file.name.endsWith(".ts") && !file.name.endsWith(".map")
);
const subcommands = [];
const subcommandGroups = [];
let errors = 0;
for (const file of files) {
if (file.name === "_meta.js") continue;
// If its a folder
if (file.isDirectory()) {
// Get the _meta.ts file
console.log(`│ ├─ Loading subcommand group ${file.name}}`)
subcommandGroups.push((await import(`../../../${path}/${file.name}/_meta.js`)).command);
} else if (file.name.endsWith(".js")) {
// If its a file
console.log(`│ ├─ Loading subcommand ${file.name}}`)
subcommands.push((await import(`../../../${path}/${file.name}`)).command);
try {
if (file.isDirectory()) {
// Get the _meta.ts file
subcommandGroups.push((await import(`../../../${path}/${file.name}/_meta.js`)).command);
} else if (file.name.endsWith(".js")) {
// If its a file
console.log(`${indent}├─ Loading subcommand ${file.name}`)
subcommands.push((await import(`../../../${path}/${file.name}`)).command);
}
} catch (e) {
console.error(`${indent}│ └─ Error loading ${file.name}: ${e}`);
errors++;
}
}
return {subcommands, subcommandGroups};
return {subcommands, subcommandGroups, errors};
}

@ -1,9 +1,16 @@
import { SlashCommandBuilder } from 'discord.js';
import { Interaction, SlashCommandBuilder } from 'discord.js';
import config from "../../config/main.json" assert { type: "json" };
import client from "../client.js";
import fs from "fs";
const colours = {
red: "\x1b[31m",
green: "\x1b[32m",
yellow: "\x1b[33m",
none: "\x1b[0m"
}
async function registerCommands() {
const developmentMode = config.enableDevelopment;
const commands = [];
@ -14,15 +21,18 @@ async function registerCommands() {
console.log(`Registering ${files.length} commands`)
let i = 0;
for (const file of files) {
// Box drawing characters: | └ ─ ┌ ┐ ┘ ┬ ┤ ├ ┴ ┼
console.log(`├─ ${file.name}`)
const last = i === files.length - 1 ? "└" : "├";
if (file.isDirectory()) {
console.log(`${last}${colours.yellow}Loading subcommands of ${file.name}${colours.none}`)
commands.push((await import(`../../../${config.commandsFolder}/${file.name}/_meta.js`)).command);
} else if (file.name.endsWith(".js")) {
commands.push((await import(`../../../${config.commandsFolder}/${file.name}`)).command);
console.log(`${last}${colours.yellow}Loading command ${file.name}${colours.none}`)
const fetched = (await import(`../../../${config.commandsFolder}/${file.name}`));
commands.push(fetched.command);
client.commands.set(fetched.command.name, [fetched.check, fetched.callback]);
}
i++;
console.log(`├─ Loaded ${file.name} [${i} / ${files.length}]`)
console.log(`${last.replace("└", " ").replace("├", "│")} └─ ${colours.green}Loaded ${file.name} [${i} / ${files.length}]${colours.none}`)
}
console.log(`Loaded ${commands.length} commands, processing...`)
const processed = []
@ -39,11 +49,9 @@ async function registerCommands() {
if (developmentMode) {
const guild = await client.guilds.fetch(config.developmentGuildID);
guild.commands.set([])
guild.commands.set(processed);
console.log(`Commands registered in ${guild.name}`)
} else {
client.application!.commands.set([])
client.application!.commands.set(processed);
console.log(`Commands registered globally`)
}
@ -51,11 +59,83 @@ async function registerCommands() {
};
async function registerEvents() {
// pass
console.log("Reading events")
const files = fs.readdirSync(config.eventsFolder, { withFileTypes: true }).filter(
file => !file.name.endsWith(".ts") && !file.name.endsWith(".map")
);
console.log(`Registering ${files.length} events`)
let i = 0;
let errors = 0;
for (const file of files) {
const last = i === files.length - 1 ? "└" : "├";
i++;
try {
console.log(`${last}${colours.yellow}Loading event ${file.name}${colours.none}`)
const event = (await import(`../../../${config.eventsFolder}/${file.name}`));
client.on(event.event, event.callback.bind(null, client));
console.log(`${last.replace("└", " ").replace("├", "│")} └─ ${colours.green}Loaded ${file.name} [${i} / ${files.length}]${colours.none}`)
} catch (e) {
errors++;
console.log(`${last.replace("└", " ").replace("├", "│")} └─ ${colours.red}Failed to load ${file.name} [${i} / ${files.length}]${colours.none}`)
}
}
console.log(`Loaded ${files.length - errors} events (${errors} failed)`)
};
async function registerCommandHandler() {
client.on("interactionCreate", async (interaction: Interaction) => {
if (!interaction.isCommand()) return;
const commandName = interaction.commandName;
const subcommandGroupName = interaction.options.getSubcommandGroup(false);
const subcommandName = interaction.options.getSubcommand(false);
let fullCommandName = commandName + (subcommandGroupName ? ` ${subcommandGroupName}` : "") + (subcommandName ? ` ${subcommandName}` : "");
const command = this.commands.get(fullCommandName);
if (!command) return;
const sendErrorMessage = async (error: Error) => {
if (this.listenerCount("commandError")) {
return this.emit("commandError", interaction, error);
}
let method = (!interaction.deferred && !interaction.replied) ? interaction.reply.bind(interaction) : interaction.followUp.bind(interaction);
await method({
embeds: [
new Embed()
.setColor(0xff0000)
.setTitle("I couldn't run that command")
.setDescription(error.message ?? error.toString())
]
, ephemeral: true});
}
try {
let hasPermission = await command.check(interaction);
if (!hasPermission) {
sendErrorMessage(new CheckFailedError("You don't have permission to run this command"));
return;
}
} catch (error) {
sendErrorMessage(error);
return;
}
try {
await command.callback(interaction);
} catch (error) {
this._error(error);
sendErrorMessage(error);
return;
}
});
}
export default async function register() {
console.log("> Registering commands")
await registerCommands();
await registerCommandHandler();
await registerEvents();
console.log(`${colours.green}Registered commands and events${colours.none}`)
};

@ -4,8 +4,17 @@ import config from "../../config/main.json" assert { type: "json" };
import getSubcommandsInFolder from "./getFilesInFolder.js";
const colours = {
red: "\x1b[31m",
green: "\x1b[32m",
none: "\x1b[0m"
}
export async function group(name: string, description: string, path: string) {
const fetched = await getSubcommandsInFolder(config.commandsFolder + "/" + path)
console.log(`│ ├─ Loading group ${name}`)
const fetched = await getSubcommandsInFolder(config.commandsFolder + "/" + path, "│ ")
console.log(`│ │ └─ ${fetched.errors ? colours.red : colours.green}Loaded ${fetched.subcommands.length} subcommands for ${name} (${fetched.errors} failed)${colours.none}`)
return (subcommandGroup: SlashCommandSubcommandGroupBuilder) => {
subcommandGroup
.setName(name)
@ -21,7 +30,7 @@ export async function group(name: string, description: string, path: string) {
export async function command(name: string, description: string, path: string) {
const fetched = await getSubcommandsInFolder(config.commandsFolder + "/" + path);
console.log(`├─ Loaded ${fetched.subcommands.length} subcommands and ${fetched.subcommandGroups.length} subcommand groups for ${name}`)
console.log(` ├─ ${fetched.errors ? colours.red : colours.green}Loaded ${fetched.subcommands.length} subcommands and ${fetched.subcommandGroups.length} subcommand groups for ${name} (${fetched.errors} failed)${colours.none}`)
return (command: SlashCommandBuilder) => {
command.setName(name)
command.setDescription(description)

Loading…
Cancel
Save