lavalink-client 1.2.0 → 1.2.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/README.md CHANGED
@@ -111,9 +111,22 @@ Check out the [Documentation](https://lc4.gitbook.io/lavalink-client) for **Exam
111
111
  - `player.deleteSponsorBlock()` / `node.deleteSponsorBlock()`
112
112
  - That Plugin adds following **Events** to the **Manager**: `"SegmentsLoaded"`, `"SegmentSkipped"`, `"ChapterStarted"`, `"ChaptersLoaded"`
113
113
  - Example Bot show example in autoplayFunction how to "disable" / "enable" Autoplay with bot data variables.
114
- - Added `ManagerOptions#onlyEmitNewTracks`. If set to true, it won't emit "trackStart" Event, when track.loop is active, or the new current track == the previous (current) track.
114
+ - Added `ManagerOptions#emitNewSongsOnly`. If set to true, it won't emit "trackStart" Event, when track.loop is active, or the new current track == the previous (current) track.
115
115
  - Added `ManagerOptions#linksBlacklist` which allows user to specify an array of regExp / strings to match query strings (for links / words) and if a match happens it doesn't allow the request (blacklist)
116
116
  - Added `ManagerOptions#linksWhitelist` which allows user to specify an array of regExp / strings to match query strings (for links only) and if a match does NOT HAPPEN it doesn't allow the request (whitelist)
117
117
  - Added `ManagerOptions#linksAllowed` if set to false, it does not allow requests which are links
118
118
  - Moved `ManaagerOptions#debugOptions` to `ManaagerOptions#advancedOptions.debugOptions`
119
119
 
120
+ ### **Version 1.2.1**
121
+ - Adjusted `player.stopPlaying()`
122
+ - There are now following parameters. `stopPlaying(clearQueue:boolean = true, executeAutoplay:boolean = false)`.
123
+ - On Default it now clears the queue and stops playing. Also it does not execute Autoplay on default. IF you want the function to behave differently, you can use the 2 states for that.
124
+ - Fixed that it looped the current track if repeatmode === "track" / "queue". (it stops playing and loop stays)
125
+ - Implemented a `parseLavalinkConnUrl(connectionUrl:string)` Util Function.
126
+ - It allows you to parse Lavalink Connection Data of a Lavalink Connection Url.
127
+ Pattern: `lavalink://<nodeId>:<nodeAuthorization(Password)>@<NodeHost>:<NodePort>`
128
+ - Note that the nodeId and NodeAuthorization must be encoded via encodeURIComponents before you provide it into the function.
129
+ - The function will return the following: `{ id: string, authorization: string, host: string, port: number }`
130
+ - Example: `parseLavalinkConnUrl("lavalink://LavalinkNode_1:strong%23password1@localhost:2345")` will give you:
131
+ `{ id: "LavalinkNode_1", authorization: "strong#password1", host: "localhost", port: 2345 }`
132
+ - Note that the password "strong#password1" when encoded turns into "strong%23password1". For more information check the example bot
@@ -240,17 +240,17 @@ export declare class LavalinkNode {
240
240
  private error;
241
241
  private message;
242
242
  private handleEvent;
243
+ private trackStart;
244
+ private trackEnd;
245
+ private trackStuck;
246
+ private trackError;
247
+ private socketClosed;
243
248
  private SponsorBlockSegmentLoaded;
244
249
  private SponsorBlockSegmentkipped;
245
250
  private SponsorBlockChaptersLoaded;
246
251
  private SponsorBlockChapterStarted;
247
- private trackStart;
248
- private trackEnd;
249
252
  getSponsorBlock(player: Player): Promise<SponsorBlockSegment[]>;
250
253
  setSponsorBlock(player: Player, segments?: SponsorBlockSegment[]): Promise<void>;
251
254
  deleteSponsorBlock(player: Player): Promise<void>;
252
255
  private queueEnd;
253
- private trackStuck;
254
- private trackError;
255
- private socketClosed;
256
256
  }
@@ -566,6 +566,7 @@ class LavalinkNode {
566
566
  return;
567
567
  }
568
568
  }
569
+ // LAVALINK EVENT HANDLING UTIL FUNCTION
569
570
  async handleEvent(payload) {
570
571
  if (!payload.guildId)
571
572
  return;
@@ -606,18 +607,7 @@ class LavalinkNode {
606
607
  }
607
608
  return;
608
609
  }
609
- SponsorBlockSegmentLoaded(player, track, payload) {
610
- return this.NodeManager.LavalinkManager.emit("SegmentsLoaded", player, track, payload);
611
- }
612
- SponsorBlockSegmentkipped(player, track, payload) {
613
- return this.NodeManager.LavalinkManager.emit("SegmentSkipped", player, track, payload);
614
- }
615
- SponsorBlockChaptersLoaded(player, track, payload) {
616
- return this.NodeManager.LavalinkManager.emit("ChaptersLoaded", player, track, payload);
617
- }
618
- SponsorBlockChapterStarted(player, track, payload) {
619
- return this.NodeManager.LavalinkManager.emit("ChapterStarted", player, track, payload);
620
- }
610
+ // LAVALINK EVENT HANDLING FUNCTIONS
621
611
  trackStart(player, track, payload) {
622
612
  player.playing = true;
623
613
  player.paused = false;
@@ -628,7 +618,7 @@ class LavalinkNode {
628
618
  }
629
619
  async trackEnd(player, track, payload) {
630
620
  // If there are no songs in the queue
631
- if (!player.queue.tracks.length && player.repeatMode === "off")
621
+ if (!player.queue.tracks.length && (player.repeatMode === "off" || player.get("internal_stopPlaying")))
632
622
  return this.queueEnd(player, track, payload);
633
623
  // If a track was forcibly played
634
624
  if (payload.reason === "replaced")
@@ -661,6 +651,49 @@ class LavalinkNode {
661
651
  // play track if autoSkip is true
662
652
  return this.NodeManager.LavalinkManager.options.autoSkip && player.play({ noReplace: true });
663
653
  }
654
+ async trackStuck(player, track, payload) {
655
+ this.NodeManager.LavalinkManager.emit("trackStuck", player, track, payload);
656
+ // If there are no songs in the queue
657
+ if (!player.queue.tracks.length && (player.repeatMode === "off" || player.get("internal_stopPlaying")))
658
+ return this.queueEnd(player, track, payload);
659
+ // remove the current track, and enqueue the next one
660
+ await (0, Utils_1.queueTrackEnd)(player);
661
+ // if no track available, end queue
662
+ if (!player.queue.current)
663
+ return this.queueEnd(player, track, payload);
664
+ // play track if autoSkip is true
665
+ return (this.NodeManager.LavalinkManager.options.autoSkip && player.queue.current) && player.play({ noReplace: true });
666
+ }
667
+ async trackError(player, track, payload) {
668
+ this.NodeManager.LavalinkManager.emit("trackError", player, track, payload);
669
+ // If there are no songs in the queue
670
+ if (!player.queue.tracks.length && (player.repeatMode === "off" || player.get("internal_stopPlaying")))
671
+ return this.queueEnd(player, track, payload);
672
+ // remove the current track, and enqueue the next one
673
+ await (0, Utils_1.queueTrackEnd)(player);
674
+ // if no track available, end queue
675
+ if (!player.queue.current)
676
+ return this.queueEnd(player, track, payload);
677
+ // play track if autoSkip is true
678
+ return (this.NodeManager.LavalinkManager.options.autoSkip && player.queue.current) && player.play({ noReplace: true });
679
+ }
680
+ socketClosed(player, payload) {
681
+ return this.NodeManager.LavalinkManager.emit("playerSocketClosed", player, payload);
682
+ }
683
+ // SPONSOR BLOCK EVENT FUNCTIONS
684
+ SponsorBlockSegmentLoaded(player, track, payload) {
685
+ return this.NodeManager.LavalinkManager.emit("SegmentsLoaded", player, track, payload);
686
+ }
687
+ SponsorBlockSegmentkipped(player, track, payload) {
688
+ return this.NodeManager.LavalinkManager.emit("SegmentSkipped", player, track, payload);
689
+ }
690
+ SponsorBlockChaptersLoaded(player, track, payload) {
691
+ return this.NodeManager.LavalinkManager.emit("ChaptersLoaded", player, track, payload);
692
+ }
693
+ SponsorBlockChapterStarted(player, track, payload) {
694
+ return this.NodeManager.LavalinkManager.emit("ChapterStarted", player, track, payload);
695
+ }
696
+ // SPONSOR BLOCK EXECUTE FUNCTIONS
664
697
  async getSponsorBlock(player) {
665
698
  // no plugin enabled
666
699
  if (!this.info.plugins.find(v => v.name === "sponsorblock-plugin"))
@@ -697,11 +730,13 @@ class LavalinkNode {
697
730
  });
698
731
  return;
699
732
  }
733
+ // UTIL FOR QUEUE END
700
734
  async queueEnd(player, track, payload) {
701
735
  // add previous track to the queue!
702
736
  player.queue.current = null;
703
737
  player.playing = false;
704
- if (typeof this.NodeManager.LavalinkManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction === "function") {
738
+ player.set("internal_stopPlaying", undefined);
739
+ if (typeof this.NodeManager.LavalinkManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction === "function" && typeof player.get("internal_autoplayStopPlaying") === "undefined") {
705
740
  await this.NodeManager.LavalinkManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction(player, track);
706
741
  if (player.queue.tracks.length > 0)
707
742
  await (0, Utils_1.queueTrackEnd)(player);
@@ -711,6 +746,7 @@ class LavalinkNode {
711
746
  return player.play({ noReplace: true, paused: false });
712
747
  }
713
748
  }
749
+ player.set("internal_autoplayStopPlaying", undefined);
714
750
  player.queue.previous.unshift(track);
715
751
  if (payload?.reason !== "stopped") {
716
752
  await player.queue.utils.save();
@@ -730,31 +766,5 @@ class LavalinkNode {
730
766
  }
731
767
  return this.NodeManager.LavalinkManager.emit("queueEnd", player, track, payload);
732
768
  }
733
- async trackStuck(player, track, payload) {
734
- this.NodeManager.LavalinkManager.emit("trackStuck", player, track, payload);
735
- // If there are no songs in the queue
736
- if (!player.queue.tracks.length && player.repeatMode === "off")
737
- return;
738
- // remove the current track, and enqueue the next one
739
- await (0, Utils_1.queueTrackEnd)(player);
740
- // if no track available, end queue
741
- if (!player.queue.current)
742
- return this.queueEnd(player, track, payload);
743
- // play track if autoSkip is true
744
- return (this.NodeManager.LavalinkManager.options.autoSkip && player.queue.current) && player.play({ noReplace: true });
745
- }
746
- async trackError(player, track, payload) {
747
- this.NodeManager.LavalinkManager.emit("trackError", player, track, payload);
748
- // remove the current track, and enqueue the next one
749
- await (0, Utils_1.queueTrackEnd)(player);
750
- // if no track available, end queue
751
- if (!player.queue.current)
752
- return this.queueEnd(player, track, payload);
753
- // play track if autoSkip is true
754
- return (this.NodeManager.LavalinkManager.options.autoSkip && player.queue.current) && player.play({ noReplace: true });
755
- }
756
- socketClosed(player, payload) {
757
- return this.NodeManager.LavalinkManager.emit("playerSocketClosed", player, payload);
758
- }
759
769
  }
760
770
  exports.LavalinkNode = LavalinkNode;
@@ -185,7 +185,7 @@ export declare class Player {
185
185
  * Clears the queue and stops playing. Does not destroy the Player and not leave the channel
186
186
  * @returns
187
187
  */
188
- stopPlaying(): Promise<this>;
188
+ stopPlaying(clearQueue?: boolean, executeAutoplay?: boolean): Promise<this>;
189
189
  /**
190
190
  * Connects the Player to the Voice Channel
191
191
  * @returns
@@ -313,10 +313,16 @@ class Player {
313
313
  * Clears the queue and stops playing. Does not destroy the Player and not leave the channel
314
314
  * @returns
315
315
  */
316
- async stopPlaying() {
316
+ async stopPlaying(clearQueue = true, executeAutoplay = false) {
317
+ // use internal_stopPlaying on true, so that it doesn't utilize current loop states. on trackEnd event
318
+ this.set("internal_stopPlaying", true);
317
319
  // remove tracks from the queue
318
- if (this.queue.tracks.length)
320
+ if (this.queue.tracks.length && clearQueue === true)
319
321
  await this.queue.splice(0, this.queue.tracks.length);
322
+ if (executeAutoplay === false)
323
+ this.set("internal_autoplayStopPlaying", true);
324
+ else
325
+ this.set("internal_autoplayStopPlaying", undefined);
320
326
  const now = performance.now();
321
327
  // send to lavalink, that it should stop playing
322
328
  await this.node.updatePlayer({ guildId: this.guildId, playerOptions: { encodedTrack: null } });
@@ -51,6 +51,17 @@ export interface UnresolvedSearchResult {
51
51
  playlist: PlaylistInfo | null;
52
52
  tracks: UnresolvedTrack[];
53
53
  }
54
+ /**
55
+ * Parses Node Connection Url: "lavalink://<nodeId>:<nodeAuthorization(Password)>@<NodeHost>:<NodePort>"
56
+ * @param connectionUrl
57
+ * @returns
58
+ */
59
+ export declare function parseLavalinkConnUrl(connectionUrl: string): {
60
+ authorization: string;
61
+ id: string;
62
+ host: string;
63
+ port: number;
64
+ };
54
65
  export declare class ManagerUtils {
55
66
  LavalinkManager: LavalinkManager | null;
56
67
  constructor(LavalinkManager?: LavalinkManager);
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.queueTrackEnd = exports.MiniMap = exports.ManagerUtils = exports.NodeSymbol = exports.QueueSymbol = exports.UnresolvedTrackSymbol = exports.TrackSymbol = void 0;
4
- const types_1 = require("util/types");
3
+ exports.queueTrackEnd = exports.MiniMap = exports.ManagerUtils = exports.parseLavalinkConnUrl = exports.NodeSymbol = exports.QueueSymbol = exports.UnresolvedTrackSymbol = exports.TrackSymbol = void 0;
4
+ const node_url_1 = require("node:url");
5
+ const types_1 = require("node:util/types");
5
6
  const LavalinkManagerStatics_1 = require("./LavalinkManagerStatics");
6
7
  exports.TrackSymbol = Symbol("LC-Track");
7
8
  exports.UnresolvedTrackSymbol = Symbol("LC-Track-Unresolved");
@@ -9,6 +10,23 @@ exports.QueueSymbol = Symbol("LC-Queue");
9
10
  exports.NodeSymbol = Symbol("LC-Node");
10
11
  /** @hidden */
11
12
  const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
13
+ /**
14
+ * Parses Node Connection Url: "lavalink://<nodeId>:<nodeAuthorization(Password)>@<NodeHost>:<NodePort>"
15
+ * @param connectionUrl
16
+ * @returns
17
+ */
18
+ function parseLavalinkConnUrl(connectionUrl) {
19
+ if (!connectionUrl.startsWith("lavalink://"))
20
+ throw new Error(`ConnectionUrl (${connectionUrl}) must start with 'lavalink://'`);
21
+ const parsed = new node_url_1.URL(connectionUrl);
22
+ return {
23
+ authorization: parsed.password,
24
+ id: parsed.username,
25
+ host: parsed.hostname,
26
+ port: Number(parsed.port),
27
+ };
28
+ }
29
+ exports.parseLavalinkConnUrl = parseLavalinkConnUrl;
12
30
  class ManagerUtils {
13
31
  LavalinkManager = null;
14
32
  constructor(LavalinkManager) {
@@ -240,17 +240,17 @@ export declare class LavalinkNode {
240
240
  private error;
241
241
  private message;
242
242
  private handleEvent;
243
+ private trackStart;
244
+ private trackEnd;
245
+ private trackStuck;
246
+ private trackError;
247
+ private socketClosed;
243
248
  private SponsorBlockSegmentLoaded;
244
249
  private SponsorBlockSegmentkipped;
245
250
  private SponsorBlockChaptersLoaded;
246
251
  private SponsorBlockChapterStarted;
247
- private trackStart;
248
- private trackEnd;
249
252
  getSponsorBlock(player: Player): Promise<SponsorBlockSegment[]>;
250
253
  setSponsorBlock(player: Player, segments?: SponsorBlockSegment[]): Promise<void>;
251
254
  deleteSponsorBlock(player: Player): Promise<void>;
252
255
  private queueEnd;
253
- private trackStuck;
254
- private trackError;
255
- private socketClosed;
256
256
  }
@@ -562,6 +562,7 @@ export class LavalinkNode {
562
562
  return;
563
563
  }
564
564
  }
565
+ // LAVALINK EVENT HANDLING UTIL FUNCTION
565
566
  async handleEvent(payload) {
566
567
  if (!payload.guildId)
567
568
  return;
@@ -602,18 +603,7 @@ export class LavalinkNode {
602
603
  }
603
604
  return;
604
605
  }
605
- SponsorBlockSegmentLoaded(player, track, payload) {
606
- return this.NodeManager.LavalinkManager.emit("SegmentsLoaded", player, track, payload);
607
- }
608
- SponsorBlockSegmentkipped(player, track, payload) {
609
- return this.NodeManager.LavalinkManager.emit("SegmentSkipped", player, track, payload);
610
- }
611
- SponsorBlockChaptersLoaded(player, track, payload) {
612
- return this.NodeManager.LavalinkManager.emit("ChaptersLoaded", player, track, payload);
613
- }
614
- SponsorBlockChapterStarted(player, track, payload) {
615
- return this.NodeManager.LavalinkManager.emit("ChapterStarted", player, track, payload);
616
- }
606
+ // LAVALINK EVENT HANDLING FUNCTIONS
617
607
  trackStart(player, track, payload) {
618
608
  player.playing = true;
619
609
  player.paused = false;
@@ -624,7 +614,7 @@ export class LavalinkNode {
624
614
  }
625
615
  async trackEnd(player, track, payload) {
626
616
  // If there are no songs in the queue
627
- if (!player.queue.tracks.length && player.repeatMode === "off")
617
+ if (!player.queue.tracks.length && (player.repeatMode === "off" || player.get("internal_stopPlaying")))
628
618
  return this.queueEnd(player, track, payload);
629
619
  // If a track was forcibly played
630
620
  if (payload.reason === "replaced")
@@ -657,6 +647,49 @@ export class LavalinkNode {
657
647
  // play track if autoSkip is true
658
648
  return this.NodeManager.LavalinkManager.options.autoSkip && player.play({ noReplace: true });
659
649
  }
650
+ async trackStuck(player, track, payload) {
651
+ this.NodeManager.LavalinkManager.emit("trackStuck", player, track, payload);
652
+ // If there are no songs in the queue
653
+ if (!player.queue.tracks.length && (player.repeatMode === "off" || player.get("internal_stopPlaying")))
654
+ return this.queueEnd(player, track, payload);
655
+ // remove the current track, and enqueue the next one
656
+ await queueTrackEnd(player);
657
+ // if no track available, end queue
658
+ if (!player.queue.current)
659
+ return this.queueEnd(player, track, payload);
660
+ // play track if autoSkip is true
661
+ return (this.NodeManager.LavalinkManager.options.autoSkip && player.queue.current) && player.play({ noReplace: true });
662
+ }
663
+ async trackError(player, track, payload) {
664
+ this.NodeManager.LavalinkManager.emit("trackError", player, track, payload);
665
+ // If there are no songs in the queue
666
+ if (!player.queue.tracks.length && (player.repeatMode === "off" || player.get("internal_stopPlaying")))
667
+ return this.queueEnd(player, track, payload);
668
+ // remove the current track, and enqueue the next one
669
+ await queueTrackEnd(player);
670
+ // if no track available, end queue
671
+ if (!player.queue.current)
672
+ return this.queueEnd(player, track, payload);
673
+ // play track if autoSkip is true
674
+ return (this.NodeManager.LavalinkManager.options.autoSkip && player.queue.current) && player.play({ noReplace: true });
675
+ }
676
+ socketClosed(player, payload) {
677
+ return this.NodeManager.LavalinkManager.emit("playerSocketClosed", player, payload);
678
+ }
679
+ // SPONSOR BLOCK EVENT FUNCTIONS
680
+ SponsorBlockSegmentLoaded(player, track, payload) {
681
+ return this.NodeManager.LavalinkManager.emit("SegmentsLoaded", player, track, payload);
682
+ }
683
+ SponsorBlockSegmentkipped(player, track, payload) {
684
+ return this.NodeManager.LavalinkManager.emit("SegmentSkipped", player, track, payload);
685
+ }
686
+ SponsorBlockChaptersLoaded(player, track, payload) {
687
+ return this.NodeManager.LavalinkManager.emit("ChaptersLoaded", player, track, payload);
688
+ }
689
+ SponsorBlockChapterStarted(player, track, payload) {
690
+ return this.NodeManager.LavalinkManager.emit("ChapterStarted", player, track, payload);
691
+ }
692
+ // SPONSOR BLOCK EXECUTE FUNCTIONS
660
693
  async getSponsorBlock(player) {
661
694
  // no plugin enabled
662
695
  if (!this.info.plugins.find(v => v.name === "sponsorblock-plugin"))
@@ -693,11 +726,13 @@ export class LavalinkNode {
693
726
  });
694
727
  return;
695
728
  }
729
+ // UTIL FOR QUEUE END
696
730
  async queueEnd(player, track, payload) {
697
731
  // add previous track to the queue!
698
732
  player.queue.current = null;
699
733
  player.playing = false;
700
- if (typeof this.NodeManager.LavalinkManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction === "function") {
734
+ player.set("internal_stopPlaying", undefined);
735
+ if (typeof this.NodeManager.LavalinkManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction === "function" && typeof player.get("internal_autoplayStopPlaying") === "undefined") {
701
736
  await this.NodeManager.LavalinkManager.options?.playerOptions?.onEmptyQueue?.autoPlayFunction(player, track);
702
737
  if (player.queue.tracks.length > 0)
703
738
  await queueTrackEnd(player);
@@ -707,6 +742,7 @@ export class LavalinkNode {
707
742
  return player.play({ noReplace: true, paused: false });
708
743
  }
709
744
  }
745
+ player.set("internal_autoplayStopPlaying", undefined);
710
746
  player.queue.previous.unshift(track);
711
747
  if (payload?.reason !== "stopped") {
712
748
  await player.queue.utils.save();
@@ -726,30 +762,4 @@ export class LavalinkNode {
726
762
  }
727
763
  return this.NodeManager.LavalinkManager.emit("queueEnd", player, track, payload);
728
764
  }
729
- async trackStuck(player, track, payload) {
730
- this.NodeManager.LavalinkManager.emit("trackStuck", player, track, payload);
731
- // If there are no songs in the queue
732
- if (!player.queue.tracks.length && player.repeatMode === "off")
733
- return;
734
- // remove the current track, and enqueue the next one
735
- await queueTrackEnd(player);
736
- // if no track available, end queue
737
- if (!player.queue.current)
738
- return this.queueEnd(player, track, payload);
739
- // play track if autoSkip is true
740
- return (this.NodeManager.LavalinkManager.options.autoSkip && player.queue.current) && player.play({ noReplace: true });
741
- }
742
- async trackError(player, track, payload) {
743
- this.NodeManager.LavalinkManager.emit("trackError", player, track, payload);
744
- // remove the current track, and enqueue the next one
745
- await queueTrackEnd(player);
746
- // if no track available, end queue
747
- if (!player.queue.current)
748
- return this.queueEnd(player, track, payload);
749
- // play track if autoSkip is true
750
- return (this.NodeManager.LavalinkManager.options.autoSkip && player.queue.current) && player.play({ noReplace: true });
751
- }
752
- socketClosed(player, payload) {
753
- return this.NodeManager.LavalinkManager.emit("playerSocketClosed", player, payload);
754
- }
755
765
  }
@@ -185,7 +185,7 @@ export declare class Player {
185
185
  * Clears the queue and stops playing. Does not destroy the Player and not leave the channel
186
186
  * @returns
187
187
  */
188
- stopPlaying(): Promise<this>;
188
+ stopPlaying(clearQueue?: boolean, executeAutoplay?: boolean): Promise<this>;
189
189
  /**
190
190
  * Connects the Player to the Voice Channel
191
191
  * @returns
@@ -310,10 +310,16 @@ export class Player {
310
310
  * Clears the queue and stops playing. Does not destroy the Player and not leave the channel
311
311
  * @returns
312
312
  */
313
- async stopPlaying() {
313
+ async stopPlaying(clearQueue = true, executeAutoplay = false) {
314
+ // use internal_stopPlaying on true, so that it doesn't utilize current loop states. on trackEnd event
315
+ this.set("internal_stopPlaying", true);
314
316
  // remove tracks from the queue
315
- if (this.queue.tracks.length)
317
+ if (this.queue.tracks.length && clearQueue === true)
316
318
  await this.queue.splice(0, this.queue.tracks.length);
319
+ if (executeAutoplay === false)
320
+ this.set("internal_autoplayStopPlaying", true);
321
+ else
322
+ this.set("internal_autoplayStopPlaying", undefined);
317
323
  const now = performance.now();
318
324
  // send to lavalink, that it should stop playing
319
325
  await this.node.updatePlayer({ guildId: this.guildId, playerOptions: { encodedTrack: null } });
@@ -51,6 +51,17 @@ export interface UnresolvedSearchResult {
51
51
  playlist: PlaylistInfo | null;
52
52
  tracks: UnresolvedTrack[];
53
53
  }
54
+ /**
55
+ * Parses Node Connection Url: "lavalink://<nodeId>:<nodeAuthorization(Password)>@<NodeHost>:<NodePort>"
56
+ * @param connectionUrl
57
+ * @returns
58
+ */
59
+ export declare function parseLavalinkConnUrl(connectionUrl: string): {
60
+ authorization: string;
61
+ id: string;
62
+ host: string;
63
+ port: number;
64
+ };
54
65
  export declare class ManagerUtils {
55
66
  LavalinkManager: LavalinkManager | null;
56
67
  constructor(LavalinkManager?: LavalinkManager);
@@ -1,4 +1,5 @@
1
- import { isRegExp } from "util/types";
1
+ import { URL } from "node:url";
2
+ import { isRegExp } from "node:util/types";
2
3
  import { DefaultSources, LavalinkPlugins, SourceLinksRegexes } from "./LavalinkManagerStatics";
3
4
  export const TrackSymbol = Symbol("LC-Track");
4
5
  export const UnresolvedTrackSymbol = Symbol("LC-Track-Unresolved");
@@ -6,6 +7,22 @@ export const QueueSymbol = Symbol("LC-Queue");
6
7
  export const NodeSymbol = Symbol("LC-Node");
7
8
  /** @hidden */
8
9
  const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
10
+ /**
11
+ * Parses Node Connection Url: "lavalink://<nodeId>:<nodeAuthorization(Password)>@<NodeHost>:<NodePort>"
12
+ * @param connectionUrl
13
+ * @returns
14
+ */
15
+ export function parseLavalinkConnUrl(connectionUrl) {
16
+ if (!connectionUrl.startsWith("lavalink://"))
17
+ throw new Error(`ConnectionUrl (${connectionUrl}) must start with 'lavalink://'`);
18
+ const parsed = new URL(connectionUrl);
19
+ return {
20
+ authorization: parsed.password,
21
+ id: parsed.username,
22
+ host: parsed.hostname,
23
+ port: Number(parsed.port),
24
+ };
25
+ }
9
26
  export class ManagerUtils {
10
27
  LavalinkManager = null;
11
28
  constructor(LavalinkManager) {
@@ -240,17 +240,17 @@ export declare class LavalinkNode {
240
240
  private error;
241
241
  private message;
242
242
  private handleEvent;
243
+ private trackStart;
244
+ private trackEnd;
245
+ private trackStuck;
246
+ private trackError;
247
+ private socketClosed;
243
248
  private SponsorBlockSegmentLoaded;
244
249
  private SponsorBlockSegmentkipped;
245
250
  private SponsorBlockChaptersLoaded;
246
251
  private SponsorBlockChapterStarted;
247
- private trackStart;
248
- private trackEnd;
249
252
  getSponsorBlock(player: Player): Promise<SponsorBlockSegment[]>;
250
253
  setSponsorBlock(player: Player, segments?: SponsorBlockSegment[]): Promise<void>;
251
254
  deleteSponsorBlock(player: Player): Promise<void>;
252
255
  private queueEnd;
253
- private trackStuck;
254
- private trackError;
255
- private socketClosed;
256
256
  }
@@ -185,7 +185,7 @@ export declare class Player {
185
185
  * Clears the queue and stops playing. Does not destroy the Player and not leave the channel
186
186
  * @returns
187
187
  */
188
- stopPlaying(): Promise<this>;
188
+ stopPlaying(clearQueue?: boolean, executeAutoplay?: boolean): Promise<this>;
189
189
  /**
190
190
  * Connects the Player to the Voice Channel
191
191
  * @returns
@@ -51,6 +51,17 @@ export interface UnresolvedSearchResult {
51
51
  playlist: PlaylistInfo | null;
52
52
  tracks: UnresolvedTrack[];
53
53
  }
54
+ /**
55
+ * Parses Node Connection Url: "lavalink://<nodeId>:<nodeAuthorization(Password)>@<NodeHost>:<NodePort>"
56
+ * @param connectionUrl
57
+ * @returns
58
+ */
59
+ export declare function parseLavalinkConnUrl(connectionUrl: string): {
60
+ authorization: string;
61
+ id: string;
62
+ host: string;
63
+ port: number;
64
+ };
54
65
  export declare class ManagerUtils {
55
66
  LavalinkManager: LavalinkManager | null;
56
67
  constructor(LavalinkManager?: LavalinkManager);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lavalink-client",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "Easy, flexible and feature-rich lavalink@v4 Client. Both for Beginners and Proficients.",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",