initial update

This commit is contained in:
murm 2023-03-15 10:09:09 -04:00
parent 3272429cf6
commit db9b70bf66
280 changed files with 11772 additions and 11966 deletions

View file

@ -1,43 +1,43 @@
import Command from "../../classes/command.js";
import { random } from "../../utils/misc.js";
class EightBallCommand extends Command {
static responses = [
"It is certain",
"It is decidedly so",
"Without a doubt",
"Yes, definitely",
"You may rely on it",
"As I see it, yes",
"Most likely",
"Outlook good",
"Yes",
"Signs point to yes",
"Reply hazy, try again",
"Ask again later",
"Better not tell you now",
"Cannot predict now",
"Concentrate and ask again",
"Don't count on it",
"My reply is no",
"My sources say no",
"Outlook not so good",
"Very doubtful"
];
async run() {
return `🎱 ${random(EightBallCommand.responses)}`;
}
static flags = [{
name: "question",
type: 3,
description: "A question you want to ask the ball"
}];
static description = "Asks the magic 8-ball a question";
static aliases = ["magicball", "magikball", "magic8ball", "magik8ball", "eightball"];
static arguments = ["{text}"];
}
import Command from "../../classes/command.js";
import { random } from "../../utils/misc.js";
class EightBallCommand extends Command {
static responses = [
"It is certain",
"It is decidedly so",
"Without a doubt",
"Yes, definitely",
"You may rely on it",
"As I see it, yes",
"Most likely",
"Outlook good",
"Yes",
"Signs point to yes",
"Reply hazy, try again",
"Ask again later",
"Better not tell you now",
"Cannot predict now",
"Concentrate and ask again",
"Don't count on it",
"My reply is no",
"My sources say no",
"Outlook not so good",
"Very doubtful"
];
async run() {
return `🎱 ${random(EightBallCommand.responses)}`;
}
static flags = [{
name: "question",
type: 3,
description: "A question you want to ask the ball"
}];
static description = "Asks the magic 8-ball a question";
static aliases = ["magicball", "magikball", "magic8ball", "magik8ball", "eightball"];
static arguments = ["{text}"];
}
export default EightBallCommand;

View file

@ -1,27 +1,27 @@
import { request } from "undici";
import Command from "../../classes/command.js";
class AncientCommand extends Command {
async run() {
await this.acknowledge();
const controller = new AbortController();
const timeout = setTimeout(() => {
controller.abort();
}, 15000);
try {
const data = await request("https://files.projectlounge.pw/meme/", { method: "HEAD", signal: controller.signal });
clearTimeout(timeout);
return `https://files.projectlounge.pw${data.headers.location}`;
} catch (e) {
if (e.name === "AbortError") {
this.success = false;
return "I couldn't get a meme in time. Maybe try again?";
}
}
}
static description = "Gets a random ancient meme";
static aliases = ["old", "oldmeme", "badmeme"];
}
import { request } from "undici";
import Command from "../../classes/command.js";
class AncientCommand extends Command {
async run() {
await this.acknowledge();
const controller = new AbortController();
const timeout = setTimeout(() => {
controller.abort();
}, 15000);
try {
const data = await request("https://files.projectlounge.pw/meme/", { method: "HEAD", signal: controller.signal });
clearTimeout(timeout);
return `https://files.projectlounge.pw${data.headers.location}`;
} catch (e) {
if (e.name === "AbortError") {
this.success = false;
return "I couldn't get a meme in time. Maybe try again?";
}
}
}
static description = "Gets a random ancient meme";
static aliases = ["old", "oldmeme", "badmeme"];
}
export default AncientCommand;

View file

@ -1,28 +1,28 @@
import { request } from "undici";
import Command from "../../classes/command.js";
class BirdCommand extends Command {
async run() {
await this.acknowledge();
const controller = new AbortController();
const timeout = setTimeout(() => {
controller.abort();
}, 15000);
try {
const imageData = await request("http://shibe.online/api/birds", { signal: controller.signal });
clearTimeout(timeout);
const json = await imageData.body.json();
return json[0];
} catch (e) {
if (e.name === "AbortError") {
this.success = false;
return "I couldn't get a bird image in time. Maybe try again?";
}
}
}
static description = "Gets a random bird picture";
static aliases = ["birb", "birds", "birbs"];
}
import { request } from "undici";
import Command from "../../classes/command.js";
class BirdCommand extends Command {
async run() {
await this.acknowledge();
const controller = new AbortController();
const timeout = setTimeout(() => {
controller.abort();
}, 15000);
try {
const imageData = await request("http://shibe.online/api/birds", { signal: controller.signal });
clearTimeout(timeout);
const json = await imageData.body.json();
return json[0];
} catch (e) {
if (e.name === "AbortError") {
this.success = false;
return "I couldn't get a bird image in time. Maybe try again?";
}
}
}
static description = "Gets a random bird picture";
static aliases = ["birb", "birds", "birbs"];
}
export default BirdCommand;

View file

@ -1,27 +1,27 @@
import { request } from "undici";
import Command from "../../classes/command.js";
class CatCommand extends Command {
async run() {
await this.acknowledge();
const controller = new AbortController();
const timeout = setTimeout(() => {
controller.abort();
}, 15000);
try {
const data = await request("https://files.projectlounge.pw/cta/", { method: "HEAD", signal: controller.signal });
clearTimeout(timeout);
return `https://files.projectlounge.pw${data.headers.location}`;
} catch (e) {
if (e.name === "AbortError") {
this.success = false;
return "I couldn't get a cat image in time. Maybe try again?";
}
}
}
static description = "Gets a random cat picture";
static aliases = ["kitters", "kitties", "kitty", "cattos", "catto", "cats", "cta"];
}
import { request } from "undici";
import Command from "../../classes/command.js";
class CatCommand extends Command {
async run() {
await this.acknowledge();
const controller = new AbortController();
const timeout = setTimeout(() => {
controller.abort();
}, 15000);
try {
const data = await request("https://files.projectlounge.pw/cta/", { method: "HEAD", signal: controller.signal });
clearTimeout(timeout);
return `https://files.projectlounge.pw${data.headers.location}`;
} catch (e) {
if (e.name === "AbortError") {
this.success = false;
return "I couldn't get a cat image in time. Maybe try again?";
}
}
}
static description = "Gets a random cat picture";
static aliases = ["kitters", "kitties", "kitty", "cattos", "catto", "cats", "cta"];
}
export default CatCommand;

View file

@ -1,25 +1,25 @@
import Command from "../../classes/command.js";
class DiceCommand extends Command {
async run() {
const max = this.options.max ?? parseInt(this.args[0]);
if (!max) {
return `🎲 The dice landed on ${Math.floor(Math.random() * 6) + 1}.`;
} else {
return `🎲 The dice landed on ${Math.floor(Math.random() * max) + 1}.`;
}
}
static flags = [{
name: "max",
type: 4,
description: "The maximum dice value",
min_value: 1
}];
static description = "Rolls the dice";
static aliases = ["roll", "die", "rng", "random"];
static arguments = ["{number}"];
}
import Command from "../../classes/command.js";
class DiceCommand extends Command {
async run() {
const max = this.options.max ?? parseInt(this.args[0]);
if (!max) {
return `🎲 The dice landed on ${Math.floor(Math.random() * 6) + 1}.`;
} else {
return `🎲 The dice landed on ${Math.floor(Math.random() * max) + 1}.`;
}
}
static flags = [{
name: "max",
type: 4,
description: "The maximum dice value",
min_value: 1
}];
static description = "Rolls the dice";
static aliases = ["roll", "die", "rng", "random"];
static arguments = ["{number}"];
}
export default DiceCommand;

View file

@ -1,28 +1,28 @@
import { request } from "undici";
import Command from "../../classes/command.js";
class DogCommand extends Command {
async run() {
await this.acknowledge();
const controller = new AbortController();
const timeout = setTimeout(() => {
controller.abort();
}, 15000);
try {
const imageData = await request("https://dog.ceo/api/breeds/image/random", { signal: controller.signal });
clearTimeout(timeout);
const json = await imageData.body.json();
return json.message;
} catch (e) {
if (e.name === "AbortError") {
this.success = false;
return "I couldn't get a dog image in time. Maybe try again?";
}
}
}
static description = "Gets a random dog picture";
static aliases = ["doggos", "doggo", "pupper", "puppers", "dogs", "puppy", "puppies", "pups", "pup"];
}
import { request } from "undici";
import Command from "../../classes/command.js";
class DogCommand extends Command {
async run() {
await this.acknowledge();
const controller = new AbortController();
const timeout = setTimeout(() => {
controller.abort();
}, 15000);
try {
const imageData = await request("https://dog.ceo/api/breeds/image/random", { signal: controller.signal });
clearTimeout(timeout);
const json = await imageData.body.json();
return json.message;
} catch (e) {
if (e.name === "AbortError") {
this.success = false;
return "I couldn't get a dog image in time. Maybe try again?";
}
}
}
static description = "Gets a random dog picture";
static aliases = ["doggos", "doggo", "pupper", "puppers", "dogs", "puppy", "puppies", "pups", "pup"];
}
export default DogCommand;

View file

@ -1,20 +1,20 @@
import ImageCommand from "../../classes/imageCommand.js";
class HomebrewCommand extends ImageCommand {
params() {
return {
caption: (this.options.text ?? this.args.join(" ")).toLowerCase().replaceAll("\n", " ")
};
}
static description = "Creates a Homebrew Channel edit";
static aliases = ["hbc", "brew", "wiibrew"];
static arguments = ["[text]"];
static requiresImage = false;
static requiresText = true;
static noText = "You need to provide some text to make a Homebrew Channel edit!";
static command = "homebrew";
}
import ImageCommand from "../../classes/imageCommand.js";
class HomebrewCommand extends ImageCommand {
params() {
return {
caption: (this.options.text ?? this.args.join(" ")).toLowerCase().replaceAll("\n", " ")
};
}
static description = "Creates a Homebrew Channel edit";
static aliases = ["hbc", "brew", "wiibrew"];
static arguments = ["[text]"];
static requiresImage = false;
static requiresText = true;
static noText = "You need to provide some text to make a Homebrew Channel edit!";
static command = "homebrew";
}
export default HomebrewCommand;

View file

@ -1,22 +1,22 @@
//import wrap from "../../utils/wrap.js";
import ImageCommand from "../../classes/imageCommand.js";
import { cleanMessage } from "../../utils/misc.js";
class SonicCommand extends ImageCommand {
params() {
const cleanedMessage = cleanMessage(this.message ?? this.interaction, this.options.text ?? this.args.join(" "));
return {
text: cleanedMessage
};
}
static description = "Creates a Sonic speech bubble image";
static arguments = ["[text]"];
static requiresImage = false;
static requiresText = true;
static noText = "You need to provide some text to make a Sonic meme!";
static command = "sonic";
}
//import wrap from "../../utils/wrap.js";
import ImageCommand from "../../classes/imageCommand.js";
import { cleanMessage } from "../../utils/misc.js";
class SonicCommand extends ImageCommand {
params() {
const cleanedMessage = cleanMessage(this.message ?? this.interaction, this.options.text ?? this.args.join(" "));
return {
text: cleanedMessage
};
}
static description = "Creates a Sonic speech bubble image";
static arguments = ["[text]"];
static requiresImage = false;
static requiresText = true;
static noText = "You need to provide some text to make a Sonic meme!";
static command = "sonic";
}
export default SonicCommand;

View file

@ -1,34 +1,34 @@
import { request } from "undici";
import Command from "../../classes/command.js";
class WikihowCommand extends Command {
async run() {
await this.acknowledge();
const controller = new AbortController();
const timeout = setTimeout(() => {
controller.abort();
}, 15000);
try {
const req = await request("https://www.wikihow.com/api.php?action=query&generator=random&prop=imageinfo&format=json&iiprop=url&grnnamespace=6", { signal: controller.signal });
clearTimeout(timeout);
const json = await req.body.json();
const id = Object.keys(json.query.pages)[0];
const data = json.query.pages[id];
if (data.imageinfo) {
return json.query.pages[id].imageinfo[0].url;
} else {
return await this.run();
}
} catch (e) {
if (e.name === "AbortError") {
this.success = false;
return "I couldn't get a WikiHow image in time. Maybe try again?";
}
}
}
static description = "Gets a random WikiHow image";
static aliases = ["wiki"];
}
export default WikihowCommand;
import { request } from "undici";
import Command from "../../classes/command.js";
class WikihowCommand extends Command {
async run() {
await this.acknowledge();
const controller = new AbortController();
const timeout = setTimeout(() => {
controller.abort();
}, 15000);
try {
const req = await request("https://www.wikihow.com/api.php?action=query&generator=random&prop=imageinfo&format=json&iiprop=url&grnnamespace=6", { signal: controller.signal });
clearTimeout(timeout);
const json = await req.body.json();
const id = Object.keys(json.query.pages)[0];
const data = json.query.pages[id];
if (data.imageinfo) {
return json.query.pages[id].imageinfo[0].url;
} else {
return await this.run();
}
} catch (e) {
if (e.name === "AbortError") {
this.success = false;
return "I couldn't get a WikiHow image in time. Maybe try again?";
}
}
}
static description = "Gets a random WikiHow image";
static aliases = ["wiki"];
}
export default WikihowCommand;

View file

@ -1,53 +1,53 @@
import Command from "../../classes/command.js";
const mentionRegex = /^<?[@#]?[&!]?(\d+)>?$/;
class AvatarCommand extends Command {
async run() {
const member = this.options.member ?? this.args[0];
const self = this.client.users.get(this.author.id) ?? await this.client.rest.users.get(this.author.id);
if (this.type === "classic" && this.message.mentions.users[0]) {
return this.message.mentions.users[0].avatarURL(null, 512);
} else if (member && member > 21154535154122752n) {
const user = this.client.users.get(member) ?? await this.client.rest.users.get(member);
if (user) {
return user.avatarURL(null, 512);
} else if (mentionRegex.test(member)) {
const id = member.match(mentionRegex)[1];
if (id < 21154535154122752n) {
this.success = false;
return "That's not a valid mention!";
}
try {
const user = this.client.users.get(id) ?? await this.client.rest.users.get(id);
return user.avatarURL(null, 512);
} catch {
return self.avatarURL(null, 512);
}
} else {
return self.avatarURL(null, 512);
}
} else if (this.args.join(" ") !== "" && this.guild) {
const searched = await this.guild.searchMembers({
query: this.args.join(" "),
limit: 1
});
if (searched.length === 0) return self.avatarURL(null, 512);
const user = this.client.users.get(searched[0].user.id) ?? await this.client.rest.users.get(searched[0].user.id);
return user ? user.avatarURL(null, 512) : self.avatarURL(null, 512);
} else {
return self.avatarURL(null, 512);
}
}
static description = "Gets a user's avatar";
static aliases = ["pfp", "ava"];
static arguments = ["{mention/id}"];
static flags = [{
name: "member",
type: 6,
description: "The member to get the avatar from",
required: false
}];
}
export default AvatarCommand;
import Command from "../../classes/command.js";
const mentionRegex = /^<?[@#]?[&!]?(\d+)>?$/;
class AvatarCommand extends Command {
async run() {
const member = this.options.member ?? this.args[0];
const self = this.client.users.get(this.author.id) ?? await this.client.rest.users.get(this.author.id);
if (this.type === "classic" && this.message.mentions.users[0]) {
return this.message.mentions.users[0].avatarURL(null, 512);
} else if (member && member > 21154535154122752n) {
const user = this.client.users.get(member) ?? await this.client.rest.users.get(member);
if (user) {
return user.avatarURL(null, 512);
} else if (mentionRegex.test(member)) {
const id = member.match(mentionRegex)[1];
if (id < 21154535154122752n) {
this.success = false;
return "That's not a valid mention!";
}
try {
const user = this.client.users.get(id) ?? await this.client.rest.users.get(id);
return user.avatarURL(null, 512);
} catch {
return self.avatarURL(null, 512);
}
} else {
return self.avatarURL(null, 512);
}
} else if (this.args.join(" ") !== "" && this.guild) {
const searched = await this.guild.searchMembers({
query: this.args.join(" "),
limit: 1
});
if (searched.length === 0) return self.avatarURL(null, 512);
const user = this.client.users.get(searched[0].user.id) ?? await this.client.rest.users.get(searched[0].user.id);
return user ? user.avatarURL(null, 512) : self.avatarURL(null, 512);
} else {
return self.avatarURL(null, 512);
}
}
static description = "Gets a user's avatar";
static aliases = ["pfp", "ava"];
static arguments = ["{mention/id}"];
static flags = [{
name: "member",
type: 6,
description: "The member to get the avatar from",
required: false
}];
}
export default AvatarCommand;

View file

@ -1,55 +1,55 @@
import Command from "../../classes/command.js";
import { Routes } from "oceanic.js";
const mentionRegex = /^<?[@#]?[&!]?(\d+)>?$/;
class BannerCommand extends Command {
// this command sucks
async run() {
const member = this.options.member ?? this.args[0];
const self = await this.client.rest.users.get(this.author.id); // banners are only available over REST
if (this.type === "classic" && this.message.mentions.users[0] && this.message.mentions.users[0].banner) {
return this.client.util.formatImage(Routes.BANNER(this.message.mentions.users[0].id, this.message.mentions.users[0].banner), null, 512);
} else if (member && member > 21154535154122752n) {
const user = await this.client.rest.users.get(member);
if (user && user.banner) {
return this.client.util.formatImage(Routes.BANNER(user.id, user.banner), null, 512);
} else if (mentionRegex.test(member)) {
const id = member.match(mentionRegex)[1];
if (id < 21154535154122752n) {
this.success = false;
return "That's not a valid mention!";
}
try {
const user = await this.client.rest.users.get(id);
return user.banner ? this.client.util.formatImage(Routes.BANNER(user.id, user.banner), null, 512) : "This user doesn't have a banner!";
} catch {
return self.banner ? this.client.util.formatImage(Routes.BANNER(self.id, self.banner), null, 512) : "You don't have a banner!";
}
} else {
return "This user doesn't have a banner!";
}
} else if (this.args.join(" ") !== "" && this.guild) {
const searched = await this.guild.searchMembers({
query: this.args.join(" "),
limit: 1
});
if (searched.length === 0) return self.banner ? this.client.util.formatImage(Routes.BANNER(self.id, self.banner), null, 512) : "This user doesn't have a banner!";
const user = await this.client.rest.users.get(searched[0].user.id);
return user.banner ? this.client.util.formatImage(Routes.BANNER(user.id, user.banner), null, 512) : (self.banner ? this.client.util.formatImage(Routes.BANNER(self.id, self.banner), null, 512) : "This user doesn't have a banner!");
} else {
return self.banner ? this.client.util.formatImage(Routes.BANNER(self.id, self.banner), null, 512) : "You don't have a banner!";
}
}
static description = "Gets a user's banner";
static aliases = ["userbanner"];
static arguments = ["{mention/id}"];
static flags = [{
name: "member",
type: 6,
description: "The member to get the banner from",
required: false
}];
}
export default BannerCommand;
import Command from "../../classes/command.js";
import { Routes } from "oceanic.js";
const mentionRegex = /^<?[@#]?[&!]?(\d+)>?$/;
class BannerCommand extends Command {
// this command sucks
async run() {
const member = this.options.member ?? this.args[0];
const self = await this.client.rest.users.get(this.author.id); // banners are only available over REST
if (this.type === "classic" && this.message.mentions.users[0] && this.message.mentions.users[0].banner) {
return this.client.util.formatImage(Routes.BANNER(this.message.mentions.users[0].id, this.message.mentions.users[0].banner), null, 512);
} else if (member && member > 21154535154122752n) {
const user = await this.client.rest.users.get(member);
if (user && user.banner) {
return this.client.util.formatImage(Routes.BANNER(user.id, user.banner), null, 512);
} else if (mentionRegex.test(member)) {
const id = member.match(mentionRegex)[1];
if (id < 21154535154122752n) {
this.success = false;
return "That's not a valid mention!";
}
try {
const user = await this.client.rest.users.get(id);
return user.banner ? this.client.util.formatImage(Routes.BANNER(user.id, user.banner), null, 512) : "This user doesn't have a banner!";
} catch {
return self.banner ? this.client.util.formatImage(Routes.BANNER(self.id, self.banner), null, 512) : "You don't have a banner!";
}
} else {
return "This user doesn't have a banner!";
}
} else if (this.args.join(" ") !== "" && this.guild) {
const searched = await this.guild.searchMembers({
query: this.args.join(" "),
limit: 1
});
if (searched.length === 0) return self.banner ? this.client.util.formatImage(Routes.BANNER(self.id, self.banner), null, 512) : "This user doesn't have a banner!";
const user = await this.client.rest.users.get(searched[0].user.id);
return user.banner ? this.client.util.formatImage(Routes.BANNER(user.id, user.banner), null, 512) : (self.banner ? this.client.util.formatImage(Routes.BANNER(self.id, self.banner), null, 512) : "This user doesn't have a banner!");
} else {
return self.banner ? this.client.util.formatImage(Routes.BANNER(self.id, self.banner), null, 512) : "You don't have a banner!";
}
}
static description = "Gets a user's banner";
static aliases = ["userbanner"];
static arguments = ["{mention/id}"];
static flags = [{
name: "member",
type: 6,
description: "The member to get the banner from",
required: false
}];
}
export default BannerCommand;

View file

@ -1,48 +1,48 @@
import Command from "../../classes/command.js";
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)}\`\`\``;
} else if (command === "encode") {
const b64Encoded = Buffer.from(string, "utf8").toString("base64");
return `\`\`\`\n${b64Encoded}\`\`\``;
}
}
static flags = [{
name: "decode",
type: 1,
description: "Decodes a Base64 string",
options: [{
name: "text",
type: 3,
description: "The text to decode",
required: true
}]
}, {
name: "encode",
type: 1,
description: "Encodes a Base64 string",
options: [{
name: "text",
type: 3,
description: "The text to encode",
required: true
}]
}];
static description = "Encodes/decodes a Base64 string";
static arguments = ["[encode/decode]", "[text]"];
}
import Command from "../../classes/command.js";
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)}\`\`\``;
} else if (command === "encode") {
const b64Encoded = Buffer.from(string, "utf8").toString("base64");
return `\`\`\`\n${b64Encoded}\`\`\``;
}
}
static flags = [{
name: "decode",
type: 1,
description: "Decodes a Base64 string",
options: [{
name: "text",
type: 3,
description: "The text to decode",
required: true
}]
}, {
name: "encode",
type: 1,
description: "Encodes a Base64 string",
options: [{
name: "text",
type: 3,
description: "The text to encode",
required: true
}]
}];
static description = "Encodes/decodes a Base64 string";
static arguments = ["[encode/decode]", "[text]"];
}
export default Base64Command;

View file

@ -1,52 +1,52 @@
import Command from "../../classes/command.js";
import database from "../../utils/database.js";
import { endBroadcast, startBroadcast } from "../../utils/misc.js";
class BroadcastCommand extends Command {
async run() {
const owners = process.env.OWNER.split(",");
if (!owners.includes(this.author.id)) {
this.success = false;
return "Only the bot owner can broadcast messages!";
}
const message = this.options.message ?? this.args.join(" ");
if (message?.trim()) {
await database.setBroadcast(message);
startBroadcast(this.client, message);
if (process.env.PM2_USAGE) {
process.send({
type: "process:msg",
data: {
type: "broadcastStart",
message
}
});
}
return "Started broadcast.";
} else {
await database.setBroadcast(null);
endBroadcast(this.client);
if (process.env.PM2_USAGE) {
process.send({
type: "process:msg",
data: {
type: "broadcastEnd"
}
});
}
return "Ended broadcast.";
}
}
static flags = [{
name: "message",
type: 3,
description: "The message to broadcast"
}];
static description = "Broadcasts a playing message until the command is run again or the bot restarts";
static adminOnly = true;
static dbRequired = true;
}
import Command from "../../classes/command.js";
import database from "../../utils/database.js";
import { endBroadcast, startBroadcast } from "../../utils/misc.js";
class BroadcastCommand extends Command {
async run() {
const owners = process.env.OWNER.split(",");
if (!owners.includes(this.author.id)) {
this.success = false;
return "Only the bot owner can broadcast messages!";
}
const message = this.options.message ?? this.args.join(" ");
if (message?.trim()) {
await database.setBroadcast(message);
startBroadcast(this.client, message);
if (process.env.PM2_USAGE) {
process.send({
type: "process:msg",
data: {
type: "broadcastStart",
message
}
});
}
return "Started broadcast.";
} else {
await database.setBroadcast(null);
endBroadcast(this.client);
if (process.env.PM2_USAGE) {
process.send({
type: "process:msg",
data: {
type: "broadcastEnd"
}
});
}
return "Ended broadcast.";
}
}
static flags = [{
name: "message",
type: 3,
description: "The message to broadcast"
}];
static description = "Broadcasts a playing message until the command is run again or the bot restarts";
static adminOnly = true;
static dbRequired = true;
}
export default BroadcastCommand;

View file

@ -1,53 +1,53 @@
import db from "../../utils/database.js";
import Command from "../../classes/command.js";
class ChannelCommand extends Command {
async run() {
this.success = false;
if (!this.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!";
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.guild.id);
if (this.args[0].toLowerCase() === "disable") {
let channel;
if (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.guild.channels.get(id) ?? await this.client.rest.channels.get(id);
} else {
if (guildDB.disabled.includes(this.channel.id)) return "I'm already disabled in this channel!";
channel = this.channel;
}
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;
if (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.guild.channels.get(id) ?? await this.client.rest.channels.get(id);
} else {
if (!guildDB.disabled.includes(this.channel.id)) return "I'm not disabled in this channel!";
channel = this.channel;
}
await db.enableChannel(channel);
this.success = true;
return "I have been re-enabled in this channel.";
}
}
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;
static dbRequired = true;
}
export default ChannelCommand;
import db from "../../utils/database.js";
import Command from "../../classes/command.js";
class ChannelCommand extends Command {
async run() {
this.success = false;
if (!this.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!";
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.guild.id);
if (this.args[0].toLowerCase() === "disable") {
let channel;
if (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.guild.channels.get(id) ?? await this.client.rest.channels.get(id);
} else {
if (guildDB.disabled.includes(this.channel.id)) return "I'm already disabled in this channel!";
channel = this.channel;
}
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;
if (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.guild.channels.get(id) ?? await this.client.rest.channels.get(id);
} else {
if (!guildDB.disabled.includes(this.channel.id)) return "I'm not disabled in this channel!";
channel = this.channel;
}
await db.enableChannel(channel);
this.success = true;
return "I have been re-enabled in this channel.";
}
}
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;
static dbRequired = true;
}
export default ChannelCommand;

View file

@ -1,44 +1,44 @@
import db from "../../utils/database.js";
import Command from "../../classes/command.js";
import * as collections from "../../utils/collections.js";
class CommandCommand extends Command {
async run() {
this.success = false;
if (!this.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!";
if (this.args.length === 0) return "You need to provide whether you want to enable/disable a command!";
if (this.args[0] !== "disable" && this.args[0] !== "enable") return "That's not a valid option!";
if (!this.args[1]) return "You need to provide what command to enable/disable!";
if (!collections.commands.has(this.args[1].toLowerCase()) && !collections.aliases.has(this.args[1].toLowerCase())) return "That isn't a command!";
const guildDB = await db.getGuild(this.guild.id);
const disabled = guildDB.disabled_commands ?? guildDB.disabledCommands;
const command = collections.aliases.get(this.args[1].toLowerCase()) ?? this.args[1].toLowerCase();
if (this.args[0].toLowerCase() === "disable") {
if (command === "command") return "You can't disable that command!";
if (disabled?.includes(command)) return "That command is already disabled!";
await db.disableCommand(this.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.guild.id, command);
this.success = true;
return `The command \`${command}\` has been re-enabled.`;
}
}
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;
static directAllowed = false;
static dbRequired = true;
}
export default CommandCommand;
import db from "../../utils/database.js";
import Command from "../../classes/command.js";
import * as collections from "../../utils/collections.js";
class CommandCommand extends Command {
async run() {
this.success = false;
if (!this.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!";
if (this.args.length === 0) return "You need to provide whether you want to enable/disable a command!";
if (this.args[0] !== "disable" && this.args[0] !== "enable") return "That's not a valid option!";
if (!this.args[1]) return "You need to provide what command to enable/disable!";
if (!collections.commands.has(this.args[1].toLowerCase()) && !collections.aliases.has(this.args[1].toLowerCase())) return "That isn't a command!";
const guildDB = await db.getGuild(this.guild.id);
const disabled = guildDB.disabled_commands ?? guildDB.disabledCommands;
const command = collections.aliases.get(this.args[1].toLowerCase()) ?? this.args[1].toLowerCase();
if (this.args[0].toLowerCase() === "disable") {
if (command === "command") return "You can't disable that command!";
if (disabled?.includes(command)) return "That command is already disabled!";
await db.disableCommand(this.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.guild.id, command);
this.success = true;
return `The command \`${command}\` has been re-enabled.`;
}
}
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;
static directAllowed = false;
static dbRequired = true;
}
export default CommandCommand;

View file

@ -1,54 +1,54 @@
import paginator from "../../utils/pagination/pagination.js";
import database from "../../utils/database.js";
import Command from "../../classes/command.js";
class CountCommand extends Command {
async run() {
if (this.guild && !this.channel.permissionsOf(this.client.user.id.toString()).has("EMBED_LINKS")) {
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)) {
countArray.push(entry);
}
const sortedValues = countArray.sort((a, b) => {
return b[1] - a[1];
});
const countArray2 = [];
for (const [key, value] of sortedValues) {
countArray2.push(`**${key}**: ${value}`);
}
const embeds = [];
const groups = countArray2.map((item, index) => {
return index % 15 === 0 ? countArray2.slice(index, index + 15) : null;
}).filter((item) => {
return item;
});
for (const [i, value] of groups.entries()) {
embeds.push({
embeds: [{
title: "Command Usage Counts",
color: 16711680,
footer: {
text: `Page ${i + 1} of ${groups.length}`
},
description: value.join("\n"),
author: {
name: this.author.username,
iconURL: this.author.avatarURL()
}
}]
});
}
return paginator(this.client, { type: this.type, message: this.message, interaction: this.interaction, channel: this.channel, author: this.author }, embeds);
}
static description = "Gets how many times every command was used";
static arguments = ["{mention/id}"];
static aliases = ["counts"];
static dbRequired = true;
}
import paginator from "../../utils/pagination/pagination.js";
import database from "../../utils/database.js";
import Command from "../../classes/command.js";
class CountCommand extends Command {
async run() {
if (this.guild && !this.channel.permissionsOf(this.client.user.id.toString()).has("EMBED_LINKS")) {
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)) {
countArray.push(entry);
}
const sortedValues = countArray.sort((a, b) => {
return b[1] - a[1];
});
const countArray2 = [];
for (const [key, value] of sortedValues) {
countArray2.push(`**${key}**: ${value}`);
}
const embeds = [];
const groups = countArray2.map((item, index) => {
return index % 15 === 0 ? countArray2.slice(index, index + 15) : null;
}).filter((item) => {
return item;
});
for (const [i, value] of groups.entries()) {
embeds.push({
embeds: [{
title: "Command Usage Counts",
color: 16711680,
footer: {
text: `Page ${i + 1} of ${groups.length}`
},
description: value.join("\n"),
author: {
name: this.author.username,
iconURL: this.author.avatarURL()
}
}]
});
}
return paginator(this.client, { type: this.type, message: this.message, interaction: this.interaction, channel: this.channel, author: this.author }, embeds);
}
static description = "Gets how many times every command was used";
static arguments = ["{mention/id}"];
static aliases = ["counts"];
static dbRequired = true;
}
export default CountCommand;

View file

@ -1,30 +1,30 @@
import { request } from "undici";
import Command from "../../classes/command.js";
class DonateCommand extends Command {
async run() {
await this.acknowledge();
let prefix = "";
const controller = new AbortController();
const timeout = setTimeout(() => {
controller.abort();
}, 5000);
try {
const patrons = await request("https://projectlounge.pw/patrons", { signal: controller.signal }).then(data => data.body.json());
clearTimeout(timeout);
prefix = "Thanks to the following patrons for their support:\n";
for (const patron of patrons) {
prefix += `**- ${patron}**\n`;
}
prefix += "\n";
} catch (e) {
// no-op
}
return `${prefix}Like esmBot? Consider supporting the developer on Patreon to help keep it running! https://patreon.com/TheEssem`;
}
static description = "Learn more about how you can support esmBot's development";
static aliases = ["support", "patreon", "patrons"];
}
import { request } from "undici";
import Command from "../../classes/command.js";
class DonateCommand extends Command {
async run() {
await this.acknowledge();
let prefix = "";
const controller = new AbortController();
const timeout = setTimeout(() => {
controller.abort();
}, 5000);
try {
const patrons = await request("https://projectlounge.pw/patrons", { signal: controller.signal }).then(data => data.body.json());
clearTimeout(timeout);
prefix = "Thanks to the following patrons for their support:\n";
for (const patron of patrons) {
prefix += `**- ${patron}**\n`;
}
prefix += "\n";
} catch (e) {
// no-op
}
return `${prefix}Like esmBot? Consider supporting the developer on Patreon to help keep it running! https://patreon.com/TheEssem`;
}
static description = "Learn more about how you can support esmBot's development";
static aliases = ["support", "patreon", "patrons"];
}
export default DonateCommand;

View file

@ -1,33 +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(/^<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 = [];
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;
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(/^<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 = [];
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;

View file

@ -1,49 +1,49 @@
import { clean } from "../../utils/misc.js";
import Command from "../../classes/command.js";
class EvalCommand extends Command {
async run() {
const owners = process.env.OWNER.split(",");
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 {
let evaled = eval(code);
if (evaled?.constructor?.name == "Promise") evaled = await evaled;
const cleaned = clean(evaled);
const sendString = `\`\`\`js\n${cleaned}\n\`\`\``;
if (sendString.length >= 2000) {
return {
content: "The result was too large, so here it is as a file:",
files: [{
contents: cleaned,
name: "result.txt"
}]
};
} else {
return sendString;
}
} catch (err) {
let error = err;
if (err?.constructor?.name == "Promise") error = await err;
return `\`ERROR\` \`\`\`xl\n${clean(error)}\n\`\`\``;
}
}
static flags = [{
name: "code",
type: 3,
description: "The code to execute",
required: true
}];
static description = "Executes JavaScript code";
static aliases = ["run"];
static arguments = ["[code]"];
static adminOnly = true;
}
import { clean } from "../../utils/misc.js";
import Command from "../../classes/command.js";
class EvalCommand extends Command {
async run() {
const owners = process.env.OWNER.split(",");
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 {
let evaled = eval(code);
if (evaled?.constructor?.name == "Promise") evaled = await evaled;
const cleaned = clean(evaled);
const sendString = `\`\`\`js\n${cleaned}\n\`\`\``;
if (sendString.length >= 2000) {
return {
content: "The result was too large, so here it is as a file:",
files: [{
contents: cleaned,
name: "result.txt"
}]
};
} else {
return sendString;
}
} catch (err) {
let error = err;
if (err?.constructor?.name == "Promise") error = await err;
return `\`ERROR\` \`\`\`xl\n${clean(error)}\n\`\`\``;
}
}
static flags = [{
name: "code",
type: 3,
description: "The code to execute",
required: true
}];
static description = "Executes JavaScript code";
static aliases = ["run"];
static arguments = ["[code]"];
static adminOnly = true;
}
export default EvalCommand;

View file

@ -1,48 +1,48 @@
import { clean } from "../../utils/misc.js";
import * as util from "util";
import { exec as baseExec } from "child_process";
const exec = util.promisify(baseExec);
import Command from "../../classes/command.js";
class ExecCommand extends Command {
async run() {
const owners = process.env.OWNER.split(",");
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 {
const execed = await exec(code);
if (execed.stderr) return `\`ERROR\` \`\`\`xl\n${await clean(execed.stderr)}\n\`\`\``;
const cleaned = await clean(execed.stdout);
const sendString = `\`\`\`bash\n${cleaned}\n\`\`\``;
if (sendString.length >= 2000) {
return {
text: "The result was too large, so here it is as a file:",
file: cleaned,
name: "result.txt"
};
} else {
return sendString;
}
} catch (err) {
return `\`ERROR\` \`\`\`xl\n${await clean(err)}\n\`\`\``;
}
}
static flags = [{
name: "cmd",
type: 3,
description: "The command to execute",
required: true
}];
static description = "Executes a shell command";
static aliases = ["runcmd"];
static arguments = ["[command]"];
static adminOnly = true;
}
import { clean } from "../../utils/misc.js";
import * as util from "util";
import { exec as baseExec } from "child_process";
const exec = util.promisify(baseExec);
import Command from "../../classes/command.js";
class ExecCommand extends Command {
async run() {
const owners = process.env.OWNER.split(",");
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 {
const execed = await exec(code);
if (execed.stderr) return `\`ERROR\` \`\`\`xl\n${await clean(execed.stderr)}\n\`\`\``;
const cleaned = await clean(execed.stdout);
const sendString = `\`\`\`bash\n${cleaned}\n\`\`\``;
if (sendString.length >= 2000) {
return {
text: "The result was too large, so here it is as a file:",
file: cleaned,
name: "result.txt"
};
} else {
return sendString;
}
} catch (err) {
return `\`ERROR\` \`\`\`xl\n${await clean(err)}\n\`\`\``;
}
}
static flags = [{
name: "cmd",
type: 3,
description: "The command to execute",
required: true
}];
static description = "Executes a shell command";
static aliases = ["runcmd"];
static arguments = ["[command]"];
static adminOnly = true;
}
export default ExecCommand;

View file

@ -1,120 +1,120 @@
import { Constants } from "oceanic.js";
import database from "../../utils/database.js";
import * as collections from "../../utils/collections.js";
import { random } from "../../utils/misc.js";
import paginator from "../../utils/pagination/pagination.js";
import * as help from "../../utils/help.js";
import Command from "../../classes/command.js";
const tips = ["You can change the bot's prefix using the prefix command.", "Image commands also work with images previously posted in that channel.", "You can use the tags commands to save things for later use.", "You can visit https://esmbot.net/help.html for a web version of this command list.", "You can view a command's aliases by putting the command name after the help command (e.g. help image).", "Parameters wrapped in [] are required, while parameters wrapped in {} are optional.", "esmBot is hosted and paid for completely out-of-pocket by the main developer. If you want to support development, please consider donating! https://patreon.com/TheEssem"];
class HelpCommand extends Command {
async run() {
let prefix;
if (this.guild && database) {
prefix = (await database.getGuild(this.guild.id)).prefix;
} else {
prefix = process.env.PREFIX;
}
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);
const embed = {
embeds: [{
author: {
name: "esmBot Help",
iconURL: this.client.user.avatarURL()
},
title: `${this.guild ? prefix : ""}${command}`,
url: "https://esmbot.net/help.html",
description: command === "tags" ? "The main tags command. Check the help page for more info: https://esmbot.net/help.html" : info.description,
color: 16711680,
fields: [{
name: "Aliases",
value: info.aliases.length !== 0 ? info.aliases.join(", ") : "None"
}, {
name: "Parameters",
value: command === "tags" ? "[name]" : (info.params ? (info.params.length !== 0 ? info.params.join(" ") : "None") : "None"),
inline: true
}]
}]
};
if (database) {
embed.embeds[0].fields.push({
name: "Times used",
value: (await database.getCounts())[command],
inline: true
});
}
if (info.flags.length !== 0) {
const flagInfo = [];
for (const flag of info.flags) {
if (flag.type === 1) continue;
flagInfo.push(`\`--${flag.name}${flag.type ? `=[${Constants.ApplicationCommandOptionTypes[flag.type]}]` : ""}\` - ${flag.description}`);
}
if (flagInfo.length !== 0) {
embed.embeds[0].fields.push({
"name": "Flags",
"value": flagInfo.join("\n")
});
}
}
return embed;
} else {
if (this.guild && !this.channel.permissionsOf(this.client.user.id.toString()).has("EMBED_LINKS")) {
this.success = false;
return "I don't have the `Embed Links` permission!";
}
const pages = [];
if (help.categories === help.categoryTemplate && !help.generated) help.generateList();
for (const category of Object.keys(help.categories)) {
const splitPages = help.categories[category].map((item, index) => {
return index % 15 === 0 ? help.categories[category].slice(index, index + 15) : null;
}).filter((item) => {
return item;
});
const categoryStringArray = category.split("-");
for (const index of categoryStringArray.keys()) {
categoryStringArray[index] = categoryStringArray[index].charAt(0).toUpperCase() + categoryStringArray[index].slice(1);
}
for (const page of splitPages) {
pages.push({
title: categoryStringArray.join(" "),
page: page
});
}
}
const embeds = [];
for (const [i, value] of pages.entries()) {
embeds.push({
embeds: [{
author: {
name: "esmBot Help",
iconURL: this.client.user.avatarURL()
},
title: value.title,
description: value.page.join("\n"),
color: 16711680,
footer: {
text: `Page ${i + 1} of ${pages.length}`
},
fields: [{
name: "Prefix",
value: prefix
}, {
name: "Tip",
value: random(tips)
}]
}]
});
}
return paginator(this.client, { type: this.type, message: this.message, interaction: this.interaction, author: this.author }, embeds);
}
}
static description = "Gets a list of commands";
static aliases = ["commands"];
static arguments = ["{command}"];
static slashAllowed = false;
}
export default HelpCommand;
import { Constants } from "oceanic.js";
import database from "../../utils/database.js";
import * as collections from "../../utils/collections.js";
import { random } from "../../utils/misc.js";
import paginator from "../../utils/pagination/pagination.js";
import * as help from "../../utils/help.js";
import Command from "../../classes/command.js";
const tips = ["You can change the bot's prefix using the prefix command.", "Image commands also work with images previously posted in that channel.", "You can use the tags commands to save things for later use.", "You can visit https://esmbot.net/help.html for a web version of this command list.", "You can view a command's aliases by putting the command name after the help command (e.g. help image).", "Parameters wrapped in [] are required, while parameters wrapped in {} are optional.", "esmBot is hosted and paid for completely out-of-pocket by the main developer. If you want to support development, please consider donating! https://patreon.com/TheEssem"];
class HelpCommand extends Command {
async run() {
let prefix;
if (this.guild && database) {
prefix = (await database.getGuild(this.guild.id)).prefix;
} else {
prefix = process.env.PREFIX;
}
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);
const embed = {
embeds: [{
author: {
name: "esmBot Help",
iconURL: this.client.user.avatarURL()
},
title: `${this.guild ? prefix : ""}${command}`,
url: "https://esmbot.net/help.html",
description: command === "tags" ? "The main tags command. Check the help page for more info: https://esmbot.net/help.html" : info.description,
color: 16711680,
fields: [{
name: "Aliases",
value: info.aliases.length !== 0 ? info.aliases.join(", ") : "None"
}, {
name: "Parameters",
value: command === "tags" ? "[name]" : (info.params ? (info.params.length !== 0 ? info.params.join(" ") : "None") : "None"),
inline: true
}]
}]
};
if (database) {
embed.embeds[0].fields.push({
name: "Times used",
value: (await database.getCounts())[command],
inline: true
});
}
if (info.flags.length !== 0) {
const flagInfo = [];
for (const flag of info.flags) {
if (flag.type === 1) continue;
flagInfo.push(`\`--${flag.name}${flag.type ? `=[${Constants.ApplicationCommandOptionTypes[flag.type]}]` : ""}\` - ${flag.description}`);
}
if (flagInfo.length !== 0) {
embed.embeds[0].fields.push({
"name": "Flags",
"value": flagInfo.join("\n")
});
}
}
return embed;
} else {
if (this.guild && !this.channel.permissionsOf(this.client.user.id.toString()).has("EMBED_LINKS")) {
this.success = false;
return "I don't have the `Embed Links` permission!";
}
const pages = [];
if (help.categories === help.categoryTemplate && !help.generated) help.generateList();
for (const category of Object.keys(help.categories)) {
const splitPages = help.categories[category].map((item, index) => {
return index % 15 === 0 ? help.categories[category].slice(index, index + 15) : null;
}).filter((item) => {
return item;
});
const categoryStringArray = category.split("-");
for (const index of categoryStringArray.keys()) {
categoryStringArray[index] = categoryStringArray[index].charAt(0).toUpperCase() + categoryStringArray[index].slice(1);
}
for (const page of splitPages) {
pages.push({
title: categoryStringArray.join(" "),
page: page
});
}
}
const embeds = [];
for (const [i, value] of pages.entries()) {
embeds.push({
embeds: [{
author: {
name: "esmBot Help",
iconURL: this.client.user.avatarURL()
},
title: value.title,
description: value.page.join("\n"),
color: 16711680,
footer: {
text: `Page ${i + 1} of ${pages.length}`
},
fields: [{
name: "Prefix",
value: prefix
}, {
name: "Tip",
value: random(tips)
}]
}]
});
}
return paginator(this.client, { type: this.type, message: this.message, interaction: this.interaction, author: this.author }, embeds);
}
}
static description = "Gets a list of commands";
static aliases = ["commands"];
static arguments = ["{command}"];
static slashAllowed = false;
}
export default HelpCommand;

View file

@ -1,54 +1,54 @@
import paginator from "../../utils/pagination/pagination.js";
import { readFileSync } from "fs";
const { searx } = JSON.parse(readFileSync(new URL("../../config/servers.json", import.meta.url)));
import { random } from "../../utils/misc.js";
import { request } from "undici";
import Command from "../../classes/command.js";
class ImageSearchCommand extends Command {
async run() {
this.success = false;
if (this.channel && !this.channel.permissionsOf(this.client.user.id.toString()).has("EMBED_LINKS")) 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!";
await this.acknowledge();
const embeds = [];
const rawImages = await request(`${random(searx)}/search?format=json&safesearch=2&categories=images&q=!goi%20!ddi%20${encodeURIComponent(query)}`).then(res => res.body.json());
if (rawImages.results.length === 0) return "I couldn't find any results!";
const images = rawImages.results.filter((val) => !val.img_src.startsWith("data:"));
for (const [i, value] of images.entries()) {
embeds.push({
embeds: [{
title: "Search Results",
color: 16711680,
footer: {
text: `Page ${i + 1} of ${images.length}`
},
description: value.title,
image: {
url: encodeURI(value.img_src)
},
author: {
name: this.author.username,
iconURL: this.author.avatarURL()
}
}]
});
}
this.success = true;
return paginator(this.client, { type: this.type, message: this.message, interaction: this.interaction, channel: this.channel, author: this.author }, embeds);
}
static flags = [{
name: "query",
type: 3,
description: "The query you want to search for",
required: true
}];
static description = "Searches for images across the web";
static aliases = ["im", "photo", "img"];
static arguments = ["[query]"];
}
import paginator from "../../utils/pagination/pagination.js";
import { readFileSync } from "fs";
const { searx } = JSON.parse(readFileSync(new URL("../../config/servers.json", import.meta.url)));
import { random } from "../../utils/misc.js";
import { request } from "undici";
import Command from "../../classes/command.js";
class ImageSearchCommand extends Command {
async run() {
this.success = false;
if (this.channel && !this.channel.permissionsOf(this.client.user.id.toString()).has("EMBED_LINKS")) 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!";
await this.acknowledge();
const embeds = [];
const rawImages = await request(`${random(searx)}/search?format=json&safesearch=2&categories=images&q=!goi%20!ddi%20${encodeURIComponent(query)}`).then(res => res.body.json());
if (rawImages.results.length === 0) return "I couldn't find any results!";
const images = rawImages.results.filter((val) => !val.img_src.startsWith("data:"));
for (const [i, value] of images.entries()) {
embeds.push({
embeds: [{
title: "Search Results",
color: 16711680,
footer: {
text: `Page ${i + 1} of ${images.length}`
},
description: value.title,
image: {
url: encodeURI(value.img_src)
},
author: {
name: this.author.username,
iconURL: this.author.avatarURL()
}
}]
});
}
this.success = true;
return paginator(this.client, { type: this.type, message: this.message, interaction: this.interaction, channel: this.channel, author: this.author }, embeds);
}
static flags = [{
name: "query",
type: 3,
description: "The query you want to search for",
required: true
}];
static description = "Searches for images across the web";
static aliases = ["im", "photo", "img"];
static arguments = ["[query]"];
}
export default ImageSearchCommand;

View file

@ -1,32 +1,32 @@
import Command from "../../classes/command.js";
import { reloadImageConnections } from "../../utils/image.js";
class ImageReloadCommand extends Command {
async run() {
const owners = process.env.OWNER.split(",");
if (!owners.includes(this.author.id)) {
this.success = false;
return "Only the bot owner can reload the image servers!";
}
await this.acknowledge();
const length = await reloadImageConnections();
if (!length) {
if (process.env.PM2_USAGE) {
process.send({
type: "process:msg",
data: {
type: "imagereload"
}
});
}
return `Successfully connected to ${length} image server(s).`;
} else {
return "I couldn't connect to any image servers!";
}
}
static description = "Attempts to reconnect to all available image processing servers";
static adminOnly = true;
}
export default ImageReloadCommand;
import Command from "../../classes/command.js";
import { reloadImageConnections } from "../../utils/image.js";
class ImageReloadCommand extends Command {
async run() {
const owners = process.env.OWNER.split(",");
if (!owners.includes(this.author.id)) {
this.success = false;
return "Only the bot owner can reload the image servers!";
}
await this.acknowledge();
const length = await reloadImageConnections();
if (!length) {
if (process.env.PM2_USAGE) {
process.send({
type: "process:msg",
data: {
type: "imagereload"
}
});
}
return `Successfully connected to ${length} image server(s).`;
} else {
return "I couldn't connect to any image servers!";
}
}
static description = "Attempts to reconnect to all available image processing servers";
static adminOnly = true;
}
export default ImageReloadCommand;

View file

@ -1,34 +1,34 @@
import Command from "../../classes/command.js";
import { connections } from "../../utils/image.js";
class ImageStatsCommand extends Command {
async run() {
await this.acknowledge();
const embed = {
embeds: [{
"author": {
"name": "esmBot Image Statistics",
"iconURL": this.client.user.avatarURL()
},
"color": 16711680,
"description": `The bot is currently connected to ${connections.size} image server(s).`,
"fields": []
}]
};
let i = 0;
for (const connection of connections.values()) {
const count = await connection.getCount();
if (!count) continue;
embed.embeds[0].fields.push({
name: `Server ${i++}`,
value: `Running Jobs: ${count}`
});
}
return embed;
}
static description = "Gets some statistics about the image servers";
static aliases = ["imgstat", "imstats", "imgstats", "imstat"];
}
export default ImageStatsCommand;
import Command from "../../classes/command.js";
import { connections } from "../../utils/image.js";
class ImageStatsCommand extends Command {
async run() {
await this.acknowledge();
const embed = {
embeds: [{
"author": {
"name": "esmBot Image Statistics",
"iconURL": this.client.user.avatarURL()
},
"color": 16711680,
"description": `The bot is currently connected to ${connections.size} image server(s).`,
"fields": []
}]
};
let i = 0;
for (const connection of connections.values()) {
const count = await connection.getCount();
if (!count) continue;
embed.embeds[0].fields.push({
name: `Server ${i++}`,
value: `Running Jobs: ${count}`
});
}
return embed;
}
static description = "Gets some statistics about the image servers";
static aliases = ["imgstat", "imstats", "imgstats", "imstat"];
}
export default ImageStatsCommand;

View file

@ -1,57 +1,57 @@
import { readFileSync } from "fs";
const { version } = JSON.parse(readFileSync(new URL("../../package.json", import.meta.url)));
import Command from "../../classes/command.js";
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 {
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";
static aliases = ["botinfo", "credits"];
}
import { readFileSync } from "fs";
const { version } = JSON.parse(readFileSync(new URL("../../package.json", import.meta.url)));
import Command from "../../classes/command.js";
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 {
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";
static aliases = ["botinfo", "credits"];
}
export default InfoCommand;

View file

@ -1,32 +1,32 @@
import urlCheck from "../../utils/urlcheck.js";
import { request } from "undici";
import Command from "../../classes/command.js";
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!";
}
}
static flags = [{
name: "url",
type: 3,
description: "The URL you want to lengthen",
required: true
}];
static description = "Lengthens a short URL";
static aliases = ["longurl", "lengthenurl", "longuri", "lengthenuri", "unshorten"];
static arguments = ["[url]"];
}
import urlCheck from "../../utils/urlcheck.js";
import { request } from "undici";
import Command from "../../classes/command.js";
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!";
}
}
static flags = [{
name: "url",
type: 3,
description: "The URL you want to lengthen",
required: true
}];
static description = "Lengthens a short URL";
static aliases = ["longurl", "lengthenurl", "longuri", "lengthenuri", "unshorten"];
static arguments = ["[url]"];
}
export default LengthenCommand;

View file

@ -1,27 +1,27 @@
import Command from "../../classes/command.js";
class PingCommand extends Command {
async run() {
if (this.type === "classic") {
const pingMessage = await this.client.rest.channels.createMessage(this.message.channelID, Object.assign({
content: "🏓 Ping?"
}, this.reference));
await pingMessage.edit({
content: `🏓 Pong!\n\`\`\`\nLatency: ${pingMessage.timestamp - this.message.timestamp}ms${this.message.guildID ? `\nShard Latency: ${Math.round(this.client.shards.get(this.client.guildShardMap[this.message.guildID]).latency)}ms` : ""}\n\`\`\``
});
} else {
await this.interaction.createMessage({
content: "🏓 Ping?"
});
const pingMessage = await this.interaction.getOriginal();
await this.interaction.editOriginal({
content: `🏓 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";
static aliases = ["pong"];
}
import Command from "../../classes/command.js";
class PingCommand extends Command {
async run() {
if (this.type === "classic") {
const pingMessage = await this.client.rest.channels.createMessage(this.message.channelID, Object.assign({
content: "🏓 Ping?"
}, this.reference));
await pingMessage.edit({
content: `🏓 Pong!\n\`\`\`\nLatency: ${pingMessage.timestamp - this.message.timestamp}ms${this.message.guildID ? `\nShard Latency: ${Math.round(this.client.shards.get(this.client.guildShardMap[this.message.guildID]).latency)}ms` : ""}\n\`\`\``
});
} else {
await this.interaction.createMessage({
content: "🏓 Ping?"
});
const pingMessage = await this.interaction.getOriginal();
await this.interaction.editOriginal({
content: `🏓 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";
static aliases = ["pong"];
}
export default PingCommand;

View file

@ -1,30 +1,30 @@
import database from "../../utils/database.js";
import Command from "../../classes/command.js";
class PrefixCommand extends Command {
async run() {
if (!this.guild) return `The current prefix is \`${process.env.PREFIX}\`.`;
const guild = await database.getGuild(this.guild.id);
if (this.args.length !== 0) {
if (!database) {
return "Setting a per-guild prefix is not possible on a stateless instance of esmBot!";
}
const owners = process.env.OWNER.split(",");
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.guild);
return `The prefix has been changed to ${this.args[0]}.`;
} else {
return `The current prefix is \`${guild.prefix}\`.`;
}
}
static description = "Checks/changes the server prefix";
static aliases = ["setprefix", "changeprefix", "checkprefix"];
static arguments = ["{prefix}"];
static slashAllowed = false;
}
import database from "../../utils/database.js";
import Command from "../../classes/command.js";
class PrefixCommand extends Command {
async run() {
if (!this.guild) return `The current prefix is \`${process.env.PREFIX}\`.`;
const guild = await database.getGuild(this.guild.id);
if (this.args.length !== 0) {
if (!database) {
return "Setting a per-guild prefix is not possible on a stateless instance of esmBot!";
}
const owners = process.env.OWNER.split(",");
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.guild);
return `The prefix has been changed to ${this.args[0]}.`;
} else {
return `The current prefix is \`${guild.prefix}\`.`;
}
}
static description = "Checks/changes the server prefix";
static aliases = ["setprefix", "changeprefix", "checkprefix"];
static arguments = ["{prefix}"];
static slashAllowed = false;
}
export default PrefixCommand;

View file

@ -1,40 +1,40 @@
import qrcode from "qrcode";
import { PassThrough } from "stream";
import Command from "../../classes/command.js";
class QrCreateCommand extends Command {
async run() {
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 });
const file = await this.streamToBuf(writable);
return {
contents: file,
name: "qr.png"
};
}
streamToBuf(stream) {
return new Promise((resolve, reject) => {
const chunks = [];
stream.on("data", (chunk) => {
chunks.push(chunk);
});
stream.once("error", (error) => {
reject(error);
});
stream.once("end", () => {
resolve(Buffer.concat(chunks));
});
});
}
static description = "Generates a QR code";
static arguments = ["[text]"];
}
import qrcode from "qrcode";
import { PassThrough } from "stream";
import Command from "../../classes/command.js";
class QrCreateCommand extends Command {
async run() {
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 });
const file = await this.streamToBuf(writable);
return {
contents: file,
name: "qr.png"
};
}
streamToBuf(stream) {
return new Promise((resolve, reject) => {
const chunks = [];
stream.on("data", (chunk) => {
chunks.push(chunk);
});
stream.once("error", (error) => {
reject(error);
});
stream.once("end", () => {
resolve(Buffer.concat(chunks));
});
});
}
static description = "Generates a QR code";
static arguments = ["[text]"];
}
export default QrCreateCommand;

View file

@ -1,34 +1,34 @@
import jsqr from "jsqr";
import { request } from "undici";
import sharp from "sharp";
import { clean } from "../../utils/misc.js";
import Command from "../../classes/command.js";
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\`\`\``;
}
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;
import jsqr from "jsqr";
import { request } from "undici";
import sharp from "sharp";
import { clean } from "../../utils/misc.js";
import Command from "../../classes/command.js";
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\`\`\``;
}
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

@ -1,28 +1,28 @@
import Command from "../../classes/command.js";
import imageDetect from "../../utils/imagedetect.js";
class RawCommand extends Command {
async run() {
await this.acknowledge();
const image = await imageDetect(this.client, this.message, this.interaction, this.options);
if (image === undefined) {
this.success = false;
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 = ["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;
import Command from "../../classes/command.js";
import imageDetect from "../../utils/imagedetect.js";
class RawCommand extends Command {
async run() {
await this.acknowledge();
const image = await imageDetect(this.client, this.message, this.interaction, this.options);
if (image === undefined) {
this.success = false;
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 = ["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

@ -1,40 +1,40 @@
import Command from "../../classes/command.js";
import { load } from "../../utils/handler.js";
import { paths } from "../../utils/collections.js";
class ReloadCommand extends Command {
async run() {
const owners = process.env.OWNER.split(",");
if (!owners.includes(this.author.id)) return "Only the bot owner can reload commands!";
const commandName = this.options.cmd ?? this.args.join(" ");
if (!commandName || !commandName.trim()) return "You need to provide a command to reload!";
await this.acknowledge();
const path = paths.get(commandName);
if (!path) return "I couldn't find that command!";
const result = await load(this.client, path, true);
if (result !== commandName) return "I couldn't reload that command!";
if (process.env.PM2_USAGE) {
process.send({
type: "process:msg",
data: {
type: "reload",
message: commandName
}
});
}
return `The command \`${commandName}\` has been reloaded.`;
}
static flags = [{
name: "cmd",
type: 3,
description: "The command to reload",
required: true
}];
static description = "Reloads a command";
static arguments = ["[command]"];
static adminOnly = true;
}
export default ReloadCommand;
import Command from "../../classes/command.js";
import { load } from "../../utils/handler.js";
import { paths } from "../../utils/collections.js";
class ReloadCommand extends Command {
async run() {
const owners = process.env.OWNER.split(",");
if (!owners.includes(this.sender)) return "Only the bot owner can reload commands!";
const commandName = this.options.cmd ?? this.args.join(" ");
if (!commandName || !commandName.trim()) return "You need to provide a command to reload!";
await this.acknowledge();
const path = paths.get(commandName);
if (!path) return "I couldn't find that command!";
const result = await load(this.matrixClient, path, true);
if (result !== commandName) return "I couldn't reload that command!";
if (process.env.PM2_USAGE) {
process.send({
type: "process:msg",
data: {
type: "reload",
message: commandName
}
});
}
return `The command \`${commandName}\` has been reloaded.`;
}
static flags = [{
name: "cmd",
type: 3,
description: "The command to reload",
required: true
}];
static description = "Reloads a command";
static arguments = ["[command]"];
static adminOnly = true;
}
export default ReloadCommand;

View file

@ -1,21 +1,21 @@
import Command from "../../classes/command.js";
class RestartCommand extends Command {
async run() {
const owners = process.env.OWNER.split(",");
if (!owners.includes(this.author.id)) {
this.success = false;
return "Only the bot owner can restart me!";
}
await this.channel.createMessage(Object.assign({
content: "esmBot is restarting."
}, this.reference));
process.exit(1);
}
static description = "Restarts me";
static aliases = ["reboot"];
static adminOnly = true;
}
import Command from "../../classes/command.js";
class RestartCommand extends Command {
async run() {
const owners = process.env.OWNER.split(",");
if (!owners.includes(this.author.id)) {
this.success = false;
return "Only the bot owner can restart me!";
}
await this.channel.createMessage(Object.assign({
content: "esmBot is restarting."
}, this.reference));
process.exit(1);
}
static description = "Restarts me";
static aliases = ["reboot"];
static adminOnly = true;
}
export default RestartCommand;

View file

@ -1,20 +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(/^<?[@#]?[&!]?\d+>?$/) && 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 `<t:${id}:F>`;
}
static description = "Converts a Discord snowflake id into a timestamp";
static aliases = ["timestamp", "snowstamp", "snow"];
static arguments = ["[id]"];
static slashAllowed = false;
}
export default SnowflakeCommand;
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!";
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 `<t:${id}:F>`;
}
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

@ -1,33 +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.id)) {
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;
}
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.id)) {
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;

View file

@ -1,90 +1,90 @@
import { readFileSync } from "fs";
const { version } = JSON.parse(readFileSync(new URL("../../package.json", import.meta.url)));
import os from "os";
import Command from "../../classes/command.js";
import { VERSION } from "oceanic.js";
import pm2 from "pm2";
import { getServers } from "../../utils/misc.js";
class StatsCommand extends Command {
async run() {
const uptime = process.uptime() * 1000;
const connUptime = this.client.uptime;
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);
const processMem = `${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2)} MB`;
return {
embeds: [{
"author": {
"name": "esmBot Statistics",
"iconURL": this.client.user.avatarURL()
},
"description": `This instance is managed by **${owner.username}#${owner.discriminator}**.`,
"color": 16711680,
"fields": [{
"name": "Version",
"value": `v${version}${process.env.NODE_ENV === "development" ? `-dev (${process.env.GIT_REV})` : ""}`
},
{
"name": "Process Memory Usage",
"value": processMem,
"inline": true
},
{
"name": "Total Memory Usage",
"value": process.env.PM2_USAGE ? `${((await this.list()).reduce((prev, cur) => prev + cur.monit.memory, 0) / 1024 / 1024).toFixed(2)} MB` : processMem,
"inline": true
},
{
"name": "Bot Uptime",
"value": `${Math.trunc(uptime / 86400000)} days, ${Math.trunc(uptime / 3600000) % 24} hrs, ${Math.trunc(uptime / 60000) % 60} mins, ${Math.trunc(uptime / 1000) % 60} secs`
},
{
"name": "Connection Uptime",
"value": `${Math.trunc(connUptime / 86400000)} days, ${Math.trunc(connUptime / 3600000) % 24} hrs, ${Math.trunc(connUptime / 60000) % 60} mins, ${Math.trunc(connUptime / 1000) % 60} secs`
},
{
"name": "Host",
"value": `${os.type()} ${os.release()} (${os.arch()})`,
"inline": true
},
{
"name": "Library",
"value": `Oceanic ${VERSION}`,
"inline": true
},
{
"name": "Node.js Version",
"value": process.version,
"inline": true
},
{
"name": "Shard",
"value": this.guild ? this.client.guildShardMap[this.guild.id] : "N/A",
"inline": true
},
{
"name": "Servers",
"value": servers ? servers : `${this.client.guilds.size} (for this process only)`,
"inline": true
}
]
}]
};
}
list() {
return new Promise((resolve, reject) => {
pm2.list((err, list) => {
if (err) return reject(err);
resolve(list.filter((v) => v.name.includes("esmBot-proc")));
});
});
}
static description = "Gets some statistics about me";
static aliases = ["status", "stat"];
}
import { readFileSync } from "fs";
const { version } = JSON.parse(readFileSync(new URL("../../package.json", import.meta.url)));
import os from "os";
import Command from "../../classes/command.js";
import { VERSION } from "oceanic.js";
import pm2 from "pm2";
import { getServers } from "../../utils/misc.js";
class StatsCommand extends Command {
async run() {
const uptime = process.uptime() * 1000;
const connUptime = this.client.uptime;
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);
const processMem = `${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2)} MB`;
return {
embeds: [{
"author": {
"name": "esmBot Statistics",
"iconURL": this.client.user.avatarURL()
},
"description": `This instance is managed by **${owner.username}#${owner.discriminator}**.`,
"color": 16711680,
"fields": [{
"name": "Version",
"value": `v${version}${process.env.NODE_ENV === "development" ? `-dev (${process.env.GIT_REV})` : ""}`
},
{
"name": "Process Memory Usage",
"value": processMem,
"inline": true
},
{
"name": "Total Memory Usage",
"value": process.env.PM2_USAGE ? `${((await this.list()).reduce((prev, cur) => prev + cur.monit.memory, 0) / 1024 / 1024).toFixed(2)} MB` : processMem,
"inline": true
},
{
"name": "Bot Uptime",
"value": `${Math.trunc(uptime / 86400000)} days, ${Math.trunc(uptime / 3600000) % 24} hrs, ${Math.trunc(uptime / 60000) % 60} mins, ${Math.trunc(uptime / 1000) % 60} secs`
},
{
"name": "Connection Uptime",
"value": `${Math.trunc(connUptime / 86400000)} days, ${Math.trunc(connUptime / 3600000) % 24} hrs, ${Math.trunc(connUptime / 60000) % 60} mins, ${Math.trunc(connUptime / 1000) % 60} secs`
},
{
"name": "Host",
"value": `${os.type()} ${os.release()} (${os.arch()})`,
"inline": true
},
{
"name": "Library",
"value": `Oceanic ${VERSION}`,
"inline": true
},
{
"name": "Node.js Version",
"value": process.version,
"inline": true
},
{
"name": "Shard",
"value": this.guild ? this.client.guildShardMap[this.guild.id] : "N/A",
"inline": true
},
{
"name": "Servers",
"value": servers ? servers : `${this.client.guilds.size} (for this process only)`,
"inline": true
}
]
}]
};
}
list() {
return new Promise((resolve, reject) => {
pm2.list((err, list) => {
if (err) return reject(err);
resolve(list.filter((v) => v.name.includes("esmBot-proc")));
});
});
}
static description = "Gets some statistics about me";
static aliases = ["status", "stat"];
}
export default StatsCommand;

View file

@ -1,36 +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]"];
}
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;

View file

@ -1,36 +1,35 @@
import { request } from "undici";
import { readFileSync } from "fs";
const { searx } = JSON.parse(readFileSync(new URL("../../config/servers.json", import.meta.url)));
import { random } from "../../utils/misc.js";
import paginator from "../../utils/pagination/pagination.js";
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 = [];
const videos = await request(`${random(searx)}/search?format=json&safesearch=1&categories=videos&q=!youtube%20${encodeURIComponent(query)}`).then(res => res.body.json());
if (videos.results.length === 0) return "I couldn't find any results!";
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);
}
static flags = [{
name: "query",
type: 3,
description: "The query you want to search for",
required: true
}];
static description = "Searches YouTube";
static aliases = ["yt", "video", "ytsearch"];
static arguments = ["[query]"];
}
import { request } from "undici";
import { readFileSync } from "fs";
const { searx } = JSON.parse(readFileSync(new URL("../../config/servers.json", import.meta.url)));
import { random } from "../../utils/misc.js";
// import paginator from "../../utils/pagination/pagination.js";
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 = [];
const videos = await request(`${random(searx)}/search?format=json&safesearch=1&categories=videos&q=!youtube%20${encodeURIComponent(query)}`).then(res => res.body.json());
if (videos.results.length === 0) return "I couldn't find any results!";
// console.log(videos.results[0])
this.success = true;
return videos.results[0].url
// return paginator(this.client, { type: this.type, message: this.message, interaction: this.interaction, channel: this.channel, author: this.author }, messages);
}
static flags = [{
name: "query",
type: 3,
description: "The query you want to search for",
required: true
}];
static description = "Searches YouTube";
static aliases = ["yt", "video", "ytsearch"];
static arguments = ["[query]"];
}
export default YouTubeCommand;

View file

@ -1,16 +1,16 @@
import ImageCommand from "../../classes/imageCommand.js";
class NineGagCommand extends ImageCommand {
params = {
water: "assets/images/9gag.png",
gravity: 6
};
static description = "Adds the 9GAG watermark to an image";
static aliases = ["ninegag", "gag"];
static noImage = "You need to provide an image/GIF to add a 9GAG watermark!";
static command = "watermark";
}
export default NineGagCommand;
import ImageCommand from "../../classes/imageCommand.js";
class NineGagCommand extends ImageCommand {
params = {
water: "assets/images/9gag.png",
gravity: 6
};
static description = "Adds the 9GAG watermark to an image";
static aliases = ["ninegag", "gag"];
static noImage = "You need to provide an image/GIF to add a 9GAG watermark!";
static command = "watermark";
}
export default NineGagCommand;

View file

@ -1,17 +1,17 @@
import ImageCommand from "../../classes/imageCommand.js";
class AVSCommand extends ImageCommand {
params = {
water: "assets/images/avs4you.png",
gravity: 5,
resize: true
};
static description = "Adds the avs4you watermark to an image";
static aliases = ["a4y", "avs"];
static noImage = "You need to provide an image/GIF to add an avs4you watermark!";
static command = "watermark";
}
export default AVSCommand;
import ImageCommand from "../../classes/imageCommand.js";
class AVSCommand extends ImageCommand {
params = {
water: "assets/images/avs4you.png",
gravity: 5,
resize: true
};
static description = "Adds the avs4you watermark to an image";
static aliases = ["a4y", "avs"];
static noImage = "You need to provide an image/GIF to add an avs4you watermark!";
static command = "watermark";
}
export default AVSCommand;

View file

@ -1,17 +1,17 @@
import ImageCommand from "../../classes/imageCommand.js";
class BandicamCommand extends ImageCommand {
params = {
water: "assets/images/bandicam.png",
gravity: 2,
resize: true
};
static description = "Adds the Bandicam watermark to an image";
static aliases = ["bandi"];
static noImage = "You need to provide an image/GIF to add a Bandicam watermark!";
static command = "watermark";
}
export default BandicamCommand;
import ImageCommand from "../../classes/imageCommand.js";
class BandicamCommand extends ImageCommand {
params = {
water: "assets/images/bandicam.png",
gravity: 2,
resize: true
};
static description = "Adds the Bandicam watermark to an image";
static aliases = ["bandi"];
static noImage = "You need to provide an image/GIF to add a Bandicam watermark!";
static command = "watermark";
}
export default BandicamCommand;

View file

@ -1,14 +1,14 @@
import ImageCommand from "../../classes/imageCommand.js";
class BlurCommand extends ImageCommand {
params = {
sharp: false
};
static description = "Blurs an image";
static noImage = "You need to provide an image/GIF to blur!";
static command = "blur";
}
export default BlurCommand;
import ImageCommand from "../../classes/imageCommand.js";
class BlurCommand extends ImageCommand {
params = {
sharp: false
};
static description = "Blurs an image";
static noImage = "You need to provide an image/GIF to blur!";
static command = "blur";
}
export default BlurCommand;

View file

@ -1,11 +1,11 @@
import ImageCommand from "../../classes/imageCommand.js";
class BounceCommand extends ImageCommand {
static description = "Makes an image bounce up and down";
static aliases = ["bouncy"];
static noImage = "You need to provide an image/GIF to bounce!";
static command = "bounce";
}
export default BounceCommand;
import ImageCommand from "../../classes/imageCommand.js";
class BounceCommand extends ImageCommand {
static description = "Makes an image bounce up and down";
static aliases = ["bouncy"];
static noImage = "You need to provide an image/GIF to bounce!";
static command = "bounce";
}
export default BounceCommand;

View file

@ -1,46 +1,46 @@
import ImageCommand from "../../classes/imageCommand.js";
import { cleanMessage } from "../../utils/misc.js";
class CaptionCommand extends ImageCommand {
params(url) {
const newArgs = this.options.text ?? this.args.filter(item => !item.includes(url)).join(" ");
let newCaption = cleanMessage(this.message ?? this.interaction, newArgs);
if (process.env.NODE_ENV === "development" && newCaption.toLowerCase() === "get real" && !this.options.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,
font: typeof this.options.font === "string" && this.constructor.allowedFonts.includes(this.options.font.toLowerCase()) ? this.options.font.toLowerCase() : "futura"
};
}
static init() {
super.init();
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 this.allowedFonts) {
array.push({ name: font, value: font });
}
return array;
})(),
description: "Specify the font you want to use (default: futura)"
});
return this;
}
static description = "Adds a caption to an image";
static aliases = ["gifc", "gcaption", "ifcaption", "ifunnycaption"];
static arguments = ["[text]"];
static requiresText = 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 = "caption";
}
export default CaptionCommand;
import ImageCommand from "../../classes/imageCommand.js";
import { cleanMessage } from "../../utils/misc.js";
class CaptionCommand extends ImageCommand {
params(url) {
const newArgs = this.options.text ?? this.args.filter(item => !item.includes(url)).join(" ");
let newCaption = cleanMessage(this.message ?? this.interaction, newArgs);
if (process.env.NODE_ENV === "development" && newCaption.toLowerCase() === "get real" && !this.options.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,
font: typeof this.options.font === "string" && this.constructor.allowedFonts.includes(this.options.font.toLowerCase()) ? this.options.font.toLowerCase() : "futura"
};
}
static init() {
super.init();
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 this.allowedFonts) {
array.push({ name: font, value: font });
}
return array;
})(),
description: "Specify the font you want to use (default: futura)"
});
return this;
}
static description = "Adds a caption to an image";
static aliases = ["gifc", "gcaption", "ifcaption", "ifunnycaption"];
static arguments = ["[text]"];
static requiresText = 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 = "caption";
}
export default CaptionCommand;

View file

@ -1,46 +1,46 @@
import ImageCommand from "../../classes/imageCommand.js";
import { cleanMessage } from "../../utils/misc.js";
const words = ["me irl", "dank", "follow my second account @esmBot_", "2016", "meme", "wholesome", "reddit", "instagram", "twitter", "facebook", "fortnite", "minecraft", "relatable", "gold", "funny", "template", "hilarious", "memes", "deep fried", "2020", "leafy", "pewdiepie"];
class CaptionTwoCommand extends ImageCommand {
params(url) {
const newArgs = this.options.text ?? this.args.filter(item => !item.includes(url)).join(" ");
return {
caption: newArgs && newArgs.trim() ? cleanMessage(this.message ?? this.interaction, newArgs) : words.sort(() => 0.5 - Math.random()).slice(0, Math.floor(Math.random() * words.length + 1)).join(" "),
top: !!this.options.top,
font: typeof this.options.font === "string" && this.constructor.allowedFonts.includes(this.options.font.toLowerCase()) ? this.options.font.toLowerCase() : "helvetica"
};
}
static init() {
super.init();
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 this.allowedFonts) {
array.push({ name: font, value: font });
}
return array;
})(),
description: "Specify the font you want to use (default: helvetica)"
});
return this;
}
static description = "Adds a me.me caption/tag list to an image";
static aliases = ["tags2", "meirl", "memecaption", "medotmecaption"];
static arguments = ["{text}"];
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";
}
export default CaptionTwoCommand;
import ImageCommand from "../../classes/imageCommand.js";
import { cleanMessage } from "../../utils/misc.js";
const words = ["me irl", "dank", "follow my second account @esmBot_", "2016", "meme", "wholesome", "reddit", "instagram", "twitter", "facebook", "fortnite", "minecraft", "relatable", "gold", "funny", "template", "hilarious", "memes", "deep fried", "2020", "leafy", "pewdiepie"];
class CaptionTwoCommand extends ImageCommand {
params(url) {
const newArgs = this.options.text ?? this.args.filter(item => !item.includes(url)).join(" ");
return {
caption: newArgs && newArgs.trim() ? cleanMessage(this.message ?? this.interaction, newArgs) : words.sort(() => 0.5 - Math.random()).slice(0, Math.floor(Math.random() * words.length + 1)).join(" "),
top: !!this.options.top,
font: typeof this.options.font === "string" && this.constructor.allowedFonts.includes(this.options.font.toLowerCase()) ? this.options.font.toLowerCase() : "helvetica"
};
}
static init() {
super.init();
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 this.allowedFonts) {
array.push({ name: font, value: font });
}
return array;
})(),
description: "Specify the font you want to use (default: helvetica)"
});
return this;
}
static description = "Adds a me.me caption/tag list to an image";
static aliases = ["tags2", "meirl", "memecaption", "medotmecaption"];
static arguments = ["{text}"];
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";
}
export default CaptionTwoCommand;

View file

@ -1,11 +1,11 @@
import ImageCommand from "../../classes/imageCommand.js";
class CircleCommand extends ImageCommand {
static description = "Applies a radial blur effect on an image";
static aliases = ["cblur", "radial", "radialblur"];
static noImage = "You need to provide an image/GIF to add radial blur!";
static command = "circle";
}
export default CircleCommand;
import ImageCommand from "../../classes/imageCommand.js";
class CircleCommand extends ImageCommand {
static description = "Applies a radial blur effect on an image";
static aliases = ["cblur", "radial", "radialblur"];
static noImage = "You need to provide an image/GIF to add radial blur!";
static command = "circle";
}
export default CircleCommand;

View file

@ -1,10 +1,10 @@
import ImageCommand from "../../classes/imageCommand.js";
class CropCommand extends ImageCommand {
static description = "Crops an image to 1:1";
static noImage = "You need to provide an image/GIF to crop!";
static command = "crop";
}
export default CropCommand;
import ImageCommand from "../../classes/imageCommand.js";
class CropCommand extends ImageCommand {
static description = "Crops an image to 1:1";
static noImage = "You need to provide an image/GIF to crop!";
static command = "crop";
}
export default CropCommand;

View file

@ -1,11 +1,11 @@
import ImageCommand from "../../classes/imageCommand.js";
class DeepfryCommand extends ImageCommand {
static description = "Deep-fries an image";
static aliases = ["fry", "jpeg2", "nuke", "df"];
static noImage = "You need to provide an image/GIF to fry!";
static command = "deepfry";
}
export default DeepfryCommand;
import ImageCommand from "../../classes/imageCommand.js";
class DeepfryCommand extends ImageCommand {
static description = "Deep-fries an image";
static aliases = ["fry", "jpeg2", "nuke", "df"];
static noImage = "You need to provide an image/GIF to fry!";
static command = "deepfry";
}
export default DeepfryCommand;

View file

@ -1,17 +1,17 @@
import ImageCommand from "../../classes/imageCommand.js";
class DeviantArtCommand extends ImageCommand {
params = {
water: "assets/images/deviantart.png",
gravity: 5,
resize: true
};
static description = "Adds a DeviantArt watermark to an image";
static aliases = ["da", "deviant"];
static noImage = "You need to provide an image/GIF to add a DeviantArt watermark!";
static command = "watermark";
}
export default DeviantArtCommand;
import ImageCommand from "../../classes/imageCommand.js";
class DeviantArtCommand extends ImageCommand {
params = {
water: "assets/images/deviantart.png",
gravity: 5,
resize: true
};
static description = "Adds a DeviantArt watermark to an image";
static aliases = ["da", "deviant"];
static noImage = "You need to provide an image/GIF to add a DeviantArt watermark!";
static command = "watermark";
}
export default DeviantArtCommand;

View file

@ -1,11 +1,11 @@
import ImageCommand from "../../classes/imageCommand.js";
class ExplodeCommand extends ImageCommand {
static description = "Explodes an image";
static aliases = ["exp"];
static noImage = "You need to provide an image/GIF to explode!";
static command = "explode";
}
export default ExplodeCommand;
import ImageCommand from "../../classes/imageCommand.js";
class ExplodeCommand extends ImageCommand {
static description = "Explodes an image";
static aliases = ["exp"];
static noImage = "You need to provide an image/GIF to explode!";
static command = "explode";
}
export default ExplodeCommand;

View file

@ -1,45 +1,45 @@
import fs from "fs";
import emojiRegex from "emoji-regex";
import emoji from "node-emoji";
import ImageCommand from "../../classes/imageCommand.js";
class FlagCommand extends ImageCommand {
flagPath = "";
async criteria() {
const text = this.options.text ?? this.args[0];
if (!text.match(emojiRegex())) return false;
const flag = emoji.unemojify(text).replaceAll(":", "").replace("flag-", "");
let path = `assets/images/region-flags/png/${flag.toUpperCase()}.png`;
if (flag === "pirate_flag") path = "assets/images/pirateflag.png";
if (flag === "rainbow-flag") path = "assets/images/rainbowflag.png";
if (flag === "checkered_flag") path = "assets/images/checkeredflag.png";
if (flag === "transgender_flag") path = "assets/images/transflag.png";
if (text === "🏴󠁧󠁢󠁳󠁣󠁴󠁿") path = "assets/images/region-flags/png/GB-SCT.png";
if (text === "🏴󠁧󠁢󠁷󠁬󠁳󠁿") path = "assets/images/region-flags/png/GB-WLS.png";
if (text === "🏴󠁧󠁢󠁥󠁮󠁧󠁿") path = "assets/images/region-flags/png/GB-ENG.png";
try {
await fs.promises.access(path);
this.flagPath = path;
return true;
} catch {
return false;
}
}
params() {
return {
overlay: this.flagPath
};
}
static description = "Overlays a flag onto an image";
static arguments = ["[flag]"];
static requiresText = true;
static noText = "You need to provide an emoji of a flag to overlay!";
static noImage = "You need to provide an image/GIF to overlay a flag onto!";
static command = "flag";
}
export default FlagCommand;
import fs from "fs";
import emojiRegex from "emoji-regex";
import emoji from "node-emoji";
import ImageCommand from "../../classes/imageCommand.js";
class FlagCommand extends ImageCommand {
flagPath = "";
async criteria() {
const text = this.options.text ?? this.args[0];
if (!text.match(emojiRegex())) return false;
const flag = emoji.unemojify(text).replaceAll(":", "").replace("flag-", "");
let path = `assets/images/region-flags/png/${flag.toUpperCase()}.png`;
if (flag === "pirate_flag") path = "assets/images/pirateflag.png";
if (flag === "rainbow-flag") path = "assets/images/rainbowflag.png";
if (flag === "checkered_flag") path = "assets/images/checkeredflag.png";
if (flag === "transgender_flag") path = "assets/images/transflag.png";
if (text === "🏴󠁧󠁢󠁳󠁣󠁴󠁿") path = "assets/images/region-flags/png/GB-SCT.png";
if (text === "🏴󠁧󠁢󠁷󠁬󠁳󠁿") path = "assets/images/region-flags/png/GB-WLS.png";
if (text === "🏴󠁧󠁢󠁥󠁮󠁧󠁿") path = "assets/images/region-flags/png/GB-ENG.png";
try {
await fs.promises.access(path);
this.flagPath = path;
return true;
} catch {
return false;
}
}
params() {
return {
overlay: this.flagPath
};
}
static description = "Overlays a flag onto an image";
static arguments = ["[flag]"];
static requiresText = true;
static noText = "You need to provide an emoji of a flag to overlay!";
static noImage = "You need to provide an image/GIF to overlay a flag onto!";
static command = "flag";
}
export default FlagCommand;

View file

@ -1,10 +1,10 @@
import ImageCommand from "../../classes/imageCommand.js";
class FlipCommand extends ImageCommand {
static description = "Flips an image";
static noImage = "You need to provide an image/GIF to flip!";
static command = "flip";
}
export default FlipCommand;
import ImageCommand from "../../classes/imageCommand.js";
class FlipCommand extends ImageCommand {
static description = "Flips an image";
static noImage = "You need to provide an image/GIF to flip!";
static command = "flip";
}
export default FlipCommand;

View file

@ -1,15 +1,15 @@
import ImageCommand from "../../classes/imageCommand.js";
class FlopCommand extends ImageCommand {
params = {
flop: true
};
static description = "Flips an image";
static aliases = ["flip2"];
static noImage = "You need to provide an image/GIF to flop!";
static command = "flip";
}
export default FlopCommand;
import ImageCommand from "../../classes/imageCommand.js";
class FlopCommand extends ImageCommand {
params = {
flop: true
};
static description = "Flips an image";
static aliases = ["flip2"];
static noImage = "You need to provide an image/GIF to flop!";
static command = "flip";
}
export default FlopCommand;

View file

@ -1,32 +1,32 @@
import ImageCommand from "../../classes/imageCommand.js";
class FreezeCommand extends ImageCommand {
params() {
const frameCount = parseInt(this.options.endframe ?? this.args[0]);
return {
loop: false,
frame: isNaN(frameCount) ? -1 : frameCount
};
}
static init() {
super.init();
this.flags.push({
name: "endframe",
type: 4,
description: "Set the end frame (default: last frame)",
min_value: 0
});
return this;
}
static description = "Makes an image sequence only play once";
static aliases = ["noloop", "once"];
static arguments = ["{end frame number}"];
static requiresGIF = true;
static noImage = "You need to provide an image/GIF to freeze!";
static command = "freeze";
}
export default FreezeCommand;
import ImageCommand from "../../classes/imageCommand.js";
class FreezeCommand extends ImageCommand {
params() {
const frameCount = parseInt(this.options.endframe ?? this.args[0]);
return {
loop: false,
frame: isNaN(frameCount) ? -1 : frameCount
};
}
static init() {
super.init();
this.flags.push({
name: "endframe",
type: 4,
description: "Set the end frame (default: last frame)",
min_value: 0
});
return this;
}
static description = "Makes an image sequence only play once";
static aliases = ["noloop", "once"];
static arguments = ["{end frame number}"];
static requiresGIF = true;
static noImage = "You need to provide an image/GIF to freeze!";
static command = "freeze";
}
export default FreezeCommand;

View file

@ -1,17 +1,17 @@
import ImageCommand from "../../classes/imageCommand.js";
class FunkyCommand extends ImageCommand {
params = {
water: "assets/images/funky.png",
gravity: 3,
resize: true
};
static description = "Adds the New Funky Mode banner to an image";
static aliases = ["funkymode", "newfunkymode", "funkykong"];
static noImage = "You need to provide an image/GIF to add a New Funky Mode banner!";
static command = "watermark";
}
export default FunkyCommand;
import ImageCommand from "../../classes/imageCommand.js";
class FunkyCommand extends ImageCommand {
params = {
water: "assets/images/funky.png",
gravity: 3,
resize: true
};
static description = "Adds the New Funky Mode banner to an image";
static aliases = ["funkymode", "newfunkymode", "funkykong"];
static noImage = "You need to provide an image/GIF to add a New Funky Mode banner!";
static command = "watermark";
}
export default FunkyCommand;

View file

@ -1,11 +1,11 @@
import ImageCommand from "../../classes/imageCommand.js";
class GameXplainCommand extends ImageCommand {
static description = "Makes a GameXplain thumbnail from an image";
static aliases = ["gx"];
static noImage = "You need to provide an image/GIF to make a GameXplain thumbnail from!";
static command = "gamexplain";
}
export default GameXplainCommand;
import ImageCommand from "../../classes/imageCommand.js";
class GameXplainCommand extends ImageCommand {
static description = "Makes a GameXplain thumbnail from an image";
static aliases = ["gx"];
static noImage = "You need to provide an image/GIF to make a GameXplain thumbnail from!";
static command = "gamexplain";
}
export default GameXplainCommand;

View file

@ -1,11 +1,11 @@
import ImageCommand from "../../classes/imageCommand.js";
class GIFCommand extends ImageCommand {
static description = "Converts an image into a GIF";
static aliases = ["gif", "getgif", "togif", "tgif", "gifify"];
static noImage = "You need to provide an image to convert to GIF!";
static command = "togif";
}
export default GIFCommand;
import ImageCommand from "../../classes/imageCommand.js";
class GIFCommand extends ImageCommand {
static description = "Converts an image into a GIF";
static aliases = ["gif", "getgif", "togif", "tgif", "gifify"];
static noImage = "You need to provide an image to convert to GIF!";
static command = "togif";
}
export default GIFCommand;

View file

@ -1,11 +1,11 @@
import ImageCommand from "../../classes/imageCommand.js";
class GlobeCommand extends ImageCommand {
static description = "Spins an image";
static aliases = ["sphere"];
static noImage = "You need to provide an image/GIF to spin!";
static command = "globe";
}
export default GlobeCommand;
import ImageCommand from "../../classes/imageCommand.js";
class GlobeCommand extends ImageCommand {
static description = "Spins an image";
static aliases = ["sphere"];
static noImage = "You need to provide an image/GIF to spin!";
static command = "globe";
}
export default GlobeCommand;

View file

@ -1,15 +1,15 @@
import ImageCommand from "../../classes/imageCommand.js";
class GrayscaleCommand extends ImageCommand {
params = {
color: "grayscale"
};
static description = "Adds a grayscale filter";
static noImage = "You need to provide an image/GIF to turn grayscale!";
static command = "colors";
static aliases = ["gray", "greyscale", "grey"];
}
export default GrayscaleCommand;
import ImageCommand from "../../classes/imageCommand.js";
class GrayscaleCommand extends ImageCommand {
params = {
color: "grayscale"
};
static description = "Adds a grayscale filter";
static noImage = "You need to provide an image/GIF to turn grayscale!";
static command = "colors";
static aliases = ["gray", "greyscale", "grey"];
}
export default GrayscaleCommand;

View file

@ -1,15 +1,15 @@
import ImageCommand from "../../classes/imageCommand.js";
class HaaHCommand extends ImageCommand {
params = {
first: true
};
static description = "Mirrors the left side of an image onto the right";
static aliases = ["magik4", "mirror2"];
static noImage = "You need to provide an image/GIF to mirror!";
static command = "mirror";
}
export default HaaHCommand;
import ImageCommand from "../../classes/imageCommand.js";
class HaaHCommand extends ImageCommand {
params = {
first: true
};
static description = "Mirrors the left side of an image onto the right";
static aliases = ["magik4", "mirror2"];
static noImage = "You need to provide an image/GIF to mirror!";
static command = "mirror";
}
export default HaaHCommand;

View file

@ -1,15 +1,15 @@
import ImageCommand from "../../classes/imageCommand.js";
class HooHCommand extends ImageCommand {
params = {
vertical: true
};
static description = "Mirrors the bottom of an image onto the top";
static aliases = ["magik6", "mirror4"];
static noImage = "You need to provide an image/GIF to mirror!";
static command = "mirror";
}
export default HooHCommand;
import ImageCommand from "../../classes/imageCommand.js";
class HooHCommand extends ImageCommand {
params = {
vertical: true
};
static description = "Mirrors the bottom of an image onto the top";
static aliases = ["magik6", "mirror4"];
static noImage = "You need to provide an image/GIF to mirror!";
static command = "mirror";
}
export default HooHCommand;

View file

@ -1,17 +1,17 @@
import ImageCommand from "../../classes/imageCommand.js";
class HypercamCommand extends ImageCommand {
params = {
water: "assets/images/hypercam.png",
gravity: 1,
resize: true
};
static description = "Adds the Hypercam watermark to an image";
static aliases = ["hcam"];
static noImage = "You need to provide an image/GIF to add a Hypercam watermark!";
static command = "watermark";
}
export default HypercamCommand;
import ImageCommand from "../../classes/imageCommand.js";
class HypercamCommand extends ImageCommand {
params = {
water: "assets/images/hypercam.png",
gravity: 1,
resize: true
};
static description = "Adds the Hypercam watermark to an image";
static aliases = ["hcam"];
static noImage = "You need to provide an image/GIF to add a Hypercam watermark!";
static command = "watermark";
}
export default HypercamCommand;

View file

@ -1,17 +1,17 @@
import ImageCommand from "../../classes/imageCommand.js";
class iFunnyCommand extends ImageCommand {
params = {
water: "assets/images/ifunny.png",
gravity: 8,
resize: true,
append: true
};
static description = "Adds the iFunny watermark to an image";
static noImage = "You need to provide an image/GIF to add an iFunny watermark!";
static command = "watermark";
}
export default iFunnyCommand;
import ImageCommand from "../../classes/imageCommand.js";
class iFunnyCommand extends ImageCommand {
params = {
water: "assets/images/ifunny.png",
gravity: 8,
resize: true,
append: true
};
static description = "Adds the iFunny watermark to an image";
static noImage = "You need to provide an image/GIF to add an iFunny watermark!";
static command = "watermark";
}
export default iFunnyCommand;

View file

@ -1,15 +1,15 @@
import ImageCommand from "../../classes/imageCommand.js";
class ImplodeCommand extends ImageCommand {
params = {
implode: true
};
static description = "Implodes an image";
static aliases = ["imp"];
static noImage = "You need to provide an image/GIF to implode!";
static command = "explode";
}
export default ImplodeCommand;
import ImageCommand from "../../classes/imageCommand.js";
class ImplodeCommand extends ImageCommand {
params = {
implode: true
};
static description = "Implodes an image";
static aliases = ["imp"];
static noImage = "You need to provide an image/GIF to implode!";
static command = "explode";
}
export default ImplodeCommand;

View file

@ -1,11 +1,11 @@
import ImageCommand from "../../classes/imageCommand.js";
class InvertCommand extends ImageCommand {
static description = "Inverts an image";
static aliases = ["inverse", "negate", "negative"];
static noImage = "You need to provide an image/GIF to invert!";
static command = "invert";
}
export default InvertCommand;
import ImageCommand from "../../classes/imageCommand.js";
class InvertCommand extends ImageCommand {
static description = "Inverts an image";
static aliases = ["inverse", "negate", "negative"];
static noImage = "You need to provide an image/GIF to invert!";
static command = "invert";
}
export default InvertCommand;

View file

@ -1,31 +1,31 @@
import ImageCommand from "../../classes/imageCommand.js";
class JPEGCommand extends ImageCommand {
params() {
const quality = parseInt(this.options.quality ?? this.args[0]);
return {
quality: isNaN(quality) ? 1 : Math.max(1, Math.min(quality, 100))
};
}
static init() {
super.init();
this.flags.push({
name: "quality",
type: 4,
description: "Set the JPEG quality (default: 1)",
min_value: 1,
max_value: 100
});
return this;
}
static description = "Adds JPEG compression to an image";
static aliases = ["needsmorejpeg", "jpegify", "magik2", "morejpeg", "jpg", "quality"];
static arguments = ["{quality}"];
static noImage = "You need to provide an image/GIF to add more JPEG!";
static command = "jpeg";
}
export default JPEGCommand;
import ImageCommand from "../../classes/imageCommand.js";
class JPEGCommand extends ImageCommand {
params() {
const quality = parseInt(this.options.quality ?? this.args[0]);
return {
quality: isNaN(quality) ? 1 : Math.max(1, Math.min(quality, 100))
};
}
static init() {
super.init();
this.flags.push({
name: "quality",
type: 4,
description: "Set the JPEG quality (default: 1)",
min_value: 1,
max_value: 100
});
return this;
}
static description = "Adds JPEG compression to an image";
static aliases = ["needsmorejpeg", "jpegify", "magik2", "morejpeg", "jpg", "quality"];
static arguments = ["{quality}"];
static noImage = "You need to provide an image/GIF to add more JPEG!";
static command = "jpeg";
}
export default JPEGCommand;

View file

@ -1,17 +1,17 @@
import ImageCommand from "../../classes/imageCommand.js";
class KineMasterCommand extends ImageCommand {
params = {
water: "assets/images/kinemaster.png",
gravity: 3,
resize: true
};
static description = "Adds the KineMaster watermark to an image";
static aliases = ["kine"];
static noImage = "You need to provide an image/GIF to add a KineMaster watermark!";
static command = "watermark";
}
export default KineMasterCommand;
import ImageCommand from "../../classes/imageCommand.js";
class KineMasterCommand extends ImageCommand {
params = {
water: "assets/images/kinemaster.png",
gravity: 3,
resize: true
};
static description = "Adds the KineMaster watermark to an image";
static aliases = ["kine"];
static noImage = "You need to provide an image/GIF to add a KineMaster watermark!";
static command = "watermark";
}
export default KineMasterCommand;

View file

@ -1,11 +1,11 @@
import ImageCommand from "../../classes/imageCommand.js";
class MagikCommand extends ImageCommand {
static description = "Adds a content aware scale effect to an image";
static aliases = ["imagemagic", "imagemagick", "imagemagik", "magic", "magick", "cas", "liquid"];
static noImage = "You need to provide an image/GIF to add some magik!";
static command = "magik";
}
export default MagikCommand;
import ImageCommand from "../../classes/imageCommand.js";
class MagikCommand extends ImageCommand {
static description = "Adds a content aware scale effect to an image";
static aliases = ["imagemagic", "imagemagick", "imagemagik", "magic", "magick", "cas", "liquid"];
static noImage = "You need to provide an image/GIF to add some magik!";
static command = "magik";
}
export default MagikCommand;

View file

@ -1,54 +1,54 @@
import ImageCommand from "../../classes/imageCommand.js";
import { cleanMessage } from "../../utils/misc.js";
class MemeCommand extends ImageCommand {
async criteria(text, url) {
const [topText, bottomText] = text.replaceAll(url, "").split(/(?<!\\),/).map(elem => elem.trim());
if (topText === "" && bottomText === "") {
return false;
} else {
return true;
}
}
params(url) {
const newArgs = this.options.text ?? this.args.join(" ");
const [topText, bottomText] = newArgs.replaceAll(url, "").split(/(?<!\\),/).map(elem => elem.trim());
return {
top: cleanMessage(this.message ?? this.interaction, this.options.case ? topText : topText.toUpperCase()),
bottom: bottomText ? cleanMessage(this.message ?? this.interaction, this.options.case ? bottomText : bottomText.toUpperCase()) : "",
font: typeof this.options.font === "string" && this.constructor.allowedFonts.includes(this.options.font.toLowerCase()) ? this.options.font.toLowerCase() : "impact"
};
}
static init() {
super.init();
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 this.allowedFonts) {
array.push({ name: font, value: font });
}
return array;
})(),
description: "Specify the font you want to use (default: impact)"
});
return this;
}
static description = "Generates a meme from an image (separate top/bottom text with a comma)";
static arguments = ["[top text]", "{bottom text}"];
static requiresText = true;
static noText = "You need to provide some text to generate a meme!";
static noImage = "You need to provide an image/GIF to generate a meme!";
static command = "meme";
}
export default MemeCommand;
import ImageCommand from "../../classes/imageCommand.js";
import { cleanMessage } from "../../utils/misc.js";
class MemeCommand extends ImageCommand {
async criteria(text, url) {
const [topText, bottomText] = text.replaceAll(url, "").split(/(?<!\\),/).map(elem => elem.trim());
if (topText === "" && bottomText === "") {
return false;
} else {
return true;
}
}
params(url) {
const newArgs = this.options.text ?? this.args.join(" ");
const [topText, bottomText] = newArgs.replaceAll(url, "").split(/(?<!\\),/).map(elem => elem.trim());
return {
top: cleanMessage(this.message ?? this.interaction, this.options.case ? topText : topText.toUpperCase()),
bottom: bottomText ? cleanMessage(this.message ?? this.interaction, this.options.case ? bottomText : bottomText.toUpperCase()) : "",
font: typeof this.options.font === "string" && this.constructor.allowedFonts.includes(this.options.font.toLowerCase()) ? this.options.font.toLowerCase() : "impact"
};
}
static init() {
super.init();
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 this.allowedFonts) {
array.push({ name: font, value: font });
}
return array;
})(),
description: "Specify the font you want to use (default: impact)"
});
return this;
}
static description = "Generates a meme from an image (separate top/bottom text with a comma)";
static arguments = ["[top text]", "{bottom text}"];
static requiresText = true;
static noText = "You need to provide some text to generate a meme!";
static noImage = "You need to provide an image/GIF to generate a meme!";
static command = "meme";
}
export default MemeCommand;

View file

@ -1,17 +1,17 @@
import ImageCommand from "../../classes/imageCommand.js";
class MemeCenterCommand extends ImageCommand {
params = {
water: "assets/images/memecenter.png",
gravity: 9,
mc: true
};
static description = "Adds the MemeCenter watermark to an image";
static aliases = ["memec", "mcenter"];
static noImage = "You need to provide an image/GIF to add a MemeCenter watermark!";
static command = "watermark";
}
export default MemeCenterCommand;
import ImageCommand from "../../classes/imageCommand.js";
class MemeCenterCommand extends ImageCommand {
params = {
water: "assets/images/memecenter.png",
gravity: 9,
mc: true
};
static description = "Adds the MemeCenter watermark to an image";
static aliases = ["memec", "mcenter"];
static noImage = "You need to provide an image/GIF to add a MemeCenter watermark!";
static command = "watermark";
}
export default MemeCenterCommand;

View file

@ -1,51 +1,51 @@
import ImageCommand from "../../classes/imageCommand.js";
import { cleanMessage } from "../../utils/misc.js";
class MotivateCommand extends ImageCommand {
async criteria(text, url) {
const [topText, bottomText] = text.replaceAll(url, "").split(/(?<!\\),/).map(elem => elem.trim());
if (topText === "" && bottomText === "") {
return false;
} else {
return true;
}
}
params(url) {
const newArgs = this.options.text ?? this.args.join(" ");
const [topText, bottomText] = newArgs.replaceAll(url, "").split(/(?<!\\),/).map(elem => elem.trim());
return {
top: cleanMessage(this.message ?? this.interaction, topText),
bottom: bottomText ? cleanMessage(this.message ?? this.interaction, bottomText) : "",
font: typeof this.options.font === "string" && this.constructor.allowedFonts.includes(this.options.font.toLowerCase()) ? this.options.font.toLowerCase() : "times"
};
}
static init() {
super.init();
this.flags.push({
name: "font",
type: 3,
choices: (() => {
const array = [];
for (const font of this.allowedFonts) {
array.push({ name: font, value: font });
}
return array;
})(),
description: "Specify the font you want to use (default: times)"
});
return this;
}
static description = "Generates a motivational poster";
static aliases = ["motivational", "motiv", "demotiv", "demotivational", "poster", "motivation", "demotivate"];
static arguments = ["[top text]", "{bottom text}"];
static requiresText = true;
static noText = "You need to provide some text to generate a motivational poster!";
static noImage = "You need to provide an image/GIF to generate a motivational poster!";
static command = "motivate";
}
export default MotivateCommand;
import ImageCommand from "../../classes/imageCommand.js";
import { cleanMessage } from "../../utils/misc.js";
class MotivateCommand extends ImageCommand {
async criteria(text, url) {
const [topText, bottomText] = text.replaceAll(url, "").split(/(?<!\\),/).map(elem => elem.trim());
if (topText === "" && bottomText === "") {
return false;
} else {
return true;
}
}
params(url) {
const newArgs = this.options.text ?? this.args.join(" ");
const [topText, bottomText] = newArgs.replaceAll(url, "").split(/(?<!\\),/).map(elem => elem.trim());
return {
top: cleanMessage(this.message ?? this.interaction, topText),
bottom: bottomText ? cleanMessage(this.message ?? this.interaction, bottomText) : "",
font: typeof this.options.font === "string" && this.constructor.allowedFonts.includes(this.options.font.toLowerCase()) ? this.options.font.toLowerCase() : "times"
};
}
static init() {
super.init();
this.flags.push({
name: "font",
type: 3,
choices: (() => {
const array = [];
for (const font of this.allowedFonts) {
array.push({ name: font, value: font });
}
return array;
})(),
description: "Specify the font you want to use (default: times)"
});
return this;
}
static description = "Generates a motivational poster";
static aliases = ["motivational", "motiv", "demotiv", "demotivational", "poster", "motivation", "demotivate"];
static arguments = ["[top text]", "{bottom text}"];
static requiresText = true;
static noText = "You need to provide some text to generate a motivational poster!";
static noImage = "You need to provide an image/GIF to generate a motivational poster!";
static command = "motivate";
}
export default MotivateCommand;

View file

@ -1,11 +1,11 @@
import ImageCommand from "../../classes/imageCommand.js";
class PixelateCommand extends ImageCommand {
static description = "Pixelates an image";
static aliases = ["pixel", "small"];
static noImage = "You need to provide an image/GIF to pixelate!";
static command = "resize";
}
export default PixelateCommand;
import ImageCommand from "../../classes/imageCommand.js";
class PixelateCommand extends ImageCommand {
static description = "Pixelates an image";
static aliases = ["pixel", "small"];
static noImage = "You need to provide an image/GIF to pixelate!";
static command = "resize";
}
export default PixelateCommand;

View file

@ -1,22 +1,22 @@
import ImageCommand from "../../classes/imageCommand.js";
import { random } from "../../utils/misc.js";
const names = ["esmBot", "me_irl", "dankmemes", "hmmm", "gaming", "wholesome", "chonkers", "memes", "funny", "lies"];
class RedditCommand extends ImageCommand {
params(url) {
const newArgs = this.options.text ?? this.args.filter(item => !item.includes(url)).join(" ");
return {
caption: newArgs?.trim() ? newArgs.replaceAll("\n", "").replaceAll(" ", "") : random(names)
};
}
static textOptional = true;
static description = "Adds a Reddit watermark to an image";
static arguments = ["{text}"];
static noText = "You need to provide some text to add a Reddit watermark!";
static command = "reddit";
}
export default RedditCommand;
import ImageCommand from "../../classes/imageCommand.js";
import { random } from "../../utils/misc.js";
const names = ["esmBot", "me_irl", "dankmemes", "hmmm", "gaming", "wholesome", "chonkers", "memes", "funny", "lies"];
class RedditCommand extends ImageCommand {
params(url) {
const newArgs = this.options.text ?? this.args.filter(item => !item.includes(url)).join(" ");
return {
caption: newArgs?.trim() ? newArgs.replaceAll("\n", "").replaceAll(" ", "") : random(names)
};
}
static textOptional = true;
static description = "Adds a Reddit watermark to an image";
static arguments = ["{text}"];
static noText = "You need to provide some text to add a Reddit watermark!";
static command = "reddit";
}
export default RedditCommand;

View file

@ -1,12 +1,12 @@
import ImageCommand from "../../classes/imageCommand.js";
class ReverseCommand extends ImageCommand {
static description = "Reverses an image sequence";
static aliases = ["backwards"];
static requiresGIF = true;
static noImage = "You need to provide an image/GIF to reverse!";
static command = "reverse";
}
export default ReverseCommand;
import ImageCommand from "../../classes/imageCommand.js";
class ReverseCommand extends ImageCommand {
static description = "Reverses an image sequence";
static aliases = ["backwards"];
static requiresGIF = true;
static noImage = "You need to provide an image/GIF to reverse!";
static command = "reverse";
}
export default ReverseCommand;

View file

@ -1,11 +1,11 @@
import ImageCommand from "../../classes/imageCommand.js";
class ScottCommand extends ImageCommand {
static description = "Makes Scott the Woz show off an image";
static aliases = ["woz", "tv", "porn"];
static noImage = "You need to provide an image/GIF for Scott to show off!";
static command = "scott";
}
export default ScottCommand;
import ImageCommand from "../../classes/imageCommand.js";
class ScottCommand extends ImageCommand {
static description = "Makes Scott the Woz show off an image";
static aliases = ["woz", "tv", "porn"];
static noImage = "You need to provide an image/GIF for Scott to show off!";
static command = "scott";
}
export default ScottCommand;

View file

@ -1,14 +1,14 @@
import ImageCommand from "../../classes/imageCommand.js";
class SepiaCommand extends ImageCommand {
params = {
color: "sepia"
};
static description = "Adds a sepia filter";
static noImage = "You need to provide an image/GIF to add a sepia filter!";
static command = "colors";
}
export default SepiaCommand;
import ImageCommand from "../../classes/imageCommand.js";
class SepiaCommand extends ImageCommand {
params = {
color: "sepia"
};
static description = "Adds a sepia filter";
static noImage = "You need to provide an image/GIF to add a sepia filter!";
static command = "colors";
}
export default SepiaCommand;

View file

@ -1,15 +1,15 @@
import ImageCommand from "../../classes/imageCommand.js";
class SharpenCommand extends ImageCommand {
params = {
sharp: true
};
static description = "Sharpens an image";
static aliases = ["sharp"];
static noImage = "You need to provide an image/GIF to sharpen!";
static command = "blur";
}
export default SharpenCommand;
import ImageCommand from "../../classes/imageCommand.js";
class SharpenCommand extends ImageCommand {
params = {
sharp: true
};
static description = "Sharpens an image";
static aliases = ["sharp"];
static noImage = "You need to provide an image/GIF to sharpen!";
static command = "blur";
}
export default SharpenCommand;

View file

@ -1,17 +1,17 @@
import ImageCommand from "../../classes/imageCommand.js";
class ShutterstockCommand extends ImageCommand {
params = {
water: "assets/images/shutterstock.png",
gravity: 5,
resize: true
};
static description = "Adds the Shutterstock watermark to an image";
static aliases = ["stock", "stockphoto"];
static noImage = "You need to provide an image/GIF to add a Shutterstock watermark!";
static command = "watermark";
}
export default ShutterstockCommand;
import ImageCommand from "../../classes/imageCommand.js";
class ShutterstockCommand extends ImageCommand {
params = {
water: "assets/images/shutterstock.png",
gravity: 5,
resize: true
};
static description = "Adds the Shutterstock watermark to an image";
static aliases = ["stock", "stockphoto"];
static noImage = "You need to provide an image/GIF to add a Shutterstock watermark!";
static command = "watermark";
}
export default ShutterstockCommand;

View file

@ -1,32 +1,32 @@
import ImageCommand from "../../classes/imageCommand.js";
class SlowCommand extends ImageCommand {
params() {
const speed = parseInt(this.options.multiplier ?? this.args[0]);
return {
slow: true,
speed: isNaN(speed) ? 2 : speed
};
}
static init() {
super.init();
this.flags.push({
name: "multiplier",
type: 4,
description: "Set the speed multiplier (default: 2)",
min_value: 1
});
return this;
}
static description = "Makes an image sequence slower";
static aliases = ["slowdown", "slower", "gifspeed2"];
static arguments = ["{multiplier}"];
static requiresGIF = true;
static noImage = "You need to provide an image/GIF to slow down!";
static command = "speed";
}
export default SlowCommand;
import ImageCommand from "../../classes/imageCommand.js";
class SlowCommand extends ImageCommand {
params() {
const speed = parseInt(this.options.multiplier ?? this.args[0]);
return {
slow: true,
speed: isNaN(speed) ? 2 : speed
};
}
static init() {
super.init();
this.flags.push({
name: "multiplier",
type: 4,
description: "Set the speed multiplier (default: 2)",
min_value: 1
});
return this;
}
static description = "Makes an image sequence slower";
static aliases = ["slowdown", "slower", "gifspeed2"];
static arguments = ["{multiplier}"];
static requiresGIF = true;
static noImage = "You need to provide an image/GIF to slow down!";
static command = "speed";
}
export default SlowCommand;

View file

@ -1,36 +1,36 @@
import ImageCommand from "../../classes/imageCommand.js";
import { cleanMessage } from "../../utils/misc.js";
class SnapchatCommand extends ImageCommand {
params(url) {
const newArgs = this.options.text ?? this.args.filter(item => !item.includes(url)).join(" ");
const position = parseFloat(this.options.position);
return {
caption: cleanMessage(this.message ?? this.interaction, newArgs),
pos: isNaN(position) ? 0.5 : position
};
}
static init() {
super.init();
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
});
return this;
}
static description = "Adds a Snapchat style caption to an image";
static aliases = ["snap", "caption3"];
static arguments = ["[text]"];
static requiresText = 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 = "snapchat";
}
export default SnapchatCommand;
import ImageCommand from "../../classes/imageCommand.js";
import { cleanMessage } from "../../utils/misc.js";
class SnapchatCommand extends ImageCommand {
params(url) {
const newArgs = this.options.text ?? this.args.filter(item => !item.includes(url)).join(" ");
const position = parseFloat(this.options.position);
return {
caption: cleanMessage(this.message ?? this.interaction, newArgs),
pos: isNaN(position) ? 0.5 : position
};
}
static init() {
super.init();
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
});
return this;
}
static description = "Adds a Snapchat style caption to an image";
static aliases = ["snap", "caption3"];
static arguments = ["[text]"];
static requiresText = 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 = "snapchat";
}
export default SnapchatCommand;

View file

@ -1,16 +1,16 @@
import ImageCommand from "../../classes/imageCommand.js";
class SooSCommand extends ImageCommand {
params = {
soos: true
};
static description = "\"Loops\" an image sequence by reversing it when it's finished";
static aliases = ["boomerang"];
static requiresGIF = true;
static noImage = "You need to provide an image/GIF to loop!";
static command = "reverse";
}
export default SooSCommand;
import ImageCommand from "../../classes/imageCommand.js";
class SooSCommand extends ImageCommand {
params = {
soos: true
};
static description = "\"Loops\" an image sequence by reversing it when it's finished";
static aliases = ["boomerang"];
static requiresGIF = true;
static noImage = "You need to provide an image/GIF to loop!";
static command = "reverse";
}
export default SooSCommand;

View file

@ -1,36 +1,36 @@
import ImageCommand from "../../classes/imageCommand.js";
class SpeechBubbleCommand extends ImageCommand {
params() {
return {
water: this.options.alpha ? "assets/images/speech.png" : "assets/images/speechbubble.png",
gravity: "north",
resize: true,
yscale: 0.2,
alpha: this.options.alpha ? true : false,
flip: this.options.flip ? true : false
};
}
static init() {
super.init();
this.flags.push({
name: "alpha",
description: "Make the top of the speech bubble transparent",
type: 5
}, {
name: "flip",
description: "Flips the speech bubble",
type: 5
});
return this;
}
static description = "Adds a speech bubble to an image";
static aliases = ["speech"];
static noImage = "You need to provide an image/GIF to add a speech bubble!";
static command = "watermark";
}
export default SpeechBubbleCommand;
import ImageCommand from "../../classes/imageCommand.js";
class SpeechBubbleCommand extends ImageCommand {
params() {
return {
water: this.options.alpha ? "assets/images/speech.png" : "assets/images/speechbubble.png",
gravity: "north",
resize: true,
yscale: 0.2,
alpha: this.options.alpha ? true : false,
flip: this.options.flip ? true : false
};
}
static init() {
super.init();
this.flags.push({
name: "alpha",
description: "Make the top of the speech bubble transparent",
type: 5
}, {
name: "flip",
description: "Flips the speech bubble",
type: 5
});
return this;
}
static description = "Adds a speech bubble to an image";
static aliases = ["speech"];
static noImage = "You need to provide an image/GIF to add a speech bubble!";
static command = "watermark";
}
export default SpeechBubbleCommand;

View file

@ -1,31 +1,31 @@
import ImageCommand from "../../classes/imageCommand.js";
class SpeedCommand extends ImageCommand {
params() {
const speed = parseInt(this.options.multiplier ?? this.args[0]);
return {
speed: isNaN(speed) || speed < 1 ? 2 : speed
};
}
static init() {
super.init();
this.flags.push({
name: "multiplier",
type: 4,
description: "Set the speed multiplier (default: 2)",
min_value: 1
});
return this;
}
static description = "Makes an image sequence faster";
static aliases = ["speedup", "fast", "gifspeed", "faster"];
static arguments = ["{multiplier}"];
static requiresGIF = true;
static noImage = "You need to provide an image/GIF to speed up!";
static command = "speed";
}
export default SpeedCommand;
import ImageCommand from "../../classes/imageCommand.js";
class SpeedCommand extends ImageCommand {
params() {
const speed = parseInt(this.options.multiplier ?? this.args[0]);
return {
speed: isNaN(speed) || speed < 1 ? 2 : speed
};
}
static init() {
super.init();
this.flags.push({
name: "multiplier",
type: 4,
description: "Set the speed multiplier (default: 2)",
min_value: 1
});
return this;
}
static description = "Makes an image sequence faster";
static aliases = ["speedup", "fast", "gifspeed", "faster"];
static arguments = ["{multiplier}"];
static requiresGIF = true;
static noImage = "You need to provide an image/GIF to speed up!";
static command = "speed";
}
export default SpeedCommand;

View file

@ -1,11 +1,11 @@
import ImageCommand from "../../classes/imageCommand.js";
class SpinCommand extends ImageCommand {
static description = "Spins an image";
static aliases = ["rotate"];
static noImage = "You need to provide an image/GIF to spin!";
static command = "spin";
}
export default SpinCommand;
import ImageCommand from "../../classes/imageCommand.js";
class SpinCommand extends ImageCommand {
static description = "Spins an image";
static aliases = ["rotate"];
static noImage = "You need to provide an image/GIF to spin!";
static command = "spin";
}
export default SpinCommand;

View file

@ -1,11 +1,11 @@
import ImageCommand from "../../classes/imageCommand.js";
class SquishCommand extends ImageCommand {
static description = "Squishes/stretches an image";
static aliases = ["squishy", "squash"];
static noImage = "You need to provide an image/GIF to squish!";
static command = "squish";
}
export default SquishCommand;
import ImageCommand from "../../classes/imageCommand.js";
class SquishCommand extends ImageCommand {
static description = "Squishes/stretches an image";
static aliases = ["squishy", "squash"];
static noImage = "You need to provide an image/GIF to squish!";
static command = "squish";
}
export default SquishCommand;

View file

@ -1,15 +1,15 @@
import ImageCommand from "../../classes/imageCommand.js";
class StretchCommand extends ImageCommand {
params = {
stretch: true
};
static description = "Stretches an image to a 1:1 aspect ratio";
static aliases = ["aspect", "ratio", "aspect11", "11"];
static noImage = "You need to provide an image/GIF to stretch!";
static command = "resize";
}
export default StretchCommand;
import ImageCommand from "../../classes/imageCommand.js";
class StretchCommand extends ImageCommand {
params = {
stretch: true
};
static description = "Stretches an image to a 1:1 aspect ratio";
static aliases = ["aspect", "ratio", "aspect11", "11"];
static noImage = "You need to provide an image/GIF to stretch!";
static command = "resize";
}
export default StretchCommand;

View file

@ -1,11 +1,11 @@
import ImageCommand from "../../classes/imageCommand.js";
class SwirlCommand extends ImageCommand {
static description = "Swirls an image";
static aliases = ["whirlpool", "distort"];
static noImage = "You need to provide an image/GIF to swirl!";
static command = "swirl";
}
export default SwirlCommand;
import ImageCommand from "../../classes/imageCommand.js";
class SwirlCommand extends ImageCommand {
static description = "Swirls an image";
static aliases = ["whirlpool", "distort"];
static noImage = "You need to provide an image/GIF to swirl!";
static command = "swirl";
}
export default SwirlCommand;

View file

@ -1,11 +1,11 @@
import ImageCommand from "../../classes/imageCommand.js";
class TileCommand extends ImageCommand {
static description = "Creates a tile pattern from an image";
static aliases = ["wall2"];
static noImage = "You need to provide an image/GIF to tile!";
static command = "tile";
}
export default TileCommand;
import ImageCommand from "../../classes/imageCommand.js";
class TileCommand extends ImageCommand {
static description = "Creates a tile pattern from an image";
static aliases = ["wall2"];
static noImage = "You need to provide an image/GIF to tile!";
static command = "tile";
}
export default TileCommand;

View file

@ -1,65 +1,65 @@
import ImageCommand from "../../classes/imageCommand.js";
import { random, cleanMessage } from "../../utils/misc.js";
import { readdirSync } from "fs";
import { resolve, dirname } from "path";
import { fileURLToPath } from "url";
const prompts = ["you found:", "your dad is:", "you ate:", "your mom is:", "your sister is:", "you saw:", "you get lost in:", "you find:", "you grab:", "you pull out of your pocket:", "you fight:", "it's in your room:"];
const names = readdirSync(resolve(dirname(fileURLToPath(import.meta.url)), "../../assets/images/uncanny/")).filter((val) => {
if (!val.startsWith(".") && val.endsWith(".png")) return true;
}).map((val) => {
return val.split(".")[0];
});
class UncannyCommand extends ImageCommand {
params(url, name = "unknown") {
const newArgs = this.options.text ?? this.args.join(" ");
// eslint-disable-next-line prefer-const
let [text1, text2] = newArgs.replaceAll(url, "").split(/(?<!\\),/).map(elem => elem.trim());
if (!text2?.trim()) text2 = name;
return {
caption: text1?.trim() ? cleanMessage(this.message ?? this.interaction, text1) : random(prompts),
caption2: cleanMessage(this.message ?? this.interaction, text2),
path: `assets/images/uncanny/${typeof this.options.phase === "string" && names.includes(this.options.phase.toLowerCase()) ? this.options.phase.toLowerCase() : random(names.filter((val) => val !== "goated"))}.png`,
font: typeof this.options.font === "string" && this.constructor.allowedFonts.includes(this.options.font.toLowerCase()) ? this.options.font.toLowerCase() : "helvetica"
};
}
static init() {
super.init();
this.flags.push({
name: "font",
type: 3,
choices: (() => {
const array = [];
for (const font of this.allowedFonts) {
array.push({ name: font, value: font });
}
return array;
})(),
description: "Specify the font you want to use (default: helvetica)"
}, {
name: "phase",
type: 3,
choices: (() => {
const array = [];
for (const name of names) {
array.push({ name, value: name });
}
return array;
})(),
description: "Specify the uncanny image you want to use"
});
return this;
}
static textOptional = true;
static description = "Makes a Mr. Incredible Becomes Uncanny image (separate left/right text with a comma)";
static aliases = ["canny", "incredible", "pain"];
static arguments = ["{left text}", "{right text}"];
static noImage = "You need to provide an image/GIF to create an uncanny image!";
static command = "uncanny";
}
export default UncannyCommand;
import ImageCommand from "../../classes/imageCommand.js";
import { random, cleanMessage } from "../../utils/misc.js";
import { readdirSync } from "fs";
import { resolve, dirname } from "path";
import { fileURLToPath } from "url";
const prompts = ["you found:", "your dad is:", "you ate:", "your mom is:", "your sister is:", "you saw:", "you get lost in:", "you find:", "you grab:", "you pull out of your pocket:", "you fight:", "it's in your room:"];
const names = readdirSync(resolve(dirname(fileURLToPath(import.meta.url)), "../../assets/images/uncanny/")).filter((val) => {
if (!val.startsWith(".") && val.endsWith(".png")) return true;
}).map((val) => {
return val.split(".")[0];
});
class UncannyCommand extends ImageCommand {
params(url, name = "unknown") {
const newArgs = this.options.text ?? this.args.join(" ");
// eslint-disable-next-line prefer-const
let [text1, text2] = newArgs.replaceAll(url, "").split(/(?<!\\),/).map(elem => elem.trim());
if (!text2?.trim()) text2 = name;
return {
caption: text1?.trim() ? cleanMessage(this.message ?? this.interaction, text1) : random(prompts),
caption2: cleanMessage(this.message ?? this.interaction, text2),
path: `assets/images/uncanny/${typeof this.options.phase === "string" && names.includes(this.options.phase.toLowerCase()) ? this.options.phase.toLowerCase() : random(names.filter((val) => val !== "goated"))}.png`,
font: typeof this.options.font === "string" && this.constructor.allowedFonts.includes(this.options.font.toLowerCase()) ? this.options.font.toLowerCase() : "helvetica"
};
}
static init() {
super.init();
this.flags.push({
name: "font",
type: 3,
choices: (() => {
const array = [];
for (const font of this.allowedFonts) {
array.push({ name: font, value: font });
}
return array;
})(),
description: "Specify the font you want to use (default: helvetica)"
}, {
name: "phase",
type: 3,
choices: (() => {
const array = [];
for (const name of names) {
array.push({ name, value: name });
}
return array;
})(),
description: "Specify the uncanny image you want to use"
});
return this;
}
static textOptional = true;
static description = "Makes a Mr. Incredible Becomes Uncanny image (separate left/right text with a comma)";
static aliases = ["canny", "incredible", "pain"];
static arguments = ["{left text}", "{right text}"];
static noImage = "You need to provide an image/GIF to create an uncanny image!";
static command = "uncanny";
}
export default UncannyCommand;

View file

@ -1,29 +1,29 @@
import ImageCommand from "../../classes/imageCommand.js";
class UncaptionCommand extends ImageCommand {
params() {
const tolerance = parseFloat(this.options.tolerance);
return {
tolerance: isNaN(tolerance) ? 0.95 : tolerance
};
}
static init() {
super.init();
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
});
return this;
}
static description = "Removes the caption from an image";
static noImage = "You need to provide an image/GIF to uncaption!";
static command = "uncaption";
}
export default UncaptionCommand;
import ImageCommand from "../../classes/imageCommand.js";
class UncaptionCommand extends ImageCommand {
params() {
const tolerance = parseFloat(this.options.tolerance);
return {
tolerance: isNaN(tolerance) ? 0.95 : tolerance
};
}
static init() {
super.init();
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
});
return this;
}
static description = "Removes the caption from an image";
static noImage = "You need to provide an image/GIF to uncaption!";
static command = "uncaption";
}
export default UncaptionCommand;

View file

@ -1,15 +1,15 @@
import ImageCommand from "../../classes/imageCommand.js";
class UnfreezeCommand extends ImageCommand {
params = {
loop: true
};
static description = "Unfreezes an image sequence";
static requiresGIF = true;
static noImage = "You need to provide an image/GIF to unfreeze!";
static command = "freeze";
}
export default UnfreezeCommand;
import ImageCommand from "../../classes/imageCommand.js";
class UnfreezeCommand extends ImageCommand {
params = {
loop: true
};
static description = "Unfreezes an image sequence";
static requiresGIF = true;
static noImage = "You need to provide an image/GIF to unfreeze!";
static command = "freeze";
}
export default UnfreezeCommand;

View file

@ -1,11 +1,11 @@
import ImageCommand from "../../classes/imageCommand.js";
class WaaWCommand extends ImageCommand {
static description = "Mirrors the right side of an image onto the left";
static aliases = ["magik3", "mirror"];
static noImage = "You need to provide an image/GIF to mirror!";
static command = "mirror";
}
export default WaaWCommand;
import ImageCommand from "../../classes/imageCommand.js";
class WaaWCommand extends ImageCommand {
static description = "Mirrors the right side of an image onto the left";
static aliases = ["magik3", "mirror"];
static noImage = "You need to provide an image/GIF to mirror!";
static command = "mirror";
}
export default WaaWCommand;

View file

@ -1,10 +1,10 @@
import ImageCommand from "../../classes/imageCommand.js";
class WallCommand extends ImageCommand {
static description = "Creates a wall from an image";
static noImage = "You need to provide an image/GIF to make a wall!";
static command = "wall";
}
export default WallCommand;
import ImageCommand from "../../classes/imageCommand.js";
class WallCommand extends ImageCommand {
static description = "Creates a wall from an image";
static noImage = "You need to provide an image/GIF to make a wall!";
static command = "wall";
}
export default WallCommand;

View file

@ -1,22 +1,22 @@
import ImageCommand from "../../classes/imageCommand.js";
import { cleanMessage } from "../../utils/misc.js";
class WhisperCommand extends ImageCommand {
params(url) {
const newArgs = this.options.text ?? this.args.filter(item => !item.includes(url)).join(" ");
return {
caption: cleanMessage(this.message ?? this.interaction, newArgs)
};
}
static description = "Adds a Whisper style caption to an image";
static aliases = ["caption4"];
static arguments = ["[text]"];
static requiresText = 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 = "whisper";
}
export default WhisperCommand;
import ImageCommand from "../../classes/imageCommand.js";
import { cleanMessage } from "../../utils/misc.js";
class WhisperCommand extends ImageCommand {
params(url) {
const newArgs = this.options.text ?? this.args.filter(item => !item.includes(url)).join(" ");
return {
caption: cleanMessage(this.message ?? this.interaction, newArgs)
};
}
static description = "Adds a Whisper style caption to an image";
static aliases = ["caption4"];
static arguments = ["[text]"];
static requiresText = 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 = "whisper";
}
export default WhisperCommand;

View file

@ -1,15 +1,15 @@
import ImageCommand from "../../classes/imageCommand.js";
class WideCommand extends ImageCommand {
params = {
wide: true
};
static description = "Stretches an image to 19x its width";
static aliases = ["w19", "wide19"];
static noImage = "You need to provide an image/GIF to stretch!";
static command = "resize";
}
export default WideCommand;
import ImageCommand from "../../classes/imageCommand.js";
class WideCommand extends ImageCommand {
params = {
wide: true
};
static description = "Stretches an image to 19x its width";
static aliases = ["w19", "wide19"];
static noImage = "You need to provide an image/GIF to stretch!";
static command = "resize";
}
export default WideCommand;

View file

@ -1,16 +1,16 @@
import ImageCommand from "../../classes/imageCommand.js";
class WooWCommand extends ImageCommand {
params = {
vertical: true,
first: true
};
static description = "Mirrors the top of an image onto the bottom";
static aliases = ["magik5", "mirror3"];
static noImage = "You need to provide an image/GIF to mirror!";
static command = "mirror";
}
export default WooWCommand;
import ImageCommand from "../../classes/imageCommand.js";
class WooWCommand extends ImageCommand {
params = {
vertical: true,
first: true
};
static description = "Mirrors the top of an image onto the bottom";
static aliases = ["magik5", "mirror3"];
static noImage = "You need to provide an image/GIF to mirror!";
static command = "mirror";
}
export default WooWCommand;

View file

@ -1,10 +1,10 @@
import ImageCommand from "../../classes/imageCommand.js";
class ZamnCommand extends ImageCommand {
static description = "Adds a \"ZAMN\" reaction to an image";
static noImage = "You need to provide an image/GIF to \"ZAMN\" at!";
static command = "zamn";
}
export default ZamnCommand;
import ImageCommand from "../../classes/imageCommand.js";
class ZamnCommand extends ImageCommand {
static description = "Adds a \"ZAMN\" reaction to an image";
static noImage = "You need to provide an image/GIF to \"ZAMN\" at!";
static command = "zamn";
}
export default ZamnCommand;

View file

@ -1,23 +1,23 @@
import Command from "../../classes/command.js";
import imageDetect from "../../utils/imagedetect.js";
import { selectedImages } from "../../utils/collections.js";
class SelectImageCommand extends Command {
async run() {
await this.acknowledge();
const message = this.interaction.data.target;
const image = await imageDetect(this.client, message, this.interaction, this.options, true, false, false, true);
this.success = false;
if (image === undefined) {
return "I couldn't find an image in that message!";
} else if (image.type === "large") {
return "That image is too large (>= 25MB)! Try using a smaller image.";
} else if (image.type === "tenorlimit") {
return "I've been rate-limited by Tenor. Please try uploading your GIF elsewhere.";
}
selectedImages.set(this.author.id, image);
return "The image has been selected for your next command.";
}
}
import Command from "../../classes/command.js";
import imageDetect from "../../utils/imagedetect.js";
import { selectedImages } from "../../utils/collections.js";
class SelectImageCommand extends Command {
async run() {
await this.acknowledge();
const message = this.interaction.data.target;
const image = await imageDetect(this.client, message, this.interaction, this.options, true, false, false, true);
this.success = false;
if (image === undefined) {
return "I couldn't find an image in that message!";
} else if (image.type === "large") {
return "That image is too large (>= 25MB)! Try using a smaller image.";
} else if (image.type === "tenorlimit") {
return "I've been rate-limited by Tenor. Please try uploading your GIF elsewhere.";
}
selectedImages.set(this.author.id, image);
return "The image has been selected for your next command.";
}
}
export default SelectImageCommand;

View file

@ -1,60 +1,60 @@
import { players } from "../../utils/soundplayer.js";
import MusicCommand from "../../classes/musicCommand.js";
class HostCommand extends MusicCommand {
async run() {
this.success = false;
if (!this.guild) return "This command only works in servers!";
if (!this.member.voiceState) return "You need to be in a voice channel first!";
if (!this.guild.voiceStates.has(this.client.user.id)) return "I'm not in a voice channel!";
if (!this.connection) return "I haven't completely connected yet!";
if (this.connection.host !== this.author.id && !process.env.OWNER.split(",").includes(this.connection.host)) return "Only the current voice session host can choose another host!";
const input = this.options.user ?? this.args.join(" ");
if (input?.trim()) {
let user;
if (this.type === "classic") {
const getUser = this.message.mentions.users.length >= 1 ? this.message.mentions.users[0] : this.client.users.get(input);
if (getUser) {
user = getUser;
} else if (input.match(/^<?[@#]?[&!]?\d+>?$/) && input >= 21154535154122752n) {
try {
user = await this.client.rest.users.get(input);
} catch {
// no-op
}
} else {
const userRegex = new RegExp(input.split(" ").join("|"), "i");
const member = this.client.users.find(element => {
return userRegex.test(element.username);
});
user = member;
}
} else {
user = input;
}
if (!user) return "I can't find that user!";
if (user.bot) return "This is illegal, you know.";
const member = this.guild.members.get(user.id);
if (!member) return "That user isn't in this server!";
const object = this.connection;
object.host = member.id;
players.set(this.guildID, object);
this.success = true;
return `🔊 ${member.mention} is the new voice channel host.`;
} else {
const member = this.guild.members.get(players.get(this.guild.id).host);
this.success = true;
return `🔊 The current voice channel host is **${member?.username}#${member?.discriminator}**.`;
}
}
static flags = [{
name: "user",
type: 6,
description: "The user you want the new host to be"
}];
static description = "Gets or changes the host of the current voice session";
static aliases = ["sethost"];
}
export default HostCommand;
import { players } from "../../utils/soundplayer.js";
import MusicCommand from "../../classes/musicCommand.js";
class HostCommand extends MusicCommand {
async run() {
this.success = false;
if (!this.guild) return "This command only works in servers!";
if (!this.member.voiceState) return "You need to be in a voice channel first!";
if (!this.guild.voiceStates.has(this.client.user.id)) return "I'm not in a voice channel!";
if (!this.connection) return "I haven't completely connected yet!";
if (this.connection.host !== this.author.id && !process.env.OWNER.split(",").includes(this.connection.host)) return "Only the current voice session host can choose another host!";
const input = this.options.user ?? this.args.join(" ");
if (input?.trim()) {
let user;
if (this.type === "classic") {
const getUser = this.message.mentions.users.length >= 1 ? this.message.mentions.users[0] : this.client.users.get(input);
if (getUser) {
user = getUser;
} else if (input.match(/^<?[@#]?[&!]?\d+>?$/) && input >= 21154535154122752n) {
try {
user = await this.client.rest.users.get(input);
} catch {
// no-op
}
} else {
const userRegex = new RegExp(input.split(" ").join("|"), "i");
const member = this.client.users.find(element => {
return userRegex.test(element.username);
});
user = member;
}
} else {
user = input;
}
if (!user) return "I can't find that user!";
if (user.bot) return "This is illegal, you know.";
const member = this.guild.members.get(user.id);
if (!member) return "That user isn't in this server!";
const object = this.connection;
object.host = member.id;
players.set(this.guildID, object);
this.success = true;
return `🔊 ${member.mention} is the new voice channel host.`;
} else {
const member = this.guild.members.get(players.get(this.guild.id).host);
this.success = true;
return `🔊 The current voice channel host is **${member?.username}#${member?.discriminator}**.`;
}
}
static flags = [{
name: "user",
type: 6,
description: "The user you want the new host to be"
}];
static description = "Gets or changes the host of the current voice session";
static aliases = ["sethost"];
}
export default HostCommand;

View file

@ -1,23 +1,23 @@
import { players } from "../../utils/soundplayer.js";
import MusicCommand from "../../classes/musicCommand.js";
class LoopCommand extends MusicCommand {
async run() {
this.success = false;
if (!this.guild) return "This command only works in servers!";
if (!this.member.voiceState) return "You need to be in a voice channel first!";
if (!this.guild.voiceStates.has(this.client.user.id)) return "I'm not in a voice channel!";
if (!this.connection) return "I haven't completely connected yet!";
if (this.connection.host !== this.author.id && !this.member.permissions.has("MANAGE_CHANNELS")) return "Only the current voice session host can loop the music!";
const object = this.connection;
object.loop = !object.loop;
players.set(this.guild.id, object);
this.success = true;
return object.loop ? "🔊 The player is now looping." : "🔊 The player is no longer looping.";
}
static description = "Loops the music";
static aliases = ["toggleloop", "repeat"];
}
import { players } from "../../utils/soundplayer.js";
import MusicCommand from "../../classes/musicCommand.js";
class LoopCommand extends MusicCommand {
async run() {
this.success = false;
if (!this.guild) return "This command only works in servers!";
if (!this.member.voiceState) return "You need to be in a voice channel first!";
if (!this.guild.voiceStates.has(this.client.user.id)) return "I'm not in a voice channel!";
if (!this.connection) return "I haven't completely connected yet!";
if (this.connection.host !== this.author.id && !this.member.permissions.has("MANAGE_CHANNELS")) return "Only the current voice session host can loop the music!";
const object = this.connection;
object.loop = !object.loop;
players.set(this.guild.id, object);
this.success = true;
return object.loop ? "🔊 The player is now looping." : "🔊 The player is no longer looping.";
}
static description = "Loops the music";
static aliases = ["toggleloop", "repeat"];
}
export default LoopCommand;

Some files were not shown because too many files have changed in this diff Show more