lavalink-client 2.9.9 → 2.9.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +102 -51
- package/dist/index.d.cts +30 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +102 -51
- package/dist/index.mjs +102 -51
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2743,7 +2743,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2743
2743
|
}
|
|
2744
2744
|
/** @private util function for handling trackStart event */
|
|
2745
2745
|
async trackStart(player, track, payload) {
|
|
2746
|
-
if (!player.
|
|
2746
|
+
if (!player.getData("internal_nodeChanging")) {
|
|
2747
2747
|
player.playing = true;
|
|
2748
2748
|
player.paused = false;
|
|
2749
2749
|
}
|
|
@@ -2771,7 +2771,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2771
2771
|
}
|
|
2772
2772
|
/** @private util function for handling trackEnd event */
|
|
2773
2773
|
async trackEnd(player, track, payload) {
|
|
2774
|
-
if (player.
|
|
2774
|
+
if (player.getData("internal_nodeChanging") === true) return;
|
|
2775
2775
|
const trackToUse = track || this.getTrackOfPayload(payload);
|
|
2776
2776
|
if (payload.reason === "replaced") {
|
|
2777
2777
|
this._emitDebugEvent("TrackEndReplaced" /* TrackEndReplaced */, {
|
|
@@ -2782,10 +2782,10 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2782
2782
|
this._LManager.emit("trackEnd", player, trackToUse, payload);
|
|
2783
2783
|
return;
|
|
2784
2784
|
}
|
|
2785
|
-
if (!player.queue.tracks.length && (player.repeatMode === "off" || player.
|
|
2785
|
+
if (!player.queue.tracks.length && (player.repeatMode === "off" || player.getData("internal_stopPlaying")))
|
|
2786
2786
|
return this.queueEnd(player, track, payload);
|
|
2787
2787
|
if (["loadFailed", "cleanup"].includes(payload.reason)) {
|
|
2788
|
-
if (player.
|
|
2788
|
+
if (player.getData("internal_destroystatus") === true) return;
|
|
2789
2789
|
await queueTrackEnd(player);
|
|
2790
2790
|
if (!player.queue.current) return this.queueEnd(player, trackToUse, payload);
|
|
2791
2791
|
this._LManager.emit("trackEnd", player, trackToUse, payload);
|
|
@@ -2794,7 +2794,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2794
2794
|
}
|
|
2795
2795
|
return;
|
|
2796
2796
|
}
|
|
2797
|
-
if (player.repeatMode !== "track" || player.
|
|
2797
|
+
if (player.repeatMode !== "track" || player.getData("internal_skipped")) await queueTrackEnd(player);
|
|
2798
2798
|
else if (trackToUse && !trackToUse?.pluginInfo?.clientData?.previousTrack) {
|
|
2799
2799
|
player.queue.previous.unshift(trackToUse);
|
|
2800
2800
|
if (player.queue.previous.length > player.queue.options.maxPreviousTracks)
|
|
@@ -2802,7 +2802,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2802
2802
|
await player.queue.utils.save();
|
|
2803
2803
|
}
|
|
2804
2804
|
if (!player.queue.current) return this.queueEnd(player, trackToUse, payload);
|
|
2805
|
-
player.
|
|
2805
|
+
player.setData("internal_skipped", false);
|
|
2806
2806
|
this._LManager.emit("trackEnd", player, trackToUse, payload);
|
|
2807
2807
|
if (this._LManager.options.autoSkip && player.queue.current) {
|
|
2808
2808
|
player.play({ noReplace: true });
|
|
@@ -2812,10 +2812,10 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2812
2812
|
/** @private util function for handling trackStuck event */
|
|
2813
2813
|
async trackStuck(player, track, payload) {
|
|
2814
2814
|
if (this._LManager.options.playerOptions.maxErrorsPerTime?.threshold > 0 && this._LManager.options.playerOptions.maxErrorsPerTime?.maxAmount >= 0) {
|
|
2815
|
-
const oldTimestamps = (player.
|
|
2815
|
+
const oldTimestamps = (player.getData("internal_erroredTracksTimestamps") || []).filter(
|
|
2816
2816
|
(v) => Date.now() - v < this._LManager.options.playerOptions.maxErrorsPerTime?.threshold
|
|
2817
2817
|
);
|
|
2818
|
-
player.
|
|
2818
|
+
player.setData("internal_erroredTracksTimestamps", [...oldTimestamps, Date.now()]);
|
|
2819
2819
|
if (oldTimestamps.length >= this._LManager.options.playerOptions.maxErrorsPerTime?.maxAmount) {
|
|
2820
2820
|
this._emitDebugEvent("TrackStuckMaxTracksErroredPerTime" /* TrackStuckMaxTracksErroredPerTime */, {
|
|
2821
2821
|
state: "log",
|
|
@@ -2827,7 +2827,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2827
2827
|
}
|
|
2828
2828
|
}
|
|
2829
2829
|
this._LManager.emit("trackStuck", player, track || this.getTrackOfPayload(payload), payload);
|
|
2830
|
-
if (!player.queue.tracks.length && (player.repeatMode === "off" || player.
|
|
2830
|
+
if (!player.queue.tracks.length && (player.repeatMode === "off" || player.getData("internal_stopPlaying"))) {
|
|
2831
2831
|
try {
|
|
2832
2832
|
await player.node.updatePlayer({
|
|
2833
2833
|
guildId: player.guildId,
|
|
@@ -2850,10 +2850,10 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2850
2850
|
/** @private util function for handling trackError event */
|
|
2851
2851
|
async trackError(player, track, payload) {
|
|
2852
2852
|
if (this._LManager.options.playerOptions.maxErrorsPerTime?.threshold > 0 && this._LManager.options.playerOptions.maxErrorsPerTime?.maxAmount >= 0) {
|
|
2853
|
-
const oldTimestamps = (player.
|
|
2853
|
+
const oldTimestamps = (player.getData("internal_erroredTracksTimestamps") || []).filter(
|
|
2854
2854
|
(v) => Date.now() - v < this._LManager.options.playerOptions.maxErrorsPerTime?.threshold
|
|
2855
2855
|
);
|
|
2856
|
-
player.
|
|
2856
|
+
player.setData("internal_erroredTracksTimestamps", [...oldTimestamps, Date.now()]);
|
|
2857
2857
|
if (oldTimestamps.length >= this._LManager.options.playerOptions.maxErrorsPerTime?.maxAmount) {
|
|
2858
2858
|
this._emitDebugEvent("TrackErrorMaxTracksErroredPerTime" /* TrackErrorMaxTracksErroredPerTime */, {
|
|
2859
2859
|
state: "log",
|
|
@@ -2937,7 +2937,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2937
2937
|
};
|
|
2938
2938
|
r.body = safeStringify(segments.map((v) => v.toLowerCase()));
|
|
2939
2939
|
});
|
|
2940
|
-
player.
|
|
2940
|
+
player.setData(
|
|
2941
2941
|
"internal_sponsorBlockCategories",
|
|
2942
2942
|
segments.map((v) => v.toLowerCase())
|
|
2943
2943
|
);
|
|
@@ -2965,7 +2965,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2965
2965
|
await this.request(`/sessions/${this.sessionId}/players/${player.guildId}/sponsorblock/categories`, (r) => {
|
|
2966
2966
|
r.method = "DELETE";
|
|
2967
2967
|
});
|
|
2968
|
-
player.
|
|
2968
|
+
player.setData("internal_sponsorBlockCategories", []);
|
|
2969
2969
|
this._emitDebugEvent("DeleteSponsorBlock" /* DeleteSponsorBlock */, {
|
|
2970
2970
|
state: "log",
|
|
2971
2971
|
message: `SponsorBlock was deleted for Player: ${player.guildId}`,
|
|
@@ -2975,26 +2975,26 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2975
2975
|
}
|
|
2976
2976
|
/** private util function for handling the queue end event */
|
|
2977
2977
|
async queueEnd(player, track, payload) {
|
|
2978
|
-
if (player.
|
|
2978
|
+
if (player.getData("internal_nodeChanging") === true) return;
|
|
2979
2979
|
player.queue.current = null;
|
|
2980
2980
|
player.playing = false;
|
|
2981
|
-
player.
|
|
2981
|
+
player.setData("internal_stopPlaying", void 0);
|
|
2982
2982
|
this._emitDebugEvent("QueueEnded" /* QueueEnded */, {
|
|
2983
2983
|
state: "log",
|
|
2984
2984
|
message: `Queue Ended because no more Tracks were in the Queue, due to EventName: "${payload.type}"`,
|
|
2985
2985
|
functionLayer: "LavalinkNode > queueEnd()"
|
|
2986
2986
|
});
|
|
2987
|
-
if (typeof this._LManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction === "function" && typeof player.
|
|
2987
|
+
if (typeof this._LManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction === "function" && typeof player.getData("internal_autoplayStopPlaying") === "undefined") {
|
|
2988
2988
|
this._emitDebugEvent("AutoplayExecution" /* AutoplayExecution */, {
|
|
2989
2989
|
state: "log",
|
|
2990
2990
|
message: `Now Triggering Autoplay.`,
|
|
2991
2991
|
functionLayer: "LavalinkNode > queueEnd() > autoplayFunction"
|
|
2992
2992
|
});
|
|
2993
|
-
const previousAutoplayTime = player.
|
|
2993
|
+
const previousAutoplayTime = player.getData("internal_previousautoplay");
|
|
2994
2994
|
const duration = previousAutoplayTime ? Date.now() - previousAutoplayTime : 0;
|
|
2995
|
-
if (!duration || duration > this._LManager.options.playerOptions.minAutoPlayMs || !!player.
|
|
2995
|
+
if (!duration || duration > this._LManager.options.playerOptions.minAutoPlayMs || !!player.getData("internal_skipped")) {
|
|
2996
2996
|
await this._LManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction(player, track);
|
|
2997
|
-
player.
|
|
2997
|
+
player.setData("internal_previousautoplay", Date.now());
|
|
2998
2998
|
if (player.queue.tracks.length > 0) await queueTrackEnd(player);
|
|
2999
2999
|
else
|
|
3000
3000
|
this._emitDebugEvent("AutoplayNoSongsAdded" /* AutoplayNoSongsAdded */, {
|
|
@@ -3014,8 +3014,8 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
3014
3014
|
});
|
|
3015
3015
|
}
|
|
3016
3016
|
}
|
|
3017
|
-
player.
|
|
3018
|
-
player.
|
|
3017
|
+
player.setData("internal_skipped", false);
|
|
3018
|
+
player.setData("internal_autoplayStopPlaying", void 0);
|
|
3019
3019
|
if (track && !track?.pluginInfo?.clientData?.previousTrack) {
|
|
3020
3020
|
player.queue.previous.unshift(track);
|
|
3021
3021
|
if (player.queue.previous.length > player.queue.options.maxPreviousTracks)
|
|
@@ -3040,11 +3040,11 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
3040
3040
|
player,
|
|
3041
3041
|
this._LManager.options.playerOptions.onEmptyQueue?.destroyAfterMs
|
|
3042
3042
|
);
|
|
3043
|
-
if (player.
|
|
3044
|
-
player.
|
|
3043
|
+
if (player.getData("internal_queueempty")) clearTimeout(player.getData("internal_queueempty"));
|
|
3044
|
+
player.setData(
|
|
3045
3045
|
"internal_queueempty",
|
|
3046
3046
|
setTimeout(() => {
|
|
3047
|
-
player.
|
|
3047
|
+
player.setData("internal_queueempty", void 0);
|
|
3048
3048
|
if (player.queue.current) {
|
|
3049
3049
|
return this._LManager.emit("playerQueueEmptyCancel", player);
|
|
3050
3050
|
}
|
|
@@ -3138,6 +3138,50 @@ var NodeLinkNode = class extends LavalinkNode {
|
|
|
3138
3138
|
}
|
|
3139
3139
|
this.nodeType = "NodeLink";
|
|
3140
3140
|
}
|
|
3141
|
+
/**
|
|
3142
|
+
* Uses the gapless feature to set the next track to be played.
|
|
3143
|
+
* @param player current player
|
|
3144
|
+
* @param track if no track provided, it will use the next track from queue
|
|
3145
|
+
*/
|
|
3146
|
+
async setNextTrackGapLess(player, track) {
|
|
3147
|
+
if (!this.sessionId) throw new Error("The Lavalink Node is either not ready, or not up to date!");
|
|
3148
|
+
const nextTrack = track || player.queue.tracks[0];
|
|
3149
|
+
if (!nextTrack) throw new Error("No track provided");
|
|
3150
|
+
await this.updatePlayer({
|
|
3151
|
+
guildId: player.guildId,
|
|
3152
|
+
// @ts-expect-error - nextTrack is not a valid property of LavalinkPlayOptions but for NodeLink it is
|
|
3153
|
+
playerOptions: { nextTrack: { encoded: nextTrack.encoded, userData: nextTrack.userData || {} } }
|
|
3154
|
+
});
|
|
3155
|
+
return true;
|
|
3156
|
+
}
|
|
3157
|
+
/**
|
|
3158
|
+
* Removes the nextTrackGapLess configuration
|
|
3159
|
+
* @param player current player
|
|
3160
|
+
* @param track if no track provided, it will use the next track from queue
|
|
3161
|
+
*/
|
|
3162
|
+
async removeNextTrackGapLess(player) {
|
|
3163
|
+
if (!this.sessionId) throw new Error("The Lavalink Node is either not ready, or not up to date!");
|
|
3164
|
+
await this.updatePlayer({
|
|
3165
|
+
guildId: player.guildId,
|
|
3166
|
+
// @ts-expect-error - nextTrack is not a valid property of LavalinkPlayOptions but for NodeLink it is
|
|
3167
|
+
playerOptions: { nextTrack: { encoded: null } }
|
|
3168
|
+
});
|
|
3169
|
+
return true;
|
|
3170
|
+
}
|
|
3171
|
+
/**
|
|
3172
|
+
* Retrieves the meaning of a track.
|
|
3173
|
+
* @param track
|
|
3174
|
+
* @returns {MeaningResponse}
|
|
3175
|
+
* @link {https://nodelink.js.org/docs/api/nodelink-features#meaning-system}
|
|
3176
|
+
*/
|
|
3177
|
+
async getMeaning(track) {
|
|
3178
|
+
if (!this.sessionId) throw new Error("The Lavalink Node is either not ready, or not up to date!");
|
|
3179
|
+
const encodedTrack = track?.encoded;
|
|
3180
|
+
if (!encodedTrack) throw new Error("No track provided");
|
|
3181
|
+
return await this.request(`/meaning?encodedTrack=${encodedTrack}`, (m) => {
|
|
3182
|
+
m.method = "GET";
|
|
3183
|
+
});
|
|
3184
|
+
}
|
|
3141
3185
|
/**
|
|
3142
3186
|
* Adds a new audio track to be mixed over the current playback.
|
|
3143
3187
|
* @param player The player to add the mixer layer to.
|
|
@@ -3155,7 +3199,7 @@ var NodeLinkNode = class extends LavalinkNode {
|
|
|
3155
3199
|
//identifier: trackToAdd.info?.identifier, // atm not supported
|
|
3156
3200
|
userData: trackToAdd.userData
|
|
3157
3201
|
},
|
|
3158
|
-
volume:
|
|
3202
|
+
volume: volume / 100
|
|
3159
3203
|
});
|
|
3160
3204
|
});
|
|
3161
3205
|
}
|
|
@@ -3182,7 +3226,7 @@ var NodeLinkNode = class extends LavalinkNode {
|
|
|
3182
3226
|
await this.request(`/sessions/${this.sessionId}/players/${player.guildId}/mix/${mixId}`, (m) => {
|
|
3183
3227
|
m.method = "PATCH";
|
|
3184
3228
|
m.body = safeStringify({
|
|
3185
|
-
volume:
|
|
3229
|
+
volume: volume / 100
|
|
3186
3230
|
});
|
|
3187
3231
|
});
|
|
3188
3232
|
return true;
|
|
@@ -3354,7 +3398,7 @@ var NodeLinkNode = class extends LavalinkNode {
|
|
|
3354
3398
|
*/
|
|
3355
3399
|
async loadDirectStream(track, volume, position, filters) {
|
|
3356
3400
|
let requestPath = `/loadstream?encodedTrack=${track.encoded}`;
|
|
3357
|
-
if (volume && volume > 0 && volume <= 100) requestPath += `&volume=${
|
|
3401
|
+
if (volume && volume > 0 && volume <= 100) requestPath += `&volume=${volume / 100}`;
|
|
3358
3402
|
if (position && position > 0) requestPath += `&position=${position}`;
|
|
3359
3403
|
if (filters) requestPath += `&filters=${typeof filters === "object" ? safeStringify(filters) : filters}`;
|
|
3360
3404
|
const res = await this.rawRequest(requestPath, (m) => {
|
|
@@ -3924,8 +3968,8 @@ var FilterManager = class {
|
|
|
3924
3968
|
this.player.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
|
|
3925
3969
|
return;
|
|
3926
3970
|
}
|
|
3927
|
-
privateNot0(value) {
|
|
3928
|
-
return typeof value === "number" && value !==
|
|
3971
|
+
privateNot0(value, numToCheckAgains = 0) {
|
|
3972
|
+
return typeof value === "number" && value !== numToCheckAgains;
|
|
3929
3973
|
}
|
|
3930
3974
|
getLavalinkFilterData() {
|
|
3931
3975
|
return this.data.pluginFilters?.["lavalink-filter-plugin"] || {
|
|
@@ -3972,7 +4016,8 @@ var FilterManager = class {
|
|
|
3972
4016
|
this.filters.lowPass = this.privateNot0(this.data.lowPass?.smoothing);
|
|
3973
4017
|
this.filters.nodeLinkEcho = this.privateNot0(this.data.echo?.delay) || this.privateNot0(this.data.echo?.feedback) || this.privateNot0(this.data.echo?.mix);
|
|
3974
4018
|
this.filters.nodeLinkChorus = this.privateNot0(this.data.chorus?.rate) || this.privateNot0(this.data.chorus?.depth) || this.privateNot0(this.data.chorus?.delay) || this.privateNot0(this.data.chorus?.mix) || this.privateNot0(this.data.chorus?.feedback);
|
|
3975
|
-
this.filters.nodeLinkCompressor = this.privateNot0(this.data.compressor?.threshold) || this.privateNot0(this.data.compressor?.ratio) ||
|
|
4019
|
+
this.filters.nodeLinkCompressor = this.privateNot0(this.data.compressor?.threshold) || this.privateNot0(this.data.compressor?.ratio, 1) || // here "1" is the default
|
|
4020
|
+
this.privateNot0(this.data.compressor?.attack) || this.privateNot0(this.data.compressor?.release) || this.privateNot0(this.data.compressor?.gain);
|
|
3976
4021
|
this.filters.nodeLinkHighPass = this.privateNot0(this.data.highPass?.smoothing);
|
|
3977
4022
|
this.filters.nodeLinkPhaser = this.privateNot0(this.data.phaser?.stages) || this.privateNot0(this.data.phaser?.rate) || this.privateNot0(this.data.phaser?.depth) || this.privateNot0(this.data.phaser?.feedback) || this.privateNot0(this.data.phaser?.mix) || this.privateNot0(this.data.phaser?.minFrequency) || this.privateNot0(this.data.phaser?.maxFrequency);
|
|
3978
4023
|
this.filters.nodeLinkSpatial = this.privateNot0(this.data.spatial?.depth) || this.privateNot0(this.data.spatial?.rate);
|
|
@@ -5335,7 +5380,7 @@ var Player = class {
|
|
|
5335
5380
|
*/
|
|
5336
5381
|
constructor(options, LavalinkManager2, dontEmitPlayerCreateEvent) {
|
|
5337
5382
|
if (typeof options?.customData === "object")
|
|
5338
|
-
for (const [key, value] of Object.entries(options.customData)) this.
|
|
5383
|
+
for (const [key, value] of Object.entries(options.customData)) this.setData(key, value);
|
|
5339
5384
|
this.options = options;
|
|
5340
5385
|
this.filterManager = new FilterManager(this);
|
|
5341
5386
|
this.LavalinkManager = LavalinkManager2;
|
|
@@ -5444,15 +5489,15 @@ var Player = class {
|
|
|
5444
5489
|
* @param options
|
|
5445
5490
|
*/
|
|
5446
5491
|
async play(options = {}) {
|
|
5447
|
-
if (this.
|
|
5492
|
+
if (this.getData("internal_queueempty")) {
|
|
5448
5493
|
this._emitDebugEvent("PlayerPlayQueueEmptyTimeoutClear" /* PlayerPlayQueueEmptyTimeoutClear */, {
|
|
5449
5494
|
state: "log",
|
|
5450
5495
|
message: `Player was called to play something, while there was a queueEmpty Timeout set, clearing the timeout.`,
|
|
5451
5496
|
functionLayer: "Player > play()"
|
|
5452
5497
|
});
|
|
5453
5498
|
this.LavalinkManager.emit("playerQueueEmptyCancel", this);
|
|
5454
|
-
clearTimeout(this.
|
|
5455
|
-
this.
|
|
5499
|
+
clearTimeout(this.getData("internal_queueempty"));
|
|
5500
|
+
this.setData("internal_queueempty", void 0);
|
|
5456
5501
|
}
|
|
5457
5502
|
if (options?.clientTrack && (this.LavalinkManager.utils.isTrack(options?.clientTrack) || this.LavalinkManager.utils.isUnresolvedTrack(options.clientTrack))) {
|
|
5458
5503
|
if (this.LavalinkManager.utils.isUnresolvedTrack(options.clientTrack)) {
|
|
@@ -5800,7 +5845,7 @@ var Player = class {
|
|
|
5800
5845
|
}
|
|
5801
5846
|
if (!this.playing && !this.queue.current) return this.play(), this;
|
|
5802
5847
|
const now = performance.now();
|
|
5803
|
-
this.
|
|
5848
|
+
this.setData("internal_skipped", true);
|
|
5804
5849
|
await this.node.updatePlayer({
|
|
5805
5850
|
guildId: this.guildId,
|
|
5806
5851
|
playerOptions: { track: { encoded: null }, paused: false }
|
|
@@ -5813,14 +5858,20 @@ var Player = class {
|
|
|
5813
5858
|
* @returns
|
|
5814
5859
|
*/
|
|
5815
5860
|
async stopPlaying(clearQueue = true, executeAutoplay = false) {
|
|
5816
|
-
this.
|
|
5861
|
+
this.setData("internal_stopPlaying", true);
|
|
5817
5862
|
if (this.queue.tracks.length && clearQueue === true) await this.queue.splice(0, this.queue.tracks.length);
|
|
5818
|
-
if (executeAutoplay === false) this.
|
|
5819
|
-
else this.
|
|
5863
|
+
if (executeAutoplay === false) this.setData("internal_autoplayStopPlaying", true);
|
|
5864
|
+
else this.setData("internal_autoplayStopPlaying", void 0);
|
|
5820
5865
|
const now = performance.now();
|
|
5821
5866
|
await this.node.updatePlayer({
|
|
5822
5867
|
guildId: this.guildId,
|
|
5823
|
-
playerOptions:
|
|
5868
|
+
playerOptions: this.node.isNodeLink() ? {
|
|
5869
|
+
track: { encoded: null },
|
|
5870
|
+
// @ts-expect-error - nextTrack is not a valid property of LavalinkPlayOptions but for NodeLink it is
|
|
5871
|
+
nextTrack: { encoded: null }
|
|
5872
|
+
} : {
|
|
5873
|
+
track: { encoded: null }
|
|
5874
|
+
}
|
|
5824
5875
|
});
|
|
5825
5876
|
this.paused = false;
|
|
5826
5877
|
this.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
|
|
@@ -5891,11 +5942,11 @@ var Player = class {
|
|
|
5891
5942
|
console.log(
|
|
5892
5943
|
`Lavalink-Client-Debug | PlayerDestroy [::] destroy Function, [guildId ${this.guildId}] - Destroy-Reason: ${String(reason)}`
|
|
5893
5944
|
);
|
|
5894
|
-
if (this.
|
|
5895
|
-
clearTimeout(this.
|
|
5896
|
-
this.
|
|
5945
|
+
if (this.getData("internal_queueempty")) {
|
|
5946
|
+
clearTimeout(this.getData("internal_queueempty"));
|
|
5947
|
+
this.setData("internal_queueempty", void 0);
|
|
5897
5948
|
}
|
|
5898
|
-
if (this.
|
|
5949
|
+
if (this.getData("internal_destroystatus") === true) {
|
|
5899
5950
|
this._emitDebugEvent("PlayerDestroyingSomewhereElse" /* PlayerDestroyingSomewhereElse */, {
|
|
5900
5951
|
state: "warn",
|
|
5901
5952
|
message: `Player is already destroying somewhere else..`,
|
|
@@ -5907,9 +5958,9 @@ var Player = class {
|
|
|
5907
5958
|
);
|
|
5908
5959
|
return;
|
|
5909
5960
|
}
|
|
5910
|
-
this.
|
|
5961
|
+
this.setData("internal_destroystatus", true);
|
|
5911
5962
|
if (disconnect) await this.disconnect(true);
|
|
5912
|
-
else this.
|
|
5963
|
+
else this.setData("internal_destroywithoutdisconnect", true);
|
|
5913
5964
|
await this.queue.utils.destroy();
|
|
5914
5965
|
this.LavalinkManager.deletePlayer(this.guildId);
|
|
5915
5966
|
await this.node.destroyPlayer(this.guildId);
|
|
@@ -5984,7 +6035,7 @@ var Player = class {
|
|
|
5984
6035
|
if (!updateNode) throw new Error("Could not find the new Node");
|
|
5985
6036
|
if (!updateNode.connected) throw new Error("The provided Node is not active or disconnected");
|
|
5986
6037
|
if (this.node.id === updateNode.id) throw new Error("Player is already on the provided Node");
|
|
5987
|
-
if (this.
|
|
6038
|
+
if (this.getData("internal_nodeChanging") === true)
|
|
5988
6039
|
throw new Error("Player is already changing the node please wait");
|
|
5989
6040
|
if (checkSources) {
|
|
5990
6041
|
const isDefaultSource = () => {
|
|
@@ -6022,7 +6073,7 @@ var Player = class {
|
|
|
6022
6073
|
const currentTrack = this.queue.current;
|
|
6023
6074
|
if (!this.voice.endpoint || !this.voice.sessionId || !this.voice.token)
|
|
6024
6075
|
throw new Error("Voice Data is missing, can't change the node");
|
|
6025
|
-
this.
|
|
6076
|
+
this.setData("internal_nodeChanging", true);
|
|
6026
6077
|
if (this.node.connected) await this.node.destroyPlayer(this.guildId);
|
|
6027
6078
|
this.node = updateNode;
|
|
6028
6079
|
const now = performance.now();
|
|
@@ -6030,7 +6081,7 @@ var Player = class {
|
|
|
6030
6081
|
await this.connect();
|
|
6031
6082
|
const hasSponsorBlock = !this.node._checkForPlugins || this.node.info?.plugins?.find((v) => v.name === "sponsorblock-plugin");
|
|
6032
6083
|
if (hasSponsorBlock) {
|
|
6033
|
-
const sponsorBlockCategories = this.
|
|
6084
|
+
const sponsorBlockCategories = this.getData("internal_sponsorBlockCategories");
|
|
6034
6085
|
if (Array.isArray(sponsorBlockCategories) && sponsorBlockCategories.length) {
|
|
6035
6086
|
await this.setSponsorBlock(sponsorBlockCategories).catch((error) => {
|
|
6036
6087
|
this._emitDebugEvent("PlayerChangeNode" /* PlayerChangeNode */, {
|
|
@@ -6081,7 +6132,7 @@ var Player = class {
|
|
|
6081
6132
|
});
|
|
6082
6133
|
throw new Error(`Failed to change the node: ${error}`);
|
|
6083
6134
|
} finally {
|
|
6084
|
-
this.
|
|
6135
|
+
this.setData("internal_nodeChanging", void 0);
|
|
6085
6136
|
}
|
|
6086
6137
|
}
|
|
6087
6138
|
/**
|
|
@@ -6471,7 +6522,7 @@ var LavalinkManager = class _LavalinkManager extends import_node_events2.EventEm
|
|
|
6471
6522
|
deletePlayer(guildId) {
|
|
6472
6523
|
const oldPlayer = this.getPlayer(guildId);
|
|
6473
6524
|
if (!oldPlayer) return;
|
|
6474
|
-
if (typeof oldPlayer.voiceChannelId === "string" && oldPlayer.connected && !oldPlayer.
|
|
6525
|
+
if (typeof oldPlayer.voiceChannelId === "string" && oldPlayer.connected && !oldPlayer.getData("internal_destroywithoutdisconnect")) {
|
|
6475
6526
|
if (!this.options?.advancedOptions?.debugOptions?.playerDestroy?.dontThrowError)
|
|
6476
6527
|
throw new Error(
|
|
6477
6528
|
`Use Player#destroy() not LavalinkManager#deletePlayer() to stop the Player ${safeStringify(oldPlayer.toJSON?.())}`
|
|
@@ -6618,7 +6669,7 @@ var LavalinkManager = class _LavalinkManager extends import_node_events2.EventEm
|
|
|
6618
6669
|
);
|
|
6619
6670
|
return;
|
|
6620
6671
|
}
|
|
6621
|
-
if (player.
|
|
6672
|
+
if (player.getData("internal_destroystatus") === true) {
|
|
6622
6673
|
this._debugNoAudio("warn", "LavalinkManager > sendRawData()", {
|
|
6623
6674
|
message: "Player is in a destroying state. can't signal the voice states"
|
|
6624
6675
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1514,6 +1514,17 @@ type YoutubeOAuthResponse = {
|
|
|
1514
1514
|
scope: string;
|
|
1515
1515
|
token_type: string;
|
|
1516
1516
|
};
|
|
1517
|
+
type MeaningResponse = {
|
|
1518
|
+
loadType: "meaning";
|
|
1519
|
+
data: {
|
|
1520
|
+
title: string;
|
|
1521
|
+
description: string;
|
|
1522
|
+
paragraphs: string[];
|
|
1523
|
+
url: string;
|
|
1524
|
+
provider: string;
|
|
1525
|
+
type: string;
|
|
1526
|
+
};
|
|
1527
|
+
};
|
|
1517
1528
|
|
|
1518
1529
|
/** Ability to manipulate fetch requests */
|
|
1519
1530
|
type ModifyRequest = (options: RequestInit & {
|
|
@@ -2882,6 +2893,25 @@ declare class Player {
|
|
|
2882
2893
|
declare class NodeLinkNode extends LavalinkNode {
|
|
2883
2894
|
nodeType: "NodeLink";
|
|
2884
2895
|
constructor(options: LavalinkNodeOptions, manager: NodeManager);
|
|
2896
|
+
/**
|
|
2897
|
+
* Uses the gapless feature to set the next track to be played.
|
|
2898
|
+
* @param player current player
|
|
2899
|
+
* @param track if no track provided, it will use the next track from queue
|
|
2900
|
+
*/
|
|
2901
|
+
setNextTrackGapLess(player: Player, track?: Track | UnresolvedTrack): Promise<boolean>;
|
|
2902
|
+
/**
|
|
2903
|
+
* Removes the nextTrackGapLess configuration
|
|
2904
|
+
* @param player current player
|
|
2905
|
+
* @param track if no track provided, it will use the next track from queue
|
|
2906
|
+
*/
|
|
2907
|
+
removeNextTrackGapLess(player: Player): Promise<boolean>;
|
|
2908
|
+
/**
|
|
2909
|
+
* Retrieves the meaning of a track.
|
|
2910
|
+
* @param track
|
|
2911
|
+
* @returns {MeaningResponse}
|
|
2912
|
+
* @link {https://nodelink.js.org/docs/api/nodelink-features#meaning-system}
|
|
2913
|
+
*/
|
|
2914
|
+
getMeaning(track?: Track | UnresolvedTrack): Promise<MeaningResponse>;
|
|
2885
2915
|
/**
|
|
2886
2916
|
* Adds a new audio track to be mixed over the current playback.
|
|
2887
2917
|
* @param player The player to add the mixer layer to.
|
package/dist/index.d.ts
CHANGED
|
@@ -1514,6 +1514,17 @@ type YoutubeOAuthResponse = {
|
|
|
1514
1514
|
scope: string;
|
|
1515
1515
|
token_type: string;
|
|
1516
1516
|
};
|
|
1517
|
+
type MeaningResponse = {
|
|
1518
|
+
loadType: "meaning";
|
|
1519
|
+
data: {
|
|
1520
|
+
title: string;
|
|
1521
|
+
description: string;
|
|
1522
|
+
paragraphs: string[];
|
|
1523
|
+
url: string;
|
|
1524
|
+
provider: string;
|
|
1525
|
+
type: string;
|
|
1526
|
+
};
|
|
1527
|
+
};
|
|
1517
1528
|
|
|
1518
1529
|
/** Ability to manipulate fetch requests */
|
|
1519
1530
|
type ModifyRequest = (options: RequestInit & {
|
|
@@ -2882,6 +2893,25 @@ declare class Player {
|
|
|
2882
2893
|
declare class NodeLinkNode extends LavalinkNode {
|
|
2883
2894
|
nodeType: "NodeLink";
|
|
2884
2895
|
constructor(options: LavalinkNodeOptions, manager: NodeManager);
|
|
2896
|
+
/**
|
|
2897
|
+
* Uses the gapless feature to set the next track to be played.
|
|
2898
|
+
* @param player current player
|
|
2899
|
+
* @param track if no track provided, it will use the next track from queue
|
|
2900
|
+
*/
|
|
2901
|
+
setNextTrackGapLess(player: Player, track?: Track | UnresolvedTrack): Promise<boolean>;
|
|
2902
|
+
/**
|
|
2903
|
+
* Removes the nextTrackGapLess configuration
|
|
2904
|
+
* @param player current player
|
|
2905
|
+
* @param track if no track provided, it will use the next track from queue
|
|
2906
|
+
*/
|
|
2907
|
+
removeNextTrackGapLess(player: Player): Promise<boolean>;
|
|
2908
|
+
/**
|
|
2909
|
+
* Retrieves the meaning of a track.
|
|
2910
|
+
* @param track
|
|
2911
|
+
* @returns {MeaningResponse}
|
|
2912
|
+
* @link {https://nodelink.js.org/docs/api/nodelink-features#meaning-system}
|
|
2913
|
+
*/
|
|
2914
|
+
getMeaning(track?: Track | UnresolvedTrack): Promise<MeaningResponse>;
|
|
2885
2915
|
/**
|
|
2886
2916
|
* Adds a new audio track to be mixed over the current playback.
|
|
2887
2917
|
* @param player The player to add the mixer layer to.
|
package/dist/index.js
CHANGED
|
@@ -2679,7 +2679,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2679
2679
|
}
|
|
2680
2680
|
/** @private util function for handling trackStart event */
|
|
2681
2681
|
async trackStart(player, track, payload) {
|
|
2682
|
-
if (!player.
|
|
2682
|
+
if (!player.getData("internal_nodeChanging")) {
|
|
2683
2683
|
player.playing = true;
|
|
2684
2684
|
player.paused = false;
|
|
2685
2685
|
}
|
|
@@ -2707,7 +2707,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2707
2707
|
}
|
|
2708
2708
|
/** @private util function for handling trackEnd event */
|
|
2709
2709
|
async trackEnd(player, track, payload) {
|
|
2710
|
-
if (player.
|
|
2710
|
+
if (player.getData("internal_nodeChanging") === true) return;
|
|
2711
2711
|
const trackToUse = track || this.getTrackOfPayload(payload);
|
|
2712
2712
|
if (payload.reason === "replaced") {
|
|
2713
2713
|
this._emitDebugEvent("TrackEndReplaced" /* TrackEndReplaced */, {
|
|
@@ -2718,10 +2718,10 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2718
2718
|
this._LManager.emit("trackEnd", player, trackToUse, payload);
|
|
2719
2719
|
return;
|
|
2720
2720
|
}
|
|
2721
|
-
if (!player.queue.tracks.length && (player.repeatMode === "off" || player.
|
|
2721
|
+
if (!player.queue.tracks.length && (player.repeatMode === "off" || player.getData("internal_stopPlaying")))
|
|
2722
2722
|
return this.queueEnd(player, track, payload);
|
|
2723
2723
|
if (["loadFailed", "cleanup"].includes(payload.reason)) {
|
|
2724
|
-
if (player.
|
|
2724
|
+
if (player.getData("internal_destroystatus") === true) return;
|
|
2725
2725
|
await queueTrackEnd(player);
|
|
2726
2726
|
if (!player.queue.current) return this.queueEnd(player, trackToUse, payload);
|
|
2727
2727
|
this._LManager.emit("trackEnd", player, trackToUse, payload);
|
|
@@ -2730,7 +2730,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2730
2730
|
}
|
|
2731
2731
|
return;
|
|
2732
2732
|
}
|
|
2733
|
-
if (player.repeatMode !== "track" || player.
|
|
2733
|
+
if (player.repeatMode !== "track" || player.getData("internal_skipped")) await queueTrackEnd(player);
|
|
2734
2734
|
else if (trackToUse && !trackToUse?.pluginInfo?.clientData?.previousTrack) {
|
|
2735
2735
|
player.queue.previous.unshift(trackToUse);
|
|
2736
2736
|
if (player.queue.previous.length > player.queue.options.maxPreviousTracks)
|
|
@@ -2738,7 +2738,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2738
2738
|
await player.queue.utils.save();
|
|
2739
2739
|
}
|
|
2740
2740
|
if (!player.queue.current) return this.queueEnd(player, trackToUse, payload);
|
|
2741
|
-
player.
|
|
2741
|
+
player.setData("internal_skipped", false);
|
|
2742
2742
|
this._LManager.emit("trackEnd", player, trackToUse, payload);
|
|
2743
2743
|
if (this._LManager.options.autoSkip && player.queue.current) {
|
|
2744
2744
|
player.play({ noReplace: true });
|
|
@@ -2748,10 +2748,10 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2748
2748
|
/** @private util function for handling trackStuck event */
|
|
2749
2749
|
async trackStuck(player, track, payload) {
|
|
2750
2750
|
if (this._LManager.options.playerOptions.maxErrorsPerTime?.threshold > 0 && this._LManager.options.playerOptions.maxErrorsPerTime?.maxAmount >= 0) {
|
|
2751
|
-
const oldTimestamps = (player.
|
|
2751
|
+
const oldTimestamps = (player.getData("internal_erroredTracksTimestamps") || []).filter(
|
|
2752
2752
|
(v) => Date.now() - v < this._LManager.options.playerOptions.maxErrorsPerTime?.threshold
|
|
2753
2753
|
);
|
|
2754
|
-
player.
|
|
2754
|
+
player.setData("internal_erroredTracksTimestamps", [...oldTimestamps, Date.now()]);
|
|
2755
2755
|
if (oldTimestamps.length >= this._LManager.options.playerOptions.maxErrorsPerTime?.maxAmount) {
|
|
2756
2756
|
this._emitDebugEvent("TrackStuckMaxTracksErroredPerTime" /* TrackStuckMaxTracksErroredPerTime */, {
|
|
2757
2757
|
state: "log",
|
|
@@ -2763,7 +2763,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2763
2763
|
}
|
|
2764
2764
|
}
|
|
2765
2765
|
this._LManager.emit("trackStuck", player, track || this.getTrackOfPayload(payload), payload);
|
|
2766
|
-
if (!player.queue.tracks.length && (player.repeatMode === "off" || player.
|
|
2766
|
+
if (!player.queue.tracks.length && (player.repeatMode === "off" || player.getData("internal_stopPlaying"))) {
|
|
2767
2767
|
try {
|
|
2768
2768
|
await player.node.updatePlayer({
|
|
2769
2769
|
guildId: player.guildId,
|
|
@@ -2786,10 +2786,10 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2786
2786
|
/** @private util function for handling trackError event */
|
|
2787
2787
|
async trackError(player, track, payload) {
|
|
2788
2788
|
if (this._LManager.options.playerOptions.maxErrorsPerTime?.threshold > 0 && this._LManager.options.playerOptions.maxErrorsPerTime?.maxAmount >= 0) {
|
|
2789
|
-
const oldTimestamps = (player.
|
|
2789
|
+
const oldTimestamps = (player.getData("internal_erroredTracksTimestamps") || []).filter(
|
|
2790
2790
|
(v) => Date.now() - v < this._LManager.options.playerOptions.maxErrorsPerTime?.threshold
|
|
2791
2791
|
);
|
|
2792
|
-
player.
|
|
2792
|
+
player.setData("internal_erroredTracksTimestamps", [...oldTimestamps, Date.now()]);
|
|
2793
2793
|
if (oldTimestamps.length >= this._LManager.options.playerOptions.maxErrorsPerTime?.maxAmount) {
|
|
2794
2794
|
this._emitDebugEvent("TrackErrorMaxTracksErroredPerTime" /* TrackErrorMaxTracksErroredPerTime */, {
|
|
2795
2795
|
state: "log",
|
|
@@ -2873,7 +2873,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2873
2873
|
};
|
|
2874
2874
|
r.body = safeStringify(segments.map((v) => v.toLowerCase()));
|
|
2875
2875
|
});
|
|
2876
|
-
player.
|
|
2876
|
+
player.setData(
|
|
2877
2877
|
"internal_sponsorBlockCategories",
|
|
2878
2878
|
segments.map((v) => v.toLowerCase())
|
|
2879
2879
|
);
|
|
@@ -2901,7 +2901,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2901
2901
|
await this.request(`/sessions/${this.sessionId}/players/${player.guildId}/sponsorblock/categories`, (r) => {
|
|
2902
2902
|
r.method = "DELETE";
|
|
2903
2903
|
});
|
|
2904
|
-
player.
|
|
2904
|
+
player.setData("internal_sponsorBlockCategories", []);
|
|
2905
2905
|
this._emitDebugEvent("DeleteSponsorBlock" /* DeleteSponsorBlock */, {
|
|
2906
2906
|
state: "log",
|
|
2907
2907
|
message: `SponsorBlock was deleted for Player: ${player.guildId}`,
|
|
@@ -2911,26 +2911,26 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2911
2911
|
}
|
|
2912
2912
|
/** private util function for handling the queue end event */
|
|
2913
2913
|
async queueEnd(player, track, payload) {
|
|
2914
|
-
if (player.
|
|
2914
|
+
if (player.getData("internal_nodeChanging") === true) return;
|
|
2915
2915
|
player.queue.current = null;
|
|
2916
2916
|
player.playing = false;
|
|
2917
|
-
player.
|
|
2917
|
+
player.setData("internal_stopPlaying", void 0);
|
|
2918
2918
|
this._emitDebugEvent("QueueEnded" /* QueueEnded */, {
|
|
2919
2919
|
state: "log",
|
|
2920
2920
|
message: `Queue Ended because no more Tracks were in the Queue, due to EventName: "${payload.type}"`,
|
|
2921
2921
|
functionLayer: "LavalinkNode > queueEnd()"
|
|
2922
2922
|
});
|
|
2923
|
-
if (typeof this._LManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction === "function" && typeof player.
|
|
2923
|
+
if (typeof this._LManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction === "function" && typeof player.getData("internal_autoplayStopPlaying") === "undefined") {
|
|
2924
2924
|
this._emitDebugEvent("AutoplayExecution" /* AutoplayExecution */, {
|
|
2925
2925
|
state: "log",
|
|
2926
2926
|
message: `Now Triggering Autoplay.`,
|
|
2927
2927
|
functionLayer: "LavalinkNode > queueEnd() > autoplayFunction"
|
|
2928
2928
|
});
|
|
2929
|
-
const previousAutoplayTime = player.
|
|
2929
|
+
const previousAutoplayTime = player.getData("internal_previousautoplay");
|
|
2930
2930
|
const duration = previousAutoplayTime ? Date.now() - previousAutoplayTime : 0;
|
|
2931
|
-
if (!duration || duration > this._LManager.options.playerOptions.minAutoPlayMs || !!player.
|
|
2931
|
+
if (!duration || duration > this._LManager.options.playerOptions.minAutoPlayMs || !!player.getData("internal_skipped")) {
|
|
2932
2932
|
await this._LManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction(player, track);
|
|
2933
|
-
player.
|
|
2933
|
+
player.setData("internal_previousautoplay", Date.now());
|
|
2934
2934
|
if (player.queue.tracks.length > 0) await queueTrackEnd(player);
|
|
2935
2935
|
else
|
|
2936
2936
|
this._emitDebugEvent("AutoplayNoSongsAdded" /* AutoplayNoSongsAdded */, {
|
|
@@ -2950,8 +2950,8 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2950
2950
|
});
|
|
2951
2951
|
}
|
|
2952
2952
|
}
|
|
2953
|
-
player.
|
|
2954
|
-
player.
|
|
2953
|
+
player.setData("internal_skipped", false);
|
|
2954
|
+
player.setData("internal_autoplayStopPlaying", void 0);
|
|
2955
2955
|
if (track && !track?.pluginInfo?.clientData?.previousTrack) {
|
|
2956
2956
|
player.queue.previous.unshift(track);
|
|
2957
2957
|
if (player.queue.previous.length > player.queue.options.maxPreviousTracks)
|
|
@@ -2976,11 +2976,11 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2976
2976
|
player,
|
|
2977
2977
|
this._LManager.options.playerOptions.onEmptyQueue?.destroyAfterMs
|
|
2978
2978
|
);
|
|
2979
|
-
if (player.
|
|
2980
|
-
player.
|
|
2979
|
+
if (player.getData("internal_queueempty")) clearTimeout(player.getData("internal_queueempty"));
|
|
2980
|
+
player.setData(
|
|
2981
2981
|
"internal_queueempty",
|
|
2982
2982
|
setTimeout(() => {
|
|
2983
|
-
player.
|
|
2983
|
+
player.setData("internal_queueempty", void 0);
|
|
2984
2984
|
if (player.queue.current) {
|
|
2985
2985
|
return this._LManager.emit("playerQueueEmptyCancel", player);
|
|
2986
2986
|
}
|
|
@@ -3074,6 +3074,50 @@ var NodeLinkNode = class extends LavalinkNode {
|
|
|
3074
3074
|
}
|
|
3075
3075
|
this.nodeType = "NodeLink";
|
|
3076
3076
|
}
|
|
3077
|
+
/**
|
|
3078
|
+
* Uses the gapless feature to set the next track to be played.
|
|
3079
|
+
* @param player current player
|
|
3080
|
+
* @param track if no track provided, it will use the next track from queue
|
|
3081
|
+
*/
|
|
3082
|
+
async setNextTrackGapLess(player, track) {
|
|
3083
|
+
if (!this.sessionId) throw new Error("The Lavalink Node is either not ready, or not up to date!");
|
|
3084
|
+
const nextTrack = track || player.queue.tracks[0];
|
|
3085
|
+
if (!nextTrack) throw new Error("No track provided");
|
|
3086
|
+
await this.updatePlayer({
|
|
3087
|
+
guildId: player.guildId,
|
|
3088
|
+
// @ts-expect-error - nextTrack is not a valid property of LavalinkPlayOptions but for NodeLink it is
|
|
3089
|
+
playerOptions: { nextTrack: { encoded: nextTrack.encoded, userData: nextTrack.userData || {} } }
|
|
3090
|
+
});
|
|
3091
|
+
return true;
|
|
3092
|
+
}
|
|
3093
|
+
/**
|
|
3094
|
+
* Removes the nextTrackGapLess configuration
|
|
3095
|
+
* @param player current player
|
|
3096
|
+
* @param track if no track provided, it will use the next track from queue
|
|
3097
|
+
*/
|
|
3098
|
+
async removeNextTrackGapLess(player) {
|
|
3099
|
+
if (!this.sessionId) throw new Error("The Lavalink Node is either not ready, or not up to date!");
|
|
3100
|
+
await this.updatePlayer({
|
|
3101
|
+
guildId: player.guildId,
|
|
3102
|
+
// @ts-expect-error - nextTrack is not a valid property of LavalinkPlayOptions but for NodeLink it is
|
|
3103
|
+
playerOptions: { nextTrack: { encoded: null } }
|
|
3104
|
+
});
|
|
3105
|
+
return true;
|
|
3106
|
+
}
|
|
3107
|
+
/**
|
|
3108
|
+
* Retrieves the meaning of a track.
|
|
3109
|
+
* @param track
|
|
3110
|
+
* @returns {MeaningResponse}
|
|
3111
|
+
* @link {https://nodelink.js.org/docs/api/nodelink-features#meaning-system}
|
|
3112
|
+
*/
|
|
3113
|
+
async getMeaning(track) {
|
|
3114
|
+
if (!this.sessionId) throw new Error("The Lavalink Node is either not ready, or not up to date!");
|
|
3115
|
+
const encodedTrack = track?.encoded;
|
|
3116
|
+
if (!encodedTrack) throw new Error("No track provided");
|
|
3117
|
+
return await this.request(`/meaning?encodedTrack=${encodedTrack}`, (m) => {
|
|
3118
|
+
m.method = "GET";
|
|
3119
|
+
});
|
|
3120
|
+
}
|
|
3077
3121
|
/**
|
|
3078
3122
|
* Adds a new audio track to be mixed over the current playback.
|
|
3079
3123
|
* @param player The player to add the mixer layer to.
|
|
@@ -3091,7 +3135,7 @@ var NodeLinkNode = class extends LavalinkNode {
|
|
|
3091
3135
|
//identifier: trackToAdd.info?.identifier, // atm not supported
|
|
3092
3136
|
userData: trackToAdd.userData
|
|
3093
3137
|
},
|
|
3094
|
-
volume:
|
|
3138
|
+
volume: volume / 100
|
|
3095
3139
|
});
|
|
3096
3140
|
});
|
|
3097
3141
|
}
|
|
@@ -3118,7 +3162,7 @@ var NodeLinkNode = class extends LavalinkNode {
|
|
|
3118
3162
|
await this.request(`/sessions/${this.sessionId}/players/${player.guildId}/mix/${mixId}`, (m) => {
|
|
3119
3163
|
m.method = "PATCH";
|
|
3120
3164
|
m.body = safeStringify({
|
|
3121
|
-
volume:
|
|
3165
|
+
volume: volume / 100
|
|
3122
3166
|
});
|
|
3123
3167
|
});
|
|
3124
3168
|
return true;
|
|
@@ -3290,7 +3334,7 @@ var NodeLinkNode = class extends LavalinkNode {
|
|
|
3290
3334
|
*/
|
|
3291
3335
|
async loadDirectStream(track, volume, position, filters) {
|
|
3292
3336
|
let requestPath = `/loadstream?encodedTrack=${track.encoded}`;
|
|
3293
|
-
if (volume && volume > 0 && volume <= 100) requestPath += `&volume=${
|
|
3337
|
+
if (volume && volume > 0 && volume <= 100) requestPath += `&volume=${volume / 100}`;
|
|
3294
3338
|
if (position && position > 0) requestPath += `&position=${position}`;
|
|
3295
3339
|
if (filters) requestPath += `&filters=${typeof filters === "object" ? safeStringify(filters) : filters}`;
|
|
3296
3340
|
const res = await this.rawRequest(requestPath, (m) => {
|
|
@@ -3860,8 +3904,8 @@ var FilterManager = class {
|
|
|
3860
3904
|
this.player.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
|
|
3861
3905
|
return;
|
|
3862
3906
|
}
|
|
3863
|
-
privateNot0(value) {
|
|
3864
|
-
return typeof value === "number" && value !==
|
|
3907
|
+
privateNot0(value, numToCheckAgains = 0) {
|
|
3908
|
+
return typeof value === "number" && value !== numToCheckAgains;
|
|
3865
3909
|
}
|
|
3866
3910
|
getLavalinkFilterData() {
|
|
3867
3911
|
return this.data.pluginFilters?.["lavalink-filter-plugin"] || {
|
|
@@ -3908,7 +3952,8 @@ var FilterManager = class {
|
|
|
3908
3952
|
this.filters.lowPass = this.privateNot0(this.data.lowPass?.smoothing);
|
|
3909
3953
|
this.filters.nodeLinkEcho = this.privateNot0(this.data.echo?.delay) || this.privateNot0(this.data.echo?.feedback) || this.privateNot0(this.data.echo?.mix);
|
|
3910
3954
|
this.filters.nodeLinkChorus = this.privateNot0(this.data.chorus?.rate) || this.privateNot0(this.data.chorus?.depth) || this.privateNot0(this.data.chorus?.delay) || this.privateNot0(this.data.chorus?.mix) || this.privateNot0(this.data.chorus?.feedback);
|
|
3911
|
-
this.filters.nodeLinkCompressor = this.privateNot0(this.data.compressor?.threshold) || this.privateNot0(this.data.compressor?.ratio) ||
|
|
3955
|
+
this.filters.nodeLinkCompressor = this.privateNot0(this.data.compressor?.threshold) || this.privateNot0(this.data.compressor?.ratio, 1) || // here "1" is the default
|
|
3956
|
+
this.privateNot0(this.data.compressor?.attack) || this.privateNot0(this.data.compressor?.release) || this.privateNot0(this.data.compressor?.gain);
|
|
3912
3957
|
this.filters.nodeLinkHighPass = this.privateNot0(this.data.highPass?.smoothing);
|
|
3913
3958
|
this.filters.nodeLinkPhaser = this.privateNot0(this.data.phaser?.stages) || this.privateNot0(this.data.phaser?.rate) || this.privateNot0(this.data.phaser?.depth) || this.privateNot0(this.data.phaser?.feedback) || this.privateNot0(this.data.phaser?.mix) || this.privateNot0(this.data.phaser?.minFrequency) || this.privateNot0(this.data.phaser?.maxFrequency);
|
|
3914
3959
|
this.filters.nodeLinkSpatial = this.privateNot0(this.data.spatial?.depth) || this.privateNot0(this.data.spatial?.rate);
|
|
@@ -5271,7 +5316,7 @@ var Player = class {
|
|
|
5271
5316
|
*/
|
|
5272
5317
|
constructor(options, LavalinkManager2, dontEmitPlayerCreateEvent) {
|
|
5273
5318
|
if (typeof options?.customData === "object")
|
|
5274
|
-
for (const [key, value] of Object.entries(options.customData)) this.
|
|
5319
|
+
for (const [key, value] of Object.entries(options.customData)) this.setData(key, value);
|
|
5275
5320
|
this.options = options;
|
|
5276
5321
|
this.filterManager = new FilterManager(this);
|
|
5277
5322
|
this.LavalinkManager = LavalinkManager2;
|
|
@@ -5380,15 +5425,15 @@ var Player = class {
|
|
|
5380
5425
|
* @param options
|
|
5381
5426
|
*/
|
|
5382
5427
|
async play(options = {}) {
|
|
5383
|
-
if (this.
|
|
5428
|
+
if (this.getData("internal_queueempty")) {
|
|
5384
5429
|
this._emitDebugEvent("PlayerPlayQueueEmptyTimeoutClear" /* PlayerPlayQueueEmptyTimeoutClear */, {
|
|
5385
5430
|
state: "log",
|
|
5386
5431
|
message: `Player was called to play something, while there was a queueEmpty Timeout set, clearing the timeout.`,
|
|
5387
5432
|
functionLayer: "Player > play()"
|
|
5388
5433
|
});
|
|
5389
5434
|
this.LavalinkManager.emit("playerQueueEmptyCancel", this);
|
|
5390
|
-
clearTimeout(this.
|
|
5391
|
-
this.
|
|
5435
|
+
clearTimeout(this.getData("internal_queueempty"));
|
|
5436
|
+
this.setData("internal_queueempty", void 0);
|
|
5392
5437
|
}
|
|
5393
5438
|
if (options?.clientTrack && (this.LavalinkManager.utils.isTrack(options?.clientTrack) || this.LavalinkManager.utils.isUnresolvedTrack(options.clientTrack))) {
|
|
5394
5439
|
if (this.LavalinkManager.utils.isUnresolvedTrack(options.clientTrack)) {
|
|
@@ -5736,7 +5781,7 @@ var Player = class {
|
|
|
5736
5781
|
}
|
|
5737
5782
|
if (!this.playing && !this.queue.current) return this.play(), this;
|
|
5738
5783
|
const now = performance.now();
|
|
5739
|
-
this.
|
|
5784
|
+
this.setData("internal_skipped", true);
|
|
5740
5785
|
await this.node.updatePlayer({
|
|
5741
5786
|
guildId: this.guildId,
|
|
5742
5787
|
playerOptions: { track: { encoded: null }, paused: false }
|
|
@@ -5749,14 +5794,20 @@ var Player = class {
|
|
|
5749
5794
|
* @returns
|
|
5750
5795
|
*/
|
|
5751
5796
|
async stopPlaying(clearQueue = true, executeAutoplay = false) {
|
|
5752
|
-
this.
|
|
5797
|
+
this.setData("internal_stopPlaying", true);
|
|
5753
5798
|
if (this.queue.tracks.length && clearQueue === true) await this.queue.splice(0, this.queue.tracks.length);
|
|
5754
|
-
if (executeAutoplay === false) this.
|
|
5755
|
-
else this.
|
|
5799
|
+
if (executeAutoplay === false) this.setData("internal_autoplayStopPlaying", true);
|
|
5800
|
+
else this.setData("internal_autoplayStopPlaying", void 0);
|
|
5756
5801
|
const now = performance.now();
|
|
5757
5802
|
await this.node.updatePlayer({
|
|
5758
5803
|
guildId: this.guildId,
|
|
5759
|
-
playerOptions:
|
|
5804
|
+
playerOptions: this.node.isNodeLink() ? {
|
|
5805
|
+
track: { encoded: null },
|
|
5806
|
+
// @ts-expect-error - nextTrack is not a valid property of LavalinkPlayOptions but for NodeLink it is
|
|
5807
|
+
nextTrack: { encoded: null }
|
|
5808
|
+
} : {
|
|
5809
|
+
track: { encoded: null }
|
|
5810
|
+
}
|
|
5760
5811
|
});
|
|
5761
5812
|
this.paused = false;
|
|
5762
5813
|
this.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
|
|
@@ -5827,11 +5878,11 @@ var Player = class {
|
|
|
5827
5878
|
console.log(
|
|
5828
5879
|
`Lavalink-Client-Debug | PlayerDestroy [::] destroy Function, [guildId ${this.guildId}] - Destroy-Reason: ${String(reason)}`
|
|
5829
5880
|
);
|
|
5830
|
-
if (this.
|
|
5831
|
-
clearTimeout(this.
|
|
5832
|
-
this.
|
|
5881
|
+
if (this.getData("internal_queueempty")) {
|
|
5882
|
+
clearTimeout(this.getData("internal_queueempty"));
|
|
5883
|
+
this.setData("internal_queueempty", void 0);
|
|
5833
5884
|
}
|
|
5834
|
-
if (this.
|
|
5885
|
+
if (this.getData("internal_destroystatus") === true) {
|
|
5835
5886
|
this._emitDebugEvent("PlayerDestroyingSomewhereElse" /* PlayerDestroyingSomewhereElse */, {
|
|
5836
5887
|
state: "warn",
|
|
5837
5888
|
message: `Player is already destroying somewhere else..`,
|
|
@@ -5843,9 +5894,9 @@ var Player = class {
|
|
|
5843
5894
|
);
|
|
5844
5895
|
return;
|
|
5845
5896
|
}
|
|
5846
|
-
this.
|
|
5897
|
+
this.setData("internal_destroystatus", true);
|
|
5847
5898
|
if (disconnect) await this.disconnect(true);
|
|
5848
|
-
else this.
|
|
5899
|
+
else this.setData("internal_destroywithoutdisconnect", true);
|
|
5849
5900
|
await this.queue.utils.destroy();
|
|
5850
5901
|
this.LavalinkManager.deletePlayer(this.guildId);
|
|
5851
5902
|
await this.node.destroyPlayer(this.guildId);
|
|
@@ -5920,7 +5971,7 @@ var Player = class {
|
|
|
5920
5971
|
if (!updateNode) throw new Error("Could not find the new Node");
|
|
5921
5972
|
if (!updateNode.connected) throw new Error("The provided Node is not active or disconnected");
|
|
5922
5973
|
if (this.node.id === updateNode.id) throw new Error("Player is already on the provided Node");
|
|
5923
|
-
if (this.
|
|
5974
|
+
if (this.getData("internal_nodeChanging") === true)
|
|
5924
5975
|
throw new Error("Player is already changing the node please wait");
|
|
5925
5976
|
if (checkSources) {
|
|
5926
5977
|
const isDefaultSource = () => {
|
|
@@ -5958,7 +6009,7 @@ var Player = class {
|
|
|
5958
6009
|
const currentTrack = this.queue.current;
|
|
5959
6010
|
if (!this.voice.endpoint || !this.voice.sessionId || !this.voice.token)
|
|
5960
6011
|
throw new Error("Voice Data is missing, can't change the node");
|
|
5961
|
-
this.
|
|
6012
|
+
this.setData("internal_nodeChanging", true);
|
|
5962
6013
|
if (this.node.connected) await this.node.destroyPlayer(this.guildId);
|
|
5963
6014
|
this.node = updateNode;
|
|
5964
6015
|
const now = performance.now();
|
|
@@ -5966,7 +6017,7 @@ var Player = class {
|
|
|
5966
6017
|
await this.connect();
|
|
5967
6018
|
const hasSponsorBlock = !this.node._checkForPlugins || this.node.info?.plugins?.find((v) => v.name === "sponsorblock-plugin");
|
|
5968
6019
|
if (hasSponsorBlock) {
|
|
5969
|
-
const sponsorBlockCategories = this.
|
|
6020
|
+
const sponsorBlockCategories = this.getData("internal_sponsorBlockCategories");
|
|
5970
6021
|
if (Array.isArray(sponsorBlockCategories) && sponsorBlockCategories.length) {
|
|
5971
6022
|
await this.setSponsorBlock(sponsorBlockCategories).catch((error) => {
|
|
5972
6023
|
this._emitDebugEvent("PlayerChangeNode" /* PlayerChangeNode */, {
|
|
@@ -6017,7 +6068,7 @@ var Player = class {
|
|
|
6017
6068
|
});
|
|
6018
6069
|
throw new Error(`Failed to change the node: ${error}`);
|
|
6019
6070
|
} finally {
|
|
6020
|
-
this.
|
|
6071
|
+
this.setData("internal_nodeChanging", void 0);
|
|
6021
6072
|
}
|
|
6022
6073
|
}
|
|
6023
6074
|
/**
|
|
@@ -6407,7 +6458,7 @@ var LavalinkManager = class _LavalinkManager extends EventEmitter2 {
|
|
|
6407
6458
|
deletePlayer(guildId) {
|
|
6408
6459
|
const oldPlayer = this.getPlayer(guildId);
|
|
6409
6460
|
if (!oldPlayer) return;
|
|
6410
|
-
if (typeof oldPlayer.voiceChannelId === "string" && oldPlayer.connected && !oldPlayer.
|
|
6461
|
+
if (typeof oldPlayer.voiceChannelId === "string" && oldPlayer.connected && !oldPlayer.getData("internal_destroywithoutdisconnect")) {
|
|
6411
6462
|
if (!this.options?.advancedOptions?.debugOptions?.playerDestroy?.dontThrowError)
|
|
6412
6463
|
throw new Error(
|
|
6413
6464
|
`Use Player#destroy() not LavalinkManager#deletePlayer() to stop the Player ${safeStringify(oldPlayer.toJSON?.())}`
|
|
@@ -6554,7 +6605,7 @@ var LavalinkManager = class _LavalinkManager extends EventEmitter2 {
|
|
|
6554
6605
|
);
|
|
6555
6606
|
return;
|
|
6556
6607
|
}
|
|
6557
|
-
if (player.
|
|
6608
|
+
if (player.getData("internal_destroystatus") === true) {
|
|
6558
6609
|
this._debugNoAudio("warn", "LavalinkManager > sendRawData()", {
|
|
6559
6610
|
message: "Player is in a destroying state. can't signal the voice states"
|
|
6560
6611
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -2679,7 +2679,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2679
2679
|
}
|
|
2680
2680
|
/** @private util function for handling trackStart event */
|
|
2681
2681
|
async trackStart(player, track, payload) {
|
|
2682
|
-
if (!player.
|
|
2682
|
+
if (!player.getData("internal_nodeChanging")) {
|
|
2683
2683
|
player.playing = true;
|
|
2684
2684
|
player.paused = false;
|
|
2685
2685
|
}
|
|
@@ -2707,7 +2707,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2707
2707
|
}
|
|
2708
2708
|
/** @private util function for handling trackEnd event */
|
|
2709
2709
|
async trackEnd(player, track, payload) {
|
|
2710
|
-
if (player.
|
|
2710
|
+
if (player.getData("internal_nodeChanging") === true) return;
|
|
2711
2711
|
const trackToUse = track || this.getTrackOfPayload(payload);
|
|
2712
2712
|
if (payload.reason === "replaced") {
|
|
2713
2713
|
this._emitDebugEvent("TrackEndReplaced" /* TrackEndReplaced */, {
|
|
@@ -2718,10 +2718,10 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2718
2718
|
this._LManager.emit("trackEnd", player, trackToUse, payload);
|
|
2719
2719
|
return;
|
|
2720
2720
|
}
|
|
2721
|
-
if (!player.queue.tracks.length && (player.repeatMode === "off" || player.
|
|
2721
|
+
if (!player.queue.tracks.length && (player.repeatMode === "off" || player.getData("internal_stopPlaying")))
|
|
2722
2722
|
return this.queueEnd(player, track, payload);
|
|
2723
2723
|
if (["loadFailed", "cleanup"].includes(payload.reason)) {
|
|
2724
|
-
if (player.
|
|
2724
|
+
if (player.getData("internal_destroystatus") === true) return;
|
|
2725
2725
|
await queueTrackEnd(player);
|
|
2726
2726
|
if (!player.queue.current) return this.queueEnd(player, trackToUse, payload);
|
|
2727
2727
|
this._LManager.emit("trackEnd", player, trackToUse, payload);
|
|
@@ -2730,7 +2730,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2730
2730
|
}
|
|
2731
2731
|
return;
|
|
2732
2732
|
}
|
|
2733
|
-
if (player.repeatMode !== "track" || player.
|
|
2733
|
+
if (player.repeatMode !== "track" || player.getData("internal_skipped")) await queueTrackEnd(player);
|
|
2734
2734
|
else if (trackToUse && !trackToUse?.pluginInfo?.clientData?.previousTrack) {
|
|
2735
2735
|
player.queue.previous.unshift(trackToUse);
|
|
2736
2736
|
if (player.queue.previous.length > player.queue.options.maxPreviousTracks)
|
|
@@ -2738,7 +2738,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2738
2738
|
await player.queue.utils.save();
|
|
2739
2739
|
}
|
|
2740
2740
|
if (!player.queue.current) return this.queueEnd(player, trackToUse, payload);
|
|
2741
|
-
player.
|
|
2741
|
+
player.setData("internal_skipped", false);
|
|
2742
2742
|
this._LManager.emit("trackEnd", player, trackToUse, payload);
|
|
2743
2743
|
if (this._LManager.options.autoSkip && player.queue.current) {
|
|
2744
2744
|
player.play({ noReplace: true });
|
|
@@ -2748,10 +2748,10 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2748
2748
|
/** @private util function for handling trackStuck event */
|
|
2749
2749
|
async trackStuck(player, track, payload) {
|
|
2750
2750
|
if (this._LManager.options.playerOptions.maxErrorsPerTime?.threshold > 0 && this._LManager.options.playerOptions.maxErrorsPerTime?.maxAmount >= 0) {
|
|
2751
|
-
const oldTimestamps = (player.
|
|
2751
|
+
const oldTimestamps = (player.getData("internal_erroredTracksTimestamps") || []).filter(
|
|
2752
2752
|
(v) => Date.now() - v < this._LManager.options.playerOptions.maxErrorsPerTime?.threshold
|
|
2753
2753
|
);
|
|
2754
|
-
player.
|
|
2754
|
+
player.setData("internal_erroredTracksTimestamps", [...oldTimestamps, Date.now()]);
|
|
2755
2755
|
if (oldTimestamps.length >= this._LManager.options.playerOptions.maxErrorsPerTime?.maxAmount) {
|
|
2756
2756
|
this._emitDebugEvent("TrackStuckMaxTracksErroredPerTime" /* TrackStuckMaxTracksErroredPerTime */, {
|
|
2757
2757
|
state: "log",
|
|
@@ -2763,7 +2763,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2763
2763
|
}
|
|
2764
2764
|
}
|
|
2765
2765
|
this._LManager.emit("trackStuck", player, track || this.getTrackOfPayload(payload), payload);
|
|
2766
|
-
if (!player.queue.tracks.length && (player.repeatMode === "off" || player.
|
|
2766
|
+
if (!player.queue.tracks.length && (player.repeatMode === "off" || player.getData("internal_stopPlaying"))) {
|
|
2767
2767
|
try {
|
|
2768
2768
|
await player.node.updatePlayer({
|
|
2769
2769
|
guildId: player.guildId,
|
|
@@ -2786,10 +2786,10 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2786
2786
|
/** @private util function for handling trackError event */
|
|
2787
2787
|
async trackError(player, track, payload) {
|
|
2788
2788
|
if (this._LManager.options.playerOptions.maxErrorsPerTime?.threshold > 0 && this._LManager.options.playerOptions.maxErrorsPerTime?.maxAmount >= 0) {
|
|
2789
|
-
const oldTimestamps = (player.
|
|
2789
|
+
const oldTimestamps = (player.getData("internal_erroredTracksTimestamps") || []).filter(
|
|
2790
2790
|
(v) => Date.now() - v < this._LManager.options.playerOptions.maxErrorsPerTime?.threshold
|
|
2791
2791
|
);
|
|
2792
|
-
player.
|
|
2792
|
+
player.setData("internal_erroredTracksTimestamps", [...oldTimestamps, Date.now()]);
|
|
2793
2793
|
if (oldTimestamps.length >= this._LManager.options.playerOptions.maxErrorsPerTime?.maxAmount) {
|
|
2794
2794
|
this._emitDebugEvent("TrackErrorMaxTracksErroredPerTime" /* TrackErrorMaxTracksErroredPerTime */, {
|
|
2795
2795
|
state: "log",
|
|
@@ -2873,7 +2873,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2873
2873
|
};
|
|
2874
2874
|
r.body = safeStringify(segments.map((v) => v.toLowerCase()));
|
|
2875
2875
|
});
|
|
2876
|
-
player.
|
|
2876
|
+
player.setData(
|
|
2877
2877
|
"internal_sponsorBlockCategories",
|
|
2878
2878
|
segments.map((v) => v.toLowerCase())
|
|
2879
2879
|
);
|
|
@@ -2901,7 +2901,7 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2901
2901
|
await this.request(`/sessions/${this.sessionId}/players/${player.guildId}/sponsorblock/categories`, (r) => {
|
|
2902
2902
|
r.method = "DELETE";
|
|
2903
2903
|
});
|
|
2904
|
-
player.
|
|
2904
|
+
player.setData("internal_sponsorBlockCategories", []);
|
|
2905
2905
|
this._emitDebugEvent("DeleteSponsorBlock" /* DeleteSponsorBlock */, {
|
|
2906
2906
|
state: "log",
|
|
2907
2907
|
message: `SponsorBlock was deleted for Player: ${player.guildId}`,
|
|
@@ -2911,26 +2911,26 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2911
2911
|
}
|
|
2912
2912
|
/** private util function for handling the queue end event */
|
|
2913
2913
|
async queueEnd(player, track, payload) {
|
|
2914
|
-
if (player.
|
|
2914
|
+
if (player.getData("internal_nodeChanging") === true) return;
|
|
2915
2915
|
player.queue.current = null;
|
|
2916
2916
|
player.playing = false;
|
|
2917
|
-
player.
|
|
2917
|
+
player.setData("internal_stopPlaying", void 0);
|
|
2918
2918
|
this._emitDebugEvent("QueueEnded" /* QueueEnded */, {
|
|
2919
2919
|
state: "log",
|
|
2920
2920
|
message: `Queue Ended because no more Tracks were in the Queue, due to EventName: "${payload.type}"`,
|
|
2921
2921
|
functionLayer: "LavalinkNode > queueEnd()"
|
|
2922
2922
|
});
|
|
2923
|
-
if (typeof this._LManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction === "function" && typeof player.
|
|
2923
|
+
if (typeof this._LManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction === "function" && typeof player.getData("internal_autoplayStopPlaying") === "undefined") {
|
|
2924
2924
|
this._emitDebugEvent("AutoplayExecution" /* AutoplayExecution */, {
|
|
2925
2925
|
state: "log",
|
|
2926
2926
|
message: `Now Triggering Autoplay.`,
|
|
2927
2927
|
functionLayer: "LavalinkNode > queueEnd() > autoplayFunction"
|
|
2928
2928
|
});
|
|
2929
|
-
const previousAutoplayTime = player.
|
|
2929
|
+
const previousAutoplayTime = player.getData("internal_previousautoplay");
|
|
2930
2930
|
const duration = previousAutoplayTime ? Date.now() - previousAutoplayTime : 0;
|
|
2931
|
-
if (!duration || duration > this._LManager.options.playerOptions.minAutoPlayMs || !!player.
|
|
2931
|
+
if (!duration || duration > this._LManager.options.playerOptions.minAutoPlayMs || !!player.getData("internal_skipped")) {
|
|
2932
2932
|
await this._LManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction(player, track);
|
|
2933
|
-
player.
|
|
2933
|
+
player.setData("internal_previousautoplay", Date.now());
|
|
2934
2934
|
if (player.queue.tracks.length > 0) await queueTrackEnd(player);
|
|
2935
2935
|
else
|
|
2936
2936
|
this._emitDebugEvent("AutoplayNoSongsAdded" /* AutoplayNoSongsAdded */, {
|
|
@@ -2950,8 +2950,8 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2950
2950
|
});
|
|
2951
2951
|
}
|
|
2952
2952
|
}
|
|
2953
|
-
player.
|
|
2954
|
-
player.
|
|
2953
|
+
player.setData("internal_skipped", false);
|
|
2954
|
+
player.setData("internal_autoplayStopPlaying", void 0);
|
|
2955
2955
|
if (track && !track?.pluginInfo?.clientData?.previousTrack) {
|
|
2956
2956
|
player.queue.previous.unshift(track);
|
|
2957
2957
|
if (player.queue.previous.length > player.queue.options.maxPreviousTracks)
|
|
@@ -2976,11 +2976,11 @@ var LavalinkNode = class _LavalinkNode {
|
|
|
2976
2976
|
player,
|
|
2977
2977
|
this._LManager.options.playerOptions.onEmptyQueue?.destroyAfterMs
|
|
2978
2978
|
);
|
|
2979
|
-
if (player.
|
|
2980
|
-
player.
|
|
2979
|
+
if (player.getData("internal_queueempty")) clearTimeout(player.getData("internal_queueempty"));
|
|
2980
|
+
player.setData(
|
|
2981
2981
|
"internal_queueempty",
|
|
2982
2982
|
setTimeout(() => {
|
|
2983
|
-
player.
|
|
2983
|
+
player.setData("internal_queueempty", void 0);
|
|
2984
2984
|
if (player.queue.current) {
|
|
2985
2985
|
return this._LManager.emit("playerQueueEmptyCancel", player);
|
|
2986
2986
|
}
|
|
@@ -3074,6 +3074,50 @@ var NodeLinkNode = class extends LavalinkNode {
|
|
|
3074
3074
|
}
|
|
3075
3075
|
this.nodeType = "NodeLink";
|
|
3076
3076
|
}
|
|
3077
|
+
/**
|
|
3078
|
+
* Uses the gapless feature to set the next track to be played.
|
|
3079
|
+
* @param player current player
|
|
3080
|
+
* @param track if no track provided, it will use the next track from queue
|
|
3081
|
+
*/
|
|
3082
|
+
async setNextTrackGapLess(player, track) {
|
|
3083
|
+
if (!this.sessionId) throw new Error("The Lavalink Node is either not ready, or not up to date!");
|
|
3084
|
+
const nextTrack = track || player.queue.tracks[0];
|
|
3085
|
+
if (!nextTrack) throw new Error("No track provided");
|
|
3086
|
+
await this.updatePlayer({
|
|
3087
|
+
guildId: player.guildId,
|
|
3088
|
+
// @ts-expect-error - nextTrack is not a valid property of LavalinkPlayOptions but for NodeLink it is
|
|
3089
|
+
playerOptions: { nextTrack: { encoded: nextTrack.encoded, userData: nextTrack.userData || {} } }
|
|
3090
|
+
});
|
|
3091
|
+
return true;
|
|
3092
|
+
}
|
|
3093
|
+
/**
|
|
3094
|
+
* Removes the nextTrackGapLess configuration
|
|
3095
|
+
* @param player current player
|
|
3096
|
+
* @param track if no track provided, it will use the next track from queue
|
|
3097
|
+
*/
|
|
3098
|
+
async removeNextTrackGapLess(player) {
|
|
3099
|
+
if (!this.sessionId) throw new Error("The Lavalink Node is either not ready, or not up to date!");
|
|
3100
|
+
await this.updatePlayer({
|
|
3101
|
+
guildId: player.guildId,
|
|
3102
|
+
// @ts-expect-error - nextTrack is not a valid property of LavalinkPlayOptions but for NodeLink it is
|
|
3103
|
+
playerOptions: { nextTrack: { encoded: null } }
|
|
3104
|
+
});
|
|
3105
|
+
return true;
|
|
3106
|
+
}
|
|
3107
|
+
/**
|
|
3108
|
+
* Retrieves the meaning of a track.
|
|
3109
|
+
* @param track
|
|
3110
|
+
* @returns {MeaningResponse}
|
|
3111
|
+
* @link {https://nodelink.js.org/docs/api/nodelink-features#meaning-system}
|
|
3112
|
+
*/
|
|
3113
|
+
async getMeaning(track) {
|
|
3114
|
+
if (!this.sessionId) throw new Error("The Lavalink Node is either not ready, or not up to date!");
|
|
3115
|
+
const encodedTrack = track?.encoded;
|
|
3116
|
+
if (!encodedTrack) throw new Error("No track provided");
|
|
3117
|
+
return await this.request(`/meaning?encodedTrack=${encodedTrack}`, (m) => {
|
|
3118
|
+
m.method = "GET";
|
|
3119
|
+
});
|
|
3120
|
+
}
|
|
3077
3121
|
/**
|
|
3078
3122
|
* Adds a new audio track to be mixed over the current playback.
|
|
3079
3123
|
* @param player The player to add the mixer layer to.
|
|
@@ -3091,7 +3135,7 @@ var NodeLinkNode = class extends LavalinkNode {
|
|
|
3091
3135
|
//identifier: trackToAdd.info?.identifier, // atm not supported
|
|
3092
3136
|
userData: trackToAdd.userData
|
|
3093
3137
|
},
|
|
3094
|
-
volume:
|
|
3138
|
+
volume: volume / 100
|
|
3095
3139
|
});
|
|
3096
3140
|
});
|
|
3097
3141
|
}
|
|
@@ -3118,7 +3162,7 @@ var NodeLinkNode = class extends LavalinkNode {
|
|
|
3118
3162
|
await this.request(`/sessions/${this.sessionId}/players/${player.guildId}/mix/${mixId}`, (m) => {
|
|
3119
3163
|
m.method = "PATCH";
|
|
3120
3164
|
m.body = safeStringify({
|
|
3121
|
-
volume:
|
|
3165
|
+
volume: volume / 100
|
|
3122
3166
|
});
|
|
3123
3167
|
});
|
|
3124
3168
|
return true;
|
|
@@ -3290,7 +3334,7 @@ var NodeLinkNode = class extends LavalinkNode {
|
|
|
3290
3334
|
*/
|
|
3291
3335
|
async loadDirectStream(track, volume, position, filters) {
|
|
3292
3336
|
let requestPath = `/loadstream?encodedTrack=${track.encoded}`;
|
|
3293
|
-
if (volume && volume > 0 && volume <= 100) requestPath += `&volume=${
|
|
3337
|
+
if (volume && volume > 0 && volume <= 100) requestPath += `&volume=${volume / 100}`;
|
|
3294
3338
|
if (position && position > 0) requestPath += `&position=${position}`;
|
|
3295
3339
|
if (filters) requestPath += `&filters=${typeof filters === "object" ? safeStringify(filters) : filters}`;
|
|
3296
3340
|
const res = await this.rawRequest(requestPath, (m) => {
|
|
@@ -3860,8 +3904,8 @@ var FilterManager = class {
|
|
|
3860
3904
|
this.player.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
|
|
3861
3905
|
return;
|
|
3862
3906
|
}
|
|
3863
|
-
privateNot0(value) {
|
|
3864
|
-
return typeof value === "number" && value !==
|
|
3907
|
+
privateNot0(value, numToCheckAgains = 0) {
|
|
3908
|
+
return typeof value === "number" && value !== numToCheckAgains;
|
|
3865
3909
|
}
|
|
3866
3910
|
getLavalinkFilterData() {
|
|
3867
3911
|
return this.data.pluginFilters?.["lavalink-filter-plugin"] || {
|
|
@@ -3908,7 +3952,8 @@ var FilterManager = class {
|
|
|
3908
3952
|
this.filters.lowPass = this.privateNot0(this.data.lowPass?.smoothing);
|
|
3909
3953
|
this.filters.nodeLinkEcho = this.privateNot0(this.data.echo?.delay) || this.privateNot0(this.data.echo?.feedback) || this.privateNot0(this.data.echo?.mix);
|
|
3910
3954
|
this.filters.nodeLinkChorus = this.privateNot0(this.data.chorus?.rate) || this.privateNot0(this.data.chorus?.depth) || this.privateNot0(this.data.chorus?.delay) || this.privateNot0(this.data.chorus?.mix) || this.privateNot0(this.data.chorus?.feedback);
|
|
3911
|
-
this.filters.nodeLinkCompressor = this.privateNot0(this.data.compressor?.threshold) || this.privateNot0(this.data.compressor?.ratio) ||
|
|
3955
|
+
this.filters.nodeLinkCompressor = this.privateNot0(this.data.compressor?.threshold) || this.privateNot0(this.data.compressor?.ratio, 1) || // here "1" is the default
|
|
3956
|
+
this.privateNot0(this.data.compressor?.attack) || this.privateNot0(this.data.compressor?.release) || this.privateNot0(this.data.compressor?.gain);
|
|
3912
3957
|
this.filters.nodeLinkHighPass = this.privateNot0(this.data.highPass?.smoothing);
|
|
3913
3958
|
this.filters.nodeLinkPhaser = this.privateNot0(this.data.phaser?.stages) || this.privateNot0(this.data.phaser?.rate) || this.privateNot0(this.data.phaser?.depth) || this.privateNot0(this.data.phaser?.feedback) || this.privateNot0(this.data.phaser?.mix) || this.privateNot0(this.data.phaser?.minFrequency) || this.privateNot0(this.data.phaser?.maxFrequency);
|
|
3914
3959
|
this.filters.nodeLinkSpatial = this.privateNot0(this.data.spatial?.depth) || this.privateNot0(this.data.spatial?.rate);
|
|
@@ -5271,7 +5316,7 @@ var Player = class {
|
|
|
5271
5316
|
*/
|
|
5272
5317
|
constructor(options, LavalinkManager2, dontEmitPlayerCreateEvent) {
|
|
5273
5318
|
if (typeof options?.customData === "object")
|
|
5274
|
-
for (const [key, value] of Object.entries(options.customData)) this.
|
|
5319
|
+
for (const [key, value] of Object.entries(options.customData)) this.setData(key, value);
|
|
5275
5320
|
this.options = options;
|
|
5276
5321
|
this.filterManager = new FilterManager(this);
|
|
5277
5322
|
this.LavalinkManager = LavalinkManager2;
|
|
@@ -5380,15 +5425,15 @@ var Player = class {
|
|
|
5380
5425
|
* @param options
|
|
5381
5426
|
*/
|
|
5382
5427
|
async play(options = {}) {
|
|
5383
|
-
if (this.
|
|
5428
|
+
if (this.getData("internal_queueempty")) {
|
|
5384
5429
|
this._emitDebugEvent("PlayerPlayQueueEmptyTimeoutClear" /* PlayerPlayQueueEmptyTimeoutClear */, {
|
|
5385
5430
|
state: "log",
|
|
5386
5431
|
message: `Player was called to play something, while there was a queueEmpty Timeout set, clearing the timeout.`,
|
|
5387
5432
|
functionLayer: "Player > play()"
|
|
5388
5433
|
});
|
|
5389
5434
|
this.LavalinkManager.emit("playerQueueEmptyCancel", this);
|
|
5390
|
-
clearTimeout(this.
|
|
5391
|
-
this.
|
|
5435
|
+
clearTimeout(this.getData("internal_queueempty"));
|
|
5436
|
+
this.setData("internal_queueempty", void 0);
|
|
5392
5437
|
}
|
|
5393
5438
|
if (options?.clientTrack && (this.LavalinkManager.utils.isTrack(options?.clientTrack) || this.LavalinkManager.utils.isUnresolvedTrack(options.clientTrack))) {
|
|
5394
5439
|
if (this.LavalinkManager.utils.isUnresolvedTrack(options.clientTrack)) {
|
|
@@ -5736,7 +5781,7 @@ var Player = class {
|
|
|
5736
5781
|
}
|
|
5737
5782
|
if (!this.playing && !this.queue.current) return this.play(), this;
|
|
5738
5783
|
const now = performance.now();
|
|
5739
|
-
this.
|
|
5784
|
+
this.setData("internal_skipped", true);
|
|
5740
5785
|
await this.node.updatePlayer({
|
|
5741
5786
|
guildId: this.guildId,
|
|
5742
5787
|
playerOptions: { track: { encoded: null }, paused: false }
|
|
@@ -5749,14 +5794,20 @@ var Player = class {
|
|
|
5749
5794
|
* @returns
|
|
5750
5795
|
*/
|
|
5751
5796
|
async stopPlaying(clearQueue = true, executeAutoplay = false) {
|
|
5752
|
-
this.
|
|
5797
|
+
this.setData("internal_stopPlaying", true);
|
|
5753
5798
|
if (this.queue.tracks.length && clearQueue === true) await this.queue.splice(0, this.queue.tracks.length);
|
|
5754
|
-
if (executeAutoplay === false) this.
|
|
5755
|
-
else this.
|
|
5799
|
+
if (executeAutoplay === false) this.setData("internal_autoplayStopPlaying", true);
|
|
5800
|
+
else this.setData("internal_autoplayStopPlaying", void 0);
|
|
5756
5801
|
const now = performance.now();
|
|
5757
5802
|
await this.node.updatePlayer({
|
|
5758
5803
|
guildId: this.guildId,
|
|
5759
|
-
playerOptions:
|
|
5804
|
+
playerOptions: this.node.isNodeLink() ? {
|
|
5805
|
+
track: { encoded: null },
|
|
5806
|
+
// @ts-expect-error - nextTrack is not a valid property of LavalinkPlayOptions but for NodeLink it is
|
|
5807
|
+
nextTrack: { encoded: null }
|
|
5808
|
+
} : {
|
|
5809
|
+
track: { encoded: null }
|
|
5810
|
+
}
|
|
5760
5811
|
});
|
|
5761
5812
|
this.paused = false;
|
|
5762
5813
|
this.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
|
|
@@ -5827,11 +5878,11 @@ var Player = class {
|
|
|
5827
5878
|
console.log(
|
|
5828
5879
|
`Lavalink-Client-Debug | PlayerDestroy [::] destroy Function, [guildId ${this.guildId}] - Destroy-Reason: ${String(reason)}`
|
|
5829
5880
|
);
|
|
5830
|
-
if (this.
|
|
5831
|
-
clearTimeout(this.
|
|
5832
|
-
this.
|
|
5881
|
+
if (this.getData("internal_queueempty")) {
|
|
5882
|
+
clearTimeout(this.getData("internal_queueempty"));
|
|
5883
|
+
this.setData("internal_queueempty", void 0);
|
|
5833
5884
|
}
|
|
5834
|
-
if (this.
|
|
5885
|
+
if (this.getData("internal_destroystatus") === true) {
|
|
5835
5886
|
this._emitDebugEvent("PlayerDestroyingSomewhereElse" /* PlayerDestroyingSomewhereElse */, {
|
|
5836
5887
|
state: "warn",
|
|
5837
5888
|
message: `Player is already destroying somewhere else..`,
|
|
@@ -5843,9 +5894,9 @@ var Player = class {
|
|
|
5843
5894
|
);
|
|
5844
5895
|
return;
|
|
5845
5896
|
}
|
|
5846
|
-
this.
|
|
5897
|
+
this.setData("internal_destroystatus", true);
|
|
5847
5898
|
if (disconnect) await this.disconnect(true);
|
|
5848
|
-
else this.
|
|
5899
|
+
else this.setData("internal_destroywithoutdisconnect", true);
|
|
5849
5900
|
await this.queue.utils.destroy();
|
|
5850
5901
|
this.LavalinkManager.deletePlayer(this.guildId);
|
|
5851
5902
|
await this.node.destroyPlayer(this.guildId);
|
|
@@ -5920,7 +5971,7 @@ var Player = class {
|
|
|
5920
5971
|
if (!updateNode) throw new Error("Could not find the new Node");
|
|
5921
5972
|
if (!updateNode.connected) throw new Error("The provided Node is not active or disconnected");
|
|
5922
5973
|
if (this.node.id === updateNode.id) throw new Error("Player is already on the provided Node");
|
|
5923
|
-
if (this.
|
|
5974
|
+
if (this.getData("internal_nodeChanging") === true)
|
|
5924
5975
|
throw new Error("Player is already changing the node please wait");
|
|
5925
5976
|
if (checkSources) {
|
|
5926
5977
|
const isDefaultSource = () => {
|
|
@@ -5958,7 +6009,7 @@ var Player = class {
|
|
|
5958
6009
|
const currentTrack = this.queue.current;
|
|
5959
6010
|
if (!this.voice.endpoint || !this.voice.sessionId || !this.voice.token)
|
|
5960
6011
|
throw new Error("Voice Data is missing, can't change the node");
|
|
5961
|
-
this.
|
|
6012
|
+
this.setData("internal_nodeChanging", true);
|
|
5962
6013
|
if (this.node.connected) await this.node.destroyPlayer(this.guildId);
|
|
5963
6014
|
this.node = updateNode;
|
|
5964
6015
|
const now = performance.now();
|
|
@@ -5966,7 +6017,7 @@ var Player = class {
|
|
|
5966
6017
|
await this.connect();
|
|
5967
6018
|
const hasSponsorBlock = !this.node._checkForPlugins || this.node.info?.plugins?.find((v) => v.name === "sponsorblock-plugin");
|
|
5968
6019
|
if (hasSponsorBlock) {
|
|
5969
|
-
const sponsorBlockCategories = this.
|
|
6020
|
+
const sponsorBlockCategories = this.getData("internal_sponsorBlockCategories");
|
|
5970
6021
|
if (Array.isArray(sponsorBlockCategories) && sponsorBlockCategories.length) {
|
|
5971
6022
|
await this.setSponsorBlock(sponsorBlockCategories).catch((error) => {
|
|
5972
6023
|
this._emitDebugEvent("PlayerChangeNode" /* PlayerChangeNode */, {
|
|
@@ -6017,7 +6068,7 @@ var Player = class {
|
|
|
6017
6068
|
});
|
|
6018
6069
|
throw new Error(`Failed to change the node: ${error}`);
|
|
6019
6070
|
} finally {
|
|
6020
|
-
this.
|
|
6071
|
+
this.setData("internal_nodeChanging", void 0);
|
|
6021
6072
|
}
|
|
6022
6073
|
}
|
|
6023
6074
|
/**
|
|
@@ -6407,7 +6458,7 @@ var LavalinkManager = class _LavalinkManager extends EventEmitter2 {
|
|
|
6407
6458
|
deletePlayer(guildId) {
|
|
6408
6459
|
const oldPlayer = this.getPlayer(guildId);
|
|
6409
6460
|
if (!oldPlayer) return;
|
|
6410
|
-
if (typeof oldPlayer.voiceChannelId === "string" && oldPlayer.connected && !oldPlayer.
|
|
6461
|
+
if (typeof oldPlayer.voiceChannelId === "string" && oldPlayer.connected && !oldPlayer.getData("internal_destroywithoutdisconnect")) {
|
|
6411
6462
|
if (!this.options?.advancedOptions?.debugOptions?.playerDestroy?.dontThrowError)
|
|
6412
6463
|
throw new Error(
|
|
6413
6464
|
`Use Player#destroy() not LavalinkManager#deletePlayer() to stop the Player ${safeStringify(oldPlayer.toJSON?.())}`
|
|
@@ -6554,7 +6605,7 @@ var LavalinkManager = class _LavalinkManager extends EventEmitter2 {
|
|
|
6554
6605
|
);
|
|
6555
6606
|
return;
|
|
6556
6607
|
}
|
|
6557
|
-
if (player.
|
|
6608
|
+
if (player.getData("internal_destroystatus") === true) {
|
|
6558
6609
|
this._debugNoAudio("warn", "LavalinkManager > sendRawData()", {
|
|
6559
6610
|
message: "Player is in a destroying state. can't signal the voice states"
|
|
6560
6611
|
});
|
package/package.json
CHANGED