lavalink-client 2.6.7 → 2.7.1

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.mjs CHANGED
@@ -19,6 +19,7 @@ var DebugEvents = /* @__PURE__ */ ((DebugEvents2) => {
19
19
  DebugEvents2["PlayerUpdateSuccess"] = "PlayerUpdateSuccess";
20
20
  DebugEvents2["HeartBeatTriggered"] = "HeartBeatTriggered";
21
21
  DebugEvents2["NoSocketOnDestroy"] = "NoSocketOnDestroy";
22
+ DebugEvents2["SocketCleanupError"] = "SocketCleanupError";
22
23
  DebugEvents2["SocketTerminateHeartBeatTimeout"] = "SocketTerminateHeartBeatTimeout";
23
24
  DebugEvents2["TryingConnectWhileConnected"] = "TryingConnectWhileConnected";
24
25
  DebugEvents2["LavaSearchNothingFound"] = "LavaSearchNothingFound";
@@ -421,7 +422,7 @@ var SourceLinksRegexes = {
421
422
  /** DEFAULT SUPPORTED BY LAVALINK */
422
423
  YoutubeRegex: /https?:\/\/?(?:www\.)?(?:(m|www)\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|shorts|playlist\?|watch\?v=|watch\?.+(?:&|&);v=))([a-zA-Z0-9\-_]{11})?(?:(?:\?|&|&)index=((?:\d){1,3}))?(?:(?:\?|&|&)?list=([a-zA-Z\-_0-9]{34}))?(?:\S+)?/,
423
424
  YoutubeMusicRegex: /https?:\/\/?(?:www\.)?(?:(music|m|www)\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|shorts|playlist\?|watch\?v=|watch\?.+(?:&|&);v=))([a-zA-Z0-9\-_]{11})?(?:(?:\?|&|&)index=((?:\d){1,3}))?(?:(?:\?|&|&)?list=([a-zA-Z\-_0-9]{34}))?(?:\S+)?/,
424
- SoundCloudRegex: /https:\/\/(?:on\.)?soundcloud\.com\//,
425
+ SoundCloudRegex: /https?:\/\/(?:on\.)?soundcloud\.com\//,
425
426
  SoundCloudMobileRegex: /https?:\/\/(soundcloud\.app\.goo\.gl)\/(\S+)/,
426
427
  bandcamp: /https?:\/\/?(?:www\.)?([\d|\w]+)\.bandcamp\.com\/(\S+)/,
427
428
  TwitchTv: /https?:\/\/?(?:www\.)?twitch\.tv\/\w+/,
@@ -941,9 +942,15 @@ async function getClosestTrack(data, player) {
941
942
  source: sourceName !== "twitch" && sourceName !== "flowery-tts" ? sourceName : player.LavalinkManager.options?.playerOptions?.defaultSearchPlatform
942
943
  }, data.requester).then((res) => {
943
944
  let trackToUse = null;
944
- if (data.info.author && !trackToUse) trackToUse = res.tracks.find((track) => [data.info?.author || "", `${data.info?.author} - Topic`].some((name) => new RegExp(`^${escapeRegExp(name)}$`, "i").test(track.info?.author)) || new RegExp(`^${escapeRegExp(data.info?.title)}$`, "i").test(track.info?.title));
945
- if (data.info.duration && !trackToUse) trackToUse = res.tracks.find((track) => track.info?.duration >= data.info?.duration - 1500 && track?.info.duration <= data.info?.duration + 1500);
946
- if (data.info.isrc && !trackToUse) trackToUse = res.tracks.find((track) => track.info?.isrc === data.info?.isrc);
945
+ if ((data.info?.title || data.info?.author) && !trackToUse) trackToUse = res.tracks.find(
946
+ (track) => (
947
+ // find via author name (i ... case insensitve)
948
+ [data.info?.author || "", `${data.info?.author} - Topic`].some((name) => new RegExp(`^${escapeRegExp(name)}$`, "i").test(track.info?.author)) || // find via title (i ... case insensitve)
949
+ new RegExp(`^${escapeRegExp(data.info?.title)}$`, "i").test(track.info?.title)
950
+ )
951
+ );
952
+ if (data.info?.isrc && !trackToUse) trackToUse = res.tracks.find((track) => track.info?.isrc === data.info?.isrc);
953
+ if (data.info?.duration && !trackToUse) trackToUse = res.tracks.find((track) => track.info?.duration >= data.info?.duration - 1500 && track?.info.duration <= data.info?.duration + 1500);
947
954
  return applyUnresolvedData(trackToUse || res.tracks[0], data, player.LavalinkManager.utils);
948
955
  });
949
956
  }
@@ -1287,7 +1294,7 @@ var LavalinkNode = class {
1287
1294
  functionLayer: "LavalinkNode > nodeEvent > stats > heartBeat()"
1288
1295
  });
1289
1296
  }
1290
- if (this.pingTimeout) clearTimeout(this.pingTimeout);
1297
+ this.resetAckTimeouts(false, true);
1291
1298
  this.pingTimeout = setTimeout(() => {
1292
1299
  this.pingTimeout = null;
1293
1300
  if (!this.socket) {
@@ -1380,31 +1387,27 @@ var LavalinkNode = class {
1380
1387
  }
1381
1388
  };
1382
1389
  handlePlayerOperations().finally(() => {
1383
- this.socket.close(1e3, "Node-Destroy");
1384
- this.socket.removeAllListeners();
1390
+ this.socket?.close(1e3, "Node-Destroy");
1391
+ this.socket?.removeAllListeners();
1385
1392
  this.socket = null;
1386
- this.reconnectAttempts = 1;
1387
- clearTimeout(this.reconnectTimeout);
1393
+ this.resetReconnectionAttempts();
1388
1394
  if (deleteNode) {
1389
1395
  this.NodeManager.emit("destroy", this, destroyReason);
1390
1396
  this.NodeManager.nodes.delete(this.id);
1391
- clearInterval(this.heartBeatInterval);
1392
- clearTimeout(this.pingTimeout);
1397
+ this.resetAckTimeouts(true, true);
1393
1398
  } else {
1394
1399
  this.NodeManager.emit("disconnect", this, { code: 1e3, reason: destroyReason });
1395
1400
  }
1396
1401
  });
1397
1402
  } else {
1398
- this.socket.close(1e3, "Node-Destroy");
1399
- this.socket.removeAllListeners();
1403
+ this.socket?.close(1e3, "Node-Destroy");
1404
+ this.socket?.removeAllListeners();
1400
1405
  this.socket = null;
1401
- this.reconnectAttempts = 1;
1402
- clearTimeout(this.reconnectTimeout);
1406
+ this.resetReconnectionAttempts();
1403
1407
  if (deleteNode) {
1404
1408
  this.NodeManager.emit("destroy", this, destroyReason);
1405
1409
  this.NodeManager.nodes.delete(this.id);
1406
- clearInterval(this.heartBeatInterval);
1407
- clearTimeout(this.pingTimeout);
1410
+ this.resetAckTimeouts(true, true);
1408
1411
  } else {
1409
1412
  this.NodeManager.emit("disconnect", this, { code: 1e3, reason: destroyReason });
1410
1413
  }
@@ -1425,11 +1428,10 @@ var LavalinkNode = class {
1425
1428
  */
1426
1429
  disconnect(disconnectReason) {
1427
1430
  if (!this.connected) return;
1428
- this.socket.close(1e3, "Node-Disconnect");
1429
- this.socket.removeAllListeners();
1431
+ this.socket?.close(1e3, "Node-Disconnect");
1432
+ this.socket?.removeAllListeners();
1430
1433
  this.socket = null;
1431
- this.reconnectAttempts = 1;
1432
- clearTimeout(this.reconnectTimeout);
1434
+ this.resetReconnectionAttempts();
1433
1435
  this.NodeManager.emit("disconnect", this, { code: 1e3, reason: disconnectReason });
1434
1436
  }
1435
1437
  /**
@@ -1817,8 +1819,6 @@ var LavalinkNode = class {
1817
1819
  this.NodeManager.emit("error", this, error);
1818
1820
  return this.destroy("NodeReconnectFail" /* NodeReconnectFail */);
1819
1821
  }
1820
- this.socket.removeAllListeners();
1821
- this.socket = null;
1822
1822
  this.NodeManager.emit("reconnecting", this);
1823
1823
  this.connect();
1824
1824
  this.reconnectAttempts++;
@@ -1831,16 +1831,42 @@ var LavalinkNode = class {
1831
1831
  this.NodeManager.emit("error", this, error);
1832
1832
  return this.destroy("NodeReconnectFail" /* NodeReconnectFail */);
1833
1833
  }
1834
- this.socket.removeAllListeners();
1835
- this.socket = null;
1836
1834
  this.NodeManager.emit("reconnecting", this);
1837
1835
  this.connect();
1838
1836
  this.reconnectAttempts++;
1839
1837
  }, this.options.retryDelay || 1e3);
1840
1838
  }
1839
+ /**
1840
+ * Private function to reset the reconnection attempts
1841
+ * @returns
1842
+ */
1843
+ resetReconnectionAttempts() {
1844
+ this.reconnectAttempts = 1;
1845
+ clearTimeout(this.reconnectTimeout);
1846
+ this.reconnectTimeout = null;
1847
+ return;
1848
+ }
1849
+ /**
1850
+ * Private function to reset timeouts/intervals for heartbeating/pinging
1851
+ * @param heartbeat
1852
+ * @param ping
1853
+ * @returns
1854
+ */
1855
+ resetAckTimeouts(heartbeat = true, ping = true) {
1856
+ if (ping) {
1857
+ if (this.pingTimeout) clearTimeout(this.pingTimeout);
1858
+ this.pingTimeout = null;
1859
+ }
1860
+ if (heartbeat) {
1861
+ if (this.heartBeatInterval) clearInterval(this.heartBeatInterval);
1862
+ this.heartBeatInterval = null;
1863
+ }
1864
+ return;
1865
+ }
1841
1866
  /** @private util function for handling opening events from websocket */
1842
1867
  async open() {
1843
1868
  this.isAlive = true;
1869
+ this.resetReconnectionAttempts();
1844
1870
  if (this.options.enablePingOnStatsCheck) this.heartBeat();
1845
1871
  if (this.heartBeatInterval) clearInterval(this.heartBeatInterval);
1846
1872
  if (this.options.heartBeatInterval > 0) {
@@ -1856,8 +1882,6 @@ var LavalinkNode = class {
1856
1882
  this.socket.ping();
1857
1883
  }, this.options.heartBeatInterval || 3e4);
1858
1884
  }
1859
- if (this.reconnectTimeout) clearTimeout(this.reconnectTimeout);
1860
- this.reconnectAttempts = 1;
1861
1885
  this.info = await this.fetchInfo().catch((e) => (console.error(e, "ON-OPEN-FETCH"), null));
1862
1886
  if (!this.info && ["v3", "v4"].includes(this.version)) {
1863
1887
  const errorString = `Lavalink Node (${this.restAddress}) does not provide any /${this.version}/info`;
@@ -1867,8 +1891,22 @@ var LavalinkNode = class {
1867
1891
  }
1868
1892
  /** @private util function for handling closing events from websocket */
1869
1893
  close(code, reason) {
1870
- if (this.pingTimeout) clearTimeout(this.pingTimeout);
1871
- if (this.heartBeatInterval) clearInterval(this.heartBeatInterval);
1894
+ this.resetAckTimeouts(true, true);
1895
+ try {
1896
+ if (this.socket) {
1897
+ this.socket.removeAllListeners();
1898
+ this.socket = null;
1899
+ }
1900
+ } catch (e) {
1901
+ if (this.NodeManager?.LavalinkManager?.options?.advancedOptions?.enableDebugEvents) {
1902
+ this.NodeManager.LavalinkManager.emit("debug", "SocketCleanupError" /* SocketCleanupError */, {
1903
+ state: "warn",
1904
+ message: `An error occurred during socket cleanup in close() (likely a race condition): ${e.message}`,
1905
+ functionLayer: "LavalinkNode > close()"
1906
+ });
1907
+ }
1908
+ }
1909
+ this.isAlive = false;
1872
1910
  if (code === 1006 && !reason) reason = "Socket got terminated due to no ping connection";
1873
1911
  if (code === 1e3 && reason === "Node-Disconnect") return;
1874
1912
  this.NodeManager.emit("disconnect", this, { code, reason });
@@ -1953,6 +1991,7 @@ var LavalinkNode = class {
1953
1991
  this.handleEvent(payload);
1954
1992
  break;
1955
1993
  case "ready":
1994
+ this.resetReconnectionAttempts();
1956
1995
  this.sessionId = payload.sessionId;
1957
1996
  this.resuming.enabled = payload.resumed;
1958
1997
  if (payload.resumed === true) {
@@ -2631,13 +2670,19 @@ var bandCampSearch = async (player, query, requestUser) => {
2631
2670
  "Cookie": "$Version=1"
2632
2671
  }
2633
2672
  });
2634
- const json = await data.json();
2673
+ if (!data.ok) throw new Error(`Bandcamp Error: ${data.statusText}`);
2674
+ let json = null;
2675
+ try {
2676
+ json = await data.json();
2677
+ } catch {
2678
+ throw new Error("Invalid JSON response from Bandcamp");
2679
+ }
2635
2680
  tracks = json?.results?.filter((x) => !!x && typeof x === "object" && "type" in x && x.type === "t").map?.((item) => player.LavalinkManager.utils.buildUnresolvedTrack({
2636
2681
  uri: item.url || item.uri,
2637
2682
  artworkUrl: item.img,
2638
2683
  author: item.band_name,
2639
2684
  title: item.name,
2640
- identifier: item.id ? `${item.id}` : item.url?.split("/").reverse()[0]
2685
+ identifier: item.id ? `${item.id}` : item.url?.split("/")?.reverse()[0]
2641
2686
  }, requestUser));
2642
2687
  } catch (e) {
2643
2688
  error = e;
@@ -2846,15 +2891,15 @@ var FilterManager = class {
2846
2891
  const lavalinkFilterData = this.data.pluginFilters?.["lavalink-filter-plugin"] || { echo: { decay: this.data.pluginFilters?.echo?.decay && !this.data.pluginFilters?.echo?.echoLength ? this.data.pluginFilters.echo.decay : 0, delay: this.data.pluginFilters?.echo?.delay || 0 }, reverb: { gains: [], delays: [], ...this.data.pluginFilters.reverb } };
2847
2892
  this.filters.lavalinkFilterPlugin.echo = lavalinkFilterData.echo.decay !== 0 || lavalinkFilterData.echo.delay !== 0;
2848
2893
  this.filters.lavalinkFilterPlugin.reverb = lavalinkFilterData.reverb?.delays?.length !== 0 || lavalinkFilterData.reverb?.gains?.length !== 0;
2849
- this.filters.lavalinkLavaDspxPlugin.highPass = Object.values(this.data.pluginFilters["high-pass"] || {}).length > 0;
2850
- this.filters.lavalinkLavaDspxPlugin.lowPass = Object.values(this.data.pluginFilters["low-pass"] || {}).length > 0;
2851
- this.filters.lavalinkLavaDspxPlugin.normalization = Object.values(this.data.pluginFilters.normalization || {}).length > 0;
2852
- this.filters.lavalinkLavaDspxPlugin.echo = Object.values(this.data.pluginFilters.echo || {}).length > 0 && typeof this.data.pluginFilters?.echo?.delay === "undefined";
2853
- this.filters.lowPass = this.data.lowPass.smoothing !== 0;
2854
- this.filters.karaoke = Object.values(this.data.karaoke).some((v) => v !== 0);
2894
+ this.filters.lavalinkLavaDspxPlugin.highPass = Object.values(this.data.pluginFilters?.["high-pass"] || {}).length > 0;
2895
+ this.filters.lavalinkLavaDspxPlugin.lowPass = Object.values(this.data.pluginFilters?.["low-pass"] || {}).length > 0;
2896
+ this.filters.lavalinkLavaDspxPlugin.normalization = Object.values(this.data.pluginFilters?.normalization || {}).length > 0;
2897
+ this.filters.lavalinkLavaDspxPlugin.echo = Object.values(this.data.pluginFilters?.echo || {}).length > 0 && typeof this.data.pluginFilters?.echo?.delay === "undefined";
2898
+ this.filters.lowPass = this.privateNot0(this.data.lowPass?.smoothing);
2899
+ this.filters.karaoke = Object.values(this.data.karaoke ?? {}).some((v) => v !== 0);
2855
2900
  if ((this.filters.nightcore || this.filters.vaporwave) && oldFilterTimescale) {
2856
- if (oldFilterTimescale.pitch !== this.data.timescale.pitch || oldFilterTimescale.rate !== this.data.timescale.rate || oldFilterTimescale.speed !== this.data.timescale.speed) {
2857
- this.filters.custom = Object.values(this.data.timescale).some((v) => v !== 1);
2901
+ if (oldFilterTimescale.pitch !== this.data.timescale?.pitch || oldFilterTimescale.rate !== this.data.timescale?.rate || oldFilterTimescale.speed !== this.data.timescale?.speed) {
2902
+ this.filters.custom = Object.values(this.data.timescale || {}).some((v) => v !== 1);
2858
2903
  this.filters.nightcore = false;
2859
2904
  this.filters.vaporwave = false;
2860
2905
  }
@@ -3667,8 +3712,11 @@ var Queue = class {
3667
3712
  this.queueChanges.tracksAdd(this.guildId, (Array.isArray(TrackOrTracks) ? TrackOrTracks : [TrackOrTracks]).flat(2).filter((v) => this.managerUtils.isTrack(v) || this.managerUtils.isUnresolvedTrack(v)), index, oldStored, this.utils.toJSON());
3668
3713
  } catch {
3669
3714
  }
3670
- let spliced = TrackOrTracks ? this.tracks.splice(index, amount, ...(Array.isArray(TrackOrTracks) ? TrackOrTracks : [TrackOrTracks]).flat(2).filter((v) => this.managerUtils.isTrack(v) || this.managerUtils.isUnresolvedTrack(v))) : this.tracks.splice(index, amount);
3671
- spliced = Array.isArray(spliced) ? spliced : [spliced];
3715
+ const spliced = TrackOrTracks ? this.tracks.splice(
3716
+ index,
3717
+ amount,
3718
+ ...(Array.isArray(TrackOrTracks) ? TrackOrTracks : [TrackOrTracks]).flat(2).filter((v) => this.managerUtils.isTrack(v) || this.managerUtils.isUnresolvedTrack(v))
3719
+ ) : this.tracks.splice(index, amount);
3672
3720
  if (typeof this.queueChanges?.tracksRemoved === "function") try {
3673
3721
  this.queueChanges.tracksRemoved(this.guildId, spliced, index, oldStored, this.utils.toJSON());
3674
3722
  } catch {
@@ -3681,6 +3729,7 @@ var Queue = class {
3681
3729
  * - single Track | UnresolvedTrack
3682
3730
  * - multiple Track | UnresovedTrack
3683
3731
  * - at the index or multiple indexes
3732
+ * - Since v2.7 the removed tracks get unshifted into the previous queue state instead of pushed (indexed at the start instead of end - as it should)
3684
3733
  * @param removeQueryTrack
3685
3734
  * @returns null (if nothing was removed) / { removed } where removed is an array with all removed elements
3686
3735
  *
@@ -3726,9 +3775,10 @@ var Queue = class {
3726
3775
  if (Array.isArray(removeQueryTrack)) {
3727
3776
  if (removeQueryTrack.every((v) => typeof v === "number")) {
3728
3777
  const removed3 = [];
3729
- for (const i of removeQueryTrack) {
3778
+ const sortedIndexes = removeQueryTrack.sort((a, b) => b - a);
3779
+ for (const i of sortedIndexes) {
3730
3780
  if (this.tracks[i]) {
3731
- removed3.push(...this.tracks.splice(i, 1));
3781
+ removed3.unshift(...this.tracks.splice(i, 1));
3732
3782
  }
3733
3783
  }
3734
3784
  if (!removed3.length) return null;
@@ -3744,9 +3794,10 @@ var Queue = class {
3744
3794
  ));
3745
3795
  if (!tracksToRemove.length) return null;
3746
3796
  const removed2 = [];
3797
+ tracksToRemove.sort((a, b) => b.i - a.i);
3747
3798
  for (const { i } of tracksToRemove) {
3748
3799
  if (this.tracks[i]) {
3749
- removed2.push(...this.tracks.splice(i, 1));
3800
+ removed2.unshift(...this.tracks.splice(i, 1));
3750
3801
  }
3751
3802
  }
3752
3803
  if (typeof this.queueChanges?.tracksRemoved === "function") try {
@@ -3969,7 +4020,7 @@ var Player = class {
3969
4020
  this.queue.current = options.clientTrack || null;
3970
4021
  this.queue.utils.save();
3971
4022
  if (typeof options?.volume === "number" && !isNaN(options?.volume)) {
3972
- this.volume = Math.max(Math.min(options?.volume, 500), 0);
4023
+ this.volume = Math.max(Math.min(options?.volume, 1e3), 0);
3973
4024
  let vol = Number(this.volume);
3974
4025
  if (this.LavalinkManager.options.playerOptions.volumeDecrementer) vol *= this.LavalinkManager.options.playerOptions.volumeDecrementer;
3975
4026
  this.lavalinkVolume = Math.round(vol);
@@ -4039,7 +4090,7 @@ var Player = class {
4039
4090
  }
4040
4091
  if (!this.queue.current) throw new Error(`There is no Track in the Queue, nor provided in the PlayOptions`);
4041
4092
  if (typeof options?.volume === "number" && !isNaN(options?.volume)) {
4042
- this.volume = Math.max(Math.min(options?.volume, 500), 0);
4093
+ this.volume = Math.max(Math.min(options?.volume, 1e3), 0);
4043
4094
  let vol = Number(this.volume);
4044
4095
  if (this.LavalinkManager.options.playerOptions.volumeDecrementer) vol *= this.LavalinkManager.options.playerOptions.volumeDecrementer;
4045
4096
  this.lavalinkVolume = Math.round(vol);
@@ -4062,9 +4113,9 @@ var Player = class {
4062
4113
  paused: options?.paused ?? void 0,
4063
4114
  voice: options?.voice ?? void 0
4064
4115
  }).filter((v) => typeof v[1] !== "undefined"));
4065
- if (typeof finalOptions.position !== "undefined" && isNaN(finalOptions.position) || typeof finalOptions.position === "number" && (finalOptions.position < 0 || finalOptions.position >= this.queue.current.info.duration)) throw new Error("PlayerOption#position must be a positive number, less than track's duration");
4116
+ if (typeof finalOptions.position !== "undefined" && isNaN(finalOptions.position) || typeof finalOptions.position === "number" && finalOptions.position < 0 || typeof finalOptions.position === "number" && this.queue.current.info.duration > 0 && finalOptions.position >= this.queue.current.info.duration) throw new Error("PlayerOption#position must be a positive number, less than track's duration");
4066
4117
  if (typeof finalOptions.volume !== "undefined" && isNaN(finalOptions.volume) || typeof finalOptions.volume === "number" && finalOptions.volume < 0) throw new Error("PlayerOption#volume must be a positive number");
4067
- if (typeof finalOptions.endTime !== "undefined" && isNaN(finalOptions.endTime) || typeof finalOptions.endTime === "number" && (finalOptions.endTime < 0 || finalOptions.endTime >= this.queue.current.info.duration)) throw new Error("PlayerOption#endTime must be a positive number, less than track's duration");
4118
+ if (typeof finalOptions.endTime !== "undefined" && isNaN(finalOptions.endTime) || typeof finalOptions.endTime === "number" && finalOptions.endTime < 0 || typeof finalOptions.endTime === "number" && this.queue.current.info.duration > 0 && finalOptions.endTime >= this.queue.current.info.duration) throw new Error("PlayerOption#endTime must be a positive number, less than track's duration");
4068
4119
  if (typeof finalOptions.position === "number" && typeof finalOptions.endTime === "number" && finalOptions.endTime < finalOptions.position) throw new Error("PlayerOption#endTime must be bigger than PlayerOption#position");
4069
4120
  const now = performance.now();
4070
4121
  await this.node.updatePlayer({
@@ -4139,7 +4190,7 @@ var Player = class {
4139
4190
  */
4140
4191
  async search(query, requestUser, throwOnEmpty = false) {
4141
4192
  const Query = this.LavalinkManager.utils.transformQuery(query);
4142
- if (["bcsearch", "bandcamp"].includes(Query.source) && !this.node.info.sourceManagers.includes("bandcamp")) {
4193
+ if (["bcsearch", "bandcamp"].includes(Query.source) && !this.node.info?.sourceManagers.includes("bandcamp")) {
4143
4194
  if (this.LavalinkManager.options?.advancedOptions?.enableDebugEvents) {
4144
4195
  this.LavalinkManager.emit("debug", "BandcampSearchLokalEngine" /* BandcampSearchLokalEngine */, {
4145
4196
  state: "log",
@@ -4230,6 +4281,7 @@ var Player = class {
4230
4281
  else this.set("internal_autoplayStopPlaying", void 0);
4231
4282
  const now = performance.now();
4232
4283
  await this.node.updatePlayer({ guildId: this.guildId, playerOptions: { track: { encoded: null } } });
4284
+ this.paused = false;
4233
4285
  this.ping.lavalink = Math.round((performance.now() - now) / 10) / 100;
4234
4286
  return this;
4235
4287
  }
@@ -4394,7 +4446,7 @@ var Player = class {
4394
4446
  if (this.queue.current || this.queue.tracks.length) {
4395
4447
  const trackSources = new Set([this.queue.current, ...this.queue.tracks].map((track) => track.info.sourceName));
4396
4448
  const missingSources = [...trackSources].filter(
4397
- (source) => !updateNode.info.sourceManagers.includes(source)
4449
+ (source) => !updateNode.info?.sourceManagers.includes(source)
4398
4450
  );
4399
4451
  if (missingSources.length)
4400
4452
  throw new RangeError(`Sources missing for Node ${updateNode.id}: ${missingSources.join(", ")}`);
@@ -4816,7 +4868,7 @@ var LavalinkManager = class extends EventEmitter2 {
4816
4868
  deletePlayer(guildId) {
4817
4869
  const oldPlayer = this.getPlayer(guildId);
4818
4870
  if (!oldPlayer) return;
4819
- if (oldPlayer.voiceChannelId === "string" && oldPlayer.connected && !oldPlayer.get("internal_destroywithoutdisconnect")) {
4871
+ if (typeof oldPlayer.voiceChannelId === "string" && oldPlayer.connected && !oldPlayer.get("internal_destroywithoutdisconnect")) {
4820
4872
  if (!this.options?.advancedOptions?.debugOptions?.playerDestroy?.dontThrowError) throw new Error(`Use Player#destroy() not LavalinkManager#deletePlayer() to stop the Player ${safeStringify(oldPlayer.toJSON?.())}`);
4821
4873
  else if (this.options?.advancedOptions?.enableDebugEvents) {
4822
4874
  this.emit("debug", "PlayerDeleteInsteadOfDestroy" /* PlayerDeleteInsteadOfDestroy */, {
@@ -5032,6 +5084,7 @@ var LavalinkManager = class extends EventEmitter2 {
5032
5084
  if (this.options?.advancedOptions?.debugOptions?.noAudio === true) console.debug(`Lavalink-Client-Debug | NO-AUDIO [::] sendRawData function, Function to assing sessionId provided, but no found in Payload: ${safeStringify(update, 2)}`);
5033
5085
  }
5034
5086
  player.voiceChannelId = update.channel_id;
5087
+ player.options.voiceChannelId = update.channel_id;
5035
5088
  const selfMuteChanged = typeof update.self_mute === "boolean" && player.voiceState.selfMute !== update.self_mute;
5036
5089
  const serverMuteChanged = typeof update.mute === "boolean" && player.voiceState.serverMute !== update.mute;
5037
5090
  const selfDeafChanged = typeof update.self_deaf === "boolean" && player.voiceState.selfDeaf !== update.self_deaf;
@@ -5074,11 +5127,14 @@ var LavalinkManager = class extends EventEmitter2 {
5074
5127
  if (player.queue.tracks.length) {
5075
5128
  return void await player.play({ paused: previousPaused });
5076
5129
  }
5077
- this.emit("debug", "PlayerAutoReconnect" /* PlayerAutoReconnect */, {
5078
- state: "log",
5079
- message: `Auto reconnected, but nothing to play`,
5080
- functionLayer: "LavalinkManager > sendRawData()"
5081
- });
5130
+ if (this.options?.advancedOptions?.enableDebugEvents) {
5131
+ this.emit("debug", "PlayerAutoReconnect" /* PlayerAutoReconnect */, {
5132
+ state: "log",
5133
+ message: `Auto reconnected, but nothing to play`,
5134
+ functionLayer: "LavalinkManager > sendRawData()"
5135
+ });
5136
+ }
5137
+ return;
5082
5138
  } catch (e) {
5083
5139
  console.error(e);
5084
5140
  return void await player.destroy("PlayerReconnectFail" /* PlayerReconnectFail */);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lavalink-client",
3
- "version": "2.6.7",
3
+ "version": "2.7.1",
4
4
  "description": "Easy, flexible and feature-rich lavalink@v4 Client. Both for Beginners and Proficients.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -55,14 +55,14 @@
55
55
  },
56
56
  "homepage": "https://tomato6966.github.io/lavalink-client/",
57
57
  "devDependencies": {
58
- "@eslint/eslintrc": "^3.3.1",
58
+ "@eslint/eslintrc": "^3.3.3",
59
59
  "@eslint/js": "^9.39.1",
60
- "@types/node": "^24.10.0",
60
+ "@types/node": "^24.10.1",
61
61
  "@types/ws": "^8.18.1",
62
- "@typescript-eslint/eslint-plugin": "^8.46.3",
63
- "@typescript-eslint/parser": "^8.46.3",
62
+ "@typescript-eslint/eslint-plugin": "^8.48.0",
63
+ "@typescript-eslint/parser": "^8.48.0",
64
64
  "eslint": "^9.39.1",
65
- "tsup": "^8.5.0",
65
+ "tsup": "^8.5.1",
66
66
  "typescript": "^5.9.3"
67
67
  },
68
68
  "dependencies": {