Initial gitea commit

This commit is contained in:
Kaydax 2023-09-17 01:29:56 -04:00
commit d647273993
Signed by: Kaydax
GPG Key ID: 6D32EED87DE7F090
61 changed files with 7696 additions and 0 deletions

4
.dockerignore Normal file
View File

@ -0,0 +1,4 @@
node_modules
npm-debug.log
Dockerfile
.dockerignore

9
.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
node_modules
backups
secret.js
lavalink/logs
lavalink/application.yml
lavalink/Lavalink.jar.old
npm-debug.log
config.json
utils/Utils.js.old

165
App.js Normal file
View File

@ -0,0 +1,165 @@
module.exports = class App
{
constructor()
{
var secret = require("./secret.js");
this.bot = new Eris(secret.discord, { maxShards: 'auto' });
this.commands = new Commands(this);
this.version = require('./package.json').version;
this.config = JSON.parse(fs.readFileSync("./config.json"));
if(this.config.disableDBL == false)
{
setInterval(() => {
DLA.postGuilds(this.bot, secret.tokens);
}, 1800000);
}
this.db = new Database(this);
this.bot.on("ready", this.onReady.bind(this));
this.bot.on("guildCreate", this.onJoin.bind(this));
this.bot.on("guildMemberAdd", this.onMemberJoined.bind(this));
this.bot.on("messageCreate", this.onMessage.bind(this));
this.bot.on("error", this.onDisconnect.bind(this));
this.bot.connect();
}
onReady()
{
console.log("Vertbot is now online.");
this.bot.editStatus("online", {name: "v-help for info", type: 0})
var secret = require("./secret.js");
if(this.config.disableDBL == false) { DLA.postGuilds(this.bot, secret.tokens); } //Post the guild stats to bot list apon launch
//TODO: init function?
this.lavalink = new Lavalink(this);
//this.settings = new Settings(this);
}
onPosted()
{
console.log("Server count posted!");
}
onDBLError()
{
console.error("Server count could not be posted. This may be because of the fact there is no token");
}
onDisconnect(err, id)
{
//this.bot.disconnect();
//console.log("Lost connection to discord, trying to reconnect...");
//this.bot.connect();
console.log(err);
}
onJoin(guild)
{
var channel = U.getLogicalChannel(this, guild);
if(channel != null)
{
this.bot.createMessage(channel.id, U.createWelcomeEmbed(this));
}
}
onMemberJoined(guild, member)
{
if(member.username.toLowerCase().includes("h0nd"))
{
member.ban(7, "Shitty fucking spammer");
}
}
async onMessage(msg)
{
try
{
if(!msg.channel.type == 1)
{
//var prefix = (await this.db.getGuildSettings(msg.channel.guild.id)).prefix || this.config.prefix;
var prefix = (this.bot.user.id == "430118450795380736") ? "[=" : (await this.db.getGuildSettings(msg.channel.guild.id)).prefix || this.config.prefix;
var mention = msg.content.startsWith(this.bot.user.mention) ? "<@" + this.bot.user.id + ">" : "<@!" + this.bot.user.id + ">"
if((msg.content.startsWith(prefix) || msg.content.startsWith(mention)) && !msg.author.bot)
{
//the command
var text = msg.content.startsWith(prefix) ? msg.content.slice(prefix.length).trim() : msg.content.slice((mention).length).trim(); //TODO: trim?
this.commands.doCommand(msg, this, text); //Command system
}
if(msg.author.bot && msg.author.id == "817790099823525909")
{
//Scramble!
if(msg.embeds.length > 0)
{
if(msg.embeds[0].title == "Scramble!")
{
var word = msg.embeds[0].description.split("\n")[1];
console.log(word);
var words = ["bell","jail","heart","Mickey Mouse","bus","butterfly","elephant","flower","turtle","snowflake","candy","key","sun","starfish","button","leg","table","ghost","orange","house","nail","apple","football","love","ants","beak","feet","river","lemon","daisy","jar","clock","flag","snail","smile","island","inchworm","mitten","king","bench","dog","knee","horse","music","square","hair","doll","sea turtle","book","whale","arm","seashell","shirt","purse","stairs","oval","camera","truck","motorcycle","moon","fly","pillow","coat","helicopter","bowl","mouth","chicken","light","hippo","woman","chimney","grapes","jacket","float","rock","snowman","bread","snake","corn","cup","baseball","pizza","beach","bug","sunglasses","rain","robot","cherry","bunny","lamp","popsicle","ears","lollipop","socks","ladybug","triangle","zebra","broom","mouse","caterpillar","dragon","bone","door","desk","grass","car","curl","cat","ring","worm","banana","mountain","water","ball","roly poly/pill bug/doodle bug","legs","sheep","rocket","man","coin","ant","night","crayon","ocean","swimming pool","bumblebee","swing","person","blanket","bark","slide","boy","hat","star","mountains","diamond","tree","bow","computer","zigzag","dinosaur","balloon","cow","boat","bunk bed","giraffe","eyes","bird","chair","comb","circle","nose","hook","feather","bear","bee","ear","leaf","pig","drum","pie","milk","suitcase","fire","window","wheel","glasses","kite","box","cupcake","zoo","girl","pants","bed","rainbow","hamburger","jellyfish","bracelet","baby","octopus","ship","eye","lips","alive","face","dream","spider web","angel","train","egg","tail","alligator","finger","pen","bike","fish","cheese","bounce","blocks","kitten","bathroom","crack","skateboard","fork","bridge","plant","owl","branch","ice cream cone","monkey","spoon","shoe","duck","crab","lizard","lion","backpack","sea","hand","head","frog","carrot","cloud","candle","line","bat","neck","cube","family","airplane","Earth","spider","basketball","monster","pencil","cookie","rabbit"];
var scram = await unscramble(word, words);
console.log(scram);
this.bot.createMessage(msg.channel.id, U.createQuickEmbed("Word Unscrambled!", "Try: `" + scram.join(", ") + "`"));
}
//Translate!
if(msg.embeds[0].title == "Translate!")
{
var word = msg.embeds[0].description.split("\n")[1];
console.log(word);
const res = await fetch("https://libretranslate.de/translate", {
method: "POST",
body: JSON.stringify({
q: word,
source: "es",
target: "en",
format: "text",
api_key: ""
}),
headers: { "Content-Type": "application/json" }
});
var json = await res.json();
var tran = json.translatedText;
console.log(json);
console.log(tran);
this.bot.createMessage(msg.channel.id, U.createQuickEmbed("Word Translated!", "The word is: `" + tran + "`"));
}
}
}
} else {
if(!msg.author.bot && !msg.author.id == "817790099823525909")
{
this.bot.createMessage(msg.channel.id, U.createErrorEmbed("This is a DM chat", "I can't do anything in dms. If you need a gf that bad go outside"));
}
}
}
catch(e)
{
console.log(e);
//this.bot.createMessage(msg.channel.id, "" + (typeof e));
}
}
}
//var YouTube = require('youtube-node');
var Eris = require('eris');
var assert = require("assert");
//var unscramble = require('unscramble');
const unscramble = require('word-unscrambler');
//const { translate } = require('free-translate');
const fetch = require('node-fetch');
var U = require('./utils/Utils.js');
var DLA = require('./utils/Discord-List-api.js');
var Commands = require("./commands/Commands.js");
var Lavalink = require("./utils/Lavalink.js");
var Database = require("./utils/Database.js");
var Settings = require("./utils/Settings.js");
//var RestartHandler = require("./utils/RestartHandler.js");
var fs = require("fs");

16
Dockerfile Normal file
View File

@ -0,0 +1,16 @@
FROM node:19-alpine
# Create app directory
WORKDIR /app
#copy package(lock).json
COPY package*.json ./
#install git (needed in alpine for git repos)
#RUN apk add git
#install packages
RUN npm ci --only=production
# Bundle app source
COPY . .
#ports and env
#EXPOSE 80
CMD [ "node", "main.js" ]

26
LICENSE Normal file
View File

@ -0,0 +1,26 @@
# DON'T BE A DICK PUBLIC LICENSE
> Version 1.1, December 2016
> Copyright (C) 2019 Kaydax & tehZevo
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document.
> DON'T BE A DICK PUBLIC LICENSE
> TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
1. Do whatever you like with the original work, just don't be a dick.
Being a dick includes - but is not limited to - the following instances:
1a. Outright copyright infringement - Don't just copy this and change the name.
1b. Selling the unmodified original with no work done what-so-ever, that's REALLY being a dick.
1c. Modifying the original work to contain hidden harmful content. That would make you a PROPER dick.
2. If you become rich through modifications, related works/services, or supporting the original work,
share the love. Only a dick would make loads off this work and not buy the original work's
creator(s) a pint.
3. Code is provided with no warranty. Using somebody else's code and bitching when it goes wrong makes
you a DONKEY dick. Fix the problem yourself. A non-dick would submit the fix back.

2
README.md Normal file
View File

@ -0,0 +1,2 @@
# Vertbot
Vertbot - A lightweight lag free music bot

212
commands/Command.js Normal file
View File

@ -0,0 +1,212 @@
module.exports = class Command
{
constructor()
{
this.name = "";
this.aliases = [];
this.usage = "";
this.description = "";
this.commandFiles = [];
this.commands = [];
//required permissions (must have all; except for hierarchy)
this.permissions = [];
this.parent = null;
//TODO: guild/dm commands?
}
setParent(parent)
{
this.parent = parent;
}
/** returns the root of the command tree */
getRoot()
{
var parent = this.parent;
while(parent.parent != null)
{
parent = parent.parent;
}
return parent;
}
init()
{
//TODO: other init stuff
this.reload();
}
reload()
{
this.commands = this.commandFiles.map((e) =>
{
//console.log("loading " + e + " in " + this.constructor.name);
var sub = new (require(e))();
sub.setParent(this);
return sub;
});
}
async doCommand(message, app, text)
{
text = text || message.content;
//Get the playlist settings for dj mode when checking permissions
var pl = await app.db.getPlaylist(message.channel.guild.id);
//grab permissions for user that sent the message
var perms = await P.getPerms(app, message);
var ret = this.findCommand(text);
if(ret != null && ret.sub != this)
{
if(perms.includes("banned") && !perms.includes("dev"))
{
app.bot.createMessage(message.channel.id, U.createErrorEmbed("You seem to be banned", "You seem to be banned from using the bot by a developer, sorry about that..."));
return;
}
if(!U.canUseCommand(perms, ret.sub, pl))
{
//app.bot.createMessage(message.channel.id, U.wrapCode("ur perms here: " + Array.from(perms).join(" ")));
app.bot.createMessage(message.channel.id, U.createErrorEmbed("You don't have permissions", "You seem to not have `" + ret.sub.permissions.join(", ") + "`"));
return;
}
ret.sub.doCommand(message, app, ret.text);
return;
}
//TODO: display help, but not on root level
//TODO: we can use this != root check for that
if(this.parent != null)
{
app.bot.createMessage(message.channel.id, U.wrapMention(message, U.wrapCode(this.getHelp())));
}
}
/** pass a command FILENAME not an object */
addCommand(commandFile)
{
if(this.commandFiles.includes(commandFile))
{
console.log("REEEEEEE YOU ALREADY ADDED THIS COMMAND");
return;
}
this.commandFiles.push(commandFile);
this.reload();
}
findCommand(text)
{
var ret = {};
ret.text = null;
ret.sub = null;
text = text.trim(); //TODO: hmm
var token = text.split(/\s+/)[0]; //grab the first token in text
token = token.toLowerCase() //just to be safe
var matches = this.findMatchingCommands(token);
//no matches found
if(matches.length == 0)
{
return null;
}
//TODO: filter out commands user cant access?
//matches = matches.filter((e) => U.canUseCommand(perms, e));
return {sub: matches[0], text: text.slice(token.length).trim()}; //TODO: trim?
}
/** pass it a single command token, if perms is passed, performs permission checks, returns {cmd, canUse} */
findMatchingCommands(token)
{
token = token.toLowerCase(); //just to be safe
var commands = [];
for(var i = 0; i < this.commands.length; i++)
{
var sub = this.commands[i];
if(sub.name.toLowerCase().startsWith(token) || sub.aliases.some((e) => e.toLowerCase().startsWith(token)))
{
//var canUse = perms == null ? true : U.canUseCommand(perms, e);
//TODO: command visibility based on "hidden" and permissions (recursively?)
commands.push(sub);
}
//grab subcommand's matches too
commands = commands.concat(sub.findMatchingCommands(token));
}
return commands;
}
/** padLength = how much to pad name+usage by */
formatHelp(name, usage, desc, padLength)
{
var nameUsage = name + " " + usage;
padLength = padLength == null ? nameUsage.length - 1 : padLength;
nameUsage = pad(Array(padLength + 2).join(" "), nameUsage);
return nameUsage + " | " + desc; //TODO: OwO
}
/** if self, then print command's own help line, otherwise, print help for all subcommands */
getHelp(self)
{
if(self)
{
return this.formatHelp(this.name, this.usage, this.description);
}
var str = "";
var nameUsageLen = 0;
var data = [];
//iterate over each subcommand, gather data, get max length of name + usage
this.commands.forEach((e) =>
{
nameUsageLen = Math.max(nameUsageLen, e.name.length + e.usage.length);
data.push([e.name, e.usage, e.description]);
});
//create help return string (pad name + usage to max length)
data.forEach((e) =>
{
str += this.formatHelp(e[0], e[1], e[2], nameUsageLen);
str += "\n";
});
return str;
}
}
var U = require.main.require("./utils/Utils.js");
var P = require.main.require("./utils/Permissions.js");
function pad(pad, str, padLeft)
{
if (typeof str === 'undefined')
return pad;
if (padLeft)
{
return (pad + str).slice(-pad.length);
}
else
{
return (str + pad).substring(0, pad.length);
}
}

20
commands/Commands.js Normal file
View File

@ -0,0 +1,20 @@
var Command = require("./Command.js");
module.exports = class Commands extends Command
{
constructor()
{
super();
this.addCommand("./HelpCommand.js");
this.addCommand("./PingCommand.js");
this.addCommand("./DonateCommand.js");
this.addCommand("./SettingsCommand.js");
this.addCommand("./InfoCommand.js");
this.addCommand("./MusicCommand.js");
this.addCommand("./FunCommand.js");
this.addCommand("./DevCommand.js");
this.init();
}
}

21
commands/DevCommand.js Normal file
View File

@ -0,0 +1,21 @@
var Command = require("./Command.js");
module.exports = class DevCommand extends Command
{
//TODO: shuffle, loop, silent, volume (auto?), autoremove (queue mode?)
constructor()
{
super();
this.name = "dev";
this.description = "Commands for only my developer";
this.usage = "<subcommand>";
this.permissions = ["dev"];
this.addCommand("./dev/PermCommand.js");
this.addCommand("./dev/PermsCommand.js");
this.addCommand("./dev/AvatarCommand.js");
this.addCommand("./dev/SayCommand.js");
this.addCommand("./dev/TestCommand.js");
}
}

19
commands/DonateCommand.js Normal file
View File

@ -0,0 +1,19 @@
var Command = require("./Command.js");
module.exports = class DonateCommand extends Command
{
constructor()
{
super();
this.name = "donate";
this.description = "Help me run this bot!";
}
async doCommand(msg, app, text)
{
app.bot.createMessage(msg.channel.id, U.createDonateEmbed());
}
}
var U = require.main.require("./utils/Utils.js");

18
commands/FunCommand.js Normal file
View File

@ -0,0 +1,18 @@
var Command = require("./Command.js");
module.exports = class FunCommand extends Command
{
//TODO: shuffle, loop, silent, volume (auto?), autoremove (queue mode?)
constructor()
{
super();
this.name = "fun";
this.description = "Commands for some random fun things";
this.usage = "<subcommand>";
this.addCommand("./fun/AsciiCommand.js");
this.addCommand("./fun/BooruCommand.js");
this.addCommand("./fun/VideoCommand.js");
}
}

36
commands/HelpCommand.js Normal file
View File

@ -0,0 +1,36 @@
var Command = require("./Command.js");
module.exports = class HelpCommand extends Command
{
constructor()
{
super();
this.name = "help";
this.description = "shows you the help menu";
}
async doCommand(msg, app, text)
{
var command;
var self = false;
//if empty, use root
if(text.trim() == "")
{
command = this.getRoot();
}
else
{
//grab subcommand
command = this.getRoot().findCommand(text);
//if not found, use root
command = command == null ? this.getRoot() : command.sub
//Check if the command has sub commands or not, and if none are found then display just that command
self = command.commands.length == 0 ? true : false
}
U.sendHelp(app, msg, command, self);
}
}
var U = require.main.require("./utils/Utils.js");

20
commands/InfoCommand.js Normal file
View File

@ -0,0 +1,20 @@
var Command = require("./Command.js");
module.exports = class InfoCommand extends Command
{
constructor()
{
super();
this.name = "info";
this.description = "Gives you important info about me";
}
async doCommand(msg, app, text)
{
var prefix = (await app.db.getGuildSettings(msg.channel.guild.id)).prefix || app.config.prefix;
app.bot.createMessage(msg.channel.id, U.createInfoEmbed(app, msg.channel.guild.id, prefix, msg));
}
}
var U = require.main.require("./utils/Utils.js");

26
commands/MusicCommand.js Normal file
View File

@ -0,0 +1,26 @@
var Command = require("./Command.js");
module.exports = class MusicCommand extends Command
{
//TODO: shuffle, loop, silent, volume (auto?), autoremove (queue mode?)
constructor()
{
super();
this.name = "music";
this.description = "Commands for music related things";
this.usage = "<subcommand>";
this.addCommand("./music/PlayCommand.js");
this.addCommand("./music/AddCommand.js");
this.addCommand("./music/StopCommand.js");
this.addCommand("./music/ClearCommand.js");
this.addCommand("./music/RemoveCommand.js");
this.addCommand("./music/SkipCommand.js");
this.addCommand("./music/GotoCommand.js");
this.addCommand("./music/VolumeCommand.js");
this.addCommand("./music/BassCommand.js");
this.addCommand("./music/PlaylistCommand.js");
this.addCommand("./music/ControlCommand.js");
}
}

17
commands/PingCommand.js Normal file
View File

@ -0,0 +1,17 @@
var Command = require("./Command.js");
module.exports = class PingCommand extends Command
{
constructor()
{
super();
this.name = "ping";
this.description = "pong";
}
async doCommand(msg, app, text)
{
app.bot.createMessage(msg.channel.id, 'Here is my current shard latency: ' + msg.channel.guild.shard.latency + "ms");
}
}

View File

@ -0,0 +1,16 @@
var Command = require("./Command.js");
module.exports = class SettingsCommand extends Command
{
//TODO: shuffle, loop, silent, volume (auto?), autoremove (queue mode?)
constructor()
{
super();
this.name = "settings";
this.description = "Commands for bot settings";
this.usage = "<subcommand>";
this.addCommand("./settings/PrefixCommand.js");
}
}

View File

@ -0,0 +1,24 @@
var Command = require("../Command.js");
module.exports = class AvatarCommand extends Command
{
constructor()
{
super();
this.name = "avatar";
this.usage = "<url>";
this.description = "Sets the avatar to what ever url you put in";
this.permissions = ["dev"];
}
async doCommand(msg, app, text)
{
var url = text.trim();
const res = await require('snekfetch').get(url);
app.bot.editSelf({ avatar: `data:image/jpg;base64,${res.body.toString('base64')}` });
app.bot.createMessage(msg.channel.id, "Avatar Set!")
}
}
var U = require.main.require("./utils/Utils.js");

View File

@ -0,0 +1,75 @@
var Command = require("../Command.js");
module.exports = class PermCommand extends Command
{
constructor()
{
super();
this.name = "perm";
this.usage = "<user> <add/remove> <permission>";
this.description = "Add and remove permissions from users";
this.permissions = ["dev"];
}
async doCommand(msg, app, text)
{
var tokens = text.toLowerCase().split(/\s+/);
//not enough tokens
if(tokens.length < 3)
{
U.sendHelp(app, msg, this, true);
return;
}
var mention = tokens[0];
//grab id
var id = U.str2id(mention);
//fail, no user id provided
if(id == null)
{
U.sendHelp(app, msg, this, true);
return;
}
//grab user settings
var us = await app.db.getUserSettings(id);
var command = tokens[1];
var perm = tokens[2];
if(command == "add")
{
if(us.hasPermission(perm))
{
U.reply(app, msg, mention + " already has '" + perm + "'");
}
else
{
await us.addPermission(perm);
U.reply(app, msg, "Gave '" + perm + "' to " + mention);
}
}
else if(command == "remove")
{
if(!us.hasPermission(perm))
{
U.reply(app, msg, mention + " doesn't have '" + perm + "'");
}
else
{
await us.removePermission(perm);
U.reply(app, msg, "Removed '" + perm + "' from " + mention);
}
}
else if(command == "get")
{
var perms = us.getPermissions().join(", ");
U.reply(app, msg, mention + " has: " + perms);
}
}
}
var U = require.main.require("./utils/Utils.js");

View File

@ -0,0 +1,63 @@
var Command = require("../Command.js");
module.exports = class PermsCommand extends Command
{
constructor()
{
super();
this.name = "perms";
this.usage = "<user>";
this.description = "get the perms of a user";
this.permissions = ["dev"];
}
async doCommand(msg, app, text)
{
text = text.trim();
if(text == "")
{
//TODO: help?
app.bot.createMessage(msg.channel.id, U.createErrorEmbed("No user mentioned", "Please mention a user."))
return;
}
var id = U.str2id(text);
var member = U.getMemberById(msg.channel.guild, id);
if(member == null)
{
//TODO: help member not found
app.bot.createMessage(msg.channel.id, U.createErrorEmbed("Invalid user mentioned", "Please mention a valid user."))
return;
}
var dbp = Array.from(await P.getDBPerms(app, member));
var gp = Array.from(await P.getGuildPerms(app, member));
var rp = Array.from(await P.getRolePerms(app, member));
var cp = Array.from(await P.getConfigPerms(app, member));
var str = "";
if(dbp.length > 0)
{
str += "Database: " + dbp.join(", ") + "\n";
}
if(gp.length > 0)
{
str += "Guild: " + gp.join(", ") + "\n";
}
if(rp.length > 0)
{
str += "Role: " + rp.join(", ") + "\n";
}
if(cp.length > 0)
{
str += "Config: " + cp.join(", ") + "\n";
}
U.reply(app, msg, "Permissions for: " + text + U.wrapCode(str));
}
}
var U = require.main.require("./utils/Utils.js");
var P = require.main.require("./utils/Permissions.js");

View File

@ -0,0 +1,20 @@
var Command = require("../Command.js");
module.exports = class SayCommand extends Command
{
constructor()
{
super();
this.name = "dsay";
this.usage = "<words>";
this.description = "Makes me say something";
this.permissions = ["dev"];
}
async doCommand(msg, app, text)
{
msg.delete("Vertbot tts message (dsay)");
app.bot.createMessage(msg.channel.id, text);
}
}

View File

@ -0,0 +1,27 @@
var Command = require("../Command.js");
module.exports = class TestCommand extends Command
{
constructor()
{
super();
this.name = "test";
this.usage = "";
this.description = "A command that is used for anything I need it for";
this.permissions = ["dev"];
}
async doCommand(msg, app, text)
{
app.bot.createMessage(U.getLogicalChannel(app, msg.channel.guild).id, U.createWelcomeEmbed(app));
}
}
/*
NOTE:
This command is nothing important, as it has no use at all. It just exist for the purpose of debugging
the bot itself during development and should be ignored.
*/
var U = require.main.require("./utils/Utils.js");

View File

@ -0,0 +1,34 @@
var Command = require("../Command.js");
module.exports = class AsciiCommand extends Command
{
constructor()
{
super();
this.name = "ascii";
this.description = "Make some fun ascii text art!";
this.usage = "<text>"
}
async doCommand(msg, app, text)
{
if(text == "")
{
app.bot.createMessage(msg.channel.id, U.createErrorEmbed("No text", "You put no text in, so I can't create the ascii art..."));
return;
}
figlet(text, function(err, data) {
if (err) {
console.log('Something went wrong...');
console.dir(err);
return;
}
app.bot.createMessage(msg.channel.id, U.wrapCode(data));
});
}
}
var U = require.main.require("./utils/Utils.js");
var figlet = require("figlet");

View File

@ -0,0 +1,48 @@
var Command = require("../Command.js");
module.exports = class BooruCommand extends Command
{
constructor()
{
super();
this.name = "booru";
this.description = "NSFW commands are the best";
this.usage = "<site> <tags>"
}
async doCommand(msg, app, text)
{
var sites = ["danbooru","konachan","konachannet","yandere","gelbooru","rule34","safebooru","tbib","xbooru","youhateus"]
if(text <= 0)
{
app.bot.createMessage(msg.channel.id, U.createQuickEmbed("Here are the sites that are supported:","```" + sites.join("\n") + "```"));
} else if(text.split(' ')[0] == "help") {
app.bot.createMessage(msg.channel.id, U.createQuickEmbed("Here are the sites that are supported:","```" + sites.join("\n") + "```"));
} else {
var array = text.split(' ');
var site = array[0];
var tag = array.splice(1, text.length);
if(msg.channel.nsfw == true)
{
if(sites.indexOf(site) > -1)
{
const images = kaori.search(site, { tags: tag, random: true }).then((images) =>
{
images.map(image => {
console.log();
app.bot.createMessage(msg.channel.id, U.createBooruEmbed(msg.author.username, image.fileURL, image.tags.join(" "), image.fileURL))
});
}).catch(err => app.bot.createMessage(msg.channel.id, U.createErrorEmbed("Something went wrong", "```" + err + "```")));
} else {
app.bot.createMessage(msg.channel.id, U.createQuickEmbed("Here are the sites that are supported:","```" + sites.join("\n") + "```"));
}
} else {
app.bot.createMessage(msg.channel.id, U.createErrorEmbed("This channel is not NSFW", "This command can only be used in channels that are marked as NSFW"))
}
}
}
}
var U = require.main.require("./utils/Utils.js");
var kaori = require('kaori');

View File

@ -0,0 +1,24 @@
var Command = require("../Command.js");
module.exports = class VideoCommand extends Command {
constructor()
{
super();
this.name = "videochat";
this.description = "Creates a link to allow video chat in your current voice channel";
}
async doCommand(msg, app, text)
{
var vc = U.msg2vc(msg);
if(vc != undefined || vc != null)
{
app.bot.createMessage(msg.channel.id, U.createSuccessEmbed("Created video chat link", "[Click Here](https://discordapp.com/channels/" + msg.channel.guild.id + "/" + vc.id + ")"));
} else {
app.bot.createMessage(msg.channel.id, U.createErrorEmbed("No Voice Channel", "You seem to not be connected to any voice channel"));
}
}
}
var U = require.main.require("./utils/Utils.js");

View File

@ -0,0 +1,32 @@
var Command = require("../Command.js");
module.exports = class AddCommand extends Command
{
constructor()
{
super();
this.name = "add";
this.description = "add music to playlist";
this.usage = "<url / query>";
}
async doCommand(msg, app, text)
{
var pl = await app.db.getPlaylist(msg.channel.guild.id);
var perms = await P.getPerms(app, msg);
//if query doesnt begin with http(s)://, prepend ytsearch:
if(text.match(/^https?:\/\//i) == null)
{
text = "ytsearch:" + text;
}
//app.bot.createMessage(msg.channel.id, text);
await app.lavalink.add(msg, text, false);
}
}
var U = require.main.require("./utils/Utils.js");
var P = require.main.require("./utils/Permissions.js");

View File

@ -0,0 +1,75 @@
var Command = require("../Command.js");
module.exports = class BassCommand extends Command
{
constructor()
{
super();
this.name = "bassboost";
this.aliases = ["boost"];
this.description = "crank that bass up to 11 (well actually 100)";
this.usage = "<#>";
}
async bassBoost(msg, app, cmd, pl, perms)
{
var vc = U.msg2vc(msg);
var hasNumber = /\d/;
var player = await app.lavalink.getPlayer(vc, true);
var boost = U.getVal(msg.content, 0, 100) / 100;
if(hasNumber.test(cmd))
{
if(cmd != "")
{
//Bands: 0-15, Gain: -0.25-1.0
pl.setBoost(boost);
if(player != null)
{
var bands = [{"band": 0,"gain": boost},{"band": 1,"gain": boost},{"band": 2,"gain": boost}]
player.setEQ(bands);
}
app.bot.createMessage(msg.channel.id, U.createSuccessEmbed("Bass boost has been changed", "The bass boost has been set to " + (pl.boost * 100) + "%"));
}
} else {
if(cmd != "")
{
app.bot.createMessage(msg.channel.id, U.createErrorEmbed("Could not change bass boost", "You seem to have not put any numbers or something broke..."));
} else {
app.bot.createMessage(msg.channel.id, U.createQuickEmbed("Bass boost:", "Currently " + (pl.boost * 100) + "%"));
}
}
}
async doCommand(msg, app, text)
{
var cmd = text.trim().toLowerCase();
var hasNumber = /\d/;
var pl = await app.db.getPlaylist(msg.channel.guild.id);
var perms = await P.getPerms(app, msg);
//Getto permission check to have less code and to make it so the command can still be used in some ways
if(pl.djmode == true && U.canUseCommand(perms, {permissions: ["dj"]}, pl))
{
await this.bassBoost(msg, app, cmd, pl, perms);
} else {
if(pl.djmode == false || pl.djmode == undefined) { await this.bassBoost(msg, app, cmd, pl, perms); }
if(pl.djmode == true)
{
if(hasNumber.test(cmd))
{
//The person failed the getto permission check and we display the fact they don't have the role we want
app.bot.createMessage(msg.channel.id, U.createErrorEmbed("You don't have permissions", "You seem to not have `dj`"));
} else {
//Cool the person has the role we want
app.bot.createMessage(msg.channel.id, U.createQuickEmbed("Bass boost:", "Currently " + (pl.boost * 100) + "%"));
}
}
}
}
}
var U = require.main.require("./utils/Utils.js");
var P = require.main.require("./utils/Permissions.js");

View File

@ -0,0 +1,26 @@
var Command = require("../Command.js");
module.exports = class ClearCommand extends Command
{
constructor()
{
super();
this.name = "clear";
this.description = "clear the playlist";
this.permissions = ["dj"];
}
async doCommand(msg, app, text)
{
var pl = await app.db.getPlaylist(msg.channel.guild.id);
pl.clear();
if(U.currentVC(app, msg.channel.guild.id) != null)
{
app.lavalink.stop(msg, app);
}
app.bot.createMessage(msg.channel.id, U.createSuccessEmbed("Playlist cleared", "The playlist has been completely cleared"));
}
}
var U = require.main.require("./utils/Utils.js");

View File

@ -0,0 +1,19 @@
var Command = require("../Command.js");
module.exports = class ControlCommand extends Command
{
//TODO: shuffle, loop, silent, volume (auto?), autoremove (queue mode?)
constructor()
{
super();
this.name = "control";
this.description = "Commands for music control related things";
this.usage = "<subcommand>";
this.addCommand("./music/control/RepeatCommand.js");
this.addCommand("./music/control/SilentCommand.js");
this.addCommand("./music/control/ShuffleCommand.js");
this.addCommand("./music/control/DJModeCommand.js");
}
}

View File

@ -0,0 +1,56 @@
var Command = require("../Command.js");
module.exports = class GotoCommand extends Command
{
constructor()
{
super();
this.name = "goto";
this.description = "Goto a song in the playlist";
this.usage = "<# for video>"
this.permission = ["dj"]
}
async findSong(songNum, pl)
{
//This is prob the best way to make this command work with shuffle turned on... but this may change
return pl.indexes.indexOf(songNum, 0);
}
async doCommand(msg, app, text)
{
var vc = U.msg2vc(msg);
var pl = await app.db.getPlaylist(msg.channel.guild.id);
var gid = U.msg2gid(msg);
var hasNumber = /\d/;
var num = parseInt(text) - 1;
if(text.match(/^\d+$/) && (text.match(/^\d+$/) != 0))
{
if(pl.tracks[num] == undefined)
{
app.bot.createMessage(msg.channel.id, U.createErrorEmbed("Invalid number", "Please put a valid number"));
return;
} else {
await pl.setPosition(pl.shuffle ? await this.findSong(num, pl) : num); //advance playlist (wait for save confirmation to prevent glitch)
app.bot.createMessage(msg.channel.id, U.createSuccessEmbed("Set new track", "Set track to: `" + pl.tracks[num].info.title + "`"));
if(U.currentVC(app, gid) != null)
{
app.lavalink.play(vc, msg, app);
}
}
} else {
app.bot.createMessage(msg.channel.id, U.createErrorEmbed("Invalid number", "Please put a valid number"));
return;
}
}
}
/*
[=add https://www.youtube.com/watch?v=dJaVI7jzc8s
[=add https://www.youtube.com/watch?v=WNxZiBexDM8
[=add https://www.youtube.com/watch?v=IUun0CWrvT0
*/
var U = require.main.require("./utils/Utils.js");

View File

@ -0,0 +1,41 @@
var Command = require("../Command.js");
module.exports = class PlayCommand extends Command
{
constructor()
{
super();
this.name = "play";
this.aliases = ["join"];
this.description = "play music";
this.usage = "<url / query>";
}
async doCommand(msg, app, text)
{
var vc = U.msg2vc(msg);
var pl = await app.db.getPlaylist(msg.channel.guild.id);
var perms = await P.getPerms(app, msg);
if(msg.member.voiceState.channelID != null)
{
if(text.length > 0)
{
if(text.match(/^https?:\/\//i) == null)
{
text = "ytsearch:" + text;
}
//app.bot.createMessage(msg.channel.id, text);
await app.lavalink.add(msg, text, true, vc, app);
} else {
app.lavalink.play(vc, msg, app, true);
}
} else {
app.bot.createMessage(msg.channel.id, U.createErrorEmbed("No Voice Channel", "You seem to not be connected to any voice channel"));
}
}
}
var U = require.main.require("./utils/Utils.js");
var P = require.main.require("./utils/Permissions.js");

View File

@ -0,0 +1,24 @@
var Command = require("../Command.js");
module.exports = class PlaylistCommand extends Command
{
constructor()
{
super();
this.name = "list";
this.aliases = ["playlist", "np", "nowplaying"];
this.description = "show the playlist";
}
async doCommand(msg, app, text)
{
var pl = await app.db.getPlaylist(msg.channel.guild.id);
var vc = U.currentVC(app, msg.channel.guild.id);
var player = app.lavalink.getPlayer(vc, true); //jeebus
app.bot.createMessage(msg.channel.id, U.createPlaylistEmbed(pl, player, vc));
}
}
var U = require.main.require("./utils/Utils.js");

View File

@ -0,0 +1,42 @@
var Command = require("../Command.js");
module.exports = class ClearCommand extends Command
{
constructor()
{
super();
this.name = "remove";
this.description = "remove an item from the playlist";
this.usage = "<# for video>";
this.permissions = ["dj"];
}
async doCommand(msg, app, text)
{
var cmd = text.trim().toLowerCase();
var pl = await app.db.getPlaylist(msg.channel.guild.id);
var hasNumber = /\d/;
var number = U.getVal(cmd, 1, pl.tracks.length) - 1;
if(pl.tracks.length == 0)
{
app.bot.createMessage(msg.channel.id, U.createErrorEmbed("The playlist is empty", "You can't remove something that isn't there ya know..."));
return;
}
if(hasNumber.test(cmd))
{
if(cmd != "")
{
app.bot.createMessage(msg.channel.id, U.createSuccessEmbed("Removed track", "`" + (number + 1 + ": ") + pl.tracks[number].info.title + "` has been removed from the playlist"));
await pl.removeTrack(number);
}
} else {
app.bot.createMessage(msg.channel.id, U.createErrorEmbed("Could not remove track", "You seem to have not put any numbers or something broke..."));
return;
}
}
}
var U = require.main.require("./utils/Utils.js");

View File

@ -0,0 +1,81 @@
var Command = require("../Command.js");
module.exports = class SkipCommand extends Command
{
constructor()
{
super();
this.name = "skip";
this.description = "skip the current playlist item";
this.votes = [];
}
async voteSkip(msg, app, vc)
{
var user = msg.author.id;
if(this.votes.includes(user))
{
return;
} else {
this.votes.push(user);
}
return;
}
async skip(msg, app, text, pl, vc)
{
//glitch likely caused by lavalink grabbing its own (slightly outdated) copy of the playlist
await pl.next(); //advance playlist (wait for save confirmation to prevent glitch)
app.lavalink.play(vc, msg, app, true);
return;
}
async doCommand(msg, app, text)
{
var pl = await app.db.getPlaylist(msg.channel.guild.id);
var vc = U.msg2vc(msg);
var beforeVotes = this.votes;
var perms = await P.getPerms(app, msg);
var gid = U.msg2gid(msg);
//Getto permission check to have less code and to make it so the command can still be used in some ways
if(pl.djmode == true && U.canUseCommand(perms, {permissions: ["dj"]}, pl))
{
this.skip(msg, app, text, pl, vc)
} else {
if(pl.djmode == false || pl.djmode == undefined) { await this.skip(msg, app, text, pl, vc); }
if(pl.djmode == true)
{
await this.voteSkip(msg, app, vc);
var currentVotes = this.votes.length;
var quota = U.getUsersInVc(msg, vc) / 2;
var voteString = currentVotes + "/" + Math.round(quota);
console.log(voteString);
if(currentVotes >= quota)
{
app.bot.createMessage(msg.channel.id, U.createSuccessEmbed("Vote Passed", voteString + " voted"));
await this.skip(msg, app, text, pl, vc);
this.votes = [];
} else {
app.bot.createMessage(msg.channel.id, U.createQuickEmbed("Vote Skip:", voteString + " voted"));
}
}
}
}
}
/*
[=add https://www.youtube.com/watch?v=dJaVI7jzc8s
[=add https://www.youtube.com/watch?v=WNxZiBexDM8
[=add https://www.youtube.com/watch?v=IUun0CWrvT0
*/
var U = require.main.require("./utils/Utils.js");
var P = require.main.require("./utils/Permissions.js");

View File