diff --git a/commands/forceskip.js b/commands/forceskip.js index 7a72b8f..8c604b2 100644 --- a/commands/forceskip.js +++ b/commands/forceskip.js @@ -15,8 +15,9 @@ exports.help = { params: '' } +const { skip } = require('../utils/music') exports.run = async (client, message, args, level, data) => { - client.music.skip(message.guild, 'forceskip'); + skip(message.guild, 'forceskip') - message.reply('skipped currently playing music'); -}; \ No newline at end of file + message.reply('skipped currently playing music') +} diff --git a/commands/play.js b/commands/play.js index 2fe5497..0e640c3 100644 --- a/commands/play.js +++ b/commands/play.js @@ -15,6 +15,7 @@ exports.help = { parameters: '[query] - A query to find video by or a link to the video.' } +const { play } = require('../utils/music') exports.run = async (client, message, args, level, data) => { - await client.music.play(message, args.join(' ')) + await play(client, message, args.join(' ')) } diff --git a/commands/volume.js b/commands/volume.js index 8a02f74..d191d13 100644 --- a/commands/volume.js +++ b/commands/volume.js @@ -15,6 +15,7 @@ exports.help = { parameters: '[volume] - Target volume from 0-100%' } +const { setVolume } = require('../utils/music') exports.run = async (client, message, args, level, data) => { let vol = args[0] @@ -24,7 +25,7 @@ exports.run = async (client, message, args, level, data) => { vol = vol / 100 * 0.5 if (vol <= 1) { - client.music.setVolume(message.guild, vol) + setVolume(message.guild, vol) message.reply('set volume to ' + vol * 100 + '%') } diff --git a/index.js b/index.js index 6d07248..53871db 100644 --- a/index.js +++ b/index.js @@ -27,7 +27,6 @@ client.version = require('./version.json') client.db = require('./utils/mongoose') client.logger = require('./utils/logger') require('./utils/_functions')(client) -require('./utils/music')(client) // Check if Woomy is running inside a Docker container if (isDocker() === true) { diff --git a/utils/music.js b/utils/music.js index a15b58b..078661e 100644 --- a/utils/music.js +++ b/utils/music.js @@ -3,209 +3,207 @@ const fetch = require('node-fetch') const { MessageEmbed } = require('discord.js') const { utc } = require('moment') -module.exports = client => { - client.music = { guilds: {} } +exports.queue = {} - client.createTimestamp = function (s) { - if (s >= 3600) { - return utc(s * 1000).format('HH:mm:ss') - } else { - return utc(s * 1000).format('mm:ss') - } +exports.createTimestamp = function (s) { + if (s >= 3600) { + return utc(s * 1000).format('HH:mm:ss') + } else { + return utc(s * 1000).format('mm:ss') + } +} + +exports.getGuild = function (id) { + let guild = exports.queue[id] + + if (!guild) { + guild = {} + + guild.dispatcher = null + guild.playing = false + guild.queue = [] + + exports.queue[id] = guild } - client.music.getGuild = function (id) { - let guild = client.music.guilds[id] + return guild +} - if (!guild) { - guild = {} +exports.getLinkFromID = function (id) { + return 'https://www.youtube.com/watch?v=' + id +} - guild.dispatcher = null - guild.playing = false - guild.queue = [] +exports.getVideoByQuery = async query => { + let res - client.music.guilds[id] = guild - } - - return guild + try { + const id = await ytdl.getURLVideoID(query) + res = await fetch('https://invidious.snopyta.org/api/v1/videos/' + id) + } catch (err) { + res = await fetch('https://invidious.snopyta.org/api/v1/search?q=' + encodeURIComponent(query)) } - client.music.getLinkFromID = function (id) { - return 'https://www.youtube.com/watch?v=' + id - } + const parsed = await res.json() - client.music.getVideoByQuery = async query => { - let resp + if (parsed) { + const videos = parsed - try { - const id = await ytdl.getURLVideoID(query) - resp = await fetch('https://invidious.snopyta.org/api/v1/videos/' + id) - } catch (err) { - resp = await fetch('https://invidious.snopyta.org/api/v1/search?q=' + encodeURIComponent(query)) - } - - const parsed = await resp.json() - - if (parsed) { - const videos = parsed - - if (videos) { - return videos - } else { - return false - } + if (videos) { + return videos } else { return false } - } - - client.music.play = async function (message, query, ignoreQueue) { - const guild = client.music.getGuild(message.guild.id) - - if (!message.member.voice.channel && !guild.voiceChannel) { - return message.reply('You have to be connected to a voice channel to use this command!') - } - - const vc = message.member.voice.channel - - let video - let videos - - if (!ignoreQueue) { - videos = await client.music.getVideoByQuery(query) - if (!videos[1]) { - if (!videos[0]) { - video = videos - } else { - video = videos[0] - } - } - } - - if (videos || ignoreQueue) { - if (!ignoreQueue) { - // Fix the bot if somehow broken - // music "playing", nothing in queue - if ((guild.playing || guild.dispatcher) && guild.queue.length === 0) { - guild.playing = false - guild.dispatcher = null - // music not playing, something is in queue - } else if (!guild.playing && !guild.dispatcher && guild.queue.length > 0) { - guild.queue = [] - } - - if (!video) { - let output = '' - let i = 0 - for (i = 0; i < 5; i++) { - if (!videos[i]) break - output += `\`${i + 1}:\` **[${videos[i].title}](https://www.youtube.com/watch?v=${videos[i].videoId})** \`[${client.createTimestamp(videos[i].lengthSeconds)}]\`\n` - } - - const embed = new MessageEmbed() - embed.setTitle('Please reply with a number `1-' + i + '` to select which song you want to add to the queue.') - embed.setColor(client.embedColour(message.guild)) - embed.setDescription(output) - - let selection = await client.awaitReply(message, embed) - selection = Number(selection) - - switch (selection) { - case 1: - video = videos[0] - break - case 2: - if (videos[1]) { - video = videos[1] - } else { - return message.channel.send('Invalid choice.') - } - break - case 3: - if (videos[2]) { - video = videos[2] - } else { - return message.channel.send('Invalid choice.') - } - break - case 4: - if (videos[3]) { - video = videos[3] - } else { - return message.channel.send('Invalid choice.') - } - break - case 5: - if (videos[4]) { - video = videos[4] - } else { - return message.channel.send('Invalid choice.') - } - break - default: - return message.channel.send('Invalid choice.') - } - } - - if (!video && videos[0]) { - video = videos[0] - } else if (!video) { - video = videos - } - - // Add video to queue - guild.queue.push({ video: video, requestedBy: message.member.id }) - } - - // Figure out if the bot should add it to queue or play it right now - if (guild.playing) { - message.reply('added **' + video.title + '** to the queue') - } else { - guild.playing = true - - guild.voiceChannel = vc - - const connection = await vc.join() - - const v = guild.queue[0] - - guild.dispatcher = connection.play(await ytdl(client.music.getLinkFromID(v.video.videoId), { highWaterMark: 1024 * 1024 * 32 }), { type: 'opus' }) - guild.dispatcher.setVolume(0.25) - - message.channel.send('Playing **' + v.video.title + '**') - - // play next in queue on end - guild.dispatcher.once('finish', () => { - guild.queue.shift() - guild.playing = false - - if (guild.queue.length > 0) { - client.music.play(message, null, true) - } else { - guild.dispatcher = null - - connection.disconnect() - } - }) - } - } else { - return message.reply('failed to find the video!') - } - } - - client.music.setVolume = function (guild, target) { - const g = client.music.getGuild(guild.id) - - if (g.dispatcher) { - g.dispatcher.setVolume(target) - } - } - - client.music.skip = function (guild, reason) { - const g = client.music.getGuild(guild.id) - - if (g.dispatcher) { - g.dispatcher.end(reason) - } + } else { + return false + } +} + +exports.play = async function (client, message, query, ignoreQueue) { + const guild = exports.getGuild(message.guild.id) + + if (!message.member.voice.channel && !guild.voiceChannel) { + return message.reply('You have to be connected to a voice channel to use this command!') + } + + const vc = message.member.voice.channel + + let video + let videos + + if (!ignoreQueue) { + videos = await exports.getVideoByQuery(query) + if (!videos[1]) { + if (!videos[0]) { + video = videos + } else { + video = videos[0] + } + } + } + + if (videos || ignoreQueue) { + if (!ignoreQueue) { + // Fix the bot if somehow broken + // music "playing", nothing in queue + if ((guild.playing || guild.dispatcher) && guild.queue.length === 0) { + guild.playing = false + guild.dispatcher = null + // music not playing, something is in queue + } else if (!guild.playing && !guild.dispatcher && guild.queue.length > 0) { + guild.queue = [] + } + + if (!video) { + let output = '' + let i = 0 + for (i = 0; i < 5; i++) { + if (!videos[i]) break + output += `\`${i + 1}:\` **[${videos[i].title}](https://www.youtube.com/watch?v=${videos[i].videoId})** \`[${exports.createTimestamp(videos[i].lengthSeconds)}]\`\n` + } + + const embed = new MessageEmbed() + embed.setTitle('Please reply with a number `1-' + i + '` to select which song you want to add to the queue.') + embed.setColor(client.embedColour(message.guild)) + embed.setDescription(output) + + let selection = await client.awaitReply(message, embed) + selection = Number(selection) + + switch (selection) { + case 1: + video = videos[0] + break + case 2: + if (videos[1]) { + video = videos[1] + } else { + return message.channel.send('Invalid choice.') + } + break + case 3: + if (videos[2]) { + video = videos[2] + } else { + return message.channel.send('Invalid choice.') + } + break + case 4: + if (videos[3]) { + video = videos[3] + } else { + return message.channel.send('Invalid choice.') + } + break + case 5: + if (videos[4]) { + video = videos[4] + } else { + return message.channel.send('Invalid choice.') + } + break + default: + return message.channel.send('Invalid choice.') + } + } + + if (!video && videos[0]) { + video = videos[0] + } else if (!video) { + video = videos + } + + // Add video to queue + guild.queue.push({ video: video, requestedBy: message.member.id }) + } + + // Figure out if the bot should add it to queue or play it right now + if (guild.playing) { + message.reply('added **' + video.title + '** to the queue') + } else { + guild.playing = true + + guild.voiceChannel = vc + + const connection = await vc.join() + + const v = guild.queue[0] + + guild.dispatcher = connection.play(await ytdl(exports.getLinkFromID(v.video.videoId), { highWaterMark: 1024 * 1024 * 32 }), { type: 'opus' }) + guild.dispatcher.setVolume(0.25) + + message.channel.send('Playing **' + v.video.title + '**') + + // play next in queue on end + guild.dispatcher.once('finish', () => { + guild.queue.shift() + guild.playing = false + + if (guild.queue.length > 0) { + exports.play(message, null, true) + } else { + guild.dispatcher = null + + connection.disconnect() + } + }) + } + } else { + return message.reply('failed to find the video!') + } +} + +exports.setVolume = function (guild, target) { + const g = exports.getGuild(guild.id) + + if (g.dispatcher) { + g.dispatcher.setVolume(target) + } +} + +exports.skip = function (guild, reason) { + const g = exports.getGuild(guild.id) + + if (g.dispatcher) { + g.dispatcher.end(reason) } }