diff --git a/package.json b/package.json index 55dcfe58..9d83b638 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "musix", - "version": "3.5.2", + "version": "3.6.0", "description": "V3 for Musix the discord music bot", "main": "./index.js", "scripts": { @@ -37,11 +37,11 @@ "node-spotify-api": "^1.1.1", "prism-media": "github:hydrabolt/prism-media", "request": "^2.88.2", + "similar-songs": "^0.1.3", "simple-youtube-api": "^5.2.1", "soundcloud-api-client": "0.0.9", "spotify-web-api-node": "^4.0.0", "utf-8-validate": "^5.0.2", - "video-thumbnail-url": "^1.0.1", "yt-search": "^1.1.2", "ytdl-core": "^3.1.0", "zlib-sync": "^0.1.6" diff --git a/src/commands/nowplaying.js b/src/commands/nowplaying.js index 2a2b2a00..f19ee741 100644 --- a/src/commands/nowplaying.js +++ b/src/commands/nowplaying.js @@ -7,41 +7,39 @@ module.exports = { permission: "none", category: "music", async execute(msg, args, client, Discord, command) { - const getThumb = require("video-thumbnail-url"); const queue = client.queue.get(msg.guild.id); if (!queue) return msg.channel.send(client.messages.noServerQueue); - let songTime = (queue.songs[0].songLength * 1000).toFixed(0); + let songTime = (queue.songs[0].info.lengthSeconds * 1000).toFixed(0); let completed = ( queue.connection.dispatcher.streamTime + queue.time ).toFixed(0); - let barlength = 20; + let barlength = 30; let completedpercent = ((completed / songTime) * barlength).toFixed(0); let array = []; for (let i = 0; i < completedpercent - 1; i++) { array.push("⎯"); } - array.push("⭗"); + array.push("🔘"); for (let i = 0; i < barlength - completedpercent - 1; i++) { array.push("⎯"); } - const thumbnail = getThumb(queue.songs[0].url); const embed = new Discord.MessageEmbed() .setTitle(client.messages.nowPlaying) .setDescription( `${client.messages.nowPlayingDesc} ${ queue.songs[0].title - }\n${array.join("")} | \`${client.funcs.msToTime( + }\n\`${array.join("")}\`\n\`${client.funcs.msToTime( completed, "hh:mm:ss" - )} / ${client.funcs.msToTime(songTime, "hh:mm:ss")}\`\nchannel: \`${queue.songs[0].channel.name}\`` + )} / ${client.funcs.msToTime(songTime, "hh:mm:ss")}\`\nchannel: \`${queue.songs[0].info.author.name}\`` ) .setFooter(`Queued by ${queue.songs[0].author.tag}`) .setURL(queue.songs[0].url) - .setThumbnail(thumbnail._rejectionHandler0) + .setThumbnail(queue.songs[0].info.thumbnail.thumbnails[4].url) .setColor(client.config.embedColor); if (queue.nigthCore) embed.setDescription( - `${client.messages.nowPlayingDesc} ${queue.songs[0].title} \nchannel: \`${queue.songs[0].channel.name}\`` + `${client.messages.nowPlayingDesc} ${queue.songs[0].title} \nchannel: \`${queue.songs[0].info.author.name}\`` ); return msg.channel.send(embed); }, diff --git a/src/commands/play.js b/src/commands/play.js index ab939df3..2fa8f8ea 100644 --- a/src/commands/play.js +++ b/src/commands/play.js @@ -43,11 +43,9 @@ module.exports = { if (!voiceChannel.speakable) return msg.channel.send(client.messages.noPermsSpeak); if (ytdl.validateURL(url)) { - const resource = { - url: url - } - client.funcs.handleVideo( - resource, + client.funcs.handleVideo({ + url: url + }, msg, voiceChannel, client, @@ -81,8 +79,7 @@ module.exports = { "ytdl" ); } - let message; - message = client.messages.playlistAdded.replace( + const message = client.messages.playlistAdded.replace( "%TITLE%", playlist.title ); diff --git a/src/commands/searchSimilar.js b/src/commands/searchSimilar.js new file mode 100644 index 00000000..5a9bc00c --- /dev/null +++ b/src/commands/searchSimilar.js @@ -0,0 +1,65 @@ +const similarSongs = require("similar-songs"); + +module.exports = { + name: "searchsimilar", + alias: ["none"], + usage: ", ", + description: "a command to search similar songs (in developement)", + onlyDev: false, + permission: "none", + category: "music", + async execute(msg, args, client, Discord, command) { + const searchString = args.slice(1).join(" "); + const query = searchString.split(","); + const queue = client.queue.get(msg.guild.id); + const voiceChannel = msg.member.voice.channel; + if ( + client.global.db.guilds[msg.guild.id].blacklist.includes( + msg.member.voice.channelID + ) + ) + return msg.channel.send(client.messages.blackListedVC); + if (!queue) { + if (!msg.member.voice.channel) + return msg.channel.send(client.messages.noVoiceChannel); + } else { + if (voiceChannel !== queue.voiceChannel) + return msg.channel.send(client.messages.wrongVoiceChannel); + } + if (!query[0] || !query[1]) { + const message = client.messages.searchSimilarUsage.replace("%USAGE%", command.usage); + return msg.channel.send(message); + + } + if (voiceChannel.full) return msg.channel.send(client.messages.channelFull); + if (!voiceChannel.joinable) + return msg.channel.send(client.messages.noPermsConnect); + if (!voiceChannel.speakable) + return msg.channel.send(client.messages.noPermsSpeak); + similarSongs.find({ + title: query[0], + artist: query[1].slice(1), + limit: 10, + lastfmAPIKey: client.config.lastfm_api_key, + lastfmAPISecret: client.config.lastfm_secret, + youtubeAPIKey: client.config.api_key, + }, + async function (err, songs) { + if (err) return msg.channel.send(err.message); + if (songs.length !== 0) { + const lmsg = await msg.channel.send(client.messages.loadingSongs); + for (let i = 0; i < songs.length; i++) { + client.funcs.handleVideo({ + url: `https://www.youtube.com/watch?v=${songs[i].youtubeId}` + }, msg, voiceChannel, client, true, "ytdl"); + } + const message = client.messages.songsAdded.replace( + "%AMOUNT%", + songs.length + ); + return lmsg.edit(message); + } else return msg.channel.send(client.messages.noSimilarResults); + } + ); + }, +}; \ No newline at end of file diff --git a/src/commands/stop.js b/src/commands/stop.js index 0cc50a54..357cd035 100644 --- a/src/commands/stop.js +++ b/src/commands/stop.js @@ -9,11 +9,20 @@ module.exports = { execute(msg, args, client, Discord, command) { const queue = client.queue.get(msg.guild.id); if (client.funcs.check(client, msg, command)) { + if (msg.content.contains("-force")) { + if (queue) { + queue.voiceChannel.leave(); + queue.exists = false; + } + if (msg.guild.voice.channel) msg.guild.voice.channel.leave(); + client.queue.delete(guild.id); + return msg.channel.send(client.messages.stop); + } queue.songs = []; queue.looping = false; queue.endReason = "stop"; queue.connection.dispatcher.end(); - msg.channel.send(client.messages.stop) + msg.channel.send(client.messages.stop); } } }; \ No newline at end of file diff --git a/src/struct/config/config.js b/src/struct/config/config.js index 9552f918..68d702e4 100644 --- a/src/struct/config/config.js +++ b/src/struct/config/config.js @@ -12,6 +12,8 @@ module.exports = { spotify_client_secret: process.env.SPOTIFY_CLIENT_SECRET, spotify_client_id: process.env.SPOTIFY_CLIENT_ID, spotify_refresh_token: process.env.SPOTIFY_REFRESH_TOKEN, + lastfm_api_key: process.env.LASTFM_API_KEY, + lastfm_secret: process.env.LASTFM_SECRET, port: 8888, redirectUri: "http://localhost:8888/callback/", testServer: "489111553321336832", diff --git a/src/struct/config/messages.js b/src/struct/config/messages.js index d68134e4..73fe2626 100644 --- a/src/struct/config/messages.js +++ b/src/struct/config/messages.js @@ -1,6 +1,7 @@ const emojis = require("./emojis.js"); module.exports = { + emojis: emojis, alreadyPaused: emojis.redx + "The music is already paused!", alreadyVoted: emojis.redx + "You have already voted to skip!", announceSongs: emojis.megaPhone + "Current setting:", @@ -100,6 +101,7 @@ module.exports = { noResultsSpotify: emojis.redx + "I could not obtain any results!", noServerQueue: emojis.redx + "There is nothing playing!", + noSimilarResults: emojis.redx + "No similar songs found!", noSongs: emojis.redx + "That song does not exist!", noSongsInQueue: emojis.redx + "There are no songs in the queue!", notPremium: emojis.redx + "This is not a premium guild!", @@ -142,6 +144,7 @@ module.exports = { reset: emojis.green_check_mark + "Reset __all__ guild settings!", restart: "restarting all shards...", resumed: emojis.resume + "Resumed the music!", + searchSimilarUsage: emojis.redx + "Correct usage: %USAGE%", seekingPointPositive: emojis.redx + "The seeking point needs to be a positive number!", seekMax: emojis.redx + "The lenght of this song is %LENGTH% seconds! You can't seek further than that!", @@ -167,6 +170,7 @@ module.exports = { songAdded: emojis.green_check_mark + "**%TITLE%** has been added to the queue!", songBlockedWMG: emojis.redx + "This song had been blocked by WMG (Warner Music Groud).\n<:skip:674685614221688832> Skipped to next song.", + songsAdded: emojis.green_check_mark + "%AMOUNT% songs added to the queue!", songSelection: "__Song Selection__", startPlaying: emojis.notes + "Start playing: ", statusField1: emojis.signal + "Ping", diff --git a/src/struct/funcs/handleVideo.js b/src/struct/funcs/handleVideo.js index 9012f949..8f62451e 100644 --- a/src/struct/funcs/handleVideo.js +++ b/src/struct/funcs/handleVideo.js @@ -14,9 +14,8 @@ module.exports = async function ( title: Discord.Util.escapeMarkdown(songInfo.videoDetails.title), url: resource.url, author: msg.author, - songLength: songInfo.videoDetails.lengthSeconds, type: type, - channel: songInfo.videoDetails.author + info: songInfo.videoDetails }; const queue = client.queue.get(msg.guild.id); diff --git a/src/struct/funcs/play.js b/src/struct/funcs/play.js index 4be3eb07..587d1310 100644 --- a/src/struct/funcs/play.js +++ b/src/struct/funcs/play.js @@ -80,7 +80,7 @@ module.exports = async function (guild, song, client, seek, play) { const embed = new Discord.MessageEmbed() .setTitle(`${client.messages.startPlaying}**${song.title}**`) .setDescription( - `Song duration: \`${client.funcs.msToTime(queue.songs[0].songLength * 1000, "hh:mm:ss")}\`` + `Song duration: \`${client.funcs.msToTime(queue.songs[0].info.lengthSeconds * 1000, "hh:mm:ss")}\`` ) .setColor(client.config.embedColor); queue.textChannel.send(embed);