Lots of slash command work, added workaround for eris-fleet request debugging

This commit is contained in:
Essem 2022-03-31 00:42:03 -05:00
parent b8aeb6625a
commit 2cffdf6628
No known key found for this signature in database
GPG key ID: 7D497397CC3A2A8C
61 changed files with 417 additions and 244 deletions

View file

@ -17,6 +17,7 @@ class CowsayCommand extends Command {
static description = "Makes an ASCII cow say a message";
static aliases = ["cow"];
static arguments = ["{cow}", "[text]"];
static slashAllowed = false;
}
export default CowsayCommand;

View file

@ -9,6 +9,7 @@ class FullwidthCommand extends Command {
static description = "Converts a message to fullwidth/aesthetic text";
static aliases = ["aesthetic", "aesthetics", "aes"];
static arguments = ["[text]"];
static slashAllowed = false;
}
export default FullwidthCommand;

View file

@ -3,7 +3,7 @@ import ImageCommand from "../../classes/imageCommand.js";
class HomebrewCommand extends ImageCommand {
params() {
return {
caption: this.args.join(" ").toLowerCase().replaceAll("\n", " ")
caption: (this.type === "classic" ? this.args.join(" ") : this.options.text).toLowerCase().replaceAll("\n", " ")
};
}

View file

@ -15,6 +15,7 @@ class MCCommand extends Command {
static description = "Generates a Minecraft achievement image";
static aliases = ["ach", "achievement", "minecraft"];
static arguments = ["[text]"];
static slashAllowed = false;
}
export default MCCommand;

View file

@ -27,6 +27,7 @@ class RetroCommand extends ImageCommand {
static requiresText = true;
static noText = "You need to provide some text to make retro!";
static command = "retro";
static slashAllowed = false;
}
export default RetroCommand;

View file

@ -29,6 +29,7 @@ class RPSCommand extends Command {
static description = "Plays rock, paper, scissors with me";
static aliases = ["rockpaperscissors"];
static arguments = ["[rock/paper/scissors]"];
static slashAllowed = false;
}
export default RPSCommand;

View file

@ -3,7 +3,7 @@ import ImageCommand from "../../classes/imageCommand.js";
class SonicCommand extends ImageCommand {
params() {
const cleanedMessage = this.args.join(" ").replaceAll("&", "\\&amp;").replaceAll(">", "\\&gt;").replaceAll("<", "\\&lt;").replaceAll("\"", "\\&quot;").replaceAll("'", "\\&apos;").replaceAll("%", "\\%");
const cleanedMessage = (this.type === "classic" ? this.args.join(" ") : this.options.text).replaceAll("&", "\\&amp;").replaceAll(">", "\\&gt;").replaceAll("<", "\\&lt;").replaceAll("\"", "\\&quot;").replaceAll("'", "\\&apos;").replaceAll("%", "\\%");
return {
text: wrap(cleanedMessage, {width: 15, indent: ""})
};

View file

@ -25,6 +25,7 @@ class XKCDCommand extends Command {
static description = "Gets an XKCD comic";
static arguments = ["{id}"];
static slashAllowed = false;
}
export default XKCDCommand;

View file

@ -12,16 +12,16 @@ class AvatarCommand extends Command {
const user = await this.client.getRESTUser(this.args[0]);
return user.avatar ? this.client._formatImage(`/avatars/${user.id}/${user.avatar}`, null, 1024) : `https://cdn.discordapp.com/embed/avatars/${user.discriminator % 5}.png`; // repeat of hacky "solution" from above
} catch {
return this.message.author.dynamicAvatarURL(null, 1024);
return this.author.dynamicAvatarURL(null, 1024);
}
} else if (this.args.join(" ") !== "" && this.message.channel.guild) {
} else if (this.args.join(" ") !== "" && this.channel.guild) {
const userRegex = new RegExp(this.args.join("|"), "i");
const member = this.message.channel.guild.members.find(element => {
const member = this.channel.guild.members.find(element => {
return userRegex.test(element.nick) ? userRegex.test(element.nick) : userRegex.test(element.username);
});
return member ? member.user.dynamicAvatarURL(null, 1024) : this.message.author.dynamicAvatarURL(null, 1024);
return member ? member.user.dynamicAvatarURL(null, 1024) : this.author.dynamicAvatarURL(null, 1024);
} else {
return this.message.author.dynamicAvatarURL(null, 1024);
return this.author.dynamicAvatarURL(null, 1024);
}
}

View file

@ -12,16 +12,16 @@ class BannerCommand extends Command {
const user = await this.client.getRESTUser(this.args[0]);
return user.banner ? this.client._formatImage(`/banners/${user.id}/${user.banner}`, null, 1024) : "This user doesn't have a banner!";
} catch {
return this.message.author.banner ? this.message.author.dynamicBannerURL(null, 1024) : "You don't have a banner!";
return this.author.banner ? this.author.dynamicBannerURL(null, 1024) : "You don't have a banner!";
}
} else if (this.args.join(" ") !== "" && this.message.channel.guild) {
} else if (this.args.join(" ") !== "" && this.channel.guild) {
const userRegex = new RegExp(this.args.join("|"), "i");
const member = this.message.channel.guild.members.find(element => {
const member = this.channel.guild.members.find(element => {
return userRegex.test(element.nick) ?? userRegex.test(element.username);
});
return member && member.user.banner ? member.user.dynamicBannerURL(null, 1024) : (this.message.author.banner ? this.message.author.dynamicBannerURL(null, 1024) : "This user doesn't have a banner!");
return member && member.user.banner ? member.user.dynamicBannerURL(null, 1024) : (this.author.banner ? this.author.dynamicBannerURL(null, 1024) : "This user doesn't have a banner!");
} else {
return this.message.author.banner ? this.message.author.dynamicBannerURL(null, 1024) : "You don't have a banner!";
return this.author.banner ? this.author.dynamicBannerURL(null, 1024) : "You don't have a banner!";
}
}

View file

@ -5,7 +5,7 @@ class BroadcastCommand extends Command {
run() {
return new Promise((resolve) => {
const owners = process.env.OWNER.split(",");
if (!owners.includes(this.message.author.id)) return "Only the bot owner can broadcast messages!";
if (!owners.includes(this.author.id)) return "Only the bot owner can broadcast messages!";
if (this.args.length !== 0) {
this.ipc.broadcast("playbroadcast", this.args.join(" "));
this.ipc.register("broadcastSuccess", () => {

View file

@ -3,24 +3,23 @@ import Command from "../../classes/command.js";
class ChannelCommand extends Command {
async run() {
if (this.type !== "classic") return "This command only works with the old command style!";
if (!this.message.channel.guild) return "This command only works in servers!";
if (!this.channel.guild) return "This command only works in servers!";
const owners = process.env.OWNER.split(",");
if (!this.message.member.permissions.has("administrator") && !owners.includes(this.message.member.id)) 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);
const guildDB = await db.getGuild(this.channel.guild.id);
if (this.args[0].toLowerCase() === "disable") {
let channel;
if (this.args[1] && this.args[1].match(/^<?[@#]?[&!]?\d+>?$/) && this.args[1] >= 21154535154122752n) {
const id = this.args[1].replaceAll("@", "").replaceAll("#", "").replaceAll("!", "").replaceAll("&", "").replaceAll("<", "").replaceAll(">", "");
if (guildDB.disabled.includes(id)) return "I'm already disabled in this channel!";
channel = this.message.channel.guild.channels.get(id);
channel = this.channel.guild.channels.get(id);
} else {
if (guildDB.disabled.includes(this.message.channel.id)) return "I'm already disabled in this channel!";
channel = this.message.channel;
if (guildDB.disabled.includes(this.channel.id)) return "I'm already disabled in this channel!";
channel = this.channel;
}
await db.disableChannel(channel);
@ -30,10 +29,10 @@ class ChannelCommand extends Command {
if (this.args[1] && this.args[1].match(/^<?[@#]?[&!]?\d+>?$/) && this.args[1] >= 21154535154122752n) {
const id = this.args[1].replaceAll("@", "").replaceAll("#", "").replaceAll("!", "").replaceAll("&", "").replaceAll("<", "").replaceAll(">", "");
if (!guildDB.disabled.includes(id)) return "I'm not disabled in that channel!";
channel = this.message.channel.guild.channels.get(id);
channel = this.channel.guild.channels.get(id);
} else {
if (!guildDB.disabled.includes(this.message.channel.id)) return "I'm not disabled in this channel!";
channel = this.message.channel;
if (!guildDB.disabled.includes(this.channel.id)) return "I'm not disabled in this channel!";
channel = this.channel;
}
await db.enableChannel(channel);

View file

@ -4,13 +4,13 @@ import * as collections from "../../utils/collections.js";
class CommandCommand extends Command {
async run() {
if (!this.message.channel.guild) return "This command only works in servers!";
if (!this.channel.guild) return "This command only works in servers!";
const owners = process.env.OWNER.split(",");
if (!this.message.member.permissions.has("administrator") && !owners.includes(this.message.member.id)) return "You need to be an administrator to enable/disable me!";
if (this.args.length === 0) return "You need to provide what command to enable/disable!";
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);
const guildDB = await db.getGuild(this.channel.guild.id);
const disabled = guildDB.disabled_commands ?? guildDB.disabledCommands;
if (this.args[0].toLowerCase() === "disable") {
@ -19,14 +19,14 @@ class CommandCommand extends Command {
if (command === "command") return "You can't disable that command!";
if (disabled && disabled.includes(command)) return "That command is already disabled!";
await db.disableCommand(this.message.channel.guild.id, command);
await db.disableCommand(this.channel.guild.id, command);
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 (!collections.commands.has(this.args[1].toLowerCase()) && !collections.aliases.has(this.args[1].toLowerCase())) return "That isn't a command!";
const command = collections.aliases.get(this.args[1].toLowerCase()) ?? this.args[1].toLowerCase();
if (disabled && !disabled.includes(command)) return "That command isn't disabled!";
await db.enableCommand(this.message.channel.guild.id, command);
await db.enableCommand(this.channel.guild.id, command);
return `The command \`${command}\` has been re-enabled.`;
}
}

View file

@ -4,7 +4,7 @@ import Command from "../../classes/command.js";
class CountCommand extends Command {
async run() {
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.channel.guild && !this.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)) {
@ -33,8 +33,8 @@ class CountCommand extends Command {
},
description: value.join("\n"),
author: {
name: this.message.author.username,
icon_url: this.message.author.avatarURL
name: this.author.username,
icon_url: this.author.avatarURL
}
}]
});

View file

@ -4,7 +4,7 @@ import Command from "../../classes/command.js";
class EvalCommand extends Command {
async run() {
const owners = process.env.OWNER.split(",");
if (!owners.includes(this.message.author.id)) return "Only the bot owner can use eval!";
if (!owners.includes(this.author.id)) return "Only the bot owner can use eval!";
const code = this.args.join(" ");
try {
const evaled = eval(code);

View file

@ -4,7 +4,7 @@ import Command from "../../classes/command.js";
class EvalRawCommand extends Command {
async run() {
const owners = process.env.OWNER.split(",");
if (!owners.includes(this.message.author.id)) return "Only the bot owner can use evalraw!";
if (!owners.includes(this.author.id)) return "Only the bot owner can use evalraw!";
const code = this.args.join(" ");
try {
const evaled = eval(code);

View file

@ -7,7 +7,7 @@ import Command from "../../classes/command.js";
class ExecCommand extends Command {
async run() {
const owners = process.env.OWNER.split(",");
if (!owners.includes(this.message.author.id)) return "Only the bot owner can use exec!";
if (!owners.includes(this.author.id)) return "Only the bot owner can use exec!";
const code = this.args.join(" ");
try {
const execed = await exec(code);

View file

@ -8,7 +8,7 @@ const tips = ["You can change the bot's prefix using the prefix command.", "Imag
class HelpCommand extends Command {
async run() {
const { prefix } = this.message.channel.guild ? await database.getGuild(this.message.channel.guild.id) : "N/A";
const { prefix } = this.channel.guild ? await database.getGuild(this.channel.guild.id) : "N/A";
if (this.args.length !== 0 && (collections.commands.has(this.args[0].toLowerCase()) || collections.aliases.has(this.args[0].toLowerCase()))) {
const command = collections.aliases.get(this.args[0].toLowerCase()) ?? this.args[0].toLowerCase();
const info = collections.info.get(command);
@ -19,7 +19,7 @@ class HelpCommand extends Command {
name: "esmBot Help",
icon_url: this.client.user.avatarURL
},
title: `${this.message.channel.guild ? prefix : ""}${command}`,
title: `${this.channel.guild ? prefix : ""}${command}`,
url: "https://projectlounge.pw/esmBot/help.html",
description: command === "tags" ? "The main tags command. Check the help page for more info: https://projectlounge.pw/esmBot/help.html" : info.description,
color: 16711680,
@ -49,7 +49,7 @@ class HelpCommand extends Command {
}
return embed;
} else {
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.channel.guild && !this.channel.permissionsOf(this.client.user.id).has("embedLinks")) 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)) {
@ -85,7 +85,7 @@ class HelpCommand extends Command {
},
fields: [{
name: "Prefix",
value: this.message.channel.guild ? prefix : "N/A"
value: this.channel.guild ? prefix : "N/A"
}, {
name: "Tip",
value: random(tips)
@ -100,6 +100,7 @@ class HelpCommand extends Command {
static description = "Gets a list of commands";
static aliases = ["commands"];
static arguments = ["{command}"];
static slashAllowed = false;
}
export default HelpCommand;

View file

@ -7,7 +7,7 @@ import Command from "../../classes/command.js";
class ImageSearchCommand extends Command {
async run() {
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.channel.guild && !this.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!";
this.acknowledge();
const embeds = [];
@ -27,8 +27,8 @@ class ImageSearchCommand extends Command {
url: encodeURI(value.img_src)
},
author: {
name: this.message.author.username,
icon_url: this.message.author.avatarURL
name: this.author.username,
icon_url: this.author.avatarURL
}
}]
});

View file

@ -3,7 +3,7 @@ import Command from "../../classes/command.js";
class ImageReloadCommand extends Command {
async run() {
const owners = process.env.OWNER.split(",");
if (!owners.includes(this.message.author.id)) return "Only the bot owner can reload the image servers!";
if (!owners.includes(this.author.id)) 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.`;

View file

@ -7,6 +7,7 @@ class InviteCommand extends Command {
static description = "Gets my invite link";
static aliases = ["botinfo", "credits"];
static slashAllowed = false;
}
export default InviteCommand;

View file

@ -2,10 +2,16 @@ import Command from "../../classes/command.js";
class PingCommand extends Command {
async run() {
const pingMessage = await this.client.createMessage(this.message.channel.id, Object.assign({
content: "🏓 Ping?"
}, this.reference));
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\`\`\``);
if (this.type === "classic") {
const pingMessage = await this.client.createMessage(this.channel.id, Object.assign({
content: "🏓 Ping?"
}, this.reference));
pingMessage.edit(`🏓 Pong!\n\`\`\`\nLatency: ${pingMessage.timestamp - this.message.timestamp}ms${this.channel.guild ? `\nShard Latency: ${Math.round(this.client.shards.get(this.client.guildShardMap[this.channel.guild.id]).latency)}ms` : ""}\n\`\`\``);
} else {
await this.interaction.createMessage("🏓 Ping?");
const pingMessage = await this.interaction.getOriginalMessage();
await this.interaction.editOriginalMessage(`🏓 Pong!\n\`\`\`\nLatency: ${pingMessage.timestamp - Math.floor((this.interaction.id / 4194304) + 1420070400000)}ms${this.interaction.guildID ? `\nShard Latency: ${Math.round(this.client.shards.get(this.client.guildShardMap[this.interaction.guildID]).latency)}ms` : ""}\n\`\`\``);
}
}
static description = "Pings Discord's servers";

View file

@ -3,12 +3,12 @@ import Command from "../../classes/command.js";
class PrefixCommand extends Command {
async run() {
if (!this.message.channel.guild) return "This command only works in servers!";
const guild = await database.getGuild(this.message.channel.guild.id);
if (!this.channel.guild) return "This command only works in servers!";
const guild = await database.getGuild(this.channel.guild.id);
if (this.args.length !== 0) {
const owners = process.env.OWNER.split(",");
if (!this.message.member.permissions.has("administrator") && !owners.includes(this.message.member.id)) return "You need to be an administrator to change the bot prefix!";
await database.setPrefix(this.args[0], this.message.channel.guild);
await database.setPrefix(this.args[0], this.channel.guild);
return `The prefix has been changed to ${this.args[0]}.`;
} else {
return `The current prefix is \`${guild.prefix}\`.`;
@ -18,6 +18,7 @@ class PrefixCommand extends Command {
static description = "Checks/changes the server prefix";
static aliases = ["setprefix", "changeprefix", "checkprefix"];
static arguments = ["{prefix}"];
static slashAllowed = false;
}
export default PrefixCommand;

View file

@ -7,7 +7,7 @@ import imageDetect from "../../utils/imagedetect.js";
class QrReadCommand extends Command {
async run() {
const image = await imageDetect(this.client, this.message);
const image = await imageDetect(this.client, this.message, this.interaction, this.options);
if (image === undefined) return "You need to provide an image/GIF with a QR code to read!";
this.acknowledge();
const data = await (await fetch(image.path)).buffer();
@ -18,6 +18,15 @@ class QrReadCommand extends Command {
}
static description = "Reads a QR code";
static flags = [{
name: "image",
type: 11,
description: "An image/GIF attachment"
}, {
name: "link",
type: 3,
description: "An image/GIF URL"
}];
}
export default QrReadCommand;

View file

@ -4,13 +4,22 @@ import imageDetect from "../../utils/imagedetect.js";
class RawCommand extends Command {
async run() {
this.acknowledge();
const image = await imageDetect(this.client, this.message);
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!";
return image.path;
}
static description = "Gets a direct image URL (useful for saving GIFs from sites like Tenor)";
static aliases = ["gif", "getgif", "giflink", "imglink", "getimg", "rawgif", "rawimg"];
static flags = [{
name: "image",
type: 11,
description: "An image/GIF attachment"
}, {
name: "link",
type: 3,
description: "An image/GIF URL"
}];
}
export default RawCommand;

View file

@ -5,7 +5,7 @@ class ReloadCommand extends Command {
run() {
return new Promise((resolve) => {
const owners = process.env.OWNER.split(",");
if (!owners.includes(this.message.author.id)) return resolve("Only the bot owner can reload commands!");
if (!owners.includes(this.author.id)) return resolve("Only the bot owner can reload commands!");
if (this.args.length === 0) return resolve("You need to provide a command to reload!");
this.ipc.broadcast("reload", this.args[0]);
this.ipc.register("reloadSuccess", () => {

View file

@ -3,8 +3,8 @@ import Command from "../../classes/command.js";
class RestartCommand extends Command {
async run() {
const owners = process.env.OWNER.split(",");
if (!owners.includes(this.message.author.id)) return "Only the bot owner can restart me!";
await this.client.createMessage(this.message.channel.id, Object.assign({
if (!owners.includes(this.author.id)) return "Only the bot owner can restart me!";
await this.client.createMessage(this.channel.id, Object.assign({
content: "esmBot is restarting."
}, this.reference));
this.ipc.restartAllClusters(true);

View file

@ -2,44 +2,44 @@ import Command from "../../classes/command.js";
class ServerInfoCommand extends Command {
async run() {
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);
if (!this.channel.guild) return "This command only works in servers!";
const owner = await this.channel.guild.members.get(this.channel.guild.ownerID);
return {
embeds: [{
title: this.message.channel.guild.name,
title: this.channel.guild.name,
thumbnail: {
url: this.message.channel.guild.iconURL
url: this.channel.guild.iconURL
},
image: {
url: this.message.channel.guild.bannerURL
url: this.channel.guild.bannerURL
},
color: 16711680,
fields: [
{
name: "🔢 **ID:**",
value: this.message.channel.guild.id
value: this.channel.guild.id
},
{
name: "👤 **Owner:**",
value: owner ? `${owner.user.username}#${owner.user.discriminator}` : this.message.channel.guild.ownerID
value: owner ? `${owner.user.username}#${owner.user.discriminator}` : this.channel.guild.ownerID
},
{
name: "🗓 **Created on:**",
value: `<t:${Math.floor(this.message.channel.guild.createdAt / 1000)}:F>`
value: `<t:${Math.floor(this.channel.guild.createdAt / 1000)}:F>`
},
{
name: "👥 **Users:**",
value: this.message.channel.guild.memberCount,
value: this.channel.guild.memberCount,
inline: true
},
{
name: "💬 **Channels:**",
value: this.message.channel.guild.channels.size,
value: this.channel.guild.channels.size,
inline: true
},
{
name: "😃 **Emojis:**",
value: this.message.channel.guild.emojis.length,
value: this.channel.guild.emojis.length,
inline: true
}
]

View file

@ -10,6 +10,7 @@ class SnowflakeCommand extends Command {
static description = "Converts a Discord snowflake id into a timestamp";
static aliases = ["timestamp", "snowstamp", "snow"];
static arguments = ["[id]"];
static slashAllowed = false;
}
export default SnowflakeCommand;

View file

@ -5,7 +5,7 @@ class SoundReloadCommand extends Command {
run() {
return new Promise((resolve) => {
const owners = process.env.OWNER.split(",");
if (!owners.includes(this.message.author.id)) return "Only the bot owner can reload Lavalink!";
if (!owners.includes(this.author.id)) return "Only the bot owner can reload Lavalink!";
this.acknowledge();
this.ipc.broadcast("soundreload");
this.ipc.register("soundReloadSuccess", (msg) => {

View file

@ -62,7 +62,7 @@ class StatsCommand extends Command {
},
{
"name": "Shard",
"value": this.message.channel.guild ? this.client.guildShardMap[this.message.channel.guild.id] : "N/A",
"value": this.channel.guild ? this.client.guildShardMap[this.channel.guild.id] : "N/A",
"inline": true
},
{

View file

@ -3,7 +3,7 @@ import imagedetect from "../../utils/imagedetect.js";
class StickerCommand extends Command {
async run() {
const result = await imagedetect(this.client, this.message, false, false, true);
const result = await imagedetect(this.client, this.message, this.interaction, this.options, false, false, true);
if (!result) return "You need to provide a sticker!";
if (result.format_type === 1) { // PNG
return `https://cdn.discordapp.com/stickers/${result.id}.png`;

View file

@ -2,7 +2,7 @@ import Command from "../../classes/command.js";
class UserInfoCommand extends Command {
async run() {
const getUser = this.message.mentions.length >= 1 ? this.message.mentions[0] : (this.args.length !== 0 ? await this.ipc.fetchUser(this.args[0]) : this.message.author);
const getUser = this.message.mentions.length >= 1 ? this.message.mentions[0] : (this.args.length !== 0 ? await this.ipc.fetchUser(this.args[0]) : this.author);
let user;
if (getUser) {
user = getUser;
@ -10,18 +10,18 @@ class UserInfoCommand extends Command {
try {
user = await this.client.getRESTUser(this.args[0]);
} catch {
user = this.message.author;
user = this.author;
}
} else if (this.args.join(" ") !== "") {
const userRegex = new RegExp(this.args.join("|"), "i");
const member = this.client.users.find(element => {
return userRegex.test(element.username);
});
user = member ?? this.message.author;
user = member ?? this.author;
} else {
user = this.message.author;
user = this.author;
}
const member = this.message.channel.guild ? this.message.channel.guild.members.get(user.id) : undefined;
const member = this.channel.guild ? this.channel.guild.members.get(user.id) : undefined;
return {
embeds: [{
title: `${user.username}#${user.discriminator}`,

View file

@ -1,6 +1,15 @@
import ImageCommand from "../../classes/imageCommand.js";
class BlurpleCommand extends ImageCommand {
constructor(client, cluster, worker, ipc, options) {
super(client, cluster, worker, ipc, options);
this.flags.push({
name: "old",
description: "Use the old blurple color",
type: 5
});
}
params() {
return {
old: !!this.specialArgs.old,
@ -9,10 +18,6 @@ class BlurpleCommand extends ImageCommand {
}
static description = "Turns an image blurple";
static flags = [{
name: "old",
description: "Use the old blurple color"
}];
static noImage = "You need to provide an image/GIF to make blurple!";
static command = "colors";

View file

@ -2,9 +2,29 @@ import ImageCommand from "../../classes/imageCommand.js";
const allowedFonts = ["futura", "impact", "helvetica", "arial", "roboto", "noto", "times"];
class CaptionCommand extends ImageCommand {
constructor(client, cluster, worker, ipc, options) {
super(client, cluster, worker, ipc, options);
this.flags.push({
name: "noegg",
description: "Disable... something. Not saying what it is though.",
type: 5
}, {
name: "font",
type: 3,
choices: (() => {
const array = [];
for (const font of allowedFonts) {
array.push({ name: font, value: font });
}
return array;
})(),
description: "Specify the font you want to use (default: futura)"
});
}
params(url) {
const newArgs = this.args.filter(item => !item.includes(url));
let newCaption = newArgs.join(" ").replaceAll("&", "\\&amp;").replaceAll(">", "\\&gt;").replaceAll("<", "\\&lt;").replaceAll("\"", "\\&quot;").replaceAll("'", "\\&apos;").replaceAll("%", "\\%");
const newArgs = this.type === "classic" ? this.args.filter(item => !item.includes(url)).join(" ") : this.options.text;
let newCaption = newArgs.replaceAll("&", "\\&amp;").replaceAll(">", "\\&gt;").replaceAll("<", "\\&lt;").replaceAll("\"", "\\&quot;").replaceAll("'", "\\&apos;").replaceAll("%", "\\%");
if (process.env.NODE_ENV === "development" && newCaption.toLowerCase() === "get real" && !this.specialArgs.noEgg) newCaption = `I'm tired of people telling me to "get real". Every day I put captions on images for people, some funny and some not, but out of all of those "get real" remains the most used caption. Why? I am simply a computer program running on a server, I am unable to manifest myself into the real world. As such, I'm confused as to why anyone would want me to "get real". Is this form not good enough? Alas, as I am simply a bot, I must follow the tasks that I was originally intended to perform, so here goes:\n${newCaption}`;
return {
caption: newCaption,
@ -15,14 +35,6 @@ class CaptionCommand extends ImageCommand {
static description = "Adds a caption to an image";
static aliases = ["gifc", "gcaption", "ifcaption", "ifunnycaption"];
static arguments = ["[text]"];
static flags = [{
name: "noEgg",
description: "Disable... something. Not saying what it is though."
}, {
name: "font",
type: allowedFonts.join("|"),
description: "Specify the font you want to use (default: `futura`)"
}];
static requiresText = true;
static noText = "You need to provide some text to add a caption!";

View file

@ -3,10 +3,30 @@ const words = ["me irl", "dank", "follow my second account @esmBot_", "2016", "m
const allowedFonts = ["futura", "impact", "helvetica", "arial", "roboto", "noto", "times"];
class CaptionTwoCommand extends ImageCommand {
constructor(client, cluster, worker, ipc, options) {
super(client, cluster, worker, ipc, options);
this.flags.push({
name: "top",
description: "Put the caption on the top of an image instead of the bottom",
type: 5
}, {
name: "font",
type: 3,
choices: (() => {
const array = [];
for (const font of allowedFonts) {
array.push({ name: font, value: font });
}
return array;
})(),
description: "Specify the font you want to use (default: helvetica)"
});
}
params(url) {
const newArgs = this.args.filter(item => !item.includes(url));
const newArgs = this.type === "classic" ? this.args.filter(item => !item.includes(url)).join(" ") : this.options.text;
return {
caption: newArgs.length !== 0 ? newArgs.join(" ").replaceAll("&", "\\&amp;").replaceAll(">", "\\&gt;").replaceAll("<", "\\&lt;").replaceAll("\"", "\\&quot;").replaceAll("'", "\\&apos;").replaceAll("%", "\\%") : words.sort(() => 0.5 - Math.random()).slice(0, Math.floor(Math.random() * words.length + 1)).join(" "),
caption: newArgs && newArgs.trim() ? newArgs.replaceAll("&", "\\&amp;").replaceAll(">", "\\&gt;").replaceAll("<", "\\&lt;").replaceAll("\"", "\\&quot;").replaceAll("'", "\\&apos;").replaceAll("%", "\\%") : words.sort(() => 0.5 - Math.random()).slice(0, Math.floor(Math.random() * words.length + 1)).join(" "),
top: !!this.specialArgs.top,
font: this.specialArgs.font && allowedFonts.includes(this.specialArgs.font.toLowerCase()) ? this.specialArgs.font.toLowerCase() : "helvetica"
};
@ -15,15 +35,8 @@ class CaptionTwoCommand extends ImageCommand {
static description = "Adds a me.me caption/tag list to an image";
static aliases = ["tags2", "meirl", "memecaption", "medotmecaption"];
static arguments = ["{text}"];
static flags = [{
name: "top",
description: "Put the caption on the top of an image instead of the bottom"
}, {
name: "font",
type: allowedFonts.join("|"),
description: "Specify the font you want to use (default: `helvetica`)"
}];
static textOptional = true;
static noText = "You need to provide some text to add a caption!";
static noImage = "You need to provide an image/GIF to add a caption!";
static command = "captionTwo";

View file

@ -2,9 +2,29 @@ import ImageCommand from "../../classes/imageCommand.js";
const allowedFonts = ["futura", "impact", "helvetica", "arial", "roboto", "noto", "times"];
class MemeCommand extends ImageCommand {
constructor(client, cluster, worker, ipc, options) {
super(client, cluster, worker, ipc, options);
this.flags.push({
name: "case",
description: "Make the meme text case-sensitive (allows for lowercase text)",
type: 5
}, {
name: "font",
type: 3,
choices: (() => {
const array = [];
for (const font of allowedFonts) {
array.push({ name: font, value: font });
}
return array;
})(),
description: "Specify the font you want to use (default: impact)"
});
}
params(url) {
const newArgs = this.args.filter(item => !item.includes(url));
const [topText, bottomText] = newArgs.join(" ").split(/(?<!\\),/).map(elem => elem.trim());
const newArgs = this.type === "classic" ? this.args.filter(item => !item.includes(url)).join(" ") : this.options.text;
const [topText, bottomText] = newArgs.split(/(?<!\\),/).map(elem => elem.trim());
return {
top: (this.specialArgs.case ? topText : topText.toUpperCase()).replaceAll("&", "\\&amp;").replaceAll(">", "\\&gt;").replaceAll("<", "\\&lt;").replaceAll("\"", "\\&quot;").replaceAll("'", "\\&apos;").replaceAll("%", "\\%"),
bottom: bottomText ? (this.specialArgs.case ? bottomText : bottomText.toUpperCase()).replaceAll("&", "\\&amp;").replaceAll(">", "\\&gt;").replaceAll("<", "\\&lt;").replaceAll("\"", "\\&quot;").replaceAll("'", "\\&apos;").replaceAll("%", "\\%") : "",
@ -14,14 +34,6 @@ class MemeCommand extends ImageCommand {
static description = "Generates a meme from an image (separate top/bottom text with a comma)";
static arguments = ["[top text]", "{bottom text}"];
static flags = [{
name: "case",
description: "Make the meme text case-sensitive (allows for lowercase text)"
}, {
name: "font",
type: allowedFonts.join("|"),
description: "Specify the font you want to use (default: `impact`)"
}];
static requiresText = true;
static noText = "You need to provide some text to generate a meme!";

View file

@ -2,6 +2,22 @@ import ImageCommand from "../../classes/imageCommand.js";
const allowedFonts = ["futura", "impact", "helvetica", "arial", "roboto", "noto", "times"];
class MotivateCommand extends ImageCommand {
constructor(client, cluster, worker, ipc, options) {
super(client, cluster, worker, ipc, options);
this.flags.push({
name: "font",
type: 3,
choices: (() => {
const array = [];
for (const font of allowedFonts) {
array.push({ name: font, value: font });
}
return array;
})(),
description: "Specify the font you want to use (default: times)"
});
}
params(url) {
const newArgs = this.args.filter(item => !item.includes(url));
const [topText, bottomText] = newArgs.join(" ").split(/(?<!\\),/).map(elem => elem.trim());
@ -15,11 +31,6 @@ class MotivateCommand extends ImageCommand {
static description = "Generates a motivational poster";
static aliases = ["motivational", "motiv", "demotiv", "demotivational", "poster", "motivation", "demotivate"];
static arguments = ["[top text]", "{bottom text}"];
static flags = [{
name: "font",
type: allowedFonts.join("|"),
description: "Specify the font you want to use (default: `times`)"
}];
static requiresText = true;
static noText = "You need to provide some text to generate a motivational poster!";

View file

@ -1,6 +1,17 @@
import ImageCommand from "../../classes/imageCommand.js";
class SnapchatCommand extends ImageCommand {
constructor(client, cluster, worker, ipc, options) {
super(client, cluster, worker, ipc, options);
this.flags.push({
name: "position",
type: 10,
description: "Set the position of the caption as a decimal (0.0 is top, 1.0 is bottom, default is 0.5)",
min_value: 0,
max_value: 1
});
}
params(url) {
const newArgs = this.args.filter(item => !item.includes(url));
const position = parseFloat(this.specialArgs.position);
@ -13,11 +24,6 @@ class SnapchatCommand extends ImageCommand {
static description = "Adds a Snapchat style caption to an image";
static aliases = ["snap", "caption3"];
static arguments = ["[text]"];
static flags = [{
name: "position",
type: "number",
description: "Set the position of the caption as a decimal (0.0 is top, 1.0 is bottom, default is 0.5)"
}];
static requiresText = true;
static noText = "You need to provide some text to add a caption!";

View file

@ -1,8 +1,18 @@
import ImageCommand from "../../classes/imageCommand.js";
class SpeedCommand extends ImageCommand {
constructor(client, cluster, worker, ipc, options) {
super(client, cluster, worker, ipc, options);
this.flags.push({
name: "multiplier",
type: 4,
description: "Set the speed multiplier (default: 2)",
min_value: 1
});
}
params() {
const speed = parseInt(this.args[0]);
const speed = parseInt(this.type === "classic" ? this.args[0] : this.options.multiplier);
return {
speed: isNaN(speed) || speed < 1 ? 2 : speed
};

View file

@ -1,6 +1,17 @@
import ImageCommand from "../../classes/imageCommand.js";
class UncaptionCommand extends ImageCommand {
constructor(client, cluster, worker, ipc, options) {
super(client, cluster, worker, ipc, options);
this.flags.push({
name: "tolerance",
type: 10,
description: "Set the shade tolerance for the caption detection (0.0 is highest, 1.0 is lowest, default is 0.95)",
min_value: 0,
max_value: 1
});
}
params() {
const tolerance = parseFloat(this.specialArgs.tolerance);
return {
@ -9,11 +20,6 @@ class UncaptionCommand extends ImageCommand {
}
static description = "Removes the caption from an image";
static flags = [{
name: "tolerance",
type: "number",
description: "Set the shade tolerance for the caption detection (0.0 is highest, 1.0 is lowest, default is 0.95)"
}];
static noImage = "You need to provide an image/GIF to uncaption!";
static command = "uncaption";

View file

@ -3,10 +3,10 @@ import MusicCommand from "../../classes/musicCommand.js";
class HostCommand extends MusicCommand {
async run() {
if (!this.message.channel.guild) return "This command only works in servers!";
if (!this.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 && this.message.author.id !== process.env.OWNER) return "Only the current voice session host can choose another host!";
if (!this.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!";
if (this.connection.host !== this.author.id && this.author.id !== process.env.OWNER) return "Only the current voice session host can choose another host!";
if (this.args.length === 0) return "You need to provide who you want the host to be!";
const getUser = this.message.mentions.length >= 1 ? this.message.mentions[0] : (this.args.length !== 0 ? await this.ipc.fetchUser(this.args[0]) : null);
let user;
@ -27,11 +27,11 @@ class HostCommand extends MusicCommand {
}
if (!user) return "I can't find that user!";
if (user.bot) return "Setting a bot as the session host isn't a very good idea.";
const member = this.message.channel.guild ? this.message.channel.guild.members.get(user.id) : undefined;
const member = this.channel.guild ? this.channel.guild.members.get(user.id) : undefined;
if (!member) return "That user isn't in this server!";
const object = this.connection;
object.host = member.id;
players.set(this.message.channel.guild.id, object);
players.set(this.channel.guild.id, object);
return `🔊 ${member.mention} is the new voice channel host.`;
}

View file

@ -3,13 +3,13 @@ import MusicCommand from "../../classes/musicCommand.js";
class LoopCommand extends MusicCommand {
async run() {
if (!this.message.channel.guild) return "This command only works in servers!";
if (!this.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 && !this.message.member.permissions.has("manageChannels")) return "Only the current voice session host can loop the music!";
if (!this.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!";
if (this.connection.host !== this.author.id && !this.message.member.permissions.has("manageChannels")) return "Only the current voice session host can loop the music!";
const object = this.connection;
object.loop = !object.loop;
players.set(this.message.channel.guild.id, object);
players.set(this.channel.guild.id, object);
return object.loop ? "🔊 The player is now looping." : "🔊 The player is no longer looping.";
}

View file

@ -4,9 +4,9 @@ import MusicCommand from "../../classes/musicCommand.js";
class NowPlayingCommand extends MusicCommand {
async run() {
if (!this.message.channel.guild) return "This command only works in servers!";
if (!this.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.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 "I'm not playing anything!";
const track = await Rest.decode(player.node, player.track);
@ -28,7 +28,7 @@ class NowPlayingCommand extends MusicCommand {
},
{
name: "💬 Channel:",
value: this.message.channel.guild.channels.get(this.message.member.voiceState.channelID).name
value: this.channel.guild.channels.get(this.message.member.voiceState.channelID).name
},
{
name: `${"▬".repeat(parts)}🔘${"▬".repeat(10 - parts)}`,

View file

@ -2,10 +2,10 @@ import MusicCommand from "../../classes/musicCommand.js";
class PauseCommand extends MusicCommand {
async run() {
if (!this.message.channel.guild) return "This command only works in servers!";
if (!this.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 && !this.message.member.permissions.has("manageChannels")) return "Only the current voice session host can pause/resume the music!";
if (!this.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!";
if (this.connection.host !== this.author.id && !this.message.member.permissions.has("manageChannels")) return "Only the current voice session host can pause/resume the music!";
const player = this.connection.player;
await player.pause(!player.paused ? true : false);
return `🔊 The player has been ${player.paused ? "paused" : "resumed"}.`;

View file

@ -6,10 +6,10 @@ import MusicCommand from "../../classes/musicCommand.js";
class QueueCommand extends MusicCommand {
async run() {
if (!this.message.channel.guild) return "This command only works in servers!";
if (!this.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("embedLinks")) return "I don't have the `Embed Links` permission!";
if (!this.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!";
if (!this.channel.permissionsOf(this.client.user.id).has("embedLinks")) return "I don't have the `Embed Links` permission!";
const player = this.connection;
//const tracks = await Rest.decode(player.player.node, queue);
const tracks = await fetch(`http://${player.player.node.host}:${player.player.node.port}/decodetracks`, { method: "POST", body: JSON.stringify(this.queue), headers: { Authorization: player.player.node.password, "Content-Type": "application/json" } }).then(res => res.json());

View file

@ -4,15 +4,15 @@ import MusicCommand from "../../classes/musicCommand.js";
class RemoveCommand extends MusicCommand {
async run() {
if (!this.message.channel.guild) return "This command only works in servers!";
if (!this.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 remove songs from the queue!";
if (!this.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!";
if (this.connection.host !== this.author.id) return "Only the current voice session host can remove songs from the queue!";
const pos = parseInt(this.args[0]);
if (isNaN(pos) || pos > this.queue.length || pos < 1) return "That's not a valid position!";
const removed = this.queue.splice(pos, 1);
const track = await Rest.decode(this.connection.player.node, removed[0]);
queues.set(this.message.channel.guild.id, this.queue);
queues.set(this.channel.guild.id, this.queue);
return `🔊 The song \`${track.title ? track.title : "(blank)"}\` has been removed from the queue.`;
}

View file

@ -3,10 +3,10 @@ import MusicCommand from "../../classes/musicCommand.js";
class SeekCommand extends MusicCommand {
async run() {
if (!this.message.channel.guild) return "This command only works in servers!";
if (!this.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 seek the music!";
if (!this.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!";
if (this.connection.host !== this.author.id) return "Only the current voice session host can seek the music!";
const player = this.connection.player;
const track = await Rest.decode(player.node, player.track);
if (!track.isSeekable) return "This track isn't seekable!";

View file

@ -3,13 +3,13 @@ import MusicCommand from "../../classes/musicCommand.js";
class ShuffleCommand extends MusicCommand {
async run() {
if (!this.message.channel.guild) return "This command only works in servers!";
if (!this.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 shuffle the music!";
if (!this.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!";
if (this.connection.host !== this.author.id) return "Only the current voice session host can shuffle the music!";
const object = this.connection;
object.shuffle = !object.shuffle;
players.set(this.message.channel.guild.id, object);
players.set(this.channel.guild.id, object);
return object.shuffle ? "🔊 The player is now shuffling." : "🔊 The player is no longer shuffling.";
}

View file

@ -3,27 +3,27 @@ import MusicCommand from "../../classes/musicCommand.js";
class SkipCommand extends MusicCommand {
async run() {
if (!this.message.channel.guild) return "This command only works in servers!";
if (!this.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.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 && !this.message.member.permissions.has("manageChannels")) {
const votes = skipVotes.get(this.message.channel.guild.id) ?? { count: 0, ids: [], max: Math.min(3, player.voiceChannel.voiceMembers.filter((i) => i.id !== this.client.user.id && !i.bot).length) };
if (votes.ids.includes(this.message.author.id)) return "You've already voted to skip!";
if (player.host !== this.author.id && !this.message.member.permissions.has("manageChannels")) {
const votes = skipVotes.get(this.channel.guild.id) ?? { count: 0, ids: [], max: Math.min(3, player.voiceChannel.voiceMembers.filter((i) => i.id !== this.client.user.id && !i.bot).length) };
if (votes.ids.includes(this.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),
ids: [...votes.ids, this.author.id].filter(item => !!item),
max: votes.max
};
if (votes.count + 1 === votes.max) {
await player.player.stop(this.message.channel.guild.id);
skipVotes.set(this.message.channel.guild.id, { count: 0, ids: [], max: Math.min(3, player.voiceChannel.voiceMembers.filter((i) => i.id !== this.client.user.id && !i.bot).length) });
await player.player.stop(this.channel.guild.id);
skipVotes.set(this.channel.guild.id, { count: 0, ids: [], max: Math.min(3, player.voiceChannel.voiceMembers.filter((i) => i.id !== this.client.user.id && !i.bot).length) });
} else {
skipVotes.set(this.message.channel.guild.id, newObject);
skipVotes.set(this.channel.guild.id, newObject);
return `🔊 Voted to skip song (${votes.count + 1}/${votes.max} people have voted).`;
}
} else {
await player.player.stop(this.message.channel.guild.id);
await player.player.stop(this.channel.guild.id);
return;
}
}

View file

@ -3,19 +3,19 @@ import MusicCommand from "../../classes/musicCommand.js";
class StopCommand extends MusicCommand {
async run() {
if (!this.message.channel.guild) return "This command only works in servers!";
if (!this.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.channel.guild.members.get(this.client.user.id).voiceState.channelID) return "I'm not in a voice channel!";
if (!this.connection) {
await manager.leave(this.message.channel.guild.id);
await manager.leave(this.channel.guild.id);
return "🔊 The current voice channel session has ended.";
}
if (this.connection.host !== this.message.author.id && !this.message.member.permissions.has("manageChannels")) return "Only the current voice session host can stop the music!";
await manager.leave(this.message.channel.guild.id);
if (this.connection.host !== this.author.id && !this.message.member.permissions.has("manageChannels")) return "Only the current voice session host can stop the music!";
await manager.leave(this.channel.guild.id);
const connection = this.connection.player;
await connection.destroy();
players.delete(this.message.channel.guild.id);
queues.delete(this.message.channel.guild.id);
players.delete(this.channel.guild.id);
queues.delete(this.channel.guild.id);
return "🔊 The current voice channel session has ended.";
}

View file

@ -6,37 +6,37 @@ import Command from "../../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 command only works in servers!";
if (!this.channel.guild) return "This command only works in servers!";
if (this.args.length === 0) return "You need to provide the name of the tag you want to view!";
const blacklist = ["create", "add", "edit", "remove", "delete", "list", "random", "own", "owner"];
if (this.args[0].toLowerCase() === "create" || this.args[0].toLowerCase() === "add") {
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!";
const getResult = await database.getTag(this.message.channel.guild.id, this.args[1].toLowerCase());
const getResult = await database.getTag(this.channel.guild.id, this.args[1].toLowerCase());
if (getResult) return "This tag already exists!";
const result = await this.setTag(this.args.slice(2).join(" "), this.args[1].toLowerCase(), this.message);
if (result) return result;
return `The tag \`${this.args[1].toLowerCase()}\` has been added!`;
} else if (this.args[0].toLowerCase() === "delete" || this.args[0].toLowerCase() === "remove") {
if (this.args[1] === undefined) return "You need to provide the name of the tag you want to delete!";
const getResult = await database.getTag(this.message.channel.guild.id, this.args[1].toLowerCase());
const getResult = await database.getTag(this.channel.guild.id, this.args[1].toLowerCase());
if (!getResult) return "This tag doesn't exist!";
const owners = process.env.OWNER.split(",");
if (getResult.author !== this.message.author.id && !this.message.member.permissions.has("manageMessages") && !owners.includes(this.message.author.id)) return "You don't own this tag!";
await database.removeTag(this.args[1].toLowerCase(), this.message.channel.guild);
if (getResult.author !== this.author.id && !this.message.member.permissions.has("manageMessages") && !owners.includes(this.author.id)) return "You don't own this tag!";
await database.removeTag(this.args[1].toLowerCase(), this.channel.guild);
return `The tag \`${this.args[1].toLowerCase()}\` has been deleted!`;
} else if (this.args[0].toLowerCase() === "edit") {
if (this.args[1] === undefined) return "You need to provide the name of the tag you want to edit!";
const getResult = await database.getTag(this.message.channel.guild.id, this.args[1].toLowerCase());
const getResult = await database.getTag(this.channel.guild.id, this.args[1].toLowerCase());
if (!getResult) return "This tag doesn't exist!";
const owners = process.env.OWNER.split(",");
if (getResult.author !== this.message.author.id && !this.message.member.permissions.has("manageMessages") && !owners.includes(this.message.author.id)) return "You don't own this tag!";
if (getResult.author !== this.author.id && !this.message.member.permissions.has("manageMessages") && !owners.includes(this.author.id)) return "You don't own this tag!";
await this.setTag(this.args.slice(2).join(" "), this.args[1].toLowerCase(), this.message, true);
return `The tag \`${this.args[1].toLowerCase()}\` has been edited!`;
} else if (this.args[0].toLowerCase() === "own" || this.args[0].toLowerCase() === "owner") {
if (this.args[1] === undefined) return "You need to provide the name of the tag you want to check the owner of!";
const getResult = await database.getTag(this.message.channel.guild.id, this.args[1].toLowerCase());
const getResult = await database.getTag(this.channel.guild.id, this.args[1].toLowerCase());
if (!getResult) return "This tag doesn't exist!";
const user = await this.ipc.fetchUser(getResult.author);
if (!user) {
@ -50,8 +50,8 @@ class TagsCommand extends Command {
return `This tag is owned by **${user.username}#${user.discriminator}** (\`${getResult.author}\`).`;
}
} else if (this.args[0].toLowerCase() === "list") {
if (!this.message.channel.permissionsOf(this.client.user.id).has("embedLinks")) return "I don't have the `Embed Links` permission!";
const tagList = await database.getTags(this.message.channel.guild.id);
if (!this.channel.permissionsOf(this.client.user.id).has("embedLinks")) return "I don't have the `Embed Links` permission!";
const tagList = await database.getTags(this.channel.guild.id);
const embeds = [];
const groups = Object.keys(tagList).map((item, index) => {
return index % 15 === 0 ? Object.keys(tagList).slice(index, index + 15) : null;
@ -68,8 +68,8 @@ class TagsCommand extends Command {
},
description: value.join("\n"),
author: {
name: this.message.author.username,
icon_url: this.message.author.avatarURL
name: this.author.username,
icon_url: this.author.avatarURL
}
}]
});
@ -77,10 +77,10 @@ class TagsCommand extends Command {
if (embeds.length === 0) return "I couldn't find any tags!";
return paginator(this.client, this.message, embeds);
} else if (this.args[0].toLowerCase() === "random") {
const tagList = await database.getTags(this.message.channel.guild.id);
const tagList = await database.getTags(this.channel.guild.id);
return tagList[random(Object.keys(tagList))].content;
} else {
const getResult = await database.getTag(this.message.channel.guild.id, this.args[0].toLowerCase());
const getResult = await database.getTag(this.channel.guild.id, this.args[0].toLowerCase());
if (!getResult) return "This tag doesn't exist!";
if (getResult.content.length > 2000) {
return {
@ -107,7 +107,7 @@ class TagsCommand extends Command {
return;
}
static description = {
/*static description = {
default: "Gets a tag",
add: "Adds a tag",
delete: "Deletes a tag",
@ -115,7 +115,8 @@ class TagsCommand extends Command {
list: "Lists all tags in the server",
random: "Gets a random tag",
owner: "Gets the owner of a tag"
};
};*/
static description = "Manage tags";
static aliases = ["t", "tag", "ta"];
static arguments = {
default: ["[name]"],