@ariijs/lavalink-client
Version:
arii "plugin" / extras for lavalink-client package. fully compatible with commonjs and esm enviroments.
143 lines (142 loc) • 6.46 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Player = void 0;
const lavalink_client_1 = require("lavalink-client");
const queue_js_1 = require("./queue.js");
const utils_1 = require("@ariijs/utils");
class Player extends lavalink_client_1.Player {
LavalinkManager;
queue;
/** returns true if the player is paused (track paused) */
paused = false;
constructor(options, lavalinkManager) {
super(options, lavalinkManager);
this.LavalinkManager = lavalinkManager;
let queueSaver = this.LavalinkManager.options.queueOptions ? new lavalink_client_1.QueueSaver(this.LavalinkManager.options.queueOptions) : undefined;
this.queue = new queue_js_1.Queue(this.guildId, this.LavalinkManager, {}, queueSaver, this.LavalinkManager.options.queueOptions); // Initialize with AriiQueue
}
;
/**
* Skip the current song, or a specific amount of songs
* @param skipTo provide the index of the next track to skip to or a string to search for a track title
* @param throwError if true, throws an error if the skip fails
* @param [withPrevious=false] set true to enable full queue skipping (previous tracks included)
* @param searchOptions search options for the skipTo string search
*/
async skip(skipTo = 0, throwError = true, withPrevious = false, searchOptions) {
let arr = this.queue.tracks;
const withError = (throwError || (typeof skipTo === "boolean" && skipTo === true));
const withAuthor = searchOptions?.withAuthor ?? false;
const threshold = searchOptions?.threshold ?? 20; // Use user-provided threshold or default to 20
if (withPrevious) {
arr = [];
if (this.queue.previous.length)
arr.push(...[...this.queue.previous].reverse());
if (this.queue.current)
arr.push(this.queue.current);
if (this.queue.tracks.length)
arr.push(...this.queue.tracks);
}
;
if (!arr.length && withError) {
throw new RangeError("Can't skip more than the queue size");
}
let targetIndex = 0;
if (typeof skipTo === "number" || (typeof skipTo === "string" && !isNaN(Number(skipTo)))) {
targetIndex = Number(skipTo);
if (targetIndex >= arr.length || targetIndex < 0) {
if (withError)
throw new RangeError("Can't skip more than the queue size");
else
return this;
}
;
}
else if (typeof skipTo === "string") {
const lowerSkipTo = skipTo.toLowerCase(); // allow accented characters to be used in the search
const titles = arr.map(track => {
let t = track.info.title.toLowerCase(); // allow accented characters to be used in the search
if (track.info.author && withAuthor)
t += " " + track.info.author.toLowerCase(); // allow accented characters to be used in the search
return t;
});
const result = utils_1.Utils.findMostSimilar(lowerSkipTo, titles, threshold); // Use user-provided threshold
if (!result) {
if (withError)
throw new RangeError("No sufficiently similar track found matching the provided title");
else
return this;
}
targetIndex = titles.indexOf(result.match); // Get the index of the best match
}
;
let currentTrackIndex = this.queue.previous.length;
if (["string", "number"].includes(typeof skipTo) && withPrevious) {
if (targetIndex > currentTrackIndex) {
const set = arr.slice(0, targetIndex);
await this.queue.setPrevious([...set].reverse());
await this.queue.setTracks(arr.slice(targetIndex));
}
else if (targetIndex < currentTrackIndex) {
const set = arr.slice(targetIndex);
await this.queue.setTracks(set);
await this.queue.setPrevious([...arr.slice(0, targetIndex)].reverse());
}
}
else if (skipTo && !withPrevious && targetIndex > 1) {
await this.queue.splice(0, targetIndex - 1);
}
;
if (!this.playing && !this.queue.current) {
this.play();
return this;
}
;
const now = performance.now();
this.set("internal_skipped", true);
if (this.queue.current) {
await this.node.updatePlayer({ guildId: this.guildId, playerOptions: { track: { encoded: null }, paused: false } });
if (["string", "number"].includes(typeof skipTo) && withPrevious)
await this.queue.shiftPrevious();
}
else {
await this.node.updatePlayer({ guildId: this.guildId, playerOptions: { track: { encoded: null }, paused: false } });
}
;
this.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
return this;
}
;
/**
* similar to skip, but it goes to the previous track. use this instead of adding the previous track to the queue and skipping for yourself
* @param throwError if true, it throws an error if there's no previous track
* @returns the player
*/
async previous(throwError = true) {
const previousTrack = this.queue.previous[0];
const currentTrack = this.queue.current;
if (!previousTrack) {
if (throwError)
throw new RangeError("there's no previous track");
return null;
}
const now = performance.now();
if (currentTrack)
await this.queue.add(currentTrack, 0); // add current track next
await this.queue.add(previousTrack, 0); // add previous track next (so current track is after the previous track added next now)
this.queue.previous.shift(); // remove previous track from previous list cause it's gonna go next now
try {
await this.skip();
}
catch (error) {
throw error;
}
;
if (currentTrack)
this.queue.previous.shift();
this.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
return this;
}
;
}
exports.Player = Player;