const logger = require("./logger.js"); const {pastelize, getTopColor} = require("./utils.js"); function parseArguments(str) { return str.match(/\\?.|^$/g).reduce( (p, c) => { if (c === '"') { p.quote ^= 1; } else if (!p.quote && c === " ") { p.a.push(""); } else { p.a[p.a.length - 1] += c.replace(/\\(.)/, "$1"); } return p; }, {a: [""]} ).a; } async function runCommand(msg, cmd, line, args) { let cmdObj = hf.commands.get(cmd); if (!cmdObj) { for (const c of hf.commands.values()) { if (c.hasAlias(cmd)) { cmdObj = c; break; } } } if (!cmdObj) return null; if (cmdObj.ownerOnly && msg.author.id != hf.config.owner_id) { return "No\n\nSent from my iPhone."; } if (cmdObj.elevatedOnly && !hf.config.elevated.includes(msg.author.id)) { return "No\n\nSent from my iPhone."; } if (cmdObj.guildOnly && !msg.guildID) { return "This command can only be used in guilds."; } try { const ret = cmdObj.callback(msg, line, ...args); if (ret instanceof Promise) { return await ret; } else { return ret; } } catch (err) { logger.error("hf:cmd:" + cmd, err); return ":warning: An internal error occurred."; } } async function CommandDispatcher(msg) { let str = msg.content; let inCommand = false; const prefix1 = hf.config.prefix; const prefix2 = `<@${hf.bot.user.id}> `; const prefix3 = `<@!${hf.bot.user.id}> `; if (str.startsWith(prefix1)) { str = str.substring(prefix1.length); inCommand = true; } else if (str.startsWith(prefix2)) { str = str.substring(prefix2.length); inCommand = true; } else if (str.startsWith(prefix3)) { str = str.substring(prefix3.length); inCommand = true; } if (inCommand) { let line = str.split(" "); let [cmd] = line.splice(0, 1); cmd = cmd.toLowerCase(); line = line.join(" "); const args = parseArguments(line); const response = await runCommand(msg, cmd, line, args); if (response != null) { let file; if (response.file) { file = response.file; delete response.file; } if (response.embeds) { for (const embed of response.embeds) { embed.color = embed.color || getTopColor(msg, hf.bot.user.id, pastelize(hf.bot.user.id)); } } if (response.reaction) { msg.addReaction(response.reaction); } else { msg.channel .createMessage( Object.assign( typeof response === "string" ? {content: response} : response, { allowedMentions: { repliedUser: false, }, messageReference: { messageID: msg.id, }, } ), file ) .catch((e) => { msg.channel.createMessage({ content: `:warning: An error has occurred:\n\`\`\`${e}\`\`\``, allowedMentions: { repliedUser: false, }, messageReference: { messageID: msg.id, }, }); }); } msg.hasRan = true; } } } module.exports = CommandDispatcher;