const logger = require("./logger.js"); const {pastelize, getTopColor} = require("./utils.js"); function convertIfApplicable(val) { if (isNaN(val)) { if (val.toString().toLowerCase() === "true") { return true; } else if (val.toString().toLowerCase() === "false") { return false; } else { return val; } } else { return Number(val); } } function removeStartHyphens(val) { return val.replace(/^--?/g, ""); } // taken from ethanent/gar // modified to make - arguments only be bools unless = function parseAsArgv(argv) { const optional = {}; const args = []; for (const arg of argv) { const equalsIndex = arg.charAt(0) === "-" ? arg.indexOf("=") : -1; const argName = equalsIndex === -1 ? removeStartHyphens(arg) : removeStartHyphens(arg.slice(0, equalsIndex)); if (equalsIndex !== -1) { optional[argName] = convertIfApplicable(arg.slice(equalsIndex + 1)); } else if (arg.charAt(0) === "-") { if (arg.charAt(1) === "-") { optional[argName] = true; } else { for (let b = 0; b < argName.length; b++) { optional[argName.charAt(b)] = true; } } } else { args.push(convertIfApplicable(argName)); } } return { optional, args, }; } 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) { 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 args = parseArguments(line); const argv = parseAsArgv(args); const ret = cmdObj.callback(msg, line, argv.args, argv.optional); 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(" "); try { const response = await runCommand(msg, cmd, line); if (response != null) { msg.hasRan = true; if (response.file) { const newFile = response.file; delete response.file; if (newFile.contents) { newFile.file = newFile.contents; delete newFile.contents; } if (newFile.name) { newFile.filename = newFile.name; delete newFile.name; } const files = response.attachments ?? []; files.push(newFile); response.attachments = files; } if (response.files) { response.attachments = response.files; delete response.files; for (const attachment of response.attachments) { if (attachment.contents) { attachment.file = attachment.contents; delete attachment.contents; } if (attachment.name) { attachment.filename = attachment.name; delete attachment.name; } } } if (response.embed) { response.embeds = [...(response.embeds ?? []), response.embed]; delete response.embed; } 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 { try { const outMessage = await msg.channel.createMessage( Object.assign( typeof response === "string" ? {content: response} : response, { allowedMentions: { repliedUser: false, }, messageReference: { messageID: msg.id, }, } ) ); if (response.addReactions) { for (const index in response.addReactions) { const reaction = response.addReactions[index]; await outMessage.addReaction(reaction); } } } catch (err) { msg.channel.createMessage({ content: `:warning: An error has occurred:\n\`\`\`${err}\`\`\``, allowedMentions: { repliedUser: false, }, messageReference: { messageID: msg.id, }, }); } } } } catch (err) { msg.channel.createMessage({ content: `:warning: An error has occurred:\n\`\`\`${err}\`\`\``, allowedMentions: { repliedUser: false, }, messageReference: { messageID: msg.id, }, }); } } } module.exports = CommandDispatcher;