move loaders out of mainfile
This commit is contained in:
parent
99e859dd48
commit
7b9f5bfa33
3 changed files with 109 additions and 81 deletions
106
bot/index.js
106
bot/index.js
|
@ -1,6 +1,8 @@
|
||||||
// Copyright 2020 Emily J. / mudkipscience and contributors. Subject to the AGPLv3 license.
|
// Copyright 2020 Emily J. / mudkipscience and contributors. Subject to the AGPLv3 license.
|
||||||
|
|
||||||
const Eris = require('eris-additions')(require('eris'));
|
const Eris = require('eris-additions')(require('eris'));
|
||||||
|
const CommandLoader = require('./util/commandLoader');
|
||||||
|
const EventLoader = require('./util/eventLoader');
|
||||||
const EventHandler = require('./util/handlers/eventHandler');
|
const EventHandler = require('./util/handlers/eventHandler');
|
||||||
// const messageHandler = require('./util/handlers/messageHandler');
|
// const messageHandler = require('./util/handlers/messageHandler');
|
||||||
const Helpers = require('./util/helpers');
|
const Helpers = require('./util/helpers');
|
||||||
|
@ -8,7 +10,6 @@ const Database = require('./util/database');
|
||||||
const Logger = require('./util/logger');
|
const Logger = require('./util/logger');
|
||||||
const sentry = require('@sentry/node');
|
const sentry = require('@sentry/node');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const read = require('fs-readdir-recursive');
|
|
||||||
const yaml = require('js-yaml');
|
const yaml = require('js-yaml');
|
||||||
const config = yaml.safeLoad(fs.readFileSync('../botconfig.yml', 'utf8'));
|
const config = yaml.safeLoad(fs.readFileSync('../botconfig.yml', 'utf8'));
|
||||||
const version = require('../package.json').version;
|
const version = require('../package.json').version;
|
||||||
|
@ -22,85 +23,34 @@ class WoomyClient extends Eris.Client {
|
||||||
this.path = __dirname;
|
this.path = __dirname;
|
||||||
this.version = version;
|
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
|
// Essential modules
|
||||||
this.logger = Logger;
|
this.logger = Logger;
|
||||||
this.db = new Database(this);
|
this.db = new Database(this);
|
||||||
this.helpers = new Helpers(this);
|
this.helpers = new Helpers(this);
|
||||||
|
this.commandLoader = new CommandLoader(this);
|
||||||
|
this.eventLoader = new EventLoader(this);
|
||||||
this.eventHandler = new EventHandler(this);
|
this.eventHandler = new EventHandler(this);
|
||||||
// this.messageHandler = new messageHandler(this);
|
// this.messageHandler = new messageHandler(this);
|
||||||
|
|
||||||
// Collections to store our successfully loaded commands and events in.
|
// Collections to store our successfully loaded commands and events in.
|
||||||
this.commands = new Eris.Collection();
|
this.commands = new Eris.Collection();
|
||||||
this.aliases = new Eris.Collection();
|
this.aliases = new Eris.Collection();
|
||||||
this.cooldowns = new Eris.Collection();
|
|
||||||
this.eventModules = new Eris.Collection();
|
this.eventModules = new Eris.Collection();
|
||||||
}
|
}
|
||||||
|
|
||||||
loadCommands () {
|
// Listen for Eris events and pass needed information to the event handler so we can respond to them.
|
||||||
for (const file of this.commandFiles) {
|
createEventListeners () {
|
||||||
try {
|
this.on('ready', this.runReadyModules);
|
||||||
const name = file.substr(file.indexOf('/') + 1).slice(0, -3);
|
this.on('error', this.runErrorModules);
|
||||||
const category = file.substr(0, file.indexOf('/'));
|
this.on('messageCreate', this.runMessageCreateModules);
|
||||||
const command = new (require(this.path + '/commands/' + file))(name, category);
|
this.on('guildCreate', this.runGuildCreateModules);
|
||||||
|
this.on('guildDelete', this.runGuildDeleteModules);
|
||||||
this.commands.set(command.name, command);
|
this.on('guildMemberAdd', this.runGuildMemberAddModules);
|
||||||
this.cooldowns.set(command.name, new Map());
|
this.on('guildMemberRemove', this.runGuildMemberRemoveModules);
|
||||||
command.aliases.forEach(alias => {
|
this.on('voiceStateUpdate', this.runVoiceStateUpdateModules);
|
||||||
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.`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reloadCommands () {
|
// Recieves information from the per-event listeners, and passes on needed information to the handler
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
mainEventListener (wsEvent, param_1, param_2) {
|
mainEventListener (wsEvent, param_1, param_2) {
|
||||||
try {
|
try {
|
||||||
this.eventHandler.handle(wsEvent, param_1, param_2);
|
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 () {
|
runReadyModules () {
|
||||||
this.mainEventListener('ready');
|
this.mainEventListener('ready');
|
||||||
}
|
}
|
||||||
|
@ -118,6 +69,7 @@ class WoomyClient extends Eris.Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
runMessageCreateModules (message) {
|
runMessageCreateModules (message) {
|
||||||
|
this.messageHandler.handle(message);
|
||||||
this.mainEventListener('messageCreate', message);
|
this.mainEventListener('messageCreate', message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,22 +92,11 @@ class WoomyClient extends Eris.Client {
|
||||||
runVoiceStateUpdateModules (oldState, newState) {
|
runVoiceStateUpdateModules (oldState, newState) {
|
||||||
this.mainEventListener('voiceStateUpdate', 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, {
|
const client = new WoomyClient(config.token, {
|
||||||
maxShards: 'auto',
|
maxShards: 'auto',
|
||||||
defaultImageFormat: 'png',
|
|
||||||
defaultImageSize: 2048,
|
defaultImageSize: 2048,
|
||||||
intents: [
|
intents: [
|
||||||
'guilds',
|
'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');
|
require('./util/prototypes');
|
||||||
|
|
||||||
client.loadCommands();
|
// Load commands, event modules and create listeners for Eris events (ready, errors, messages, etc)
|
||||||
client.loadEventModules();
|
client.commandLoader.loadCommands();
|
||||||
|
client.eventLoader.loadEventModules();
|
||||||
client.createEventListeners();
|
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) {
|
if (client.config.devmode === true) {
|
||||||
try {
|
try {
|
||||||
// sentry.init({ dsn: client.config.keys.sentry });
|
// 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.');
|
client.logger.warning('DEVELOPMENT_MODE', 'Running in development mode, some features have been disabled.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Login to Discord
|
||||||
client.connect();
|
client.connect();
|
||||||
|
|
||||||
// Process exception/promise rejection listeners
|
// Process exception/promise rejection listeners
|
||||||
|
|
||||||
process.on('uncaughtException', (error) => {
|
process.on('uncaughtException', (error) => {
|
||||||
const errorMsg = error.stack.replace(new RegExp(`${client.path}/`, 'g'), './');
|
const errorMsg = error.stack.replace(new RegExp(`${client.path}/`, 'g'), './');
|
||||||
client.logger.error('UNCAUGHT_EXCEPTION_ERROR', errorMsg);
|
client.logger.error('UNCAUGHT_EXCEPTION_ERROR', errorMsg);
|
||||||
|
|
44
bot/util/commandLoader.js
Normal file
44
bot/util/commandLoader.js
Normal file
|
@ -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;
|
40
bot/util/eventLoader.js
Normal file
40
bot/util/eventLoader.js
Normal file
|
@ -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;
|
Loading…
Reference in a new issue