Merge pull request #21 from Trivernis/develop

Develop
pull/22/head
Trivernis 6 years ago committed by GitHub
commit 2f70d9cf8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,57 @@
# Javascript Node CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-javascript/ for more details
#
version: 2
jobs:
build:
docker:
# specify the version you desire here
- image: circleci/node:10.11
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
# - image: circleci/mongo:3.4.4
working_directory: ~/repo
steps:
- checkout
# Download and cache dependencies
- restore_cache:
keys:
- v1-dependencies-{{ checksum "package.json" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
- run:
name: Installing dependencies
command: npm install
- run:
name: installing additional dependencies
command: npm install sqlite3
- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "package.json" }}
- run:
name: Creating config file
command: echo {} >> config.json
# run tests!
- run:
name: Testing ./lib/music
command: node ./testscripts/musicTest.js
- run:
name: Testing ./lib/cmd
command: node ./testscripts/cmdTest.js
- run:
name: Testing ./lib/guilding
command: node ./testscripts/guildingTest.js

@ -1,4 +1,4 @@
discordbot discordbot [![CircleCI](https://circleci.com/gh/Trivernis/discordbot.js.svg?style=svg)](https://circleci.com/gh/Trivernis/discordbot.js) [![CodeFactor](https://www.codefactor.io/repository/github/trivernis/discordbot.js/badge)](https://www.codefactor.io/repository/github/trivernis/discordbot.js)
=== ===
A bot that does the discord thing. A bot that does the discord thing.

@ -96,7 +96,7 @@ function registerCommands() {
// returns the numbe of guilds, the bot has joined // returns the numbe of guilds, the bot has joined
cmd.createGlobalCommand(prefix + 'guilds', () => { cmd.createGlobalCommand(prefix + 'guilds', () => {
return `Number of guilds: \`${client.guilds.size}\`` return `Number of guilds: \`${client.guilds.size}\``
}, [], 'Returns the uptime of the bot', 'owner'); }, [], 'Returns the number of guilds the bot has joined', 'owner');
} }
function rotatePresence() { function rotatePresence() {
@ -120,7 +120,13 @@ client.on('message', msg => {
logger.verbose(`<${msg.author.tag}>: ${msg.content}`); logger.verbose(`<${msg.author.tag}>: ${msg.content}`);
if (!msg.guild) { if (!msg.guild) {
let reply = cmd.parseMessage(msg); let reply = cmd.parseMessage(msg);
if (reply) msg.channel.send(reply); if (reply) {
if (reply.isPrototypeOf(Discord.RichEmbed)) {
msg.channel.send('', reply);
} else {
msg.channel.send(reply)
}
}
} else { } else {
guilding.getHandler(msg.guild, prefix).handleMessage(msg); guilding.getHandler(msg.guild, prefix).handleMessage(msg);
} }

@ -3,7 +3,11 @@
"help": { "help": {
"name": "help", "name": "help",
"permission": "all", "permission": "all",
"description": "Shows this help command" "description": "Shows this help command",
"category": "Utility",
"args": [
"command"
]
} }
} }
} }

@ -3,7 +3,8 @@
"roles": { "roles": {
"name": "roles", "name": "roles",
"permission": "all", "permission": "all",
"description": "Shows the roles used for commands on the server." "description": "Shows the roles used for commands on the server.",
"category": "Utility"
} }
}, },
"music": { "music": {
@ -14,11 +15,13 @@
"url" "url"
], ],
"description": "Adds the url to the YouTube video/playlist into the queue.", "description": "Adds the url to the YouTube video/playlist into the queue.",
"category": "Music",
"response": { "response": {
"success": "Added Song/Playlist to the queue.", "success": "Added Song/Playlist to the queue.",
"failure": "Failed adding Song/Playlist to the queue.", "failure": "Failed adding Song/Playlist to the queue.",
"url_invalid": "This is not a valid url!", "url_invalid": "This is not a valid url!",
"no_url": "I need an url to a video to play" "no_url": "I need an url to a video to play!",
"no_voicechannel": "You need to join a voicechannel to do that!"
} }
}, },
"playnext": { "playnext": {
@ -28,6 +31,7 @@
"url" "url"
], ],
"description": "Adds the url to the YouTube video as next song to the queue.", "description": "Adds the url to the YouTube video as next song to the queue.",
"category": "Music",
"response": { "response": {
"success": "Added Song as next Song to the queue.", "success": "Added Song as next Song to the queue.",
"failure": "Failed adding Song as next Song to the queue.", "failure": "Failed adding Song as next Song to the queue.",
@ -39,6 +43,7 @@
"name": "join", "name": "join",
"permission": "all", "permission": "all",
"description": "Joins the VC you are in.", "description": "Joins the VC you are in.",
"category": "Music",
"response": { "response": {
"not_connected": "You are not connected to a Voice Channel." "not_connected": "You are not connected to a Voice Channel."
} }
@ -47,6 +52,7 @@
"name": "stop", "name": "stop",
"permission": "dj", "permission": "dj",
"description": "Stops playing music and leaves.", "description": "Stops playing music and leaves.",
"category": "Music",
"response": { "response": {
"success": "Stopping now..." "success": "Stopping now..."
} }
@ -55,6 +61,7 @@
"name": "pause", "name": "pause",
"permission": "all", "permission": "all",
"description": "Pauses playing.", "description": "Pauses playing.",
"category": "Music",
"response": { "response": {
"success": "Pausing playback." "success": "Pausing playback."
} }
@ -63,6 +70,7 @@
"name": "resume", "name": "resume",
"permission": "all", "permission": "all",
"description": "Resumes playing.", "description": "Resumes playing.",
"category": "Music",
"response": { "response": {
"success": "Resuming playback." "success": "Resuming playback."
} }
@ -71,6 +79,7 @@
"name": "skip", "name": "skip",
"permission": "dj", "permission": "dj",
"description": "Skips the current song.", "description": "Skips the current song.",
"category": "Music",
"response": { "response": {
"success": "Skipping to the next song." "success": "Skipping to the next song."
} }
@ -79,6 +88,7 @@
"name": "clear", "name": "clear",
"permission": "dj", "permission": "dj",
"description": "Clears the queue.", "description": "Clears the queue.",
"category": "Music",
"response": { "response": {
"success": "The Queue has been cleared." "success": "The Queue has been cleared."
} }
@ -86,17 +96,20 @@
"playlist": { "playlist": {
"name": "queue", "name": "queue",
"permission": "all", "permission": "all",
"description": "Shows the next ten songs." "description": "Shows the next ten songs.",
"category": "Music"
}, },
"current": { "current": {
"name": "np", "name": "np",
"permission": "all", "permission": "all",
"description": "Shows the currently playing song." "description": "Shows the currently playing song.",
"category": "Music"
}, },
"shuffle": { "shuffle": {
"name": "shuffle", "name": "shuffle",
"permission": "all", "permission": "all",
"description": "Shuffles the playlist.", "description": "Shuffles the playlist.",
"category": "Music",
"response": { "response": {
"success": "The Queue has been shuffled." "success": "The Queue has been shuffled."
} }
@ -105,6 +118,7 @@
"name": "repeat", "name": "repeat",
"permission": "all", "permission": "all",
"description": "Toggle listening on repeat.", "description": "Toggle listening on repeat.",
"category": "Music",
"response": { "response": {
"repeat_true": "Listening on repeat now!", "repeat_true": "Listening on repeat now!",
"repeat_false": "Not listening on repeat anymore." "repeat_false": "Not listening on repeat anymore."
@ -116,12 +130,14 @@
"args": [ "args": [
"url" "url"
], ],
"description": "Saves the YouTube song/playlist with a specific name" "description": "Saves the YouTube song/playlist with a specific name",
"category": "Music"
}, },
"saved": { "saved": {
"name": "saved", "name": "saved",
"permission": "all", "permission": "all",
"description": "Prints out all saved playlists.", "description": "Prints out all saved playlists.",
"category": "Music",
"response": { "response": {
"no_saved": "There are no saved songs/playlists :(" "no_saved": "There are no saved songs/playlists :("
} }

@ -7,7 +7,8 @@ let logger = require('winston'),
config = require('../config.json'), config = require('../config.json'),
args = require('args-parser')(process.argv), args = require('args-parser')(process.argv),
gcmdTempl = require('../commands/globalcommands'), gcmdTempl = require('../commands/globalcommands'),
scmdTempl = require('../commands/servercommands'); scmdTempl = require('../commands/servercommands'),
Discord = require('discord.js');
/* Function Definition */ /* Function Definition */
@ -19,29 +20,49 @@ exports.Servant = class {
this.commands = {}; this.commands = {};
this.prefix = prefix; this.prefix = prefix;
// show all commands (except the owner commands if the user is not an owner) // show all commands (except the owner commands if the user is not an owner)
this.createCommand(gcmdTempl.utils.help, (msg) => { this.createCommand(gcmdTempl.utils.help, (msg, kwargs) => {
let helpstr = "```markdown\n"; if (kwargs.command) {
helpstr += "Commands\n===\n"; let cmd = kwargs.command;
helpstr += 'Global Commands\n---\n'; let allCommands ={...globCommands, ...this.commands};
if (cmd.charAt(0) !== prefix)
cmd = this.prefix + cmd;
if (allCommands[cmd]) {
return new Discord.RichEmbed()
.setTitle(`Help for ${cmd}`)
.addField('Usage', `\`${cmd} [${allCommands[cmd].args.join('] [')}]\``.replace('[]', ''))
.addField('Description', allCommands[cmd].description)
.addField('Permission Role', allCommands[cmd].role || 'all');
} else {
return 'Command not found :(';
}
} else {
let helpEmbed = new Discord.RichEmbed()
.setTitle('Commands');
let globHelp = '';
Object.entries(globCommands).sort().forEach(([key, value]) => { Object.entries(globCommands).sort().forEach(([key, value]) => {
if (value.role !== 'owner' || checkPermission(msg, 'owner')) { if (value.role !== 'owner' || checkPermission(msg, 'owner')) {
let cmdhelp = `${key} [${value.args.join('] [')}]`.replace('[]', '').padEnd(25, ' '); globHelp += `\`${key}\` \t`;
cmdhelp += value.description || '';
cmdhelp += `\nPermission: ${value.role||'all'}`;
helpstr += `\n${cmdhelp}\n`;
} }
}); });
helpstr += '\nServer Commands\n---\n'; helpEmbed.addField('Global Commands', globHelp);
let categories = [];
let catCommands = {};
Object.entries(this.commands).sort().forEach(([key, value]) => { Object.entries(this.commands).sort().forEach(([key, value]) => {
if (value.role !== 'owner' || checkPermission(msg, 'owner')) { if (value.role !== 'owner' || checkPermission(msg, 'owner')) {
let cmdhelp = `${key} [${value.args.join('] [')}]`.replace('[]', '').padEnd(25, ' '); if (!categories.includes(value.category)) {
cmdhelp += value.description || ''; categories.push(value.category);
cmdhelp += `\nPermission: ${value.role||'all'}`; catCommands[value.category] = `\`${key}\` \t`
helpstr += `\n${cmdhelp}\n`; } else {
catCommands[value.category] += `\`${key}\` \t`
}
} }
}); });
helpstr += "```"; for (let cat of categories) {
return helpstr; helpEmbed.addField(cat, catCommands[cat]);
}
helpEmbed.setFooter( prefix + 'help [command] for more info to each command');
return helpEmbed;
}
}); });
// show all roles that are used by commands // show all roles that are used by commands
@ -68,7 +89,8 @@ exports.Servant = class {
'args': template.args || [], 'args': template.args || [],
'description': template.description, 'description': template.description,
'callback': call, 'callback': call,
'role': template.permission 'role': template.permission,
'category': template.category || 'Other'
}; };
logger.debug(`Created server command: ${this.prefix + template.name}, args: ${template.args}`); logger.debug(`Created server command: ${this.prefix + template.name}, args: ${template.args}`);
} }
@ -104,7 +126,10 @@ exports.Servant = class {
let argv = argvars.slice(nLength); let argv = argvars.slice(nLength);
logger.debug(`Executing callback for command: ${command}, kwargs: ${kwargs}, argv: ${argv}`); logger.debug(`Executing callback for command: ${command}, kwargs: ${kwargs}, argv: ${argv}`);
try { try {
return cmd.callback(msg, kwargs, argv) || globResult; let locResult = cmd.callback(msg, kwargs, argv);
if (locResult instanceof Promise)
return locResult; // because Promise equals false in conditional
return locResult || globResult;
} catch (err) { } catch (err) {
logger.error(err.message); logger.error(err.message);
return `The command \`${command}\` has thrown an error.`; return `The command \`${command}\` has thrown an error.`;
@ -154,20 +179,35 @@ exports.parseMessage = function (msg) {
*/ */
exports.init = function (prefix) { exports.init = function (prefix) {
logger.verbose("Created help command"); logger.verbose("Created help command");
this.createGlobalCommand(((prefix || config.prefix) + 'help'), (msg) => { this.createGlobalCommand(((prefix || config.prefix) + 'help'), (msg, kwargs) => {
let helpstr = "```markdown\n"; if (kwargs.command) {
helpstr += "Commands\n---\n"; let cmd = kwargs.command;
if (cmd.charAt(0) !== prefix)
cmd = prefix + cmd;
if (globCommands[cmd]) {
return new Discord.RichEmbed()
.setTitle(`Help for ${cmd}`)
.addField('Usage', `\`${cmd} [${globCommands[cmd].args.join('] [')}]\``.replace('[]', ''))
.addField('Description', globCommands[cmd].description)
.addField('Permission Role', globCommands[cmd].role || 'all');
}
} else {
let helpEmbed = new Discord.RichEmbed()
.setTitle('Global Commands')
.setTimestamp();
let description = '';
Object.entries(globCommands).sort().forEach(([key, value]) => { Object.entries(globCommands).sort().forEach(([key, value]) => {
if (value.role !== 'owner' || checkPermission(msg, 'owner')) { if (value.role === 'owner' && checkPermission(msg, 'owner')) {
let cmdhelp = `${key} [${value.args.join('] [')}]`.replace('[]', '').padEnd(25, ' '); description += `\`${key}\` \t`;
cmdhelp += value.description || ''; } else if (value.role !== 'owner') {
cmdhelp += `\nPermission: ${value.role||'all'}`; description += `\`${key}\` \t`;
helpstr += `\n${cmdhelp}\n`;
} }
}); });
helpstr += "```"; helpEmbed.setFooter( prefix + 'help [command] for more info to each command');
return helpstr; helpEmbed.setDescription(description);
}, [], "Shows this help."); return helpEmbed;
}
}, ['command'], "Shows this help.");
}; };
/** /**

@ -4,6 +4,7 @@ const cmd = require('./cmd'),
config = require('../config.json'), config = require('../config.json'),
servercmd = require('../commands/servercommands'), servercmd = require('../commands/servercommands'),
sqlite3 = require('sqlite3'), sqlite3 = require('sqlite3'),
Discord = require('discord.js'),
handlers = {}, handlers = {},
dbDir = './data/gdb'; dbDir = './data/gdb';
let logger = require('winston'); let logger = require('winston');
@ -74,6 +75,26 @@ exports.GuildHandler = class {
)`); )`);
} }
/**
* Answers a message via mention if mentioning is active or with just sending it to the same channel.
* @param msg
* @param answer
*/
answerMessage(msg, answer) {
if (answer instanceof Promise || answer) {
if (answer instanceof Discord.RichEmbed) {
(this.mention)? msg.reply('', answer) : msg.channel.send('', answer);
} else if (answer instanceof Promise) {
answer
.then((answer) => this.answerMessage(msg, answer))
.catch((error) => this.answerMessage(msg, error));
} else {
(this.mention)? msg.reply(answer) : msg.channel.send(answer);
}
} else {
logger.warning(`Empty answer won't be send.`);
}
}
/** /**
* handles the message by letting the servant parse the command. Depending on the message setting it * handles the message by letting the servant parse the command. Depending on the message setting it
* replies or just sends the answer. * replies or just sends the answer.
@ -91,13 +112,7 @@ exports.GuildHandler = class {
} }
); );
} }
let answer = this.servant.parseCommand(msg); this.answerMessage(msg, this.servant.parseCommand(msg));
if (!answer) return;
if (this.mention) {
msg.reply(answer);
} else {
msg.channel.send(answer);
}
} else { } else {
this.msgsQueue.push(msg); this.msgsQueue.push(msg);
} }
@ -107,15 +122,20 @@ exports.GuildHandler = class {
* Connect to a voice-channel if not connected and play the url * Connect to a voice-channel if not connected and play the url
* @param vc * @param vc
* @param url * @param url
* @param next
*/ */
connectAndPlay(vc, url) { connectAndPlay(vc, url, next) {
return new Promise((resolve, reject) => {
if (!this.dj.connected) { if (!this.dj.connected) {
this.dj.connect(vc).then(() => { this.dj.connect(vc).then(() => {
this.dj.playYouTube(url); this.dj.playYouTube(url, next);
resolve();
}); });
} else { } else {
this.dj.playYouTube(url); this.dj.playYouTube(url, next);
resolve();
} }
});
} }
/** /**
@ -128,47 +148,55 @@ exports.GuildHandler = class {
// play command // play command
this.servant.createCommand(servercmd.music.play, (msg, kwargs, argv) => { this.servant.createCommand(servercmd.music.play, (msg, kwargs, argv) => {
let vc = msg.member.voiceChannel; return new Promise((resolve, reject) => {
let vc = this.dj.voiceChannel || msg.member.voiceChannel;
let url = kwargs['url']; let url = kwargs['url'];
if (!vc) if (!vc)
return 'You are not connected to a VoiceChannel'; reject(servercmd.music.play.response.no_voicechannel);
if (!url) if (!url)
return servercmd.music.play.response.no_url; reject(servercmd.music.play.response.no_url);
if (!url.match(/http/g)) { if (!url.match(/http/g)) {
if (argv) if (argv && argv.length > 0)
url += ' ' + argv.join(' '); url += ' ' + argv.join(' '); // join to get the whole expression behind the command
this.db.get('SELECT url FROM playlists WHERE name = ?', [url], (err, row) => { this.db.get('SELECT url FROM playlists WHERE name = ?', [url], (err, row) => {
if (err) { if (err) {
console.error(err.message); console.error(err.message);
} }
if (!row) { if (!row) {
return servercmd.music.play.response.url_invalid; reject(servercmd.music.play.response.url_invalid);
} logger.verbose('Got invalid url for play command.');
} else {
url = row.url; url = row.url;
try { try {
this.connectAndPlay(vc, url); this.connectAndPlay(vc, url).then(() => {
resolve(servercmd.music.play.response.success);
});
} catch (err) { } catch (err) {
logger.error(err.message); logger.error(err.message);
return servercmd.music.play.response.failure; reject(servercmd.music.play.response.failure);
}
} }
}); });
} else { } else {
try { try {
this.connectAndPlay(vc, url); this.connectAndPlay(vc, url).then(() => {
resolve(servercmd.music.play.response.success);
});
} catch (err) { } catch (err) {
logger.error(err.message); logger.error(err.message);
return servercmd.music.play.response.failure; reject(servercmd.music.play.response.failure);
} }
} }
return servercmd.music.play.response.success; })
}); });
// playnext command // playnext command
this.servant.createCommand(servercmd.music.playnext,(msg, kwargs, argv) => { this.servant.createCommand(servercmd.music.playnext,(msg, kwargs, argv) => {
return new Promise((resolve, reject) => {
let vc = msg.member.voiceChannel; let vc = msg.member.voiceChannel;
if (!this.dj.connected) this.dj.voiceChannel = vc; if (!this.dj.connected) this.dj.voiceChannel = vc;
let url = kwargs['url']; let url = kwargs['url'];
if (!url) return servercmd.music.playnext.response.no_url; if (!url) reject(servercmd.music.playnext.response.no_url);
if (!url.match(/http/g)) { if (!url.match(/http/g)) {
if (argv) if (argv)
url += ' ' + argv.join(' '); url += ' ' + argv.join(' ');
@ -177,25 +205,29 @@ exports.GuildHandler = class {
console.error(err.message); console.error(err.message);
} }
if (!row) { if (!row) {
return servercmd.music.play.response.url_invalid; reject(servercmd.music.play.response.url_invalid);
} }
url = row.url; url = row.url;
try { try {
this.dj.playYouTube(url, true); this.connectAndPlay(url, true).then(() => {
resolve(servercmd.music.playnext.response.success);
});
} catch (err) { } catch (err) {
logger.error(err.message); logger.error(err.message);
return servercmd.music.play.response.failure; reject(servercmd.music.play.response.failure);
} }
}); });
} else { } else {
try { try {
this.dj.playYouTube(url, true); this.connectAndPlay(url, true).then(() => {
resolve(servercmd.music.playnext.response.success);
});
} catch (err) { } catch (err) {
logger.error(err); logger.error(err);
return servercmd.music.playnext.response.failure; reject(servercmd.music.playnext.response.failure);
} }
} }
return servercmd.music.playnext.response.success; })
}); });
// join command // join command
@ -274,6 +306,7 @@ exports.GuildHandler = class {
// saves playlists // saves playlists
this.servant.createCommand(servercmd.music.save, (msg, kwargs, argv) => { this.servant.createCommand(servercmd.music.save, (msg, kwargs, argv) => {
return new Promise((resolve, reject) => {
let saveName = argv.join(' '); let saveName = argv.join(' ');
this.db.get('SELECT COUNT(*) count FROM playlists WHERE name = ?', [saveName], (err, row) => { this.db.get('SELECT COUNT(*) count FROM playlists WHERE name = ?', [saveName], (err, row) => {
if(err) { if(err) {
@ -283,19 +316,24 @@ exports.GuildHandler = class {
this.db.run('INSERT INTO playlists (name, url) VALUES (?, ?)', [saveName, kwargs.url], (err) => { this.db.run('INSERT INTO playlists (name, url) VALUES (?, ?)', [saveName, kwargs.url], (err) => {
if (err) if (err)
logger.error(err.message); logger.error(err.message);
else
resolve(`Saved song/playlist as ${saveName}`);
}); });
} else { } else {
this.db.run('UPDATE playlists SET url = ? WHERE name = ?', [kwargs.url, saveName], (err) => { this.db.run('UPDATE playlists SET url = ? WHERE name = ?', [kwargs.url, saveName], (err) => {
if (err) if (err)
logger.error(err.message); logger.error(err.message);
else
resolve(`Saved song/playlist as ${saveName}`);
}); });
} }
}); });
return `Saved song/playlist as ${saveName}` });
}); });
// saved command - prints out saved playlists // saved command - prints out saved playlists
this.servant.createCommand(servercmd.music.saved, (msg) => { this.servant.createCommand(servercmd.music.saved, (msg) => {
return new Promise((resolve, reject) => {
let response = ''; let response = '';
this.db.all('SELECT name, url FROM playlists', (err, rows) => { this.db.all('SELECT name, url FROM playlists', (err, rows) => {
if (err) if (err)
@ -306,14 +344,14 @@ exports.GuildHandler = class {
if (rows.length === 0) { if (rows.length === 0) {
msg.channel.send(servercmd.music.saved.response.no_saved); msg.channel.send(servercmd.music.saved.response.no_saved);
} else { } else {
msg.channel.send('', {embed: { let richEmbed = new Discord.RichEmbed()
"title": "Saved Songs and Playlists", .setTitle('Saved Songs and Playlists')
"description": response, .setDescription(response);
"fields": [] resolve(richEmbed);
}});
} }
}); });
}); });
});
} }
}; };

@ -31,16 +31,19 @@ exports.DJ = class {
* VoiceChannel is saved as object variable. * VoiceChannel is saved as object variable.
*/ */
connect(voiceChannel) { connect(voiceChannel) {
return new Promise((resolve, reject) => {
this.voiceChannel = voiceChannel || this.voiceChannel; this.voiceChannel = voiceChannel || this.voiceChannel;
if (this.connected) { if (this.connected) {
this.stop(); this.stop();
} }
logger.verbose(`Connecting to voiceChannel ${this.voiceChannel.name}`); logger.verbose(`Connecting to voiceChannel ${this.voiceChannel.name}`);
return this.voiceChannel.join().then(connection => { this.voiceChannel.join().then(connection => {
logger.info(`Connected to Voicechannel ${this.voiceChannel.name}`); logger.info(`Connected to Voicechannel ${this.voiceChannel.name}`);
this.conn = connection; this.conn = connection;
this.checkListeners(); this.checkListeners();
}); resolve();
}).catch((error) => reject(error));
})
} }
/** /**
@ -97,10 +100,14 @@ exports.DJ = class {
* @param playnext * @param playnext
*/ */
playYouTube(url, playnext) { playYouTube(url, playnext) {
/** Commented because it causes an connection overflow error.
* TODO: Decide to either fix this with promises or ignore it because connection checks are performed by the guild handler.**/
/*
if (!this.connected) { if (!this.connected) {
this.connect().then(this.playYouTube(url)); this.connect().then(this.playYouTube(url));
} }
let plist = url.match(/(?<=\?list=)[\w\-]+/g); */
let plist = url.match(/(?<=\?list=)[\w\-]+/);
if (plist) { if (plist) {
logger.debug(`Adding playlist ${plist} to queue`); logger.debug(`Adding playlist ${plist} to queue`);
ypi(ytapiKey, plist).then(items => { ypi(ytapiKey, plist).then(items => {

@ -1,6 +1,9 @@
{ {
"name": "discordbot", "name": "discordbot",
"version": "1.0.0", "version": "1.0.0",
"scripts": {
"start": "node bot.js"
},
"dependencies": { "dependencies": {
"args-parser": "1.1.0", "args-parser": "1.1.0",
"discord.js": "11.4.2", "discord.js": "11.4.2",

@ -0,0 +1,39 @@
const cmd = require("../lib/cmd.js"),
mockobjects = require("./mockobjects.js"),
servercmd = require('../commands/servercommands');
function main() {
cmd.setLogger(mockobjects.mockLogger);
console.log('Creating new servant instance');
let servant = new cmd.Servant('#');
console.log('registering all music commands...');
for (let [key, value] of Object.entries(servercmd.music)) {
servant.createCommand(value, () => {
console.log(` - invoked ${value.name} callback`);
});
}
console.log('parsing and deleting all music commands...');
for (let [key, value] of Object.entries(servercmd.music)) {
servant.parseCommand({
content: '#' + value.name,
author: {
tag: undefined
}
});
servant.removeCommand(value.name);
}
process.exit(0);
}
if (typeof require !== "undefined" && require.main === module) {
process.on("unhandledRejection", (reason, p) => {
console.error("Unhandled Rejection at: Promise", p, "reason:", reason);
throw Error("Promise rejection");
});
setTimeout(() => process.exit(1), 60000);
main();
}

@ -0,0 +1,44 @@
const guilding = require("../lib/guilding.js")
music = require("../lib/music.js"),
mockobjects = require("./mockobjects.js"),
servercmd = require("../commands/servercommands");
function main() {
guilding.setLogger(mockobjects.mockLogger);
music.setLogger(mockobjects.mockLogger);
console.log('Creating guildHandler instance');
let guildHandler = new guilding.GuildHandler('TEST', '#');
guildHandler.dj = new music.DJ(mockobjects.mockVoicechannel);
setTimeout(() => {
for (let [key, value] of Object.entries(servercmd.music)) {
guildHandler.handleMessage({
content: '#' + value.name + ' arg1 arg2 arg3 arg4',
author: {
tag: undefined,
id: 0,
createdTimestamp: new Date(),
username: 'TEST'
},
member: {
voiceChannel: mockobjects.mockVoicechannel
},
channel: mockobjects.mockChannel,
reply: mockobjects.mockChannel.send
});
}
guildHandler.destroy();
process.exit(0);
}, 1000);
}
if (typeof require !== "undefined" && require.main === module) {
process.on("unhandledRejection", (reason, p) => {
console.error("Unhandled Rejection at: Promise", p, "reason:", reason);
throw Error("Promise rejection");
});
setTimeout(() => process.exit(1), 60000);
main();
}

@ -0,0 +1,51 @@
exports.mockLogger = {
error: msg => raise(msg),
warn: msg => console.error("warn: ", msg),
warning: msg => console.error("warn: ", msg),
info: msg => console.log("info: ", msg),
verbose: msg => console.log("verbose: ", msg),
debug: msg => console.log("debug: ", msg)
};
exports.mockDispatcher = {
pause: () => console.log('Dispatcher.pause();'),
resume: () => console.log('Dispatcher.resume();'),
setVolume: (perc) => console.log(`Dispatcher.setVolume(${perc});`),
on: (event, callback) => console.log(`Dispatcher.on(${event}, ${callback});`),
end: () => console.log('Dispatcher.end();')
};
exports.mockConnection = {
channel: {
members: {
size: 10
},
leave: () => console.log('Connection.leave();')
},
status: 0,
playFile: (fname) => {
console.log(`Connection.playFile(${fname});`);
return exports.mockDispatcher;
},
playStream: (stream, opts) => {
console.log(`Connection.playStream(ytdl, ${opts};`);
return exports.mockDispatcher;
},
disconnect: () => console.log('Connection.disconnect();')
};
exports.mockVoicechannel = {
name: 'mockVoicechannel',
join: () => {
console.log('Voicechannel.join();');
return new Promise((rs, rj) => rs(exports.mockConnection));
},
members: {
size: 10
},
leave: () => console.log('Voicechannel.leave();')
};
exports.mockChannel = {
send: (msg) => console.log('Send: ', msg)
}

@ -0,0 +1,33 @@
const music = require('../lib/music.js'),
mockobjects = require('./mockobjects.js');
function main() {
let dj = new music.DJ(mockobjects.mockVoicechannel)
music.setLogger(mockobjects.mockLogger);
dj.connect().then(() => {
console.log('connected', dj.connected);
dj.playFile('test');
dj.playYouTube('https://www.youtube.com/watch?v=TEST');
dj.setVolume(1);
dj.pause();
dj.resume();
dj.skip();
dj.stop();
dj.shuffle();
console.log('dj.playlist: ', dj.playlist);
console.log('dj.song: ', dj.song);
dj.clear();
process.exit(0);
});
}
// Executing the main function
if (typeof require !== 'undefined' && require.main === module) {
process.on('unhandledRejection', (reason, p) => {
console.error('Unhandled Rejection at: Promise', p, 'reason:', reason);
throw Error('Promise rejection');
});
setTimeout(() => process.exit(1), 60000);
main();
}
Loading…
Cancel
Save