summaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorAlejandro Sior <aho@sio.be>2021-02-19 11:43:18 +0100
committerAlejandro Sior <aho@sio.be>2021-02-19 11:43:18 +0100
commit405051211d60afa8a7fc4fc3fa5ffb456242973d (patch)
treedbae34350c3a54f422da70f1b7fbd857a8f5a116 /src/cmd
initial commit
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/debug.js5
-rw-r--r--src/cmd/info.js19
-rw-r--r--src/cmd/sudo.js139
-rw-r--r--src/cmd/troff.js59
-rw-r--r--src/cmd/voice.js356
5 files changed, 578 insertions, 0 deletions
diff --git a/src/cmd/debug.js b/src/cmd/debug.js
new file mode 100644
index 0000000..ecb475c
--- /dev/null
+++ b/src/cmd/debug.js
@@ -0,0 +1,5 @@
+module.exports.loadModule = function loadModule(bot) {
+ bot.handler.endpoint('^ping$', [], (match, message) => {
+ bot.createMessage(message.channel.id, 'Pong').catch(Logger.error);
+ });
+};
diff --git a/src/cmd/info.js b/src/cmd/info.js
new file mode 100644
index 0000000..899dac6
--- /dev/null
+++ b/src/cmd/info.js
@@ -0,0 +1,19 @@
+const exec = require('child_process').exec;
+
+module.exports.loadModule = function loadModule(bot) {
+ bot.handler.endpoint('^v(?:ersion)?$', [], (match, message) => {
+ exec('git rev-list --count HEAD', (error, stdout) => {
+ if (error) {
+ bot.createMessage(message.channel.id, 'An error has occured').catch(Logger.error);
+ return;
+ }
+ exec('git log -1 --pretty=%B', (error2, stdout2) => {
+ let msg = `Commit number ${stdout}`;
+ if (!error2) {
+ msg += `\n\`\`\`\n${stdout2}\`\`\``;
+ }
+ bot.createMessage(message.channel.id, msg).catch(Logger.error);
+ });
+ });
+ });
+};
diff --git a/src/cmd/sudo.js b/src/cmd/sudo.js
new file mode 100644
index 0000000..cc590bf
--- /dev/null
+++ b/src/cmd/sudo.js
@@ -0,0 +1,139 @@
+const { inspect } = require('util');
+const vm = require('vm');
+
+module.exports.loadModule = function loadModule(bot) {
+ bot.handler.endpoint('^guilds$', [], (match, message) => {
+ if (!bot.config.sudoers) return;
+ if (bot.config.sudoers.indexOf(message.author.id) <= -1) return;
+ bot.createMessage(message.channel.id, `\`${bot.guilds.size}\``).catch(Logger.error);
+ });
+ bot.handler.endpoint('^is-sudoer$', [], (match, message) => {
+ if (!bot.config.sudoers) return;
+ if (bot.config.sudoers.indexOf(message.author.id) <= -1) return;
+ bot.createMessage(message.channel.id, 'true').catch(Logger.error);
+ });
+ bot.handler.endpoint('^sudoers$', [], (match, message) => {
+ if (!bot.config.sudoers) return;
+ if (bot.config.sudoers.indexOf(message.author.id) <= -1) return;
+ bot.createMessage(message.channel.id, `\`\`\`\n[ ${bot.config.sudoers.join(',\n ')} ]\n\`\`\``).catch(Logger.error);
+ });
+ bot.handler.endpoint('^addsudo (.+)$', [], (match, message) => {
+ if (!bot.config.sudoers) return;
+ if (bot.config.sudoers.indexOf(message.author.id) <= -1) return;
+ bot.config.sudoers.push(match[1]);
+ bot.createMessage(message.channel.id, `${match[1]} temporarily added to the sudoers list`).catch(Logger.error);
+ });
+ bot.handler.endpoint('^resetsudo$', [], (match, message) => {
+ if (!bot.config.sudoers) return;
+ if (bot.config.sudoers.indexOf(message.author.id) <= -1) return;
+ bot.config.sudoers = Array.from(bot._ds);
+ bot.createMessage(message.channel.id, `Sudoers list reset`).catch(Logger.error);
+ });
+ bot.handler.endpoint('^removesudo (.+)$', [], (match, message) => {
+ if (!bot.config.sudoers) return;
+ if (bot.config.sudoers.indexOf(message.author.id) <= -1) return;
+ let i = bot.config.sudoers.indexOf(match[1]);
+ if (i >= 0) {
+ bot.config.sudoers.splice(i, 1);
+ bot.createMessage(message.channel.id, `${match[1]} removed from sudoers list`).catch(Logger.error);
+ }
+ else {
+ bot.createMessage(message.channel.id, `${match[1]} was not sudoer`).catch(Logger.error);
+ }
+ });
+ bot.handler.endpoint('^e ?```(?:.*\n)?(.*)\n?```$', [], (match, message) => {
+ if (!bot.config.sudoers) return;
+ if (bot.config.sudoers.indexOf(message.author.id) <= -1) return;
+ try {
+ let evaled = vm.runInNewContext(match[1], {
+ ctx: {
+ bot: bot,
+ message: message,
+ match: match,
+ },
+ require: require,
+ });
+
+ if (typeof evaled !== 'string') {
+ evaled = inspect(evaled);
+ }
+ evaled = evaled.replace(bot.config.token, 'ツ');
+ bot.createMessage(message.channel.id, `\`\`\`${evaled}\`\`\``).catch(Logger.error);
+ }
+ catch (e) {
+ bot.createMessage(message.channel.id, `Error:\n\`\`\`\n${e}\`\`\``).catch(Logger.error);
+ }
+ });
+ bot.handler.endpoint('^aguilds$', [], async (match, message) => {
+ if (!bot.config.sudoers) return;
+ if (bot.config.sudoers.indexOf(message.author.id) <= -1) return;
+ let aguilds = await bot.db.Aguild.findAll({ attributes: ['guildId'] });
+ let buff = '```\nAuthorized guilds:\n\n';
+ aguilds.forEach(g => {
+ buff += `- ${g.guildId}\n`;
+ });
+ buff += '```';
+ bot.createMessage(message.channel.id, buff).catch(Logger.error);
+ });
+ bot.handler.endpoint('^ausers$', [], async (match, message) => {
+ if (!bot.config.sudoers) return;
+ if (bot.config.sudoers.indexOf(message.author.id) <= -1) return;
+ let ausers = await bot.db.Auser.findAll({ attributes: ['userId'] });
+ let buff = '```\nAuthorized users:\n\n';
+ ausers.forEach(u => {
+ buff += `- ${u.userId}\n`;
+ });
+ buff += '```';
+ bot.createMessage(message.channel.id, buff).catch(Logger.error);
+ });
+ bot.handler.endpoint('^aguild ([0-9]+)$', [], async (match, message) => {
+ if (!bot.config.sudoers) return;
+ if (bot.config.sudoers.indexOf(message.author.id) <= -1) return;
+ if (!match[1]) return;
+ try {
+ await bot.db.Aguild.create({
+ guildId: match[1],
+ });
+ bot.createMessage(message.channel.id, `Guild \`${match[1]}\` successfully authorized!`).catch(Logger.error);
+ }
+ catch (e) {
+ bot.createMessage(message.channel.id, 'Guild was already authorized.').catch(Logger.error);
+ }
+ });
+ bot.handler.endpoint('^auser ([0-9]+)$', [], async (match, message) => {
+ if (!bot.config.sudoers) return;
+ if (bot.config.sudoers.indexOf(message.author.id) <= -1) return;
+ if (!match[1]) return;
+ try {
+ await bot.db.Auser.create({
+ userId: match[1],
+ });
+ bot.createMessage(message.channel.id, `User \`${match[1]}\` successfully authorized!`).catch(Logger.error);
+ }
+ catch (e) {
+ bot.createMessage(message.channel.id, 'User was already authorized.').catch(Logger.error);
+ }
+ });
+ bot.handler.endpoint('^rguild ([0-9]+)$', [], async (match, message) => {
+ if (!bot.config.sudoers) return;
+ if (bot.config.sudoers.indexOf(message.author.id) <= -1) return;
+ if (!match[1]) return;
+ await bot.db.Aguild.destroy({
+ where: {
+ guildId: match[1],
+ }
+ });
+ bot.createMessage(message.channel.id, `Guild \`${match[1]}\` successfully removed!`).catch(Logger.error);
+ });
+ bot.handler.endpoint('^ruser ([0-9]+)$', [], async (match, message) => {
+ if (!bot.config.sudoers) return;
+ if (bot.config.sudoers.indexOf(message.author.id) <= -1) return;
+ if (!match[1]) return;
+ await bot.db.Auser.destroy({
+ where: {
+ userId: match[1],
+ }
+ });
+ bot.createMessage(message.channel.id, `User \`${match[1]}\` successfully removed!`).catch(Logger.error);
+ });
+};
diff --git a/src/cmd/troff.js b/src/cmd/troff.js
new file mode 100644
index 0000000..91090a5
--- /dev/null
+++ b/src/cmd/troff.js
@@ -0,0 +1,59 @@
+const spawn = require('child_process').spawn;
+const fs = require('fs');
+const { ConsoleTransportOptions } = require('winston/lib/winston/transports');
+
+/*
+\\"".fp - R cmunrm
+\\"".fp - I cmunti
+\\"".fp - B cmunrb
+\\"".fp - BI cmunbi
+*/
+
+const prelude = `
+.fp - CMEX CMEX10
+.fp - CMSY CMSY10
+.fp - CMMI CMMI10
+.fp - CB CB
+.fspecial R CMEX CMSY
+.fspecial I CMMI
+
+.EQ
+define <=> %{vcenter roman " \\\\N'arrowdblboth' "}%
+define appr %{vcenter roman "≈"}%
+define intd %{vcenter roman "\\\\N'integraldisplay'"}%
+delim $$
+.EN
+
+.LP
+.ps +20
+\\m[white]
+`;
+
+module.exports.loadModule = function loadModule(bot) {
+ bot.handler.endpoint(/^tr(?:off)?!?(?: |\n)([\s\S]*)$/m, [], (match, message) => {
+ ma = match[1].replace(/^\.sy\s.*$/gm, '');
+ ma = ma.replace(/^sh\s.*$/gm, '');
+ ma = ma.replace(/^\.?co\s.*$/gm, '');
+ ma = ma.replace(/^\\X.*$/gm, '');
+ if (ma !== match[1]) console.log('had to sanitize');
+ const subprocess0 = spawn('pic');
+ console.log(ma);
+ subprocess0.stdin.write(prelude + '\n' + ma + '\n');
+ subprocess0.stdin.end();
+ const subprocess1 = spawn('eqn');
+ subprocess0.stdout.pipe(subprocess1.stdin);
+ const subprocess2 = spawn('roff', ['-ms']);
+ subprocess1.stdout.pipe(subprocess2.stdin);
+ const subprocess3 = spawn('pdf', ['-p', '10000x10000']);
+ subprocess2.stdout.pipe(subprocess3.stdin);
+ const subprocess4 = spawn('convert', ['-', '-trim', 'png:-']);
+ subprocess3.stdout.pipe(subprocess4.stdin);
+ let ch = Buffer.from("");
+ subprocess4.stdout.on('data', (data) => {
+ ch = Buffer.concat([ch, data]);
+ });
+ subprocess4.stdout.on('end', () => {
+ message.channel.createMessage('', {name: 'troff.png', file: ch});
+ });
+ });
+};
diff --git a/src/cmd/voice.js b/src/cmd/voice.js
new file mode 100644
index 0000000..7f12603
--- /dev/null
+++ b/src/cmd/voice.js
@@ -0,0 +1,356 @@
+const superagent = require('superagent');
+const wait = require('../Wait');
+const time = require('../Time');
+const hastebin = require('../Hastebin');
+
+const querystring = require('querystring');
+const chunk = require('chunk-text');
+
+async function resolveTracks(node, search) {
+ let result;
+ try {
+ result = await superagent.get(`http://${node.host}:${node.port}/loadtracks?identifier=${search}`)
+ .set('Authorization', node.password)
+ .set('Accept', 'application/json');
+ } catch (err) {
+ throw err;
+ }
+
+ if (!result) {
+ throw 'Unable play that video.';
+ }
+
+ return result.body; // array of tracks resolved from lavalink
+}
+
+function getLavalinkPlayer(channel, bot) {
+ if (!channel || !channel.guild) {
+ return Promise.reject('Not a guild channel.');
+ }
+
+ let player = bot.voiceConnections.get(channel.guild.id);
+ if (player) {
+ return Promise.resolve(player);
+ }
+
+ let options = {};
+ if (channel.guild.region) {
+ options.region = channel.guild.region;
+ }
+
+ return bot.joinVoiceChannel(channel.id, options);
+}
+
+function getRandomColor() {
+ var letters = '0123456789ABCDEF';
+ var color = '';
+ for (var i = 0; i < 6; i++) {
+ color += letters[Math.floor(Math.random() * 16)];
+ }
+ return parseInt(color);
+}
+
+async function crawl(player, bot, message) {
+ if (bot.voices[message.channel.guild.id].queue.length === 0) {
+ bot.voices[message.channel.guild.id].crawling = false;
+ delete bot.voices[message.channel.guild.id].current;
+ bot.leaveVoiceChannel(player.channelId);
+ return;
+ };
+
+ bot.voices[message.channel.guild.id].crawling = true;
+ let next = bot.voices[message.channel.guild.id].queue.shift();
+ bot.voices[message.channel.guild.id].current = next;
+ player.play(next.track);
+
+ player.removeAllListeners('disconnect');
+ player.once('disconnect', (err) => {
+ if (err) {
+ Logger.error(err);
+ }
+ bot.voices[message.channel.guild.id].crawling = false;
+ delete bot.voices[message.channel.guild.id].current; //Attempt to fix disconnect bug, implement `come' command to recrawl is still to do. Refer to previous commit for previous implementation
+ bot.leaveVoiceChannel(player.channelId);
+ });
+
+ player.removeAllListeners('error');
+ player.once('error', (err) => {
+ Logger.error(`Player error: ${err}`);
+ // I do not know how it behaves after there's an error so I just put these in comment for now
+ // bot.voices[message.channel.guild.id].crawling = false;
+ // delete bot.voices[message.channel.guild.id].current;
+ // bot.leaveVoiceChannel(player.channelId);
+
+ // Just in case, continue crawling
+ crawl(player, bot, message);
+ });
+
+ player.removeAllListeners('end');
+ player.once('end', async (data) => {
+ // REPLACED reason is emitted when playing without stopping, I ignore these to prevent skip loops
+ if (data.reason && data.reason === 'REPLACED') return;
+ await wait(750);
+ crawl(player, bot, message);
+ });
+}
+
+module.exports.loadModule = function loadModule(bot) {
+ bot.handler.endpoint('^(?:add|meme|play|p|a)([;:-][0-9,-]+)? (.+)$', [], async (match, message) => {
+ let ones = [];
+ // The following messy loop parses playlist selection.
+ // A hacky limitation has been used here to prevent abuse. A new system HAS to be used.
+ if (match[1]) {
+ let param = match[1].substring(1);
+ let selectors = param.split(',');
+ selectors.forEach(s => {
+ let r = s.split('-');
+ if (r.length === 2) {
+ let indS = parseInt(r[0]);
+ let indE = parseInt(r[1]);
+ if (indE <= indS) return;
+ if (indE - indS > 100) return;
+ for (let i = indS; i <= indE; i++) {
+ if (ones.indexOf(i) <= -1) {
+ ones.push(i);
+ }
+ }
+ }
+ else if (r.length === 1) {
+ let ind = parseInt(r[0]);
+ if (ones.indexOf(ind) <= -1) {
+ ones.push(ind);
+ }
+ }
+ });
+ }
+
+ if (!bot.voices[message.channel.guild.id]) bot.voices[message.channel.guild.id] = { queue: [] };
+
+ let m = match[2];
+
+ if (!m.match(/^<?https?:\/\//)) {
+ m = 'ytsearch:' + m;
+ }
+ else if (m.charAt(0) === '<' && m.charAt(m.length - 1) === '>') {
+ m = m.slice(1);
+ m = m.slice(0, -1);
+ }
+
+ let t = await resolveTracks(bot._main, `${m}`);
+ if (t.loadType === 'TRACK_LOADED' || t.loadType === 'SEARCH_RESULT') {
+ let tr = t.tracks[0];
+ if (tr.info.isStream) {
+ bot.createMessage(message.channel.id, `I do not yet support streams, I'm sorry :(`).catch(Logger.error);
+ return;
+ }
+ tr.adder = `${message.author.username}#${message.author.discriminator}`;
+ bot.voices[message.channel.guild.id].queue.push(tr);
+ let ign = !match[1] ? '' : ' Playlist selectors parameters have been ignored as it is a sole song.';
+ bot.createMessage(message.channel.id, `\`${tr.info.title}\` has been added by \`${tr.adder}\`.${ign}`).catch(Logger.error);
+ }
+ else if (t.loadType === 'PLAYLIST_LOADED') {
+ let co = 0;
+ for (let i = 0; i < t.tracks.length; i++) {
+ if (ones.indexOf(i + 1) > -1 || ones.length === 0) {
+ let tr = t.tracks[i];
+ tr.adder = `${message.author.username}#${message.author.discriminator}`;
+ bot.voices[message.channel.guild.id].queue.push(tr);
+ co++;
+ }
+ }
+ bot.createMessage(message.channel.id, `${co} songs have been added to the queue by \`${message.author.username}#${message.author.discriminator}\``).catch(Logger.error);
+ }
+ else if (t.loadType === 'NO_MATCHES' || t.loadType === 'LOAD_FAILED') {
+ bot.createMessage(message.channel.id, `No results, sorry.`).catch(Logger.error);
+ return;
+ }
+
+ if (!message.member.voiceState.channelID) return;
+ let channel = message.channel.guild.channels.find(m => m.id === message.member.voiceState.channelID);
+ if (!bot.voices[message.channel.guild.id].crawling) {
+ let player = await getLavalinkPlayer(channel, bot);
+ player.switchChannel(message.member.voiceState.channelID, true);
+ bot.createMessage(message.channel.id, 'Joined voice channel.').catch(Logger.error); // TEMPORARY
+ crawl(player, bot, message);
+ }
+ });
+
+ bot.handler.endpoint('^skip$', [], async (match, message) => {
+ let player = bot.voiceConnections.get(message.channel.guild.id);
+ if (player) {
+ player.stop();
+ bot.createMessage(message.channel.id, 'Current song skipped').catch(Logger.error);
+ }
+ else {
+ bot.createMessage(message.channel.id, 'The bot wasn\'t playing.').catch(Logger.error);
+ }
+ });
+
+ bot.handler.endpoint('^clear$', [], async (match, message) => {
+ bot.voices[message.channel.guild.id].queue = [];
+ bot.createMessage(message.channel.id, 'The current queue has been cleared!').catch(Logger.error);
+ });
+
+ bot.handler.endpoint('^(?:stop|quit|halt)!?$', [], async (match, message) => {
+ let player = bot.voiceConnections.get(message.channel.guild.id);
+ bot.voices[message.channel.guild.id].queue = [];
+ if (player) {
+ player.stop();
+ bot.createMessage(message.channel.id, 'Successfully stopped!').catch(Logger.error);
+ }
+ else {
+ bot.createMessage(message.channel.id, 'The bot wasn\'t playing but the queue still has been cleared.').catch(Logger.error);
+ }
+ });
+
+ bot.handler.endpoint('^(?:come|resume)!?$', [], async (match, message) => {
+ if (!message.member.voiceState.channelID) return;
+ let channel = message.channel.guild.channels.find(m => m.id === message.member.voiceState.channelID);
+ let player = bot.voiceConnections.get(message.channel.guild.id);
+ if (player) {
+ player.switchChannel(message.member.voiceState.channelID, true);
+ if (player.paused) {
+ player.resume();
+ bot.createMessage(message.channel.id, 'Resumed the song.').catch(Logger.error);
+ }
+ }
+ else {
+ if (!message.member.voiceState.channelID) return;
+ if (!bot.voices[message.channel.guild.id]) bot.voices[message.channel.guild.id] = { queue: [] };
+ if (bot.voices[message.channel.guild.id].queue.length >= 1) {
+ let channel = message.channel.guild.channels.find(m => m.id === message.member.voiceState.channelID);
+ //if (!bot.voices[message.channel.guild.id].crawling) {
+ let player = await getLavalinkPlayer(channel, bot);
+ player.switchChannel(message.member.voiceState.channelID, true);
+ bot.createMessage(message.channel.id, 'Joined voice channel.').catch(Logger.error); // TEMPORARY
+ crawl(player, bot, message);
+ //}
+ }
+ else {
+ bot.createMessage(message.channel.id, 'The bot wasn\'t in any voice channel.').catch(Logger.error);
+ }
+ }
+ });
+
+ bot.handler.endpoint('^pause!?$', [], async (match, message) => {
+ let player = bot.voiceConnections.get(message.channel.guild.id);
+ if (player) {
+ player.pause();
+ bot.createMessage(message.channel.id, 'Song paused.').catch(Logger.error);
+ }
+ else {
+ bot.createMessage(message.channel.id, 'The bot isn\'t in any voice channel.').catch(Logger.error);
+ }
+ });
+
+ bot.handler.endpoint('^skip-to!? ([0-9]+)$', [], async (match, message) => {
+ let player = bot.voiceConnections.get(message.channel.guild.id);
+ if (!bot.voices[message.channel.guild.id]) bot.voices[message.channel.guild.id] = { queue: [] };
+ let arg = parseInt(match[1]);
+ if (arg <= 0) {
+ bot.createMessage(message.channel.id, `The argument should be greater than 0 (the queue is one-indexed), but 0 was provided.`).catch(Logger.error);
+ return;
+ }
+ if (arg > bot.voices[message.channel.guild.id].queue.length) {
+ bot.createMessage(message.channel.id, `Can't skip that far, the queue is currently only ${bot.voices[message.channel.guild.id].queue.length} titles long :')`).catch(Logger.error);
+ return;
+ }
+ bot.voices[message.channel.guild.id].queue = bot.voices[message.channel.guild.id].queue.splice(arg - 1);
+ if (player) {
+ player.stop();
+ bot.createMessage(message.channel.id, `Current song and ${arg - 1} following where skipped.`).catch(Logger.error);
+ }
+ else {
+ bot.createMessage(message.channel.id, `The bot wasn\'t playing but the ${arg - 1} next songs were successfully removed.`).catch(Logger.error);
+ }
+ });
+
+ bot.handler.endpoint('^remove-to!? ([0-9]+)$', [], async (match, message) => {
+ if (!bot.voices[message.channel.guild.id]) bot.voices[message.channel.guild.id] = { queue: [] };
+ let arg = parseInt(match[1]);
+ if (arg <= 0) {
+ bot.createMessage(message.channel.id, `The argument should be greater than 0 (the queue is one-indexed), but 0 was provided.`).catch(Logger.error);
+ return;
+ }
+ if (arg > bot.voices[message.channel.guild.id].queue.length) {
+ bot.createMessage(message.channel.id, `Can't remove that far, the queue is currently only ${bot.voices[message.channel.guild.id].queue.length} titles long :')`).catch(Logger.error);
+ return;
+ }
+ bot.voices[message.channel.guild.id].queue = bot.voices[message.channel.guild.id].queue.splice(arg);
+ bot.createMessage(message.channel.id, `${arg} next songs in the queue were removed.`).catch(Logger.error);
+ });
+
+ bot.handler.endpoint('^remove!? ([0-9]+)$', [], async (match, message) => {
+ if (!bot.voices[message.channel.guild.id]) bot.voices[message.channel.guild.id] = { queue: [] };
+ let arg = parseInt(match[1]);
+ if (arg <= 0) {
+ bot.createMessage(message.channel.id, `The argument should be greater than 0 (the queue is one-indexed), but 0 was provided.`).catch(Logger.error);
+ return;
+ }
+ if (arg > bot.voices[message.channel.guild.id].queue.length) {
+ bot.createMessage(message.channel.id, `Can't remove that far, the queue is currently only ${bot.voices[message.channel.guild.id].queue.length} titles long :')`).catch(Logger.error);
+ return;
+ }
+ bot.voices[message.channel.guild.id].queue.splice(arg - 1, 1);
+ bot.createMessage(message.channel.id, `The ${arg}e song in the queue was removed.`).catch(Logger.error);
+ });
+
+ bot.handler.endpoint('^now\\??$', [], async (match, message) => {
+ let player = bot.voiceConnections.get(message.channel.guild.id);
+ if (player && bot.voices[message.channel.guild.id].current) {
+ bot.createMessage(message.channel.id, `Now playing \`${bot.voices[message.channel.guild.id].current.info.title}\` at position ${time.msToMinutes(player.state.position)} added by \`${bot.voices[message.channel.guild.id].current.adder}\`. Total duration: ${time.msToMinutes(bot.voices[message.channel.guild.id].current.info.length)}`).catch(Logger.error);
+ }
+ else {
+ bot.createMessage(message.channel.id, 'The bot is not playing anything ¯\\_(ツ)_/¯').catch(Logger.error);
+ }
+ });
+
+ bot.handler.endpoint('^(?:queue|playlist|q|list)\\??$', [], async (match, message) => {
+ if (!bot.voices[message.channel.guild.id].queue || bot.voices[message.channel.guild.id].queue.length === 0) {
+ bot.createMessage(message.channel.id, 'The queue is empty!').catch(Logger.error);
+ return;
+ }
+ let buff = "";
+ let count = 1;
+ bot.voices[message.channel.guild.id].queue.forEach(t => {
+ buff += `${count}. ${t.info.title}, added by \`${t.adder}\` and lasts ${time.msToMinutes(t.info.length)}\n`;
+ count++;
+ });
+ bot.createMessage(message.channel.id, buff).catch(Logger.error);
+ });
+
+ bot.handler.endpoint('^(?:lyrics|text)\\??(?: (.+))?$', [], async (match, message) => {
+ let s = match[1] ? match[1] : null;
+ if (!s && (bot.voices[message.channel.guild.id] && bot.voices[message.channel.guild.id].current)) s = bot.voices[message.channel.guild.id].current.info.title;
+ if (!s) {
+ bot.createMessage(message.channel.id, 'No request mentionned and no song currently playing ¯\\_(ツ)_/¯').catch(Logger.error);
+ return;
+ }
+ let result;
+ try {
+ result = await superagent.get(`https://lyrics.tsu.sh/v1/?q=${s}`);
+ }
+ catch (e) {
+ return;
+ }
+ let res = JSON.parse(result.text);
+ let chunks = chunk(res.content, 2048);
+ if (chunks.length <= 4) {
+ let col = getRandomColor();
+ for (let i = 0; i < chunks.length; i++) {
+ let data = {
+ embed: {
+ description: chunks[i],
+ color: col,
+ }
+ }
+ if (i === 0) data.embed.title = res.song.full_title;
+ await bot.createMessage(message.channel.id, data).catch(Logger.error);
+ }
+ }
+ else {
+ let key = await hastebin(res.content);
+ bot.createMessage(message.channel.id, `https://hasteb.in/${key}.txt`).catch(Logger.error);
+ }
+ });
+};