diff --git a/assets/json/filters.json b/assets/json/filters.json deleted file mode 100644 index 31367264..00000000 --- a/assets/json/filters.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "bassboost": "Bassboost", - "8D": "8D", - "vaporwave": "Vaporwave", - "nightcore": "Nightcore", - "phaser": "Phaser", - "tremolo": "Tremolo", - "vibrato": "Vibrato", - "reverse": "Reverse", - "treble": "Treble", - "normalizer": "Normalizer", - "surrounding": "Surrounding", - "pulsator": "Pulsator", - "superequalizer": "Superequalizer" -} \ No newline at end of file diff --git a/assets/json/partners.json b/assets/json/partners.json deleted file mode 100644 index 761943ac..00000000 --- a/assets/json/partners.json +++ /dev/null @@ -1,8 +0,0 @@ -[ - { - "name": "", - "description_french": "", - "description_english": "", - "link": "" - } -] \ No newline at end of file diff --git a/base/JaBa.js b/base/JaBa.js index 8f5f01ad..16e76a3d 100644 --- a/base/JaBa.js +++ b/base/JaBa.js @@ -1,11 +1,13 @@ const { MessageEmbed, Util, Client, Collection } = require("discord.js"), { GiveawaysManager } = require("discord-giveaways"), - { Player } = require("discord-player"), + { SoundCloudPlugin } = require("@distube/soundcloud"), + { SpotifyPlugin } = require("@distube/spotify"), { Client: Joker } = require("blague.xyz"); const util = require("util"), AmeClient = require("amethyste-api"), path = require("path"), + DisTube = require("distube"), moment = require("moment"); moment.relativeTimeThreshold("s", 60); @@ -47,91 +49,47 @@ class JaBa extends Client { if (this.config.apiKeys.amethyste) this.AmeAPI = new AmeClient(this.config.apiKeys.amethyste); if (this.config.apiKeys.blagueXYZ) this.joker = new Joker(this.config.apiKeys.blagueXYZ, { defaultLanguage: "en" }); - this.player = new Player(this, { - ytdlDownloadOptions: { - filter: "audio", - requestOptions: { - headers: { - cookie: this.config.youtubeToken, - quality: "highestaudio", - highWaterMark: 1 << 25 - } - } - }, - leaveOnEmpty: false, - enableLive: true + this.player = new DisTube.default(this, { + searchSongs: 10, + searchCooldown: 30, + leaveOnEmpty: true, + emptyCooldown: 0, + leaveOnFinish: true, + leaveOnStop: true, + nsfw: true, + plugins: [ new SoundCloudPlugin(), new SpotifyPlugin() ], }); this.player - .on("trackStart", (message, track) => { - message.success("music/play:NOW_PLAYING", { songName: track.title }); - }) - .on("playlistStart", (message, queue, playlist, track) => { - message.channel.send(`${this.customEmojis.success} ${message.translate("music/play:PLAYING_PLAYLIST", { playlistTitle: playlist.title, playlistEmoji: this.customEmojis.playlist, songName: track.title })}`); - }) - .on("searchResults", (message, query, tracks) => { - if (tracks.length > 10) tracks = tracks.slice(0, 10); + .on("playSong", (queue, song) => queue.textChannel.send(this.translate("music/play:NOW_PLAYING", { songName: song.name }))) + .on("addSong", (queue, song) => queue.textChannel.send(this.translate("music/play:ADDED_QUEUE", { songName: song.name }))) + .on("addList", (queue, playlist) => queue.textChannel.send(this.translate("music/play:ADDED_QUEUE_COUNT", { songCount: playlist.songs.length }))) + .on("searchResult", (message, result) => { + let i = 0 const embed = new MessageEmbed() - .setDescription(Util.escapeSpoiler(tracks.map((t, i) => `**${++i} -** ${t.title}`).join("\n"))) - .setFooter(message.translate("music/play:RESULTS_FOOTER")) + .setDescription(Util.escapeSpoiler(result.map(song => `**${++i} -** ${song.name}`).join("\n"))) + .setFooter(this.translate("music/play:RESULTS_FOOTER")) .setColor(this.config.embed.color); message.channel.send(embed); }) - .on("searchInvalidResponse", (message, query, tracks, content, collector) => { - if (content === "cancel") { + .on("searchDone", () => {}) + .on("searchCancel", message => message.error("misc:TIMES_UP")) + .on("searchInvalidAnswer", message => { + if (message.content === "cancel") { collector.stop(); - return message.success("music/play:RESULTS_CANCEL"); }; message.error("misc:INVALID_NUMBER_RANGE", { min: 1, max: tracks.length }); }) - .on("searchCancel", (message) => { - message.error("misc:TIMES_UP"); + .on("searchNoResult", message => message.error("music/play:NO_RESULT")) + .on("error", (textChannel, e) => { + console.error(e); + textChannel.send(this.translate("music/play:ERR_OCCURRED", { error: e.slice(0, 1900)})); }) - .on("botDisconnect", (message) => { - message.error("music/play:STOP_DISCONNECTED"); - }) - .on("noResults", (message) => { - message.error("music/play:NO_RESULT"); - }) - .on("queueEnd", (message) => { - message.success("music/play:QUEUE_ENDED"); - }) - .on("playlistAdd", (message, queue, playlist) => { - message.success("music/play:ADDED_QUEUE_COUNT", { songCount: playlist.items.length }); - }) - .on("trackAdd", (message, queue, track) => { - message.success("music/play:ADDED_QUEUE", { songName: track.title }); - }) - .on("channelEmpty", () => { - // do nothing, leaveOnEmpty is not enabled - }) - .on("error", (error, message) => { - switch (error) { - case "NotConnected": - message.error("music/play:NO_VOICE_CHANNEL"); - break; - - case "UnableToJoin": - message.error("music/play:VOICE_CHANNEL_CONNECT"); - break; - - case "NotPlaying": - message.error("music/play:NOT_PLAYING"); - break; - - case "LiveVideo": - message.error("music/play:LIVE_VIDEO"); - break; - - default: - message.error("music/play:ERR_OCCURRED", { - error - }); - break; - }; - }); + .on("finish", queue => queue.textChannel.send(this.translate("music/play:QUEUE_ENDED"))) + .on("disconnect", queue => queue.textChannel.send(this.translate("music/play:STOP_DISCONNECTED"))) + .on("empty", queue => queue.textChannel.send(this.translate("music/play:STOP_EMPTY"))); this.giveawaysManager = new GiveawaysManager(this, { storage: "./giveaways.json", @@ -146,7 +104,7 @@ class JaBa extends Client { }; get defaultLanguage() { - return this.languages.find((language) => language.default).name; + return this.languages.find(language => language.default).name; }; translate(key, args, locale) { diff --git a/commands/Music/autoplay.js b/commands/Music/autoplay.js index f1c08db1..ea80407b 100644 --- a/commands/Music/autoplay.js +++ b/commands/Music/autoplay.js @@ -17,17 +17,15 @@ class AutoPlay extends Command { } async run (message) { - const queue = this.client.player.getQueue(message); const voice = message.member.voice.channel; + const queue = this.client.player.getQueue(message); if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!queue) return message.error("music/play:NOT_PLAYING"); - // Gets the current song - await this.client.player.setAutoPlay(message, !queue.autoPlay); + const autoplay = queue.toggleAutoplay() - // Send the embed in the current channel - message.success(`music/autoplay:SUCCESS_${queue.autoPlay ? "ENABLED" : "DISABLED"}`); + message.success(`music/autoplay:SUCCESS_${autoplay ? "ENABLED" : "DISABLED"}`); } }; diff --git a/commands/Music/back.js b/commands/Music/back.js index 17f93aad..3c8ca2f1 100644 --- a/commands/Music/back.js +++ b/commands/Music/back.js @@ -18,14 +18,12 @@ class Back extends Command { } async run (message, args, data) { - const queue = this.client.player.getQueue(message); const voice = message.member.voice.channel; + const queue = this.client.player.getQueue(message); if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!queue) return message.error("music/play:NOT_PLAYING"); - if (!queue.previousTracks[0]) return message.error("music/back:NO_PREV_SONG"); - - const members = voice.members.filter((m) => !m.user.bot); + if (!queue.previousSongs[0]) return message.error("music/back:NO_PREV_SONG"); const embed = new Discord.MessageEmbed() .setAuthor(message.translate("music/back:DESCRIPTION")) @@ -35,51 +33,9 @@ class Back extends Command { const m = await message.channel.send(embed); - if (args[0] && (args[0] === "force" || args[0] === "f")) { - if (message.member.hasPermission("ADMINISTRATOR") || message.member.hasPermission("MANAGE_MESSAGES")) { - this.client.player.back(message); - embed.setDescription(message.translate("music/back:SUCCESS")); - m.edit(embed); - } else message.error("misc:NO_PERMS"); - } else if (members.size > 1) { - m.react("👍"); - - const mustVote = Math.floor(members.size / 2); - - embed.setDescription(message.translate("music/back:VOTE_CONTENT", { songName: queue.tracks[0].name, voteCount: 0, requiredCount: mustVote })); - m.edit(embed); - - const filter = (reaction, user) => { - const member = message.guild.members.cache.get(user.id); - const voiceChannel = member.voice.channel; - if (voiceChannel) return voiceChannel.id === voice.id; - }; - - const collector = await m.createReactionCollector(filter, { - time: 25000 - }); - - collector.on("collect", (reaction) => { - const haveVoted = reaction.count - 1; - if (haveVoted >= mustVote) { - this.client.player.back(message); - embed.setDescription(message.translate("music/back:SUCCESS")); - m.edit(embed); - collector.stop(true); - } else { - embed.setDescription(message.translate("music/back:VOTE_CONTENT", { songName: queue.tracks[0].title, voteCount: haveVoted, requiredCount: mustVote })); - m.edit(embed); - } - }); - - collector.on("end", (collected, isDone) => { - if (!isDone) return message.error("misc:TIMES_UP"); - }); - } else { - this.client.player.back(message); - embed.setDescription(message.translate("music/back:SUCCESS")); - m.edit(embed); - }; + this.client.player.previous(message); + embed.setDescription(message.translate("music/back:SUCCESS")); + m.edit(embed); } }; diff --git a/commands/Music/clip.js b/commands/Music/clip.js index 07d8b5a0..cfece0a1 100644 --- a/commands/Music/clip.js +++ b/commands/Music/clip.js @@ -20,17 +20,18 @@ class Clip extends Command { async run (message, args) { const voice = message.member.voice.channel; const queue = this.client.player.getQueue(message); + const clip = args[0]; - if (!args[0]) return message.error("music/clip:NO_ARG"); - if (!fs.existsSync(`./clips/${args[0]}.mp3`)) return message.error("music/clip:NO_FILE", { file: args[0] }); if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (queue) return message.error("music/clip:ACTIVE_QUEUE"); + if (!clip) return message.error("music/clip:NO_ARG"); + if (!fs.existsSync(`./clips/${clip}.mp3`)) return message.error("music/clip:NO_FILE", { file: clip }); try { const connection = await voice.join(); await connection.voice.setSelfDeaf(true); - connection.play(`./clips/${args[0]}.mp3`) + connection.play(`./clips/${clip}.mp3`) .on("finish", () => { voice.leave(); }) diff --git a/commands/Music/filter.js b/commands/Music/filter.js index 489ffe2e..e714a85c 100644 --- a/commands/Music/filter.js +++ b/commands/Music/filter.js @@ -1,5 +1,4 @@ -const Command = require("../../base/Command.js"), - FiltersList = require("../../assets/json/filters.json"); +const Command = require("../../base/Command.js") class Filter extends Command { constructor (client) { @@ -18,27 +17,22 @@ class Filter extends Command { } async run (message, args, data) { + const voice = message.member.voice.channel; const queue = this.client.player.getQueue(message); - const voice = message.member.voice.channel; if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!queue) return message.error("music/play:NOT_PLAYING"); const filter = args[0]; if (!filter) return message.error("music/filter:MISSING_FILTER", { prefix: data.guild.prefix }); - const filterToUpdate = Object.values(FiltersList).find((f) => f.toLowerCase() === filter.toLowerCase()); - - if (!filterToUpdate) return message.error("music/filter:UNKNOWN_FILTER", { prefix: data.guild.prefix }); - - const filterRealName = Object.keys(FiltersList).find((f) => FiltersList[f] === filterToUpdate); - const queueFilters = this.client.player.getQueue(message).filters; - const filtersUpdated = {}; - filtersUpdated[filterRealName] = queueFilters[filterRealName] ? false : true; - this.client.player.setFilters(message, filtersUpdated); - - if (filtersUpdated[filterRealName]) message.success("music/filter:ADDING_FILTER"); - else message.success("music/filter:REMOVING_FILTER"); + if (filter === "off" && queue.filters?.length) { + queue.setFilter(false); + message.success("music/filter:REMOVING_FILTER"); + } else if (Object.keys(this.client.player.filters).includes(args[0])) { + queue.setFilter(args[0]); + message.success("music/filter:ADDING_FILTER"); + } else if (args[0]) return message.error("music/filter:UNKNOWN_FILTER", { prefix: data.guild.prefix }); } }; diff --git a/commands/Music/filters.js b/commands/Music/filters.js index 41624424..5b229dd5 100644 --- a/commands/Music/filters.js +++ b/commands/Music/filters.js @@ -1,6 +1,5 @@ const Command = require("../../base/Command.js"), - Discord = require("discord.js"), - FiltersList = require("../../assets/json/filters.json"); + Discord = require("discord.js"); class Filters extends Command { constructor (client) { @@ -19,17 +18,17 @@ class Filters extends Command { } async run (message, args, data) { - const queue = this.client.player.getQueue(message); const voice = message.member.voice.channel; + const queue = this.client.player.getQueue(message); if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!queue) return message.error("music/play:NOT_PLAYING"); const filtersStatuses = [ [], [] ]; - Object.keys(FiltersList).forEach((filterName) => { + Object.keys(this.client.player.filters).forEach((filterName) => { const array = filtersStatuses[0].length > filtersStatuses[1].length ? filtersStatuses[1] : filtersStatuses[0]; - array.push(FiltersList[filterName] + " : " + (this.client.player.getQueue(message).filters[filterName] ? this.client.customEmojis.success : this.client.customEmojis.error)); + array.push(FiltersList[filterName] + " : " + (queue.filters[filterName] ? this.client.customEmojis.success : this.client.customEmojis.error)); }); const list = new Discord.MessageEmbed() diff --git a/commands/Music/jump.js b/commands/Music/jump.js new file mode 100644 index 00000000..5fb39a77 --- /dev/null +++ b/commands/Music/jump.js @@ -0,0 +1,43 @@ +const Command = require("../../base/Command.js"), + Discord = require("discord.js"); + +class Jump extends Command { + constructor (client) { + super(client, { + name: "jump", + dirname: __dirname, + enabled: true, + guildOnly: true, + aliases: [], + memberPermissions: [], + botPermissions: [ "SEND_MESSAGES", "EMBED_LINKS" ], + nsfw: false, + ownerOnly: false, + cooldown: 3000 + }); + } + + async run (message, args, data) { + const queue = this.client.player.getQueue(message); + const voice = message.member.voice.channel; + const number = parseInt(args[0]); + + if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); + if (!queue) return message.error("music/play:NOT_PLAYING"); + if (number < 0) return message.error("music/jump:NO_PREV_SONG", { prefix: data.guild.prefix }); + + const embed = new Discord.MessageEmbed() + .setAuthor(message.translate("music/jump:SUCCESS")) + .setThumbnail(queue.songs[number].thumbnail) + .setFooter(data.config.embed.footer) + .setColor(data.config.embed.color); + + const m = await message.channel.send(embed); + + this.client.player.jump(message, number); + embed.setDescription(message.translate("music/play:NOW_PLAYING", { songName: queue.songs[number].name })); + m.edit(embed); + } +}; + +module.exports = Jump; \ No newline at end of file diff --git a/commands/Music/loop.js b/commands/Music/loop.js index 717b53cb..1439bd17 100644 --- a/commands/Music/loop.js +++ b/commands/Music/loop.js @@ -12,7 +12,7 @@ class Loop extends Command { botPermissions: [ "SEND_MESSAGES" ], nsfw: false, ownerOnly: false, - cooldown: 3000 + cooldown: 1000 }); } @@ -20,21 +20,12 @@ class Loop extends Command { const voice = message.member.voice.channel; const queue = this.client.player.getQueue(message); - if (!args[0] || !["queue", "song"].includes(args[0])) return message.error("music/loop:NO_ARG"); if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!queue) return message.error("music/play:NOT_PLAYING"); - if (args[0].toLowerCase() === "queue") { - if (queue.repeatMode) this.client.player.setRepeatMode(message, false); + const mode = this.client.player.setRepeatMode(message); - this.client.player.setLoopMode(message, !queue.loopMode); - message.success(`music/loop:QUEUE_SUCCESS_${queue.loopMode ? "ENABLED" : "DISABLED"}`) - } else if (args[0].toLowerCase() === "song") { - if (queue.loopMode) this.client.player.setLoopMode(message, false); - - this.client.player.setRepeatMode(message, !queue.repeatMode); - message.success(`music/loop:SONG_SUCCESS_${queue.repeatMode ? "ENABLED" : "DISABLED"}`); - }; + message.success(`music/loop:${mode ? mode === 2 ? "QUEUE" : "SONG" : "DISABLED"}`) } }; diff --git a/commands/Music/np.js b/commands/Music/np.js index c9f588f1..1af7f0c1 100644 --- a/commands/Music/np.js +++ b/commands/Music/np.js @@ -18,28 +18,25 @@ class Np extends Command { } async run (message, args, data) { + const voice = message.member.voice.channel; const queue = this.client.player.getQueue(message); - const voice = message.member.voice.channel; if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); - if (!queue) return message.error("music/play:NOT_PLAYING"); // Gets the current song - const track = await this.client.player.nowPlaying(message); + const track = queue.songs[0]; // Generate discord embed to display song informations const embed = new Discord.MessageEmbed() - .setAuthor(message.translate("music/np:CURRENTLY_PLAYING")) + .setAuthor(message.translate("music/queue:TITLE")) .setThumbnail(track.thumbnail) - .addField(message.translate("music/np:T_TITLE"), track.title, true) - .addField(message.translate("music/np:T_CHANNEL"), track.author, true) - .addField(message.translate("music/np:T_DURATION"), message.convertTime(Date.now()+track.durationMS, "to", true), true) - .addField(message.translate("music/np:T_DESCRIPTION"), track.description ? (track.description.substring(0, 150) + "\n" + (message.translate("common:AND_MORE").toLowerCase())) : message.translate("music/np:NO_DESCRIPTION"), true) - .addField("\u200B", this.client.player.createProgressBar(message, { timecodes: true })) - .setTimestamp() + .addField(message.translate("music/np:T_TITLE"), track.name + `\n${track.url}`) + .addField(message.translate("music/np:T_CHANNEL"), track.uploader.name) + .addField(message.translate("music/np:T_DURATION"), message.convertTime(Date.now() + track.duration * 1000, "to", true)) .setColor(data.config.embed.color) - .setFooter(data.config.embed.footer); + .setFooter(data.config.embed.footer) + .setTimestamp(); // Send the embed in the current channel message.channel.send(embed); diff --git a/commands/Music/pause.js b/commands/Music/pause.js index 98aea16a..5db4ebef 100644 --- a/commands/Music/pause.js +++ b/commands/Music/pause.js @@ -17,16 +17,14 @@ class Pause extends Command { } async run (message) { + const voice = message.member.voice.channel; const queue = this.client.player.getQueue(message); - const voice = message.member.voice.channel; if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!queue) return message.error("music:play:NOT_PLAYING"); - // Gets the current song await this.client.player.pause(message); - // Send the embed in the current channel message.sendT("music/pause:SUCCESS"); } }; diff --git a/commands/Music/queue.js b/commands/Music/queue.js index 8bd2b0e9..5f311c31 100644 --- a/commands/Music/queue.js +++ b/commands/Music/queue.js @@ -20,19 +20,19 @@ class Queue extends Command { async run (message, args, data) { const voice = message.member.voice.channel; - if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); - const queue = this.client.player.getQueue(message); + if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!queue) return message.error("music/play:NOT_PLAYING"); - if (queue.tracks.length === 1) { + if (queue.songs.length === 1) { const embed = new Discord.MessageEmbed() - .setColor(data.config.embed.color) .setAuthor(message.translate("music/queue:TITLE"), message.guild.iconURL({ dynamic: true })) - .addField(message.translate("music/np:CURRENTLY_PLAYING"), `[${queue.tracks[0].title}](${queue.tracks[0].url})\n*Requested by ${queue.tracks[0].requestedBy}*\n`); + .addField(message.translate("music/np:CURRENTLY_PLAYING"), `[${queue.songs[0].name}](${queue.songs[0].url})\n*Добавил ${queue.songs[0].member}*\n`) + .setColor(data.config.embed.color); return message.channel.send(embed); }; + let i = 0; const FieldsEmbed = new Pagination.FieldsEmbed(); @@ -40,14 +40,14 @@ class Queue extends Command { FieldsEmbed.embed .setColor(data.config.embed.color) .setAuthor(message.translate("music/queue:TITLE"), message.guild.iconURL({ dynamic: true })) - .addField(message.translate("music/np:CURRENTLY_PLAYING"), `[${queue.tracks[0].title}](${queue.tracks[0].url})\n*Requested by ${queue.tracks[0].requestedBy}*\n`); + .addField(message.translate("music/np:CURRENTLY_PLAYING"), `[${queue.songs[0].name}](${queue.songs[0].url})\n*Добавил ${queue.songs[0].member}*\n`); - FieldsEmbed.setArray(queue.tracks[1] ? queue.tracks.slice(1, queue.tracks.length) : []) + FieldsEmbed.setArray(queue.songs[1] ? queue.songs.slice(1, queue.songs.length) : []) .setAuthorizedUsers([message.author.id]) .setChannel(message.channel) .setElementsPerPage(5) .setPageIndicator(true) - .formatField("Queue", (track) => `${++i}. [${track.title}](${track.url})\n*Requested by ${track.requestedBy}*\n`); + .formatField("Очередь", (track) => `${++i}. [${track.name}](${track.url})\n*Добавил ${track.member}*\n`); FieldsEmbed.build(); } diff --git a/commands/Music/resume.js b/commands/Music/resume.js index b5f548b4..d04519a0 100644 --- a/commands/Music/resume.js +++ b/commands/Music/resume.js @@ -17,16 +17,14 @@ class Resume extends Command { } async run (message) { + const voice = message.member.voice.channel; const queue = this.client.player.getQueue(message); - const voice = message.member.voice.channel; if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!queue) return message.error("music:play:NOT_PLAYING"); - // Gets the current song await this.client.player.resume(message); - // Send the embed in the current channel message.sendT("music/resume:SUCCESS"); } }; diff --git a/commands/Music/seek.js b/commands/Music/seek.js index c0b6ddcc..c9d30bcb 100644 --- a/commands/Music/seek.js +++ b/commands/Music/seek.js @@ -18,20 +18,17 @@ class Seek extends Command { } async run (message, args) { + const voice = message.member.voice.channel; const queue = this.client.player.getQueue(message); - const voice = message.member.voice.channel; if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); - if (!queue) return message.error("music/play:NOT_PLAYING"); const time = ms(args[0]); if (isNaN(time)) return message.error("music/seek:INVALID_TIME"); - // Change the song position - await this.client.player.setPosition(message, queue.currentStreamTime + time); + await this.client.player.seek(message, time); - // Send the embed in the current channel message.sendT("music/seek:SUCCESS"); } }; diff --git a/commands/Music/skip.js b/commands/Music/skip.js index aa11c758..f584ff47 100644 --- a/commands/Music/skip.js +++ b/commands/Music/skip.js @@ -18,69 +18,24 @@ class Skip extends Command { } async run (message, args, data) { - const queue = this.client.player.getQueue(message); const voice = message.member.voice.channel; + const queue = this.client.player.getQueue(message); if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!queue) return message.error("music/play:NOT_PLAYING"); - if (!queue.tracks[0]) return message.error("music/skip:NO_NEXT_SONG"); - - const members = voice.members.filter((m) => !m.user.bot); + if (!queue.songs[1]) return message.error("music/skip:NO_NEXT_SONG"); const embed = new Discord.MessageEmbed() - .setAuthor(message.translate("music/skip:DESCRIPTION")) - .setThumbnail(queue.tracks[0].thumbnail) + .setAuthor(message.translate("music/skip:SUCCESS")) + .setThumbnail(queue.songs[1].thumbnail) .setFooter(data.config.embed.footer) .setColor(data.config.embed.color); const m = await message.channel.send(embed); - if (args[0] && (args[0] === "force" || args[0] === "f")) { - if (message.member.hasPermission("ADMINISTRATOR") || message.member.hasPermission("MANAGE_MESSAGES")) { - this.client.player.skip(message); - embed.setDescription(message.translate("music/skip:SUCCESS")); - m.edit(embed); - } else message.error("misc:NO_PERMS"); - } else if (members.size > 1) { - m.react("👍"); - - const mustVote = Math.floor(members.size / 2); - - embed.setDescription(message.translate("music/skip:VOTE_CONTENT", { songName: queue.tracks[0].name, voteCount: 0, requiredCount: mustVote })); - m.edit(embed); - - const filter = (reaction, user) => { - const member = message.guild.members.cache.get(user.id); - const voiceChannel = member.voice.channel; - if (voiceChannel) return voiceChannel.id === voice.id; - }; - - const collector = await m.createReactionCollector(filter, { - time: 25000 - }); - - collector.on("collect", (reaction) => { - const haveVoted = reaction.count - 1; - if (haveVoted >= mustVote) { - this.client.player.skip(message); - embed.setDescription(message.translate("music/skip:SUCCESS")); - m.edit(embed); - collector.stop(true); - } else { - embed.setDescription(message.translate("music/skip:VOTE_CONTENT", { songName: queue.tracks[0].title, voteCount: haveVoted, requiredCount: mustVote })); - m.edit(embed); - }; - }); - - collector.on("end", (collected, isDone) => { - if (!isDone) return message.error("misc:TIMES_UP"); - }); - - } else { - this.client.player.skip(message); - embed.setDescription(message.translate("music/skip:SUCCESS")); - m.edit(embed); - }; + this.client.player.skip(message); + embed.setDescription(message.translate("music/play:NOW_PLAYING", { songName: queue.songs[1].name })); + m.edit(embed); } }; diff --git a/commands/Music/stop.js b/commands/Music/stop.js index 73bae081..86dc75fb 100644 --- a/commands/Music/stop.js +++ b/commands/Music/stop.js @@ -18,14 +18,12 @@ class Stop extends Command { } async run (message, args, data) { - const queue = await this.client.player.getQueue(message); const voice = message.member.voice.channel; + const queue = await this.client.player.getQueue(message); if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!queue) return message.error("music/play:NOT_PLAYING"); - const members = voice.members.filter((m) => !m.user.bot); - const embed = new Discord.MessageEmbed() .setAuthor(message.translate("music/stop:DESCRIPTION")) .setFooter(data.config.embed.footer) @@ -33,52 +31,9 @@ class Stop extends Command { const m = await message.channel.send(embed); - if (args[0] && (args[0] === "force" || args[0] === "f")) { - if (message.member.hasPermission("ADMINISTRATOR") || message.member.hasPermission("MANAGE_MESSAGES")) { - this.client.player.stop(message); - embed.setDescription(message.translate("music/stop:SUCCESS")); - m.edit(embed); - } else message.error("misc:NO_PERMS"); - } else if (members.size > 1) { - m.react("👍"); - - const mustVote = Math.floor(members.size / 2); - - embed.setDescription(message.translate("music/stop:VOTE_CONTENT", { voteCount: 0, requiredCount: mustVote })); - m.edit(embed); - - const filter = (reaction, user) => { - const member = message.guild.members.cache.get(user.id); - const voiceChannel = member.voice.channel; - if (voiceChannel) return voiceChannel.id === voice.id; - }; - - const collector = await m.createReactionCollector(filter, { - time: 25000 - }); - - collector.on("collect", (reaction) => { - const haveVoted = reaction.count - 1; - if (haveVoted >= mustVote) { - this.client.player.stop(message); - embed.setDescription(message.translate("music/stop:SUCCESS")); - m.edit(embed); - collector.stop(true); - } else { - embed.setDescription(message.translate("music/stop:VOTE_CONTENT", { voteCount: haveVoted, requiredCount: mustVote })); - m.edit(embed); - } - }); - - collector.on("end", (collected, isDone) => { - if (!isDone) return message.error("misc:TIMES_UP"); - }); - - } else { - this.client.player.stop(message); - embed.setDescription(message.translate("music/stop:SUCCESS")); - m.edit(embed); - }; + this.client.player.stop(message); + embed.setDescription(message.translate("music/stop:SUCCESS")); + m.edit(embed); } }; diff --git a/languages/en-US/music/back.json b/languages/en-US/music/back.json index e465b37f..186d7c47 100644 --- a/languages/en-US/music/back.json +++ b/languages/en-US/music/back.json @@ -3,6 +3,5 @@ "USAGE": "{{prefix}}back", "EXAMPLES": "{{prefix}}back", "NO_PREV_SONG": "There was no song before this one!", - "VOTE_CONTENT": "Previous song: {{songName}}\nReact with 👍 to play the previous song! {{requiredCount}} more votes are required.", "SUCCESS": "Playing previous song!" } \ No newline at end of file diff --git a/languages/en-US/music/filter.json b/languages/en-US/music/filter.json index 619e1434..945cbb57 100644 --- a/languages/en-US/music/filter.json +++ b/languages/en-US/music/filter.json @@ -4,6 +4,6 @@ "EXAMPLES": "{{prefix}}filter vaporwave", "MISSING_FILTER": "Please specify a valid filter to enable or disable! (or send `{{prefix}}filters` to get the statuses of the filters)", "UNKNOWN_FILTER": "This filter doesn't exist! Send `{{prefix}}filters` to get the list!", - "ADDING_FILTER": "I'm adding the filter to the music, please wait... Note: the shorter the music, the faster it will be.", - "REMOVING_FILTER": "I'm removing the filter to the music, please wait... Note: the shorter the music, the faster it will be." + "ADDING_FILTER": "I'm adding the filter to the music, please wait...", + "REMOVING_FILTER": "I'm removing the filter to the music, please wait..." } \ No newline at end of file diff --git a/languages/en-US/music/jump.json b/languages/en-US/music/jump.json new file mode 100644 index 00000000..473c6733 --- /dev/null +++ b/languages/en-US/music/jump.json @@ -0,0 +1,7 @@ +{ + "DESCRIPTION": "Jump to the given track in the queue", + "USAGE": "{{prefix}}jump [number]", + "EXAMPLES": "{{prefix}}jump 3", + "NO_PREV_SONG": "You can't go back, use `{{prefix}}back`!", + "SUCCESS": "Playing selected track!" +} \ No newline at end of file diff --git a/languages/en-US/music/loop.json b/languages/en-US/music/loop.json index 43e9a074..2367d15e 100644 --- a/languages/en-US/music/loop.json +++ b/languages/en-US/music/loop.json @@ -1,8 +1,9 @@ { - "DESCRIPTION": "Turn on/off loop of queue/single track!", + "DESCRIPTION": "Turn on/off repeat of queue/current track!", "USAGE": "{{prefix}}loop [queue/song]", "EXAMPLES": "{{prefix}}loop queue\n{{prefix}}loop song", "NO_ARG": "Select: `queue` or `song`!", - "QUEUE": "Repeating queue is **{{loop}}**!", - "SONG": "Repeating current track is **{{loop}}**!" + "QUEUE": "Repeat of queue is **enabled**!", + "SONG": "Repeat of current track is **enabled**!", + "DISABLED": "Repeat now **disabled**!" } \ No newline at end of file diff --git a/languages/en-US/music/np.json b/languages/en-US/music/np.json index 75f20670..38cb7fc5 100644 --- a/languages/en-US/music/np.json +++ b/languages/en-US/music/np.json @@ -7,5 +7,5 @@ "T_CHANNEL": "Channel", "T_DURATION": "Duration", "T_DESCRIPTION": "Description", - "NO_DESCRIPTION": "No description..." + "NO_DESCRIPTION": "No description" } \ No newline at end of file diff --git a/languages/en-US/music/play.json b/languages/en-US/music/play.json index 28c9f1a5..ac48e871 100644 --- a/languages/en-US/music/play.json +++ b/languages/en-US/music/play.json @@ -12,10 +12,11 @@ "CANCELLED": "Selection cancelled", "NOT_PLAYING": "No songs are currently playing in this server.", "QUEUE_ENDED": "Queue has ended. No more music to play...", - "ADDED_QUEUE": "{{songName}} has been added to the queue!", - "ADDED_QUEUE_COUNT": "{{songCount}} songs added to the queue!", + "ADDED_QUEUE": "**{{songName}}** has been added to the queue!", + "ADDED_QUEUE_COUNT": "**{{songCount}}** songs added to the queue!", "STOP_DISCONNECTED": "I've just stopped the music as I have been disconnected from the channel.", + "STOP_EMPTY": "I've just stopped the music as everyone disconnected from the channel.", "RESULTS_CANCEL": "Search cancelled!", "LIVE_VIDEO": "Lives are not yet supported!", "ERR_OCCURRED": "An error occurred... Code: `{{error}}`" -} +} \ No newline at end of file diff --git a/languages/en-US/music/skip.json b/languages/en-US/music/skip.json index b7cbd824..7a368095 100644 --- a/languages/en-US/music/skip.json +++ b/languages/en-US/music/skip.json @@ -3,6 +3,5 @@ "USAGE": "{{prefix}}skip", "EXAMPLES": "{{prefix}}skip", "NO_NEXT_SONG": "There's no song after this one!", - "VOTE_CONTENT": "Next song: {{songName}}\nReact with 👍 to skip the music! {{requiredCount}} more votes are required.", "SUCCESS": "Song skipped!" } \ No newline at end of file diff --git a/languages/ru-RU/music/back.json b/languages/ru-RU/music/back.json index 59df716b..37a77dc1 100644 --- a/languages/ru-RU/music/back.json +++ b/languages/ru-RU/music/back.json @@ -3,6 +3,5 @@ "USAGE": "{{prefix}}back", "EXAMPLES": "{{prefix}}back", "NO_PREV_SONG": "Предыдущий трек отсутствует!", - "VOTE_CONTENT": "Предыдущий трек: {{songName}}\nОтреагируйте 👍, чтобы проголосовать за воспроизведение! Необходимо ещё {{requiredCount}} голосов.", "SUCCESS": "Играет предыдущий трек!" } \ No newline at end of file diff --git a/languages/ru-RU/music/filter.json b/languages/ru-RU/music/filter.json index 3c30a122..45cfc0ec 100644 --- a/languages/ru-RU/music/filter.json +++ b/languages/ru-RU/music/filter.json @@ -4,6 +4,6 @@ "EXAMPLES": "{{prefix}}filter vaporwave", "MISSING_FILTER": "Укажите фильтр для его включения или отключения! (или отправьте `{{prefix}}filters`, чтобы увидеть статусы фильтров)", "UNKNOWN_FILTER": "Данный фильтр не существует! Используйте `{{prefix}}filters`, чтобы увидеть список фильтров!", - "ADDING_FILTER": "Добавляю фильтр, пожалуйста подождите... Примечание: чем короче трек, тем быстрее это будет выполнено.", - "REMOVING_FILTER": "Удаляю фильтр, пожалуйста подождите... Примечание: чем короче трек, тем быстрее это будет выполнено." + "ADDING_FILTER": "Добавляю фильтр, пожалуйста подождите...", + "REMOVING_FILTER": "Удаляю фильтр, пожалуйста подождите..." } \ No newline at end of file diff --git a/languages/ru-RU/music/jump.json b/languages/ru-RU/music/jump.json new file mode 100644 index 00000000..b46e2708 --- /dev/null +++ b/languages/ru-RU/music/jump.json @@ -0,0 +1,7 @@ +{ + "DESCRIPTION": "Перейти на данный трек", + "USAGE": "{{prefix}}jump [номер-трека]", + "EXAMPLES": "{{prefix}}jump 3", + "NO_PREV_SONG": "Вы не можете перейти назад, для этого используйте команду `{{prefix}}back`!", + "SUCCESS": "Играет выбранный трек!" +} \ No newline at end of file diff --git a/languages/ru-RU/music/loop.json b/languages/ru-RU/music/loop.json index e85eccd9..76c005ef 100644 --- a/languages/ru-RU/music/loop.json +++ b/languages/ru-RU/music/loop.json @@ -3,8 +3,7 @@ "USAGE": "{{prefix}}loop [queue/song]", "EXAMPLES": "{{prefix}}loop queue\n{{prefix}}loop song", "NO_ARG": "Выберите: `queue` или `song`!", - "QUEUE_SUCCESS_ENABLED": "{{success}} Повтор очереди включён!", - "QUEUE_SUCCESS_DISABLED": "{{success}} Повтор очереди отключён!", - "SONG_SUCCESS_ENABLED" : "{{success}} Повтор текущего трека включён!", - "SONG_SUCCESS_DISABLED" : "{{success}} Повтор текущего трека отключён!" + "QUEUE": "Повтор очереди **включён**!", + "SONG": "Повтор текущего трека **включён**!", + "DISABLED": "Повтор **отключён**!" } \ No newline at end of file diff --git a/languages/ru-RU/music/np.json b/languages/ru-RU/music/np.json index 087a52a3..856f4363 100644 --- a/languages/ru-RU/music/np.json +++ b/languages/ru-RU/music/np.json @@ -7,5 +7,5 @@ "T_CHANNEL": "Канал", "T_DURATION": "Длительность", "T_DESCRIPTION": "Описание", - "NO_DESCRIPTION": "Нет описание..." + "NO_DESCRIPTION": "Описание отсутствует" } \ No newline at end of file diff --git a/languages/ru-RU/music/play.json b/languages/ru-RU/music/play.json index 4da155e1..400f285a 100644 --- a/languages/ru-RU/music/play.json +++ b/languages/ru-RU/music/play.json @@ -12,9 +12,10 @@ "CANCELLED": "Выбор отменён", "NOT_PLAYING": "На сервере сейчас ничего не воспроизводится.", "QUEUE_ENDED": "Очередь окончена.", - "ADDED_QUEUE": "{{songName}} добавлен в очередь!", - "ADDED_QUEUE_COUNT": "{{songCount}} трек(а/ов) добавлено в очередь!", + "ADDED_QUEUE": "**{songName}}** добавлен в очередь!", + "ADDED_QUEUE_COUNT": "**{{songCount}}** трек(а/ов) добавлено в очередь!", "STOP_DISCONNECTED": "Воспроизведение окончено, т.к. я вышел из голосового канала.", + "STOP_EMPTY": "Воспроизведение окончено, т.к. все вышли из голосового канала.", "RESULTS_CANCEL": "Поиск отменён!", "LIVE_VIDEO": "Прямые трансляции не поддерживаются!", "ERR_OCCURRED": "Произошла ошибка... Код ошибки: `{{error}}`" diff --git a/languages/ru-RU/music/skip.json b/languages/ru-RU/music/skip.json index e4853f43..8ce5a355 100644 --- a/languages/ru-RU/music/skip.json +++ b/languages/ru-RU/music/skip.json @@ -3,6 +3,5 @@ "USAGE": "{{prefix}}skip", "EXAMPLES": "{{prefix}}skip", "NO_NEXT_SONG": "После текущего трека больше нет треков!", - "VOTE_CONTENT": "Следующий трек: {{songName}}\nОтреагируйте 👍, чтобы проголосовать за пропуск трека! Необходимо ещё {{requiredCount}} голосов.", "SUCCESS": "Трек пропущен!" } \ No newline at end of file diff --git a/package.json b/package.json index eaf725ef..2787db8a 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "jaba", - "version": "3.0.5", - "description": "A very complete Discord bot (more than 130 commands) that uses the Discord.js", + "version": "3.0.6", + "description": "A very complete Discord bot (more than 100 commands) that uses the Discord.js", "main": "index.js", "private": true, "scripts": { @@ -13,8 +13,9 @@ "author": "Jonny_Bro", "license": "ISC", "dependencies": { - "@discord-player/extractor": "^3.0.0", "@discordjs/opus": "^0.5.0", + "@distube/soundcloud": "^1.0.0", + "@distube/spotify": "^1.0.0", "@k3rn31p4nic/google-translate-api": "github:k3rn31p4nic/google-translate-api", "@sentry/node": "6.3.6", "@sindresorhus/slugify": "^1.1.0", @@ -32,9 +33,9 @@ "discord-canvas": "^1.3.2", "discord-giveaways": "^4.4.3", "discord-paginationembed": "^2.1.0", - "discord-player": "^4.1.4", "discord-together": "^1.3.25", "discord.js": "^12.5.3", + "distube": "^3.0.4", "ejs": "^3.1.3", "express": "^4.17.1", "express-session": "^1.17.0",