2020-10-20 05:47:05 +00:00
|
|
|
// Copyright 2020 Emily J. / mudkipscience and contributors. Subject to the AGPLv3 license.
|
|
|
|
|
|
|
|
const Eris = require('eris-additions')(require('eris'));
|
2020-10-21 03:43:05 +00:00
|
|
|
const CommandLoader = require('./util/commandLoader');
|
|
|
|
const EventLoader = require('./util/eventLoader');
|
2020-10-20 05:47:05 +00:00
|
|
|
const EventHandler = require('./util/handlers/eventHandler');
|
2020-10-21 07:06:36 +00:00
|
|
|
const MessageHandler = require('./util/handlers/messageHandler');
|
2020-10-20 05:47:05 +00:00
|
|
|
const Helpers = require('./util/helpers');
|
|
|
|
const Database = require('./util/database');
|
|
|
|
const Logger = require('./util/logger');
|
|
|
|
const sentry = require('@sentry/node');
|
2020-10-20 08:30:46 +00:00
|
|
|
const yaml = require('js-yaml');
|
2020-10-21 07:06:36 +00:00
|
|
|
const config = yaml.safeLoad(require('fs').readFileSync('../botconfig.yml', 'utf8'));
|
2020-10-20 08:30:46 +00:00
|
|
|
const version = require('../package.json').version;
|
2020-10-20 05:47:05 +00:00
|
|
|
|
|
|
|
class WoomyClient extends Eris.Client {
|
|
|
|
constructor (token, options) {
|
|
|
|
super(token, options);
|
|
|
|
|
2020-10-20 13:44:52 +00:00
|
|
|
// Important information Woomy needs to access
|
2020-10-20 05:47:05 +00:00
|
|
|
this.config = config;
|
|
|
|
this.path = __dirname;
|
2020-10-20 08:30:46 +00:00
|
|
|
this.version = version;
|
2020-10-20 13:44:52 +00:00
|
|
|
|
|
|
|
// Essential modules
|
2020-10-20 05:47:05 +00:00
|
|
|
this.logger = Logger;
|
|
|
|
this.db = new Database(this);
|
2020-10-20 08:30:46 +00:00
|
|
|
this.helpers = new Helpers(this);
|
2020-10-21 03:43:05 +00:00
|
|
|
this.commandLoader = new CommandLoader(this);
|
|
|
|
this.eventLoader = new EventLoader(this);
|
2020-10-20 08:30:46 +00:00
|
|
|
this.eventHandler = new EventHandler(this);
|
2020-10-21 07:06:36 +00:00
|
|
|
this.messageHandler = new MessageHandler(this);
|
2020-10-20 05:47:05 +00:00
|
|
|
|
2020-10-21 07:06:36 +00:00
|
|
|
// Collections to store our successfully loaded events and commands in, as well as cooldowns.
|
2020-10-20 05:47:05 +00:00
|
|
|
this.commands = new Eris.Collection();
|
|
|
|
this.aliases = new Eris.Collection();
|
|
|
|
this.eventModules = new Eris.Collection();
|
2020-10-21 07:06:36 +00:00
|
|
|
this.cooldowns = new Eris.Collection();
|
2020-10-20 05:47:05 +00:00
|
|
|
}
|
|
|
|
|
2020-10-21 03:43:05 +00:00
|
|
|
// 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);
|
2020-10-20 14:03:16 +00:00
|
|
|
}
|
2020-10-21 03:43:05 +00:00
|
|
|
|
|
|
|
// Recieves information from the per-event listeners, and passes on needed information to the handler
|
2020-10-20 08:30:46 +00:00
|
|
|
mainEventListener (wsEvent, param_1, param_2) {
|
|
|
|
try {
|
|
|
|
this.eventHandler.handle(wsEvent, param_1, param_2);
|
|
|
|
} catch (error) {
|
|
|
|
this.logger.error('MODULE_LISTENER_ERROR', error);
|
|
|
|
}
|
2020-10-20 05:47:05 +00:00
|
|
|
}
|
|
|
|
|
2020-10-21 03:43:05 +00:00
|
|
|
// All the repeated code below just tells the main event listener what information needs to be passed to the event handler
|
2020-10-20 08:30:46 +00:00
|
|
|
runReadyModules () {
|
2020-10-20 05:47:05 +00:00
|
|
|
this.mainEventListener('ready');
|
|
|
|
}
|
|
|
|
|
2020-10-20 08:30:46 +00:00
|
|
|
runErrorModules (error) {
|
|
|
|
this.mainEventListener('error', error);
|
|
|
|
}
|
|
|
|
|
|
|
|
runMessageCreateModules (message) {
|
2020-10-21 03:43:05 +00:00
|
|
|
this.messageHandler.handle(message);
|
2020-10-20 08:30:46 +00:00
|
|
|
this.mainEventListener('messageCreate', message);
|
2020-10-20 05:47:05 +00:00
|
|
|
}
|
|
|
|
|
2020-10-20 08:30:46 +00:00
|
|
|
runGuildCreateModules (guild) {
|
|
|
|
this.mainEventListener('guildCreate', guild);
|
2020-10-20 05:47:05 +00:00
|
|
|
}
|
|
|
|
|
2020-10-20 08:30:46 +00:00
|
|
|
runGuildDeleteModules (guild) {
|
|
|
|
this.mainEventListener('guildDelete', guild);
|
2020-10-20 05:47:05 +00:00
|
|
|
}
|
|
|
|
|
2020-10-20 08:30:46 +00:00
|
|
|
runGuildMemberAddModules (guild, member) {
|
|
|
|
this.mainEventListener('guildMemberAdd', guild, member);
|
|
|
|
}
|
2020-10-20 05:47:05 +00:00
|
|
|
|
2020-10-20 08:30:46 +00:00
|
|
|
runGuildMemberRemoveModules (guild, member) {
|
|
|
|
this.mainEventListener('guildMemberRemove', guild, member);
|
|
|
|
}
|
|
|
|
|
|
|
|
runVoiceStateUpdateModules (oldState, newState) {
|
|
|
|
this.mainEventListener('voiceStateUpdate', oldState, newState);
|
2020-10-20 05:47:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-21 03:43:05 +00:00
|
|
|
// Initialize our client
|
2020-10-20 13:44:52 +00:00
|
|
|
const client = new WoomyClient(config.token, {
|
|
|
|
maxShards: 'auto',
|
|
|
|
defaultImageSize: 2048,
|
|
|
|
intents: [
|
|
|
|
'guilds',
|
|
|
|
'guildMembers',
|
|
|
|
'guildEmojis',
|
|
|
|
'guildVoiceStates',
|
|
|
|
'guildMessages',
|
|
|
|
'guildMessageReactions',
|
|
|
|
'directMessages',
|
|
|
|
'directMessageReactions'
|
|
|
|
]
|
|
|
|
});
|
|
|
|
|
2020-10-21 03:43:05 +00:00
|
|
|
// Extensions of native javascript types, *not good practice* but they're useful
|
2020-10-20 13:44:52 +00:00
|
|
|
require('./util/prototypes');
|
|
|
|
|
2020-10-21 03:43:05 +00:00
|
|
|
// Load commands, event modules and create listeners for Eris events (ready, errors, messages, etc)
|
|
|
|
client.commandLoader.loadCommands();
|
|
|
|
client.eventLoader.loadEventModules();
|
2020-10-20 13:44:52 +00:00
|
|
|
client.createEventListeners();
|
|
|
|
|
2020-10-21 03:43:05 +00:00
|
|
|
// Development mode is set in botconfig.yml, and disables some stuff if enabled. Imagine how messy Sentry would be without this!
|
2020-10-20 13:44:52 +00:00
|
|
|
if (client.config.devmode === true) {
|
|
|
|
try {
|
2020-10-21 07:06:36 +00:00
|
|
|
sentry.init({ dsn: client.config.keys.sentry });
|
2020-10-20 13:44:52 +00:00
|
|
|
} catch (err) {
|
|
|
|
client.logger.error('SENTRY_INIT_ERROR', `Sentry failed to initialize: ${err}`);
|
2020-10-20 05:47:05 +00:00
|
|
|
}
|
2020-10-20 13:44:52 +00:00
|
|
|
} else {
|
|
|
|
client.logger.warning('DEVELOPMENT_MODE', 'Running in development mode, some features have been disabled.');
|
2020-10-20 05:47:05 +00:00
|
|
|
}
|
|
|
|
|
2020-10-21 03:43:05 +00:00
|
|
|
// Login to Discord
|
2020-10-20 13:44:52 +00:00
|
|
|
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);
|
|
|
|
});
|
2020-10-20 05:47:05 +00:00
|
|
|
|
2020-10-20 13:44:52 +00:00
|
|
|
process.on('unhandledRejection', err => {
|
2020-10-21 07:06:36 +00:00
|
|
|
client.logger.error('UNHANDLED_PROMISE_ERROR', err.stack);
|
2020-10-20 13:44:52 +00:00
|
|
|
});
|