Merge pull request #1 from JonnyBro:develop

New music system (again)
This commit is contained in:
Jonny_Bro 2021-12-26 13:05:29 +05:00 committed by GitHub
commit e4f2493d65
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
44 changed files with 236 additions and 362 deletions

View file

@ -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"
}

View file

@ -1,8 +0,0 @@
[
{
"name": "",
"description_french": "",
"description_english": "",
"link": ""
}
]

View file

@ -1,11 +1,13 @@
const { MessageEmbed, Util, Client, Collection } = require("discord.js"), const { MessageEmbed, Util, Client, Collection } = require("discord.js"),
{ GiveawaysManager } = require("discord-giveaways"), { GiveawaysManager } = require("discord-giveaways"),
{ Player } = require("discord-player"), { SoundCloudPlugin } = require("@distube/soundcloud"),
{ SpotifyPlugin } = require("@distube/spotify"),
{ Client: Joker } = require("blague.xyz"); { Client: Joker } = require("blague.xyz");
const util = require("util"), const util = require("util"),
AmeClient = require("amethyste-api"), AmeClient = require("amethyste-api"),
path = require("path"), path = require("path"),
DisTube = require("distube"),
moment = require("moment"); moment = require("moment");
moment.relativeTimeThreshold("s", 60); 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.amethyste) this.AmeAPI = new AmeClient(this.config.apiKeys.amethyste);
if (this.config.apiKeys.blagueXYZ) this.joker = new Joker(this.config.apiKeys.blagueXYZ, { defaultLanguage: "en" }); if (this.config.apiKeys.blagueXYZ) this.joker = new Joker(this.config.apiKeys.blagueXYZ, { defaultLanguage: "en" });
this.player = new Player(this, { this.player = new DisTube.default(this, {
ytdlDownloadOptions: { searchSongs: 10,
filter: "audio", searchCooldown: 30,
requestOptions: { leaveOnEmpty: true,
headers: { emptyCooldown: 0,
cookie: this.config.youtubeToken, leaveOnFinish: true,
quality: "highestaudio", leaveOnStop: true,
highWaterMark: 1 << 25 nsfw: true,
} plugins: [ new SoundCloudPlugin(), new SpotifyPlugin() ],
}
},
leaveOnEmpty: false,
enableLive: true
}); });
this.player this.player
.on("trackStart", (message, track) => { .on("playSong", (queue, song) => queue.textChannel.send(this.translate("music/play:NOW_PLAYING", { songName: song.name })))
message.success("music/play:NOW_PLAYING", { songName: track.title }); .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("playlistStart", (message, queue, playlist, track) => { .on("searchResult", (message, result) => {
message.channel.send(`${this.customEmojis.success} ${message.translate("music/play:PLAYING_PLAYLIST", { playlistTitle: playlist.title, playlistEmoji: this.customEmojis.playlist, songName: track.title })}`); let i = 0
})
.on("searchResults", (message, query, tracks) => {
if (tracks.length > 10) tracks = tracks.slice(0, 10);
const embed = new MessageEmbed() const embed = new MessageEmbed()
.setDescription(Util.escapeSpoiler(tracks.map((t, i) => `**${++i} -** ${t.title}`).join("\n"))) .setDescription(Util.escapeSpoiler(result.map(song => `**${++i} -** ${song.name}`).join("\n")))
.setFooter(message.translate("music/play:RESULTS_FOOTER")) .setFooter(this.translate("music/play:RESULTS_FOOTER"))
.setColor(this.config.embed.color); .setColor(this.config.embed.color);
message.channel.send(embed); message.channel.send(embed);
}) })
.on("searchInvalidResponse", (message, query, tracks, content, collector) => { .on("searchDone", () => {})
if (content === "cancel") { .on("searchCancel", message => message.error("misc:TIMES_UP"))
.on("searchInvalidAnswer", message => {
if (message.content === "cancel") {
collector.stop(); collector.stop();
return message.success("music/play:RESULTS_CANCEL"); return message.success("music/play:RESULTS_CANCEL");
}; };
message.error("misc:INVALID_NUMBER_RANGE", { min: 1, max: tracks.length }); message.error("misc:INVALID_NUMBER_RANGE", { min: 1, max: tracks.length });
}) })
.on("searchCancel", (message) => { .on("searchNoResult", message => message.error("music/play:NO_RESULT"))
message.error("misc:TIMES_UP"); .on("error", (textChannel, e) => {
console.error(e);
textChannel.send(this.translate("music/play:ERR_OCCURRED", { error: e.slice(0, 1900)}));
}) })
.on("botDisconnect", (message) => { .on("finish", queue => queue.textChannel.send(this.translate("music/play:QUEUE_ENDED")))
message.error("music/play:STOP_DISCONNECTED"); .on("disconnect", queue => queue.textChannel.send(this.translate("music/play:STOP_DISCONNECTED")))
}) .on("empty", queue => queue.textChannel.send(this.translate("music/play:STOP_EMPTY")));
.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;
};
});
this.giveawaysManager = new GiveawaysManager(this, { this.giveawaysManager = new GiveawaysManager(this, {
storage: "./giveaways.json", storage: "./giveaways.json",
@ -146,7 +104,7 @@ class JaBa extends Client {
}; };
get defaultLanguage() { get defaultLanguage() {
return this.languages.find((language) => language.default).name; return this.languages.find(language => language.default).name;
}; };
translate(key, args, locale) { translate(key, args, locale) {

View file

@ -22,7 +22,7 @@ class Translate extends Command {
async run (message, args, data) { async run (message, args, data) {
if (args[0] === "langs-list") { if (args[0] === "langs-list") {
const langsList = "```css\n" + (langs.map((l, i) => `#${i+1} - ${l}`).join("\n")) + "```"; const langsList = "```css\n" + (langs.map((lang, i) => `${i + 1} - ${lang}`).join("\n")) + "```";
message.author.send(langsList).then(() => { message.author.send(langsList).then(() => {
message.success("general/translate:LIST_SENT"); message.success("general/translate:LIST_SENT");
}).catch(() => { }).catch(() => {
@ -34,8 +34,6 @@ class Translate extends Command {
const pWait = await message.sendT("misc:PLEASE_WAIT", null, { prefixEmoji: "loading" }); const pWait = await message.sendT("misc:PLEASE_WAIT", null, { prefixEmoji: "loading" });
if (!args[0]) return pWait.error("general/translate:MISSING_LANGUAGE", { prefix: data.guild.prefix }, { edit: true }); if (!args[0]) return pWait.error("general/translate:MISSING_LANGUAGE", { prefix: data.guild.prefix }, { edit: true });
if (!args[1]) return pWait.error("general/translate:MISSING_CONTENT", null, { edit: true }); if (!args[1]) return pWait.error("general/translate:MISSING_CONTENT", null, { edit: true });
// Gets different args // Gets different args

View file

@ -57,7 +57,7 @@ class Userinfo extends Command {
}; };
if (member) { if (member) {
embed.addField(this.client.customEmojis.up + " " + message.translate("common:ROLE"), (member.roles.highest ? member.roles.highest : message.translate("general/userinfo:NO_ROLE")), true) embed.addField(this.client.customEmojis.up + " " + message.translate("general/userinfo:ROLE"), (member.roles.highest ? member.roles.highest : message.translate("general/userinfo:NO_ROLE")), true)
embed.addField(this.client.customEmojis.calendar2 + " " + message.translate("common:JOIN"), message.printDate(member.joinedAt),true) embed.addField(this.client.customEmojis.calendar2 + " " + message.translate("common:JOIN"), message.printDate(member.joinedAt),true)
embed.addField(this.client.customEmojis.color + " " + message.translate("common:COLOR"), member.displayHexColor, true) embed.addField(this.client.customEmojis.color + " " + message.translate("common:COLOR"), member.displayHexColor, true)
embed.addField(this.client.customEmojis.pencil + " " + message.translate("common:NICKNAME"), (member.nickname ? member.nickname : message.translate("general/userinfo:NO_NICKNAME")), true) embed.addField(this.client.customEmojis.pencil + " " + message.translate("common:NICKNAME"), (member.nickname ? member.nickname : message.translate("general/userinfo:NO_NICKNAME")), true)

View file

@ -17,17 +17,15 @@ class AutoPlay extends Command {
} }
async run (message) { async run (message) {
const queue = this.client.player.getQueue(message);
const voice = message.member.voice.channel; const voice = message.member.voice.channel;
const queue = this.client.player.getQueue(message);
if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!voice) return message.error("music/play:NO_VOICE_CHANNEL");
if (!queue) return message.error("music/play:NOT_PLAYING"); if (!queue) return message.error("music/play:NOT_PLAYING");
// Gets the current song const autoplay = queue.toggleAutoplay()
await this.client.player.setAutoPlay(message, !queue.autoPlay);
// Send the embed in the current channel message.success(`music/autoplay:SUCCESS_${autoplay ? "ENABLED" : "DISABLED"}`);
message.success(`music/autoplay:SUCCESS_${queue.autoPlay ? "ENABLED" : "DISABLED"}`);
} }
}; };

View file

@ -18,14 +18,12 @@ class Back extends Command {
} }
async run (message, args, data) { async run (message, args, data) {
const queue = this.client.player.getQueue(message);
const voice = message.member.voice.channel; const voice = message.member.voice.channel;
const queue = this.client.player.getQueue(message);
if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!voice) return message.error("music/play:NO_VOICE_CHANNEL");
if (!queue) return message.error("music/play:NOT_PLAYING"); if (!queue) return message.error("music/play:NOT_PLAYING");
if (!queue.previousTracks[0]) return message.error("music/back:NO_PREV_SONG"); if (!queue.previousSongs[0]) return message.error("music/back:NO_PREV_SONG");
const members = voice.members.filter((m) => !m.user.bot);
const embed = new Discord.MessageEmbed() const embed = new Discord.MessageEmbed()
.setAuthor(message.translate("music/back:DESCRIPTION")) .setAuthor(message.translate("music/back:DESCRIPTION"))
@ -35,51 +33,9 @@ class Back extends Command {
const m = await message.channel.send(embed); const m = await message.channel.send(embed);
if (args[0] && (args[0] === "force" || args[0] === "f")) { this.client.player.previous(message);
if (message.member.hasPermission("ADMINISTRATOR") || message.member.hasPermission("MANAGE_MESSAGES")) {
this.client.player.back(message);
embed.setDescription(message.translate("music/back:SUCCESS")); embed.setDescription(message.translate("music/back:SUCCESS"));
m.edit(embed); 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);
};
} }
}; };

View file

@ -20,17 +20,18 @@ class Clip extends Command {
async run (message, args) { async run (message, args) {
const voice = message.member.voice.channel; const voice = message.member.voice.channel;
const queue = this.client.player.getQueue(message); 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 (!voice) return message.error("music/play:NO_VOICE_CHANNEL");
if (queue) return message.error("music/clip:ACTIVE_QUEUE"); 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 { try {
const connection = await voice.join(); const connection = await voice.join();
await connection.voice.setSelfDeaf(true); await connection.voice.setSelfDeaf(true);
connection.play(`./clips/${args[0]}.mp3`) connection.play(`./clips/${clip}.mp3`)
.on("finish", () => { .on("finish", () => {
voice.leave(); voice.leave();
}) })

View file

@ -1,5 +1,4 @@
const Command = require("../../base/Command.js"), const Command = require("../../base/Command.js")
FiltersList = require("../../assets/json/filters.json");
class Filter extends Command { class Filter extends Command {
constructor (client) { constructor (client) {
@ -18,27 +17,22 @@ class Filter extends Command {
} }
async run (message, args, data) { async run (message, args, data) {
const voice = message.member.voice.channel;
const queue = this.client.player.getQueue(message); const queue = this.client.player.getQueue(message);
const voice = message.member.voice.channel;
if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!voice) return message.error("music/play:NO_VOICE_CHANNEL");
if (!queue) return message.error("music/play:NOT_PLAYING"); if (!queue) return message.error("music/play:NOT_PLAYING");
const filter = args[0]; const filter = args[0];
if (!filter) return message.error("music/filter:MISSING_FILTER", { prefix: data.guild.prefix }); 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 (filter === "off" && queue.filters?.length) {
queue.setFilter(false);
if (!filterToUpdate) return message.error("music/filter:UNKNOWN_FILTER", { prefix: data.guild.prefix }); message.success("music/filter:REMOVING_FILTER");
} else if (Object.keys(this.client.player.filters).includes(args[0])) {
const filterRealName = Object.keys(FiltersList).find((f) => FiltersList[f] === filterToUpdate); queue.setFilter(args[0]);
const queueFilters = this.client.player.getQueue(message).filters; message.success("music/filter:ADDING_FILTER");
const filtersUpdated = {}; } else if (args[0]) return message.error("music/filter:UNKNOWN_FILTER", { prefix: data.guild.prefix });
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");
} }
}; };

View file

@ -1,6 +1,5 @@
const Command = require("../../base/Command.js"), const Command = require("../../base/Command.js"),
Discord = require("discord.js"), Discord = require("discord.js");
FiltersList = require("../../assets/json/filters.json");
class Filters extends Command { class Filters extends Command {
constructor (client) { constructor (client) {
@ -19,17 +18,17 @@ class Filters extends Command {
} }
async run (message, args, data) { async run (message, args, data) {
const queue = this.client.player.getQueue(message);
const voice = message.member.voice.channel; const voice = message.member.voice.channel;
const queue = this.client.player.getQueue(message);
if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!voice) return message.error("music/play:NO_VOICE_CHANNEL");
if (!queue) return message.error("music/play:NOT_PLAYING"); if (!queue) return message.error("music/play:NOT_PLAYING");
const filtersStatuses = [ [], [] ]; 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]; 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() const list = new Discord.MessageEmbed()

43
commands/Music/jump.js Normal file
View file

@ -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;

View file

@ -7,12 +7,12 @@ class Loop extends Command {
dirname: __dirname, dirname: __dirname,
enabled: true, enabled: true,
guildOnly: true, guildOnly: true,
aliases: [], aliases: [ "repeat" ],
memberPermissions: [], memberPermissions: [],
botPermissions: [ "SEND_MESSAGES" ], botPermissions: [ "SEND_MESSAGES" ],
nsfw: false, nsfw: false,
ownerOnly: false, ownerOnly: false,
cooldown: 3000 cooldown: 1000
}); });
} }
@ -20,21 +20,12 @@ class Loop extends Command {
const voice = message.member.voice.channel; const voice = message.member.voice.channel;
const queue = this.client.player.getQueue(message); 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 (!voice) return message.error("music/play:NO_VOICE_CHANNEL");
if (!queue) return message.error("music/play:NOT_PLAYING"); if (!queue) return message.error("music/play:NOT_PLAYING");
if (args[0].toLowerCase() === "queue") { const mode = this.client.player.setRepeatMode(message);
if (queue.repeatMode) this.client.player.setRepeatMode(message, false);
this.client.player.setLoopMode(message, !queue.loopMode); message.success(`music/loop:${mode ? mode === 2 ? "QUEUE" : "SONG" : "DISABLED"}`)
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"}`);
};
} }
}; };

View file

@ -18,28 +18,25 @@ class Np extends Command {
} }
async run (message, args, data) { async run (message, args, data) {
const voice = message.member.voice.channel;
const queue = this.client.player.getQueue(message); const queue = this.client.player.getQueue(message);
const voice = message.member.voice.channel;
if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!voice) return message.error("music/play:NO_VOICE_CHANNEL");
if (!queue) return message.error("music/play:NOT_PLAYING"); if (!queue) return message.error("music/play:NOT_PLAYING");
// Gets the current song // Gets the current song
const track = await this.client.player.nowPlaying(message); const track = queue.songs[0];
// Generate discord embed to display song informations // Generate discord embed to display song informations
const embed = new Discord.MessageEmbed() const embed = new Discord.MessageEmbed()
.setAuthor(message.translate("music/np:CURRENTLY_PLAYING")) .setAuthor(message.translate("music/queue:TITLE"))
.setThumbnail(track.thumbnail) .setThumbnail(track.thumbnail)
.addField(message.translate("music/np:T_TITLE"), track.title, true) .addField(message.translate("music/np:T_TITLE"), track.name + `\n${track.url}`)
.addField(message.translate("music/np:T_CHANNEL"), track.author, true) .addField(message.translate("music/np:T_CHANNEL"), track.uploader.name ? track.uploader.name : "Отсутствует")
.addField(message.translate("music/np:T_DURATION"), message.convertTime(Date.now()+track.durationMS, "to", true), true) .addField(message.translate("music/np:T_DURATION"), track.isLive ? message.translate("music/play:LIVE") : message.convertTime(Date.now() + track.duration * 1000, "to", 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()
.setColor(data.config.embed.color) .setColor(data.config.embed.color)
.setFooter(data.config.embed.footer); .setFooter(data.config.embed.footer)
.setTimestamp();
// Send the embed in the current channel // Send the embed in the current channel
message.channel.send(embed); message.channel.send(embed);

View file

@ -17,16 +17,14 @@ class Pause extends Command {
} }
async run (message) { async run (message) {
const voice = message.member.voice.channel;
const queue = this.client.player.getQueue(message); const queue = this.client.player.getQueue(message);
const voice = message.member.voice.channel;
if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!voice) return message.error("music/play:NO_VOICE_CHANNEL");
if (!queue) return message.error("music:play:NOT_PLAYING"); if (!queue) return message.error("music:play:NOT_PLAYING");
// Gets the current song
await this.client.player.pause(message); await this.client.player.pause(message);
// Send the embed in the current channel
message.sendT("music/pause:SUCCESS"); message.sendT("music/pause:SUCCESS");
} }
}; };

View file

@ -27,7 +27,12 @@ class Play extends Command {
const perms = voice.permissionsFor(this.client.user); const perms = voice.permissionsFor(this.client.user);
if (!perms.has("CONNECT") || !perms.has("SPEAK")) return message.error("music/play:VOICE_CHANNEL_CONNECT"); if (!perms.has("CONNECT") || !perms.has("SPEAK")) return message.error("music/play:VOICE_CHANNEL_CONNECT");
try {
await this.client.player.play(message, args.join(" ")); await this.client.player.play(message, args.join(" "));
} catch (e) {
message.error("music/play:ERR_OCCURRED", { error: e });
console.error(e);
}
} }
}; };

View file

@ -20,19 +20,19 @@ class Queue extends Command {
async run (message, args, data) { async run (message, args, data) {
const voice = message.member.voice.channel; const voice = message.member.voice.channel;
if (!voice) return message.error("music/play:NO_VOICE_CHANNEL");
const queue = this.client.player.getQueue(message); 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) return message.error("music/play:NOT_PLAYING");
if (queue.tracks.length === 1) { if (queue.songs.length === 1) {
const embed = new Discord.MessageEmbed() const embed = new Discord.MessageEmbed()
.setColor(data.config.embed.color)
.setAuthor(message.translate("music/queue:TITLE"), message.guild.iconURL({ dynamic: true })) .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); return message.channel.send(embed);
}; };
let i = 0; let i = 0;
const FieldsEmbed = new Pagination.FieldsEmbed(); const FieldsEmbed = new Pagination.FieldsEmbed();
@ -40,14 +40,14 @@ class Queue extends Command {
FieldsEmbed.embed FieldsEmbed.embed
.setColor(data.config.embed.color) .setColor(data.config.embed.color)
.setAuthor(message.translate("music/queue:TITLE"), message.guild.iconURL({ dynamic: true })) .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]) .setAuthorizedUsers([message.author.id])
.setChannel(message.channel) .setChannel(message.channel)
.setElementsPerPage(5) .setElementsPerPage(5)
.setPageIndicator(true) .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(); FieldsEmbed.build();
} }

View file

@ -17,16 +17,14 @@ class Resume extends Command {
} }
async run (message) { async run (message) {
const voice = message.member.voice.channel;
const queue = this.client.player.getQueue(message); const queue = this.client.player.getQueue(message);
const voice = message.member.voice.channel;
if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!voice) return message.error("music/play:NO_VOICE_CHANNEL");
if (!queue) return message.error("music:play:NOT_PLAYING"); if (!queue) return message.error("music:play:NOT_PLAYING");
// Gets the current song
await this.client.player.resume(message); await this.client.player.resume(message);
// Send the embed in the current channel
message.sendT("music/resume:SUCCESS"); message.sendT("music/resume:SUCCESS");
} }
}; };

View file

@ -18,20 +18,17 @@ class Seek extends Command {
} }
async run (message, args) { async run (message, args) {
const voice = message.member.voice.channel;
const queue = this.client.player.getQueue(message); const queue = this.client.player.getQueue(message);
const voice = message.member.voice.channel;
if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!voice) return message.error("music/play:NO_VOICE_CHANNEL");
if (!queue) return message.error("music/play:NOT_PLAYING"); if (!queue) return message.error("music/play:NOT_PLAYING");
const time = ms(args[0]); const time = ms(args[0]);
if (isNaN(time)) return message.error("music/seek:INVALID_TIME"); if (isNaN(time)) return message.error("music/seek:INVALID_TIME");
// Change the song position await this.client.player.seek(message, time);
await this.client.player.setPosition(message, queue.currentStreamTime + time);
// Send the embed in the current channel
message.sendT("music/seek:SUCCESS"); message.sendT("music/seek:SUCCESS");
} }
}; };

View file

@ -18,69 +18,24 @@ class Skip extends Command {
} }
async run (message, args, data) { async run (message, args, data) {
const queue = this.client.player.getQueue(message);
const voice = message.member.voice.channel; const voice = message.member.voice.channel;
const queue = this.client.player.getQueue(message);
if (!voice) return message.error("music/play:NO_VOICE_CHANNEL"); if (!voice) return message.error("music/play:NO_VOICE_CHANNEL");
if (!queue) return message.error("music/play:NOT_PLAYING"); if (!queue) return message.error("music/play:NOT_PLAYING");
if (!queue.tracks[0]) return message.error("music/skip:NO_NEXT_SONG"); if (!queue.songs[1]) return message.error("music/skip:NO_NEXT_SONG");
const members = voice.members.filter((m) => !m.user.bot);
const embed = new Discord.MessageEmbed() const embed = new Discord.MessageEmbed()
.setAuthor(message.translate("music/skip:DESCRIPTION")) .setAuthor(message.translate("music/skip:SUCCESS"))
.setThumbnail(queue.tracks[0].thumbnail) .setThumbnail(queue.songs[1].thumbnail)
.setFooter(data.config.embed.footer) .setFooter(data.config.embed.footer)
.setColor(data.config.embed.color); .setColor(data.config.embed.color);
const m = await message.channel.send(embed); 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); this.client.player.skip(message);
embed.setDescription(message.translate("music/skip:SUCCESS")); embed.setDescription(message.translate("music/play:NOW_PLAYING", { songName: queue.songs[1].name }));
m.edit(embed); 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);
};
} }
}; };

View file

@ -18,14 +18,12 @@ class Stop extends Command {
} }
async run (message, args, data) { async run (message, args, data) {
const queue = await this.client.player.getQueue(message);
const voice = message.member.voice.channel; 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 (!voice) return message.error("music/play:NO_VOICE_CHANNEL");
if (!queue) return message.error("music/play:NOT_PLAYING"); if (!queue) return message.error("music/play:NOT_PLAYING");
const members = voice.members.filter((m) => !m.user.bot);
const embed = new Discord.MessageEmbed() const embed = new Discord.MessageEmbed()
.setAuthor(message.translate("music/stop:DESCRIPTION")) .setAuthor(message.translate("music/stop:DESCRIPTION"))
.setFooter(data.config.embed.footer) .setFooter(data.config.embed.footer)
@ -33,52 +31,9 @@ class Stop extends Command {
const m = await message.channel.send(embed); 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); this.client.player.stop(message);
embed.setDescription(message.translate("music/stop:SUCCESS")); embed.setDescription(message.translate("music/stop:SUCCESS"));
m.edit(embed); 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);
};
} }
}; };

View file

@ -194,6 +194,18 @@
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<pre class="brush: html"> <pre class="brush: html">
-----------------------------------------------------------------------------------------
JaBa v3.0.6
-----------------------------------------------------------------------------------------
Добавлено
- Команда jump - позволяет перейти на заданный трек из очереди.
Изменения
- Система музыки переписана (да, снова).
Теперь можно воспроизвести звук практически с любых источников, в том числе видео и MP3 из Discord, Vimeo, прямые ссылки на радио.
Список всех возможных источников можно найти тут: https://ytdl-org.github.io/youtube-dl/supportedsites.html
Надеюсь теперь будет меньше ошибок...
----------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------
JaBa v3.0.5 JaBa v3.0.5
----------------------------------------------------------------------------------------- -----------------------------------------------------------------------------------------
@ -202,7 +214,7 @@
- Команда debug - похожа на set, но доступна только владельцу JaBa. - Команда debug - похожа на set, но доступна только владельцу JaBa.
Имеет расширенный функционал и обходит некоторые ограничения. Имеет расширенный функционал и обходит некоторые ограничения.
- Новая активность - Puttparty. - Новая активность - Puttparty.
Доступна через activity puttparty Доступна через activity puttparty.
Изменения Изменения
- В команде profile теперь видно необходимое кол-во опыта для следующего уровня. - В команде profile теперь видно необходимое кол-во опыта для следующего уровня.

View file

@ -0,0 +1,13 @@
{
"DESCRIPTION": "Change user's XP, level, credits or bank!",
"USAGE": "{{prefix}}set [level/xp/credits/bank] [@user] [value]",
"EXAMPLES": "{{prefix}}set level @Jonny_Bro#4226 10",
"INVALID_MEMBER": "You must mention the user!",
"NO_STATUS": "Select a parameter: `level`, `xp`, `credits` or `bank`",
"BOT_USER": "Bots don't have a profile!",
"INVALID_AMOUNT": "Enter a new value!",
"SUCCESS_LEVEL": "**{{username}}**'s level was changed to **{{amount}}**!",
"SUCCESS_XP": "**{{username}}**'s XP was changed to **{{amount}}**!",
"SUCCESS_CREDITS": "**{{username}}**'s credits was changed to **{{amount}}**!",
"SUCCESS_BANK": "**{{username}}**'s bank was changed to **{{amount}}**!"
}

View file

@ -1,7 +1,7 @@
{ {
"DESCRIPTION": "Translate your text!", "DESCRIPTION": "Translate your text!",
"USAGE": "{{prefix}}translate [language] [message]", "USAGE": "{{prefix}}translate [language] [message]",
"EXAMPLES": "{{prefix}}translate fr How are you ?", "EXAMPLES": "{{prefix}}translate russian How are you ?",
"LIST_SENT": "The languages list has just been sent to you by private messages!", "LIST_SENT": "The languages list has just been sent to you by private messages!",
"MISSING_LANGUAGE": "Please enter a language! To display the languages list, type `{{prefix}}translate langs-list`!", "MISSING_LANGUAGE": "Please enter a language! To display the languages list, type `{{prefix}}translate langs-list`!",
"INVALID_LANGUAGE": "The language `{{search}}` does not exist! To display the languages list, type `{{prefix}}translate langs-list`!", "INVALID_LANGUAGE": "The language `{{search}}` does not exist! To display the languages list, type `{{prefix}}translate langs-list`!",

View file

@ -3,6 +3,5 @@
"USAGE": "{{prefix}}back", "USAGE": "{{prefix}}back",
"EXAMPLES": "{{prefix}}back", "EXAMPLES": "{{prefix}}back",
"NO_PREV_SONG": "There was no song before this one!", "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!" "SUCCESS": "Playing previous song!"
} }

View file

@ -1,9 +1,9 @@
{ {
"DESCRIPTION": "Enable or disable a filter!", "DESCRIPTION": "Enable or disable a filter",
"USAGE": "{{prefix}}filter [filter]", "USAGE": "{{prefix}}filter [filter]",
"EXAMPLES": "{{prefix}}filter vaporwave", "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)", "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!", "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.", "ADDING_FILTER": "I'm adding the filter to the music, please wait...",
"REMOVING_FILTER": "I'm removing 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..."
} }

View file

@ -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!"
}

View file

@ -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]", "USAGE": "{{prefix}}loop [queue/song]",
"EXAMPLES": "{{prefix}}loop queue\n{{prefix}}loop song", "EXAMPLES": "{{prefix}}loop queue\n{{prefix}}loop song",
"NO_ARG": "Select: `queue` or `song`!", "NO_ARG": "Select: `queue` or `song`!",
"QUEUE": "Repeating queue is **{{loop}}**!", "QUEUE": "Repeat of queue is **enabled**!",
"SONG": "Repeating current track is **{{loop}}**!" "SONG": "Repeat of current track is **enabled**!",
"DISABLED": "Repeat now **disabled**!"
} }

View file

@ -7,5 +7,5 @@
"T_CHANNEL": "Channel", "T_CHANNEL": "Channel",
"T_DURATION": "Duration", "T_DURATION": "Duration",
"T_DESCRIPTION": "Description", "T_DESCRIPTION": "Description",
"NO_DESCRIPTION": "No description..." "NO_DESCRIPTION": "No description"
} }

View file

@ -12,10 +12,11 @@
"CANCELLED": "Selection cancelled", "CANCELLED": "Selection cancelled",
"NOT_PLAYING": "No songs are currently playing in this server.", "NOT_PLAYING": "No songs are currently playing in this server.",
"QUEUE_ENDED": "Queue has ended. No more music to play...", "QUEUE_ENDED": "Queue has ended. No more music to play...",
"ADDED_QUEUE": "{{songName}} has been added to the queue!", "ADDED_QUEUE": "**{{songName}}** has been added to the queue!",
"ADDED_QUEUE_COUNT": "{{songCount}} songs 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_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!", "RESULTS_CANCEL": "Search cancelled!",
"LIVE_VIDEO": "Lives are not yet supported!", "LIVE": "Live",
"ERR_OCCURRED": "An error occurred... Code: `{{error}}`" "ERR_OCCURRED": "An error occurred... Code: `{{error}}`"
} }

View file

@ -3,6 +3,5 @@
"USAGE": "{{prefix}}skip", "USAGE": "{{prefix}}skip",
"EXAMPLES": "{{prefix}}skip", "EXAMPLES": "{{prefix}}skip",
"NO_NEXT_SONG": "There's no song after this one!", "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!" "SUCCESS": "Song skipped!"
} }

View file

@ -0,0 +1,15 @@
{
"DESCRIPTION": "Allows to change user data!",
"USAGE": "{{prefix}}debug [set/add] [level/xp/credits/bank/rep] [@user] [value]",
"EXAMPLES": "{{prefix}}debug set level @Jonny_Bro#4226 10000",
"INVALID_MEMBER": "You must mention the user!",
"NO_ACTION": "Select an option: `set` or `add`!",
"NO_STATUS": "Select a parameter: `level`, `xp`, `credits`, `rep` или `bank`!",
"BOT_USER": "Bots don't have a profile!",
"INVALID_AMOUNT": "Enter a new value!",
"SUCCESS_LEVEL": "**{{username}}**'s level was changed to **{{amount}}**!",
"SUCCESS_XP": "**{{username}}**'s XP was changed to **{{amount}}**!",
"SUCCESS_CREDITS": "**{{username}}**'s credits was changed to **{{amount}}**!",
"SUCCESS_BANK": "**{{username}}**'s bank was changed to **{{amount}}**!",
"SUCCESS_REP": "*{{username}}**'s reputation points was changed to **{{amount}}**!"
}

View file

@ -8,7 +8,7 @@
"CONTENT": "Содержимое", "CONTENT": "Содержимое",
"REASON": "Причина", "REASON": "Причина",
"USER": "Пользователь", "USER": "Пользователь",
"CREATION": "Создание", "CREATION": "Аккаунт создан",
"MEMBERS": "Участники", "MEMBERS": "Участники",
"CHANNELS": "Каналы", "CHANNELS": "Каналы",
"ID": "ID", "ID": "ID",
@ -18,7 +18,7 @@
"STATS": "Статистика", "STATS": "Статистика",
"ROBOT": "Бот", "ROBOT": "Бот",
"AVATAR": "Аватар", "AVATAR": "Аватар",
"GAME": "Игра", "GAME": "Активность",
"STATUS": "Статус", "STATUS": "Статус",
"STATUS_ONLINE": "Онлайн", "STATUS_ONLINE": "Онлайн",
"STATUS_OFFLINE": "Оффлайн", "STATUS_OFFLINE": "Оффлайн",
@ -26,7 +26,7 @@
"STATUS_DND": "Не беспокоить", "STATUS_DND": "Не беспокоить",
"ROLE": "Роль", "ROLE": "Роль",
"ROLES": "Роли", "ROLES": "Роли",
"JOIN": "Присоедениться", "JOIN": "Присоеденился",
"COLOR": "Цвет", "COLOR": "Цвет",
"NICKNAME": "Ник", "NICKNAME": "Ник",
"DESCRIPTION": "Описание", "DESCRIPTION": "Описание",

View file

@ -3,8 +3,8 @@
"USAGE": "{{prefix}}birthdate [дата]", "USAGE": "{{prefix}}birthdate [дата]",
"EXAMPLES": "{{prefix}}birthdate 01/01/2010", "EXAMPLES": "{{prefix}}birthdate 01/01/2010",
"MISSING_DATE": "Пожалуйста, укажите правильную дату! Например, 20/11/2003", "MISSING_DATE": "Пожалуйста, укажите правильную дату! Например, 20/11/2003",
"INVALID_DATE": "Используйте данный фортам: ДД/ММ/ГГГГ. Например, `1 января 2010` будет `01/01/2010`.", "INVALID_DATE": "Используйте данный формат: ДД/ММ/ГГГГ. Например, `1 января 2010` будет `01/01/2010`.",
"INVALID_DATE_FORMAT": "Используйте данный фортам: ДД/ММ/ГГГГ. Например, `1 января 2010` будет `01/01/2010`.", "INVALID_DATE_FORMAT": "Используйте данный формат: ДД/ММ/ГГГГ. Например, `1 января 2010` будет `01/01/2010`.",
"DATE_TOO_HIGH": "Вы старше 80 лет? :eyes:", "DATE_TOO_HIGH": "Вы старше 80 лет? :eyes:",
"DATE_TOO_LOW": "Хммм... Вы ещё не родились!", "DATE_TOO_LOW": "Хммм... Вы ещё не родились!",
"SUCCESS": "Ваш день рождения установлен на {{date}}!" "SUCCESS": "Ваш день рождения установлен на {{date}}!"

View file

@ -1,7 +1,7 @@
{ {
"DESCRIPTION": "Перевести текст!", "DESCRIPTION": "Перевести текст!",
"USAGE": "{{prefix}}translate [язык] [текс]", "USAGE": "{{prefix}}translate [язык] [текс]",
"EXAMPLES": "{{prefix}}translate en Как дела?", "EXAMPLES": "{{prefix}}translate english Как дела?",
"LIST_SENT": "Список языков отправлен вам в ЛС!", "LIST_SENT": "Список языков отправлен вам в ЛС!",
"MISSING_LANGUAGE": "Укажите язык! Чтобы получить список языков, введите `{{prefix}}translate langs-list`!", "MISSING_LANGUAGE": "Укажите язык! Чтобы получить список языков, введите `{{prefix}}translate langs-list`!",
"INVALID_LANGUAGE": "Язык `{{search}}` не найден! Чтобы получить список языков, введите `{{prefix}}translate langs-list`!", "INVALID_LANGUAGE": "Язык `{{search}}` не найден! Чтобы получить список языков, введите `{{prefix}}translate langs-list`!",

View file

@ -5,6 +5,7 @@
"INVALID_USER": "Пользователь с ID `{{search}}` не найден!", "INVALID_USER": "Пользователь с ID `{{search}}` не найден!",
"NO_GAME": "Не играет", "NO_GAME": "Не играет",
"NO_ROLE": "Нет роли", "NO_ROLE": "Нет роли",
"ROLE": "Высшая роль",
"NO_NICKNAME": "Нет никнейма", "NO_NICKNAME": "Нет никнейма",
"MORE_ROLES": "и ещё {{count}} роль(и/ей)", "MORE_ROLES": "и ещё {{count}} роль(и/ей)",
"BOT_STATS": "**{{votes}}** голосов ([top.gg](https://top.gg))\n**{{servers}}** серверов\n**{{shards}}** шардов\nИспользует **{{lib}}**" "BOT_STATS": "**{{votes}}** голосов ([top.gg](https://top.gg))\n**{{servers}}** серверов\n**{{shards}}** шардов\nИспользует **{{lib}}**"

View file

@ -3,6 +3,5 @@
"USAGE": "{{prefix}}back", "USAGE": "{{prefix}}back",
"EXAMPLES": "{{prefix}}back", "EXAMPLES": "{{prefix}}back",
"NO_PREV_SONG": "Предыдущий трек отсутствует!", "NO_PREV_SONG": "Предыдущий трек отсутствует!",
"VOTE_CONTENT": "Предыдущий трек: {{songName}}\nОтреагируйте 👍, чтобы проголосовать за воспроизведение! Необходимо ещё {{requiredCount}} голосов.",
"SUCCESS": "Играет предыдущий трек!" "SUCCESS": "Играет предыдущий трек!"
} }

View file

@ -1,9 +1,9 @@
{ {
"DESCRIPTION": "Включить или отключить фильтр!", "DESCRIPTION": "Включить или отключить фильтр",
"USAGE": "{{prefix}}filter [фильтр]", "USAGE": "{{prefix}}filter [фильтр]",
"EXAMPLES": "{{prefix}}filter vaporwave", "EXAMPLES": "{{prefix}}filter vaporwave",
"MISSING_FILTER": "Укажите фильтр для его включения или отключения! (или отправьте `{{prefix}}filters`, чтобы увидеть статусы фильтров)", "MISSING_FILTER": "Укажите фильтр для его включения или отключения! (или отправьте `{{prefix}}filters`, чтобы увидеть статусы фильтров)",
"UNKNOWN_FILTER": "Данный фильтр не существует! Используйте `{{prefix}}filters`, чтобы увидеть список фильтров!", "UNKNOWN_FILTER": "Заданный фильтр не существует! Используйте `{{prefix}}filters`, чтобы увидеть список фильтров!",
"ADDING_FILTER": "Добавляю фильтр, пожалуйста подождите... Примечание: чем короче трек, тем быстрее это будет выполнено.", "ADDING_FILTER": "Добавляю фильтр, пожалуйста подождите...",
"REMOVING_FILTER": "Удаляю фильтр, пожалуйста подождите... Примечание: чем короче трек, тем быстрее это будет выполнено." "REMOVING_FILTER": "Удаляю фильтр, пожалуйста подождите..."
} }

View file

@ -1,5 +1,5 @@
{ {
"DESCRIPTION": "Получить список фильтров и их статусов", "DESCRIPTION": "Получить список фильтров и их статусы",
"USAGE": "{{prefix}}filters", "USAGE": "{{prefix}}filters",
"EXAMPLES": "{{prefix}}filters", "EXAMPLES": "{{prefix}}filters",
"TITLE": "**Фильтры**", "TITLE": "**Фильтры**",

View file

@ -0,0 +1,7 @@
{
"DESCRIPTION": "Перейти на заданный трек",
"USAGE": "{{prefix}}jump [номер-трека]",
"EXAMPLES": "{{prefix}}jump 3",
"NO_PREV_SONG": "Вы не можете перейти назад, для этого используйте команду `{{prefix}}back`!",
"SUCCESS": "Играет выбранный трек!"
}

View file

@ -3,8 +3,7 @@
"USAGE": "{{prefix}}loop [queue/song]", "USAGE": "{{prefix}}loop [queue/song]",
"EXAMPLES": "{{prefix}}loop queue\n{{prefix}}loop song", "EXAMPLES": "{{prefix}}loop queue\n{{prefix}}loop song",
"NO_ARG": "Выберите: `queue` или `song`!", "NO_ARG": "Выберите: `queue` или `song`!",
"QUEUE_SUCCESS_ENABLED": "{{success}} Повтор очереди включён!", "QUEUE": "Повтор очереди **включён**!",
"QUEUE_SUCCESS_DISABLED": "{{success}} Повтор очереди отключён!", "SONG": "Повтор текущего трека **включён**!",
"SONG_SUCCESS_ENABLED" : "{{success}} Повтор текущего трека включён!", "DISABLED": "Повтор **отключён**!"
"SONG_SUCCESS_DISABLED" : "{{success}} Повтор текущего трека отключён!"
} }

View file

@ -7,5 +7,5 @@
"T_CHANNEL": "Канал", "T_CHANNEL": "Канал",
"T_DURATION": "Длительность", "T_DURATION": "Длительность",
"T_DESCRIPTION": "Описание", "T_DESCRIPTION": "Описание",
"NO_DESCRIPTION": "Нет описание..." "NO_DESCRIPTION": "Описание отсутствует"
} }

View file

@ -12,10 +12,11 @@
"CANCELLED": "Выбор отменён", "CANCELLED": "Выбор отменён",
"NOT_PLAYING": "На сервере сейчас ничего не воспроизводится.", "NOT_PLAYING": "На сервере сейчас ничего не воспроизводится.",
"QUEUE_ENDED": "Очередь окончена.", "QUEUE_ENDED": "Очередь окончена.",
"ADDED_QUEUE": "{{songName}} добавлен в очередь!", "ADDED_QUEUE": "**{{songName}}** добавлен в очередь!",
"ADDED_QUEUE_COUNT": "{{songCount}} трек(а/ов) добавлено в очередь!", "ADDED_QUEUE_COUNT": "**{{songCount}}** трек(а/ов) добавлено в очередь!",
"STOP_DISCONNECTED": "Воспроизведение окончено, т.к. я вышел из голосового канала.", "STOP_DISCONNECTED": "Воспроизведение окончено, т.к. я вышел из голосового канала.",
"STOP_EMPTY": "Воспроизведение окончено, т.к. все вышли из голосового канала.",
"RESULTS_CANCEL": "Поиск отменён!", "RESULTS_CANCEL": "Поиск отменён!",
"LIVE_VIDEO": "Прямые трансляции не поддерживаются!", "LIVE": "Прямая трансляция",
"ERR_OCCURRED": "Произошла ошибка... Код ошибки: `{{error}}`" "ERR_OCCURRED": "Произошла ошибка... Код ошибки: `{{error}}`"
} }

View file

@ -3,6 +3,5 @@
"USAGE": "{{prefix}}skip", "USAGE": "{{prefix}}skip",
"EXAMPLES": "{{prefix}}skip", "EXAMPLES": "{{prefix}}skip",
"NO_NEXT_SONG": "После текущего трека больше нет треков!", "NO_NEXT_SONG": "После текущего трека больше нет треков!",
"VOTE_CONTENT": "Следующий трек: {{songName}}\nОтреагируйте 👍, чтобы проголосовать за пропуск трека! Необходимо ещё {{requiredCount}} голосов.",
"SUCCESS": "Трек пропущен!" "SUCCESS": "Трек пропущен!"
} }

View file

@ -1,7 +1,7 @@
{ {
"name": "jaba", "name": "jaba",
"version": "3.0.5", "version": "3.0.6",
"description": "A very complete Discord bot (more than 130 commands) that uses the Discord.js", "description": "A very complete Discord bot (more than 100 commands) that uses the Discord.js",
"main": "index.js", "main": "index.js",
"private": true, "private": true,
"scripts": { "scripts": {
@ -13,8 +13,9 @@
"author": "Jonny_Bro", "author": "Jonny_Bro",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@discord-player/extractor": "^3.0.0",
"@discordjs/opus": "^0.5.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", "@k3rn31p4nic/google-translate-api": "github:k3rn31p4nic/google-translate-api",
"@sentry/node": "6.3.6", "@sentry/node": "6.3.6",
"@sindresorhus/slugify": "^1.1.0", "@sindresorhus/slugify": "^1.1.0",
@ -32,9 +33,9 @@
"discord-canvas": "^1.3.2", "discord-canvas": "^1.3.2",
"discord-giveaways": "^4.4.3", "discord-giveaways": "^4.4.3",
"discord-paginationembed": "^2.1.0", "discord-paginationembed": "^2.1.0",
"discord-player": "^4.1.4",
"discord-together": "^1.3.25", "discord-together": "^1.3.25",
"discord.js": "^12.5.3", "discord.js": "^12.5.3",
"distube": "^3.0.4",
"ejs": "^3.1.3", "ejs": "^3.1.3",
"express": "^4.17.1", "express": "^4.17.1",
"express-session": "^1.17.0", "express-session": "^1.17.0",