Improvements and fixes, start on command manager

This commit is contained in:
Isaac 2021-02-17 22:01:44 +00:00
parent 8b661f0462
commit 7c0b1311dc
No known key found for this signature in database
GPG Key ID: 279D1F53391CED07
9 changed files with 190 additions and 100 deletions

View File

@ -1 +1 @@
This documentation is intended to be access through the website (https://eartharoid.github.io/discordtickets) This documentation is intended to be access through the website (https://discordtickets.eartharoid.me)

View File

@ -28,29 +28,30 @@ if (node_version < 14)
const fs = require('fs'); const fs = require('fs');
const { path } = require('./utils/fs'); const { path } = require('./utils/fs');
const ENV_PATH = path('./.env'); const checkFile = (file, example) => {
const EXAMPLE_ENV_PATH = path('./example.env');
if (!fs.existsSync(ENV_PATH )) { file = path(file);
if (!fs.existsSync(EXAMPLE_ENV_PATH)) { example = path(example);
console.log('Error: \'.env\' not found, and unable to create it due to \'example.env\' being missing');
if (fs.existsSync(file)) return true;
if (!fs.existsSync(example)) {
console.log(`Error: '${file}' not found, and unable to create it due to '${example}' being missing`);
return process.exit(); return process.exit();
} }
console.log('Copying \'example.env\' to \'.env\'');
fs.copyFileSync(EXAMPLE_ENV_PATH, ENV_PATH); console.log(`Copying '${example}' to '${file}'`);
console.log('Please set your bot\'s token in your \'.env\' file'); fs.copyFileSync(example, file);
return false;
};
if (!checkFile('./.env', './example.env')) {
console.log('Please set your bot\'s token in \'.env\'');
process.exit(); process.exit();
} }
const CONFIG_PATH = path('./user/config.js'); checkFile('./user/config.js', './user/example.config.js');
const EXAMPLE_CONFIG_PATH = path('./user/example.config.js');
if (!fs.existsSync(CONFIG_PATH)) {
if (!fs.existsSync(EXAMPLE_CONFIG_PATH)) {
console.log('Error: \'user/config.js\' not found, and unable to create it due to \'user/example.config.js\' being missing');
return process.exit();
}
console.log('Copying \'user/example.config.js\' to \'user/config.js\'');
fs.copyFileSync(EXAMPLE_CONFIG_PATH, CONFIG_PATH);
}
require('dotenv').config({ require('dotenv').config({
@ -105,33 +106,36 @@ class Bot extends Client {
} }
}); });
/** The global bot configuration */ (async () => {
this.config= config; /** The global bot configuration */
/** A sequelize instance */ this.config = config;
this.db = require('./database')(log), // this.db.models.Ticket...
/** A leekslazylogger instance */
this.log = log;
/** An @eartharoid/i18n instance */
this.i18n = new I18n(path('./src/locales'), 'en-GB');
// set the max listeners for each event to the number in the config /** A sequelize instance */
this.setMaxListeners(this.config.max_listeners); this.db = await require('./database')(log), // this.db.models.Ticket...
// check for updates /** A leekslazylogger instance */
require('./updater')(this); this.log = log;
// load internal listeners
require('./modules/listeners')(this);
/** The command manager, used by internal and plugin commands */ /** An @eartharoid/i18n instance */
this.commands = new CommandManager(this); this.i18n = new I18n(path('./src/locales'), 'en-GB');
/** The plugin manager */
this.plugins = new PluginManager(this);
// load plugins
this.plugins.load();
this.log.info('Connecting to Discord API...'); this.setMaxListeners(this.config.max_listeners); // set the max listeners for each event
this.login(); require('./updater')(this); // check for updates
require('./modules/listeners')(this); // load internal listeners
/** The command manager, used by internal and plugin commands */
this.commands = new CommandManager(this);
this.commands.load(); // load internal commands
/** The plugin manager */
this.plugins = new PluginManager(this);
this.plugins.load(); // load plugins
this.log.info('Connecting to Discord API...');
this.login();
})();
} }
} }

View File

@ -1,41 +0,0 @@
const fs = require('fs');
const { join } = require('path');
const { path } = require('../utils/fs');
class CommandManager {
constructor(client) {
this.client = client;
this.commands = new Map();
}
load(command) {
}
unload(command) {
}
reload(command) {
}
get(command) {
}
get list() {
return this.commands;
}
}
class Command {
constructor(client) {
}
}
module.exports = {
CommandManager,
Command
};

View File

@ -0,0 +1,92 @@
/* eslint-disable no-unused-vars */
const { Client } = require('discord.js');
const fs = require('fs');
const { join } = require('path');
const { path } = require('../../utils/fs');
/** A plugin */
module.exports = class Plugin {
/**
* Create a new Plugin
* @param {Client} client The Discord Client
* @param {String} id The plugin ID
* @param {Object} options Plugin options
* @param {String} options.name A human-friendly name (can be different to the name in package.json)
*/
constructor(client, id, options = {}) {
/** The human-friendly name of the plugin */
this.name = options.name || id;
/** The Discord Client */
this.client = client;
/** The PluginManager */
this.manager = this.client.plugins;
// Object.assign(this, this.manager.plugins.get(id));
// make JSDoc happy
let {
version,
author,
description
} = this.manager.plugins.get(id);
/** The unique ID of the plugin (NPM package name) */
this.id = id;
/** The version of the plugin (NPM package version) */
this.version = version;
/** The plugin author's name (NPM package author) */
this.author = author;
/** The plugin description (NPM package description) */
this.description = description;
this.directory = {};
/** A cleaned version of the plugin's ID suitable for use in the directory name */
this.directory.name = this.id.replace(/@[-_a-zA-Z0-9]+\//, '');
/** The absolute path of the plugin directory */
this.directory.path = path(`./user/plugins/${this.directory.name}`);
}
/**
* Create the plugin directory if it doesn't already exist
* @returns {Boolean} True if created, false if it already existed
*/
createDirectory() {
if (!fs.existsSync(this.directory.path)) {
this.client.log.plugins(`Creating plugin directory for "${this.name}"`);
fs.mkdirSync(this.directory.path);
return true;
} else {
return false;
}
}
/**
* Create the plugin config file if it doesn't already exist
* @param {Object} template The default config template
* @returns {Boolean} True if created, false if it already existed
*/
createConfig(template) {
this.createDirectory();
let file = join(this.directory.path, 'config.json');
if (!fs.existsSync(file)) {
this.client.log.plugins(`Creating plugin config file for "${this.name}"`);
fs.writeFileSync(file, JSON.stringify(template, null, 2));
return true;
} else {
return false;
}
}
/**
* The main function where your code should go. Create functions and event listeners here
*/
load() {}
};

View File

@ -0,0 +1,4 @@
module.exports = {
CommandManager: require('./manager'),
Command: require('./command')
};

View File

@ -0,0 +1,33 @@
// eslint-disable-next-line no-unused-vars
const { Collection, Client } = require('discord.js');
// eslint-disable-next-line no-unused-vars
const Command = require('./command');
const fs = require('fs');
const { path } = require('../../utils/fs');
/** Manages the loading of commands */
module.exports = class CommandManager {
/**
* Create a CommandManager instance
* @param {Client} client
*/
constructor(client) {
/** The Discord Client */
this.client = client;
/** A discord.js Collection (Map) of loaded commands */
this.commands = new Collection();
}
/** Automatically load all internal commands */
load() {
const files = fs.readdirSync(path('./src/commands'))
.filter(file => file.endsWith('.js'));
for (const file of files) {
const cmd = require(`../commands/${file}`);
this.commands.set(cmd, new cmd(this.client));
}
}
};

View File

@ -80,15 +80,13 @@ module.exports = class PluginManager {
} }
} }
/** /** Automatically register and load plugins */
* Automatically register and load plugins
*/
load() { load() {
// normal plugins (NPM) // normal plugins (NPM)
this.client.config.plugins.forEach(plugin => { this.client.config.plugins.forEach(plugin => {
try { try {
let pkg = require(`${plugin}/package.json`);
let main = require(plugin); let main = require(plugin);
let pkg = require(`${plugin}/package.json`);
this.registerPlugin(true, main, pkg); this.registerPlugin(true, main, pkg);
} catch (e) { } catch (e) {
this.client.log.warn(`An error occurred whilst loading ${plugin}; have you installed it?`); this.client.log.warn(`An error occurred whilst loading ${plugin}; have you installed it?`);

View File

@ -14,14 +14,13 @@ module.exports = class Plugin {
* @param {Object} options Plugin options * @param {Object} options Plugin options
* @param {String} options.name A human-friendly name (can be different to the name in package.json) * @param {String} options.name A human-friendly name (can be different to the name in package.json)
*/ */
constructor(client, id, options) { constructor(client, id, options = {}) {
if (typeof options === 'object') { /** The human-friendly name of the plugin */
/** The human-friendly name of the plugin */ this.name = options.name || id;
this.name = options.name || id;
}
/** The Discord Client */ /** The Discord Client */
this.client = client; this.client = client;
/** The PluginManager */ /** The PluginManager */
this.manager = this.client.plugins; this.manager = this.client.plugins;
@ -36,16 +35,21 @@ module.exports = class Plugin {
/** The unique ID of the plugin (NPM package name) */ /** The unique ID of the plugin (NPM package name) */
this.id = id; this.id = id;
/** The version of the plugin (NPM package version) */ /** The version of the plugin (NPM package version) */
this.version = version; this.version = version;
/** The plugin author's name (NPM package author) */ /** The plugin author's name (NPM package author) */
this.author = author; this.author = author;
/** The plugin description (NPM package description) */ /** The plugin description (NPM package description) */
this.description = description; this.description = description;
this.directory = {}; this.directory = {};
/** A cleaned version of the plugin's ID suitable for use in the directory name */ /** A cleaned version of the plugin's ID suitable for use in the directory name */
this.directory.name = this.id.replace(/@[-_a-zA-Z0-9]+\//, ''); this.directory.name = this.id.replace(/@[-_a-zA-Z0-9]+\//, '');
/** The absolute path of the plugin directory */ /** The absolute path of the plugin directory */
this.directory.path = path(`./user/plugins/${this.directory.name}`); this.directory.path = path(`./user/plugins/${this.directory.name}`);
} }

View File

@ -10,14 +10,14 @@
* Quick Start * Quick Start
* --------------------- * ---------------------
* *
* > For detailed instructions, visit the documentation: https://eartharoid.github.io/discordtickets * > For detailed instructions, visit the documentation: https://discordtickets.eartharoid.me
* *
* --------------------- * ---------------------
* Support * Support
* --------------------- * ---------------------
* *
* > Discord support server: https://go.eartharoid.me/discord * > Discord support server: https://go.eartharoid.me/discord
* > Wiki: https://eartharoid.github.io/discordtickets * > Documentation: https://discordtickets.eartharoid.me
* *
* ############################################################################################### * ###############################################################################################
*/ */
@ -35,12 +35,8 @@ module.exports = {
max_listeners: 10, max_listeners: 10,
plugins: [ plugins: [
// 'dsctickets.plugin-name' // 'dsctickets.plugin-name'
'discordtickets-portal' // 'discordtickets-portal'
], ],
portal: {
enabled: false,
host: 'https://tickets.example.com'
},
presences: [ presences: [
{ {
activity: '/new | /help', activity: '/new | /help',