magmastream 2.9.0-dev.1 → 2.9.0-dev.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.
@@ -9,6 +9,7 @@ const Queue_1 = require("./Queue");
9
9
  const Utils_1 = require("./Utils");
10
10
  const _ = tslib_1.__importStar(require("lodash"));
11
11
  const playerCheck_1 = tslib_1.__importDefault(require("../utils/playerCheck"));
12
+ const RedisQueue_1 = require("./RedisQueue");
12
13
  class Player {
13
14
  options;
14
15
  /** The Queue for the Player. */
@@ -50,7 +51,7 @@ class Player {
50
51
  /** The autoplay state of the player. */
51
52
  isAutoplay = false;
52
53
  /** The number of times to try autoplay before emitting queueEnd. */
53
- autoplayTries = null;
54
+ autoplayTries = 3;
54
55
  static _manager;
55
56
  data = {};
56
57
  dynamicLoopInterval = null;
@@ -67,10 +68,6 @@ class Player {
67
68
  this.manager = Utils_1.Structure.get("Player")._manager;
68
69
  if (!this.manager)
69
70
  throw new RangeError("Manager has not been initiated.");
70
- // If a player with the same guild ID already exists, return it.
71
- if (this.manager.players.has(options.guildId)) {
72
- return this.manager.players.get(options.guildId);
73
- }
74
71
  // Check the player options for errors.
75
72
  (0, playerCheck_1.default)(options);
76
73
  // Set the guild ID and voice state.
@@ -91,8 +88,15 @@ class Player {
91
88
  if (!this.node)
92
89
  throw new RangeError("No available nodes.");
93
90
  // Initialize the queue with the guild ID and manager.
94
- this.queue = new Queue_1.Queue(this.guildId, this.manager);
95
- this.queue.previous = new Array();
91
+ if (this.manager.options.stateStorage.type === Manager_1.StateStorageType.Redis) {
92
+ this.queue = new RedisQueue_1.RedisQueue(this.guildId, this.manager);
93
+ }
94
+ else {
95
+ this.queue = new Queue_1.Queue(this.guildId, this.manager);
96
+ }
97
+ if (this.queue instanceof Queue_1.Queue) {
98
+ this.queue.previous = [];
99
+ }
96
100
  // Add the player to the manager's player collection.
97
101
  this.manager.players.set(options.guildId, this);
98
102
  // Set the initial volume.
@@ -225,7 +229,7 @@ class Player {
225
229
  await this.disconnect();
226
230
  }
227
231
  await this.node.rest.destroyPlayer(this.guildId);
228
- this.queue.clear();
232
+ await this.queue.clear();
229
233
  this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, null, {
230
234
  changeType: Manager_1.PlayerStateEventTypes.PlayerDestroy,
231
235
  });
@@ -307,9 +311,9 @@ class Player {
307
311
  }
308
312
  async play(optionsOrTrack, playOptions) {
309
313
  if (typeof optionsOrTrack !== "undefined" && Utils_1.TrackUtils.validate(optionsOrTrack)) {
310
- this.queue.current = optionsOrTrack;
314
+ await this.queue.setCurrent(optionsOrTrack);
311
315
  }
312
- if (!this.queue.current)
316
+ if (!(await this.queue.getCurrent()))
313
317
  throw new RangeError("No current track.");
314
318
  const finalOptions = playOptions
315
319
  ? playOptions
@@ -319,7 +323,7 @@ class Player {
319
323
  await this.node.rest.updatePlayer({
320
324
  guildId: this.guildId,
321
325
  data: {
322
- encodedTrack: this.queue.current?.track,
326
+ encodedTrack: (await this.queue.getCurrent()).track,
323
327
  ...finalOptions,
324
328
  },
325
329
  });
@@ -375,7 +379,7 @@ class Player {
375
379
  * @returns {Promise<Track[]>} - Array of recommended tracks.
376
380
  */
377
381
  async getRecommendedTracks(track) {
378
- const tracks = await Utils_1.AutoPlayUtils.getRecommendedTracks(this, track);
382
+ const tracks = await Utils_1.AutoPlayUtils.getRecommendedTracks(track);
379
383
  return tracks;
380
384
  }
381
385
  /**
@@ -509,13 +513,13 @@ class Player {
509
513
  * @throws {TypeError} If the repeat parameter is not a boolean.
510
514
  * @throws {RangeError} If the queue size is less than or equal to 1.
511
515
  */
512
- setDynamicRepeat(repeat, ms) {
516
+ async setDynamicRepeat(repeat, ms) {
513
517
  // Validate the repeat parameter
514
518
  if (typeof repeat !== "boolean") {
515
519
  throw new TypeError('Repeat can only be "true" or "false".');
516
520
  }
517
521
  // Ensure the queue has more than one track for dynamic repeat
518
- if (this.queue.size <= 1) {
522
+ if ((await this.queue.size()) <= 1) {
519
523
  throw new RangeError("The queue size must be greater than 1.");
520
524
  }
521
525
  // Clone the current player state for comparison
@@ -526,15 +530,14 @@ class Player {
526
530
  this.queueRepeat = false;
527
531
  this.dynamicRepeat = true;
528
532
  // Set an interval to shuffle the queue periodically
529
- this.dynamicLoopInterval = setInterval(() => {
533
+ this.dynamicLoopInterval = setInterval(async () => {
530
534
  if (!this.dynamicRepeat)
531
535
  return;
532
536
  // Shuffle the queue and replace it with the shuffled tracks
533
- const shuffled = _.shuffle(this.queue);
534
- this.queue.clear();
535
- shuffled.forEach((track) => {
536
- this.queue.add(track);
537
- });
537
+ const tracks = await this.queue.getTracks();
538
+ const shuffled = _.shuffle(tracks);
539
+ await this.queue.clear();
540
+ await this.queue.add(shuffled);
538
541
  }, ms);
539
542
  // Store the ms value
540
543
  this.dynamicRepeatIntervalMs = ms;
@@ -565,9 +568,9 @@ class Player {
565
568
  */
566
569
  async restart() {
567
570
  // Check if there is a current track in the queue
568
- if (!this.queue.current?.track) {
571
+ if (!(await this.queue.getCurrent())?.track) {
569
572
  // If the queue has tracks, play the next one
570
- if (this.queue.length)
573
+ if (await this.queue.size())
571
574
  await this.play();
572
575
  return this;
573
576
  }
@@ -576,7 +579,7 @@ class Player {
576
579
  guildId: this.guildId,
577
580
  data: {
578
581
  position: 0,
579
- encodedTrack: this.queue.current?.track,
582
+ encodedTrack: (await this.queue.getCurrent())?.track,
580
583
  },
581
584
  });
582
585
  return this;
@@ -591,10 +594,10 @@ class Player {
591
594
  const oldPlayer = { ...this };
592
595
  let removedTracks = [];
593
596
  if (typeof amount === "number" && amount > 1) {
594
- if (amount > this.queue.length)
597
+ if (amount > (await this.queue.size()))
595
598
  throw new RangeError("Cannot skip more than the queue length.");
596
- removedTracks = this.queue.slice(0, amount - 1);
597
- this.queue.splice(0, amount - 1);
599
+ removedTracks = await this.queue.getSlice(0, amount - 1);
600
+ await this.queue.modifyAt(0, amount - 1);
598
601
  }
599
602
  this.node.rest.updatePlayer({
600
603
  guildId: this.guildId,
@@ -654,7 +657,7 @@ class Player {
654
657
  */
655
658
  async previous() {
656
659
  // Check if there are previous tracks in the queue.
657
- if (!this.queue.previous.length) {
660
+ if (!(await this.queue.getPrevious()).length) {
658
661
  throw new Error("No previous track available.");
659
662
  }
660
663
  // Capture the current state of the player before making changes.
@@ -662,7 +665,7 @@ class Player {
662
665
  // Store the current track before changing it.
663
666
  // let currentTrackBeforeChange: Track | null = this.queue.current ? (this.queue.current as Track) : null;
664
667
  // Get the last played track and remove it from the history
665
- const lastTrack = this.queue.previous.pop();
668
+ const lastTrack = (await this.queue.getPrevious()).pop();
666
669
  // Set the skip flag to true to prevent the onTrackEnd event from playing the next track.
667
670
  this.set("skipFlag", true);
668
671
  await this.play(lastTrack);
@@ -688,7 +691,7 @@ class Player {
688
691
  * @emits {PlayerStateUpdate} - With {@link PlayerStateEventTypes.TrackChange} as the change type.
689
692
  */
690
693
  async seek(position) {
691
- if (!this.queue.current)
694
+ if (!(await this.queue.getCurrent()))
692
695
  return undefined;
693
696
  position = Number(position);
694
697
  // Check if the position is valid.
@@ -698,8 +701,8 @@ class Player {
698
701
  // Get the old player state.
699
702
  const oldPlayer = this ? { ...this } : null;
700
703
  // Clamp the position to ensure it is within the valid range.
701
- if (position < 0 || position > this.queue.current.duration) {
702
- position = Math.max(Math.min(position, this.queue.current.duration), 0);
704
+ if (position < 0 || position > (await this.queue.getCurrent()).duration) {
705
+ position = Math.max(Math.min(position, (await this.queue.getCurrent()).duration), 0);
703
706
  }
704
707
  // Update the player's position.
705
708
  this.position = position;
@@ -764,7 +767,7 @@ class Player {
764
767
  try {
765
768
  const playerPosition = this.position;
766
769
  const { sessionId, event: { token, endpoint }, } = this.voiceState;
767
- const currentTrack = this.queue.current ? this.queue.current : null;
770
+ const currentTrack = (await this.queue.getCurrent()) ? await this.queue.getCurrent() : null;
768
771
  await this.node.rest.destroyPlayer(this.guildId).catch(() => { });
769
772
  this.manager.players.delete(this.guildId);
770
773
  this.node = node;
@@ -795,7 +798,7 @@ class Player {
795
798
  if (!newOptions.textChannelId)
796
799
  throw new Error("Text channel ID is required");
797
800
  // Check if a player already exists for the new guild
798
- let newPlayer = this.manager.players.get(newOptions.guildId);
801
+ let newPlayer = await this.manager.getPlayer(newOptions.guildId);
799
802
  // If the player already exists and force is false, return the existing player
800
803
  if (newPlayer && !force)
801
804
  return newPlayer;
@@ -806,9 +809,9 @@ class Player {
806
809
  volume: this.volume,
807
810
  position: this.position,
808
811
  queue: {
809
- current: this.queue.current,
810
- tracks: [...this.queue],
811
- previous: [...this.queue.previous],
812
+ current: await this.queue.getCurrent(),
813
+ tracks: [...(await this.queue.getTracks())],
814
+ previous: [...(await this.queue.getPrevious())],
812
815
  },
813
816
  trackRepeat: this.trackRepeat,
814
817
  queueRepeat: this.queueRepeat,
@@ -828,7 +831,7 @@ class Player {
828
831
  newOptions.selfMute = newOptions.selfMute ?? oldPlayerProperties.selfMute;
829
832
  newOptions.volume = newOptions.volume ?? oldPlayerProperties.volume;
830
833
  // Deep clone the current player
831
- const clonedPlayer = this.manager.create(newOptions);
834
+ const clonedPlayer = await this.manager.create(newOptions);
832
835
  // Connect the cloned player to the new voice channel
833
836
  clonedPlayer.connect();
834
837
  // Update the player's state on the Lavalink node
@@ -841,9 +844,9 @@ class Player {
841
844
  encodedTrack: oldPlayerProperties.queue.current?.track,
842
845
  },
843
846
  });
844
- clonedPlayer.queue.current = oldPlayerProperties.queue.current;
845
- clonedPlayer.queue.previous = oldPlayerProperties.queue.previous;
846
- clonedPlayer.queue.add(oldPlayerProperties.queue.tracks);
847
+ await clonedPlayer.queue.setCurrent(oldPlayerProperties.queue.current);
848
+ await clonedPlayer.queue.addPrevious(oldPlayerProperties.queue.previous);
849
+ await clonedPlayer.queue.add(oldPlayerProperties.queue.tracks);
847
850
  clonedPlayer.filters = oldPlayerProperties.filters;
848
851
  clonedPlayer.isAutoplay = oldPlayerProperties.isAutoplay;
849
852
  clonedPlayer.nowPlayingMessage = oldPlayerProperties.nowPlayingMessage;
@@ -858,7 +861,7 @@ class Player {
858
861
  // Debug information
859
862
  const debugInfo = {
860
863
  success: true,
861
- message: `Transferred ${clonedPlayer.queue.length} tracks successfully to <#${newOptions.voiceChannelId}> bound to <#${newOptions.textChannelId}>.`,
864
+ message: `Transferred ${await clonedPlayer.queue.size()} tracks successfully to <#${newOptions.voiceChannelId}> bound to <#${newOptions.textChannelId}>.`,
862
865
  player: {
863
866
  guildId: clonedPlayer.guildId,
864
867
  voiceChannelId: clonedPlayer.voiceChannelId,
@@ -885,7 +888,7 @@ class Player {
885
888
  throw new RangeError(`There is no lavalyrics-plugin available in the Lavalink node: ${this.node.options.identifier}`);
886
889
  }
887
890
  // Fetch the lyrics for the current track from the Lavalink node
888
- let result = (await this.node.getLyrics(this.queue.current, skipTrackSource));
891
+ let result = (await this.node.getLyrics(await this.queue.getCurrent(), skipTrackSource));
889
892
  // If no lyrics are found, return a default empty lyrics object
890
893
  if (!result) {
891
894
  result = {