mirror of
https://github.com/keanuplayz/TravBot-v3.git
synced 2024-08-15 02:33:12 +00:00
Compare commits
No commits in common. "5402883a2f4c245cbc602b7dc92e87164ab96753" and "4a78ce808becae3f0c4ff60208d65e219549ec3d" have entirely different histories.
5402883a2f
...
4a78ce808b
21 changed files with 202 additions and 2695 deletions
2194
package-lock.json
generated
2194
package-lock.json
generated
File diff suppressed because it is too large
Load diff
10
package.json
10
package.json
|
@ -4,26 +4,18 @@
|
||||||
"description": "A Discord bot built on Discord.JS v12",
|
"description": "A Discord bot built on Discord.JS v12",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"canvas": "^2.7.0",
|
|
||||||
"chalk": "^4.1.0",
|
"chalk": "^4.1.0",
|
||||||
"discord.js": "^12.5.1",
|
"discord.js": "^12.5.1",
|
||||||
"discord.js-lavalink-lib": "^0.1.8",
|
"discord.js-lavalink-lib": "^0.1.8",
|
||||||
"figlet": "^1.5.0",
|
|
||||||
"glob": "^7.1.6",
|
"glob": "^7.1.6",
|
||||||
"inquirer": "^7.3.3",
|
"inquirer": "^7.3.3",
|
||||||
"mathjs": "^9.3.0",
|
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"ms": "^2.1.3",
|
"ms": "^2.1.3"
|
||||||
"relevant-urban": "^2.0.0",
|
|
||||||
"translate-google": "^1.4.3",
|
|
||||||
"weather-js": "^2.0.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/figlet": "^1.5.0",
|
|
||||||
"@types/glob": "^7.1.3",
|
"@types/glob": "^7.1.3",
|
||||||
"@types/inquirer": "^6.5.0",
|
"@types/inquirer": "^6.5.0",
|
||||||
"@types/jest": "^26.0.20",
|
"@types/jest": "^26.0.20",
|
||||||
"@types/mathjs": "^6.0.11",
|
|
||||||
"@types/ms": "^0.7.31",
|
"@types/ms": "^0.7.31",
|
||||||
"@types/node": "^14.14.20",
|
"@types/node": "^14.14.20",
|
||||||
"@types/ws": "^7.4.0",
|
"@types/ws": "^7.4.0",
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
import {Command, NamedCommand} from "../../core";
|
|
||||||
import figlet from "figlet";
|
|
||||||
|
|
||||||
export default new NamedCommand({
|
|
||||||
description: "Generates a figlet of your input.",
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
const input = args.join(" ");
|
|
||||||
if (!args[0]) {
|
|
||||||
channel.send("You have to provide input for me to create a figlet!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
channel.send(
|
|
||||||
"```" +
|
|
||||||
figlet.textSync(`${input}`, {
|
|
||||||
horizontalLayout: "full"
|
|
||||||
}) +
|
|
||||||
"```"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,14 +0,0 @@
|
||||||
import {Command, NamedCommand} from "../../core";
|
|
||||||
|
|
||||||
export default new NamedCommand({
|
|
||||||
description: "Insult TravBot! >:D",
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
channel.startTyping();
|
|
||||||
setTimeout(() => {
|
|
||||||
channel.send(
|
|
||||||
`${author} What the fuck did you just fucking say about me, you little bitch? I'll have you know I graduated top of my class in the Navy Seals, and I've been involved in numerous secret raids on Al-Quaeda, and I have over 300 confirmed kills. I am trained in gorilla warfare and I'm the top sniper in the entire US armed forces. You are nothing to me but just another target. I will wipe you the fuck out with precision the likes of which has never been seen before on this Earth, mark my fucking words. You think you can get away with saying that shit to me over the Internet? Think again, fucker. As we speak I am contacting my secret network of spies across the USA and your IP is being traced right now so you better prepare for the storm, maggot. The storm that wipes out the pathetic little thing you call your life. You're fucking dead, kid. I can be anywhere, anytime, and I can kill you in over seven hundred ways, and that's just with my bare hands. Not only am I extensively trained in unarmed combat, but I have access to the entire arsenal of the United States Marine Corps and I will use it to its full extent to wipe your miserable ass off the face of the continent, you little shit. If only you could have known what unholy retribution your little "clever" comment was about to bring down upon you, maybe you would have held your fucking tongue. But you couldn't, you didn't, and now you're paying the price, you goddamn idiot. I will shit fury all over you and you will drown in it. You're fucking dead, kiddo.`
|
|
||||||
);
|
|
||||||
channel.stopTyping();
|
|
||||||
}, 60000);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,13 +0,0 @@
|
||||||
import {Command, NamedCommand} from "../../core";
|
|
||||||
|
|
||||||
export default new NamedCommand({
|
|
||||||
description: "Chooses someone to love.",
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
if (guild) {
|
|
||||||
const member = guild.members.cache.random();
|
|
||||||
channel.send(`I love ${member.user.username}!`);
|
|
||||||
} else {
|
|
||||||
channel.send("You must use this command in a guild!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,38 +0,0 @@
|
||||||
import {Command, NamedCommand} from "../../core";
|
|
||||||
import {Random} from "../../lib";
|
|
||||||
|
|
||||||
export default new NamedCommand({
|
|
||||||
description: "Ravioli ravioli...",
|
|
||||||
usage: "[number from 1 to 9]",
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
channel.send({
|
|
||||||
embed: {
|
|
||||||
title: "Ravioli ravioli...",
|
|
||||||
image: {
|
|
||||||
url: `https://raw.githubusercontent.com/keanuplayz/TravBot/master/assets/ravi${Random.int(
|
|
||||||
1,
|
|
||||||
10
|
|
||||||
)}.png`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
number: new Command({
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
const arg: number = args[0];
|
|
||||||
|
|
||||||
if (arg >= 1 && arg <= 9) {
|
|
||||||
channel.send({
|
|
||||||
embed: {
|
|
||||||
title: "Ravioli ravioli...",
|
|
||||||
image: {
|
|
||||||
url: `https://raw.githubusercontent.com/keanuplayz/TravBot/master/assets/ravi${arg}.png`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
channel.send("Please provide a number between 1 and 9.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
|
@ -1,41 +0,0 @@
|
||||||
import {Command, NamedCommand} from "../../core";
|
|
||||||
|
|
||||||
const letters: {[letter: string]: string[]} = {
|
|
||||||
a: "aáàảãạâấầẩẫậăắằẳẵặ".split(""),
|
|
||||||
e: "eéèẻẽẹêếềểễệ".split(""),
|
|
||||||
i: "iíìỉĩị".split(""),
|
|
||||||
o: "oóòỏõọôốồổỗộơớờởỡợ".split(""),
|
|
||||||
u: "uúùủũụưứừửữự".split(""),
|
|
||||||
y: "yýỳỷỹỵ".split(""),
|
|
||||||
d: "dđ".split("")
|
|
||||||
};
|
|
||||||
|
|
||||||
function transform(str: string) {
|
|
||||||
let out = "";
|
|
||||||
|
|
||||||
for (const c of str) {
|
|
||||||
const token = c.toLowerCase();
|
|
||||||
const isUpperCase = token !== c;
|
|
||||||
|
|
||||||
if (token in letters) {
|
|
||||||
const set = letters[token];
|
|
||||||
const add = set[Math.floor(Math.random() * set.length)];
|
|
||||||
out += isUpperCase ? add.toUpperCase() : add;
|
|
||||||
} else {
|
|
||||||
out += c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
let phrase = "I have no currently set phrase!";
|
|
||||||
|
|
||||||
export default new NamedCommand({
|
|
||||||
description: "Transforms your text into vietnamese.",
|
|
||||||
usage: "thonk ([text])",
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
if (args.length > 0) phrase = args.join(" ");
|
|
||||||
channel.send(transform(phrase));
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,27 +0,0 @@
|
||||||
import {Command, NamedCommand} from "../../core";
|
|
||||||
import {MessageEmbed} from "discord.js";
|
|
||||||
// Anycasting Alert
|
|
||||||
const urban = require("relevant-urban");
|
|
||||||
|
|
||||||
export default new NamedCommand({
|
|
||||||
description: "Gives you a definition of the inputted word.",
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
if (!args[0]) {
|
|
||||||
channel.send("Please input a word.");
|
|
||||||
}
|
|
||||||
const res = await urban(args.join(" ")).catch((e: Error) => {
|
|
||||||
return channel.send("Sorry, that word was not found.");
|
|
||||||
});
|
|
||||||
const embed = new MessageEmbed()
|
|
||||||
.setColor(0x1d2439)
|
|
||||||
.setTitle(res.word)
|
|
||||||
.setURL(res.urbanURL)
|
|
||||||
.setDescription(`**Definition:**\n*${res.definition}*\n\n**Example:**\n*${res.example}*`)
|
|
||||||
.addField("Author", res.author, true)
|
|
||||||
.addField("Rating", `**\`Upvotes: ${res.thumbsUp} | Downvotes: ${res.thumbsDown}\`**`);
|
|
||||||
if (res.tags.length > 0 && res.tags.join(" ").length < 1024) {
|
|
||||||
embed.addField("Tags", res.tags.join(", "), true);
|
|
||||||
}
|
|
||||||
channel.send(embed);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,39 +0,0 @@
|
||||||
import {Command, NamedCommand} from "../../core";
|
|
||||||
import {MessageEmbed} from "discord.js";
|
|
||||||
// Anycasting Alert
|
|
||||||
const weather = require("weather-js");
|
|
||||||
|
|
||||||
export default new NamedCommand({
|
|
||||||
description: "Shows weather info of specified location.",
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
if (args.length == 0) {
|
|
||||||
channel.send("You need to provide a city.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
weather.find(
|
|
||||||
{
|
|
||||||
search: args.join(" "),
|
|
||||||
degreeType: "C"
|
|
||||||
},
|
|
||||||
function (err: any, result: any) {
|
|
||||||
if (err) channel.send(err);
|
|
||||||
var current = result[0].current;
|
|
||||||
var location = result[0].location;
|
|
||||||
const embed = new MessageEmbed()
|
|
||||||
.setDescription(`**${current.skytext}**`)
|
|
||||||
.setAuthor(`Weather for ${current.observationpoint}`)
|
|
||||||
.setThumbnail(current.imageUrl)
|
|
||||||
.setColor(0x00ae86)
|
|
||||||
.addField("Timezone", `UTC${location.timezone}`, true)
|
|
||||||
.addField("Degree Type", "C", true)
|
|
||||||
.addField("Temperature", `${current.temperature} Degrees`, true)
|
|
||||||
.addField("Feels like", `${current.feelslike} Degrees`, true)
|
|
||||||
.addField("Winds", current.winddisplay, true)
|
|
||||||
.addField("Humidity", `${current.humidity}%`, true);
|
|
||||||
channel.send({
|
|
||||||
embed
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,85 +0,0 @@
|
||||||
import {User} from "discord.js";
|
|
||||||
import {Command, NamedCommand, getMemberByUsername} from "../../core";
|
|
||||||
|
|
||||||
// Quotes must be used here or the numbers will change
|
|
||||||
const registry: {[id: string]: string} = {
|
|
||||||
"465662909645848577": "You're an idiot, that's what.",
|
|
||||||
"306499531665833984":
|
|
||||||
"Kuma, you eldritch fuck, I demand you to release me from this Discord bot and let me see my Chromebook!",
|
|
||||||
"137323711844974592": "The purple haired gunner man who makes loud noises.",
|
|
||||||
"208763015657553921": "Minzy's master.",
|
|
||||||
"229636002443034624": "The ***God*** of being Smug.",
|
|
||||||
"280876114153308161": "The best girl.",
|
|
||||||
"175823837835821067": "The somehow sentient pear.",
|
|
||||||
"145839753118351360": "The blueberry with horns.",
|
|
||||||
"173917366504259585": "A talented developer.",
|
|
||||||
"216112465321263105": "The red strawberry cat.",
|
|
||||||
"394808963356688394": "The cutest, bestest, most caring girl ever.",
|
|
||||||
"142200534781132800": "The masters of chaos.",
|
|
||||||
"186496078273708033": "The cute blue cat.",
|
|
||||||
"241293368267767808": "The cute catgirl.",
|
|
||||||
"540419616803913738": "The generically Generic hologram man.",
|
|
||||||
"157598993298227211": "The somehow sentient bowl of nachos.",
|
|
||||||
"225214401228177408": "The CMD user.",
|
|
||||||
"224619540263337984": "The guy that did 50% of the work.",
|
|
||||||
"374298111255773184": "The cutest fox around.",
|
|
||||||
"150400803503472640": "The big huggy turtle boye.",
|
|
||||||
"620777734427115523": "The small huggy turtle boye.",
|
|
||||||
"310801870048198667": "An extremely talented artist and modder.",
|
|
||||||
"328223274133880833": "The stealthiest hitman.",
|
|
||||||
"219661798742163467": "An extremely talented artist and modder.",
|
|
||||||
"440399719076855818":
|
|
||||||
"You are, uhh, Stay Put, Soft Puppy, Es-Pee, Swift Pacemaker, Smug Poyo, and many more.\n...Seriously, this woman has too many names.",
|
|
||||||
"243061915281129472":
|
|
||||||
"Some random conlanger, worldbuilder and programmer doofus. ~~May also secretly be a nyan. :3~~"
|
|
||||||
};
|
|
||||||
|
|
||||||
export default new NamedCommand({
|
|
||||||
description: "Tells you who you or the specified user is.",
|
|
||||||
aliases: ["whoami"],
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
const id = author.id;
|
|
||||||
|
|
||||||
if (id in registry) {
|
|
||||||
channel.send(registry[id]);
|
|
||||||
} else {
|
|
||||||
channel.send("You haven't been added to the registry yet!");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
user: new Command({
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
const user: User = args[0];
|
|
||||||
const id = user.id;
|
|
||||||
|
|
||||||
if (id in registry) {
|
|
||||||
channel.send(`\`${user.username}\` - ${registry[id]}`);
|
|
||||||
} else {
|
|
||||||
channel.send(`\`${user.username}#${user.discriminator}\` hasn't been added to the registry yet!`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
any: new Command({
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
if (guild) {
|
|
||||||
const query: string = args.join(" ");
|
|
||||||
const member = await getMemberByUsername(guild, query);
|
|
||||||
|
|
||||||
if (member && member.id in registry) {
|
|
||||||
const id = member.id;
|
|
||||||
|
|
||||||
if (id in registry) {
|
|
||||||
channel.send(`\`${member.user.username}\` - ${registry[member.id]}`);
|
|
||||||
} else {
|
|
||||||
channel.send(`\`${member.user.username}\` hasn't been added to the registry yet!`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
channel.send(`Couldn't find a user by the name of \`${query}\`!`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
channel.send(
|
|
||||||
"You must run this in a guild! (*If you have the user's ID, you don't have to be in a guild.*)"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
|
@ -50,113 +50,6 @@ export default new NamedCommand({
|
||||||
channel.send(`The custom prefix for this guild is now \`${args[0]}\`.`);
|
channel.send(`The custom prefix for this guild is now \`${args[0]}\`.`);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}),
|
|
||||||
welcome: new NamedCommand({
|
|
||||||
description: "Configure your server's welcome settings for the bot.",
|
|
||||||
usage: "type/channel <...>",
|
|
||||||
run: "You need to specify which part to modify, `type`/`channel`.",
|
|
||||||
subcommands: {
|
|
||||||
type: new NamedCommand({
|
|
||||||
description:
|
|
||||||
"Sets how welcome messages are displayed for your server. Removes welcome messages if unspecified.",
|
|
||||||
usage: "`none`/`text`/`graphical`",
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
if (guild) {
|
|
||||||
Storage.getGuild(guild.id).welcomeType = "none";
|
|
||||||
Storage.save();
|
|
||||||
channel.send("Set this server's welcome type to `none`.");
|
|
||||||
} else {
|
|
||||||
channel.send("You must use this command in a server.");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// I should probably make this a bit more dynamic... Oh well.
|
|
||||||
subcommands: {
|
|
||||||
text: new NamedCommand({
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
if (guild) {
|
|
||||||
Storage.getGuild(guild.id).welcomeType = "text";
|
|
||||||
Storage.save();
|
|
||||||
channel.send("Set this server's welcome type to `text`.");
|
|
||||||
} else {
|
|
||||||
channel.send("You must use this command in a server.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
graphical: new NamedCommand({
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
if (guild) {
|
|
||||||
Storage.getGuild(guild.id).welcomeType = "graphical";
|
|
||||||
Storage.save();
|
|
||||||
channel.send("Set this server's welcome type to `graphical`.");
|
|
||||||
} else {
|
|
||||||
channel.send("You must use this command in a server.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
channel: new NamedCommand({
|
|
||||||
description: "Sets the welcome channel for your server. Type `#` to reference the channel.",
|
|
||||||
usage: "(<channel mention>)",
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
if (guild) {
|
|
||||||
Storage.getGuild(guild.id).welcomeChannel = channel.id;
|
|
||||||
Storage.save();
|
|
||||||
channel.send(`Successfully set ${channel} as the welcome channel for this server.`);
|
|
||||||
} else {
|
|
||||||
channel.send("You must use this command in a server.");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// If/when channel types come out, this will be the perfect candidate to test it.
|
|
||||||
any: new Command({
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
if (guild) {
|
|
||||||
const match = args[0].match(/^<#(\d{17,19})>$/);
|
|
||||||
|
|
||||||
if (match) {
|
|
||||||
Storage.getGuild(guild.id).welcomeChannel = match[1];
|
|
||||||
Storage.save();
|
|
||||||
channel.send(
|
|
||||||
`Successfully set this server's welcome channel to ${match[0]}.`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
channel.send(
|
|
||||||
"You must provide a reference channel. You can do this by typing `#` then searching for the proper channel."
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
channel.send("You must use this command in a server.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
message: new NamedCommand({
|
|
||||||
description:
|
|
||||||
"Sets a custom welcome message for your server. Use `%user%` as the placeholder for the user.",
|
|
||||||
usage: "(<message>)",
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
if (guild) {
|
|
||||||
Storage.getGuild(guild.id).welcomeMessage = null;
|
|
||||||
Storage.save();
|
|
||||||
channel.send("Reset your server's welcome message to the default.");
|
|
||||||
} else {
|
|
||||||
channel.send("You must use this command in a server.");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
any: new Command({
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
if (guild) {
|
|
||||||
const message = args.join(" ");
|
|
||||||
Storage.getGuild(guild.id).welcomeMessage = message;
|
|
||||||
Storage.save();
|
|
||||||
channel.send(`Set your server's welcome message to \`${message}\`.`);
|
|
||||||
} else {
|
|
||||||
channel.send("You must use this command in a server.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
@ -304,19 +197,6 @@ export default new NamedCommand({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}),
|
|
||||||
syslog: new NamedCommand({
|
|
||||||
description: "Sets up the current channel to receive system logs.",
|
|
||||||
permission: PERMISSIONS.BOT_ADMIN,
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
if (guild) {
|
|
||||||
Config.systemLogsChannel = channel.id;
|
|
||||||
Config.save();
|
|
||||||
channel.send(`Successfully set ${channel} as the system logs channel.`);
|
|
||||||
} else {
|
|
||||||
channel.send("DM system log channels aren't supported.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
import {Command, NamedCommand} from "../../core";
|
|
||||||
import * as math from "mathjs";
|
|
||||||
import {MessageEmbed} from "discord.js";
|
|
||||||
|
|
||||||
export default new NamedCommand({
|
|
||||||
description: "Calculates a specified math expression.",
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
if (!args[0]) {
|
|
||||||
channel.send("Please provide a calculation.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let resp;
|
|
||||||
try {
|
|
||||||
resp = math.evaluate(args.join(" "));
|
|
||||||
} catch (e) {
|
|
||||||
channel.send("Please provide a *valid* calculation.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const embed = new MessageEmbed()
|
|
||||||
.setColor(0xffffff)
|
|
||||||
.setTitle("Math Calculation")
|
|
||||||
.addField("Input", `\`\`\`js\n${args.join("")}\`\`\``)
|
|
||||||
.addField("Output", `\`\`\`js\n${resp}\`\`\``);
|
|
||||||
channel.send(embed);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,6 +0,0 @@
|
||||||
import {Command, NamedCommand} from "../../core";
|
|
||||||
|
|
||||||
export default new NamedCommand({
|
|
||||||
description: "Gives you the Github link.",
|
|
||||||
run: "https://github.com/keanuplayz/TravBot-v3"
|
|
||||||
});
|
|
|
@ -1,12 +0,0 @@
|
||||||
import {Command, NamedCommand} from "../../core";
|
|
||||||
|
|
||||||
export default new NamedCommand({
|
|
||||||
description: "Gives you the invite link.",
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
channel.send(
|
|
||||||
`https://discordapp.com/api/oauth2/authorize?client_id=${client.user!.id}&permissions=${
|
|
||||||
args[0] || 8
|
|
||||||
}&scope=bot`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,62 +0,0 @@
|
||||||
import {Command, NamedCommand} from "../../core";
|
|
||||||
import moment from "moment";
|
|
||||||
import {Storage} from "../../structures";
|
|
||||||
import {MessageEmbed} from "discord.js";
|
|
||||||
|
|
||||||
export default new NamedCommand({
|
|
||||||
description: "Keep and edit your personal todo list.",
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
const user = Storage.getUser(author.id);
|
|
||||||
const embed = new MessageEmbed().setTitle(`Todo list for ${author.tag}`).setColor("BLUE");
|
|
||||||
|
|
||||||
for (const timestamp in user.todoList) {
|
|
||||||
const date = new Date(Number(timestamp));
|
|
||||||
embed.addField(
|
|
||||||
`${moment(date).format("LT")} ${moment(date).format("LL")} (${moment(date).fromNow()})`,
|
|
||||||
user.todoList[timestamp]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
channel.send(embed);
|
|
||||||
},
|
|
||||||
subcommands: {
|
|
||||||
add: new NamedCommand({
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
const user = Storage.getUser(author.id);
|
|
||||||
const note = args.join(" ");
|
|
||||||
user.todoList[Date.now().toString()] = note;
|
|
||||||
console.debug(user.todoList);
|
|
||||||
Storage.save();
|
|
||||||
channel.send(`Successfully added \`${note}\` to your todo list.`);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
remove: new NamedCommand({
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
const user = Storage.getUser(author.id);
|
|
||||||
const note = args.join(" ");
|
|
||||||
let isFound = false;
|
|
||||||
|
|
||||||
for (const timestamp in user.todoList) {
|
|
||||||
const selectedNote = user.todoList[timestamp];
|
|
||||||
|
|
||||||
if (selectedNote === note) {
|
|
||||||
delete user.todoList[timestamp];
|
|
||||||
Storage.save();
|
|
||||||
isFound = true;
|
|
||||||
channel.send(`Removed \`${note}\` from your todo list.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isFound) channel.send("That item couldn't be found.");
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
clear: new NamedCommand({
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
const user = Storage.getUser(author.id);
|
|
||||||
user.todoList = {};
|
|
||||||
Storage.save();
|
|
||||||
channel.send("Cleared todo list.");
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,38 +0,0 @@
|
||||||
import {Command, NamedCommand} from "../../core";
|
|
||||||
// Anycasting Alert
|
|
||||||
const translate = require("translate-google");
|
|
||||||
|
|
||||||
export default new NamedCommand({
|
|
||||||
description: "Translates your input.",
|
|
||||||
usage: "<lang ID> <input>",
|
|
||||||
async run({message, channel, guild, author, member, client, args}) {
|
|
||||||
const lang = args[0];
|
|
||||||
const input = args.slice(1).join(" ");
|
|
||||||
translate(input, {
|
|
||||||
to: lang
|
|
||||||
})
|
|
||||||
.then((res: any) => {
|
|
||||||
channel.send({
|
|
||||||
embed: {
|
|
||||||
title: "Translation",
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
name: "Input",
|
|
||||||
value: `\`\`\`${input}\`\`\``
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Output",
|
|
||||||
value: `\`\`\`${res}\`\`\``
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((err: any) => {
|
|
||||||
console.error(err);
|
|
||||||
channel.send(
|
|
||||||
`${err}\nPlease use the following list: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -69,4 +69,3 @@ import "./modules/emoteRegistry";
|
||||||
import "./modules/channelListener";
|
import "./modules/channelListener";
|
||||||
import "./modules/intercept";
|
import "./modules/intercept";
|
||||||
import "./modules/messageEmbed";
|
import "./modules/messageEmbed";
|
||||||
import "./modules/guildMemberAdd";
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import {client} from "../index";
|
import {client} from "../index";
|
||||||
import FileManager from "./storage";
|
import FileManager from "./storage";
|
||||||
import {EmoteRegistryDump, Config} from "../structures";
|
import {EmoteRegistryDump} from "../structures";
|
||||||
import {TextChannel} from "discord.js";
|
|
||||||
|
|
||||||
function updateGlobalEmoteRegistry(): void {
|
function updateGlobalEmoteRegistry(): void {
|
||||||
const data: EmoteRegistryDump = {version: 1, list: []};
|
const data: EmoteRegistryDump = {version: 1, list: []};
|
||||||
|
@ -39,43 +38,13 @@ client.on("emojiUpdate", () => {
|
||||||
updateGlobalEmoteRegistry();
|
updateGlobalEmoteRegistry();
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on("guildCreate", (guild) => {
|
client.on("guildCreate", () => {
|
||||||
console.log(
|
console.log("Updated emote registry.");
|
||||||
`[GUILD JOIN] ${guild.name} (${guild.id}) added the bot. Owner: ${guild.owner!.user.tag} (${
|
|
||||||
guild.owner!.user.id
|
|
||||||
}). Updated emote registry.`
|
|
||||||
);
|
|
||||||
|
|
||||||
if (Config.systemLogsChannel) {
|
|
||||||
const channel = client.channels.cache.get(Config.systemLogsChannel);
|
|
||||||
|
|
||||||
if (channel && channel.type === "text") {
|
|
||||||
(channel as TextChannel).send(
|
|
||||||
`TravBot joined: \`${guild.name}\`. The owner of this guild is: \`${guild.owner!.user.tag}\` (\`${
|
|
||||||
guild.owner!.user.id
|
|
||||||
}\`)`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
console.warn(`${Config.systemLogsChannel} is not a valid text channel for system logs!`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateGlobalEmoteRegistry();
|
updateGlobalEmoteRegistry();
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on("guildDelete", (guild) => {
|
client.on("guildDelete", () => {
|
||||||
console.log(`[GUILD LEAVE] ${guild.name} (${guild.id}) removed the bot. Updated emote registry.`);
|
console.log("Updated emote registry.");
|
||||||
|
|
||||||
if (Config.systemLogsChannel) {
|
|
||||||
const channel = client.channels.cache.get(Config.systemLogsChannel);
|
|
||||||
|
|
||||||
if (channel && channel.type === "text") {
|
|
||||||
(channel as TextChannel).send(`\`${guild.name}\` (\`${guild.id}\`) removed the bot.`);
|
|
||||||
} else {
|
|
||||||
console.warn(`${Config.systemLogsChannel} is not a valid text channel for system logs!`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateGlobalEmoteRegistry();
|
updateGlobalEmoteRegistry();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
import {createCanvas, loadImage, Canvas} from "canvas";
|
|
||||||
import {TextChannel, MessageAttachment} from "discord.js";
|
|
||||||
import {parseVars} from "../lib";
|
|
||||||
import {Storage} from "../structures";
|
|
||||||
import {client} from "../index";
|
|
||||||
|
|
||||||
function applyText(canvas: Canvas, text: string) {
|
|
||||||
const ctx = canvas.getContext("2d");
|
|
||||||
let fontSize = 70;
|
|
||||||
|
|
||||||
do {
|
|
||||||
ctx.font = `${(fontSize -= 10)}px sans-serif`;
|
|
||||||
} while (ctx.measureText(text).width > canvas.width - 300);
|
|
||||||
|
|
||||||
return ctx.font;
|
|
||||||
}
|
|
||||||
|
|
||||||
client.on("guildMemberAdd", async (member) => {
|
|
||||||
const {welcomeType, welcomeChannel, welcomeMessage} = Storage.getGuild(member.guild.id);
|
|
||||||
|
|
||||||
if (welcomeChannel) {
|
|
||||||
const channel = member.guild.channels.cache.get(welcomeChannel);
|
|
||||||
|
|
||||||
if (channel && channel.type === "text") {
|
|
||||||
if (welcomeType === "graphical") {
|
|
||||||
const canvas = createCanvas(700, 250);
|
|
||||||
const ctx = canvas.getContext("2d");
|
|
||||||
const background = await loadImage(
|
|
||||||
"https://raw.githubusercontent.com/keanuplayz/TravBot/dev/assets/wallpaper.png"
|
|
||||||
);
|
|
||||||
ctx.drawImage(background, 0, 0, canvas.width, canvas.height);
|
|
||||||
|
|
||||||
ctx.strokeStyle = "#74037b";
|
|
||||||
ctx.strokeRect(0, 0, canvas.width, canvas.height);
|
|
||||||
|
|
||||||
ctx.font = "28px sans-serif";
|
|
||||||
ctx.fillStyle = "#ffffff";
|
|
||||||
ctx.fillText("Welcome to the server,", canvas.width / 2.5, canvas.height / 3.5);
|
|
||||||
|
|
||||||
ctx.font = applyText(canvas, member.displayName);
|
|
||||||
ctx.fillStyle = "#ffffff";
|
|
||||||
ctx.fillText(`${member.displayName}!`, canvas.width / 2.5, canvas.height / 1.5);
|
|
||||||
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(125, 125, 100, 0, Math.PI * 2, true);
|
|
||||||
ctx.closePath();
|
|
||||||
ctx.clip();
|
|
||||||
|
|
||||||
const avatarURL =
|
|
||||||
member.user.avatarURL({
|
|
||||||
dynamic: true,
|
|
||||||
size: 2048,
|
|
||||||
format: "png"
|
|
||||||
}) ?? member.user.defaultAvatarURL;
|
|
||||||
const avatar = await loadImage(avatarURL);
|
|
||||||
ctx.drawImage(avatar, 25, 25, 200, 200);
|
|
||||||
|
|
||||||
const attachment = new MessageAttachment(canvas.toBuffer("image/png"), "welcome-image.png");
|
|
||||||
(channel as TextChannel).send(`Welcome \`${member.user.tag}\`!`, attachment);
|
|
||||||
} else if (welcomeType === "text") {
|
|
||||||
(channel as TextChannel).send(
|
|
||||||
parseVars(
|
|
||||||
welcomeMessage || "Say hello to `%user%`, everyone! We all need a warm welcome sometimes :D",
|
|
||||||
{
|
|
||||||
user: member.user.tag
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.error(`"${welcomeChannel}" is not a valid text channel ID!`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -3,9 +3,7 @@ import {Config} from "../structures";
|
||||||
|
|
||||||
client.once("ready", () => {
|
client.once("ready", () => {
|
||||||
if (client.user) {
|
if (client.user) {
|
||||||
console.ready(
|
console.ready(`Logged in as ${client.user.tag}.`);
|
||||||
`Logged in as ${client.user.tag}, ready to serve ${client.users.cache.size} users in ${client.guilds.cache.size} servers..`
|
|
||||||
);
|
|
||||||
client.user.setActivity({
|
client.user.setActivity({
|
||||||
type: "LISTENING",
|
type: "LISTENING",
|
||||||
name: `${Config.prefix}help`
|
name: `${Config.prefix}help`
|
||||||
|
|
|
@ -3,15 +3,12 @@ import {select, GenericJSON, GenericStructure} from "./lib";
|
||||||
import {watch} from "fs";
|
import {watch} from "fs";
|
||||||
import {Guild as DiscordGuild, Snowflake} from "discord.js";
|
import {Guild as DiscordGuild, Snowflake} from "discord.js";
|
||||||
|
|
||||||
// Maybe use getters and setters to auto-save on set?
|
|
||||||
|
|
||||||
class ConfigStructure extends GenericStructure {
|
class ConfigStructure extends GenericStructure {
|
||||||
public token: string;
|
public token: string;
|
||||||
public prefix: string;
|
public prefix: string;
|
||||||
public owner: string;
|
public owner: string;
|
||||||
public admins: string[];
|
public admins: string[];
|
||||||
public support: string[];
|
public support: string[];
|
||||||
public systemLogsChannel: string | null;
|
|
||||||
|
|
||||||
constructor(data: GenericJSON) {
|
constructor(data: GenericJSON) {
|
||||||
super("config");
|
super("config");
|
||||||
|
@ -20,7 +17,6 @@ class ConfigStructure extends GenericStructure {
|
||||||
this.owner = select(data.owner, "", String);
|
this.owner = select(data.owner, "", String);
|
||||||
this.admins = select(data.admins, [], String, true);
|
this.admins = select(data.admins, [], String, true);
|
||||||
this.support = select(data.support, [], String, true);
|
this.support = select(data.support, [], String, true);
|
||||||
this.systemLogsChannel = select(data.systemLogsChannel, null, String);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,7 +26,6 @@ class User {
|
||||||
public lastMonday: number;
|
public lastMonday: number;
|
||||||
public timezone: number | null; // This is for the standard timezone only, not the daylight savings timezone
|
public timezone: number | null; // This is for the standard timezone only, not the daylight savings timezone
|
||||||
public daylightSavingsRegion: "na" | "eu" | "sh" | null;
|
public daylightSavingsRegion: "na" | "eu" | "sh" | null;
|
||||||
public todoList: {[timestamp: string]: string};
|
|
||||||
|
|
||||||
constructor(data?: GenericJSON) {
|
constructor(data?: GenericJSON) {
|
||||||
this.money = select(data?.money, 0, Number);
|
this.money = select(data?.money, 0, Number);
|
||||||
|
@ -40,41 +35,14 @@ class User {
|
||||||
this.daylightSavingsRegion = /^((na)|(eu)|(sh))$/.test(data?.daylightSavingsRegion)
|
this.daylightSavingsRegion = /^((na)|(eu)|(sh))$/.test(data?.daylightSavingsRegion)
|
||||||
? data?.daylightSavingsRegion
|
? data?.daylightSavingsRegion
|
||||||
: null;
|
: null;
|
||||||
this.todoList = {};
|
|
||||||
|
|
||||||
if (data) {
|
|
||||||
for (const timestamp in data.todoList) {
|
|
||||||
const note = data.todoList[timestamp];
|
|
||||||
if (typeof note === "string") {
|
|
||||||
this.todoList[timestamp] = note;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Guild {
|
class Guild {
|
||||||
public prefix: string | null;
|
public prefix: string | null;
|
||||||
public welcomeType: "none" | "text" | "graphical";
|
|
||||||
public welcomeChannel: string | null;
|
|
||||||
public welcomeMessage: string | null;
|
|
||||||
|
|
||||||
constructor(data?: GenericJSON) {
|
constructor(data?: GenericJSON) {
|
||||||
this.prefix = select(data?.prefix, null, String);
|
this.prefix = select(data?.prefix, null, String);
|
||||||
this.welcomeChannel = select(data?.welcomeChannel, null, String);
|
|
||||||
this.welcomeMessage = select(data?.welcomeMessage, null, String);
|
|
||||||
|
|
||||||
switch (data?.welcomeType) {
|
|
||||||
case "text":
|
|
||||||
this.welcomeType = "text";
|
|
||||||
break;
|
|
||||||
case "graphical":
|
|
||||||
this.welcomeType = "graphical";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
this.welcomeType = "none";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue