diff --git a/commands/general/emote.js b/commands/general/emote.js new file mode 100644 index 0000000..34afce8 --- /dev/null +++ b/commands/general/emote.js @@ -0,0 +1,33 @@ +import emojiRegex from "emoji-regex"; +import Command from "../../classes/command.js"; + +class EmoteCommand extends Command { + async run() { + const emoji = this.options.emoji ?? this.content; + if (emoji && emoji.trim() && emoji.split(" ")[0].match(/^$/)) { + return `https://cdn.discordapp.com/emojis/${emoji.split(" ")[0].replace(/^<(a)?:.+:(\d+)>$/, "$2")}.${emoji.split(" ")[0].replace(/^<(a)?:.+:(\d+)>$/, "$1") === "a" ? "gif" : "png"}`; + } else if (emoji.match(emojiRegex())) { + const codePoints = []; + for (const codePoint of emoji) { + codePoints.push(codePoint.codePointAt(0).toString(16)); + } + return `https://twemoji.maxcdn.com/v/latest/72x72/${codePoints.join("-").replace("-fe0f", "")}.png`; + } else { + this.success = false; + return "You need to provide a valid emoji to get an image!"; + } + } + + static flags = [{ + name: "emoji", + type: 3, + description: "The emoji you want to get", + required: true + }]; + + static description = "Gets a raw emote image"; + static aliases = ["e", "em", "hugemoji", "hugeemoji", "emoji"]; + static arguments = ["[emote]"]; +} + +export default EmoteCommand; diff --git a/commands/general/help.js b/commands/general/help.js index 20ac6e8..859442b 100644 --- a/commands/general/help.js +++ b/commands/general/help.js @@ -9,7 +9,7 @@ import Command from "../../classes/command.js"; class HelpCommand extends Command { async run() { - return { html: "

There are no mrmBot Docs Yet

In the meantime, please refer to https://esmbot.net/help.html" }; + return "https://esmbot.net/help.html" } diff --git a/commands/general/info.js b/commands/general/info.js index 33ac39d..746a11e 100644 --- a/commands/general/info.js +++ b/commands/general/info.js @@ -5,8 +5,49 @@ import { getServers } from "../../utils/misc.js"; class InfoCommand extends Command { async run() { + let owner = this.client.users.get(process.env.OWNER.split(",")[0]); + if (!owner) owner = await this.client.rest.users.get(process.env.OWNER.split(",")[0]); + const servers = await getServers(this.client); // await this.acknowledge(); - return { html: `

mrmBot Info/Credits

This instance is managed by ${process.env.OWNER.split(",")[0]}.
v${version}-mrm (${process.env.GIT_REV})
Bot by Essem and other contributors.
Fork by Murm.` }; + return { + embeds: [{ + color: 16711680, + author: { + name: "esmBot Info/Credits", + iconURL: this.client.user.avatarURL() + }, + description: `This instance is managed by **${owner.username}#${owner.discriminator}**.`, + fields: [{ + name: "â„šī¸ Version:", + value: `v${version}${process.env.NODE_ENV === "development" ? `-dev (${process.env.GIT_REV})` : ""}` + }, + { + name: "📝 Credits:", + value: "Bot by **[Essem](https://essem.space)** and **[various contributors](https://github.com/esmBot/esmBot/graphs/contributors)**\nLogo by **[MintBurrow](https://twitter.com/MintBurrow)**" + }, + { + name: "đŸ’Ŧ Total Servers:", + value: servers ? servers : `${this.client.guilds.size} (for this process only)` + }, + { + name: "✅ Official Server:", + value: "[Click here!](https://esmbot.net/support)" + }, + { + name: "đŸ’ģ Source Code:", + value: "[Click here!](https://github.com/esmBot/esmBot)" + }, + { + name: "đŸ›Ąī¸ Privacy Policy:", + value: "[Click here!](https://esmbot.net/privacy.html)" + }, + { + name: "🐘 Mastodon:", + value: "[Click here!](https://wetdry.world/@esmBot)" + } + ] + }] + }; } static description = "Gets some info and credits about me"; diff --git a/commands/general/reload.js b/commands/general/reload.js index 140bec4..5f382cd 100644 --- a/commands/general/reload.js +++ b/commands/general/reload.js @@ -22,7 +22,7 @@ class ReloadCommand extends Command { } }); } - return{ html: `The command ${commandName} has been reloaded.` }; + return `The command \`${commandName}\` has been reloaded.`; } static flags = [{ diff --git a/commands/general/snowflake.js b/commands/general/snowflake.js new file mode 100644 index 0000000..0bd7c74 --- /dev/null +++ b/commands/general/snowflake.js @@ -0,0 +1,20 @@ +import Command from "../../classes/command.js"; + +class SnowflakeCommand extends Command { + async run() { + this.success = false; + if (!this.args[0]) return "You need to provide a snowflake ID!"; + if (!this.args[0].match(/^?$/) && this.args[0] < 21154535154122752n) return "That's not a valid snowflake!"; + const id = Math.floor(((this.args[0].replaceAll("@", "").replaceAll("#", "").replaceAll("!", "").replaceAll("&", "").replaceAll("<", "").replaceAll(">", "") / 4194304) + 1420070400000) / 1000); + if (isNaN(id)) return "That's not a valid snowflake!"; + this.success = true; + return ``; + } + + static description = "Converts a Discord snowflake id into a timestamp"; + static aliases = ["timestamp", "snowstamp", "snow"]; + static arguments = ["[id]"]; + static slashAllowed = false; +} + +export default SnowflakeCommand; diff --git a/commands/general/soundreload.js b/commands/general/soundreload.js new file mode 100644 index 0000000..84f48e0 --- /dev/null +++ b/commands/general/soundreload.js @@ -0,0 +1,33 @@ +import Command from "../../classes/command.js"; +import { reload } from "../../utils/soundplayer.js"; + +class SoundReloadCommand extends Command { + async run() { + const owners = process.env.OWNER.split(","); + if (!owners.includes(this.author)) { + this.success = false; + return "Only the bot owner can reload Lavalink!"; + } + // await this.acknowledge(); + const length = await reload(); + if (process.env.PM2_USAGE) { + process.send({ + type: "process:msg", + data: { + type: "soundreload" + } + }); + } + if (length) { + return `Successfully connected to ${length} Lavalink node(s).`; + } else { + return "I couldn't connect to any Lavalink nodes!"; + } + } + + static description = "Attempts to reconnect to all available Lavalink nodes"; + static aliases = ["lava", "lavalink", "lavaconnect", "soundconnect"]; + static adminOnly = true; +} + +export default SoundReloadCommand; \ No newline at end of file diff --git a/commands/general/stats.js.disabled b/commands/general/stats.js similarity index 100% rename from commands/general/stats.js.disabled rename to commands/general/stats.js diff --git a/commands/general/sticker.js b/commands/general/sticker.js new file mode 100644 index 0000000..4aece70 --- /dev/null +++ b/commands/general/sticker.js @@ -0,0 +1,36 @@ +import Command from "../../classes/command.js"; +import imagedetect from "../../utils/imagedetect.js"; + +class StickerCommand extends Command { + async run() { + const result = await imagedetect(this.client, this.message, this.interaction, this.options, false, false, true); + this.success = false; + if (!result) return "You need to provide a sticker!"; + if (result.format_type === 1) { // PNG + this.success = true; + return `https://cdn.discordapp.com/stickers/${result.id}.png`; + } else if (result.format_type === 2) { // APNG + this.success = true; + return { + embeds: [{ + color: 16711680, + description: `[This sticker is an APNG; however, since Discord doesn't allow displaying APNGs outside of stickers, you'll have to save it or open it in your browser to view it.](https://cdn.discordapp.com/stickers/${result.id}.png)`, + image: { + url: `https://cdn.discordapp.com/stickers/${result.id}.png` + } + }] + }; + } else if (result.format_type === 3) { // Lottie + this.success = true; + return `I can't display this sticker because it uses the Lottie animation format; however, I can give you the raw JSON link to it: https://cdn.discordapp.com/stickers/${result.id}.json`; + } else { + return "I don't recognize that sticker format!"; + } + } + + static description = "Gets a raw sticker image"; + static aliases = ["stick"]; + static arguments = ["[sticker]"]; +} + +export default StickerCommand; \ No newline at end of file