diff --git a/commands/Music/play.js b/commands/Music/play.js index 3bda558..7a9ac18 100644 --- a/commands/Music/play.js +++ b/commands/Music/play.js @@ -1,19 +1,63 @@ const ytdl = require("ytdl-core"); exports.run = async (client, message, args, level) => { - if(!args[1] || args[1].startsWith("https://")) return (await message.reply("you need to provide a valid URL!")).delete(5000).catch(() => { }); - if(!message.member.voiceChannel) (await return message.reply("you need to be in a voice channel to use this command.")).delete(5000).catch(() => { }); + /* + if(!args[0]) return (await message.reply("you need to provide a valid URL!")).delete(5000).catch(() => { }); + if(!message.member.voiceChannel) return (await message.reply("you need to be in a voice channel to use this command.")).delete(5000).catch(() => { }); - if(!servers[message.guild.id]) servers[message.guild.id] = { + if(!client.servers[message.guild.id]) client.servers[message.guild.id] = { queue: [] } - var server = servers[message.guild.id]; - server.queue.push(args[1]); + var server = client.servers[message.guild.id]; + server.queue.push(args[0]); + message.channel.send(`Added ${args[0]} to the queue.`) if(!message.guild.voiceConnection) message.member.voiceChannel.join().then(function(connection) { - client.play(connection, message); + play(connection, message); }) + */ + const queue = message.client.queue; + const serverQueue = message.client.queue.get(message.guild.id); + + const voiceChannel = message.member.voiceChannel; + if(!voiceChannel) return message.reply("you need to be in a voice channel to use this command!"); + + const permissions = voiceChannel.permissionsFor(client.user); + if(!permissions.has("CONNECT") || !permissions.has("SPEAK")) return message.reply("I don't have the valid permissions to connect and speak in the channel you're in!"); + + const songInfo = await ytdl.getInfo(args[0]); + const song = { + title: songInfo.title, + url: songInfo.video_url + }; + + if(!serverQueue) { + const queueConstruct = { + textChannel: message.channel, + voiceChannel: voiceChannel, + connection: null, + songs: [], + volume: 5, + playing: true + }; + + queue.set(message.guild.id, queueConstruct); + queueConstruct.songs.push(song); + + try { + var connection = await voiceChannel.join(); + queueConstruct.connection = connection; + this.play(message, queueConstruct.songs[0]); + } catch(err) { + client.Logger.error(err); + queue.delete(message.guild.id); + return message.channel.send(`Uh oh! Looks like I hit a snag. Here's the error that Node picked up: ${err}`); + } + } else { + serverQueue.songs.push(song); + return message.channel.send(`${song.title} has been added to the queue!`); + } }; exports.conf = { @@ -29,3 +73,27 @@ exports.help = { description: "Play a song/playlist, or queue it if something's already playing.", usage: "play [url]" }; + +function play(message, song) { + const queue = client.queue; + const guild = message.guild; + const serverQueue = queue.get(message.guild.id); + + if (!song) { + serverQueue.voiceChannel.leave(); + queue.delete(guild.id); + return; + } + + const dispatcher = serverQueue.connection + .playStream(ytdl(song.url, { fliter: "audioonly" })) + .on("end", () => { + console.log("Music ended!"); + serverQueue.songs.shift(); + this.play(message, serverQueue.songs[0]); + }) + .on("error", error => { + console.error(error); + }); + dispatcher.setVolumeLogarithmic(serverQueue.volume / 5); +}; diff --git a/commands/Music/skip.js b/commands/Music/skip.js index f5ccac9..b83abb4 100644 --- a/commands/Music/skip.js +++ b/commands/Music/skip.js @@ -1,5 +1,5 @@ exports.run = async (client, message, args, level) => { - var server = servers[message.guild.id]; + var server = client.servers[message.guild.id]; if(server.dispatcher) server.dispatcher.end(); message.channel.send(`${message.author.mention} has skipped the current song.`); diff --git a/commands/Music/stop.js b/commands/Music/stop.js index 71f61f4..161c887 100644 --- a/commands/Music/stop.js +++ b/commands/Music/stop.js @@ -1,15 +1,23 @@ exports.run = async (client, message, args, level) => { - var server = servers[message.guild.id]; + /* + var server = client.servers[message.guild.id]; if(message.guild.voiceConnection) { for(var i = server.queue.length -1; i >= 0; i--) { server.queue.splice(i, 1); } - server.dispatcher.end(); + if(server.dispatcher) server.dispatcher.end(); message.channel.send(`${message.author.mention} has stopped the music.`); } - if(message.guild.connection) message.guild.voiceConnection.disconnect(); + if(message.guild.voiceConnection) message.guild.voiceConnection.disconnect(); + */ + const serverQueue = message.client.queue.get(message.guild.id); + if (!message.member.voiceChannel) return message.channel.send('You have to be in a voice channel to stop the music!'); + + serverQueue.songs = []; + serverQueue.connection.dispatcher.end(); + message.channel.send(`${message.author.mention} has stopped the music.`); }; exports.conf = { diff --git a/index.js b/index.js index e74b106..af647e3 100644 --- a/index.js +++ b/index.js @@ -14,11 +14,12 @@ client.logger = require("./modules/Logger"); require("./modules/functions.js")(client); client.commands = new Enmap(); client.aliases = new Enmap(); +client.queue = new Enmap(); client.settings = new Enmap({name: "settings"}); async function crawl(directory, filesArray) { const dirs = await readdir(directory, { - withFileTypes: true + withFileTypes: true }); for (let i = 0; i < dirs.length; i++) { @@ -51,13 +52,13 @@ const init = async () => { const event = require(`./events/${file}`); client.on(eventName, event.bind(null, client)); }); - + client.levelCache = {}; for (let i = 0; i < client.config.permLevels.length; i++) { const thisLevel = client.config.permLevels[i]; client.levelCache[thisLevel.name] = thisLevel.level; } - + client.login(client.config.token); }; diff --git a/modules/functions.js b/modules/functions.js index b7da9b7..981ead7 100644 --- a/modules/functions.js +++ b/modules/functions.js @@ -352,19 +352,5 @@ module.exports = (client) => { }); } - var servers = {}; - - client.play = (connection, message) => { - var server = servers[message.guild.id]; - - server.dispatcher = connection.playStream(ytdl(server.queue[0],{filter: "audioonly"})); - server.queue.shift(); - server.dispatcher.on("end", function() { - if(server.queue[0]) { - play(connection, message); - } else { - connection.disconnect(); - } - }) - }; -}; + client.servers = {}; +} diff --git a/package-lock.json b/package-lock.json index 7dd17b7..fc04f69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -137,7 +137,7 @@ "requires": { "colors": ">= 0.6.0-1", "first": "0.0.x", - "mime": ">=1.4.1", + "mime": "1.2.x", "node_hash": "0.2.x", "optimist": "0.3.x", "prettyjson": "0.7.x", @@ -309,6 +309,11 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, + "html-entities": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", + "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=" + }, "htmlparser2": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", @@ -460,13 +465,23 @@ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" }, + "m3u8stream": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/m3u8stream/-/m3u8stream-0.6.5.tgz", + "integrity": "sha512-QZCzhcfUliZfsOboi68QkNcMejPKTEhxE+s1TApvHubDeR8ythm4ViWuYFqgUwZeoHe8q0nsPxOvA3lQvdSzyg==", + "requires": { + "miniget": "^1.6.1", + "sax": "^1.2.4" + } + }, "math-expression-evaluator": { "version": "1.2.17", "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz", "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=" }, "mime": { - "version": ">=1.4.1", + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=" }, "mimic-fn": { @@ -474,6 +489,11 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" }, + "miniget": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/miniget/-/miniget-1.6.1.tgz", + "integrity": "sha512-I5oBwZmcaOuJrjQn7lpS29HM+aAZDbzKbX5ouxVyhFYdg6fA6YKOTwOCgzZQwlHuMek3FlCxz6eNrd4pOXbwOA==" + }, "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", @@ -553,6 +573,11 @@ "wordwrap": "~0.0.2" } }, + "opusscript": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/opusscript/-/opusscript-0.0.7.tgz", + "integrity": "sha512-DcBadTdYTUuH9zQtepsLjQn4Ll6rs3dmeFvN+SD0ThPnxRBRm/WC1zXWPg+wgAJimB784gdZvUMA57gDP7FdVg==" + }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -643,6 +668,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", @@ -806,6 +836,17 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + }, + "ytdl-core": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/ytdl-core/-/ytdl-core-1.0.8.tgz", + "integrity": "sha512-GX6DHLonG6RIFVCDUxJF0754EkXTjsh0fqp5vGTmp6Ang7nGCaooEWDYrfXm5U32dTJ83TVp1c92QKehQGPlxQ==", + "requires": { + "html-entities": "^1.1.3", + "m3u8stream": "^0.6.3", + "miniget": "^1.6.0", + "sax": "^1.1.3" + } } } } diff --git a/package.json b/package.json index f5ded45..c4792d0 100644 --- a/package.json +++ b/package.json @@ -33,9 +33,11 @@ "moment": "^2.24.0", "moment-duration-format": "^2.3.2", "node-fetch": "^2.6.0", + "opusscript": "0.0.7", "recrawl": "^2.0.0", "roll": "^1.2.0", - "webdict": "^0.3.0" + "webdict": "^0.3.0", + "ytdl-core": "^1.0.8" }, "publishConfig": { "registry": "https://npm.pkg.github.com/"