From f28e65ab8035682372edbe1c11d9ca2581e0a2e6 Mon Sep 17 00:00:00 2001 From: marzavec Date: Wed, 6 Nov 2019 23:35:23 -0800 Subject: Syntax update and formatting tweaks --- server/src/serverLib/CommandManager.js | 201 +++++++++++++++++---------------- 1 file changed, 105 insertions(+), 96 deletions(-) (limited to 'server/src/serverLib/CommandManager.js') diff --git a/server/src/serverLib/CommandManager.js b/server/src/serverLib/CommandManager.js index 0c4f0aa..e715c6b 100644 --- a/server/src/serverLib/CommandManager.js +++ b/server/src/serverLib/CommandManager.js @@ -1,47 +1,71 @@ -/** - * Commands / protocol manager- loads, validates and handles command execution - * - * Version: v2.0.0 - * Developer: Marzavec ( https://github.com/marzavec ) - * License: WTFPL ( http://www.wtfpl.net/txt/copying/ ) - * - */ - -const path = require('path'); -const didYouMean = require('didyoumean2').default; +import { + basename, + join, + sep, + dirname, + relative, +} from 'path'; +import didYouMean from 'didyoumean2'; // default command modules path const CmdDir = 'src/commands'; +/** + * Commands / protocol manager- loads, validates and handles command execution + * @property {Array} commands - Array of currently loaded command modules + * @property {Array} categories - Array of command modules categories + * @author Marzavec ( https://github.com/marzavec ) + * @version v2.0.0 + * @license WTFPL ( http://www.wtfpl.net/txt/copying/ ) + */ class CommandManager { /** * Create a `CommandManager` instance for handling commands/protocol * * @param {Object} core Reference to the global core object */ - constructor (core) { + constructor(core) { + /** + * Stored reference to the core + * @type {CoreApp} + */ this.core = core; + + /** + * Command module storage + * @type {Array} + */ this.commands = []; + + /** + * Command module category names (based off directory or module meta) + * @type {Array} + */ this.categories = []; - if (!this.core.config.hasOwnProperty('logErrDetailed')) { + + /** + * Full path to config.json file + * @type {String} + */ + if (typeof this.core.config.logErrDetailed === 'undefined') { this.core.config.logErrDetailed = false; } } /** * (Re)initializes name spaces for commands and starts load routine - * + * @public * @return {String} Module errors or empty if none */ - loadCommands () { + loadCommands() { this.commands = []; this.categories = []; const commandImports = this.core.dynamicImports.getImport(CmdDir); let cmdErrors = ''; - Object.keys(commandImports).forEach(file => { - let command = commandImports[file]; - let name = path.basename(file); + Object.keys(commandImports).forEach((file) => { + const command = commandImports[file]; + const name = basename(file); cmdErrors += this.validateAndLoad(command, file, name); }); @@ -50,29 +74,28 @@ class CommandManager { /** * Checks the module after having been `require()`ed in and reports errors - * * @param {Object} command reference to the newly loaded object * @param {String} file file path to the module * @param {String} name command (`cmd`) name - * + * @private * @return {String} Module errors or empty if none */ - validateAndLoad (command, file, name) { - let error = this.validateCommand(command); + validateAndLoad(command, file, name) { + const error = this.validateCommand(command); if (error) { - let errText = `Failed to load '${name}': ${error}`; + const errText = `Failed to load command module '${name}': ${error}`; console.log(errText); return errText; } if (!command.category) { - let base = path.join(this.core.dynamicImports.base, 'commands'); + const base = join(this.core.dynamicImports.base, 'commands'); let category = 'Uncategorized'; - if (file.indexOf(path.sep) > -1) { - category = path.dirname(path.relative(base, file)) - .replace(new RegExp(path.sep.replace('\\', '\\\\'), 'g'), '/'); + if (file.indexOf(sep) > -1) { + category = dirname(relative(base, file)) + .replace(new RegExp(sep.replace('\\', '\\\\'), 'g'), '/'); } command.info.category = category; @@ -86,7 +109,7 @@ class CommandManager { try { command.init(this.core); } catch (err) { - let errText = `Failed to initialize '${name}': ${err}`; + const errText = `Failed to initialize '${name}': ${err}`; console.log(errText); return errText; } @@ -99,121 +122,109 @@ class CommandManager { /** * Checks the module after having been `require()`ed in and reports errors - * * @param {Object} object reference to the newly loaded object - * + * @private * @return {String} Module errors or null if none */ - validateCommand (object) { - if (typeof object !== 'object') - return 'command setup is invalid'; - - if (typeof object.run !== 'function') - return 'run function is missing'; - - if (typeof object.info !== 'object') - return 'info object is missing'; - - if (typeof object.info.name !== 'string') - return 'info object is missing a valid name field'; + validateCommand(object) { + if (typeof object !== 'object') { return 'command setup is invalid'; } + if (typeof object.run !== 'function') { return 'run function is missing'; } + if (typeof object.info !== 'object') { return 'info object is missing'; } + if (typeof object.info.name !== 'string') { return 'info object is missing a valid name field'; } return null; } /** * Pulls all command names from a passed `category` - * * @param {String} category [Optional] filter return results by this category - * + * @public * @return {Array} Array of command modules matching the category */ - all (category) { + all(category) { return !category ? this.commands : this.commands.filter( - c => c.info.category.toLowerCase() === category.toLowerCase() - ); + (c) => c.info.category.toLowerCase() === category.toLowerCase(), + ); } /** - * Pulls all category names - * - * @return {Array} Array of sub directories under CmdDir + * All category names + * @public + * @readonly + * @return {Array} Array of command category names */ - get categoriesList () { + get categoriesList() { return this.categories; } /** - * Pulls command by name or alia(s) - * + * Pulls command by name or alias * @param {String} name name or alias of command - * + * @public * @return {Object} Target command module object */ - get (name) { + get(name) { return this.findBy('name', name) || this.commands.find( - command => command.info.aliases instanceof Array && - command.info.aliases.indexOf(name) > -1 + (command) => command.info.aliases instanceof Array + && command.info.aliases.indexOf(name) > -1, ); } /** * Pulls command by arbitrary search of the `module.info` attribute - * * @param {String} key name or alias of command * @param {String} value name or alias of command - * + * @public * @return {Object} Target command module object */ - findBy (key, value) { - return this.commands.find(c => c.info[key] === value); + findBy(key, value) { + return this.commands.find((c) => c.info[key] === value); } /** * Runs `initHooks` function on any modules that utilize the event - * + * @private * @param {Object} server main server object */ - initCommandHooks (server) { - this.commands.filter(c => typeof c.initHooks !== 'undefined').forEach( - c => c.initHooks(server) - ); + initCommandHooks(server) { + this.commands.filter((c) => typeof c.initHooks !== 'undefined').forEach( + (c) => c.initHooks(server), + ); } /** * Finds and executes the requested command, or fails with semi-intelligent error - * * @param {Object} server main server reference * @param {Object} socket calling socket reference * @param {Object} data command structure passed by socket (client) - * + * @public * @return {*} Arbitrary module return data */ - handleCommand (server, socket, data) { + handleCommand(server, socket, data) { // Try to find command first - let command = this.get(data.cmd); + const command = this.get(data.cmd); if (command) { return this.execute(command, server, socket, data); - } else { - // Then fail with helpful (sorta) message - return this.handleFail(server, socket, data); } + + // Then fail with helpful (sorta) message + return this.handleFail(server, socket, data); } /** * Requested command failure handler, attempts to find command and reports back - * * @param {Object} server main server reference * @param {Object} socket calling socket reference * @param {Object} data command structure passed by socket (client) - * + * @private * @return {*} Arbitrary module return data */ - handleFail (server, socket, data) { - const maybe = didYouMean(data.cmd, this.all().map(c => c.info.name), { + handleFail(server, socket, data) { + const maybe = didYouMean(data.cmd, this.all().map((c) => c.info.name), { threshold: 5, - thresholdType: 'edit-distance' + thresholdType: 'edit-distance', }); if (maybe) { @@ -221,7 +232,7 @@ class CommandManager { return this.handleCommand(server, socket, { cmd: 'socketreply', cmdKey: server.cmdKey, - text: `Command not found, did you mean: \`${maybe}\`?` + text: `Command not found, did you mean: \`${maybe}\`?`, }); } @@ -229,39 +240,37 @@ class CommandManager { return this.handleCommand(server, socket, { cmd: 'socketreply', cmdKey: server.cmdKey, - text: 'Unknown command' + text: 'Unknown command', }); } /** * Attempt to execute the requested command, fail if err or bad params - * * @param {Object} command target command module * @param {Object} server main server reference * @param {Object} socket calling socket reference * @param {Object} data command structure passed by socket (client) - * + * @private * @return {*} Arbitrary module return data */ - async execute (command, server, socket, data) { + async execute(command, server, socket, data) { if (typeof command.requiredData !== 'undefined') { - let missing = []; - for (let i = 0, len = command.requiredData.length; i < len; i++) { - if (typeof data[command.requiredData[i]] === 'undefined') - missing.push(command.requiredData[i]); + const missing = []; + for (let i = 0, len = command.requiredData.length; i < len; i += 1) { + if (typeof data[command.requiredData[i]] === 'undefined') { missing.push(command.requiredData[i]); } } if (missing.length > 0) { console.log(`Failed to execute '${ - command.info.name - }': missing required ${missing.join(', ')}\n\n`); + command.info.name + }': missing required ${missing.join(', ')}\n\n`); this.handleCommand(server, socket, { cmd: 'socketreply', cmdKey: server.cmdKey, text: `Failed to execute '${ - command.info.name - }': missing required ${missing.join(', ')}\n\n` + command.info.name + }': missing required ${missing.join(', ')}\n\n`, }); return null; @@ -271,20 +280,20 @@ class CommandManager { try { return await command.run(this.core, server, socket, data); } catch (err) { - let errText = `Failed to execute '${command.info.name}': `; - + const errText = `Failed to execute '${command.info.name}': `; + // If we have more detail enabled, then we get the trace // if it isn't, or the property doesn't exist, then we'll get only the message if (this.core.config.logErrDetailed === true) { console.log(errText + err.stack); } else { - console.log(errText + err.toString()) + console.log(errText + err.toString()); } this.handleCommand(server, socket, { cmd: 'socketreply', cmdKey: server.cmdKey, - text: errText + err.toString() + text: errText + err.toString(), }); return null; @@ -292,4 +301,4 @@ class CommandManager { } } -module.exports = CommandManager; +export default CommandManager; -- cgit v1.2.1