From 6d5d4765288dbcd20cbef89f0b428fb37b5091e8 Mon Sep 17 00:00:00 2001 From: mudkipscience Date: Wed, 22 Apr 2020 14:50:00 +1000 Subject: [PATCH 01/11] music stuff, added reload --- commands/movesong.js | 34 ++++++++++++++++++++++++---------- commands/reload.js | 32 ++++++++++++++++++++++++++++++++ commands/shuffle.js | 15 +++++++-------- utils/music.js | 1 - 4 files changed, 63 insertions(+), 19 deletions(-) create mode 100644 commands/reload.js diff --git a/commands/movesong.js b/commands/movesong.js index fe61c21..363e900 100644 --- a/commands/movesong.js +++ b/commands/movesong.js @@ -20,31 +20,45 @@ 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] + const songName = queue[oldPosition].video.title + + 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 (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) { - var k = newPosition - queue.length + 1 - while (k--) { - queue.push(undefined) - } + return message.channel.send('This number is too high!') } queue.splice(newPosition, 0, queue.splice(oldPosition, 1)[0]) 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..18edaca 100644 --- a/commands/shuffle.js +++ b/commands/shuffle.js @@ -27,14 +27,13 @@ module.exports.run = (client, message, args, level) => { 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 - } + // Make it so it shuffles all elements EXCEPT [0] + + for (i = queue.length - 1; i > 1; i--) { + j = Math.floor(Math.random() * (i + 1)) + x = queue[i] + queue[i] = queue[j] + queue[j] = x } message.channel.send('Queue shuffled!') diff --git a/utils/music.js b/utils/music.js index c36c5d0..d5747d4 100644 --- a/utils/music.js +++ b/utils/music.js @@ -169,7 +169,6 @@ exports.play = async function (client, message, query, ignoreQueue) { guild.playing = true guild.voiceChannel = vc - console.log(vc) const connection = await vc.join() From 4d97bc1ad0af5ca8dc9ebc01987435c83dc37ec0 Mon Sep 17 00:00:00 2001 From: mudkipscience Date: Wed, 22 Apr 2020 16:54:55 +1000 Subject: [PATCH 02/11] shuffle command now excluses the first element --- commands/shuffle.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/commands/shuffle.js b/commands/shuffle.js index 18edaca..01f02c2 100644 --- a/commands/shuffle.js +++ b/commands/shuffle.js @@ -25,15 +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 - - // Make it so it shuffles all elements EXCEPT [0] - - for (i = queue.length - 1; i > 1; 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!') From 69815dbdf26e1b6c4e144cd8f5e43469d29c9738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20H?= Date: Wed, 22 Apr 2020 09:39:46 +0200 Subject: [PATCH 03/11] voice chat leave detection --- events/voiceStateUpdate.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 events/voiceStateUpdate.js diff --git a/events/voiceStateUpdate.js b/events/voiceStateUpdate.js new file mode 100644 index 0000000..c8118e0 --- /dev/null +++ b/events/voiceStateUpdate.js @@ -0,0 +1,13 @@ +// 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) { + let guild = music.getGuild(newState.guild.id); + + if(guild.playing && guild.voiceChannel.id == oldState.channelID) { + console.log(newState.id + ' left VC, in which Woomy is playing music'); + }; + } +} \ No newline at end of file From e7ed2881394ff33b481fc210791061588100ade1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20H?= Date: Wed, 22 Apr 2020 09:49:45 +0200 Subject: [PATCH 04/11] Leave if no one is listening --- events/voiceStateUpdate.js | 26 +++++++++++++++++++++++++- utils/music.js | 1 + 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/events/voiceStateUpdate.js b/events/voiceStateUpdate.js index c8118e0..56d7fdb 100644 --- a/events/voiceStateUpdate.js +++ b/events/voiceStateUpdate.js @@ -7,7 +7,31 @@ module.exports = (client, oldState, newState) => { let guild = music.getGuild(newState.guild.id); if(guild.playing && guild.voiceChannel.id == oldState.channelID) { - console.log(newState.id + ' left VC, in which Woomy is playing music'); + if(guild.voiceChannel.members.size == 1) { + guild.autoDisconnect = true; + + setTimeout(() => { + if(guild.voiceChannel.members.size == 1 && guild.autoDisconnect) { + setTimeout(() => { + if(guild.voiceChannel.members.size == 1 && guild.autoDisconnect) { + setTimeout(() => { + if(guild.voiceChannel.members.size == 1 && guild.autoDisconnect) { + // Probably should be async? But no need here I think + guild.dispatcher.end('silent'); + guild.message.channel.send('No one is listening to me. Leaving voice chat!'); + } else { + guild.autoDisconnect = false; + }; + }, 30000); + } else { + guild.autoDisconnect = false; + }; + }, 20000); + } else { + guild.autoDisconnect = false; + }; + }, 10000); + }; }; } } \ No newline at end of file diff --git a/utils/music.js b/utils/music.js index d5747d4..bd7e1ea 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!') From 3dd36604e51c150b8dfeb816a8eac3fab86a3831 Mon Sep 17 00:00:00 2001 From: mudkipscience Date: Wed, 22 Apr 2020 17:53:41 +1000 Subject: [PATCH 05/11] songName no longer causes problems --- commands/movesong.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/commands/movesong.js b/commands/movesong.js index 363e900..c56d95e 100644 --- a/commands/movesong.js +++ b/commands/movesong.js @@ -35,7 +35,6 @@ module.exports.run = (client, message, args, level) => { const oldPosition = +args[0] const newPosition = +args[1] - const songName = queue[oldPosition].video.title 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.)') @@ -61,6 +60,8 @@ module.exports.run = (client, message, args, level) => { 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}\``) From 3956eb6fae21eaf0ca989611900f41158d80cc13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20H?= Date: Wed, 22 Apr 2020 09:53:55 +0200 Subject: [PATCH 06/11] fix --- events/voiceStateUpdate.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/events/voiceStateUpdate.js b/events/voiceStateUpdate.js index 56d7fdb..c3c20c7 100644 --- a/events/voiceStateUpdate.js +++ b/events/voiceStateUpdate.js @@ -16,6 +16,9 @@ module.exports = (client, oldState, newState) => { if(guild.voiceChannel.members.size == 1 && guild.autoDisconnect) { setTimeout(() => { if(guild.voiceChannel.members.size == 1 && guild.autoDisconnect) { + guild.playing = false; + guild.queue = []; + // Probably should be async? But no need here I think guild.dispatcher.end('silent'); guild.message.channel.send('No one is listening to me. Leaving voice chat!'); From 7c10c5309f30102387b601a47a074ccefef81618 Mon Sep 17 00:00:00 2001 From: mudkipscience Date: Wed, 22 Apr 2020 17:58:25 +1000 Subject: [PATCH 07/11] fixed formatting --- events/voiceStateUpdate.js | 64 +++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/events/voiceStateUpdate.js b/events/voiceStateUpdate.js index c3c20c7..f2e0caf 100644 --- a/events/voiceStateUpdate.js +++ b/events/voiceStateUpdate.js @@ -1,40 +1,40 @@ // Copyright 2020 Emily J. / mudkipscience and contributors. Subject to the AGPLv3 license. -const music = require('../utils/music'); +const music = require('../utils/music') module.exports = (client, oldState, newState) => { - if(newState.channelID != oldState.channelID) { - let guild = music.getGuild(newState.guild.id); + if (newState.channelID !== oldState.channelID) { + const guild = music.getGuild(newState.guild.id) - if(guild.playing && guild.voiceChannel.id == oldState.channelID) { - if(guild.voiceChannel.members.size == 1) { - guild.autoDisconnect = true; - + if (guild.playing && guild.voiceChannel.id === oldState.channelID) { + if (guild.voiceChannel.members.size === 1) { + guild.autoDisconnect = true + + setTimeout(() => { + if (guild.voiceChannel.members.size === 1 && guild.autoDisconnect) { + setTimeout(() => { + if (guild.voiceChannel.members.size === 1 && guild.autoDisconnect) { setTimeout(() => { - if(guild.voiceChannel.members.size == 1 && guild.autoDisconnect) { - setTimeout(() => { - if(guild.voiceChannel.members.size == 1 && guild.autoDisconnect) { - setTimeout(() => { - if(guild.voiceChannel.members.size == 1 && guild.autoDisconnect) { - guild.playing = false; - guild.queue = []; + if (guild.voiceChannel.members.size === 1 && guild.autoDisconnect) { + guild.playing = false + guild.queue = [] - // Probably should be async? But no need here I think - guild.dispatcher.end('silent'); - guild.message.channel.send('No one is listening to me. Leaving voice chat!'); - } else { - guild.autoDisconnect = false; - }; - }, 30000); - } else { - guild.autoDisconnect = false; - }; - }, 20000); - } else { - guild.autoDisconnect = false; - }; - }, 10000); - }; - }; + // Probably should be async? But no need here I think + guild.dispatcher.end('silent') + guild.message.channel.send('No one is listening to me. Leaving voice chat!') + } else { + guild.autoDisconnect = false + } + }, 30000) + } else { + guild.autoDisconnect = false + } + }, 20000) + } else { + guild.autoDisconnect = false + } + }, 10000) + } } -} \ No newline at end of file + } +} From 6ee912244233278575fd9b794285adeadae58746 Mon Sep 17 00:00:00 2001 From: mudkipscience Date: Wed, 22 Apr 2020 18:00:19 +1000 Subject: [PATCH 08/11] linter is mean --- utils/music.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/music.js b/utils/music.js index bd7e1ea..38887c6 100644 --- a/utils/music.js +++ b/utils/music.js @@ -66,7 +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; + 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!') From 98612a778420d5526321f032cdde963847c369fe Mon Sep 17 00:00:00 2001 From: mudkipscience Date: Wed, 22 Apr 2020 19:00:57 +1000 Subject: [PATCH 09/11] fixed music --- commands/stop.js | 8 +++++--- events/voiceStateUpdate.js | 41 +++++++++++++++++++------------------- utils/music.js | 7 +++++++ 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/commands/stop.js b/commands/stop.js index d82baed..0259dc0 100644 --- a/commands/stop.js +++ b/commands/stop.js @@ -24,11 +24,13 @@ 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.dispatcher = null + guild.skippers = [] message.channel.send('Playback stopped!') } diff --git a/events/voiceStateUpdate.js b/events/voiceStateUpdate.js index f2e0caf..9850f01 100644 --- a/events/voiceStateUpdate.js +++ b/events/voiceStateUpdate.js @@ -7,33 +7,32 @@ module.exports = (client, oldState, newState) => { const guild = music.getGuild(newState.guild.id) if (guild.playing && guild.voiceChannel.id === oldState.channelID) { - if (guild.voiceChannel.members.size === 1) { + if (guild.voiceChannel.members.filter(member => !member.user.bot).size < 1) { guild.autoDisconnect = true - setTimeout(() => { - if (guild.voiceChannel.members.size === 1 && guild.autoDisconnect) { - setTimeout(() => { - if (guild.voiceChannel.members.size === 1 && guild.autoDisconnect) { - setTimeout(() => { - if (guild.voiceChannel.members.size === 1 && guild.autoDisconnect) { - guild.playing = false - guild.queue = [] + guild.message.channel.send(`The music will end in 2 minutes if nobody rejoins **${guild.voiceChannel.name}**`) + .then(msg => { + msg.delete({ timeout: 120000 }) + }) - // Probably should be async? But no need here I think - guild.dispatcher.end('silent') - guild.message.channel.send('No one is listening to me. Leaving voice chat!') - } else { - guild.autoDisconnect = false - } - }, 30000) - } else { - guild.autoDisconnect = false - } - }, 20000) + 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 } - }, 10000) + }, 120000) + } else { + guild.autoDisconnect = false } } } diff --git a/utils/music.js b/utils/music.js index 38887c6..d08be5d 100644 --- a/utils/music.js +++ b/utils/music.js @@ -93,8 +93,11 @@ 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.paused = false guild.dispatcher = null + guild.skippers = [] // music not playing, something is in queue } else if (!guild.playing && !guild.dispatcher && guild.queue.length > 0) { guild.queue = [] @@ -188,7 +191,11 @@ exports.play = async function (client, message, query, ignoreQueue) { if (guild.queue.length > 0) { exports.play(client, message, null, true) } else { + guild.queue = [] + guild.playing = false + guild.paused = false guild.dispatcher = null + guild.skippers = [] connection.disconnect() } From be16d511e24e3aa3b3fc0388eff23ea68cc9862b Mon Sep 17 00:00:00 2001 From: mudkipscience Date: Wed, 22 Apr 2020 19:18:14 +1000 Subject: [PATCH 10/11] being force-disconnected from vc no longer breaks --- commands/stop.js | 1 - events/voiceStateUpdate.js | 9 +++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/commands/stop.js b/commands/stop.js index 0259dc0..ccad10d 100644 --- a/commands/stop.js +++ b/commands/stop.js @@ -29,7 +29,6 @@ exports.run = async (client, message) => { guild.queue = [] guild.playing = false guild.paused = false - guild.dispatcher = null guild.skippers = [] message.channel.send('Playback stopped!') diff --git a/events/voiceStateUpdate.js b/events/voiceStateUpdate.js index 9850f01..d252946 100644 --- a/events/voiceStateUpdate.js +++ b/events/voiceStateUpdate.js @@ -6,6 +6,15 @@ 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 From 888a2fc6ef99ee90e558e11807f06aaf2d1e311d Mon Sep 17 00:00:00 2001 From: mudkipscience Date: Wed, 22 Apr 2020 19:30:19 +1000 Subject: [PATCH 11/11] removed useless stuff --- utils/music.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/utils/music.js b/utils/music.js index d08be5d..3e474b0 100644 --- a/utils/music.js +++ b/utils/music.js @@ -96,7 +96,6 @@ exports.play = async function (client, message, query, ignoreQueue) { guild.queue = [] guild.playing = false guild.paused = false - guild.dispatcher = null guild.skippers = [] // music not playing, something is in queue } else if (!guild.playing && !guild.dispatcher && guild.queue.length > 0) { @@ -194,7 +193,6 @@ exports.play = async function (client, message, query, ignoreQueue) { guild.queue = [] guild.playing = false guild.paused = false - guild.dispatcher = null guild.skippers = [] connection.disconnect()