UNPKG

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