Relocated loadCommands and loadEvents

This commit is contained in:
WatDuhHekBro 2020-07-25 18:32:49 -05:00
parent 7193c9e70a
commit 14f78a91dc
6 changed files with 59 additions and 53 deletions

View file

@ -1,6 +1,6 @@
import Command from "../core/command";
import {CommonLibrary} from "../core/lib";
import FileManager from "../core/storage";
import {loadCommands} from "../core/command";
const types = ["user", "number", "any"];
@ -9,7 +9,7 @@ export default new Command({
usage: "([command, [subcommand/type], ...])",
async run($: CommonLibrary): Promise<any>
{
const commands = await FileManager.loadCommands();
const commands = await loadCommands();
const list: string[] = [];
for(const [header, command] of commands)
@ -22,7 +22,7 @@ export default new Command({
any: new Command({
async run($: CommonLibrary): Promise<any>
{
const commands = await FileManager.loadCommands();
const commands = await loadCommands();
let header = $.args.shift();
let command = commands.get(header);

View file

@ -1,4 +1,7 @@
import {isType, parseVars, CommonLibrary} from "./lib";
import $, {isType, parseVars, CommonLibrary} from "./lib";
import {Collection} from "discord.js";
import Storage, {generateHandler} from "./storage";
import {existsSync, writeFile} from "fs";
// Permission levels starting from zero then increasing, allowing for numerical comparisons.
// Note: For my bot, there really isn't much purpose to doing so, as it's just one command. And plus, if you're doing stuff like moderation commands, it's probably better to make a permissions system that allows for you to separate permissions into different trees. After all, it'd be a really bad idea to allow a bot mechanic to ban users.
@ -94,6 +97,31 @@ export default class Command
return true;
}*/
let commands: Collection<string, Command> | null = null;
/** Returns the cache of the commands if it exists and searches the directory if not. */
// Fun, Miscellaneous (default), Music, System, Utility
export async function loadCommands(): Promise<Collection<string, Command>>
{
if(commands)
return commands;
if(process.argv[2] === "dev" && !existsSync("src/commands/test.ts"))
writeFile("src/commands/test.ts", template, generateHandler('"test.ts" (testing/template command) successfully generated.'));
commands = new Collection();
for(const file of Storage.open("dist/commands", (filename: string) => filename.endsWith(".js")))
{
const header = file.substring(0, file.indexOf(".js"));
const command = (await import(`../commands/${header}`)).default;
commands.set(header, command);
$.log(`Loading Command: ${header}`);
}
return commands;
}
// The template should be built with a reductionist mentality.
// Provide everything the user needs and then let them remove whatever they want.
// That way, they aren't focusing on what's missing, but rather what they need for their command.

View file

@ -1,7 +1,9 @@
import {Client} from "discord.js";
import Storage from "./storage";
import $ from "./lib";
// Last Updated: Discord.js v12.2.0
export const EVENTS = ["channelCreate", "channelDelete", "channelPinsUpdate", "channelUpdate", "debug", "warn", "disconnect", "emojiCreate", "emojiDelete", "emojiUpdate", "error", "guildBanAdd", "guildBanRemove", "guildCreate", "guildDelete", "guildUnavailable", "guildIntegrationsUpdate", "guildMemberAdd", "guildMemberAvailable", "guildMemberRemove", "guildMembersChunk", "guildMemberSpeaking", "guildMemberUpdate", "guildUpdate", "inviteCreate", "inviteDelete", "message", "messageDelete", "messageReactionRemoveAll", "messageReactionRemoveEmoji", "messageDeleteBulk", "messageReactionAdd", "messageReactionRemove", "messageUpdate", "presenceUpdate", "rateLimit", "ready", "invalidated", "roleCreate", "roleDelete", "roleUpdate", "typingStart", "userUpdate", "voiceStateUpdate", "webhookUpdate", "shardDisconnect", "shardError", "shardReady", "shardReconnecting", "shardResume"];
const EVENTS = ["channelCreate", "channelDelete", "channelPinsUpdate", "channelUpdate", "debug", "warn", "disconnect", "emojiCreate", "emojiDelete", "emojiUpdate", "error", "guildBanAdd", "guildBanRemove", "guildCreate", "guildDelete", "guildUnavailable", "guildIntegrationsUpdate", "guildMemberAdd", "guildMemberAvailable", "guildMemberRemove", "guildMembersChunk", "guildMemberSpeaking", "guildMemberUpdate", "guildUpdate", "inviteCreate", "inviteDelete", "message", "messageDelete", "messageReactionRemoveAll", "messageReactionRemoveEmoji", "messageDeleteBulk", "messageReactionAdd", "messageReactionRemove", "messageUpdate", "presenceUpdate", "rateLimit", "ready", "invalidated", "roleCreate", "roleDelete", "roleUpdate", "typingStart", "userUpdate", "voiceStateUpdate", "webhookUpdate", "shardDisconnect", "shardError", "shardReady", "shardReconnecting", "shardResume"];
interface EventOptions
{
@ -28,4 +30,21 @@ export default class Event
if(this.once)
client.once(event as any, this.once as any);
}
}
export async function loadEvents(client: Client)
{
for(const file of Storage.open("dist/events", (filename: string) => filename.endsWith(".js")))
{
const header = file.substring(0, file.indexOf(".js"));
const event = (await import(`../events/${header}`)).default;
if(EVENTS.includes(header))
{
event.attach(client, header);
$.log(`Loading Event: ${header}`);
}
else
$.warn(`"${header}" is not a valid event type! Did you misspell it? (Note: If you fixed the issue, delete "dist" because the compiler won't automatically delete any extra files.)`);
}
}

View file

@ -1,10 +1,5 @@
import fs from "fs";
import $ from "./lib";
import {Collection, Client} from "discord.js";
import Command, {template} from "../core/command";
import {EVENTS} from "./event";
let commands: Collection<string, Command>|null = null;
const Storage = {
read(header: string): object
@ -73,47 +68,10 @@ const Storage = {
{
if(fs.existsSync(path) && fs.readdirSync(path).length === 0)
fs.rmdir(path, generateHandler(`"${path}" successfully closed.`));
},
/** Returns the cache of the commands if it exists and searches the directory if not. */
async loadCommands(): Promise<Collection<string, Command>>
{
if(commands)
return commands;
if(process.argv[2] === "dev" && !fs.existsSync("src/commands/test.ts"))
fs.writeFile("src/commands/test.ts", template, generateHandler('"test.ts" (testing/template command) successfully generated.'));
commands = new Collection();
for(const file of Storage.open("dist/commands", (filename: string) => filename.endsWith(".js")))
{
const header = file.substring(0, file.indexOf(".js"));
const command = (await import(`../commands/${header}`)).default;
commands.set(header, command);
$.log(`Loading Command: ${header}`);
}
return commands;
},
async loadEvents(client: Client)
{
for(const file of Storage.open("dist/events", (filename: string) => filename.endsWith(".js")))
{
const header = file.substring(0, file.indexOf(".js"));
const event = (await import(`../events/${header}`)).default;
if(EVENTS.includes(header))
{
event.attach(client, header);
$.log(`Loading Event: ${header}`);
}
else
$.warn(`"${header}" is not a valid event type! Did you misspell it? (Note: If you fixed the issue, delete "dist" because the compiler won't automatically delete any extra files.)`);
}
}
};
function generateHandler(message: string)
export function generateHandler(message: string)
{
return (error: Error|null) => {
if(error)

View file

@ -2,8 +2,8 @@ import Event from "../core/event";
import Command from "../core/command";
import $ from "../core/lib";
import {Message, Permissions, Collection} from "discord.js";
import FileManager from "../core/storage";
import {Config, Storage} from "../core/structures";
import {loadCommands} from "../core/command";
// It's a rather hacky solution, but since there's no top-level await, I just have to make the loading conditional.
let commands: Collection<string, Command>|null = null;
@ -13,7 +13,7 @@ export default new Event({
{
// Load commands if it hasn't already done so. Luckily, it's called once at most.
if(!commands)
commands = await FileManager.loadCommands();
commands = await loadCommands();
// Message Setup //
if(message.author.bot)

View file

@ -1,7 +1,8 @@
import {Client} from "discord.js";
import setup from "./setup";
import FileManager from "./core/storage";
import {Config} from "./core/structures";
import {loadCommands} from "./core/command";
import {loadEvents} from "./core/event";
// This is here in order to make it much less of a headache to access the client from other files.
// This of course won't actually do anything until the setup process is complete and it logs in.
@ -9,7 +10,7 @@ export const client = new Client();
// Begin the command loading here rather than when it's needed like in the message event.
setup.init().then(() => {
FileManager.loadCommands();
FileManager.loadEvents(client);
loadCommands();
loadEvents(client);
client.login(Config.token).catch(setup.again);
});