const { literal, argument, greedyString, DynamicCommandExceptionType } = require('brigadier-commands') const TextMessage = require('../util/command/text_message') const UNKNOWN_COMMAND_ERROR = new DynamicCommandExceptionType(command => new TextMessage(['Unknown command: ', command])) module.exports = { register (dispatcher) { const node = dispatcher.register( literal('help') .executes(this.listCommands) .then( argument('command', greedyString()) .executes(this.showCommandInfo) ) ) node.description = 'Lists commands or shows info about a command' node.permissionLevel = 0 }, listCommands (context) { const source = context.source const bot = source.bot const nodes = bot.commands.dispatcher.root.getChildren() const publicList = [] const trustedList = [] const adminList = [] const unknownList = [] nodes.forEach(node => { if (node.redirect) return // ignore aliases const msg = { color: 'dark_aqua', text: bot.prefix + node.name + ' ', clickEvent: { action: 'suggest_command', value: bot.prefix + 'help ' + node.name }, hoverEvent: { action: 'show_text', value: 'Click to see info about the command' } } if (node.permissionLevel === 0) { msg.color = 'green' publicList.push(msg) } else if (node.permissionLevel === 1) { msg.color = 'red' trustedList.push(msg) } else if (node.permissionLevel === 2) { msg.color = 'dark_red' adminList.push(msg) } else { unknownList.push(msg) } }) const msg = [{ text: 'Commands - ', color: 'gray' }, ...publicList, ...trustedList, ...adminList, ...unknownList] source.sendFeedback(msg, false) }, showCommandInfo (context) { const source = context.source const bot = source.bot const nodes = bot.commands.dispatcher.root.getChildren() const commandName = context.getArgument('command') let node = nodes.find(node => node.name === commandName) if (!node) throw UNKNOWN_COMMAND_ERROR.create(commandName) if (node.redirect) node = node.redirect const aliases = [node, ...nodes.filter(_node => _node.redirect === node)].map(node => node.name) const usages = [...bot.commands.dispatcher.getSmartUsage(node, source, false).values()] let msg if (usages.length !== 1) { msg = [ { text: bot.prefix + node.name, ...bot.styles.primary }, { text: ' (' + aliases.join(', ') + ')', color: 'white' }, { text: ` - ${node.description}\n`, color: 'gray' } ] usages.forEach((usage, i) => { msg.push(bot.prefix + node.name) msg.push({ text: ` ${usage}\n`, ...bot.styles.secondary, clickEvent: { action: 'suggest_command', value: node.name + ' ' + usage } }) }) msg[msg.length - 1].text = msg[msg.length - 1].text.slice(0, -1) } else { msg = [ { text: bot.prefix + node.name, ...bot.styles.primary }, { text: ' (' + aliases.join(', ') + ')', color: 'white' }, { text: ` ${usages[0]}`, ...bot.styles.secondary, clickEvent: { action: 'suggest_command', value: node.name + ' ' + usages[0] } }, { text: ` - ${node.description}`, color: 'gray' } ] } source.sendFeedback(msg, false) } }