magmastream 2.9.0-dev.0 → 2.9.0-dev.10

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.
@@ -61,13 +61,13 @@ class Node {
61
61
  this.options = {
62
62
  port: 2333,
63
63
  password: "youshallnotpass",
64
- secure: false,
65
- retryAmount: 30,
66
- retryDelay: 60000,
67
- priority: 0,
64
+ useSSL: false,
65
+ maxRetryAttempts: 30,
66
+ retryDelayMs: 60000,
67
+ nodePriority: 0,
68
68
  ...options,
69
69
  };
70
- if (this.options.secure) {
70
+ if (this.options.useSSL) {
71
71
  this.options.port = 443;
72
72
  }
73
73
  this.options.identifier = options.identifier || options.host;
@@ -179,7 +179,7 @@ class Node {
179
179
  * @remarks
180
180
  * If the node is already connected, this method will do nothing.
181
181
  * If the node has a session ID, it will be sent in the headers of the WebSocket connection.
182
- * If the node has no session ID but the `resumeStatus` option is true, it will use the session ID
182
+ * If the node has no session ID but the `enableSessionResumeOption` option is true, it will use the session ID
183
183
  * stored in the sessionIds.json file if it exists.
184
184
  */
185
185
  connect() {
@@ -194,11 +194,11 @@ class Node {
194
194
  if (this.sessionId) {
195
195
  headers["Session-Id"] = this.sessionId;
196
196
  }
197
- else if (this.options.resumeStatus && sessionIdsMap.has(compositeKey)) {
197
+ else if (this.options.enableSessionResumeOption && sessionIdsMap.has(compositeKey)) {
198
198
  this.sessionId = sessionIdsMap.get(compositeKey) || null;
199
199
  headers["Session-Id"] = this.sessionId;
200
200
  }
201
- this.socket = new ws_1.default(`ws${this.options.secure ? "s" : ""}://${this.address}/v4/websocket`, { headers });
201
+ this.socket = new ws_1.default(`ws${this.options.useSSL ? "s" : ""}://${this.address}/v4/websocket`, { headers });
202
202
  this.socket.on("open", this.open.bind(this));
203
203
  this.socket.on("close", this.close.bind(this));
204
204
  this.socket.on("message", this.message.bind(this));
@@ -210,7 +210,7 @@ class Node {
210
210
  options: {
211
211
  clientId: this.manager.options.clientId,
212
212
  clientName: this.manager.options.clientName,
213
- secure: this.options.secure,
213
+ useSSL: this.options.useSSL,
214
214
  identifier: this.options.identifier,
215
215
  },
216
216
  };
@@ -235,11 +235,11 @@ class Node {
235
235
  identifier: this.options.identifier,
236
236
  address: this.address,
237
237
  sessionId: this.sessionId,
238
- playerCount: this.manager.players.filter((p) => p.node == this).size,
238
+ playerCount: (await this.manager.players.filter((p) => p.node == this)).size,
239
239
  };
240
240
  this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[NODE] Destroying node: ${JSON.stringify(debugInfo)}`);
241
241
  // Automove all players connected to that node
242
- const players = this.manager.players.filter((p) => p.node == this);
242
+ const players = await this.manager.players.filter((p) => p.node == this);
243
243
  if (players.size) {
244
244
  players.forEach(async (player) => {
245
245
  await player.autoMoveNode();
@@ -279,17 +279,17 @@ class Node {
279
279
  identifier: this.options.identifier,
280
280
  connected: this.connected,
281
281
  reconnectAttempts: this.reconnectAttempts,
282
- retryAmount: this.options.retryAmount,
283
- retryDelay: this.options.retryDelay,
282
+ maxRetryAttempts: this.options.maxRetryAttempts,
283
+ retryDelayMs: this.options.retryDelayMs,
284
284
  };
285
285
  // Emit a debug event indicating the node is attempting to reconnect
286
286
  this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[NODE] Reconnecting node: ${JSON.stringify(debugInfo)}`);
287
287
  // Schedule the reconnection attempt after the specified retry delay
288
288
  this.reconnectTimeout = setTimeout(async () => {
289
289
  // Check if the maximum number of retry attempts has been reached
290
- if (this.reconnectAttempts >= this.options.retryAmount) {
290
+ if (this.reconnectAttempts >= this.options.maxRetryAttempts) {
291
291
  // Emit an error event and destroy the node if retries are exhausted
292
- const error = new Error(`Unable to connect after ${this.options.retryAmount} attempts.`);
292
+ const error = new Error(`Unable to connect after ${this.options.maxRetryAttempts} attempts.`);
293
293
  this.manager.emit(Manager_1.ManagerEventTypes.NodeError, this, error);
294
294
  return await this.destroy();
295
295
  }
@@ -301,7 +301,7 @@ class Node {
301
301
  this.connect();
302
302
  // Increment the reconnect attempts counter
303
303
  this.reconnectAttempts++;
304
- }, this.options.retryDelay);
304
+ }, this.options.retryDelayMs);
305
305
  }
306
306
  /**
307
307
  * Handles the "open" event emitted by the WebSocket connection.
@@ -350,7 +350,7 @@ class Node {
350
350
  this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[NODE] Disconnected node: ${JSON.stringify(debugInfo)}`);
351
351
  // Try moving all players connected to that node to a useable one
352
352
  if (this.manager.useableNode) {
353
- const players = this.manager.players.filter((p) => p.node.options.identifier == this.options.identifier);
353
+ const players = await this.manager.players.filter((p) => p.node.options.identifier == this.options.identifier);
354
354
  if (players.size) {
355
355
  await Promise.all(Array.from(players.values(), (player) => player.autoMoveNode()));
356
356
  }
@@ -405,7 +405,7 @@ class Node {
405
405
  this.stats = { ...payload };
406
406
  break;
407
407
  case "playerUpdate":
408
- player = this.manager.players.get(payload.guildId);
408
+ player = await this.manager.players.get(payload.guildId);
409
409
  if (player && player.node.options.identifier !== this.options.identifier) {
410
410
  return;
411
411
  }
@@ -413,7 +413,7 @@ class Node {
413
413
  player.position = payload.state.position || 0;
414
414
  break;
415
415
  case "event":
416
- player = this.manager.players.get(payload.guildId);
416
+ player = await this.manager.players.get(payload.guildId);
417
417
  if (player && player.node.options.identifier !== this.options.identifier) {
418
418
  return;
419
419
  }
@@ -431,10 +431,10 @@ class Node {
431
431
  // Load player states from the JSON file
432
432
  await this.manager.loadPlayerStates(this.options.identifier);
433
433
  }
434
- if (this.options.resumeStatus) {
434
+ if (this.options.enableSessionResumeOption) {
435
435
  await this.rest.patch(`/v4/sessions/${this.sessionId}`, {
436
- resuming: this.options.resumeStatus,
437
- timeout: this.options.resumeTimeout,
436
+ resuming: this.options.enableSessionResumeOption,
437
+ timeout: this.options.sessionTimeoutMs,
438
438
  });
439
439
  }
440
440
  break;
@@ -452,10 +452,10 @@ class Node {
452
452
  async handleEvent(payload) {
453
453
  if (!payload.guildId)
454
454
  return;
455
- const player = this.manager.players.get(payload.guildId);
455
+ const player = await this.manager.players.get(payload.guildId);
456
456
  if (!player)
457
457
  return;
458
- const track = player.queue.current;
458
+ const track = await player.queue.getCurrent();
459
459
  const type = payload.type;
460
460
  let error;
461
461
  switch (type) {
@@ -478,16 +478,16 @@ class Node {
478
478
  this.socketClosed(player, payload);
479
479
  break;
480
480
  case "SegmentsLoaded":
481
- this.sponsorBlockSegmentLoaded(player, player.queue.current, payload);
481
+ this.sponsorBlockSegmentLoaded(player, track, payload);
482
482
  break;
483
483
  case "SegmentSkipped":
484
- this.sponsorBlockSegmentSkipped(player, player.queue.current, payload);
484
+ this.sponsorBlockSegmentSkipped(player, track, payload);
485
485
  break;
486
486
  case "ChaptersLoaded":
487
- this.sponsorBlockChaptersLoaded(player, player.queue.current, payload);
487
+ this.sponsorBlockChaptersLoaded(player, track, payload);
488
488
  break;
489
489
  case "ChapterStarted":
490
- this.sponsorBlockChapterStarted(player, player.queue.current, payload);
490
+ this.sponsorBlockChapterStarted(player, track, payload);
491
491
  break;
492
492
  default:
493
493
  error = new Error(`Node#event unknown event '${type}'.`);
@@ -536,12 +536,14 @@ class Node {
536
536
  async trackEnd(player, track, payload) {
537
537
  const { reason } = payload;
538
538
  const skipFlag = player.get("skipFlag");
539
- if (!skipFlag && (player.queue.previous.length === 0 || (player.queue.previous[0] && player.queue.previous[0].track !== player.queue.current?.track))) {
539
+ const previous = await player.queue.getPrevious();
540
+ const current = await player.queue.getCurrent();
541
+ if (!skipFlag && (previous.length === 0 || (previous[0] && previous[0].track !== current?.track))) {
540
542
  // Store the current track in the previous tracks queue
541
- player.queue.previous.push(player.queue.current);
543
+ await player.queue.addPrevious(await player.queue.getCurrent());
542
544
  // Limit the previous tracks queue to maxPreviousTracks
543
- if (player.queue.previous.length > this.manager.options.maxPreviousTracks) {
544
- player.queue.previous.shift();
545
+ if ((await player.queue.getPrevious()).length > this.manager.options.maxPreviousTracks) {
546
+ (await player.queue.getPrevious()).shift();
545
547
  }
546
548
  }
547
549
  const oldPlayer = player;
@@ -557,7 +559,7 @@ class Node {
557
559
  break;
558
560
  case Utils_1.TrackEndReasonTypes.Stopped:
559
561
  // If the track was forcibly replaced
560
- if (player.queue.length) {
562
+ if (await player.queue.size()) {
561
563
  await this.playNextTrack(player, track, payload);
562
564
  }
563
565
  else {
@@ -571,7 +573,7 @@ class Node {
571
573
  break;
572
574
  }
573
575
  // If there's another track in the queue
574
- if (player.queue.length) {
576
+ if (await player.queue.size()) {
575
577
  await this.playNextTrack(player, track, payload);
576
578
  }
577
579
  else {
@@ -602,200 +604,23 @@ class Node {
602
604
  */
603
605
  async handleAutoplay(player, attempt = 0) {
604
606
  // If autoplay is not enabled or all attempts have failed, early exit
605
- if (!player.isAutoplay || attempt === player.autoplayTries || !player.queue.previous.length)
607
+ if (!player.isAutoplay || attempt > player.autoplayTries || !(await player.queue.getPrevious()).length)
606
608
  return false;
607
- const lastTrack = player.queue.previous[player.queue.previous.length - 1];
609
+ const PreviousQueue = await player.queue.getPrevious();
610
+ const lastTrack = PreviousQueue?.at(-1);
608
611
  lastTrack.requester = player.get("Internal_BotUser");
609
- const tracks = await Utils_1.AutoPlayUtils.getRecommendedTracks(player, lastTrack, attempt);
612
+ if (!lastTrack)
613
+ return false;
614
+ const tracks = await Utils_1.AutoPlayUtils.getRecommendedTracks(lastTrack);
610
615
  if (tracks.length) {
611
- player.queue.add(tracks[0]);
616
+ await player.queue.add(tracks[0]);
612
617
  await player.play();
613
618
  return true;
614
619
  }
615
620
  else {
616
621
  return false;
617
622
  }
618
- // // Determine if YouTube should be used
619
- // // If Last.fm is not available, use YouTube as a fallback
620
- // // If YouTube is available and this is the last attempt, use YouTube
621
- // const shouldUseYouTube =
622
- // (!apiKey && enabledSources.includes("youtube")) || // Fallback to YouTube if Last.fm is not available
623
- // (attempt === player.autoplayTries - 1 && player.autoplayTries > 1 && enabledSources.includes("youtube")); // Use YouTube on the last attempt
624
- // if (shouldUseYouTube) {
625
- // // Use YouTube-based autoplay
626
- // return await this.handleYouTubeAutoplay(player, lastTrack);
627
- // }
628
- // // Handle Last.fm-based autoplay (or other platforms)
629
- // const selectedSource = this.selectPlatform(enabledSources);
630
- // if (selectedSource) {
631
- // // Use the selected source to handle autoplay
632
- // return await this.handlePlatformAutoplay(player, lastTrack, selectedSource, apiKey);
633
- // }
634
- // // If no source is available, return false
635
- // return false;
636
- return false;
637
623
  }
638
- // return response.data.similartracks.track.filter((t: { uri: string }) => t.uri !== track.uri);
639
- // /**
640
- // * Selects a platform from the given enabled sources.
641
- // * @param {string[]} enabledSources - The enabled sources to select from.
642
- // * @returns {SearchPlatform | null} - The selected platform or null if none was found.
643
- // */
644
- // public selectPlatform(enabledSources: string[]): SearchPlatform | null {
645
- // const { autoPlaySearchPlatform } = this.manager.options;
646
- // const platformMapping: { [key in SearchPlatform]: string } = {
647
- // [SearchPlatform.AppleMusic]: "applemusic",
648
- // [SearchPlatform.Bandcamp]: "bandcamp",
649
- // [SearchPlatform.Deezer]: "deezer",
650
- // [SearchPlatform.Jiosaavn]: "jiosaavn",
651
- // [SearchPlatform.SoundCloud]: "soundcloud",
652
- // [SearchPlatform.Spotify]: "spotify",
653
- // [SearchPlatform.Tidal]: "tidal",
654
- // [SearchPlatform.VKMusic]: "vkmusic",
655
- // [SearchPlatform.YouTube]: "youtube",
656
- // [SearchPlatform.YouTubeMusic]: "youtube",
657
- // };
658
- // // Try the autoPlaySearchPlatform first
659
- // if (enabledSources.includes(platformMapping[autoPlaySearchPlatform])) {
660
- // return autoPlaySearchPlatform;
661
- // }
662
- // // Fallback to other platforms in a predefined order
663
- // const fallbackPlatforms = [
664
- // SearchPlatform.Spotify,
665
- // SearchPlatform.Deezer,
666
- // SearchPlatform.SoundCloud,
667
- // SearchPlatform.AppleMusic,
668
- // SearchPlatform.Bandcamp,
669
- // SearchPlatform.Jiosaavn,
670
- // SearchPlatform.Tidal,
671
- // SearchPlatform.VKMusic,
672
- // SearchPlatform.YouTubeMusic,
673
- // SearchPlatform.YouTube,
674
- // ];
675
- // for (const platform of fallbackPlatforms) {
676
- // if (enabledSources.includes(platformMapping[platform])) {
677
- // return platform;
678
- // }
679
- // }
680
- // return null;
681
- // }
682
- // /**
683
- // * Handles Last.fm-based autoplay.
684
- // * @param {Player} player - The player instance.
685
- // * @param {Track} previousTrack - The previous track.
686
- // * @param {SearchPlatform} platform - The selected platform.
687
- // * @param {string} apiKey - The Last.fm API key.
688
- // * @returns {Promise<boolean>} - Whether the autoplay was successful.
689
- // */
690
- // private async handlePlatformAutoplay(player: Player, previousTrack: Track, platform: SearchPlatform, apiKey: string): Promise<boolean> {
691
- // let { author: artist } = previousTrack;
692
- // const { title } = previousTrack;
693
- // if (!artist || !title) {
694
- // if (!title) {
695
- // // No title provided, search for the artist's top tracks
696
- // const noTitleUrl = `https://ws.audioscrobbler.com/2.0/?method=artist.getTopTracks&artist=${artist}&autocorrect=1&api_key=${apiKey}&format=json`;
697
- // const response = await axios.get(noTitleUrl);
698
- // if (response.data.error || !response.data.toptracks?.track?.length) return false;
699
- // const randomTrack = response.data.toptracks.track[Math.floor(Math.random() * response.data.toptracks.track.length)];
700
- // const res = await player.search(
701
- // { query: `${randomTrack.artist.name} - ${randomTrack.name}`, source: platform },
702
- // player.get("Internal_BotUser") as User | ClientUser
703
- // );
704
- // if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) return false;
705
- // const foundTrack = res.tracks.find((t) => t.uri !== previousTrack.uri);
706
- // if (!foundTrack) return false;
707
- // player.queue.add(foundTrack);
708
- // await player.play();
709
- // return true;
710
- // }
711
- // if (!artist) {
712
- // // No artist provided, search for the track title
713
- // const noArtistUrl = `https://ws.audioscrobbler.com/2.0/?method=track.search&track=${title}&api_key=${apiKey}&format=json`;
714
- // const response = await axios.get(noArtistUrl);
715
- // artist = response.data.results.trackmatches?.track?.[0]?.artist;
716
- // if (!artist) return false;
717
- // }
718
- // }
719
- // // Search for similar tracks to the current track
720
- // const url = `https://ws.audioscrobbler.com/2.0/?method=track.getSimilar&artist=${artist}&track=${title}&limit=10&autocorrect=1&api_key=${apiKey}&format=json`;
721
- // let response: axios.AxiosResponse;
722
- // try {
723
- // response = await axios.get(url);
724
- // } catch (error) {
725
- // if (error) return false;
726
- // }
727
- // if (response.data.error || !response.data.similartracks?.track?.length) {
728
- // // Retry the request if the first attempt fails
729
- // const retryUrl = `https://ws.audioscrobbler.com/2.0/?method=artist.getTopTracks&artist=${artist}&autocorrect=1&api_key=${apiKey}&format=json`;
730
- // const retryResponse = await axios.get(retryUrl);
731
- // if (retryResponse.data.error || !retryResponse.data.toptracks?.track?.length) return false;
732
- // const randomTrack = retryResponse.data.toptracks.track[Math.floor(Math.random() * retryResponse.data.toptracks.track.length)];
733
- // const res = await player.search(
734
- // { query: `${randomTrack.artist.name} - ${randomTrack.name}`, source: platform },
735
- // player.get("Internal_BotUser") as User | ClientUser
736
- // );
737
- // if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) return false;
738
- // const foundTrack = res.tracks.find((t) => t.uri !== previousTrack.uri);
739
- // if (!foundTrack) return false;
740
- // player.queue.add(foundTrack);
741
- // await player.play();
742
- // return true;
743
- // }
744
- // const randomTrack = response.data.similartracks.track[Math.floor(Math.random() * response.data.similartracks.track.length)];
745
- // const res = await player.search(
746
- // { query: `${randomTrack.artist.name} - ${randomTrack.name}`, source: platform },
747
- // player.get("Internal_BotUser") as User | ClientUser
748
- // );
749
- // if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) return false;
750
- // const foundTrack = res.tracks.find((t) => t.uri !== previousTrack.uri);
751
- // if (!foundTrack) return false;
752
- // player.queue.add(foundTrack);
753
- // await player.play();
754
- // return true;
755
- // }
756
- // /**
757
- // * Handles YouTube-based autoplay.
758
- // * @param {Player} player - The player instance.
759
- // * @param {Track} previousTrack - The previous track.
760
- // * @returns {Promise<boolean>} - Whether the autoplay was successful.
761
- // */
762
- // private async handleYouTubeAutoplay(player: Player, previousTrack: Track): Promise<boolean> {
763
- // // Check if the previous track has a YouTube URL
764
- // const hasYouTubeURL = ["youtube.com", "youtu.be"].some((url) => previousTrack.uri.includes(url));
765
- // // Get the video ID from the previous track's URL
766
- // const videoID = hasYouTubeURL
767
- // ? previousTrack.uri.split("=").pop()
768
- // : (
769
- // await this.manager.search(
770
- // { query: `${previousTrack.author} - ${previousTrack.title}`, source: SearchPlatform.YouTube },
771
- // player.get("Internal_BotUser") as User | ClientUser
772
- // )
773
- // ).tracks[0]?.uri
774
- // .split("=")
775
- // .pop();
776
- // // If the video ID is not found, return false
777
- // if (!videoID) return false;
778
- // // Get a random video index between 2 and 24
779
- // let randomIndex: number;
780
- // let searchURI: string;
781
- // do {
782
- // // Generate a random index between 2 and 24
783
- // randomIndex = Math.floor(Math.random() * 23) + 2;
784
- // // Build the search URI
785
- // searchURI = `https://www.youtube.com/watch?v=${videoID}&list=RD${videoID}&index=${randomIndex}`;
786
- // } while (previousTrack.uri.includes(searchURI));
787
- // // Search for the video and return false if the search fails
788
- // const res = await this.manager.search({ query: searchURI, source: SearchPlatform.YouTube }, player.get("Internal_BotUser") as User | ClientUser);
789
- // if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) return false;
790
- // // Find a track that is not the same as the current track
791
- // const foundTrack = res.tracks.find((t) => t.uri !== previousTrack.uri && t.author !== previousTrack.author && t.title !== previousTrack.title);
792
- // // If no track is found, return false
793
- // if (!foundTrack) return false;
794
- // // Add the found track to the queue and play it
795
- // player.queue.add(foundTrack);
796
- // await player.play();
797
- // return true;
798
- // }
799
624
  /**
800
625
  * Handles the scenario when a track fails to play or load.
801
626
  * Shifts the queue to the next track and emits a track end event.
@@ -809,13 +634,13 @@ class Node {
809
634
  * @private
810
635
  */
811
636
  async handleFailedTrack(player, track, payload) {
812
- player.queue.current = player.queue.shift();
813
- if (!player.queue.current) {
637
+ await player.queue.setCurrent(await player.queue.dequeue());
638
+ if (!(await player.queue.getCurrent())) {
814
639
  await this.queueEnd(player, track, payload);
815
640
  return;
816
641
  }
817
642
  this.manager.emit(Manager_1.ManagerEventTypes.TrackEnd, player, track, payload);
818
- if (this.manager.options.autoPlay)
643
+ if (this.manager.options.playNextOnEnd)
819
644
  await player.play();
820
645
  }
821
646
  /**
@@ -832,30 +657,34 @@ class Node {
832
657
  */
833
658
  async handleRepeatedTrack(player, track, payload) {
834
659
  const { queue, trackRepeat, queueRepeat } = player;
835
- const { autoPlay } = this.manager.options;
660
+ const { playNextOnEnd } = this.manager.options;
836
661
  if (trackRepeat) {
837
662
  // Prevent duplicate repeat insertion
838
- if (queue[0] !== queue.current) {
839
- queue.unshift(queue.current);
663
+ if (queue[0] !== (await queue.getCurrent())) {
664
+ await queue.enqueueFront(await queue.getCurrent());
840
665
  }
841
666
  }
842
667
  else if (queueRepeat) {
843
668
  // Prevent duplicate queue insertion
844
- if (queue[queue.length - 1] !== queue.current) {
845
- queue.add(queue.current);
669
+ if (queue[(await queue.size()) - 1] !== (await queue.getCurrent())) {
670
+ await queue.add(await queue.getCurrent());
846
671
  }
847
672
  }
848
673
  // Move to the next track
849
- queue.current = queue.shift();
674
+ await queue.setCurrent(await queue.dequeue());
850
675
  // Emit track end event
851
676
  this.manager.emit(Manager_1.ManagerEventTypes.TrackEnd, player, track, payload);
852
677
  // If the track was stopped manually and no more tracks exist, end the queue
853
- if (payload.reason === Utils_1.TrackEndReasonTypes.Stopped && !(queue.current = queue.shift())) {
854
- await this.queueEnd(player, track, payload);
855
- return;
678
+ if (payload.reason === Utils_1.TrackEndReasonTypes.Stopped) {
679
+ const next = await queue.dequeue();
680
+ await queue.setCurrent(next ?? null);
681
+ if (!next) {
682
+ await this.queueEnd(player, track, payload);
683
+ return;
684
+ }
856
685
  }
857
686
  // If autoplay is enabled, play the next track
858
- if (autoPlay)
687
+ if (playNextOnEnd)
859
688
  await player.play();
860
689
  }
861
690
  /**
@@ -871,11 +700,11 @@ class Node {
871
700
  */
872
701
  async playNextTrack(player, track, payload) {
873
702
  // Shift the queue to set the next track as current
874
- player.queue.current = player.queue.shift();
703
+ await player.queue.setCurrent(await player.queue.dequeue());
875
704
  // Emit the track end event
876
705
  this.manager.emit(Manager_1.ManagerEventTypes.TrackEnd, player, track, payload);
877
706
  // If autoplay is enabled, play the next track
878
- if (this.manager.options.autoPlay)
707
+ if (this.manager.options.playNextOnEnd)
879
708
  await player.play();
880
709
  }
881
710
  /**
@@ -888,19 +717,19 @@ class Node {
888
717
  * @returns {Promise<void>} A promise that resolves when the queue end processing is complete.
889
718
  */
890
719
  async queueEnd(player, track, payload) {
891
- player.queue.current = null;
720
+ await player.queue.setCurrent(null);
892
721
  if (!player.isAutoplay) {
893
722
  player.playing = false;
894
723
  this.manager.emit(Manager_1.ManagerEventTypes.QueueEnd, player, track, payload);
895
724
  return;
896
725
  }
897
- let attempts = 1;
726
+ let attempt = 1;
898
727
  let success = false;
899
- while (attempts <= player.autoplayTries) {
900
- success = await this.handleAutoplay(player, attempts);
728
+ while (attempt <= player.autoplayTries) {
729
+ success = await this.handleAutoplay(player, attempt);
901
730
  if (success)
902
731
  return;
903
- attempts++;
732
+ attempt++;
904
733
  }
905
734
  // If all attempts fail, reset the player state and emit queueEnd
906
735
  player.playing = false;