const Command = require("../lib/command.js"); const CATEGORY = "bot"; const logger = require("npmlog"); const child_process = require("child_process"); const {inspect} = require("util"); const {resolve} = require("path"); const {hastebin} = require("../lib/utils.js"); function spawn(args) { const shell = process.env.SHELL || (process.platform == "win32" ? "powershell" : "bash"); const newArgs = []; if (shell.match(/powershell/i) && process.platform == "win32") { newArgs.push("-NoLogo", "-Command"); } else { newArgs.push("-c"); } newArgs.push(args); const proc = child_process.spawn(shell, newArgs, { cwd: resolve(__dirname, "..", ".."), }); return { pid: proc.pid, stdout: { on: (event, handler) => proc.stdout.on(event, (data) => { handler(data.toString("utf8")); }), }, stderr: { on: (event, handler) => proc.stderr.on(event, (data) => { handler(data.toString("utf8")); }), }, on: (event, handler) => proc.on(event, handler), }; } const reload = new Command("reload"); reload.ownerOnly = true; reload.category = CATEGORY; reload.helpText = "Reloads a module."; reload.callback = function (msg, line) { try { require.resolve(`./${line}.js`); } catch (err) { if (err.code == "MODULE_NOT_FOUND") { return "Module not found."; } else { return `:warning: An error occurred: \`\`\`\n${err}\`\`\``; } } try { logger.info("hf:modules", "Reloading module: '%s'", line); delete require.cache[require.resolve(`./${line}.js`)]; require(`./${line}.js`); return {reaction: "\uD83D\uDC4C"}; } catch (err) { return `:warning: An error occurred: \`\`\`\n${err}\`\`\``; } }; hf.registerCommand(reload); const restart = new Command("restart"); restart.ownerOnly = true; restart.category = CATEGORY; restart.helpText = "Restarts the bot."; restart.callback = function () { setTimeout(process.exit, 500); return {reaction: "\uD83D\uDD04"}; }; hf.registerCommand(restart); const _eval = new Command("eval"); _eval.elevatedOnly = true; _eval.category = CATEGORY; _eval.helpText = "Evalueates Javascript"; _eval.callback = async function (msg, line) { let errored = false; let out; try { out = eval(line); if (out && out instanceof Promise) out = await out; } catch (err) { out = err.toString(); errored = true; } out = errored ? out : inspect(out, {depth: 0}); const token = hf.config.token; out = out.replace( new RegExp(token.replace(/\./g, "\\."), "g"), "lol no key 4 u" ); if (errored) { return ":warning: Output (errored):\n```js\n" + out + "\n```"; } else { if (out.toString().length > 1980) { const code = await hastebin(out.toString()); return `\u2705 Output too long to send in a message: ${hf.config.haste_provider}/${code}`; } else { return "\u2705 Output:\n```js\n" + out + "\n```"; } } }; hf.registerCommand(_eval); const exec = new Command("exec"); exec.elevatedOnly = true; exec.category = CATEGORY; exec.helpText = "Executes a command"; exec.callback = async function (msg, line) { const proc = spawn(line); let out = `Spawned ${proc.pid}: \`${line}'\n`; proc.stdout.on("data", (data) => { out += data; }); proc.stderr.on("data", (data) => { out += data; }); proc.on("close", async (code) => { out += `====\nExited with ${code}`; if (out.length > 1980) { const code = await hastebin(out); msg.channel.createMessage({ content: `Output too long to send in a message: ${hf.config.haste_provider}/${code}`, allowedMentions: { repliedUser: false, }, messageReference: { messageID: msg.id, }, }); } else { msg.channel.createMessage({ content: `\`\`\`\n${out}\`\`\``, allowedMentions: { repliedUser: false, }, messageReference: { messageID: msg.id, }, }); } }); }; hf.registerCommand(exec);