/* Module definition */ /* Variable Definition */ let logger = require('winston'), globCommands = {}; /* Function Definition */ /** * @type {Servant} */ exports.Servant = class { constructor(prefix) { this.commands = {}; this.createCommand(((prefix || '~')+'help') || "~help", () => { let helpstr = "```markdown\n"; helpstr += "Commands\n---\n"; // TODO: Duplicate commands should not appear or make two sections, one with global commands, one with server commands Object.entries(globCommands).concat(Object.entries(this.commands)).forEach(([key, value]) => { let cmdhelp = `${key} [${value.args.join('] [')}]`.replace('[]', '').padEnd(25, ' '); cmdhelp += value.description || ''; helpstr += `\n${cmdhelp}\n`; }); helpstr += "```"; return helpstr; }, [], "Shows this help."); } /** * Creates a command entry in the private commands dict * @param command * @param call * @param args * @param description */ createCommand(command, call, args, description) { this.commands[command] = { 'args': args, 'description': description, 'callback': call }; } /** * Removes a command * @param command */ removeCommand(command) { delete this.commands[command]; } /** * Parses the message and executes the command callback for the found command entry in the commands dict * @param msg * @returns {*} */ parseCommand(msg) { let globResult = parseGlobalCommand(msg); logger.debug(`Global command result is ${globResult}`); let content = msg.content; let command = (content.match(/^.\w+/) || [])[0]; if (!command || !this.commands[command]) return globResult; let cmd = this.commands[command]; let argvars = content.match(/(?<= )\S+/g) || []; let kwargs = {}; let nLength = Math.min(cmd.args.length, argvars.length); for (let i = 0; i < nLength; i++) { kwargs[cmd.args[i]] = argvars[i]; } let argv = argvars.slice(nLength); logger.debug(`Executing callback for command: ${command}, kwargs: ${kwargs}, argv: ${argv}`); return cmd.callback(msg, kwargs, argv) || globResult; } }; /** * Getting the logger * @param {Object} newLogger */ exports.setLogger = function(newLogger) { logger = newLogger; }; /** * Creates a global command that can be executed in every channel. * @param command * @param call * @param args * @param description */ exports.createGlobalCommand = function(command, call, args, description) { globCommands[command] = { 'args': args || [], 'description': description, 'callback': call }; logger.debug(`Created command: ${command}, args: ${args}`); }; /** * Parses a message for a global command * @param msg * @returns {boolean|*} */ exports.parseMessage = function(msg) { return parseGlobalCommand(msg); } /** * Initializes the module by creating a help command */ exports.init = function(prefix) { logger.verbose("Created help command"); this.createGlobalCommand((prefix+'help') || "~help", () => { let helpstr = "```markdown\n"; helpstr += "Commands\n---\n"; Object.entries(globCommands).forEach(([key, value]) => { let cmdhelp = `${key} [${value.args.join('] [')}]`.replace('[]', '').padEnd(25, ' '); cmdhelp += value.description || ''; helpstr += `\n${cmdhelp}\n`; }); helpstr += "```"; return helpstr; }, [], "Shows this help."); }; /** * Parses the message by calling the assigned function for the command with arguments * @param msg */ function parseGlobalCommand(msg) { let content = msg.content; let command = (content.match(/^.\w+/) || [])[0]; if (!command || !globCommands[command]) return false; let cmd = globCommands[command]; let argvars = content.match(/(?<= )\S+/g) || []; let kwargs = {}; let nLength = Math.min(cmd.args.length, argvars.length); for (let i = 0; i < nLength; i++) { kwargs[cmd.args[i]] = argvars[i]; } let argv = argvars.slice(nLength); logger.debug(`Executing callback for command: ${command}, kwargs: ${JSON.stringify(kwargs)}, argv: ${argv}`); return cmd.callback(msg, kwargs, argv); }