diff --git a/classes/command.js b/classes/command.js index f29e7cd..ec5f49d 100644 --- a/classes/command.js +++ b/classes/command.js @@ -6,6 +6,17 @@ class Command { this.message = message; this.args = args; this.content = content; + this.reference = { + messageReference: { + channelID: this.message.channel.id, + messageID: this.message.id, + guildID: this.message.channel.guild ? this.message.channel.guild.id : undefined, + failIfNotExists: false + }, + allowedMentions: { + repliedUser: false + } + }; } async run() { diff --git a/classes/imageCommand.js b/classes/imageCommand.js index 12bc1fe..037c410 100644 --- a/classes/imageCommand.js +++ b/classes/imageCommand.js @@ -41,7 +41,7 @@ class ImageCommand extends Command { // check if this command has already been run in this channel with the same arguments, and we are awaiting its result // if so, don't re-run it if (collections.runningCommands.has(this.message.author.id) && (new Date(collections.runningCommands.get(this.message.author.id)) - new Date(this.message.createdAt)) < 5000) { - return `${this.message.author.mention}, please slow down a bit.`; + return "Please slow down a bit."; } // before awaiting the command result, add this command to the set of running commands collections.runningCommands.set(this.message.author.id, this.message.createdAt); @@ -55,7 +55,7 @@ class ImageCommand extends Command { const image = await imageDetect(this.client, this.message); if (image === undefined) { collections.runningCommands.delete(this.message.author.id); - return `${this.message.author.mention}, ${this.constructor.noImage}`; + return this.constructor.noImage; } magickParams.path = image.path; magickParams.type = image.type; @@ -72,7 +72,7 @@ class ImageCommand extends Command { if (this.constructor.requiresText) { if (this.args.length === 0 || !await this.criteria(this.args)) { collections.runningCommands.delete(this.message.author.id); - return `${this.message.author.mention}, ${this.constructor.noText}`; + return this.constructor.noText; } } @@ -96,13 +96,13 @@ class ImageCommand extends Command { const { buffer, type } = await magick.run(magickParams).catch(e => { throw e; }); - if (type === "nogif" && this.constructor.requiresGIF) return `${this.message.author.mention}, that isn't a GIF!`; + if (type === "nogif" && this.constructor.requiresGIF) return "That isn't a GIF!"; return { file: buffer, name: `${this.constructor.command}.${type}` }; } catch (e) { - if (e.toString().includes("Not connected to image server")) return `${this.message.author.mention}, I'm still trying to connect to the image servers. Please wait a little bit.`; + if (e.toString().includes("Not connected to image server")) return "I'm still trying to connect to the image servers. Please wait a little bit."; throw e; } finally { if (status && await this.client.getMessage(status.channel.id, status.id).catch(() => undefined)) await status.delete(); diff --git a/commands/fun/cowsay.js b/commands/fun/cowsay.js index 7d0cb39..d5dd3b3 100644 --- a/commands/fun/cowsay.js +++ b/commands/fun/cowsay.js @@ -5,7 +5,7 @@ const Command = require("../../classes/command.js"); class CowsayCommand extends Command { async run() { if (this.args.length === 0) { - return `${this.message.author.mention}, you need to provide some text for the cow to say!`; + return "You need to provide some text for the cow to say!"; } else if (cows[this.args[0].toLowerCase()] != undefined) { const cow = cows[this.args.shift().toLowerCase()]; return `\`\`\`\n${cowsay.say(this.args.join(" "), { cow })}\n\`\`\``; diff --git a/commands/fun/fullwidth.js b/commands/fun/fullwidth.js index 602c495..50298f3 100644 --- a/commands/fun/fullwidth.js +++ b/commands/fun/fullwidth.js @@ -2,7 +2,7 @@ const Command = require("../../classes/command.js"); class FullwidthCommand extends Command { async run() { - if (this.args.length === 0) return `${this.message.author.mention}, you need to provide some text to convert to fullwidth!`; + if (this.args.length === 0) return "You need to provide some text to convert to fullwidth!"; return this.args.join("").replaceAll(/[A-Za-z0-9]/g, (s) => { return String.fromCharCode(s.charCodeAt(0) + 0xFEE0); }); } diff --git a/commands/fun/mc.js b/commands/fun/mc.js index 6d81ff4..0951105 100644 --- a/commands/fun/mc.js +++ b/commands/fun/mc.js @@ -3,7 +3,7 @@ const Command = require("../../classes/command.js"); class MCCommand extends Command { async run() { - if (this.args.length === 0) return `${this.message.author.mention}, you need to provide some text to generate a Minecraft achievement!`; + if (this.args.length === 0) return "You need to provide some text to generate a Minecraft achievement!"; this.client.sendChannelTyping(this.message.channel.id); const request = await fetch(`https://www.minecraftskinstealer.com/achievement/a.php?i=13&h=Achievement+get%21&t=${encodeURIComponent(this.args.join("+"))}`); return { diff --git a/commands/fun/retro.js b/commands/fun/retro.js index c30a052..493663f 100644 --- a/commands/fun/retro.js +++ b/commands/fun/retro.js @@ -1,12 +1,9 @@ -const magick = require("../../utils/image.js"); const wrap = require("../../utils/wrap.js"); -const Command = require("../../classes/command.js"); +const ImageCommand = require("../../classes/imageCommand.js"); -class RetroCommand extends Command { - async run() { - if (this.args.length === 0) return `${this.message.author.mention}, you need to provide some text to generate some retro text!`; - this.client.sendChannelTyping(this.message.channel.id); - let [line1, line2, line3] = this.args.join(" ").replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%").split(",").map(elem => elem.trim()); +class RetroCommand extends ImageCommand { + params(args) { + let [line1, line2, line3] = args.join(" ").replaceAll("&", "\\&").replaceAll(">", "\\>").replaceAll("<", "\\<").replaceAll("\"", "\\"").replaceAll("'", "\\'").replaceAll("%", "\\%").split(",").map(elem => elem.trim()); if (!line2 && line1.length > 15) { const [split1, split2, split3] = wrap(line1, { width: 15, indent: "" }).split("\n"); line1 = split1; @@ -20,20 +17,16 @@ class RetroCommand extends Command { line3 = ""; } } - const { buffer } = await magick.run({ - cmd: "retro", - line1, - line2, - line3 - }); - return { - file: buffer, - name: "retro.png" - }; + return { line1, line2, line3 }; } static description = "Generates a retro text image (separate lines with a comma)"; - static arguments = ["[text]", "{middle text}", "{bottom text}"]; + static arguments = ["[top text]", "{middle text}", "{bottom text}"]; + + static requiresImage = false; + static requiresText = true; + static noText = "You need to provide some text to make retro!"; + static command = "retro"; } module.exports = RetroCommand; \ No newline at end of file diff --git a/commands/fun/rps.js b/commands/fun/rps.js index 9c399b3..355e26a 100644 --- a/commands/fun/rps.js +++ b/commands/fun/rps.js @@ -3,22 +3,22 @@ const Command = require("../../classes/command.js"); class RPSCommand extends Command { async run() { - if (this.args.length === 0 || (this.args[0] !== "rock" && this.args[0] !== "paper" && this.args[0] !== "scissors")) return `${this.message.author.mention}, you need to choose whether you want to be rock, paper, or scissors!`; + if (this.args.length === 0 || (this.args[0] !== "rock" && this.args[0] !== "paper" && this.args[0] !== "scissors")) return "You need to choose whether you want to be rock, paper, or scissors!"; let emoji; let winOrLose; const result = misc.random(["rock", "paper", "scissors"]); switch (result) { case "rock": emoji = "✊"; - if (this.args[0].toLowerCase() === "paper") winOrLose = 1; + if (this.args[0].toLowerCase() === "paper") winOrLose = true; break; case "paper": emoji = "✋"; - if (this.args[0].toLowerCase() === "scissors") winOrLose = 1; + if (this.args[0].toLowerCase() === "scissors") winOrLose = true; break; case "scissors": emoji = "✌"; - if (this.args[0].toLowerCase() === "rock") winOrLose = 1; + if (this.args[0].toLowerCase() === "rock") winOrLose = true; break; default: break; diff --git a/commands/fun/xkcd.js b/commands/fun/xkcd.js index 4b80bdf..c09e9d7 100644 --- a/commands/fun/xkcd.js +++ b/commands/fun/xkcd.js @@ -20,7 +20,7 @@ class XKCDCommand extends Command { }; return embed; } catch { - return `${this.message.author.mention}, I couldn't get that XKCD!`; + return "I couldn't get that XKCD!"; } } diff --git a/commands/general/channel.js b/commands/general/channel.js index 652e44b..e0b74f8 100644 --- a/commands/general/channel.js +++ b/commands/general/channel.js @@ -3,10 +3,10 @@ const Command = require("../../classes/command.js"); class ChannelCommand extends Command { async run() { - if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; - if (!this.message.member.permission.has("administrator") && this.message.member.id !== process.env.OWNER) return `${this.message.author.mention}, you need to be an administrator to enable/disable me!`; - if (this.args.length === 0) return `${this.message.author.mention}, you need to provide whether I should be enabled or disabled in this channel!`; - if (this.args[0] !== "disable" && this.args[0] !== "enable") return `${this.message.author.mention}, that's not a valid option!`; + if (!this.message.channel.guild) return "This command only works in servers!"; + if (!this.message.member.permission.has("administrator") && this.message.member.id !== process.env.OWNER) return "You need to be an administrator to enable/disable me!"; + if (this.args.length === 0) return "You need to provide whether I should be enabled or disabled in this channel!"; + if (this.args[0] !== "disable" && this.args[0] !== "enable") return "That's not a valid option!"; const guildDB = await db.getGuild(this.message.channel.guild.id); @@ -14,28 +14,28 @@ class ChannelCommand extends Command { let channel; if (this.args[1] && this.args[1].match(/^?$/) && this.args[1] >= 21154535154122752n) { const id = this.args[1].replaceAll("@", "").replaceAll("#", "").replaceAll("!", "").replaceAll("&", "").replaceAll("<", "").replaceAll(">", ""); - if (guildDB.disabled.includes(id)) return `${this.message.author.mention}, I'm already disabled in this channel!`; + if (guildDB.disabled.includes(id)) return "I'm already disabled in this channel!"; channel = this.message.channel.guild.channels.get(id); } else { - if (guildDB.disabled.includes(this.message.channel.id)) return `${this.message.author.mention}, I'm already disabled in this channel!`; + if (guildDB.disabled.includes(this.message.channel.id)) return "I'm already disabled in this channel!"; channel = this.message.channel; } await db.disableChannel(channel); - return `${this.message.author.mention}, I have been disabled in this channel. To re-enable me, just run \`${guildDB.prefix}channel enable\`.`; + return `I have been disabled in this channel. To re-enable me, just run \`${guildDB.prefix}channel enable\`.`; } else if (this.args[0].toLowerCase() === "enable") { let channel; if (this.args[1] && this.args[1].match(/^?$/) && this.args[1] >= 21154535154122752) { const id = this.args[1].replaceAll("@", "").replaceAll("#", "").replaceAll("!", "").replaceAll("&", "").replaceAll("<", "").replaceAll(">", ""); - if (!guildDB.disabled.includes(id)) return `${this.message.author.mention}, I'm not disabled in that channel!`; + if (!guildDB.disabled.includes(id)) return "I'm not disabled in that channel!"; channel = this.message.channel.guild.channels.get(id); } else { - if (!guildDB.disabled.includes(this.message.channel.id)) return `${this.message.author.mention}, I'm not disabled in this channel!`; + if (!guildDB.disabled.includes(this.message.channel.id)) return "I'm not disabled in this channel!"; channel = this.message.channel; } await db.enableChannel(channel); - return `${this.message.author.mention}, I have been re-enabled in this channel.`; + return "I have been re-enabled in this channel."; } } diff --git a/commands/general/count.js b/commands/general/count.js index c969b5a..48cf792 100644 --- a/commands/general/count.js +++ b/commands/general/count.js @@ -4,8 +4,8 @@ const Command = require("../../classes/command.js"); class CountCommand extends Command { async run() { - if (this.message.channel.guild && !this.message.channel.permissionsOf(this.client.user.id).has("addReactions")) return `${this.message.author.mention}, I don't have the \`Add Reactions\` permission!`; - if (this.message.channel.guild && !this.message.channel.permissionsOf(this.client.user.id).has("embedLinks")) return `${this.message.author.mention}, I don't have the \`Embed Links\` permission!`; + if (this.message.channel.guild && !this.message.channel.permissionsOf(this.client.user.id).has("addReactions")) return "I don't have the `Add Reactions` permission!"; + if (this.message.channel.guild && !this.message.channel.permissionsOf(this.client.user.id).has("embedLinks")) return "I don't have the `Embed Links` permission!"; const counts = await database.getCounts(); const countArray = []; for (const entry of Object.entries(counts)) { diff --git a/commands/general/decode.js b/commands/general/decode.js index d2be1e2..23f93af 100644 --- a/commands/general/decode.js +++ b/commands/general/decode.js @@ -3,8 +3,8 @@ const Command = require("../../classes/command.js"); class DecodeCommand extends Command { async run() { - if (this.args.length === 0) return `${this.message.author.mention}, you need to provide a string to decode!`; - const b64Decoded = Buffer.from(this.args.join(" "), "base64").toString("utf-8"); + if (this.args.length === 0) return "You need to provide a string to decode!"; + const b64Decoded = Buffer.from(this.args.join(" "), "base64").toString("utf8"); return `\`\`\`\n${await clean(b64Decoded)}\`\`\``; } diff --git a/commands/general/emote.js b/commands/general/emote.js index e28715a..0442c70 100644 --- a/commands/general/emote.js +++ b/commands/general/emote.js @@ -3,7 +3,7 @@ const Command = require("../../classes/command.js"); class EmoteCommand extends Command { async run() { - if (this.args.length === 0) return `${this.message.author.mention}, you need to provide an emoji!`; + if (this.args.length === 0) return "You need to provide an emoji!"; if (this.content.split(" ")[0].match(/^$/)) { return `https://cdn.discordapp.com/emojis/${this.content.split(" ")[0].replace(/^<(a)?:.+:(\d+)>$/, "$2")}.${this.content.split(" ")[0].replace(/^<(a)?:.+:(\d+)>$/, "$1") === "a" ? "gif" : "png"}`; } else if (this.args[0].match(emojiRegex)) { @@ -13,7 +13,7 @@ class EmoteCommand extends Command { } return `https://twemoji.maxcdn.com/v/latest/72x72/${codePoints.join("-").replace("-fe0f", "")}.png`; } else { - return `${this.message.author.mention}, you need to provide a valid emoji to get an image!`; + return "You need to provide a valid emoji to get an image!"; } } diff --git a/commands/general/encode.js b/commands/general/encode.js index bd68924..594f0fb 100644 --- a/commands/general/encode.js +++ b/commands/general/encode.js @@ -2,8 +2,8 @@ const Command = require("../../classes/command.js"); class EncodeCommand extends Command { async run() { - if (this.args.length === 0) return `${this.message.author.mention}, you need to provide a string to encode!`; - const b64Encoded = Buffer.from(this.args.join(" ")).toString("base64"); + if (this.args.length === 0) return "You need to provide a string to encode!"; + const b64Encoded = Buffer.from(this.args.join(" "), "utf8").toString("base64"); return `\`\`\`\n${b64Encoded}\`\`\``; } diff --git a/commands/general/eval.js b/commands/general/eval.js index e3ac399..3ecd4a3 100644 --- a/commands/general/eval.js +++ b/commands/general/eval.js @@ -3,7 +3,7 @@ const Command = require("../../classes/command.js"); class EvalCommand extends Command { async run() { - if (this.message.author.id !== process.env.OWNER) return `${this.message.author.mention}, only the bot owner can use eval!`; + if (this.message.author.id !== process.env.OWNER) return "Only the bot owner can use eval!"; const code = this.args.join(" "); try { const evaled = eval(code); diff --git a/commands/general/exec.js b/commands/general/exec.js index 44a1521..23540e9 100644 --- a/commands/general/exec.js +++ b/commands/general/exec.js @@ -5,7 +5,7 @@ const Command = require("../../classes/command.js"); class ExecCommand extends Command { async run() { - if (this.message.author.id !== process.env.OWNER) return `${this.message.author.mention}, only the bot owner can use exec!`; + if (this.message.author.id !== process.env.OWNER) return "Only the bot owner can use exec!"; const code = this.args.join(" "); try { const execed = await exec(code); diff --git a/commands/general/image.js b/commands/general/image.js index f87a751..3a1a1df 100644 --- a/commands/general/image.js +++ b/commands/general/image.js @@ -4,13 +4,13 @@ const Command = require("../../classes/command.js"); class ImageSearchCommand extends Command { async run() { - if (this.message.channel.guild && !this.message.channel.permissionsOf(this.client.user.id).has("addReactions")) return `${this.message.author.mention}, I don't have the \`Add Reactions\` permission!`; - if (this.message.channel.guild && !this.message.channel.permissionsOf(this.client.user.id).has("embedLinks")) return `${this.message.author.mention}, I don't have the \`Embed Links\` permission!`; - if (this.args.length === 0) return `${this.message.author.mention}, you need to provide something to search for!`; + if (this.message.channel.guild && !this.message.channel.permissionsOf(this.client.user.id).has("addReactions")) return "I don't have the `Add Reactions` permission!"; + if (this.message.channel.guild && !this.message.channel.permissionsOf(this.client.user.id).has("embedLinks")) return "I don't have the `Embed Links` permission!"; + if (this.args.length === 0) return "You need to provide something to search for!"; const embeds = []; const images = await image_search({ query: this.args.join(" "), moderate: true }); - if (images.error && images.error.code === 403) return `${this.message.author.mention}, the daily search quota has been exceeded. Check back later.`; - if (images.length === 0) return `${this.message.author.mention}, I couldn't find any results!`; + if (images.error && images.error.code === 403) return "The daily search quota has been exceeded. Check back later."; + if (images.length === 0) return "I couldn't find any results!"; for (const [i, value] of images.entries()) { embeds.push({ "embed": { diff --git a/commands/general/imagereload.js b/commands/general/imagereload.js index 1ad8944..2a4230e 100644 --- a/commands/general/imagereload.js +++ b/commands/general/imagereload.js @@ -4,7 +4,7 @@ const Command = require("../../classes/command.js"); class ImageReloadCommand extends Command { async run() { - if (this.message.author.id !== process.env.OWNER) return `${this.message.author.mention}, only the bot owner can reload the image servers!`; + if (this.message.author.id !== process.env.OWNER) return "Only the bot owner can reload the image servers!"; await image.disconnect(); await image.repopulate(); let amount = 0; @@ -19,7 +19,7 @@ class ImageReloadCommand extends Command { if (amount > 0) { return `Successfully connected to ${amount} image servers.`; } else { - return `${this.message.author.mention}, I couldn't connect to any image servers!`; + return "I couldn't connect to any image servers!"; } } diff --git a/commands/general/invite.js b/commands/general/invite.js index 507ecde..de8fb25 100644 --- a/commands/general/invite.js +++ b/commands/general/invite.js @@ -2,7 +2,7 @@ const Command = require("../../classes/command.js"); class InviteCommand extends Command { async run() { - return `${this.message.author.mention}, you can invite me to your server here: `; + return "You can invite me to your server here: "; } static description = "Gets my invite link"; diff --git a/commands/general/lengthen.js b/commands/general/lengthen.js index 526e6ac..6fdee67 100644 --- a/commands/general/lengthen.js +++ b/commands/general/lengthen.js @@ -5,12 +5,12 @@ const Command = require("../../classes/command.js"); class LengthenCommand extends Command { async run() { this.client.sendChannelTyping(this.message.channel.id); - if (this.args.length === 0 || !urlCheck(this.args[0])) return `${this.message.author.mention}, you need to provide a short URL to lengthen!`; + if (this.args.length === 0 || !urlCheck(this.args[0])) return "You need to provide a short URL to lengthen!"; if (urlCheck(this.args[0])) { const url = await fetch(encodeURI(this.args[0]), { redirect: "manual" }); return url.headers.get("location") || this.args[0]; } else { - return `${this.message.author.mention}, that isn't a URL!`; + return "That isn't a URL!"; } } diff --git a/commands/general/ping.js b/commands/general/ping.js index 9d0a714..3878b43 100644 --- a/commands/general/ping.js +++ b/commands/general/ping.js @@ -2,7 +2,9 @@ const Command = require("../../classes/command.js"); class PingCommand extends Command { async run() { - const pingMessage = await this.client.createMessage(this.message.channel.id, "🏓 Ping?"); + const pingMessage = await this.client.createMessage(this.message.channel.id, Object.assign({ + content: "🏓 Ping?" + }, this.reference)); return pingMessage.edit(`🏓 Pong!\n\`\`\`\nLatency: ${pingMessage.timestamp - this.message.timestamp}ms${this.message.channel.guild ? `\nShard Latency: ${Math.round(this.client.shards.get(this.client.guildShardMap[this.message.channel.guild.id]).latency)}ms` : ""}\n\`\`\``); } diff --git a/commands/general/prefix.js b/commands/general/prefix.js index d3b8493..5aaa8c5 100644 --- a/commands/general/prefix.js +++ b/commands/general/prefix.js @@ -3,14 +3,14 @@ const Command = require("../../classes/command.js"); class PrefixCommand extends Command { async run() { - if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; + if (!this.message.channel.guild) return "This command only works in servers!"; const guild = await database.getGuild(this.message.channel.guild.id); if (this.args.length !== 0) { - if (!this.message.member.permission.has("administrator") && this.message.member.id !== process.env.OWNER) return `${this.message.author.mention}, you need to be an administrator to change the bot prefix!`; + if (!this.message.member.permission.has("administrator") && this.message.member.id !== process.env.OWNER) return "You need to be an administrator to change the bot prefix!"; await database.setPrefix(this.args[0], this.message.channel.guild); return `The prefix has been changed to ${this.args[0]}.`; } else { - return `${this.message.author.mention}, the current prefix is \`${guild.prefix}\`.`; + return `The current prefix is \`${guild.prefix}\`.`; } } diff --git a/commands/general/qrcreate.js b/commands/general/qrcreate.js index e7c3a60..e4f1931 100644 --- a/commands/general/qrcreate.js +++ b/commands/general/qrcreate.js @@ -4,7 +4,7 @@ const Command = require("../../classes/command.js"); class QrCreateCommand extends Command { async run() { - if (this.args.length === 0) return `${this.message.author.mention}, you need to provide some text to generate a QR code!`; + if (this.args.length === 0) return "You need to provide some text to generate a QR code!"; this.client.sendChannelTyping(this.message.channel.id); const writable = new stream.PassThrough(); qrcode.toFileStream(writable, this.content, { margin: 1 }); diff --git a/commands/general/qrread.js b/commands/general/qrread.js index 35c4625..7b0530d 100644 --- a/commands/general/qrread.js +++ b/commands/general/qrread.js @@ -7,12 +7,12 @@ const Command = require("../../classes/command.js"); class QrReadCommand extends Command { async run() { const image = await require("../../utils/imagedetect.js")(this.client, this.message); - if (image === undefined) return `${this.message.author.mention}, you need to provide an image with a QR code to read!`; + if (image === undefined) return "You need to provide an image with a QR code to read!"; this.client.sendChannelTyping(this.message.channel.id); const data = await (await fetch(image.path)).buffer(); const rawData = await sharp(data).ensureAlpha().raw().toBuffer({ resolveWithObject: true }); const qrBuffer = jsqr(rawData.data, rawData.info.width, rawData.info.height); - if (!qrBuffer) return `${this.message.author.mention}, I couldn't find a QR code!`; + if (!qrBuffer) return "I couldn't find a QR code!"; return `\`\`\`\n${await clean(qrBuffer.data)}\n\`\`\``; } diff --git a/commands/general/reload.js b/commands/general/reload.js index a86d2d4..e96ed6c 100644 --- a/commands/general/reload.js +++ b/commands/general/reload.js @@ -4,13 +4,13 @@ class ReloadCommand extends Command { // quite possibly one of the hackiest commands in the bot run() { return new Promise((resolve) => { - if (this.message.author.id !== process.env.OWNER) resolve(`${this.message.author.mention}, only the bot owner can reload commands!`); - if (this.args.length === 0) resolve(`${this.message.author.mention}, you need to provide a command to reload!`); + if (this.message.author.id !== process.env.OWNER) resolve("Only the bot owner can reload commands!"); + if (this.args.length === 0) resolve("You need to provide a command to reload!"); this.ipc.broadcast("reload", { cmd: this.args[0] }); this.ipc.register("reloadSuccess", () => { this.ipc.unregister("reloadSuccess"); this.ipc.unregister("reloadFail"); - resolve(`${this.message.author.mention}, the command \`${this.args[0]}\` has been reloaded.`); + resolve(`The command \`${this.args[0]}\` has been reloaded.`); }); this.ipc.register("reloadFail", (message) => { this.ipc.unregister("reloadSuccess"); diff --git a/commands/general/restart.js b/commands/general/restart.js index c010bac..7b767ef 100644 --- a/commands/general/restart.js +++ b/commands/general/restart.js @@ -4,8 +4,10 @@ const Command = require("../../classes/command.js"); class RestartCommand extends Command { async run() { - if (this.message.author.id !== process.env.OWNER) return `${this.message.author.mention}, only the bot owner can restart me!`; - await this.client.createMessage(this.message.channel.id, `${this.message.author.mention}, esmBot is restarting.`); + if (this.message.author.id !== process.env.OWNER) return "Only the bot owner can restart me!"; + await this.client.createMessage(this.message.channel.id, Object.assign({ + content: "esmBot is restarting." + }, this.reference)); for (const command of collections.commands) { await handler.unload(command); } diff --git a/commands/general/serverinfo.js b/commands/general/serverinfo.js index 7643286..6ea57ba 100644 --- a/commands/general/serverinfo.js +++ b/commands/general/serverinfo.js @@ -2,7 +2,7 @@ const Command = require("../../classes/command.js"); class ServerInfoCommand extends Command { async run() { - if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; + if (!this.message.channel.guild) return "This command only works in servers!"; const owner = await this.message.channel.guild.members.get(this.message.channel.guild.ownerID); return { "embed": { diff --git a/commands/general/snowflake.js b/commands/general/snowflake.js index 13b13c2..893d7f6 100644 --- a/commands/general/snowflake.js +++ b/commands/general/snowflake.js @@ -2,8 +2,8 @@ const Command = require("../../classes/command.js"); class SnowflakeCommand extends Command { async run() { - if (!this.args[0]) return `${this.message.author.mention}, you need to provide a snowflake ID!`; - if (!this.args[0].match(/^?$/) && this.args[0] < 21154535154122752) return `${this.message.author.mention}, that's not a valid snowflake!`; + if (!this.args[0]) return "You need to provide a snowflake ID!"; + if (!this.args[0].match(/^?$/) && this.args[0] < 21154535154122752) return "That's not a valid snowflake!"; return new Date((this.args[0].replaceAll("@", "").replaceAll("#", "").replaceAll("!", "").replaceAll("&", "").replaceAll("<", "").replaceAll(">", "") / 4194304) + 1420070400000).toUTCString(); } diff --git a/commands/general/soundreload.js b/commands/general/soundreload.js index 720d0aa..7e924d0 100644 --- a/commands/general/soundreload.js +++ b/commands/general/soundreload.js @@ -3,13 +3,13 @@ const Command = require("../../classes/command.js"); class SoundReloadCommand extends Command { async run() { - if (this.message.author.id !== process.env.OWNER) return `${this.message.author.mention}, only the bot owner can reload Lavalink!`; + if (this.message.author.id !== process.env.OWNER) return "Only the bot owner can reload Lavalink!"; const soundStatus = await soundPlayer.checkStatus(); if (!soundStatus) { const length = await soundPlayer.connect(this.client); return `Successfully connected to ${length} Lavalink node(s).`; } else { - return `${this.message.author.mention}, I couldn't connect to any Lavalink nodes!`; + return "I couldn't connect to any Lavalink nodes!"; } } diff --git a/commands/general/youtube.js b/commands/general/youtube.js index 3708ed2..709fe0e 100644 --- a/commands/general/youtube.js +++ b/commands/general/youtube.js @@ -5,12 +5,12 @@ const Command = require("../../classes/command.js"); class YouTubeCommand extends Command { async run() { - if (this.args.length === 0) return `${this.message.author.mention}, you need to provide something to search for!`; + if (this.args.length === 0) return "You need to provide something to search for!"; this.client.sendChannelTyping(this.message.channel.id); const messages = []; const request = await fetch(`https://www.googleapis.com/youtube/v3/search?part=snippet&q=${encodeURIComponent(this.args.join(" "))}&key=${process.env.GOOGLE}&maxResults=50`); const result = await request.json(); - if (result.error && result.error.code === 403) return `${this.message.author.mention}, I've exceeded my YouTube API search quota for the day. Check back later.`; + if (result.error && result.error.code === 403) return "I've exceeded my YouTube API search quota for the day. Check back later."; for (const [i, value] of result.items.entries()) { if (value.id.kind === "youtube#channel") { messages.push(`Page ${i + 1} of ${result.items.length}\n<:youtube:637020823005167626> **${decodeEntities(value.snippet.title).replaceAll("*", "\\*")}**\nhttps://youtube.com/channel/${value.id.channelId}`); diff --git a/commands/music/loop.js b/commands/music/loop.js index aacfea2..2a154e7 100644 --- a/commands/music/loop.js +++ b/commands/music/loop.js @@ -5,10 +5,10 @@ class LoopCommand extends MusicCommand { async run() { if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; - if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; - if (!this.message.member.voiceState.channelID) return `${this.message.author.mention}, you need to be in a voice channel first!`; - if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return `${this.message.author.mention}, I'm not in a voice channel!`; - if (this.connection.host !== this.message.author.id) return `${this.message.author.mention}, only the current voice session host can loop the music!`; + if (!this.message.channel.guild) return "This command only works in servers!"; + if (!this.message.member.voiceState.channelID) return "You need to be in a voice channel first!"; + if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!"; + if (this.connection.host !== this.message.author.id) return "Only the current voice session host can loop the music!"; const object = this.connection; object.loop = !object.loop; soundPlayer.players.set(this.message.channel.guild.id, object); diff --git a/commands/music/nowplaying.js b/commands/music/nowplaying.js index d9dcb8a..613c454 100644 --- a/commands/music/nowplaying.js +++ b/commands/music/nowplaying.js @@ -8,11 +8,11 @@ class NowPlayingCommand extends MusicCommand { async run() { if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; - if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; - if (!this.message.member.voiceState.channelID) return `${this.message.author.mention}, you need to be in a voice channel first!`; - if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return `${this.message.author.mention}, I'm not in a voice channel!`; + if (!this.message.channel.guild) return "This command only works in servers!"; + if (!this.message.member.voiceState.channelID) return "You need to be in a voice channel first!"; + if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!"; const player = this.connection.player; - if (!player) return `${this.message.author.mention}, I'm not playing anything!`; + if (!player) return "I'm not playing anything!"; const track = await fetch(`http://${player.node.host}:${player.node.port}/decodetrack?track=${encodeURIComponent(player.track)}`, { headers: { Authorization: player.node.password } }).then(res => res.json()); const parts = Math.floor((player.state.position / track.length) * 10); return { diff --git a/commands/music/pause.js b/commands/music/pause.js index 81dfbc6..f4eb373 100644 --- a/commands/music/pause.js +++ b/commands/music/pause.js @@ -4,10 +4,10 @@ class PauseCommand extends MusicCommand { async run() { if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; - if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; - if (!this.message.member.voiceState.channelID) return `${this.message.author.mention}, you need to be in a voice channel first!`; - if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return `${this.message.author.mention}, I'm not in a voice channel!`; - if (this.connection.host !== this.message.author.id) return `${this.message.author.mention}, only the current voice session host can pause/resume the music!`; + if (!this.message.channel.guild) return "This command only works in servers!"; + if (!this.message.member.voiceState.channelID) return "You need to be in a voice channel first!"; + if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!"; + if (this.connection.host !== this.message.author.id) return "Only the current voice session host can pause/resume the music!"; const player = this.connection.player; player.pause(!player.paused ? true : false); return `🔊 The player has been ${!player.paused ? "paused" : "resumed"}.`; diff --git a/commands/music/play.js b/commands/music/play.js index ec70cca..d6aa2f0 100644 --- a/commands/music/play.js +++ b/commands/music/play.js @@ -7,7 +7,7 @@ class PlayCommand extends MusicCommand { async run() { if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; - if (!this.args[0]) return `${this.message.author.mention}, you need to provide what you want to play!`; + if (!this.args[0]) return "You need to provide what you want to play!"; const query = this.args.join(" ").trim(); const search = urlRegex.test(query) ? query : (searchRegex.test(query) ? query : `ytsearch:${query}`); return await soundPlayer.play(this.client, encodeURIComponent(search), this.message, true); diff --git a/commands/music/queue.js b/commands/music/queue.js index a6bb47a..cdea4d7 100644 --- a/commands/music/queue.js +++ b/commands/music/queue.js @@ -10,11 +10,11 @@ class QueueCommand extends MusicCommand { async run() { if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; - if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; - if (!this.message.member.voiceState.channelID) return `${this.message.author.mention}, you need to be in a voice channel first!`; - if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return `${this.message.author.mention}, I'm not in a voice channel!`; - if (!this.message.channel.permissionsOf(this.client.user.id).has("addReactions")) return `${this.message.author.mention}, I don't have the \`Add Reactions\` permission!`; - if (!this.message.channel.permissionsOf(this.client.user.id).has("embedLinks")) return `${this.message.author.mention}, I don't have the \`Embed Links\` permission!`; + if (!this.message.channel.guild) return "This command only works in servers!"; + if (!this.message.member.voiceState.channelID) return "You need to be in a voice channel first!"; + if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!"; + if (!this.message.channel.permissionsOf(this.client.user.id).has("addReactions")) return "I don't have the `Add Reactions` permission!"; + if (!this.message.channel.permissionsOf(this.client.user.id).has("embedLinks")) return "I don't have the `Embed Links` permission!"; const queue = soundPlayer.queues.get(this.message.channel.guild.id); const player = this.connection; const tracks = await fetch(`http://${player.player.node.host}:${player.player.node.port}/decodetracks`, { method: "POST", body: JSON.stringify(queue), headers: { Authorization: player.player.node.password, "Content-Type": "application/json" } }).then(res => res.json()); @@ -53,7 +53,7 @@ class QueueCommand extends MusicCommand { } }); } - if (embeds.length === 0) return `${this.message.author.mention}, there's nothing in the queue!`; + if (embeds.length === 0) return "There's nothing in the queue!"; return paginator(this.client, this.message, embeds); } diff --git a/commands/music/skip.js b/commands/music/skip.js index 4d9e6d0..2f95bba 100644 --- a/commands/music/skip.js +++ b/commands/music/skip.js @@ -5,13 +5,13 @@ class SkipCommand extends MusicCommand { async run() { if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; - if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; - if (!this.message.member.voiceState.channelID) return `${this.message.author.mention}, you need to be in a voice channel first!`; - if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return `${this.message.author.mention}, I'm not in a voice channel!`; + if (!this.message.channel.guild) return "This command only works in servers!"; + if (!this.message.member.voiceState.channelID) return "You need to be in a voice channel first!"; + if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!"; const player = this.connection; if (player.host !== this.message.author.id) { const votes = soundPlayer.skipVotes.has(this.message.channel.guild.id) ? soundPlayer.skipVotes.get(this.message.channel.guild.id) : { count: 0, ids: [] }; - if (votes.ids.includes(this.message.author.id)) return `${this.message.author.mention}, you've already voted to skip!`; + if (votes.ids.includes(this.message.author.id)) return "You've already voted to skip!"; const newObject = { count: votes.count + 1, ids: [...votes.ids, this.message.author.id].filter(item => !!item) diff --git a/commands/music/stop.js b/commands/music/stop.js index b95d27d..bbacdf0 100644 --- a/commands/music/stop.js +++ b/commands/music/stop.js @@ -5,10 +5,10 @@ class StopCommand extends MusicCommand { async run() { if (process.env.NODE_ENV === "production") return "Music commands are coming soon, but they aren't ready yet. Stay tuned to @esmBot_ on Twitter for updates!"; - if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; - if (!this.message.member.voiceState.channelID) return `${this.message.author.mention}, you need to be in a voice channel first!`; - if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return `${this.message.author.mention}, I'm not in a voice channel!`; - if (this.connection.host !== this.message.author.id) return `${this.message.author.mention}, only the current voice session host can stop the music!`; + if (!this.message.channel.guild) return "This command only works in servers!"; + if (!this.message.member.voiceState.channelID) return "You need to be in a voice channel first!"; + if (!this.message.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!"; + if (this.connection.host !== this.message.author.id) return "Only the current voice session host can stop the music!"; soundPlayer.manager.leave(this.message.channel.guild.id); const connection = this.connection.player; connection.destroy(); diff --git a/commands/tags/tags.js b/commands/tags/tags.js index 3e953c0..ae2f7f3 100644 --- a/commands/tags/tags.js +++ b/commands/tags/tags.js @@ -6,42 +6,42 @@ const Command = require("../../classes/command.js"); class TagsCommand extends Command { // todo: find a way to split this into subcommands async run() { - if (!this.message.channel.guild) return `${this.message.author.mention}, this command only works in servers!`; + if (!this.message.channel.guild) return "This command only works in servers!"; const guild = await database.getGuild(this.message.channel.guild.id); if ((guild.tagsDisabled || guild.tags_disabled) && this.args[0].toLowerCase() !== ("enable" || "disable")) return; - if (this.args.length === 0) return `${this.message.author.mention}, you need to specify the name of the tag you want to view!`; + if (this.args.length === 0) return "You need to provide the name of the tag you want to view!"; const tags = guild.tags instanceof Map ? Object.fromEntries(guild.tags) : guild.tags; const blacklist = ["add", "edit", "remove", "delete", "list", "random", "own", "owner", "enable", "disable"]; switch (this.args[0].toLowerCase()) { case "add": - if (this.args[1] === undefined) return `${this.message.author.mention}, you need to provide the name of the tag you want to add!`; - if (blacklist.includes(this.args[1].toLowerCase())) return `${this.message.author.mention}, you can't make a tag with that name!`; - if (tags[this.args[1].toLowerCase()]) return `${this.message.author.mention}, this tag already exists!`; + if (this.args[1] === undefined) return "You need to provide the name of the tag you want to add!"; + if (blacklist.includes(this.args[1].toLowerCase())) return "You can't make a tag with that name!"; + if (tags[this.args[1].toLowerCase()]) return "This tag already exists!"; var result = await this.setTag(this.args.slice(2).join(" "), this.args[1].toLowerCase(), this.message, guild); if (result) return result; - return `${this.message.author.mention}, the tag \`${this.args[1].toLowerCase()}\` has been added!`; + return `The tag \`${this.args[1].toLowerCase()}\` has been added!`; case "delete": case "remove": - if (this.args[1] === undefined) return `${this.message.author.mention}, you need to provide the name of the tag you want to delete!`; - if (!tags[this.args[1].toLowerCase()]) return `${this.message.author.mention}, this tag doesn't exist!`; - if (tags[this.args[1].toLowerCase()].author !== this.message.author.id && !this.message.member.permission.has("manageMessages") && this.message.author.id !== process.env.OWNER) return `${this.message.author.mention}, you don't own this tag!`; + if (this.args[1] === undefined) return "You need to provide the name of the tag you want to delete!"; + if (!tags[this.args[1].toLowerCase()]) return "This tag doesn't exist!"; + if (tags[this.args[1].toLowerCase()].author !== this.message.author.id && !this.message.member.permission.has("manageMessages") && this.message.author.id !== process.env.OWNER) return "You don't own this tag!"; await database.removeTag(this.args[1].toLowerCase(), this.message.channel.guild); - return `${this.message.author.mention}, the tag \`${this.args[1].toLowerCase()}\` has been deleted!`; + return `The tag \`${this.args[1].toLowerCase()}\` has been deleted!`; case "edit": - if (this.args[1] === undefined) return `${this.message.author.mention}, you need to provide the name of the tag you want to edit!`; - if (!tags[this.args[1].toLowerCase()]) return `${this.message.author.mention}, this tag doesn't exist!`; - if (tags[this.args[1].toLowerCase()].author !== this.message.author.id && !this.message.member.permission.has("manageMessages") && this.message.author.id !== process.env.OWNER) return `${this.message.author.mention}, you don't own this tag!`; + if (this.args[1] === undefined) return "You need to provide the name of the tag you want to edit!"; + if (!tags[this.args[1].toLowerCase()]) return "This tag doesn't exist!"; + if (tags[this.args[1].toLowerCase()].author !== this.message.author.id && !this.message.member.permission.has("manageMessages") && this.message.author.id !== process.env.OWNER) return "You don't own this tag!"; await this.setTag(this.args.slice(2).join(" "), this.args[1].toLowerCase(), this.message, guild); - return `${this.message.author.mention}, the tag \`${this.args[1].toLowerCase()}\` has been edited!`; + return `The tag \`${this.args[1].toLowerCase()}\` has been edited!`; case "own": case "owner": - if (this.args[1] === undefined) return `${this.message.author.mention}, you need to provide the name of the tag you want to check the owner of!`; - if (!tags[this.args[1].toLowerCase()]) return `${this.message.author.mention}, this tag doesn't exist!`; - return `${this.message.author.mention}, this tag is owned by **${this.client.users.get(tags[this.args[1].toLowerCase()].author).username}#${this.client.users.get(tags[this.args[1].toLowerCase()].author).discriminator}** (\`${tags[this.args[1].toLowerCase()].author}\`).`; + if (this.args[1] === undefined) return "You need to provide the name of the tag you want to check the owner of!"; + if (!tags[this.args[1].toLowerCase()]) return "This tag doesn't exist!"; + return `This tag is owned by **${this.client.users.get(tags[this.args[1].toLowerCase()].author).username}#${this.client.users.get(tags[this.args[1].toLowerCase()].author).discriminator}** (\`${tags[this.args[1].toLowerCase()].author}\`).`; case "list": - if (!this.message.channel.permissionsOf(this.client.user.id).has("addReactions")) return `${this.message.author.mention}, I don't have the \`Add Reactions\` permission!`; - if (!this.message.channel.permissionsOf(this.client.user.id).has("embedLinks")) return `${this.message.author.mention}, I don't have the \`Embed Links\` permission!`; + if (!this.message.channel.permissionsOf(this.client.user.id).has("addReactions")) return "I don't have the `Add Reactions` permission!"; + if (!this.message.channel.permissionsOf(this.client.user.id).has("embedLinks")) return "I don't have the `Embed Links` permission!"; var pageSize = 15; var embeds = []; var groups = Object.keys(tags).map((item, index) => { @@ -66,23 +66,23 @@ class TagsCommand extends Command { } }); } - if (embeds.length === 0) return `${this.message.author.mention}, I couldn't find any tags!`; + if (embeds.length === 0) return "I couldn't find any tags!"; return paginator(this.client, this.message, embeds); case "random": return tags[random(Object.keys(tags))].content; case "enable": case "disable": - if (!this.message.member.permission.has("manageMessages") && this.message.author.id !== process.env.OWNER) return `${this.message.author.mention}, you don't have permission to disable tags!`; + if (!this.message.member.permission.has("manageMessages") && this.message.author.id !== process.env.OWNER) return "You don't have permission to disable tags!"; var toggleResult = await database.toggleTags(this.message.channel.guild); - return `${this.message.author.mention}, tags for this guild have been ${toggleResult ? "disabled" : "enabled"}. To ${toggleResult ? "enable" : "disable"} them again, run ${guild.prefix}tags ${toggleResult ? "enable" : "disable"}.`; + return `Tags for this guild have been ${toggleResult ? "disabled" : "enabled"}. To ${toggleResult ? "enable" : "disable"} them again, run ${guild.prefix}tags ${toggleResult ? "enable" : "disable"}.`; default: - if (!tags[this.args[0].toLowerCase()]) return `${this.message.author.mention}, this tag doesn't exist!`; + if (!tags[this.args[0].toLowerCase()]) return "This tag doesn't exist!"; return tags[this.args[0].toLowerCase()].content; } } async setTag(content, name, message) { - if ((!content || content.length === 0) && message.attachments.length === 0) return `${message.author.mention}, you need to provide the content of the tag!`; + if ((!content || content.length === 0) && message.attachments.length === 0) return "You need to provide the content of the tag!"; if (message.attachments.length !== 0 && content) { await database.setTag(name, { content: `${content} ${message.attachments[0].url}`, author: message.author.id }, message.channel.guild); } else if (message.attachments.length !== 0) { diff --git a/events/messageCreate.js b/events/messageCreate.js index 0b6d310..b3f8d66 100644 --- a/events/messageCreate.js +++ b/events/messageCreate.js @@ -82,19 +82,36 @@ module.exports = async (client, cluster, ipc, message) => { // actually run the command logger.log("log", `${message.author.username} (${message.author.id}) ran command ${command}`); + const reference = { + messageReference: { + channelID: message.channel.id, + messageID: message.id, + guildID: message.channel.guild ? message.channel.guild.id : undefined, + failIfNotExists: false + }, + allowedMentions: { + repliedUser: false + } + }; try { await database.addCount(collections.aliases.has(command) ? collections.aliases.get(command) : command); const startTime = new Date(); const commandClass = new cmd(client, cluster, ipc, message, args, message.content.substring(prefix.length).trim().replace(command, "").trim()); const result = await commandClass.run(); // we also provide the message content as a parameter for cases where we need more accuracy const endTime = new Date(); - if (typeof result === "string" || (typeof result === "object" && result.embed)) { - await client.createMessage(message.channel.id, result); + if ((endTime - startTime) >= 180000) reference.allowedMentions.repliedUser = true; + if (typeof result === "string") { + reference.allowedMentions.repliedUser = true; + await client.createMessage(message.channel.id, Object.assign({ + content: result + }, reference)); + } else if (typeof result === "object" && result.embed) { + await client.createMessage(message.channel.id, Object.assign(result, reference)); } else if (typeof result === "object" && result.file) { if (result.file.length > 8388119 && process.env.TEMPDIR !== "") { const filename = `${Math.random().toString(36).substring(2, 15)}.${result.name.split(".")[1]}`; await fs.promises.writeFile(`${process.env.TEMPDIR}/${filename}`, result.file); - await client.createMessage(message.channel.id, { + await client.createMessage(message.channel.id, Object.assign({ embed: { color: 16711680, title: "Here's your image!", @@ -105,24 +122,33 @@ module.exports = async (client, cluster, ipc, message) => { footer: { text: "The result image was more than 8MB in size, so it was uploaded to an external site instead." }, - }, - content: (endTime - startTime) >= 180000 ? message.author.mention : undefined - }); + } + }, reference)); } else { - await client.createMessage(message.channel.id, result.text ? result.text : ((endTime - startTime) >= 180000 ? message.author.mention : undefined), result); + await client.createMessage(message.channel.id, Object.assign({ + content: result.text ? result.text : undefined + }, reference), result); } } } catch (error) { if (error.toString().includes("Request entity too large")) { - await client.createMessage(message.channel.id, `${message.author.mention}, the resulting file was too large to upload. Try again with a smaller image if possible.`); - } else if (error.toString().includes("UDP timed out")) { - await client.createMessage(message.channel.id, `${message.author.mention}, I couldn't contact the image API in time (most likely due to it being overloaded). Try running your command again.`); + await client.createMessage(message.channel.id, Object.assign({ + content: "The resulting file was too large to upload. Try again with a smaller image if possible." + }, reference)); + } else if (error.toString().includes("Job ended prematurely")) { + await client.createMessage(message.channel.id, Object.assign({ + content: "Something happened to the image servers before I could receive the image. Try running your command again." + }, reference)); } else if (error.toString().includes("Timed out")) { - await client.createMessage(message.channel.id, `${message.author.mention}, the request timed out before I could download that image. Try uploading your image somewhere else.`); + await client.createMessage(message.channel.id, Object.assign({ + content: "The request timed out before I could download that image. Try uploading your image somewhere else or reducing its size." + }, reference)); } else { logger.error(error.toString()); try { - await client.createMessage(message.channel.id, "Uh oh! I ran into an error while running this command. Please report the content of the attached file here or on the esmBot Support server: ", [{ + await client.createMessage(message.channel.id, Object.assign({ + content: "Uh oh! I ran into an error while running this command. Please report the content of the attached file at the following link or on the esmBot Support server: " + }, reference), [{ file: `Message: ${error}\n\nStack Trace: ${error.stack}`, name: "error.txt" }]); diff --git a/shard.js b/shard.js index edff310..3e4443b 100644 --- a/shard.js +++ b/shard.js @@ -132,17 +132,16 @@ connected_workers ${image.connections.length} } async launch() { - try { - await this.init(); - } catch { - logger.error("Might have failed to register some things"); - } + await this.init(); this.ipc.register("stat", (message) => { collections.stats = message; }); - this.ipc.register("restart", () => { + this.ipc.register("restart", async () => { + await this.bot.editStatus("dnd", { + name: "Restarting/shutting down..." + }); process.exit(1); }); diff --git a/utils/pagination/pagination.js b/utils/pagination/pagination.js index c1d485e..e50bf10 100644 --- a/utils/pagination/pagination.js +++ b/utils/pagination/pagination.js @@ -4,7 +4,17 @@ const MessageCollector = require("./awaitmessages.js"); module.exports = async (client, message, pages, timeout = 120000) => { const manageMessages = message.channel.guild && message.channel.permissionsOf(client.user.id).has("manageMessages") ? true : false; let page = 0; - let currentPage = await client.createMessage(message.channel.id, pages[page]); + let currentPage = await client.createMessage(message.channel.id, Object.assign(pages[page], { + messageReference: { + channelID: message.channel.id, + messageID: message.id, + guildID: message.channel.guild ? message.channel.guild.id : undefined, + failIfNotExists: false + }, + allowedMentions: { + repliedUser: false + } + })); const emojiList = ["◀", "🔢", "▶", "🗑"]; for (const emoji of emojiList) { await currentPage.addReaction(emoji); @@ -19,7 +29,17 @@ module.exports = async (client, message, pages, timeout = 120000) => { if (manageMessages) msg.removeReaction("◀", member.id); break; case "🔢": - client.createMessage(message.channel.id, `${message.author.mention}, what page do you want to jump to?`).then(askMessage => { + client.createMessage(message.channel.id, Object.assign({ content: "What page do you want to jump to?" }, { + messageReference: { + channelID: currentPage.channel.id, + messageID: currentPage.id, + guildID: currentPage.channel.guild ? currentPage.channel.guild.id : undefined, + failIfNotExists: false + }, + allowedMentions: { + repliedUser: false + } + })).then(askMessage => { const messageCollector = new MessageCollector(client, askMessage.channel, (response) => response.author.id === message.author.id && !isNaN(response.content) && Number(response.content) <= pages.length && Number(response.content) > 0, { time: timeout, maxMatches: 1 diff --git a/utils/soundplayer.js b/utils/soundplayer.js index 487e31b..002c368 100644 --- a/utils/soundplayer.js +++ b/utils/soundplayer.js @@ -53,21 +53,21 @@ exports.connect = async (client) => { }; exports.play = async (client, sound, message, music = false) => { - if (!this.manager) return `${message.author.mention}, the sound commands are still starting up!`; - if (!message.channel.guild) return `${message.author.mention}, this command only works in servers!`; - if (!message.member.voiceState.channelID) return `${message.author.mention}, you need to be in a voice channel first!`; - if (!message.channel.permissionsOf(client.user.id).has("voiceConnect")) return `${message.author.mention}, I can't join this voice channel!`; + if (!this.manager) return "The sound commands are still starting up!"; + if (!message.channel.guild) return "This command only works in servers!"; + if (!message.member.voiceState.channelID) return "You need to be in a voice channel first!"; + if (!message.channel.permissionsOf(client.user.id).has("voiceConnect")) return "I can't join this voice channel!"; const voiceChannel = message.channel.guild.channels.get(message.member.voiceState.channelID); - if (!voiceChannel.permissionsOf(client.user.id).has("voiceConnect")) return `${message.author.mention}, I don't have permission to join this voice channel!`; + if (!voiceChannel.permissionsOf(client.user.id).has("voiceConnect")) return "I don't have permission to join this voice channel!"; const player = this.players.get(message.channel.guild.id); - if (!music && this.manager.voiceStates.has(message.channel.guild.id) && (player && player.type === "music")) return `${message.author.mention}, I can't play a sound effect while playing music!`; + if (!music && this.manager.voiceStates.has(message.channel.guild.id) && (player && player.type === "music")) return "I can't play a sound effect while playing music!"; const node = this.manager.idealNodes[0]; if (!music && !nodes.filter(obj => obj.host === node.host)[0].local) { sound = sound.replace(/\.\//, "https://raw.githubusercontent.com/esmBot/esmBot/master/"); } const { tracks } = await fetch(`http://${node.host}:${node.port}/loadtracks?identifier=${sound}`, { headers: { Authorization: node.password } }).then(res => res.json()); const oldQueue = this.queues.get(voiceChannel.guild.id); - if (!tracks || tracks.length === 0) return `${message.author.mention}, I couldn't find that song!`; + if (!tracks || tracks.length === 0) return "I couldn't find that song!"; if (music) { this.queues.set(voiceChannel.guild.id, oldQueue ? [...oldQueue, tracks[0].track] : [tracks[0].track]); } @@ -83,7 +83,7 @@ exports.play = async (client, sound, message, music = false) => { } if (oldQueue && music) { - return `${message.author.mention}, your tune \`${tracks[0].info.title}\` has been added to the queue!`; + return `Your tune \`${tracks[0].info.title}\` has been added to the queue!`; } else { this.nextSong(client, message, connection, tracks[0].track, tracks[0].info, music, voiceChannel, player ? player.loop : false); return;