summaryrefslogtreecommitdiff
path: root/src/cmd/voice.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/voice.js')
-rw-r--r--src/cmd/voice.js356
1 files changed, 0 insertions, 356 deletions
diff --git a/src/cmd/voice.js b/src/cmd/voice.js
deleted file mode 100644
index 7f12603..0000000
--- a/src/cmd/voice.js
+++ /dev/null
@@ -1,356 +0,0 @@
-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);
- }
- });
-};