From 2623e3d22167caac621972baa7308df74f8141e1 Mon Sep 17 00:00:00 2001 From: Sudhan <55418697+SudhanPlayz@users.noreply.github.com> Date: Thu, 6 May 2021 09:08:32 +0530 Subject: [PATCH] Development (#183) (#184) * Update index.js (#178) * Handle error LavaLink not connect (#180) * Delete .replit * Handle error node not connect .. * Handle error lavalink not connect * Create .replit * Master branch to development (#171) * Latest commits to fix stuff (#169) * 24/7 Stay in vc stuff * edits and fixes (#168) Co-authored-by: Joseph <71621973+joeyk710@users.noreply.github.com> * ;-; (#170) * 24/7 Stay in vc stuff * edits and fixes (#168) * add: YouTube Tutorial at readme Co-authored-by: Joseph <71621973+joeyk710@users.noreply.github.com> Co-authored-by: Joseph <71621973+joeyk710@users.noreply.github.com> * edits and some fixes, but not all * split loop and loopqueue to make it simpler * Fixed single Spotify track "no matches" error * Small edits Co-authored-by: A cute Blob <77403361+A-cute-blob@users.noreply.github.com> Co-authored-by: ColonelOU <67454598+Colonel-Ltd@users.noreply.github.com> Co-authored-by: Sudhan <55418697+SudhanPlayz@users.noreply.github.com> Co-authored-by: Joseph <71621973+joeyk710@users.noreply.github.com> Co-authored-by: A cute Blob <77403361+A-cute-blob@users.noreply.github.com> Co-authored-by: ColonelOU <67454598+Colonel-Ltd@users.noreply.github.com> --- commands/clear.js | 2 +- commands/config.js | 2 +- commands/grab.js | 80 ++++++++++++++++++ commands/leave.js | 2 +- commands/loop.js | 189 ++++++++++++------------------------------ commands/loopqueue.js | 62 ++++++++++++++ commands/lyrics.js | 4 +- commands/pause.js | 4 +- commands/play.js | 21 ++--- commands/resume.js | 2 +- commands/search.js | 2 - commands/seek.js | 2 +- commands/shuffle.js | 2 +- commands/skip.js | 2 +- events/message.js | 2 +- util/pagination.js | 14 +--- 16 files changed, 219 insertions(+), 173 deletions(-) create mode 100644 commands/grab.js create mode 100644 commands/loopqueue.js diff --git a/commands/clear.js b/commands/clear.js index cd2bff722..db454fa78 100644 --- a/commands/clear.js +++ b/commands/clear.js @@ -2,7 +2,7 @@ const { MessageEmbed } = require("discord.js"); module.exports = { name: "clear", - description: "To clear the queue in this server", + description: "Clears the server queue", usage: "", permissions: { channel: ["VIEW_CHANNEL", "SEND_MESSAGES", "EMBED_LINKS"], diff --git a/commands/config.js b/commands/config.js index 23fe391f7..6d6b967f2 100644 --- a/commands/config.js +++ b/commands/config.js @@ -2,7 +2,7 @@ const { MessageEmbed, MessageReaction } = require("discord.js"); module.exports = { name: "config", - description: "To setup server settings", + description: "Edit the bot settings", usage: "", permissions: { channel: ["VIEW_CHANNEL", "SEND_MESSAGES", "EMBED_LINKS"], diff --git a/commands/grab.js b/commands/grab.js new file mode 100644 index 000000000..7963d98bf --- /dev/null +++ b/commands/grab.js @@ -0,0 +1,80 @@ +const { MessageEmbed } = require("discord.js"); +const prettyMilliseconds = require("pretty-ms"); + +module.exports = { + name: "grab", + description: "Saves the current playing song to your Direct Messages", + usage: "", + permissions: { + channel: ["VIEW_CHANNEL", "SEND_MESSAGES", "EMBED_LINKS"], + member: [], + }, + aliases: ["save"], +/** +* +* @param {import("../structures/DiscordMusicBot")} client +* @param {import("discord.js").Message} message +* @param {string[]} args +* @param {*} param3 +*/ +run: async (client, message, args, { GuildDB }) => { + let player = await client.Manager.get(message.guild.id); + if (!player) return client.sendTime(message.channel, "❌ | **Nothing is playing right now...**"); + message.author.send(new MessageEmbed() + .setAuthor(`Saved Song:`, client.user.displayAvatarURL({ + dynamic: true + })) + .setThumbnail(`https://img.youtube.com/vi/${player.queue.current.identifier}/mqdefault.jpg`) + .setURL(player.queue.current.uri) + .setColor("RANDOM") + .setTitle(`**${player.queue.current.title}**`) + .addField(`⌛ Duration: `, `\`${prettyMilliseconds(player.queue.current.duration, {colonNotation: true})}\``, true) + .addField(`đŸŽĩ Author: `, `\`${player.queue.current.author}\``, true) + .addField(`â–ļ Play it:`, `\`${GuildDB ? GuildDB.prefix : client.config.DefaultPrefix + }play ${player.queue.current.uri}\``) + .addField(`🔎 Saved in:`, `<#${message.channel.id}>`) + .setFooter(`Requested by: ${player.queue.current.requester.tag} | Guild: ${message.guild.name}`, player.queue.current.requester.displayAvatarURL({ + dynamic: true + })) + ).catch(e=>{ + return message.channel.send("**:x: Your Dm's are disabled**") + }) + + message.react("✅").catch(e=>console.log("Could not react")) + }, + SlashCommand: { +/** +* +* @param {import("../structures/DiscordMusicBot")} client +* @param {import("discord.js").Message} message +* @param {string[]} args +* @param {*} param3 +*/ + run: async (client, interaction, args, { GuildDB }) => { + let player = await client.Manager.get(interaction.guild_id); + if (!player) return client.sendTime(interaction, "❌ | **Nothing is playing right now...**"); + try{ + let embed = new MessageEmbed() + .setAuthor(`Saved from `, interaction.guild.name, client.user.displayAvatarURL()) + .setThumbnail(`https://img.youtube.com/vi/${player.queue.current.identifier}/mqdefault.jpg`) + .setURL(player.queue.current.uri) + .setColor("RANDOM") + .setTimestamp() + .setTitle(`**${player.queue.current.title}**`) + .addField(`⌛ Duration: `, `\`${prettyMilliseconds(player.queue.current.duration, {colonNotation: true})}\``, true) + .addField(`đŸŽĩ Author: `, `\`${player.queue.current.author}\``, true) + .addField(`â–ļ Play it:`, `\`${GuildDB ? GuildDB.prefix : client.config.DefaultPrefix + }play ${player.queue.current.uri}\``) + .addField(`🔎 Saved in:`, `<#${interaction.channel_id}>`) + .setFooter(`Requested by: ${player.queue.current.requester.tag} | Guild: ${interaction.guild.name}`, player.queue.current.requester.displayAvatarURL({ + dynamic: true + })) + interaction.send(embed); + }catch(e) { + return client.sendTime(interaction, "**:x: Your DM's are disabled**") + } + + interaction.react("✅").catch(e => console.log("Could not react")) + }, + }, +}; \ No newline at end of file diff --git a/commands/leave.js b/commands/leave.js index 414641450..d8794d622 100644 --- a/commands/leave.js +++ b/commands/leave.js @@ -2,7 +2,7 @@ const { MessageEmbed } = require("discord.js"); module.exports = { name: "leave", - description: "To leave the voice channel", + description: "Disconnecting the bot from the voice channel", usage: "", permissions: { channel: ["VIEW_CHANNEL", "SEND_MESSAGES", "EMBED_LINKS"], diff --git a/commands/loop.js b/commands/loop.js index 825b8e5a2..5844196e3 100644 --- a/commands/loop.js +++ b/commands/loop.js @@ -2,141 +2,60 @@ const { MessageEmbed } = require("discord.js"); const { TrackUtils } = require("erela.js"); module.exports = { - name: "loop", - description: "To loop the current song/queue", - usage: "", - permissions: { - channel: ["VIEW_CHANNEL", "SEND_MESSAGES", "EMBED_LINKS"], - member: [], - }, - aliases: ["l", "repeat"], - /** - * - * @param {import("../structures/DiscordMusicBot")} client - * @param {import("discord.js").Message} message - * @param {string[]} args - * @param {*} param3 - */ - run: async (client, message, args, { GuildDB }) => { - let player = await client.Manager.get(message.guild.id); - if (!player) return client.sendTime(message.channel, "❌ | **Nothing is playing right now...**"); - let Config = new MessageEmbed() - .setAuthor("Server Config", client.config.IconURL) - .setColor("GREEN") - .addField("Song loop", player.trackRepeat?"✅":"❌", true) - .addField("Queue loop", player.queueRepeat?"✅":"❌", true) - .setFooter("React to your choice below.") - .setDescription(` -What do you want to loop? + name: "loop", + description: "Loop the current song", + usage: "", + permissions: { + channel: ["VIEW_CHANNEL", "SEND_MESSAGES", "EMBED_LINKS"], + member: [], + }, + aliases: ["l", "repeat"], + /** + * + * @param {import("../structures/DiscordMusicBot")} client + * @param {import("discord.js").Message} message + * @param {string[]} args + * @param {*} param3 + */ + run: async (client, message, args, { GuildDB }) => { + let player = await client.Manager.get(message.guild.id); + if (!player) return client.sendTime(message.channel, "❌ | **Nothing is playing right now...**"); + if (!message.member.voice.channel) return client.sendTime(message.channel, "❌ | **You must be in a voice channel to play something!**"); + //else if(message.guild.me.voice && message.guild.me.voice.channel.id !== message.member.voice.channel.id)return client.sendTime(message.channel, `❌ | **You must be in ${guild.me.voice.channel} to use this command.**`); -:one: - **Song Loop** (This will loop the current song) -:two: - **Queue Loop** (This will loop the whole queue) -`); - - let LoopingMessage = await message.channel.send(Config); - await LoopingMessage.react("1ī¸âƒŖ"); - await LoopingMessage.react("2ī¸âƒŖ"); - let emoji = await LoopingMessage.awaitReactions( - (reaction, user) => - user.id === message.author.id && - ["1ī¸âƒŖ", "2ī¸âƒŖ"].includes(reaction.emoji.name), - { max: 1, errors: ["time"], time: 30000 } - ).catch(() => { - LoopingMessage.reactions.removeAll(); - Config.setDescription( - "You took too long to respond. Run the command again !" - ); - Config.setFooter("") - LoopingMessage.edit(Config); - }); - emoji = emoji.first(); - /**@type {MessageReaction} */ - let em = emoji; - LoopingMessage.reactions.removeAll(); - let config = new MessageEmbed() - - if (em._emoji.name === "1ī¸âƒŖ") { - if(player.trackRepeat){ - player.setTrackRepeat(false) - config.setAuthor("Server Config", client.config.IconURL) - config.setColor("GREEN") - config.setDescription("**Loop** \`disabled\`") - config.addField("Song loop", player.trackRepeat?"✅":"❌", true) - config.addField("Queue loop", player.queueRepeat?"✅":"❌", true) - config.setTimestamp(); - LoopingMessage.edit(config); - }else if (em._emoji.name === "1ī¸âƒŖ") { - player.setTrackRepeat(true) - config.setAuthor("Server Config", client.config.IconURL) - config.setColor("GREEN") - config.setDescription("**Loop** \`enabled\`") - config.addField("Song loop", player.trackRepeat?"✅":"❌", true) - config.addField("Queue loop", player.queueRepeat?"✅":"❌", true) - config.setTimestamp(); - LoopingMessage.edit(config); + if (player.trackRepeat) { + player.setTrackRepeat(false) + client.sendTime(message.channel, `Loop \`disabled\``); + } else { + player.setTrackRepeat(true) + client.sendTime(message.channel, `Loop \`enabled\``); } - } if (em._emoji.name === "2ī¸âƒŖ") { - if(player.queueRepeat){ - player.setQueueRepeat(false) - config.setAuthor("Server Config", client.config.IconURL) - config.setColor("GREEN") - config.setDescription("**Queue loop** \`disabled\`") - config.addField("Song loop", player.trackRepeat?"✅":"❌", true) - config.addField("Queue loop", player.queueRepeat?"✅":"❌", true) - config.setTimestamp(); - LoopingMessage.edit(config); - }else if (em._emoji.name === "2ī¸âƒŖ"){ - player.setQueueRepeat(true) - config.setAuthor("Server Config", client.config.IconURL) - config.setColor("GREEN") - config.setDescription("**Queue loop** \`enabled\`") - config.addField("Song loop", player.trackRepeat?"✅":"❌", true) - config.addField("Queue loop", player.queueRepeat?"✅":"❌", true) - config.setTimestamp(); - LoopingMessage.edit(config); - } - } - }, + }, + SlashCommand: { + /** + * + * @param {import("../structures/DiscordMusicBot")} client + * @param {import("discord.js").Message} message + * @param {string[]} args + * @param {*} param3 + */ + run: async (client, interaction, args, { GuildDB }) => { + const guild = client.guilds.cache.get(interaction.guild_id); + const member = guild.members.cache.get(interaction.member.user.id); + const voiceChannel = member.voice.channel; + let player = await client.Manager.get(interaction.guild_id); + if (!player) return client.sendTime(interaction, "❌ | **Nothing is playing right now...**"); + if (!member.voice.channel) return interaction.send("❌ | You must be on a voice channel."); + if (guild.me.voice.channel && !guild.me.voice.channel.equals(member.voice.channel)) return interaction.send(`❌ | You must be on ${guild.me.voice.channel} to use this command.`); - SlashCommand: { - options: [ - { - name: "Song", - value: "song", - type: 1, - description: "Loops the song" - }, - { - name: "Queue", - value: "queue", - type: 2, - description: "Loops the queue" - } - ], - - run: async (client, interaction, args, { GuildDB }) => { - let player = await client.Manager.get(interaction.guild_id); - if (!player) return interaction.send("Nothing is playing right now..."); - let loop = (args.value); - if (loop === "song") { - if(player.trackRepeat){ - player.setTrackRepeat(false) - interaction.send("Loop disabled") - }else{ - player.setTrackRepeat(true) - interaction.send("Loop enabled") - } - } else { - if (loop === "queue") { - if(player.queueRepeat){ - player.setQueueRepeat(false) - interaction.send("Queue loop disabled") - }else{ - player.setTrackRepeat(true) - interaction.send("Queue loop enabled") - } - }} - console.log(interaction.data) - } - } -}; + if(player.trackRepeat){ + player.setTrackRepeat(false) + client.sendTime(interaction, `Loop \`disabled\``); + }else{ + player.setTrackRepeat(true) + client.sendTime(interaction, `Loop \`enabled\``); + } + console.log(interaction.data) + } + } +}; \ No newline at end of file diff --git a/commands/loopqueue.js b/commands/loopqueue.js new file mode 100644 index 000000000..d5cdcc82b --- /dev/null +++ b/commands/loopqueue.js @@ -0,0 +1,62 @@ +const { MessageEmbed } = require("discord.js"); +const { TrackUtils } = require("erela.js"); + +module.exports = { + name: "loopqueue", + description: "Loop the whole queue", + usage: "", + permissions: { + channel: ["VIEW_CHANNEL", "SEND_MESSAGES", "EMBED_LINKS"], + member: [], + }, + aliases: ["lq", "repeatqueue", "rq"], + /** + * + * @param {import("../structures/DiscordMusicBot")} client + * @param {import("discord.js").Message} message + * @param {string[]} args + * @param {*} param3 + */ + run: async (client, message, args, { GuildDB }) => { + let player = await client.Manager.get(message.guild.id); + if (!player) return client.sendTime(message.channel, "❌ | **Nothing is playing right now...**"); + if (!message.member.voice.channel) return client.sendTime(message.channel, "❌ | **You must be in a voice channel to play something!**"); + //else if(message.guild.me.voice && message.guild.me.voice.channel.id !== message.member.voice.channel.id)return client.sendTime(message.channel, `❌ | **You must be in ${guild.me.voice.channel} to use this command.**`); + + if (player.QueueRepeat) { + player.setQueueRepeat(false) + client.sendTime(message.channel, `Queue loop \`disabled\``); + } else { + player.setQueueRepeat(true) + client.sendTime(message.channel, `Queue loop \`enabled\``); + } + }, + SlashCommand: { + /** + * + * @param {import("../structures/DiscordMusicBot")} client + * @param {import("discord.js").Message} message + * @param {string[]} args + * @param {*} param3 + */ + run: async (client, interaction, args, { GuildDB }) => { + let player = await client.Manager.get(interaction.guild_id); + const guild = client.guilds.cache.get(interaction.guild_id); + const member = guild.members.cache.get(interaction.member.user.id); + const voiceChannel = member.voice.channel; + let awaitchannel = client.channels.cache.get(interaction.channel_id); /// thanks Reyansh for this idea ;-; + if (!player) return client.sendTime(interaction, "❌ | **Nothing is playing right now...**"); + if (!member.voice.channel) return client.sendTime(interaction, "❌ | **You must be in a voice channel to use this command.**"); + if (guild.me.voice.channel && !guild.me.voice.channel.equals(voiceChannel)) return client.sendTime(interaction, `❌ | **You must be in ${guild.me.voice.channel} to use this command.**`); + + if(player.queueRepeat){ + player.setQueueRepeat(false) + client.sendTime(interaction, `Queue loop \`disabled\``); + }else{ + player.setQueueRepeat(true) + client.sendTime(interaction, `Queue loop \`enabled\``); + } + console.log(interaction.data) + } + } +}; \ No newline at end of file diff --git a/commands/lyrics.js b/commands/lyrics.js index b846db441..fea73ed71 100644 --- a/commands/lyrics.js +++ b/commands/lyrics.js @@ -5,7 +5,7 @@ const _ = require("lodash"); module.exports = { name: "lyrics", - description: "To get and search lyrics of a song", + description: "Search lyrics for any song", usage: "[Song Name]", permissions: { channel: ["VIEW_CHANNEL", "SEND_MESSAGES", "EMBED_LINKS"], @@ -98,4 +98,4 @@ module.exports = { return interaction.send(Pages[0]); } } -} +} \ No newline at end of file diff --git a/commands/pause.js b/commands/pause.js index b21e8c313..0e60ee711 100644 --- a/commands/pause.js +++ b/commands/pause.js @@ -3,7 +3,7 @@ const { TrackUtils } = require("erela.js"); module.exports = { name: "pause", - description: "To pause the current song", + description: "Pauses the music", usage: "", permissions: { channel: ["VIEW_CHANNEL", "SEND_MESSAGES", "EMBED_LINKS"], @@ -22,7 +22,7 @@ module.exports = { if (!player) return client.sendTime(message.channel, "❌ | **Nothing is playing right now...**"); if (!message.member.voice.channel) return client.sendTime(message.channel, "❌ | **You must be in a voice channel to play something!**"); //else if(message.guild.me.voice && message.guild.me.voice.channel.id !== message.member.voice.channel.id)return client.sendTime(message.channel, `❌ | **You must be in ${guild.me.voice.channel} to use this command.**`); - if (player.paused) return message.channel.send("Music is already paused!"); + if (player.paused) return client.sendTime(message.channel, "❌ | **Music is already paused!**"); player.pause(true); let embed = new MessageEmbed().setAuthor(`Paused!`, client.config.IconURL).setColor("RANDOM").setDescription(`Type \`${GuildDB.prefix}resume\` to play!`); await message.channel.send(embed); diff --git a/commands/play.js b/commands/play.js index f64de60ad..0e04ffbb6 100644 --- a/commands/play.js +++ b/commands/play.js @@ -4,7 +4,7 @@ const prettyMilliseconds = require("pretty-ms"); module.exports = { name: "play", - description: "To play music in the voice channel", + description: "Play your favorite songs", usage: "[Song Name|Song URL]", permissions: { channel: ["VIEW_CHANNEL", "SEND_MESSAGES", "EMBED_LINKS"], @@ -53,21 +53,16 @@ module.exports = { player.queue.add(songs); if (!player.playing && !player.paused && player.queue.totalSize === Searched.tracks.length) player.play(); SongAddedEmbed.setAuthor(`Playlist added to queue`, message.author.displayAvatarURL()); - /* - SongAddedEmbed.setDescription( - `[${SearchString.name}](${SearchString})` - ); - */ SongAddedEmbed.addField("Enqueued", `\`${Searched.tracks.length}\` songs`, false); - //SongAddedEmbed.addField("Playlist duration", `\`${prettyMilliseconds(Searched.tracks.duration, { colonNotation: true })}\``, false) + //SongAddedEmbed.addField("Playlist duration", `\`${prettyMilliseconds(Searched.tracks, { colonNotation: true })}\``, false) Searching.edit(SongAddedEmbed); } else if (Searched.loadType.startsWith("TRACK")) { player.queue.add(TrackUtils.build(Searched.tracks[0], message.author)); if (!player.playing && !player.paused && !player.queue.size) player.play(); SongAddedEmbed.setAuthor(`Added to queue`, client.config.IconURL); - SongAddedEmbed.setDescription(`[${Searched.tracks[0].title}](${Searched.tracks[0].uri})`); - SongAddedEmbed.addField("Author", Searched.tracks[0].author, true); - SongAddedEmbed.addField("Duration", `\`${prettyMilliseconds(Searched.tracks[0].duration, { colonNotation: true })}\``, true); + SongAddedEmbed.setDescription(`[${Searched.tracks[0].info.title}](${Searched.tracks[0].info.uri})`); + SongAddedEmbed.addField("Author", Searched.tracks[0].info.author, true); + //SongAddedEmbed.addField("Duration", `\`${prettyMilliseconds(Searched.tracks[0].length, { colonNotation: true })}\``, true); if (player.queue.totalSize > 1) SongAddedEmbed.addField("Position in queue", `${player.queue.size - 0}`, true); Searching.edit(SongAddedEmbed); } else { @@ -193,18 +188,18 @@ module.exports = { case "TRACK_LOADED": player.queue.add(res.tracks[0]); if (!player.playing && !player.paused && !player.queue.length) player.play(); - return interaction.send(`**Added to queue**: \`${res.tracks[0].title}\``); + return client.sendTime(interaction, `**Added to queue** \n[${res.tracks[0].title}](${res.tracks[0].uri})`); case "PLAYLIST_LOADED": player.queue.add(res.tracks); if (!player.playing && !player.paused && player.queue.size === res.tracks.length) player.play(); - return interaction.send(`**Searched playlist**: \n **${res.playlist.name}** : **${res.tracks.length} tracks**`); + return client.sendTime(interaction, `**Searched playlist**: \n **${res.playlist.name}** : **${res.tracks.length} tracks**`); case "SEARCH_RESULT": const track = res.tracks[0]; player.queue.add(track); if (!player.playing && !player.paused && !player.queue.length) { - interaction.send(`**Now playing â™Ē:** \`[${res.tracks[0].title}](${res.tracks[0].uri})\``); + client.sendTime(interaction, `**Added to queue** [${res.tracks[0].title}](${res.tracks[0].uri})`); player.play(); } else { let SongAddedEmbed = new MessageEmbed(); diff --git a/commands/resume.js b/commands/resume.js index 93ed52bf7..ab73bab10 100644 --- a/commands/resume.js +++ b/commands/resume.js @@ -3,7 +3,7 @@ const { TrackUtils } = require("erela.js"); module.exports = { name: "resume", - description: "To resume the current song", + description: "Resumes the music", usage: "", permissions: { channel: ["VIEW_CHANNEL", "SEND_MESSAGES", "EMBED_LINKS"], diff --git a/commands/search.js b/commands/search.js index 674cdd778..ee569715e 100644 --- a/commands/search.js +++ b/commands/search.js @@ -25,8 +25,6 @@ module.exports = { let SearchString = args.join(" "); if (!SearchString) return client.sendTime(message.channel, `**Usage - **\`${GuildDB.prefix}search [Song Name|SongURL]\``); - - let Searching = await message.channel.send(":mag_right: Searching..."); let CheckNode = client.Manager.nodes.get(client.config.Lavalink.id); if (!CheckNode || !CheckNode.connected) { return client.sendTime(message.channel,"❌ | Lavalink node not connected."); diff --git a/commands/seek.js b/commands/seek.js index 15ae55ec8..483c30cc7 100644 --- a/commands/seek.js +++ b/commands/seek.js @@ -3,7 +3,7 @@ const { TrackUtils } = require("erela.js"); module.exports = { name: "seek", - description: "To seek the current song", + description: "Seek to a position in the song", usage: "