From 7b9f5bfa3371ec868b7a33d3e37016301524a6be Mon Sep 17 00:00:00 2001 From: Emily J Date: Wed, 21 Oct 2020 14:43:05 +1100 Subject: [PATCH] move loaders out of mainfile --- bot/index.js | 106 +++++++++----------------------------- bot/util/commandLoader.js | 44 ++++++++++++++++ bot/util/eventLoader.js | 40 ++++++++++++++ 3 files changed, 109 insertions(+), 81 deletions(-) create mode 100644 bot/util/commandLoader.js create mode 100644 bot/util/eventLoader.js diff --git a/bot/index.js b/bot/index.js index ccd6f8b..954deab 100644 --- a/bot/index.js +++ b/bot/index.js @@ -1,6 +1,8 @@ // Copyright 2020 Emily J. / mudkipscience and contributors. Subject to the AGPLv3 license. const Eris = require('eris-additions')(require('eris')); +const CommandLoader = require('./util/commandLoader'); +const EventLoader = require('./util/eventLoader'); const EventHandler = require('./util/handlers/eventHandler'); // const messageHandler = require('./util/handlers/messageHandler'); const Helpers = require('./util/helpers'); @@ -8,7 +10,6 @@ const Database = require('./util/database'); const Logger = require('./util/logger'); const sentry = require('@sentry/node'); const fs = require('fs'); -const read = require('fs-readdir-recursive'); const yaml = require('js-yaml'); const config = yaml.safeLoad(fs.readFileSync('../botconfig.yml', 'utf8')); const version = require('../package.json').version; @@ -22,85 +23,34 @@ class WoomyClient extends Eris.Client { this.path = __dirname; this.version = version; - // Load up our command/event modules - this.commandFiles = read('./commands').filter(file => file.endsWith('.js')); - this.eventFiles = read('./event_modules').filter(file => file.endsWith('.js')); - // Essential modules this.logger = Logger; this.db = new Database(this); this.helpers = new Helpers(this); + this.commandLoader = new CommandLoader(this); + this.eventLoader = new EventLoader(this); this.eventHandler = new EventHandler(this); // this.messageHandler = new messageHandler(this); // Collections to store our successfully loaded commands and events in. this.commands = new Eris.Collection(); this.aliases = new Eris.Collection(); - this.cooldowns = new Eris.Collection(); this.eventModules = new Eris.Collection(); } - loadCommands () { - for (const file of this.commandFiles) { - try { - const name = file.substr(file.indexOf('/') + 1).slice(0, -3); - const category = file.substr(0, file.indexOf('/')); - const command = new (require(this.path + '/commands/' + file))(name, category); - - this.commands.set(command.name, command); - this.cooldowns.set(command.name, new Map()); - command.aliases.forEach(alias => { - this.aliases.set(alias, command.name); - }); - } catch (error) { - this.logger.error('COMMAND_LOADER_ERROR', `Failed to load ${file}: ${error}`); - } - } - - this.logger.success('COMMAND_LOADER_SUCCESS', `Loaded ${this.commands.size}/${this.commandFiles.length} commands.`); + // Listen for Eris events and pass needed information to the event handler so we can respond to them. + createEventListeners () { + this.on('ready', this.runReadyModules); + this.on('error', this.runErrorModules); + this.on('messageCreate', this.runMessageCreateModules); + this.on('guildCreate', this.runGuildCreateModules); + this.on('guildDelete', this.runGuildDeleteModules); + this.on('guildMemberAdd', this.runGuildMemberAddModules); + this.on('guildMemberRemove', this.runGuildMemberRemoveModules); + this.on('voiceStateUpdate', this.runVoiceStateUpdateModules); } - - reloadCommands () { - this.commands.forEach(cmd => { - try { - delete require.cache[require.resolve(`${this.path}/commands/${cmd.category}/${cmd.name}.js`)]; - this.commands.delete(cmd.name); - } catch (error) { - this.logger.error('COMMAND_LOADER_ERROR', `Failed to unload ${cmd}: ${error}`); - } - }); - - this.loadCommands(); - } - - loadEventModules () { - for (const file of this.eventFiles) { - try { - const name = file.substr(file.indexOf('/') + 1).slice(0, -3); - const category = file.substr(0, file.indexOf('/')); - const event = new (require(this.path + '/event_modules/' + file))(category); - this.eventModules.set(name, event); - } catch (error) { - this.logger.error('EVENT_LOADER_ERROR', `Failed to load ${file}: ${error}`); - } - } - - this.logger.success('EVENT_LOADER_SUCCESS', `Loaded ${this.eventModules.size}/${this.eventFiles.length} event modules.`); - } - - reloadEventModules () { - this.eventModules.forEach((props, event) => { - try { - delete require.cache[require.resolve(`${this.path}/event_modules/${props.wsEvent}/${event}.js`)]; - this.eventModules.delete(event); - } catch (error) { - this.logger.error('EVENT_LOADER_ERROR', `Failed to unload ${event}: ${error}`); - } - }); - - this.loadEventModules(); - } - + + // Recieves information from the per-event listeners, and passes on needed information to the handler mainEventListener (wsEvent, param_1, param_2) { try { this.eventHandler.handle(wsEvent, param_1, param_2); @@ -109,6 +59,7 @@ class WoomyClient extends Eris.Client { } } + // All the repeated code below just tells the main event listener what information needs to be passed to the event handler runReadyModules () { this.mainEventListener('ready'); } @@ -118,6 +69,7 @@ class WoomyClient extends Eris.Client { } runMessageCreateModules (message) { + this.messageHandler.handle(message); this.mainEventListener('messageCreate', message); } @@ -140,22 +92,11 @@ class WoomyClient extends Eris.Client { runVoiceStateUpdateModules (oldState, newState) { this.mainEventListener('voiceStateUpdate', oldState, newState); } - - createEventListeners () { - this.on('ready', this.runReadyModules); - this.on('error', this.runErrorModules); - this.on('messageCreate', this.runMessageCreateModules); - this.on('guildCreate', this.runGuildCreateModules); - this.on('guildDelete', this.runGuildDeleteModules); - this.on('guildMemberAdd', this.runGuildMemberAddModules); - this.on('guildMemberRemove', this.runGuildMemberRemoveModules); - this.on('voiceStateUpdate', this.runVoiceStateUpdateModules); - } } +// Initialize our client const client = new WoomyClient(config.token, { maxShards: 'auto', - defaultImageFormat: 'png', defaultImageSize: 2048, intents: [ 'guilds', @@ -169,12 +110,15 @@ const client = new WoomyClient(config.token, { ] }); +// Extensions of native javascript types, *not good practice* but they're useful require('./util/prototypes'); -client.loadCommands(); -client.loadEventModules(); +// Load commands, event modules and create listeners for Eris events (ready, errors, messages, etc) +client.commandLoader.loadCommands(); +client.eventLoader.loadEventModules(); client.createEventListeners(); +// Development mode is set in botconfig.yml, and disables some stuff if enabled. Imagine how messy Sentry would be without this! if (client.config.devmode === true) { try { // sentry.init({ dsn: client.config.keys.sentry }); @@ -185,10 +129,10 @@ if (client.config.devmode === true) { client.logger.warning('DEVELOPMENT_MODE', 'Running in development mode, some features have been disabled.'); } +// Login to Discord client.connect(); // Process exception/promise rejection listeners - process.on('uncaughtException', (error) => { const errorMsg = error.stack.replace(new RegExp(`${client.path}/`, 'g'), './'); client.logger.error('UNCAUGHT_EXCEPTION_ERROR', errorMsg); diff --git a/bot/util/commandLoader.js b/bot/util/commandLoader.js new file mode 100644 index 0000000..b75021a --- /dev/null +++ b/bot/util/commandLoader.js @@ -0,0 +1,44 @@ +const read = require('fs-readdir-recursive'); + +class CommandLoader { + constructor (client) { + this.client = client; + this.commandFiles = read('./commands').filter(file => file.endsWith('.js')); + } + + // Loads up all commands + loadCommands () { + for (const file of this.commandFiles) { + try { + const name = file.substr(file.indexOf('/') + 1).slice(0, -3); + const category = file.substr(0, file.indexOf('/')); + const command = new (require(this.client.path + '/commands/' + file))(name, category); + + this.client.commands.set(command.name, command); + command.aliases.forEach(alias => { + this.client.aliases.set(alias, command.name); + }); + } catch (error) { + this.client.logger.error('COMMAND_LOADER_ERROR', `Failed to load ${file}: ${error}`); + } + } + + this.client.logger.success('COMMAND_LOADER_SUCCESS', `Loaded ${this.client.commands.size}/${this.commandFiles.length} commands.`); + } + + // Reloads all currently loaded commands, so we don't need to restart to apply changes + reloadCommands () { + this.client.commands.forEach(cmd => { + try { + delete require.cache[require.resolve(`${this.client.path}/commands/${cmd.category}/${cmd.name}.js`)]; + this.client.commands.delete(cmd.name); + } catch (error) { + this.client.logger.error('COMMAND_LOADER_ERROR', `Failed to unload ${cmd}: ${error}`); + } + }); + + this.loadCommands(); + } +} + +module.exports = CommandLoader; \ No newline at end of file diff --git a/bot/util/eventLoader.js b/bot/util/eventLoader.js new file mode 100644 index 0000000..b3a8f61 --- /dev/null +++ b/bot/util/eventLoader.js @@ -0,0 +1,40 @@ +const read = require('fs-readdir-recursive'); + +class EventLoader { + constructor (client) { + this.client = client; + this.eventFiles = read('./event_modules').filter(file => file.endsWith('.js')); + } + + // Load all our event modules + loadEventModules () { + for (const file of this.eventFiles) { + try { + const name = file.substr(file.indexOf('/') + 1).slice(0, -3); + const category = file.substr(0, file.indexOf('/')); + const event = new (require(this.client.path + '/event_modules/' + file))(category); + this.client.eventModules.set(name, event); + } catch (error) { + this.client.logger.error('EVENT_LOADER_ERROR', `Failed to load ${file}: ${error}`); + } + } + + this.client.logger.success('EVENT_LOADER_SUCCESS', `Loaded ${this.client.eventModules.size}/${this.eventFiles.length} event modules.`); + } + + // Reloads all currently loaded events, so we don't need to restart to apply changes + reloadEventModules () { + this.client.eventModules.forEach((props, event) => { + try { + delete require.cache[require.resolve(`${this.client.path}/event_modules/${props.wsEvent}/${event}.js`)]; + this.client.eventModules.delete(event); + } catch (error) { + this.client.logger.error('EVENT_LOADER_ERROR', `Failed to unload ${event}: ${error}`); + } + }); + + this.loadEventModules(); + } +} + +module.exports = EventLoader; \ No newline at end of file