diff --git a/commands/movesong.js b/commands/movesong.js index fe61c21..c56d95e 100644 --- a/commands/movesong.js +++ b/commands/movesong.js @@ -20,33 +20,48 @@ exports.help = { const { getGuild } = require('../utils/music') module.exports.run = (client, message, args, level) => { const queue = getGuild(message.guild.id).queue - const oldPosition = +args[0] - const newPosition = +args[1] - const songName = queue[oldPosition].video.title if (queue.length < 3) { return message.channel.send('<:error:466995152976871434> Not enough songs are in the queue for this command to work!') } if (!args[0]) { - return message.channel.send(`<:error:466995152976871434> You didn't tell me what song to move! Usage: \`${client.commands.get('removesong').help.usage}\``) + return client.userError(message, exports, 'Missing argument, the `current position` argument is required!') } if (!args[1]) { - return message.channel.send(`<:error:466995152976871434> You didn't tell me what position in the queue you want to move this song to! Usage: \`${client.commands.get('removesong').help.usage}\``) + return client.userError(message, exports, 'Missing argument, the `new position` argument is required!') } - if (isNaN(oldPosition) === true || isNaN(newPosition) === true) { + const oldPosition = +args[0] + const newPosition = +args[1] + + if (isNaN(oldPosition) === true) { return message.channel.send('That isn\'t a number! You need to tell me the songs position in the queue (1, 2, etc.)') } - if (newPosition >= queue.length) { - var k = newPosition - queue.length + 1 - while (k--) { - queue.push(undefined) - } + if (isNaN(newPosition) === true) { + return message.channel.send('That isn\'t a number! You need to tell me the songs position in the queue (1, 2, etc.)') } + if (oldPosition < 1) { + return message.channel.send('This number is too low!') + } + + if (newPosition < 1) { + return message.channel.send('This number is too low!') + } + + if (oldPosition >= queue.length) { + return message.channel.send('This number is too high!') + } + + if (newPosition >= queue.length) { + return message.channel.send('This number is too high!') + } + + const songName = queue[oldPosition].video.title + queue.splice(newPosition, 0, queue.splice(oldPosition, 1)[0]) message.channel.send(`Moved **${songName}** from position \`${oldPosition}\` to \`${newPosition}\``) diff --git a/commands/reload.js b/commands/reload.js new file mode 100644 index 0000000..3de7af1 --- /dev/null +++ b/commands/reload.js @@ -0,0 +1,32 @@ +exports.conf = { + enabled: true, + guildOnly: false, + aliases: [], + permLevel: 'Developer', + requiredPerms: [], + cooldown: 2000 +} + +exports.help = { + name: 'reload', + category: 'Developer', + description: 'Reloads a command without having to restart the whole bot.', + usage: 'reload [command]', + parameters: '[command] - command you want to reload' +} + +exports.run = async (client, message, args) => { // eslint-disable-line no-unused-vars + if (!args || args.length < 1) { + return message.channel.send( + `<:error:466995152976871434> You must provide a command to reload! Usage: \`${client.commands.get('reload').help.usage}\`` + ) + } + + let response = await client.unloadCommand(args[0]) + if (response) return message.channel.send(`<:error:466995152976871434> Error unloading: ${response}`) + + response = client.loadCommand(args[0]) + if (response) return message.channel.send(`<:error:466995152976871434> Error loading: ${response}`) + + message.channel.send(`<:success:466995111885144095> \`${args[0]}\` has been reloaded!`) +} diff --git a/commands/shuffle.js b/commands/shuffle.js index a574933..01f02c2 100644 --- a/commands/shuffle.js +++ b/commands/shuffle.js @@ -25,16 +25,13 @@ module.exports.run = (client, message, args, level) => { return message.channel.send('Not enough songs are in the queue for this command to work!') } - let j, x, i - - for (i = queue.length - 1; i > 0; i--) { - if (i > 1) { - console.log(i) - j = Math.floor(Math.random() * (i + 1)) - x = queue[i] - queue[i] = queue[j] - queue[j] = x - } + const max = queue.length - 1 + const min = 1 + for (let i = max; i >= min; i--) { + const randomIndex = Math.floor(Math.random() * (max - min + 1)) + min + const itemAtIndex = queue[randomIndex] + queue[randomIndex] = queue[i] + queue[i] = itemAtIndex } message.channel.send('Queue shuffled!') diff --git a/commands/stop.js b/commands/stop.js index d82baed..ccad10d 100644 --- a/commands/stop.js +++ b/commands/stop.js @@ -24,11 +24,12 @@ exports.run = async (client, message) => { if (guild.queue.length < 1 || !guild.playing || !guild.dispatcher) return message.channel.send('Nothing is playing.') if (!message.member.voice.channel) return message.channel.send('You need to be in voice channel to use this command!') + guild.dispatcher.end('silent') + + guild.queue = [] guild.playing = false guild.paused = false - guild.queue = [] - - guild.dispatcher.end('silent') + guild.skippers = [] message.channel.send('Playback stopped!') } diff --git a/events/voiceStateUpdate.js b/events/voiceStateUpdate.js new file mode 100644 index 0000000..d252946 --- /dev/null +++ b/events/voiceStateUpdate.js @@ -0,0 +1,48 @@ +// Copyright 2020 Emily J. / mudkipscience and contributors. Subject to the AGPLv3 license. + +const music = require('../utils/music') + +module.exports = (client, oldState, newState) => { + if (newState.channelID !== oldState.channelID) { + const guild = music.getGuild(newState.guild.id) + + // Reset queue, dispatcher, etc if Woomy is forcibly disconnected from the queue + if (!guild.voiceChannel.members.get(client.user.id) && guild.queue.length > 0) { + guild.queue = [] + guild.playing = false + guild.paused = false + guild.skippers = [] + } + + // Auto-disconnect feature + if (guild.playing && guild.voiceChannel.id === oldState.channelID) { + if (guild.voiceChannel.members.filter(member => !member.user.bot).size < 1) { + guild.autoDisconnect = true + + guild.message.channel.send(`The music will end in 2 minutes if nobody rejoins **${guild.voiceChannel.name}**`) + .then(msg => { + msg.delete({ timeout: 120000 }) + }) + + setTimeout(() => { + if (guild.dispatcher !== null && guild.voiceChannel.members.filter(member => !member.user.bot).size < 1 && guild.autoDisconnect) { + // Probably should be async? But no need here I think + guild.dispatcher.end('silent') + + guild.queue = [] + guild.playing = false + guild.paused = false + guild.dispatcher = null + guild.skippers = [] + + guild.message.channel.send('The music has ended because no one was listening to me ;~;') + } else { + guild.autoDisconnect = false + } + }, 120000) + } else { + guild.autoDisconnect = false + } + } + } +} diff --git a/utils/music.js b/utils/music.js index c36c5d0..3e474b0 100644 --- a/utils/music.js +++ b/utils/music.js @@ -66,6 +66,7 @@ exports.getVideoByQuery = async function (client, query) { exports.play = async function (client, message, query, ignoreQueue) { const guild = exports.getGuild(message.guild.id) + guild.message = message if (!message.member.voice.channel && !guild.voiceChannel) { return message.reply('You have to be connected to a voice channel to use this command!') @@ -92,8 +93,10 @@ exports.play = async function (client, message, query, ignoreQueue) { // Fix the bot if somehow broken // music "playing", nothing in queue if ((guild.playing || guild.dispatcher) && guild.queue.length === 0) { + guild.queue = [] guild.playing = false - guild.dispatcher = null + guild.paused = false + guild.skippers = [] // music not playing, something is in queue } else if (!guild.playing && !guild.dispatcher && guild.queue.length > 0) { guild.queue = [] @@ -169,7 +172,6 @@ exports.play = async function (client, message, query, ignoreQueue) { guild.playing = true guild.voiceChannel = vc - console.log(vc) const connection = await vc.join() @@ -188,7 +190,10 @@ exports.play = async function (client, message, query, ignoreQueue) { if (guild.queue.length > 0) { exports.play(client, message, null, true) } else { - guild.dispatcher = null + guild.queue = [] + guild.playing = false + guild.paused = false + guild.skippers = [] connection.disconnect() }