const { stripIndents } = require('common-tags'); const { escapeRegex } = require('escape-string-regexp'); const { Observer } = require('../../../interfaces/'); class CommandHandler extends Observer { constructor(client) { super(client, { name: 'commandHandler', priority: 5, guarded: true }); this.client = client; this.hooks = [ ['message', this.handleMessage.bind(this)] ]; } async handleMessage(message) { if(!this.client._built || message.webhookID || message.author.bot || (message.guild && !message.guild.available)) return undefined; if(message.guild && !message.member) { await message.guild.members.fetch(message.author.id); } const content = message.content; const args = content.split(' '); const { command, newArgs } = await this._getCommand(message, args); if(!command) return undefined; message.command = command; return await this.handleCommand(message, newArgs); } async _getCommand(message, [arg1, arg2, ...args]) { const prefix = this.client._options.bot.prefix; //Change this for guild prefix settings. let command = null; let remains = []; if(arg1 && arg1.startsWith(prefix)) { const commandName = arg1.slice(1); command = await this._matchCommand(message, commandName); remains = [arg2, ...args]; } else if(arg1 && arg2 && arg1.startsWith('<@')){ const pattern = new RegExp(`^(<@!?${this.client.user.id}>)`, 'i'); if(arg2 && pattern.test(arg1)) { command = await this._matchCommand(message, arg2); } remains = args } return { command, newArgs: remains }; } async _matchCommand(message, commandName) { const command = this.client.resolver.components(commandName, 'command', true)[0]; if(!command) return null; //Eventually search for custom commands here. return command; } /* Command Handling */ async handleCommand(message, args) { const inhibitor = await this._handleInhibitors(message); if(inhibitor.error) { message.channel.send(`${inhibitor.resolveable} failed to pass.`); return undefined; } const parsedArguments = await this._parseArguments(message, args); } async _handleInhibitors(message) { const inhibitors = this.client.registry.components.filter(c=>c.type === 'inhibitor' && !c.disabled); if(inhibitors.size === 0) return { error: false }; const promises = []; for(const inhibitor of inhibitors.values()) { if(inhibitor.guild && !message.guild) continue; promises.push((async () => { let inhibited = inhibitor.execute(message); if(inhibited instanceof Promise) inhibited = await inhibited; return inhibited; })()); } const reasons = (await Promise.all(promises)).filter(p=>p.error); if(reasons.length === 0) return { error: false }; reasons.sort((a, b) => b.inhibitor.priority - a.inhibitor.priority); return reasons[0]; } async _parseArguments(message, args = []) { const command = message.command; let parsedArguments = []; const parsedFlags = {}; const { shortFlags, longFlags, keys } = await this._createFlags(command.arguments); let currentArgument = null; for(const word of args) { if(currentArgument) { //what } const [one,two,...chars] = word.split(''); if(one === '-' && two !== '-') { //short flag maybe? const name = [ two, ...chars ].join(''); currentArgument = shortFlags[name]; if(!currentArgument) continue; } else if(one === '-' && two === '-') { //long flag maybe? const name = chars.join(''); currentArgument = longFlags[name]; if(!currentArgument) continue; } else { //verbal argument const regex = new RegExp('([0-9]*)([a-zA-Z]+)([0-9]*)', 'g'); let match = regex.exec(word); if(!match) continue; currentArgument = longFlags[match[2]]; if(!currentArgument) continue; const value = match[1] || match[3]; console.log(currentArgument); } } } async _createFlags(args) { let shortFlags = {}; let longFlags = {}; let keys = []; for(const arg of args) { let letters = []; let names = [ arg.name, ...arg.aliases ]; keys = [...keys, ...names]; for(const name of names) { longFlags[name] = arg; if(!arg.types.includes('FLAG')) continue; let letter = name.slice(0, 1); if(letters.includes(letter)) continue; if(keys.includes(letter)) letter = letter.toUpperCase(); if(keys.includes(letter)) break; keys.push(letter); letters.push(letter); shortFlags[letter] = arg; } } return { shortFlags, longFlags, keys }; } } module.exports = CommandHandler;