revert lavalink rewrite

This commit is contained in:
Jonny_Bro (Nikita) 2024-04-30 12:19:44 +05:00
parent 707991f416
commit 02990bab63
Signed by: jonny_bro
GPG key ID: 3F1ECC04147E9BD8
17 changed files with 429 additions and 207 deletions

View file

@ -1,7 +1,7 @@
const { Client, Collection, SlashCommandBuilder, ContextMenuCommandBuilder, EmbedBuilder, PermissionsBitField, ChannelType } = require("discord.js"), const { Client, Collection, SlashCommandBuilder, ContextMenuCommandBuilder, EmbedBuilder, PermissionsBitField, ChannelType } = require("discord.js"),
{ GiveawaysManager } = require("discord-giveaways"), { GiveawaysManager } = require("discord-giveaways"),
{ REST } = require("@discordjs/rest"), { REST } = require("@discordjs/rest"),
{ LavalinkManager } = require("lavalink-client"), { Player } = require("discord-player"),
{ Routes } = require("discord-api-types/v10"); { Routes } = require("discord-api-types/v10");
const BaseEvent = require("./BaseEvent.js"), const BaseEvent = require("./BaseEvent.js"),
@ -32,61 +32,43 @@ class JaBaClient extends Client {
this.databaseCache.members = new Collection(); this.databaseCache.members = new Collection();
this.databaseCache.usersReminds = new Collection(); this.databaseCache.usersReminds = new Collection();
this.lavalink = new LavalinkManager({ this.player = new Player(this);
nodes: [this.config.lavalinkNodes], this.player.extractors.loadDefault(null, {
sendToShard: (guildId, payload) => this.guilds.cache.get(guildId)?.shard?.send(payload), SpotifyExtractor: {
client: { clientId: this.config.spotify.clientId,
id: this.config.userId, clientSecret: this.config.spotify.clientSecret,
username: "JaBa",
},
autoSkip: true,
playerOptions: {
defaultSearchPlatform: "ytmsearch",
volumeDecrementer: 1,
onDisconnect: {
autoReconnect: false,
destroyPlayer: true,
},
onEmptyQueue: {
destroyAfterMs: 5000,
},
}, },
}); });
this.lavalink.on("trackStart", async (player, track) => { this.player.events.on("playerStart", async (queue, track) => {
const guildData = await this.findOrCreateGuild(player.guildId),
channel = this.channels.cache.get(player.textChannelId);
const m = ( const m = (
await channel.send({ await queue.metadata.channel.send({
content: this.translate("music/play:NOW_PLAYING", { songName: `${track.info.title} - ${track.info.author}` }, guildData.language), content: this.translate("music/play:NOW_PLAYING", { songName: `${track.title} - ${track.author}` }, queue.metadata.data.guild.language),
}) })
).id; ).id;
if (track.info.duration > 1) if (track.durationMS > 1)
setTimeout(() => { setTimeout(() => {
const message = channel.messages.cache.get(m); const message = queue.metadata.channel.messages.cache.get(m);
if (message && message.deletable) message.delete(); if (message && message.deletable) message.delete();
}, track.info.duration); }, track.durationMS);
else else
setTimeout(() => { setTimeout(() => {
const message = channel.messages.cache.get(m); const message = queue.metadata.channel.messages.cache.get(m);
if (message && message.deletable) message.delete(); if (message && message.deletable) message.delete();
}, 5 * 60 * 1000); }, 5 * 60 * 1000);
}); });
this.lavalink.on("queueEnd", async player => { this.player.events.on("emptyQueue", queue => queue.metadata.channel.send(this.translate("music/play:QUEUE_ENDED", null, queue.metadata.data.guild.language)));
const guildData = await this.findOrCreateGuild(player.guildId), this.player.events.on("emptyChannel", queue => queue.metadata.channel.send(this.translate("music/play:STOP_EMPTY", null, queue.metadata.data.guild.language)));
channel = this.channels.cache.get(player.textChannelId); this.player.events.on("playerError", (queue, e) => {
queue.metadata.channel.send({ content: this.translate("music/play:ERR_OCCURRED", { error: e.message }, queue.metadata.data.guild.language) });
channel.send(this.translate("music/play:QUEUE_ENDED", null, guildData.language)); console.log(e);
}); });
this.lavalink.on("trackError", async player => { this.player.events.on("error", (queue, e) => {
const guildData = await this.findOrCreateGuild(player.guildId), queue.metadata.channel.send({ content: this.translate("music/play:ERR_OCCURRED", { error: e.message }, queue.metadata.data.guild.language) });
channel = this.channels.cache.get(player.textChannelId); console.log(e);
channel.send({ content: this.translate("music/play:ERR_OCCURRED", null, guildData.language) });
}); });
this.giveawaysManager = new GiveawaysManager(this, { this.giveawaysManager = new GiveawaysManager(this, {

View file

@ -1,4 +1,5 @@
const { SlashCommandBuilder } = require("discord.js"); const { SlashCommandBuilder } = require("discord.js"),
{ QueueRepeatMode } = require("discord-player");
const BaseCommand = require("../../base/BaseCommand"); const BaseCommand = require("../../base/BaseCommand");
class Loop extends BaseCommand { class Loop extends BaseCommand {
@ -26,10 +27,10 @@ class Loop extends BaseCommand {
}) })
.setRequired(true) .setRequired(true)
.setChoices( .setChoices(
// { name: client.translate("music/loop:AUTOPLAY"), value: "3" }, { name: client.translate("music/loop:AUTOPLAY"), value: "3" },
{ name: client.translate("music/loop:QUEUE"), value: "queue" }, { name: client.translate("music/loop:QUEUE"), value: "2" },
{ name: client.translate("music/loop:TRACK"), value: "track" }, { name: client.translate("music/loop:TRACK"), value: "1" },
{ name: client.translate("music/loop:DISABLE"), value: "off" }, { name: client.translate("music/loop:DISABLE"), value: "0" },
), ),
), ),
dirname: __dirname, dirname: __dirname,
@ -43,25 +44,25 @@ class Loop extends BaseCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction * @param {import("discord.js").ChatInputCommandInteraction} interaction
*/ */
async execute(client, interaction) { async execute(client, interaction) {
await interaction.deferReply();
const voice = interaction.member.voice.channel; const voice = interaction.member.voice.channel;
if (!voice) return interaction.error("music/play:NO_VOICE_CHANNEL", null, { edit: true }); if (!voice) return interaction.error("music/play:NO_VOICE_CHANNEL", null, { edit: true });
const player = client.lavalink.getPlayer(interaction.guildId); const queue = client.player.nodes.get(interaction.guildId);
if (!player) return interaction.error("music/play:NOT_PLAYING", null, { edit: true }); if (!queue) return interaction.error("music/play:NOT_PLAYING", null, { edit: true });
const type = interaction.options.getString("option");
const translated = { const translated = {
// "3": interaction.translate("music/loop:AUTOPLAY_ENABLED"), "3": interaction.translate("music/loop:AUTOPLAY_ENABLED"),
"queue": interaction.translate("music/loop:QUEUE_ENABLED"), "2": interaction.translate("music/loop:QUEUE_ENABLED"),
"track": interaction.translate("music/loop:TRACK_ENABLED"), "1": interaction.translate("music/loop:TRACK_ENABLED"),
"off": interaction.translate("music/loop:LOOP_DISABLED"), "0": interaction.translate("music/loop:LOOP_DISABLED"),
}; };
await player.setRepeatMode(type); const type = interaction.options.getString("option"),
interaction.editReply({ content: translated[type] }); mode = type === "3" ? QueueRepeatMode.AUTOPLAY : type === "2" ? QueueRepeatMode.QUEUE : type === "1" ? QueueRepeatMode.TRACK : QueueRepeatMode.OFF;
queue.setRepeatMode(mode);
interaction.reply({ content: translated[type] });
} }
} }

View file

@ -29,38 +29,40 @@ class PlayContext extends BaseCommand {
if (!links) return interaction.error("music/play:NO_LINK", null, { edit: true }); if (!links) return interaction.error("music/play:NO_LINK", null, { edit: true });
const query = links[0], const query = links[0],
voice = interaction.member.voice; voice = interaction.member.voice.channel;
if (!voice.channel) return interaction.error("music/play:NO_VOICE_CHANNEL", null, { edit: true }); if (!voice) return interaction.error("music/play:NO_VOICE_CHANNEL", null, { edit: true });
const perms = voice.channel.permissionsFor(client.user); const perms = voice.permissionsFor(client.user);
if (!perms.has(PermissionsBitField.Flags.Connect) || !perms.has(PermissionsBitField.Flags.Speak)) return interaction.error("music/play:VOICE_CHANNEL_CONNECT", null, { edit: true }); if (!perms.has(PermissionsBitField.Flags.Connect) || !perms.has(PermissionsBitField.Flags.Speak)) return interaction.error("music/play:VOICE_CHANNEL_CONNECT", null, { edit: true });
const player = await client.lavalink.createPlayer({ const searchResult = await client.player.search(query, {
guildId: interaction.guildId, requestedBy: interaction.user,
voiceChannelId: voice.channelId,
textChannelId: interaction.channelId,
selfDeaf: true,
selfMute: false,
volume: 100,
}); });
await player.connect(); if (!searchResult.hasTracks()) {
console.log(searchResult);
const res = await player.search({ query }, interaction.member); return interaction.error("music/play:NO_RESULT", { query }, { edit: true });
} else {
if (res.loadType === "playlist") await player.queue.add(res.tracks); await client.player.play(voice, searchResult, {
else if (res.loadType === "search") await player.queue.add(res.tracks[0]); nodeOptions: {
else if (res.loadType === "track") await player.queue.add(res.tracks[0]); metadata: interaction,
else console.log(res); },
selfDeaf: true,
if (!player.playing) await player.play(); leaveOnEnd: false,
leaveOnStop: true,
skipOnNoStream: true,
maxSize: 100,
maxHistorySize: 50,
});
interaction.editReply({ interaction.editReply({
content: interaction.translate("music/play:ADDED_QUEUE", { content: interaction.translate("music/play:ADDED_QUEUE", {
songName: res.loadType === "playlist" ? res.playlist.name : `${res.tracks[0].info.title} - ${res.tracks[0].info.author}`, songName: searchResult.hasPlaylist() ? searchResult.playlist.title : searchResult.tracks[0].title,
}), }),
}); });
} }
}
} }
module.exports = PlayContext; module.exports = PlayContext;

View file

@ -1,4 +1,5 @@
const { SlashCommandBuilder, PermissionsBitField } = require("discord.js"); const { SlashCommandBuilder, PermissionsBitField } = require("discord.js"),
{ QueryType } = require("discord-player");
const BaseCommand = require("../../base/BaseCommand"); const BaseCommand = require("../../base/BaseCommand");
class Play extends BaseCommand { class Play extends BaseCommand {
@ -24,7 +25,8 @@ class Play extends BaseCommand {
uk: client.translate("music/play:QUERY", null, "uk-UA"), uk: client.translate("music/play:QUERY", null, "uk-UA"),
ru: client.translate("music/play:QUERY", null, "ru-RU"), ru: client.translate("music/play:QUERY", null, "ru-RU"),
}) })
.setRequired(true), .setRequired(true)
.setAutocomplete(true),
), ),
dirname: __dirname, dirname: __dirname,
ownerOnly: false, ownerOnly: false,
@ -40,38 +42,40 @@ class Play extends BaseCommand {
await interaction.deferReply(); await interaction.deferReply();
const query = interaction.options.getString("query"), const query = interaction.options.getString("query"),
voice = interaction.member.voice; voice = interaction.member.voice.channel;
if (!voice.channel) return interaction.error("music/play:NO_VOICE_CHANNEL", null, { edit: true }); if (!voice) return interaction.error("music/play:NO_VOICE_CHANNEL", null, { edit: true });
const perms = voice.channel.permissionsFor(client.user); const perms = voice.permissionsFor(client.user);
if (!perms.has(PermissionsBitField.Flags.Connect) || !perms.has(PermissionsBitField.Flags.Speak)) return interaction.error("music/play:VOICE_CHANNEL_CONNECT", null, { edit: true }); if (!perms.has(PermissionsBitField.Flags.Connect) || !perms.has(PermissionsBitField.Flags.Speak)) return interaction.error("music/play:VOICE_CHANNEL_CONNECT", null, { edit: true });
const player = await client.lavalink.createPlayer({ const searchResult = await client.player.search(query, {
guildId: interaction.guildId, requestedBy: interaction.user,
voiceChannelId: voice.channelId,
textChannelId: interaction.channelId,
selfDeaf: true,
selfMute: false,
volume: 100,
}); });
await player.connect(); if (!searchResult.hasTracks()) {
console.log(searchResult);
const res = await player.search({ query }, interaction.member); return interaction.error("music/play:NO_RESULT", { query }, { edit: true });
} else {
if (res.loadType === "playlist") await player.queue.add(res.tracks); await client.player.play(voice, searchResult, {
else if (res.loadType === "search") await player.queue.add(res.tracks[0]); nodeOptions: {
else if (res.loadType === "track") await player.queue.add(res.tracks[0]); metadata: interaction,
else console.log(res); },
selfDeaf: true,
if (!player.playing) await player.play(); leaveOnEnd: false,
leaveOnStop: true,
skipOnNoStream: true,
maxSize: 100,
maxHistorySize: 50,
});
interaction.editReply({ interaction.editReply({
content: interaction.translate("music/play:ADDED_QUEUE", { content: interaction.translate("music/play:ADDED_QUEUE", {
songName: res.loadType === "playlist" ? res.playlist.name : `${res.tracks[0].info.title} - ${res.tracks[0].info.author}`, songName: searchResult.hasPlaylist() ? searchResult.playlist.title : `${searchResult.tracks[0].title} - ${searchResult.tracks[0].author}`,
}), }),
}); });
} }
}
/** /**
* *
@ -79,34 +83,32 @@ class Play extends BaseCommand {
* @param {import("discord.js").AutocompleteInteraction} interaction * @param {import("discord.js").AutocompleteInteraction} interaction
* @returns * @returns
*/ */
// async autocompleteRun(client, interaction) { // TODO: Works from time to time async autocompleteRun(client, interaction) {
// const query = interaction.options.getString("query"); const query = interaction.options.getString("query");
// if (query === "") return; if (query === "" || query === null) return;
// if (!client.lavalink.players.get(interaction.guildId)) { const youtubeResults = await client.player.search(query, { searchEngine: QueryType.YOUTUBE });
// const player = await client.lavalink.createPlayer({ const spotifyResults = await client.player.search(query, { searchEngine: QueryType.SPOTIFY_SEARCH });
// guildId: interaction.guildId, const tracks = [];
// voiceChannelId: interaction.member.voice.channelId,
// textChannelId: interaction.channelId,
// selfDeaf: true,
// selfMute: false,
// volume: 100,
// });
// const results = await player.search({ query }, interaction.member); youtubeResults.tracks
// if (results.loadType === "empty") return interaction.respond([{ name: "Nothing found", "value": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" }]); .slice(0, 5)
// const tracks = []; .map(t => ({
name: `YouTube: ${`${t.title} - ${t.author} (${t.duration})`.length > 75 ? `${`${t.title} - ${t.author}`.substring(0, 75)}... (${t.duration})` : `${t.title} - ${t.author} (${t.duration})`}`,
value: t.url,
}))
.forEach(t => tracks.push({ name: t.name, value: t.value }));
// results.tracks spotifyResults.tracks
// .map(t => ({ .slice(0, 5)
// name: `YouTube: ${`${t.info.title} - ${t.info.author} (${client.functions.printDate(client, t.info.duration, null, interaction.data.guild.lanugage)})`.length > 75 ? `${`${t.info.title} - ${t.info.author}`.substring(0, 75)}... (${client.functions.printDate(client, t.info.duration, null, interaction.data.guild.lanugage)})` : `${t.info.title} - ${t.info.author} (${client.functions.printDate(client, t.info.duration, null, interaction.data.guild.lanugage)})`}`, .map(t => ({
// value: t.info.uri, name: `Spotify: ${`${t.title} - ${t.author} (${t.duration})`.length > 75 ? `${`${t.title} - ${t.author}`.substring(0, 75)}... (${t.duration})` : `${t.title} - ${t.author} (${t.duration})`}`,
// })) value: t.url,
// .forEach(t => tracks.push({ name: t.name, value: t.value })); }))
.forEach(t => tracks.push({ name: t.name, value: t.value }));
// return interaction.respond(tracks); return interaction.respond(tracks);
// } }
// }
} }
module.exports = Play; module.exports = Play;

View file

@ -32,10 +32,10 @@ class Queue extends BaseCommand {
if (interaction.customId.startsWith("queue_")) { if (interaction.customId.startsWith("queue_")) {
const locale = (await client.findOrCreateGuild(interaction.guildId)).language; const locale = (await client.findOrCreateGuild(interaction.guildId)).language;
const player = client.lavalink.getPlayer(interaction.guildId); const queue = client.player.nodes.get(interaction.guildId);
if (!player) return interaction.error("music/play:NOT_PLAYING"); if (!queue) return interaction.error("music/play:NOT_PLAYING", null, locale);
const { embeds, size } = generateQueueEmbeds(interaction, player, locale); const { embeds, size } = generateQueueEmbeds(interaction, queue, locale);
let currentPage = Number(interaction.message.content.match(/\d+/g)[0]) - 1 ?? 0; let currentPage = Number(interaction.message.content.match(/\d+/g)[0]) - 1 ?? 0;
@ -123,10 +123,10 @@ class Queue extends BaseCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction * @param {import("discord.js").ChatInputCommandInteraction} interaction
*/ */
async execute(client, interaction) { async execute(client, interaction) {
const player = client.lavalink.getPlayer(interaction.guildId); const queue = client.player.nodes.get(interaction.guildId);
if (!player) return interaction.error("music/play:NOT_PLAYING"); if (!queue) return interaction.error("music/play:NOT_PLAYING");
const { embeds, size } = generateQueueEmbeds(interaction, player), const { embeds, size } = generateQueueEmbeds(interaction, queue),
row = new ActionRowBuilder().addComponents( row = new ActionRowBuilder().addComponents(
new ButtonBuilder().setCustomId("queue_prev_page").setStyle(ButtonStyle.Primary).setEmoji("⬅️"), new ButtonBuilder().setCustomId("queue_prev_page").setStyle(ButtonStyle.Primary).setEmoji("⬅️"),
new ButtonBuilder().setCustomId("queue_next_page").setStyle(ButtonStyle.Primary).setEmoji("➡️"), new ButtonBuilder().setCustomId("queue_next_page").setStyle(ButtonStyle.Primary).setEmoji("➡️"),
@ -151,29 +151,29 @@ class Queue extends BaseCommand {
/** /**
* *
* @param {import("discord.js").ChatInputCommandInteraction} interaction * @param {import("discord.js").ChatInputCommandInteraction} interaction
* @param {import("lavalink-client").Player} player * @param {import("discord-player").GuildQueue} queue
* @param {string} locale * @param {string} locale
* @returns * @returns
*/ */
function generateQueueEmbeds(interaction, player, locale) { function generateQueueEmbeds(interaction, queue, locale) {
const embeds = [], const embeds = [],
currentTrack = player.queue.current, currentTrack = queue.currentTrack,
translated = { translated = {
// "3": interaction.translate("music/loop:AUTOPLAY"), "3": interaction.translate("music/loop:AUTOPLAY", null, locale),
"queue": interaction.translate("music/loop:QUEUE", null, locale), "2": interaction.translate("music/loop:QUEUE", null, locale),
"track": interaction.translate("music/loop:TRACK", null, locale), "1": interaction.translate("music/loop:TRACK", null, locale),
"off": interaction.translate("common:DISABLED", null, locale), "0": interaction.translate("common:DISABLED", null, locale),
}; };
let k = 10; let k = 10;
if (!player.queue.tracks.length) { if (!queue.tracks.size) {
const embed = interaction.client.embed({ const embed = interaction.client.embed({
title: interaction.translate("music/nowplaying:CURRENTLY_PLAYING", null, locale), title: interaction.translate("music/nowplaying:CURRENTLY_PLAYING", null, locale),
thumbnail: currentTrack.info.artworkUrl || null, thumbnail: currentTrack.thumbnail || null,
description: `${interaction.translate("music/nowplaying:REPEAT", null, locale)}: \`${translated[player.repeatMode]}\`\n${ description: `${interaction.translate("music/nowplaying:REPEAT", null, locale)}: \`${translated[queue.repeatMode]}\`\n${
currentTrack.info.uri.startsWith("./clips", null, locale) ? `${currentTrack.info.title} (clips)` : `[${currentTrack.info.title}](${currentTrack.info.uri})` currentTrack.url.startsWith("./clips") ? `${currentTrack.title} (clips)` : `[${currentTrack.title}](${currentTrack.url})`
}\n> ${interaction.translate("music/queue:ADDED", null, locale)} ${currentTrack.requester.toString()}\n\n**${interaction.translate("music/queue:NEXT", null, locale)}**\n${interaction.translate("music/queue:NO_QUEUE", null, locale)}`, }\n> ${interaction.translate("music/queue:ADDED", null, locale)} ${currentTrack.requestedBy}\n\n**${interaction.translate("music/queue:NEXT", null, locale)}**\n${interaction.translate("music/queue:NO_QUEUE", null, locale)}`,
}); });
embeds.push(embed); embeds.push(embed);
@ -181,19 +181,19 @@ function generateQueueEmbeds(interaction, player, locale) {
return { embeds: embeds, size: embeds.length }; return { embeds: embeds, size: embeds.length };
} }
for (let i = 0; i < player.queue.tracks.length; i += 10) { for (let i = 0; i < queue.getSize(); i += 10) {
const current = player.queue.tracks.slice(i, k); const current = queue.tracks.toArray().slice(i, k);
let j = i; let j = i;
k += 10; k += 10;
const info = current.map(track => `${++j}. ${track.info.uri.startsWith("./clips") ? `${track.info.title} (clips)` : `[${track.info.title}](${track.info.uri})`}\n> ${interaction.translate("music/queue:ADDED", null, locale)} ${track.requester.toString()}`).join("\n"); const info = current.map(track => `${++j}. ${track.url.startsWith("./clips") ? `${track.title} (clips)` : `[${track.title}](${track.url})`}\n> ${interaction.translate("music/queue:ADDED", null, locale)} ${track.requestedBy}`).join("\n");
const embed = interaction.client.embed({ const embed = interaction.client.embed({
title: interaction.translate("music/nowplaying:CURRENTLY_PLAYING", null, locale), title: interaction.translate("music/nowplaying:CURRENTLY_PLAYING", null, locale),
thumbnail: currentTrack.info.artworkUrl || null, thumbnail: currentTrack.thumbnail || null,
description: `${interaction.translate("music/nowplaying:REPEAT", null, locale)}: \`${translated[player.repeatMode]}\`\n${ description: `${interaction.translate("music/nowplaying:REPEAT", null, locale)}: \`${translated[queue.repeatMode]}\`\n${
currentTrack.info.uri.startsWith("./clips") ? `${currentTrack.info.title} (clips)` : `[${currentTrack.info.title}](${currentTrack.info.uri})` currentTrack.url.startsWith("./clips") ? `${currentTrack.title} (clips)` : `[${currentTrack.title}](${currentTrack.url})`
}\n * ${interaction.translate("music/queue:ADDED", null, locale)} ${currentTrack.requester.toString()}\n\n**${interaction.translate("music/queue:NEXT", null, locale)}**\n${info}`, }\n * ${interaction.translate("music/queue:ADDED", null, locale)} ${currentTrack.requestedBy}\n\n**${interaction.translate("music/queue:NEXT", null, locale)}**\n${info}`,
}); });
embeds.push(embed); embeds.push(embed);

View file

@ -40,11 +40,10 @@ class Seek extends BaseCommand {
voice = interaction.member.voice.channel; voice = interaction.member.voice.channel;
if (!voice) return interaction.error("music/play:NO_VOICE_CHANNEL"); if (!voice) return interaction.error("music/play:NO_VOICE_CHANNEL");
const player = client.lavalink.getPlayer(interaction.guildId); const queue = client.player.nodes.get(interaction.guildId);
if (!player) return interaction.error("music/play:NOT_PLAYING"); if (!queue) return interaction.error("music/play:NOT_PLAYING");
await player.seek(time * 1000);
queue.node.seek(time * 1000);
interaction.success("music/seek:SUCCESS", { interaction.success("music/seek:SUCCESS", {
time: `**${time}** ${client.functions.getNoun(time, interaction.translate("misc:NOUNS:SECONDS:1"), interaction.translate("misc:NOUNS:SECONDS:2"), interaction.translate("misc:NOUNS:SECONDS:5"))}`, time: `**${time}** ${client.functions.getNoun(time, interaction.translate("misc:NOUNS:SECONDS:1"), interaction.translate("misc:NOUNS:SECONDS:2"), interaction.translate("misc:NOUNS:SECONDS:5"))}`,
}); });

View file

@ -30,10 +30,10 @@ class Shuffle extends BaseCommand {
const voice = interaction.member.voice.channel; const voice = interaction.member.voice.channel;
if (!voice) return interaction.error("music/play:NO_VOICE_CHANNEL", null, { ephemeral: true }); if (!voice) return interaction.error("music/play:NO_VOICE_CHANNEL", null, { ephemeral: true });
const player = client.lavalink.getPlayer(interaction.guildId); const queue = client.player.nodes.get(interaction.guildId);
if (!player) return interaction.error("music/play:NOT_PLAYING", null, { ephemeral: true }); if (!queue) return interaction.error("music/play:NOT_PLAYING", null, { ephemeral: true });
await player.queue.shuffle(); queue.tracks.shuffle();
interaction.success("music/shuffle:SUCCESS"); interaction.success("music/shuffle:SUCCESS");
} }
} }

View file

@ -40,26 +40,25 @@ class Skip extends BaseCommand {
const voice = interaction.member.voice.channel; const voice = interaction.member.voice.channel;
if (!voice) return interaction.error("music/play:NO_VOICE_CHANNEL"); if (!voice) return interaction.error("music/play:NO_VOICE_CHANNEL");
const player = client.lavalink.getPlayer(interaction.guildId); const queue = client.player.nodes.get(interaction.guildId);
if (!player) return interaction.error("music/play:NOT_PLAYING"); if (!queue) return interaction.error("music/play:NOT_PLAYING");
const position = interaction.options.getInteger("position"); const position = interaction.options.getInteger("position");
if (position) { if (position) {
if (position <= 0) return interaction.error("music/skip:NO_PREV_SONG"); if (position <= 0) return interaction.error("music/skipto:NO_PREV_SONG");
if (player.queue.tracks[position]) { if (queue.tracks.at(position - 1)) {
await player.skip(position); queue.node.skipTo(queue.tracks.at(position - 1));
return interaction.success("music/skip:SUCCESS", { interaction.success("music/skipto:SUCCESS", {
track: player.queue.current.info.title, track: queue.tracks.at(0).title,
}); });
} else return interaction.error("music/skip:ERROR", { position }); } else return interaction.error("music/skipto:ERROR", { position });
} else { } else {
await player.skip(); queue.node.skip();
interaction.success("music/skip:SUCCESS"); interaction.success("music/skip:SUCCESS");
} }
} }
} }

View file

@ -30,10 +30,10 @@ class Stop extends BaseCommand {
const voice = interaction.member.voice.channel; const voice = interaction.member.voice.channel;
if (!voice) return interaction.error("music/play:NO_VOICE_CHANNEL"); if (!voice) return interaction.error("music/play:NO_VOICE_CHANNEL");
const player = client.lavalink.getPlayer(interaction.guildId); const queue = client.player.nodes.get(interaction.guildId);
if (!player) return interaction.error("music/play:NOT_PLAYING"); if (!queue) return interaction.error("music/play:NOT_PLAYING");
await player.destroy(); queue.delete();
interaction.success("music/stop:SUCCESS"); interaction.success("music/stop:SUCCESS");
} }
} }

View file

@ -1,6 +1,5 @@
const { SlashCommandBuilder } = require("discord.js"); const { SlashCommandBuilder } = require("discord.js");
const BaseCommand = require("../../base/BaseCommand"); const BaseCommand = require("../../base/BaseCommand");
const numbers = Array.from({ length: 100 }, (_, k) => k + 1);
class Volume extends BaseCommand { class Volume extends BaseCommand {
/** /**
@ -42,13 +41,13 @@ class Volume extends BaseCommand {
const voice = interaction.member.voice.channel; const voice = interaction.member.voice.channel;
if (!voice) return interaction.error("music/play:NO_VOICE_CHANNEL", null, { ephemeral: true }); if (!voice) return interaction.error("music/play:NO_VOICE_CHANNEL", null, { ephemeral: true });
const player = client.lavalink.getPlayer(interaction.guildId); const queue = client.player.nodes.get(interaction.guildId);
if (!player) return interaction.error("music/play:NOT_PLAYING", null, { ephemeral: true }); if (!queue) return interaction.error("music/play:NOT_PLAYING", null, { ephemeral: true });
const volume = interaction.options.getInteger("int"); const volume = interaction.options.getInteger("int");
if (volume <= 0 || volume > 100) return interaction.error("misc:INVALID_NUMBER_RANGE", { min: 1, max: 100 }); if (volume <= 0 || volume > 100) return interaction.error("misc:INVALID_NUMBER_RANGE", { min: 1, max: 100 });
await player.setVolume(volume); queue.node.setVolume(volume);
interaction.success("music/volume:SUCCESS", { interaction.success("music/volume:SUCCESS", {
volume, volume,
}); });
@ -62,7 +61,7 @@ class Volume extends BaseCommand {
*/ */
async autocompleteRun(client, interaction) { async autocompleteRun(client, interaction) {
const int = interaction.options.getInteger("int"), const int = interaction.options.getInteger("int"),
results = numbers.filter(i => i.toString().includes(int)); results = Array.from({ length: 100 }, (_, k) => k + 1).filter(i => i.toString().includes(int));
return await interaction.respond( return await interaction.respond(
results.slice(0, 25).map(i => ({ results.slice(0, 25).map(i => ({

View file

@ -8,13 +8,10 @@ module.exports = {
/* Set to true for production */ /* Set to true for production */
/* If set to false, commands only will be registered on the support.id server */ /* If set to false, commands only will be registered on the support.id server */
production: true, production: true,
/* Lavalink Nodes */ /* Spotify */
lavalinkNodes: { spotify: {
id: "localhost", clientId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
host: "localhost", clientSecret: "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
port: 2333,
authorization: "strongpassword",
secure: true,
}, },
/* Support server */ /* Support server */
support: { support: {

View file

@ -61,10 +61,6 @@ class Ready extends BaseEvent {
if (status[i + 1]) i++; if (status[i + 1]) i++;
else i = 0; else i = 0;
}, 30 * 1000); // Every 30 seconds }, 30 * 1000); // Every 30 seconds
await client.lavalink.init({ ...client.user });
client.on("raw", d => client.lavalink.sendRawData(d));
client.logger.ready("Lavalink ready.");
} }
} }

View file

@ -10,6 +10,7 @@
}, },
"author": "@jonny_bro", "author": "@jonny_bro",
"dependencies": { "dependencies": {
"@discord-player/extractor": "^4.4.7",
"@discordjs/opus": "^0.9.0", "@discordjs/opus": "^0.9.0",
"@discordjs/rest": "^2.2.0", "@discordjs/rest": "^2.2.0",
"@discordjs/voice": "^0.16.1", "@discordjs/voice": "^0.16.1",
@ -18,16 +19,17 @@
"cron": "^2.4.4", "cron": "^2.4.4",
"discord-api-types": "^0.37.71", "discord-api-types": "^0.37.71",
"discord-giveaways": "^6.0.1", "discord-giveaways": "^6.0.1",
"discord-player": "^6.6.8",
"discord.js": "^14.14.1", "discord.js": "^14.14.1",
"gamedig": "^4.1.0", "gamedig": "^4.1.0",
"i18next": "^21.10.0", "i18next": "^21.10.0",
"i18next-fs-backend": "^1.2.0", "i18next-fs-backend": "^1.2.0",
"lavalink-client": "^2.1.7",
"md5": "^2.3.0", "md5": "^2.3.0",
"moment": "^2.29.4", "moment": "^2.29.4",
"mongoose": "^7.6.3", "mongoose": "^7.6.3",
"ms": "^2.1.3", "ms": "^2.1.3",
"node-fetch": "^2.7.0" "node-fetch": "^2.7.0",
"youtube-ext": "^1.1.23"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^8.56.0" "eslint": "^8.56.0"

View file

@ -5,6 +5,9 @@ settings:
excludeLinksFromLockfile: false excludeLinksFromLockfile: false
dependencies: dependencies:
'@discord-player/extractor':
specifier: ^4.4.7
version: 4.4.7
'@discordjs/opus': '@discordjs/opus':
specifier: ^0.9.0 specifier: ^0.9.0
version: 0.9.0 version: 0.9.0
@ -29,6 +32,9 @@ dependencies:
discord-giveaways: discord-giveaways:
specifier: ^6.0.1 specifier: ^6.0.1
version: 6.0.1(discord.js@14.14.1) version: 6.0.1(discord.js@14.14.1)
discord-player:
specifier: ^6.6.8
version: 6.6.8(@discord-player/extractor@4.4.7)(@discordjs/opus@0.9.0)
discord.js: discord.js:
specifier: ^14.14.1 specifier: ^14.14.1
version: 14.14.1 version: 14.14.1
@ -41,9 +47,6 @@ dependencies:
i18next-fs-backend: i18next-fs-backend:
specifier: ^1.2.0 specifier: ^1.2.0
version: 1.2.0 version: 1.2.0
lavalink-client:
specifier: ^2.1.7
version: 2.1.7
md5: md5:
specifier: ^2.3.0 specifier: ^2.3.0
version: 2.3.0 version: 2.3.0
@ -59,6 +62,9 @@ dependencies:
node-fetch: node-fetch:
specifier: ^2.7.0 specifier: ^2.7.0
version: 2.7.0 version: 2.7.0
youtube-ext:
specifier: ^1.1.23
version: 1.1.23
devDependencies: devDependencies:
eslint: eslint:
@ -79,6 +85,39 @@ packages:
regenerator-runtime: 0.14.0 regenerator-runtime: 0.14.0
dev: false dev: false
/@discord-player/equalizer@0.2.3:
resolution: {integrity: sha512-71UAepYMbHTg2QQLXQAgyuXYHrgAYpJDxjg9dRWfTUNf+zfOAlyJEiRRk/WFhQyGu6m23iLR/H/JxgF4AW8Csg==}
dev: false
/@discord-player/extractor@4.4.7:
resolution: {integrity: sha512-XHG9Y45rQVWk3quf0IJqAj1ybTqiRgAy6vr5hnlaDZeaxXlsHRlDSzmSYl+teFVw2G9bjzR0jIvm8a4BW9hCBw==}
dependencies:
file-type: 16.5.4
genius-lyrics: 4.4.7
isomorphic-unfetch: 4.0.2
node-html-parser: 6.1.13
reverbnation-scraper: 2.0.0
soundcloud.ts: 0.5.2
spotify-url-info: 3.2.13
youtube-sr: 4.3.11
transitivePeerDependencies:
- encoding
dev: false
/@discord-player/ffmpeg@0.1.0:
resolution: {integrity: sha512-0kW6q4gMQN2B4Z4EzmUgXrKQSXXmyhjdZBBZ/6jSHZ9fh814oOu+JXP01VvtWHwTylI7qJHIctEWtSyjEubCJg==}
dev: false
/@discord-player/opus@0.1.2:
resolution: {integrity: sha512-yF0m+pW7H9RCbRcgk/i6vv47tlWxaCHjp6/F0W4GXZMGZ0pcvZaxk8ic7aFPc3+IoDvrAHvWNomLq+JeFzdncA==}
dev: false
/@discord-player/utils@0.2.2:
resolution: {integrity: sha512-UklWUT7BcZEkBgywM9Cmpo2nwj3SQ9Wmhu6ml1uy/YRQnY8IRdZEHD84T2kfjOg4LVZek0ej1VerIqq7a9PAHQ==}
dependencies:
'@discordjs/collection': 1.5.3
dev: false
/@discordjs/builders@1.7.0: /@discordjs/builders@1.7.0:
resolution: {integrity: sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw==} resolution: {integrity: sha512-GDtbKMkg433cOZur8Dv6c25EHxduNIBsxeHrsRoIM8+AwmEZ8r0tEpckx/sHwTLwQPOF3e2JWloZh9ofCaMfAw==}
engines: {node: '>=16.11.0'} engines: {node: '>=16.11.0'}
@ -334,6 +373,10 @@ packages:
defer-to-connect: 2.0.1 defer-to-connect: 2.0.1
dev: false dev: false
/@tokenizer/token@0.3.0:
resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==}
dev: false
/@types/http-cache-semantics@4.0.3: /@types/http-cache-semantics@4.0.3:
resolution: {integrity: sha512-V46MYLFp08Wf2mmaBhvgjStM3tPa+2GAdy/iqoX+noX1//zje2x4XmrIU0cAwyClATsTmahbtoQ2EwP7I5WSiA==} resolution: {integrity: sha512-V46MYLFp08Wf2mmaBhvgjStM3tPa+2GAdy/iqoX+noX1//zje2x4XmrIU0cAwyClATsTmahbtoQ2EwP7I5WSiA==}
dev: false dev: false
@ -611,6 +654,11 @@ packages:
engines: {node: '>= 6'} engines: {node: '>= 6'}
dev: false dev: false
/data-uri-to-buffer@4.0.1:
resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
engines: {node: '>= 12'}
dev: false
/debug@4.3.4: /debug@4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'} engines: {node: '>=6.0'}
@ -678,6 +726,47 @@ packages:
serialize-javascript: 6.0.1 serialize-javascript: 6.0.1
dev: false dev: false
/discord-player@6.6.8(@discord-player/extractor@4.4.7)(@discordjs/opus@0.9.0):
resolution: {integrity: sha512-aZQxtWbHaQPYs0KWU3XObxQLabWg7RWvLlytEitVsqbyfoBFKv2KMYX4swq0/I6eBbu2755z80pbvwU7ycjmsw==}
peerDependencies:
'@discord-player/extractor': ^4.4.7
dependencies:
'@discord-player/equalizer': 0.2.3
'@discord-player/extractor': 4.4.7
'@discord-player/ffmpeg': 0.1.0
'@discord-player/utils': 0.2.2
discord-voip: 0.1.3(@discordjs/opus@0.9.0)
ip: 1.1.9
libsodium-wrappers: 0.7.13
transitivePeerDependencies:
- '@discordjs/opus'
- bufferutil
- ffmpeg-static
- node-opus
- opusscript
- utf-8-validate
dev: false
/discord-voip@0.1.3(@discordjs/opus@0.9.0):
resolution: {integrity: sha512-9DWY5/BLPXeldVwPr8/ggGjggTYOTw77aGQc3+4n5K54bRbbiJ9DUJc+mJzDiSLoHN3f286eRGACJYtrUu27xA==}
engines: {node: '>=16.9.0'}
dependencies:
'@discord-player/ffmpeg': 0.1.0
'@discord-player/opus': 0.1.2
'@types/ws': 8.5.10
discord-api-types: 0.37.71
prism-media: 1.3.5(@discordjs/opus@0.9.0)
tslib: 2.6.2
ws: 8.14.2
transitivePeerDependencies:
- '@discordjs/opus'
- bufferutil
- ffmpeg-static
- node-opus
- opusscript
- utf-8-validate
dev: false
/discord.js@14.14.1: /discord.js@14.14.1:
resolution: {integrity: sha512-/hUVzkIerxKHyRKopJy5xejp4MYKDPTszAnpYxzVVv4qJYf+Tkt+jnT2N29PIPschicaEEpXwF2ARrTYHYwQ5w==} resolution: {integrity: sha512-/hUVzkIerxKHyRKopJy5xejp4MYKDPTszAnpYxzVVv4qJYf+Tkt+jnT2N29PIPschicaEEpXwF2ARrTYHYwQ5w==}
engines: {node: '>=16.11.0'} engines: {node: '>=16.11.0'}
@ -864,6 +953,14 @@ packages:
reusify: 1.0.4 reusify: 1.0.4
dev: true dev: true
/fetch-blob@3.2.0:
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
engines: {node: ^12.20 || >= 14.13}
dependencies:
node-domexception: 1.0.0
web-streams-polyfill: 3.3.3
dev: false
/file-entry-cache@6.0.1: /file-entry-cache@6.0.1:
resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==}
engines: {node: ^10.12.0 || >=12.0.0} engines: {node: ^10.12.0 || >=12.0.0}
@ -871,6 +968,15 @@ packages:
flat-cache: 3.1.1 flat-cache: 3.1.1
dev: true dev: true
/file-type@16.5.4:
resolution: {integrity: sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==}
engines: {node: '>=10'}
dependencies:
readable-web-to-node-stream: 3.0.2
strtok3: 6.3.0
token-types: 4.2.1
dev: false
/find-up@5.0.0: /find-up@5.0.0:
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -897,6 +1003,13 @@ packages:
engines: {node: '>= 14.17'} engines: {node: '>= 14.17'}
dev: false dev: false
/formdata-polyfill@4.0.10:
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
engines: {node: '>=12.20.0'}
dependencies:
fetch-blob: 3.2.0
dev: false
/fs-minipass@2.1.0: /fs-minipass@2.1.0:
resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
engines: {node: '>= 8'} engines: {node: '>= 8'}
@ -949,6 +1062,13 @@ packages:
xmlrpc: 1.3.2 xmlrpc: 1.3.2
dev: false dev: false
/genius-lyrics@4.4.7:
resolution: {integrity: sha512-cgO5nSeFqtLZAUyWB+8XWMRBIRzPUSUC42N3CoDGRgKX1anGAyDUhM6/RVIJXCNnQa6XHZHswKcKgHaRiyl+GQ==}
dependencies:
node-html-parser: 6.1.13
undici: 6.15.0
dev: false
/get-stream@6.0.1: /get-stream@6.0.1:
resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -1007,6 +1127,15 @@ packages:
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
dev: false dev: false
/he@1.2.0:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
dev: false
/himalaya@1.1.0:
resolution: {integrity: sha512-LLase1dHCRMel68/HZTFft0N0wti0epHr3nNY7ynpLbyZpmrKMQ8YIpiOV77TM97cNpC8Wb2n6f66IRggwdWPw==}
dev: false
/htmlparser2@8.0.2: /htmlparser2@8.0.2:
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
dependencies: dependencies:
@ -1055,6 +1184,10 @@ packages:
safer-buffer: 2.1.2 safer-buffer: 2.1.2
dev: false dev: false
/ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
dev: false
/ignore@5.2.4: /ignore@5.2.4:
resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==}
engines: {node: '>= 4'} engines: {node: '>= 4'}
@ -1082,6 +1215,10 @@ packages:
/inherits@2.0.4: /inherits@2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
/ip@1.1.9:
resolution: {integrity: sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==}
dev: false
/ip@2.0.0: /ip@2.0.0:
resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==}
dev: false dev: false
@ -1124,6 +1261,13 @@ packages:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
dev: true dev: true
/isomorphic-unfetch@4.0.2:
resolution: {integrity: sha512-1Yd+CF/7al18/N2BDbsLBcp6RO3tucSW+jcLq24dqdX5MNbCNTw1z4BsGsp4zNmjr/Izm2cs/cEqZPp4kvWSCA==}
dependencies:
node-fetch: 3.3.2
unfetch: 5.0.0
dev: false
/js-yaml@4.1.0: /js-yaml@4.1.0:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
hasBin: true hasBin: true
@ -1152,17 +1296,6 @@ packages:
dependencies: dependencies:
json-buffer: 3.0.1 json-buffer: 3.0.1
/lavalink-client@2.1.7:
resolution: {integrity: sha512-MtXtyTowC+SGmnZRZ7aNuShQ7ADc2ULC8ib31sJTKzYqJ7gvjxfay9P21ewwOHtmnsOvN4999s1bPeP8K6vJOg==}
dependencies:
tslib: 2.6.2
undici: 5.27.2
ws: 8.14.2
transitivePeerDependencies:
- bufferutil
- utf-8-validate
dev: false
/levn@0.4.1: /levn@0.4.1:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
@ -1171,6 +1304,16 @@ packages:
type-check: 0.4.0 type-check: 0.4.0
dev: true dev: true
/libsodium-wrappers@0.7.13:
resolution: {integrity: sha512-kasvDsEi/r1fMzKouIDv7B8I6vNmknXwGiYodErGuESoFTohGSKZplFtVxZqHaoQ217AynyIFgnOVRitpHs0Qw==}
dependencies:
libsodium: 0.7.13
dev: false
/libsodium@0.7.13:
resolution: {integrity: sha512-mK8ju0fnrKXXfleL53vtp9xiPq5hKM0zbDQtcxQIsSmxNgSxqCj6R7Hl9PkrNe2j29T4yoDaF7DJLK9/i5iWUw==}
dev: false
/locate-path@6.0.0: /locate-path@6.0.0:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'} engines: {node: '>=10'}
@ -1378,6 +1521,11 @@ packages:
resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==}
dev: false dev: false
/node-domexception@1.0.0:
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
engines: {node: '>=10.5.0'}
dev: false
/node-fetch@2.7.0: /node-fetch@2.7.0:
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
engines: {node: 4.x || >=6.0.0} engines: {node: 4.x || >=6.0.0}
@ -1390,6 +1538,22 @@ packages:
whatwg-url: 5.0.0 whatwg-url: 5.0.0
dev: false dev: false
/node-fetch@3.3.2:
resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dependencies:
data-uri-to-buffer: 4.0.1
fetch-blob: 3.2.0
formdata-polyfill: 4.0.10
dev: false
/node-html-parser@6.1.13:
resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==}
dependencies:
css-select: 5.1.0
he: 1.2.0
dev: false
/nopt@5.0.0: /nopt@5.0.0:
resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==}
engines: {node: '>=6'} engines: {node: '>=6'}
@ -1493,6 +1657,11 @@ packages:
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true dev: true
/peek-readable@4.1.0:
resolution: {integrity: sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==}
engines: {node: '>=8'}
dev: false
/prelude-ls@1.2.1: /prelude-ls@1.2.1:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'} engines: {node: '>= 0.8.0'}
@ -1571,6 +1740,13 @@ packages:
util-deprecate: 1.0.2 util-deprecate: 1.0.2
dev: false dev: false
/readable-web-to-node-stream@3.0.2:
resolution: {integrity: sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==}
engines: {node: '>=8'}
dependencies:
readable-stream: 3.6.2
dev: false
/regenerator-runtime@0.14.0: /regenerator-runtime@0.14.0:
resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==} resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==}
dev: false dev: false
@ -1596,6 +1772,14 @@ packages:
engines: {iojs: '>=1.0.0', node: '>=0.10.0'} engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
dev: true dev: true
/reverbnation-scraper@2.0.0:
resolution: {integrity: sha512-t1Mew5QC9QEVEry5DXyagvci2O+TgXTGoMHbNoW5NRz6LTOzK/DLHUpnrQwloX8CVX5z1a802vwHM3YgUVOvKg==}
dependencies:
node-fetch: 2.7.0
transitivePeerDependencies:
- encoding
dev: false
/rimraf@3.0.2: /rimraf@3.0.2:
resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
hasBin: true hasBin: true
@ -1699,6 +1883,12 @@ packages:
smart-buffer: 4.2.0 smart-buffer: 4.2.0
dev: false dev: false
/soundcloud.ts@0.5.2:
resolution: {integrity: sha512-/pc72HWYJpSpup+mJBE9pT31JsrMcxJGBlip3Vem+0Fsscg98xh1/7I2nCpAKuMAeV6MVyrisI8TfjO6T7qKJg==}
dependencies:
undici: 5.27.2
dev: false
/sparse-bitfield@3.0.3: /sparse-bitfield@3.0.3:
resolution: {integrity: sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==} resolution: {integrity: sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==}
requiresBuild: true requiresBuild: true
@ -1707,6 +1897,19 @@ packages:
dev: false dev: false
optional: true optional: true
/spotify-uri@4.0.1:
resolution: {integrity: sha512-dEt8UN5fSsZpcPk8HOEHkv29U71kefKjcYt2dopsShrkIZhXtDXe9Xse4xq0GW6831LnEZFry5mpzm1HV/TNLw==}
engines: {node: '>= 16'}
dev: false
/spotify-url-info@3.2.13:
resolution: {integrity: sha512-b1D4n4vnSHf8/HkLT7SIwBsj21t5AV8uhWvzU6c1v8JHS34Ocdb1SsPlannRChCuRAWMKbOEntSn/sP3RhsDfQ==}
engines: {node: '>= 12'}
dependencies:
himalaya: 1.1.0
spotify-uri: 4.0.1
dev: false
/string-to-stream@1.1.1: /string-to-stream@1.1.1:
resolution: {integrity: sha512-QySF2+3Rwq0SdO3s7BAp4x+c3qsClpPQ6abAmb0DGViiSBAkT5kL6JT2iyzEVP+T1SmzHrQD1TwlP9QAHCc+Sw==} resolution: {integrity: sha512-QySF2+3Rwq0SdO3s7BAp4x+c3qsClpPQ6abAmb0DGViiSBAkT5kL6JT2iyzEVP+T1SmzHrQD1TwlP9QAHCc+Sw==}
dependencies: dependencies:
@ -1750,6 +1953,14 @@ packages:
engines: {node: '>=8'} engines: {node: '>=8'}
dev: true dev: true
/strtok3@6.3.0:
resolution: {integrity: sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==}
engines: {node: '>=10'}
dependencies:
'@tokenizer/token': 0.3.0
peek-readable: 4.1.0
dev: false
/supports-color@7.2.0: /supports-color@7.2.0:
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -1772,6 +1983,14 @@ packages:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
dev: true dev: true
/token-types@4.2.1:
resolution: {integrity: sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==}
engines: {node: '>=10'}
dependencies:
'@tokenizer/token': 0.3.0
ieee754: 1.2.1
dev: false
/tr46@0.0.3: /tr46@0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
dev: false dev: false
@ -1814,6 +2033,15 @@ packages:
'@fastify/busboy': 2.0.0 '@fastify/busboy': 2.0.0
dev: false dev: false
/undici@6.15.0:
resolution: {integrity: sha512-VviMt2tlMg1BvQ0FKXxrz1eJuyrcISrL2sPfBf7ZskX/FCEc/7LeThQaoygsMJpNqrATWQIsRVx+1Dpe4jaYuQ==}
engines: {node: '>=18.17'}
dev: false
/unfetch@5.0.0:
resolution: {integrity: sha512-3xM2c89siXg0nHvlmYsQ2zkLASvVMBisZm5lF3gFDqfF2xonNStDJyMpvaOBe0a1Edxmqrf2E0HBdmy9QyZaeg==}
dev: false
/uri-js@4.4.1: /uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
dependencies: dependencies:
@ -1828,6 +2056,11 @@ packages:
resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==} resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==}
dev: false dev: false
/web-streams-polyfill@3.3.3:
resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
engines: {node: '>= 8'}
dev: false
/webidl-conversions@3.0.1: /webidl-conversions@3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
dev: false dev: false
@ -1903,3 +2136,13 @@ packages:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'} engines: {node: '>=10'}
dev: true dev: true
/youtube-ext@1.1.23:
resolution: {integrity: sha512-YqOg3pQONwIZ5OMyLaDzAKmyN4ZsLzhCll20VGL20Z6aakNK6n9hHEdf7Bn3VkGw8/ehub7OpoqepHzBkomk+Q==}
dependencies:
undici: 6.15.0
dev: false
/youtube-sr@4.3.11:
resolution: {integrity: sha512-3oHiS2x7PpMiDRW7Cq8nz1bkAIBOJHoOwkPl/oncM/+A9/3xxMDgMLGW2dsBEP1DHFyRXYTVABgfbdwHF8sXXQ==}
dev: false