Added (hacky) message command support, lots of work to prepare for message content intent enforcement, improve broadcast, remove evalraw, update packages
This commit is contained in:
parent
3392c3c89e
commit
d33a7804d7
56 changed files with 443 additions and 315 deletions
|
@ -8,11 +8,15 @@ class AvatarCommand extends Command {
|
|||
if (this.type === "classic" && this.message.mentions[0]) {
|
||||
return this.message.mentions[0].dynamicAvatarURL(null, 512);
|
||||
} else if (await this.ipc.fetchUser(member)) {
|
||||
const user = await this.ipc.fetchUser(member);
|
||||
return user.avatar ? this.client._formatImage(`/avatars/${user.id}/${user.avatar}`, null, 512) : `https://cdn.discordapp.com/embed/avatars/${user.discriminator % 5}.png`; // hacky "solution"
|
||||
let user = await this.ipc.fetchUser(member);
|
||||
if (!user) user = await this.client.getRESTUser(member);
|
||||
return user?.avatar ? this.client._formatImage(`/avatars/${user.id}/${user.avatar}`, null, 512) : `https://cdn.discordapp.com/embed/avatars/${user.discriminator % 5}.png`; // hacky "solution"
|
||||
} else if (mentionRegex.test(member)) {
|
||||
const id = member.match(mentionRegex)[1];
|
||||
if (id < 21154535154122752n) return "That's not a valid mention!";
|
||||
if (id < 21154535154122752n) {
|
||||
this.success = false;
|
||||
return "That's not a valid mention!";
|
||||
}
|
||||
try {
|
||||
const user = await this.client.getRESTUser(id);
|
||||
return user.avatar ? this.client._formatImage(`/avatars/${user.id}/${user.avatar}`, null, 512) : `https://cdn.discordapp.com/embed/avatars/${user.discriminator % 5}.png`; // repeat of hacky "solution" from above
|
||||
|
|
|
@ -12,7 +12,10 @@ class BannerCommand extends Command {
|
|||
return user.dynamicBannerURL(null, 512) ?? "This user doesn't have a banner!";
|
||||
} else if (mentionRegex.test(member)) {
|
||||
const id = member.match(mentionRegex)[1];
|
||||
if (id < 21154535154122752n) return "That's not a valid mention!";
|
||||
if (id < 21154535154122752n) {
|
||||
this.success = false;
|
||||
return "That's not a valid mention!";
|
||||
}
|
||||
try {
|
||||
const user = await this.client.getRESTUser(id);
|
||||
return user.dynamicBannerURL(null, 512) ?? "This user doesn't have a banner!";
|
||||
|
|
|
@ -3,11 +3,13 @@ import { clean } from "../../utils/misc.js";
|
|||
|
||||
class Base64Command extends Command {
|
||||
async run() {
|
||||
this.success = false;
|
||||
if (this.type === "classic" && this.args.length === 0) return "You need to provide whether you want to encode or decode the text!";
|
||||
const command = this.type === "classic" ? this.args[0].toLowerCase() : this.optionsArray[0].name.toLowerCase();
|
||||
if (command !== "decode" && command !== "encode") return "You need to provide whether you want to encode or decode the text!";
|
||||
const string = this.options.text ?? this.args.slice(1).join(" ");
|
||||
if (!string || !string.trim()) return `You need to provide a string to ${command}!`;
|
||||
this.success = true;
|
||||
if (command === "decode") {
|
||||
const b64Decoded = Buffer.from(string, "base64").toString("utf8");
|
||||
return `\`\`\`\n${await clean(b64Decoded)}\`\`\``;
|
||||
|
|
|
@ -5,15 +5,20 @@ class BroadcastCommand extends Command {
|
|||
run() {
|
||||
return new Promise((resolve) => {
|
||||
const owners = process.env.OWNER.split(",");
|
||||
if (!owners.includes(this.author.id)) return "Only the bot owner can broadcast messages!";
|
||||
if (!owners.includes(this.author.id)) {
|
||||
this.success = false;
|
||||
resolve("Only the bot owner can broadcast messages!");
|
||||
}
|
||||
const message = this.options.message ?? this.args.join(" ");
|
||||
if (message?.trim()) {
|
||||
this.ipc.centralStore.set("broadcast", message);
|
||||
this.ipc.broadcast("playbroadcast", message);
|
||||
this.ipc.register("broadcastSuccess", () => {
|
||||
this.ipc.unregister("broadcastSuccess");
|
||||
resolve("Successfully broadcasted message.");
|
||||
});
|
||||
} else {
|
||||
this.ipc.centralStore.delete("broadcast");
|
||||
this.ipc.broadcast("broadcastend");
|
||||
this.ipc.register("broadcastEnd", () => {
|
||||
this.ipc.unregister("broadcastEnd");
|
||||
|
|
|
@ -3,6 +3,7 @@ import Command from "../../classes/command.js";
|
|||
|
||||
class ChannelCommand extends Command {
|
||||
async run() {
|
||||
this.success = false;
|
||||
if (!this.channel.guild) return "This command only works in servers!";
|
||||
const owners = process.env.OWNER.split(",");
|
||||
if (!this.member.permissions.has("administrator") && !owners.includes(this.member.id)) return "You need to be an administrator to enable/disable me!";
|
||||
|
@ -23,6 +24,7 @@ class ChannelCommand extends Command {
|
|||
}
|
||||
|
||||
await db.disableChannel(channel);
|
||||
this.success = true;
|
||||
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;
|
||||
|
@ -36,11 +38,12 @@ class ChannelCommand extends Command {
|
|||
}
|
||||
|
||||
await db.enableChannel(channel);
|
||||
this.success = true;
|
||||
return "I have been re-enabled in this channel.";
|
||||
}
|
||||
}
|
||||
|
||||
static description = "Enables/disables me in a channel (does not work with slash commands)";
|
||||
static description = "Enables/disables classic commands in a channel (use server settings for slash commands)";
|
||||
static arguments = ["[enable/disable]", "{id}"];
|
||||
static slashAllowed = false;
|
||||
static directAllowed = false;
|
||||
|
|
|
@ -4,6 +4,7 @@ import * as collections from "../../utils/collections.js";
|
|||
|
||||
class CommandCommand extends Command {
|
||||
async run() {
|
||||
this.success = false;
|
||||
if (!this.channel.guild) return "This command only works in servers!";
|
||||
const owners = process.env.OWNER.split(",");
|
||||
if (!this.member.permissions.has("administrator") && !owners.includes(this.member.id)) return "You need to be an administrator to enable/disable me!";
|
||||
|
@ -21,16 +22,18 @@ class CommandCommand extends Command {
|
|||
if (disabled?.includes(command)) return "That command is already disabled!";
|
||||
|
||||
await db.disableCommand(this.channel.guild.id, command);
|
||||
this.success = true;
|
||||
return `The command has been disabled. To re-enable it, just run \`${guildDB.prefix}command enable ${command}\`.`;
|
||||
} else if (this.args[0].toLowerCase() === "enable") {
|
||||
if (!disabled?.includes(command)) return "That command isn't disabled!";
|
||||
|
||||
await db.enableCommand(this.channel.guild.id, command);
|
||||
this.success = true;
|
||||
return `The command \`${command}\` has been re-enabled.`;
|
||||
}
|
||||
}
|
||||
|
||||
static description = "Enables/disables a command for a server";
|
||||
static description = "Enables/disables a classic command for a server (use server settings for slash commands)";
|
||||
static aliases = ["cmd"];
|
||||
static arguments = ["[enable/disable]", "[command]"];
|
||||
static slashAllowed = false;
|
||||
|
|
|
@ -4,7 +4,10 @@ import Command from "../../classes/command.js";
|
|||
|
||||
class CountCommand extends Command {
|
||||
async run() {
|
||||
if (this.channel.guild && !this.channel.permissionsOf(this.client.user.id).has("embedLinks")) return "I don't have the `Embed Links` permission!";
|
||||
if (this.channel.guild && !this.channel.permissionsOf(this.client.user.id).has("embedLinks")) {
|
||||
this.success = false;
|
||||
return "I don't have the `Embed Links` permission!";
|
||||
}
|
||||
const counts = await database.getCounts();
|
||||
const countArray = [];
|
||||
for (const entry of Object.entries(counts)) {
|
||||
|
|
|
@ -4,8 +4,7 @@ import Command from "../../classes/command.js";
|
|||
class EmoteCommand extends Command {
|
||||
async run() {
|
||||
const emoji = this.options.emoji ?? this.content;
|
||||
if (!emoji || !emoji.trim()) return "You need to provide an emoji!";
|
||||
if (emoji.split(" ")[0].match(/^<a?:.+:\d+>$/)) {
|
||||
if (emoji && emoji.trim() && emoji.split(" ")[0].match(/^<a?:.+:\d+>$/)) {
|
||||
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 = [];
|
||||
|
@ -14,6 +13,7 @@ class EmoteCommand extends Command {
|
|||
}
|
||||
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!";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,10 @@ import Command from "../../classes/command.js";
|
|||
class EvalCommand extends Command {
|
||||
async run() {
|
||||
const owners = process.env.OWNER.split(",");
|
||||
if (!owners.includes(this.author.id)) return "Only the bot owner can use eval!";
|
||||
if (!owners.includes(this.author.id)) {
|
||||
this.success = false;
|
||||
return "Only the bot owner can use eval!";
|
||||
}
|
||||
await this.acknowledge();
|
||||
const code = this.options.code ?? this.args.join(" ");
|
||||
try {
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
import { clean } from "../../utils/misc.js";
|
||||
import Command from "../../classes/command.js";
|
||||
|
||||
class EvalRawCommand extends Command {
|
||||
async run() {
|
||||
const owners = process.env.OWNER.split(",");
|
||||
if (!owners.includes(this.author.id)) return "Only the bot owner can use evalraw!";
|
||||
const code = this.args.join(" ");
|
||||
try {
|
||||
const evaled = eval(code);
|
||||
if (evaled.length >= 2000) {
|
||||
return {
|
||||
text: "The result was too large, so here it is as a file:",
|
||||
file: evaled,
|
||||
name: "result.txt"
|
||||
};
|
||||
} else {
|
||||
return evaled;
|
||||
}
|
||||
} catch (err) {
|
||||
return `\`ERROR\` \`\`\`xl\n${await clean(err)}\n\`\`\``;
|
||||
}
|
||||
}
|
||||
|
||||
static description = "Executes JavaScript code (with raw output)";
|
||||
static aliases = ["run"];
|
||||
static arguments = ["[code]"];
|
||||
static slashAllowed = false;
|
||||
}
|
||||
|
||||
export default EvalRawCommand;
|
|
@ -7,7 +7,10 @@ import Command from "../../classes/command.js";
|
|||
class ExecCommand extends Command {
|
||||
async run() {
|
||||
const owners = process.env.OWNER.split(",");
|
||||
if (!owners.includes(this.author.id)) return "Only the bot owner can use exec!";
|
||||
if (!owners.includes(this.author.id)) {
|
||||
this.success = false;
|
||||
return "Only the bot owner can use exec!";
|
||||
}
|
||||
await this.acknowledge();
|
||||
const code = this.options.cmd ?? this.args.join(" ");
|
||||
try {
|
||||
|
|
|
@ -54,7 +54,10 @@ class HelpCommand extends Command {
|
|||
}
|
||||
return embed;
|
||||
} else {
|
||||
if (this.channel.guild && !this.channel.permissionsOf(this.client.user.id).has("embedLinks")) return "I don't have the `Embed Links` permission!";
|
||||
if (this.channel.guild && !this.channel.permissionsOf(this.client.user.id).has("embedLinks")) {
|
||||
this.success = false;
|
||||
return "I don't have the `Embed Links` permission!";
|
||||
}
|
||||
const pages = [];
|
||||
if (help.categories === help.categoryTemplate && !help.generated) await help.generateList();
|
||||
for (const category of Object.keys(help.categories)) {
|
||||
|
|
|
@ -7,6 +7,7 @@ import Command from "../../classes/command.js";
|
|||
|
||||
class ImageSearchCommand extends Command {
|
||||
async run() {
|
||||
this.success = false;
|
||||
if (this.channel.guild && !this.channel.permissionsOf(this.client.user.id).has("embedLinks")) return "I don't have the `Embed Links` permission!";
|
||||
const query = this.options.query ?? this.args.join(" ");
|
||||
if (!query || !query.trim()) return "You need to provide something to search for!";
|
||||
|
@ -34,6 +35,7 @@ class ImageSearchCommand extends Command {
|
|||
}]
|
||||
});
|
||||
}
|
||||
this.success = true;
|
||||
return paginator(this.client, { type: this.type, message: this.message, interaction: this.interaction, channel: this.channel, author: this.author }, embeds);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,10 @@ import Command from "../../classes/command.js";
|
|||
class ImageReloadCommand extends Command {
|
||||
async run() {
|
||||
const owners = process.env.OWNER.split(",");
|
||||
if (!owners.includes(this.author.id)) return "Only the bot owner can reload the image servers!";
|
||||
if (!owners.includes(this.author.id)) {
|
||||
this.success = false;
|
||||
return "Only the bot owner can reload the image servers!";
|
||||
}
|
||||
const amount = await this.ipc.serviceCommand("image", { type: "reload" }, true);
|
||||
if (amount > 0) {
|
||||
return `Successfully connected to ${amount} image servers.`;
|
||||
|
|
|
@ -6,9 +6,11 @@ class LengthenCommand extends Command {
|
|||
async run() {
|
||||
await this.acknowledge();
|
||||
const input = this.options.url ?? this.args.join(" ");
|
||||
this.success = false;
|
||||
if (!input || !input.trim() || !urlCheck(input)) return "You need to provide a short URL to lengthen!";
|
||||
if (urlCheck(input)) {
|
||||
const url = await request(encodeURI(input), { method: "HEAD" });
|
||||
this.success = true;
|
||||
return url.headers.location || input;
|
||||
} else {
|
||||
return "That isn't a URL!";
|
||||
|
|
|
@ -7,7 +7,10 @@ class PrefixCommand extends Command {
|
|||
const guild = await database.getGuild(this.channel.guild.id);
|
||||
if (this.args.length !== 0) {
|
||||
const owners = process.env.OWNER.split(",");
|
||||
if (!this.member.permissions.has("administrator") && !owners.includes(this.member.id)) return "You need to be an administrator to change the bot prefix!";
|
||||
if (!this.member.permissions.has("administrator") && !owners.includes(this.member.id)) {
|
||||
this.success = false;
|
||||
return "You need to be an administrator to change the bot prefix!";
|
||||
}
|
||||
await database.setPrefix(this.args[0], this.channel.guild);
|
||||
return `The prefix has been changed to ${this.args[0]}.`;
|
||||
} else {
|
||||
|
|
|
@ -4,7 +4,10 @@ import Command from "../../classes/command.js";
|
|||
|
||||
class QrCreateCommand extends Command {
|
||||
async run() {
|
||||
if (this.args.length === 0) return "You need to provide some text to generate a QR code!";
|
||||
if (this.args.length === 0) {
|
||||
this.success = false;
|
||||
return "You need to provide some text to generate a QR code!";
|
||||
}
|
||||
await this.acknowledge();
|
||||
const writable = new PassThrough();
|
||||
qrcode.toFileStream(writable, this.content, { margin: 1 });
|
||||
|
|
|
@ -8,12 +8,14 @@ import imageDetect from "../../utils/imagedetect.js";
|
|||
class QrReadCommand extends Command {
|
||||
async run() {
|
||||
const image = await imageDetect(this.client, this.message, this.interaction, this.options);
|
||||
this.success = false;
|
||||
if (image === undefined) return "You need to provide an image/GIF with a QR code to read!";
|
||||
await this.acknowledge();
|
||||
const data = Buffer.from(await (await request(image.path)).body.arrayBuffer());
|
||||
const rawData = await sharp(data).ensureAlpha().raw().toBuffer({ resolveWithObject: true });
|
||||
const qrBuffer = jsqr(rawData.data, rawData.info.width, rawData.info.height);
|
||||
if (!qrBuffer) return "I couldn't find a QR code!";
|
||||
this.success = true;
|
||||
return `\`\`\`\n${await clean(qrBuffer.data)}\n\`\`\``;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,10 @@ class RawCommand extends Command {
|
|||
async run() {
|
||||
await this.acknowledge();
|
||||
const image = await imageDetect(this.client, this.message, this.interaction, this.options);
|
||||
if (image === undefined) return "You need to provide an image/GIF to get a raw URL!";
|
||||
if (image === undefined) {
|
||||
this.success = false;
|
||||
return "You need to provide an image/GIF to get a raw URL!";
|
||||
}
|
||||
return image.path;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,10 @@ import Command from "../../classes/command.js";
|
|||
class RestartCommand extends Command {
|
||||
async run() {
|
||||
const owners = process.env.OWNER.split(",");
|
||||
if (!owners.includes(this.author.id)) return "Only the bot owner can restart me!";
|
||||
if (!owners.includes(this.author.id)) {
|
||||
this.success = false;
|
||||
return "Only the bot owner can restart me!";
|
||||
}
|
||||
await this.client.createMessage(this.channel.id, Object.assign({
|
||||
content: "esmBot is restarting."
|
||||
}, this.reference));
|
||||
|
|
|
@ -2,7 +2,10 @@ import Command from "../../classes/command.js";
|
|||
|
||||
class ServerInfoCommand extends Command {
|
||||
async run() {
|
||||
if (!this.channel.guild) return "This command only works in servers!";
|
||||
if (!this.channel.guild) {
|
||||
this.success = false;
|
||||
return "This command only works in servers!";
|
||||
}
|
||||
const owner = await this.channel.guild.members.get(this.channel.guild.ownerID);
|
||||
return {
|
||||
embeds: [{
|
||||
|
|
|
@ -2,8 +2,10 @@ 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(/^<?[@#]?[&!]?\d+>?$/) && this.args[0] < 21154535154122752n) return "That's not a valid snowflake!";
|
||||
this.success = true;
|
||||
return `<t:${Math.floor(((this.args[0].replaceAll("@", "").replaceAll("#", "").replaceAll("!", "").replaceAll("&", "").replaceAll("<", "").replaceAll(">", "") / 4194304) + 1420070400000) / 1000)}:F>`;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,10 @@ class SoundReloadCommand extends Command {
|
|||
run() {
|
||||
return new Promise((resolve) => {
|
||||
const owners = process.env.OWNER.split(",");
|
||||
if (!owners.includes(this.author.id)) return "Only the bot owner can reload Lavalink!";
|
||||
if (!owners.includes(this.author.id)) {
|
||||
this.success = false;
|
||||
return "Only the bot owner can reload Lavalink!";
|
||||
}
|
||||
this.acknowledge().then(() => {
|
||||
this.ipc.broadcast("soundreload");
|
||||
this.ipc.register("soundReloadSuccess", (msg) => {
|
||||
|
|
|
@ -4,10 +4,13 @@ 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,
|
||||
|
@ -18,6 +21,7 @@ class StickerCommand extends Command {
|
|||
}]
|
||||
};
|
||||
} 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!";
|
||||
|
|
|
@ -8,6 +8,7 @@ import Command from "../../classes/command.js";
|
|||
class YouTubeCommand extends Command {
|
||||
async run() {
|
||||
const query = this.options.query ?? this.args.join(" ");
|
||||
this.success = false;
|
||||
if (!query || !query.trim()) return "You need to provide something to search for!";
|
||||
await this.acknowledge();
|
||||
const messages = [];
|
||||
|
@ -16,6 +17,7 @@ class YouTubeCommand extends Command {
|
|||
for (const [i, value] of videos.results.entries()) {
|
||||
messages.push({ content: `Page ${i + 1} of ${videos.results.length}\n<:youtube:637020823005167626> **${value.title.replaceAll("*", "\\*")}**\nUploaded by **${value.author.replaceAll("*", "\\*")}**\n${value.url}` });
|
||||
}
|
||||
this.success = true;
|
||||
return paginator(this.client, { type: this.type, message: this.message, interaction: this.interaction, channel: this.channel, author: this.author }, messages);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue