diff options
Diffstat (limited to 'src/commands/voice')
| -rw-r--r-- | src/commands/voice/abee.ts | 199 | ||||
| -rw-r--r-- | src/commands/voice/itemshop.ts | 209 | ||||
| -rw-r--r-- | src/commands/voice/join.js | 31 | ||||
| -rw-r--r-- | src/commands/voice/leave.js | 34 | ||||
| -rw-r--r-- | src/commands/voice/loop.js | 34 | ||||
| -rw-r--r-- | src/commands/voice/minecraft.ts | 204 | ||||
| -rw-r--r-- | src/commands/voice/pause.js | 32 | ||||
| -rw-r--r-- | src/commands/voice/play.ts | 292 | ||||
| -rw-r--r-- | src/commands/voice/psycho.ts | 198 | ||||
| -rw-r--r-- | src/commands/voice/queue.js | 51 | ||||
| -rw-r--r-- | src/commands/voice/remove.js | 41 | ||||
| -rw-r--r-- | src/commands/voice/resume.js | 32 | ||||
| -rw-r--r-- | src/commands/voice/shuffle.js | 53 | ||||
| -rw-r--r-- | src/commands/voice/skip.js | 29 | ||||
| -rw-r--r-- | src/commands/voice/skipall.js | 44 | ||||
| -rw-r--r-- | src/commands/voice/skipto.js | 43 | ||||
| -rw-r--r-- | src/commands/voice/volume.js | 45 |
17 files changed, 1571 insertions, 0 deletions
diff --git a/src/commands/voice/abee.ts b/src/commands/voice/abee.ts new file mode 100644 index 0000000..939b575 --- /dev/null +++ b/src/commands/voice/abee.ts @@ -0,0 +1,199 @@ +import ytdl from 'ytdl-core'; +import { Command } from 'discord.js-commando'; +import { MessageEmbed, Message } from 'discord.js'; +import Youtube from 'simple-youtube-api'; +//const { youtubeAPI } = require('../../config.json'); +import config from '../../config.json'; +const youtube = new Youtube(config['yt-api-key']); +import emoji from 'emoji-random'; + +module.exports = class ABeeVoice extends Command { + constructor(client) { + super(client, { + name: 'abee', + aliases: ['a-bee'], + group: 'voice', + memberName: 'abee', + description: 'A bee 🐝', + guildOnly: true, + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + examples: ['uwu!abee', 'uwu!a-bee'], + }); + } + async run(msg: Message) { + const voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.say('Please join a channel and try again. ' + emoji.random()); + + const id = 'lvdnhWhQBdo'; + const video = await youtube.getVideoByID(id).catch(function () { + return msg.say( + 'There was a problem getting the video you provided. ' + emoji.random() + ); + }); + // // can be uncommented if you don't want the bot to play live streams + // if (video.raw.snippet.liveBroadcastContent === 'live') { + // return msg.say("I don't support live streams!"); + // } + // // can be uncommented if you don't want the bot to play videos longer than 1 hour + // if (video.duration.hours !== 0) { + // return msg.say('I cannot play videos longer than 1 hour'); + // } + // // can be uncommented if you want to limit the queue + // if (msg.guild.musicData.queue.length > 10) { + // return msg.say( + // 'There are too many songs in the queue already, skip or wait a bit' + // ); + // } + msg.guild.musicData.queue.push( + this.constructSongObj(video, voiceChannel) + ); + if ( + msg.guild.musicData.isPlaying == false || + typeof msg.guild.musicData.isPlaying == 'undefined' + ) { + msg.guild.musicData.isPlaying = true; + return this.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + return msg.say(`${video.title} added to queue. ` + emoji.random()); + } + + var that = this; + msg.channel + .awaitMessages( + function (msg) { + return (msg.content > 0 && msg.content < 6) || msg.content === 'exit'; + }, { + max: 1, + time: 60000, + errors: ['time'] + } + ) + .then(function (response) { + const videoIndex = parseInt(response.first().content); + if (response.first().content === 'exit') return songEmbed.delete(); + youtube + .getVideoByID(videos[videoIndex - 1].id) + .then(function (video) { + // // can be uncommented if you don't want the bot to play live streams + // if (video.raw.snippet.liveBroadcastContent === 'live') { + // songEmbed.delete(); + // return msg.say("I don't support live streams!"); + // } + + // // can be uncommented if you don't want the bot to play videos longer than 1 hour + // if (video.duration.hours !== 0) { + // songEmbed.delete(); + // return msg.say('I cannot play videos longer than 1 hour'); + // } + + // // can be uncommented if you don't want to limit the queue + // if (msg.guild.musicData.queue.length > 10) { + // songEmbed.delete(); + // return msg.say( + // 'There are too many songs in the queue already, skip or wait a bit' + // ); + // } + msg.guild.musicData.queue.push( + that.constructSongObj(video, voiceChannel) + ); + if (msg.guild.musicData.isPlaying == false) { + msg.guild.musicData.isPlaying = true; + if (songEmbed) { + songEmbed.delete(); + } + that.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say(`${video.title} added to queue. ` + emoji.random()); + } + }) + .catch(function () { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say( + 'An error has occured when trying to get the video ID from YouTube. ' + emoji.random() + ); + }); + }); + } + playSong(queue, msg) { + const classThis = this; // use classThis instead of 'this' because of lexical scope below + queue[0].voiceChannel + .join() + .then(function (connection) { + const dispatcher = connection + .play( + ytdl(queue[0].url, { + quality: 'highestaudio', + highWaterMark: 1024 * 1024 * 10 + }) + ) + .on('start', function () { + msg.guild.musicData.songDispatcher = dispatcher; + const volume = 100 / 100; + msg.guild.musicData.volume = volume; + dispatcher.setVolume(msg.guild.musicData.volume); + const videoEmbed = new MessageEmbed() + .setThumbnail(queue[0].thumbnail) + .setColor(0xF97DAE) + .addField('Now playing:', queue[0].title) + .addField('Duration:', queue[0].duration); + if (queue[1]) videoEmbed.addField('Next song:', queue[1].title); + msg.say(videoEmbed); + msg.guild.musicData.nowPlaying = queue[0]; + return queue.shift(); + }) + .on('finish', function () { + if (queue.length >= 1) { + return classThis.playSong(queue, msg); + } else { + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + } + }) + .on('error', function (e) { + msg.say('Can\'t play song. ' + emoji.random()); + console.error(e); + msg.guild.musicData.queue.length = 0; + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + }); + }) + .catch(function (e) { + console.error(e); + return msg.guild.me.voice.channel.leave(); + }); + } + constructSongObj(video, voiceChannel) { + let duration = this.formatDuration(video.duration); + if (duration == '00:00') duration = 'Live Stream'; + return { + url: `https://www.youtube.com/watch?v=${video.raw.id}`, + title: video.title, + duration, + thumbnail: video.thumbnails.high.url, + voiceChannel + }; + } + // prettier-ignore + formatDuration(durationObj) { + const duration = `${durationObj.hours ? (durationObj.hours + ':') : ''}${ + durationObj.minutes ? durationObj.minutes : '00' + }:${ + (durationObj.seconds < 10) + ? ('0' + durationObj.seconds) + : (durationObj.seconds + ? durationObj.seconds + : '00') + }`; + return duration; + } +};
\ No newline at end of file diff --git a/src/commands/voice/itemshop.ts b/src/commands/voice/itemshop.ts new file mode 100644 index 0000000..f8c0b2b --- /dev/null +++ b/src/commands/voice/itemshop.ts @@ -0,0 +1,209 @@ +import ytdl from 'ytdl-core'; +import { Command } from 'discord.js-commando'; +import { MessageEmbed, Message } from 'discord.js'; +import Youtube from 'simple-youtube-api'; +//const { youtubeAPI } = require('../../config.json'); +import config from '../../config.json'; +const youtube = new Youtube(config['yt-api-key']); +import emoji from 'emoji-random'; + +module.exports = class ABeeVoice extends Command { + constructor(client) { + super(client, { + name: 'itemshop', + aliases: ['item-shop'], + group: 'voice', + memberName: 'itemshop', + description: 'Use code \'Frozen\' in the Fortnite item shop.', + guildOnly: true, + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + examples: ['uwu!itemshop', 'uwu!item-shop'] + }); + } + async run(msg: Message) { + const voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.say('Please join a channel and try again. ' + emoji.random()); + + const id = 'pBiI1hTwU7E'; + const video = await youtube.getVideoByID(id).catch(function () { + return msg.say( + 'There was a problem getting the video you provided. ' + emoji.random() + ); + }); + // // can be uncommented if you don't want the bot to play live streams + // if (video.raw.snippet.liveBroadcastContent === 'live') { + // return msg.say("I don't support live streams!"); + // } + // // can be uncommented if you don't want the bot to play videos longer than 1 hour + // if (video.duration.hours !== 0) { + // return msg.say('I cannot play videos longer than 1 hour'); + // } + // // can be uncommented if you want to limit the queue + // if (msg.guild.musicData.queue.length > 10) { + // return msg.say( + // 'There are too many songs in the queue already, skip or wait a bit' + // ); + // } + msg.guild.musicData.queue.push( + this.constructSongObj(video, voiceChannel) + ); + if ( + msg.guild.musicData.isPlaying == false || + typeof msg.guild.musicData.isPlaying == 'undefined' + ) { + msg.guild.musicData.isPlaying = true; + return this.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + return msg.say(`${video.title} added to queue. ` + emoji.random()); + } + + var that = this; + msg.channel + .awaitMessages( + function (msg) { + return (msg.content > 0 && msg.content < 6) || msg.content === 'exit'; + }, { + max: 1, + time: 60000, + errors: ['time'] + } + ) + .then(function (response) { + const videoIndex = parseInt(response.first().content); + if (response.first().content === 'exit') return songEmbed.delete(); + youtube + .getVideoByID(videos[videoIndex - 1].id) + .then(function (video) { + // // can be uncommented if you don't want the bot to play live streams + // if (video.raw.snippet.liveBroadcastContent === 'live') { + // songEmbed.delete(); + // return msg.say("I don't support live streams!"); + // } + + // // can be uncommented if you don't want the bot to play videos longer than 1 hour + // if (video.duration.hours !== 0) { + // songEmbed.delete(); + // return msg.say('I cannot play videos longer than 1 hour'); + // } + + // // can be uncommented if you don't want to limit the queue + // if (msg.guild.musicData.queue.length > 10) { + // songEmbed.delete(); + // return msg.say( + // 'There are too many songs in the queue already, skip or wait a bit' + // ); + // } + msg.guild.musicData.queue.push( + that.constructSongObj(video, voiceChannel) + ); + if (msg.guild.musicData.isPlaying == false) { + msg.guild.musicData.isPlaying = true; + if (songEmbed) { + songEmbed.delete(); + } + that.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + if (songEmbed) { + songEmbed.delete(); + } + msg.say(`${video.title} added to queue. ` + emoji.random()); + return; + } + }) + .catch(function () { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say( + 'An error has occured when trying to get the video ID from Youtube.' + emoji.random() + ); + }); + }); + } + playSong(queue, msg) { + const classThis = this; // use classThis instead of 'this' because of lexical scope below + queue[0].voiceChannel + .join() + .then(function (connection) { + const dispatcher = connection + .play( + ytdl(queue[0].url, { + quality: 'highestaudio', + highWaterMark: 1024 * 1024 * 10 + }) + + ) + .on('start', function () { + msg.guild.musicData.songDispatcher = dispatcher; + const volume = 100 / 100; + msg.guild.musicData.volume = volume; + dispatcher.setVolume(msg.guild.musicData.volume); + const videoEmbed = new MessageEmbed() + .setThumbnail(queue[0].thumbnail) + .setColor(0xF97DAE) + .addField('Now playing:', queue[0].title) + .addField('Duration:', queue[0].duration); + if (queue[1]) videoEmbed.addField('Next song:', queue[1].title); + msg.say(videoEmbed); + msg.guild.musicData.nowPlaying = queue[0]; + return queue.shift(); + }) + .on('finish', function () { + if (queue.length >= 1) { + return classThis.playSong(queue, msg); + } else { + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + } + }) + .on('error', function (e) { + msg.say('Can\'t play song. ' + emoji.random()); + console.error(e); + msg.guild.musicData.queue.length = 0; + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + }); + function timeCheck() { + if (dispatcher.streamTime >= 6000) { + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + } + } + setInterval(timeCheck, 500); + }) + .catch(function (e) { + console.error(e); + return msg.guild.me.voice.channel.leave(); + }); + } + constructSongObj(video, voiceChannel) { + let duration = this.formatDuration(video.duration); + if (duration == '00:00') duration = 'Live Stream'; + return { + url: `https://www.youtube.com/watch?v=${video.raw.id}`, + title: video.title, + duration, + thumbnail: video.thumbnails.high.url, + voiceChannel + }; + } + // prettier-ignore + formatDuration(durationObj) { + const duration = `${durationObj.hours ? (durationObj.hours + ':') : ''}${ + durationObj.minutes ? durationObj.minutes : '00' + }:${ + (durationObj.seconds < 10) + ? ('0' + durationObj.seconds) + : (durationObj.seconds + ? durationObj.seconds + : '00') + }`; + return duration; + } +};
\ No newline at end of file diff --git a/src/commands/voice/join.js b/src/commands/voice/join.js new file mode 100644 index 0000000..4410e4c --- /dev/null +++ b/src/commands/voice/join.js @@ -0,0 +1,31 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class JoinVoice extends Command { + constructor(client) { + super(client, { + name: 'join', + group: 'voice', + memberName: 'join', + description: 'Joins your current voice channel.', + throttling: { + usages: 2, + duration: 5 + }, + guildOnly: true, + examples: ['uwu!join'], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg) { + if (msg.guild.musicData.isPlaying == false && msg.member.voice.channel) { + msg.member.voice.channel.join(); + msg.reply('Succesfully joined voice channel. ' + emoji.random()); + } else if (msg.guild.musicData.isPlaying == false) { + msg.reply('I\'m already in voice channel. ' + emoji.random()); + } else if (!msg.member.voice.channel) { + msg.reply('Please join a channel and try again. ' + emoji.random()); + } + } +};
\ No newline at end of file diff --git a/src/commands/voice/leave.js b/src/commands/voice/leave.js new file mode 100644 index 0000000..4c25e62 --- /dev/null +++ b/src/commands/voice/leave.js @@ -0,0 +1,34 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class LeaveVoice extends Command { + constructor(client) { + super(client, { + name: 'leave', + aliases: ['end', 'stop'], + group: 'voice', + memberName: 'leave', + description: 'Leaves voice channel and stops currently playing audio.', + guildOnly: true, + examples: ['uwu!leave', 'uwu!end', 'uwu!stop'], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg) { + var voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join a channel and try again. ' + emoji.random()); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + if (!msg.guild.musicData.queue) + return msg.say('There aren\'t any songs in the current queue. ' + emoji.random()); + msg.guild.musicData.songDispatcher.end(); + msg.guild.musicData.queue.length = 0; + return; + } +};
\ No newline at end of file diff --git a/src/commands/voice/loop.js b/src/commands/voice/loop.js new file mode 100644 index 0000000..05c0e99 --- /dev/null +++ b/src/commands/voice/loop.js @@ -0,0 +1,34 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class LoopVoice extends Command { + constructor(client) { + super(client, { + name: 'loop', + aliases: ['repeat'], + group: 'voice', + memberName: 'loop', + description: 'Loops currently playing audio.', + guildOnly: true, + examples: ['uwu!loop', 'uwu!repeat'], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg) { + var voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join a channel and try again. ' + emoji.random()); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + msg.channel.send( + `${msg.guild.musicData.nowPlaying.title} added to queue. ` + emoji.random() + ); + msg.guild.musicData.queue.unshift(msg.guild.musicData.nowPlaying); + return; + } +};
\ No newline at end of file diff --git a/src/commands/voice/minecraft.ts b/src/commands/voice/minecraft.ts new file mode 100644 index 0000000..cad7c06 --- /dev/null +++ b/src/commands/voice/minecraft.ts @@ -0,0 +1,204 @@ +import ytdl from 'ytdl-core'; +import { Command } from 'discord.js-commando'; +import { MessageEmbed } from 'discord.js'; +import Youtube from 'simple-youtube-api'; +//const { youtubeAPI } = require('../../config.json'); +import config from '../../config.json'; +const youtube = new Youtube(config['yt-api-key']); +import emoji from 'emoji-random'; + +module.exports = class MinecraftVoice extends Command { + constructor(client) { + super(client, { + name: 'minecraft', + aliases: ['minecraftsountrack', 'minecraft-soundtrack', 'mcs', 'mc-s'], + group: 'voice', + memberName: 'minecraft', + description: 'Plays the Minecraft soundtrack.', + guildOnly: true, + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + examples: [ + 'uwu!minecraft', + 'uwu!minecraftsountrack', + 'uwu!minecraft-soundtrack', + 'uwu!mcs', + 'uwu!mc-s' + ] + }); + } + async run(msg) { + const voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.say('Join a channel and try again. ' + emoji.random()); + + const playlist = await youtube.getPlaylist('https://www.youtube.com/watch?v=05UM-i4PuOY&list=PLxOTV5xn7n1i2HcKtRBthP2loWjrBGAIY').catch(function () { + return msg.say('There was a problem getting the soundtrack. ' + emoji.random()); + }); + // remove the 10 if you removed the queue limit conditions below + const videosObj = await playlist.getVideos(24).catch(function () { + return msg.say( + 'There was a problem getting the soundtrack. ' + emoji.random() + ); + }); + for (let i = 0; i < videosObj.length; i++) { + const video = await videosObj[i].fetch(); + // this can be uncommented if you choose to limit the queue + // if (msg.guild.musicData.queue.length < 10) { + // + msg.guild.musicData.queue.push( + this.constructSongObj(video, voiceChannel) + ); + // } else { + // return msg.say( + // `I can't play the full playlist because there will be more than 10 songs in queue` + // ); + // } + } + if (msg.guild.musicData.isPlaying == false) { + msg.guild.musicData.isPlaying = true; + return this.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + return msg.say( + 'Now playing the Minecraft soundtrack. ' + emoji.random() + ); + } + + var that = this; + msg.channel + .awaitMessages( + function (msg) { + return (msg.content > 0 && msg.content < 6) || msg.content === 'exit'; + }, { + max: 1, + time: 60000, + errors: ['time'] + } + ) + .then(function (response) { + const videoIndex = parseInt(response.first().content); + if (response.first().content === 'exit') return songEmbed.delete(); + youtube + .getVideoByID(videos[videoIndex - 1].id) + .then(function (video) { + // // can be uncommented if you don't want the bot to play live streams + // if (video.raw.snippet.liveBroadcastContent === 'live') { + // songEmbed.delete(); + // return msg.say("I don't support live streams!"); + // } + + // // can be uncommented if you don't want the bot to play videos longer than 1 hour + // if (video.duration.hours !== 0) { + // songEmbed.delete(); + // return msg.say('I cannot play videos longer than 1 hour'); + // } + + // // can be uncommented if you don't want to limit the queue + // if (msg.guild.musicData.queue.length > 10) { + // songEmbed.delete(); + // return msg.say( + // 'There are too many songs in the queue already, skip or wait a bit' + // ); + // } + msg.guild.musicData.queue.push( + that.constructSongObj(video, voiceChannel) + ); + if (msg.guild.musicData.isPlaying == false) { + msg.guild.musicData.isPlaying = true; + if (songEmbed) { + songEmbed.delete(); + } + that.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say('Now playing the Minecraft soundtrack. ' + emoji.random()); + } + }) + .catch(function () { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say( + 'An error has occured when trying to get the video ID from YouTube. ' + emoji.random() + ); + }); + }); + } + playSong(queue, msg) { + const classThis = this; // use classThis instead of 'this' because of lexical scope below + queue[0].voiceChannel + .join() + .then(function (connection) { + const dispatcher = connection + .play( + ytdl(queue[0].url, { + quality: 'highestaudio', + highWaterMark: 1024 * 1024 * 10 + }) + ) + .on('start', function () { + msg.guild.musicData.songDispatcher = dispatcher; + const volume = 100 / 100; + msg.guild.musicData.volume = volume; + dispatcher.setVolume(msg.guild.musicData.volume); + const videoEmbed = new MessageEmbed() + .setThumbnail(queue[0].thumbnail) + .setColor(0xFFCC4D) + .addField('Now Playing:', queue[0].title) + .addField('Duration:', queue[0].duration); + if (queue[1]) videoEmbed.addField('Next Song:', queue[1].title); + msg.say(videoEmbed); + msg.guild.musicData.nowPlaying = queue[0]; + return queue.shift(); + }) + .on('finish', function () { + if (queue.length >= 1) { + return classThis.playSong(queue, msg); + } else { + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + } + }) + .on('error', function (e) { + msg.say('Can\'t play soundtrack. ' + emoji.random()); + console.error(e); + msg.guild.musicData.queue.length = 0; + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + }); + }) + .catch(function (e) { + console.error(e); + return msg.guild.me.voice.channel.leave(); + }); + } + constructSongObj(video, voiceChannel) { + let duration = this.formatDuration(video.duration); + if (duration == '00:00') duration = 'Live Stream'; + return { + url: `https://www.youtube.com/watch?v=${video.raw.id}`, + title: video.title, + duration, + thumbnail: video.thumbnails.high.url, + voiceChannel + }; + } + // prettier-ignore + formatDuration(durationObj) { + const duration = `${durationObj.hours ? (durationObj.hours + ':') : ''}${ + durationObj.minutes ? durationObj.minutes : '00' + }:${ + (durationObj.seconds < 10) + ? ('0' + durationObj.seconds) + : (durationObj.seconds + ? durationObj.seconds + : '00') + }`; + return duration; + } +};
\ No newline at end of file diff --git a/src/commands/voice/pause.js b/src/commands/voice/pause.js new file mode 100644 index 0000000..6ab6fb0 --- /dev/null +++ b/src/commands/voice/pause.js @@ -0,0 +1,32 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class PauseVoice extends Command { + constructor(client) { + super(client, { + name: 'pause', + group: 'voice', + memberName: 'pause', + description: 'Pauses audio of previously playing.', + guildOnly: true, + examples: ['uwu!pause'], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg) { + var voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join a channel and try again. ' + emoji.random()); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + + msg.say('Song paused :pause_button:'); + + msg.guild.musicData.songDispatcher.pause(); + } +};
\ No newline at end of file diff --git a/src/commands/voice/play.ts b/src/commands/voice/play.ts new file mode 100644 index 0000000..61cf5d4 --- /dev/null +++ b/src/commands/voice/play.ts @@ -0,0 +1,292 @@ +import ytdl from 'ytdl-core'; +import { Command } from 'discord.js-commando'; +import { MessageEmbed, Message } from 'discord.js'; +import Youtube from 'simple-youtube-api'; +//const { youtubeAPI } = require('../../config.json'); +import config from '../../config.json'; +const youtube = new Youtube(config['yt-api-key']); +import emoji from 'emoji-random'; + +module.exports = class PlayVoice extends Command { + constructor(client) { + super(client, { + name: 'play', + group: 'voice', + memberName: 'play', + description: 'Play the audio of a YouTube video in a voice channel.', + guildOnly: true, + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + args: [ + { + key: 'query', + prompt: 'What song would you like to hear?', + type: 'string', + validate: function (query) { + return query.length > 0 && query.length < 200; + } + } + ], + examples: [ + 'uwu!play https://www.youtube.com/watch?v=dQw4w9WgXcQ', + 'uwu!play despacito' + ] + }); + } + async run(msg: Message, { query }) { + const voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.say('Please join a channel and try again. ' + emoji.random()); + + if ( + // if the user entered yt playlist url + query.match( + /^(?!.*\?.*\bv=)https:\/\/www\.youtube\.com\/.*\?.*\blist=.*$/ + ) + ) { + const playlist = await youtube.getPlaylist(query).catch(function () { + return msg.say('Playlist is either private or it does not exist. ' + emoji.random()); + }); + // remove the 10 if you removed the queue limit conditions below + const videosObj = await playlist.getVideos(10).catch(function () { + return msg.say( + 'There was a problem getting one or more of the videos in the playlist. ' + emoji.random() + ); + }); + for (let i = 0; i < videosObj.length; i++) { + const video = await videosObj[i].fetch(); + // this can be uncommented if you choose to limit the queue + // if (msg.guild.musicData.queue.length < 10) { + // + msg.guild.musicData.queue.push( + this.constructSongObj(video, voiceChannel) + ); + // } else { + // return msg.say( + // `I can't play the full playlist because there will be more than 10 songs in queue` + // ); + // } + } + if (msg.guild.musicData.isPlaying == false) { + msg.guild.musicData.isPlaying = true; + return this.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + return msg.say( + `Playlist - :musical_note: ${playlist.title} :musical_note: has been added to queue. ` + emoji.random() + ); + } + } + + // This if statement checks if the user entered a youtube url, it can be any kind of youtube url + if (query.match(/^(http(s)?:\/\/)?((w){3}.)?youtu(be|.be)?(\.com)?\/.+/)) { + query = query + .replace(/(>|<)/gi, '') + .split(/(vi\/|v=|\/v\/|youtu\.be\/|\/embed\/)/); + const id = query[2].split(/[^0-9a-z_\-]/i)[0]; + const video = await youtube.getVideoByID(id).catch(function () { + return msg.say( + 'There was a problem getting the video you provided. ' + emoji.random() + ); + }); + // // can be uncommented if you don't want the bot to play live streams + // if (video.raw.snippet.liveBroadcastContent === 'live') { + // return msg.say("I don't support live streams!"); + // } + // // can be uncommented if you don't want the bot to play videos longer than 1 hour + // if (video.duration.hours !== 0) { + // return msg.say('I cannot play videos longer than 1 hour'); + // } + // // can be uncommented if you want to limit the queue + // if (msg.guild.musicData.queue.length > 10) { + // return msg.say( + // 'There are too many songs in the queue already, skip or wait a bit' + // ); + // } + msg.guild.musicData.queue.push( + this.constructSongObj(video, voiceChannel) + ); + if ( + msg.guild.musicData.isPlaying == false || + typeof msg.guild.musicData.isPlaying == 'undefined' + ) { + msg.guild.musicData.isPlaying = true; + return this.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + return msg.say(`${video.title} added to queue. ` + emoji.random()); + } + } + + // if user provided a song/video name + const videos = await youtube.searchVideos(query, 5).catch(function () { + return msg.say( + 'There was a problem searching the video you requested. ' + emoji.random() + ); + }); + if (videos.length < 5) { + return msg.say( + `There was some trouble finding what you were looking for, please try again or be more specific. ` + emoji.random() + ); + } + const vidNameArr = []; + for (let i = 0; i < videos.length; i++) { + vidNameArr.push(`${i + 1}: ${videos[i].title}`); + } + vidNameArr.push('exit'); + const embed = new MessageEmbed() + .setColor(0xFFCC4D) + .setTitle('Please choose a song (1 to 5) ' + emoji.random()) + .addField(``, '**Song #**' + vidNameArr[0]) + .addField(``, '**Song #**' + vidNameArr[1]) + .addField(``, '**Song #**' + vidNameArr[2]) + .addField(``, '**Song #**' + vidNameArr[3]) + .addField(``, '**Song #**' + vidNameArr[4]) + .addField(``, '**Exit selection**: ' + 'exit'); + var songEmbed = await msg.channel.send({ + embed + }); + var that = this; + msg.channel + .awaitMessages( + function (msg) { + return (msg.content > 0 && msg.content < 6) || msg.content === 'exit'; + }, { + max: 1, + time: 60000, + errors: ['time'] + } + ) + .then(function (response) { + const videoIndex = parseInt(response.first().content); + if (response.first().content === 'exit') return songEmbed.delete(); + youtube + .getVideoByID(videos[videoIndex - 1].id) + .then(function (video) { + // // can be uncommented if you don't want the bot to play live streams + // if (video.raw.snippet.liveBroadcastContent === 'live') { + // songEmbed.delete(); + // return msg.say("I don't support live streams!"); + // } + + // // can be uncommented if you don't want the bot to play videos longer than 1 hour + // if (video.duration.hours !== 0) { + // songEmbed.delete(); + // return msg.say('I cannot play videos longer than 1 hour'); + // } + + // // can be uncommented if you don't want to limit the queue + // if (msg.guild.musicData.queue.length > 10) { + // songEmbed.delete(); + // return msg.say( + // 'There are too many songs in the queue already, skip or wait a bit' + // ); + // } + msg.guild.musicData.queue.push( + that.constructSongObj(video, voiceChannel) + ); + if (msg.guild.musicData.isPlaying == false) { + msg.guild.musicData.isPlaying = true; + if (songEmbed) { + songEmbed.delete(); + } + that.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say(`${video.title} added to queue. ` + emoji.random()); + } + }) + .catch(function () { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say( + 'An error has occured when trying to get the video ID from YouTube. ' + emoji.random() + ); + }); + }) + .catch(function () { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say( + 'Try again and enter a number between 1 and 5 or exit. ' + emoji.random() + ); + }); + } + playSong(queue, msg) { + const classThis = this; // use classThis instead of 'this' because of lexical scope below + queue[0].voiceChannel + .join() + .then(function (connection) { + const dispatcher = connection + .play( + ytdl(queue[0].url, { + quality: 'highestaudio', + highWaterMark: 1024 * 1024 * 10 + }) + ) + .on('start', function () { + msg.guild.musicData.songDispatcher = dispatcher; + const volume = 100 / 100; + msg.guild.musicData.volume = volume; + dispatcher.setVolume(msg.guild.musicData.volume); + const videoEmbed = new MessageEmbed() + .setThumbnail(queue[0].thumbnail) + .setColor(0xFFCC4D) + .addField('Now playing:', queue[0].title) + .addField('Duration:', queue[0].duration); + if (queue[1]) videoEmbed.addField('Next song:', queue[1].title); + msg.say(videoEmbed); + msg.guild.musicData.nowPlaying = queue[0]; + return queue.shift(); + }) + .on('finish', function () { + if (queue.length >= 1) { + return classThis.playSong(queue, msg); + } else { + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + } + }) + .on('error', function (e) { + msg.say('Can\'t play song. ' + emoji.random()); + console.error(e); + msg.guild.musicData.queue.length = 0; + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + }); + }) + .catch(function (e) { + console.error(e); + return msg.guild.me.voice.channel.leave(); + }); + } + constructSongObj(video, voiceChannel) { + let duration = this.formatDuration(video.duration); + if (duration == '00:00') duration = 'Live Stream'; + return { + url: `https://www.youtube.com/watch?v=${video.raw.id}`, + title: video.title, + duration, + thumbnail: video.thumbnails.high.url, + voiceChannel + }; + } + // prettier-ignore + formatDuration(durationObj) { + const duration = `${durationObj.hours ? (durationObj.hours + ':') : ''}${ + durationObj.minutes ? durationObj.minutes : '00' + }:${ + (durationObj.seconds < 10) + ? ('0' + durationObj.seconds) + : (durationObj.seconds + ? durationObj.seconds + : '00') + }`; + return duration; + } +};
\ No newline at end of file diff --git a/src/commands/voice/psycho.ts b/src/commands/voice/psycho.ts new file mode 100644 index 0000000..827c00a --- /dev/null +++ b/src/commands/voice/psycho.ts @@ -0,0 +1,198 @@ +import ytdl from 'ytdl-core'; +import { Command } from 'discord.js-commando'; +import { MessageEmbed, Message } from 'discord.js'; +import Youtube from 'simple-youtube-api'; +//const { youtubeAPI } = require('../../config.json'); +import config from '../../config.json'; +const youtube = new Youtube(config['yt-api-key']); +import emoji from 'emoji-random'; + +module.exports = class PsychoVoice extends Command { + constructor(client) { + super(client, { + name: 'psycho', + group: 'voice', + memberName: 'psycho', + description: 'Plays Psycho by Mase.', + guildOnly: true, + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + examples: ['uwu!psycho'] + }); + } + async run(msg: Message, { query }) { + const voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.say('Please join a channel and try again. ' + emoji.random()); + + const id = 'fnd_HSmAODs'; + const video = await youtube.getVideoByID(id).catch(function () { + return msg.say( + 'There was a problem getting the video you provided. ' + emoji.random() + ); + }); + // // can be uncommented if you don't want the bot to play live streams + // if (video.raw.snippet.liveBroadcastContent === 'live') { + // return msg.say("I don't support live streams!"); + // } + // // can be uncommented if you don't want the bot to play videos longer than 1 hour + // if (video.duration.hours !== 0) { + // return msg.say('I cannot play videos longer than 1 hour'); + // } + // // can be uncommented if you want to limit the queue + // if (msg.guild.musicData.queue.length > 10) { + // return msg.say( + // 'There are too many songs in the queue already, skip or wait a bit' + // ); + // } + msg.guild.musicData.queue.push( + this.constructSongObj(video, voiceChannel) + ); + if ( + msg.guild.musicData.isPlaying == false || + typeof msg.guild.musicData.isPlaying == 'undefined' + ) { + msg.guild.musicData.isPlaying = true; + return this.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + return msg.say(`${video.title} added to queue. ` + emoji.random()); + } + + var that = this; + msg.channel + .awaitMessages( + function (msg) { + return (msg.content > 0 && msg.content < 6) || msg.content === 'exit'; + }, { + max: 1, + time: 60000, + errors: ['time'] + } + ) + .then(function (response) { + const videoIndex = parseInt(response.first().content); + if (response.first().content === 'exit') return songEmbed.delete(); + youtube + .getVideoByID(videos[videoIndex - 1].id) + .then(function (video) { + // // can be uncommented if you don't want the bot to play live streams + // if (video.raw.snippet.liveBroadcastContent === 'live') { + // songEmbed.delete(); + // return msg.say("I don't support live streams!"); + // } + + // // can be uncommented if you don't want the bot to play videos longer than 1 hour + // if (video.duration.hours !== 0) { + // songEmbed.delete(); + // return msg.say('I cannot play videos longer than 1 hour'); + // } + + // // can be uncommented if you don't want to limit the queue + // if (msg.guild.musicData.queue.length > 10) { + // songEmbed.delete(); + // return msg.say( + // 'There are too many songs in the queue already, skip or wait a bit' + // ); + // } + msg.guild.musicData.queue.push( + that.constructSongObj(video, voiceChannel) + ); + if (msg.guild.musicData.isPlaying == false) { + msg.guild.musicData.isPlaying = true; + if (songEmbed) { + songEmbed.delete(); + } + that.playSong(msg.guild.musicData.queue, msg); + } else if (msg.guild.musicData.isPlaying == true) { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say(`${video.title} added to queue. ` + emoji.random()); + } + }) + .catch(function () { + if (songEmbed) { + songEmbed.delete(); + } + return msg.say( + 'An error has occured when trying to get the video ID from YouTube. ' + emoji.random() + ); + }); + }); + } + playSong(queue, msg) { + const classThis = this; // use classThis instead of 'this' because of lexical scope below + queue[0].voiceChannel + .join() + .then(function (connection) { + const dispatcher = connection + .play( + ytdl(queue[0].url, { + quality: 'highestaudio', + highWaterMark: 1024 * 1024 * 10 + }) + ) + .on('start', function () { + msg.guild.musicData.songDispatcher = dispatcher; + const volume = 100 / 100; + msg.guild.musicData.volume = volume; + dispatcher.setVolume(msg.guild.musicData.volume); + const videoEmbed = new MessageEmbed() + .setThumbnail(queue[0].thumbnail) + .setColor(0xFFCC4D) + .addField('Now playing:', queue[0].title) + .addField('Duration:', queue[0].duration); + if (queue[1]) videoEmbed.addField('Next song:', queue[1].title); + msg.say(videoEmbed); + msg.guild.musicData.nowPlaying = queue[0]; + return queue.shift(); + }) + .on('finish', function () { + if (queue.length >= 1) { + return classThis.playSong(queue, msg); + } else { + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + } + }) + .on('error', function (e) { + msg.say('Can\'t play song ' + emoji.random()); + console.error(e); + msg.guild.musicData.queue.length = 0; + msg.guild.musicData.isPlaying = false; + msg.guild.musicData.nowPlaying = null; + msg.guild.musicData.songDispatcher = null; + return msg.guild.me.voice.channel.leave(); + }); + }) + .catch(function (e) { + console.error(e); + return msg.guild.me.voice.channel.leave(); + }); + } + constructSongObj(video, voiceChannel) { + let duration = this.formatDuration(video.duration); + if (duration == '00:00') duration = 'Live Stream'; + return { + url: `https://www.youtube.com/watch?v=${video.raw.id}`, + title: video.title, + duration, + thumbnail: video.thumbnails.high.url, + voiceChannel + }; + } + // prettier-ignore + formatDuration(durationObj) { + const duration = `${durationObj.hours ? (durationObj.hours + ':') : ''}${ + durationObj.minutes ? durationObj.minutes : '00' + }:${ + (durationObj.seconds < 10) + ? ('0' + durationObj.seconds) + : (durationObj.seconds + ? durationObj.seconds + : '00') + }`; + return duration; + } +};
\ No newline at end of file diff --git a/src/commands/voice/queue.js b/src/commands/voice/queue.js new file mode 100644 index 0000000..59fce1a --- /dev/null +++ b/src/commands/voice/queue.js @@ -0,0 +1,51 @@ +const { Command } = require('discord.js-commando'); +const { MessageEmbed } = require('discord.js'); +const emoji = require('emoji-random'); + +module.exports = class QueueVoice extends Command { + constructor(client) { + super(client, { + name: 'queue', + aliases: [ + 'q', + 'song-list', + 'next-songs', + 'songlist', + 'nextsongs', + 'nextsong', + 'next-song' + ], + group: 'voice', + memberName: 'queue', + description: 'Displays the current queue.', + guildOnly: true, + examples: [ + 'uwu!queue', + 'uwu!q', + 'uwu!songlist', + 'uwu!song-list', + 'uwu!nextsong', + 'uwu!next-song', + 'uwu!nextsongs', + 'uwu!next-songs' + ], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg) { + if (msg.guild.musicData.queue.length == 0) + return msg.say('There aren\'t any songs in the current queue. ' + emoji.random()); + const titleArray = []; + msg.guild.musicData.queue.map(obj => { + titleArray.push(obj.title); + }); + let queueEmbed = new MessageEmbed() + .setColor(0xFFCC4D) + .setTitle('Music Queue ' + emoji.random()); + for (let i = 0; i < titleArray.length; i++) { + queueEmbed.addField(``, `**${i + 1}**: ` + `${titleArray[i]}`); + } + return msg.say(queueEmbed); + } +};
\ No newline at end of file diff --git a/src/commands/voice/remove.js b/src/commands/voice/remove.js new file mode 100644 index 0000000..34a30de --- /dev/null +++ b/src/commands/voice/remove.js @@ -0,0 +1,41 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class RemoveVoice extends Command { + constructor(client) { + super(client, { + name: 'remove', + group: 'voice', + memberName: 'remove', + description: 'Removes a song from the current queue.', + guildOnly: true, + args: [ + { + key: 'songNumber', + prompt: 'What song would you like to remove from the current queue?', + type: 'integer' + } + ], + examples: ['uwu!remove 2'], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg, { songNumber }) { + if (songNumber < 1 && songNumber >= msg.guild.musicData.queue.length) { + return msg.reply('Please enter a valid song. ' + emoji.random()); + } + var voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join a channel and try again. ' + emoji.random()); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + + msg.guild.musicData.queue.splice(songNumber - 1, 1); + return msg.say(`Removed song **#${songNumber}** from current queue. ` + emoji.random()); + } +};
\ No newline at end of file diff --git a/src/commands/voice/resume.js b/src/commands/voice/resume.js new file mode 100644 index 0000000..1b28b28 --- /dev/null +++ b/src/commands/voice/resume.js @@ -0,0 +1,32 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class ResumeVoice extends Command { + constructor(client) { + super(client, { + name: 'resume', + group: 'voice', + memberName: 'resume', + description: 'Resumes audio of previously paused.', + guildOnly: true, + examples: ['uwu!resume'], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg) { + var voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join a channel and try again. ') + emoji.random(); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + + msg.say('Song resumed :play_pause:'); + + msg.guild.musicData.songDispatcher.resume(); + } +};
\ No newline at end of file diff --git a/src/commands/voice/shuffle.js b/src/commands/voice/shuffle.js new file mode 100644 index 0000000..3183f87 --- /dev/null +++ b/src/commands/voice/shuffle.js @@ -0,0 +1,53 @@ +const { Command } = require('discord.js-commando'); +const { MessageEmbed } = require('discord.js'); +const emoji = require('emoji-random'); + +module.exports = class ShuffleVoice extends Command { + constructor(client) { + super(client, { + name: 'shuffle', + group: 'voice', + memberName: 'shuffle', + description: 'Shuffles the current queue.', + guildOnly: true, + examples: ['uwu!shuffle'], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg) { + var voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join channel and try again. ' + emoji.random()); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + + if (msg.guild.musicData.queue.length < 1) + return msg.say('There aren\'t any songs in the current queue. ' + emoji.random()); + + shuffleQueue(msg.guild.musicData.queue); + + const titleArray = []; + msg.guild.musicData.queue.map(obj => { + titleArray.push(obj.title); + }); + var queueEmbed = new MessageEmbed() + .setColor(0xF97DAE) + .setTitle('New Music Queue ' + emoji.random()); + for (let i = 0; i < titleArray.length; i++) { + queueEmbed.addField(`${i + 1}:`, `${titleArray[i]}`); + } + return msg.say(queueEmbed); + } +}; + +function shuffleQueue(queue) { + for (let i = queue.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [queue[i], queue[j]] = [queue[j], queue[i]]; + } +}
\ No newline at end of file diff --git a/src/commands/voice/skip.js b/src/commands/voice/skip.js new file mode 100644 index 0000000..8638291 --- /dev/null +++ b/src/commands/voice/skip.js @@ -0,0 +1,29 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class SkipVoice extends Command { + constructor(client) { + super(client, { + name: 'skip', + group: 'voice', + memberName: 'skip', + description: 'Skips one song ahead in the current queue.', + guildOnly: true, + examples: ['uwu!skip'], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg) { + const voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join a channel and try again. ' + emoji.random()); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + msg.guild.musicData.songDispatcher.end(); + } +};
\ No newline at end of file diff --git a/src/commands/voice/skipall.js b/src/commands/voice/skipall.js new file mode 100644 index 0000000..e981f46 --- /dev/null +++ b/src/commands/voice/skipall.js @@ -0,0 +1,44 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class SkipAllVoice extends Command { + constructor(client) { + super(client, { + name: 'skipall', + aliases: [ + 'endqueue', + 'endq', + 'skipqueue', + 'skipq' + ], + group: 'voice', + memberName: 'skipall', + description: 'Removes all the songs from current queue.', + guildOnly: true, + examples: [ + 'uwu!endqueue', + 'uwu!endq', + 'uwu!skipqueue', + 'uwu!skipq' + ], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg) { + var voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join a channel and try again. ' + emoji.random()); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + if (!msg.guild.musicData.queue) + return msg.say('There aren\'t any songs in the current queue. ' + emoji.random()); + msg.guild.musicData.songDispatcher.end(); + msg.guild.musicData.queue.length = 0; // clear queue + return; + } +};
\ No newline at end of file diff --git a/src/commands/voice/skipto.js b/src/commands/voice/skipto.js new file mode 100644 index 0000000..f43d56c --- /dev/null +++ b/src/commands/voice/skipto.js @@ -0,0 +1,43 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class SkipToVoice extends Command { + constructor(client) { + super(client, { + name: 'skipto', + group: 'voice', + memberName: 'skipto', + description: 'Skip to a certain song in the current queue.', + guildOnly: true, + args: [{ + key: 'songNumber', + prompt: 'What song would you like to skip to in the current queue?', + type: 'integer' + }], + examples: ['uwu!skipto 5'], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg, { songNumber }) { + if (songNumber < 1 && songNumber >= msg.guild.musicData.queue.length) { + return msg.reply('Please enter a valid song. ' + emoji.random()); + } + var voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join channel and try again. ' + emoji.random()); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + + if (msg.guild.musicData.queue < 1) + return msg.reply('There aren\'t any songs in the current queue. ' + emoji.random()); + + msg.guild.musicData.queue.splice(0, songNumber - 1); + msg.guild.musicData.songDispatcher.end(); + return; + } +};
\ No newline at end of file diff --git a/src/commands/voice/volume.js b/src/commands/voice/volume.js new file mode 100644 index 0000000..96a6de3 --- /dev/null +++ b/src/commands/voice/volume.js @@ -0,0 +1,45 @@ +const { Command } = require('discord.js-commando'); +const emoji = require('emoji-random'); + +module.exports = class VolumeVoice extends Command { + constructor(client) { + super(client, { + name: 'volume', + aliases: ['vol'], + group: 'voice', + memberName: 'volume', + description: 'Changes volume of any currentaly playing audio.', + guildOnly: true, + args: [ + { + key: 'wantedVol', + prompt: 'What would volume you like? (1 to 200)', + type: 'integer', + validate: wantedVol => wantedVol >= 1 && wantedVol <= 200 + } + ], + examples: [ + 'uwu!volume 20', + 'uwu!vol 50' + ], + clientPermissions: ['SPEAK', 'CONNECT', 'SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + userPermissions: ['SEND_MESSAGES', 'READ_MESSAGE_HISTORY'], + }); + } + run(msg, { wantedVol }) { + var voiceChannel = msg.member.voice.channel; + if (!voiceChannel) return msg.reply('Please join a channel and try again. ' + emoji.random()); + + if ( + typeof msg.guild.musicData.songDispatcher == 'undefined' || + msg.guild.musicData.songDispatcher == null + ) { + return msg.reply('There isn\'t any audio playing right now. ' + emoji.random()); + } + + const volume = wantedVol / 100; + msg.guild.musicData.volume = volume; + msg.guild.musicData.songDispatcher.setVolume(volume); + msg.reply(`Volume is now: **${wantedVol}%**. ` + emoji.random()); + } +};
\ No newline at end of file |