magmastream 2.9.0-dev.23 → 2.9.0-dev.25

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.d.ts CHANGED
@@ -1528,6 +1528,7 @@ declare class Player {
1528
1528
  autoplayTries: number;
1529
1529
  private static _manager;
1530
1530
  private readonly data;
1531
+ private volumeFadeInProgress;
1531
1532
  private dynamicLoopInterval;
1532
1533
  dynamicRepeatIntervalMs: number | null;
1533
1534
  /**
@@ -1643,14 +1644,16 @@ declare class Player {
1643
1644
  /**
1644
1645
  * Sets the volume of the player.
1645
1646
  * @param {number} volume - The new volume. Must be between 0 and 1000.
1647
+ * @param {GradualOptions} options - The options to use for the gradual change.
1646
1648
  * @returns {Promise<Player>} - The updated player.
1647
1649
  * @throws {TypeError} If the volume is not a number.
1648
1650
  * @throws {RangeError} If the volume is not between 0 and 1000.
1649
1651
  * @emits {PlayerStateUpdate} - Emitted when the volume is changed.
1650
1652
  * @example
1651
1653
  * player.setVolume(50);
1654
+ * player.setVolume(50, { gradual: true, interval: 50, step: 5 });
1652
1655
  */
1653
- setVolume(volume: number): Promise<this>;
1656
+ setVolume(volume: number, options?: GradualOptions): Promise<this>;
1654
1657
  /**
1655
1658
  * Sets the sponsorblock for the player. This will set the sponsorblock segments for the player to the given segments.
1656
1659
  * @param {SponsorBlockSegment[]} segments - The sponsorblock segments to set. Defaults to `[SponsorBlockSegment.Sponsor, SponsorBlockSegment.SelfPromo]` if not provided.
@@ -1761,6 +1764,12 @@ declare class Player {
1761
1764
  * @throws {RangeError} - If the 'lavalyrics-plugin' is not available on the Lavalink node.
1762
1765
  */
1763
1766
  getCurrentLyrics(skipTrackSource?: boolean): Promise<Lyrics>;
1767
+ /**
1768
+ * Sleeps for a specified amount of time.
1769
+ * @param ms The amount of time to sleep in milliseconds.
1770
+ * @returns A promise that resolves after the specified amount of time.
1771
+ */
1772
+ private sleep;
1764
1773
  }
1765
1774
  interface PlayerOptions {
1766
1775
  /** The guild ID the Player belongs to. */
@@ -1778,6 +1787,14 @@ interface PlayerOptions {
1778
1787
  /** If the player should deaf itself. */
1779
1788
  selfDeafen?: boolean;
1780
1789
  }
1790
+ interface GradualOptions {
1791
+ /** If the change should be gradual. */
1792
+ gradual?: boolean;
1793
+ /** The duration of the gradual change. */
1794
+ interval?: number;
1795
+ /** The step of the gradual change. */
1796
+ step?: number;
1797
+ }
1781
1798
  /** If track partials are set some of these will be `undefined` as they were removed. */
1782
1799
  interface Track {
1783
1800
  /** The base64 encoded track. */
@@ -2260,4 +2277,4 @@ declare class Plugin {
2260
2277
  }
2261
2278
 
2262
2279
  export { AutoPlayPlatform, AutoPlayUtils, AvailableFilters, Filters, LoadTypes, Manager, ManagerEventTypes, Node, Player, PlayerStateEventTypes, Plugin, Queue, Rest, SearchPlatform, SeverityTypes, SponsorBlockSegment, StateStorageType, StateTypes, Structure, TrackEndReasonTypes, TrackPartial, TrackSourceTypes, TrackUtils, UseNodeOptions };
2263
- export type { CPUStats, EqualizerBand, Exception, Extendable, FrameStats, IQueue, LavalinkInfo, LavalinkResponse, LoadType, Lyrics, LyricsLine, ManagerEvents, ManagerOptions, MemoryStats, NodeMessage, NodeOptions, NodeStats, Payload, PlayOptions, PlayerEvent, PlayerEventType, PlayerEvents, PlayerOptions, PlayerStore, PlayerUpdate, PlaylistData, PlaylistInfoData, PlaylistRawData, RedisConfig, SearchQuery, SearchResult, Severity, Sizes, SponsorBlockChapterStarted, SponsorBlockChaptersLoaded, SponsorBlockSegmentEventType, SponsorBlockSegmentEvents, SponsorBlockSegmentSkipped, SponsorBlockSegmentsLoaded, State, StateStorageOptions, Track, TrackData, TrackDataInfo, TrackEndEvent, TrackEndReason, TrackExceptionEvent, TrackPluginInfo, TrackSourceName, TrackStartEvent, TrackStuckEvent, UseNodeOption, VoicePacket, VoiceServer, VoiceState, WebSocketClosedEvent };
2280
+ export type { CPUStats, EqualizerBand, Exception, Extendable, FrameStats, GradualOptions, IQueue, LavalinkInfo, LavalinkResponse, LoadType, Lyrics, LyricsLine, ManagerEvents, ManagerOptions, MemoryStats, NodeMessage, NodeOptions, NodeStats, Payload, PlayOptions, PlayerEvent, PlayerEventType, PlayerEvents, PlayerOptions, PlayerStore, PlayerUpdate, PlaylistData, PlaylistInfoData, PlaylistRawData, RedisConfig, SearchQuery, SearchResult, Severity, Sizes, SponsorBlockChapterStarted, SponsorBlockChaptersLoaded, SponsorBlockSegmentEventType, SponsorBlockSegmentEvents, SponsorBlockSegmentSkipped, SponsorBlockSegmentsLoaded, State, StateStorageOptions, Track, TrackData, TrackDataInfo, TrackEndEvent, TrackEndReason, TrackExceptionEvent, TrackPluginInfo, TrackSourceName, TrackStartEvent, TrackStuckEvent, UseNodeOption, VoicePacket, VoiceServer, VoiceState, WebSocketClosedEvent };
@@ -246,11 +246,11 @@ class Manager extends events_1.EventEmitter {
246
246
  * @returns A promise that resolves when the player has been destroyed.
247
247
  */
248
248
  async destroy(guildId) {
249
- // Emit debug message for player destruction
250
249
  this.emit(ManagerEventTypes.Debug, `[MANAGER] Destroying player: ${guildId}`);
251
- // Remove the player from the manager's collection
252
- this.players.delete(guildId);
253
- // Clean up any inactive players
250
+ const player = this.getPlayer(guildId);
251
+ if (!player)
252
+ return;
253
+ await player.destroy();
254
254
  await this.cleanupInactivePlayers();
255
255
  }
256
256
  /**
@@ -313,13 +313,6 @@ class Manager extends events_1.EventEmitter {
313
313
  }
314
314
  if (update.user_id !== this.options.clientId)
315
315
  return;
316
- const missingSessionButHasEvent = !player.voiceState.sessionId && player.voiceState.event;
317
- if (missingSessionButHasEvent) {
318
- if (player.state !== Utils_1.StateTypes.Destroying && player.state !== Utils_1.StateTypes.Disconnected) {
319
- await player.destroy();
320
- }
321
- return;
322
- }
323
316
  return await this.handleVoiceStateUpdate(player, update);
324
317
  }
325
318
  /**
@@ -54,6 +54,7 @@ class Player {
54
54
  autoplayTries = 3;
55
55
  static _manager;
56
56
  data = {};
57
+ volumeFadeInProgress = false;
57
58
  dynamicLoopInterval = null;
58
59
  dynamicRepeatIntervalMs = null;
59
60
  /**
@@ -224,10 +225,6 @@ class Player {
224
225
  */
225
226
  async destroy(disconnect = true) {
226
227
  const oldPlayer = this ? { ...this } : null;
227
- if (this.state === Utils_1.StateTypes.Destroying || this.state === Utils_1.StateTypes.Disconnected) {
228
- console.debug(`[Player#destroy] Already destroying/destroyed for ${this.guildId}`);
229
- return false;
230
- }
231
228
  this.state = Utils_1.StateTypes.Destroying;
232
229
  if (disconnect) {
233
230
  await this.disconnect().catch((err) => {
@@ -392,30 +389,66 @@ class Player {
392
389
  /**
393
390
  * Sets the volume of the player.
394
391
  * @param {number} volume - The new volume. Must be between 0 and 1000.
392
+ * @param {GradualOptions} options - The options to use for the gradual change.
395
393
  * @returns {Promise<Player>} - The updated player.
396
394
  * @throws {TypeError} If the volume is not a number.
397
395
  * @throws {RangeError} If the volume is not between 0 and 1000.
398
396
  * @emits {PlayerStateUpdate} - Emitted when the volume is changed.
399
397
  * @example
400
398
  * player.setVolume(50);
399
+ * player.setVolume(50, { gradual: true, interval: 50, step: 5 });
401
400
  */
402
- async setVolume(volume) {
401
+ async setVolume(volume, options) {
403
402
  if (isNaN(volume))
404
403
  throw new TypeError("Volume must be a number.");
405
404
  if (volume < 0 || volume > 1000)
406
405
  throw new RangeError("Volume must be between 0 and 1000.");
407
- const oldPlayer = this ? { ...this } : null;
408
- await this.node.rest.updatePlayer({
409
- guildId: this.options.guildId,
410
- data: {
411
- volume,
412
- },
413
- });
414
- this.volume = volume;
415
- this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this, {
416
- changeType: Manager_1.PlayerStateEventTypes.VolumeChange,
417
- details: { previousVolume: oldPlayer.volume || null, currentVolume: this.volume },
418
- });
406
+ const oldVolume = this.volume;
407
+ if (options?.gradual) {
408
+ if (this.volumeFadeInProgress) {
409
+ throw new Error("A volume fade is already in progress.");
410
+ }
411
+ this.volumeFadeInProgress = true;
412
+ const interval = options.interval ?? 100;
413
+ const step = options.step ?? 5;
414
+ const direction = volume > this.volume ? 1 : -1;
415
+ let currentVolume = this.volume;
416
+ while (currentVolume !== volume) {
417
+ currentVolume = direction > 0 ? Math.min(currentVolume + step, volume) : Math.max(currentVolume - step, volume);
418
+ await this.node.rest.updatePlayer({
419
+ guildId: this.options.guildId,
420
+ data: { volume: currentVolume },
421
+ });
422
+ this.volume = currentVolume;
423
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, {
424
+ changeType: Manager_1.PlayerStateEventTypes.VolumeChange,
425
+ details: {
426
+ previousVolume: oldVolume,
427
+ currentVolume: this.volume,
428
+ isGradual: true,
429
+ },
430
+ });
431
+ if (currentVolume !== volume) {
432
+ await this.sleep(interval);
433
+ }
434
+ }
435
+ this.volumeFadeInProgress = false;
436
+ }
437
+ else {
438
+ await this.node.rest.updatePlayer({
439
+ guildId: this.options.guildId,
440
+ data: { volume },
441
+ });
442
+ this.volume = volume;
443
+ this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, {
444
+ changeType: Manager_1.PlayerStateEventTypes.VolumeChange,
445
+ details: {
446
+ previousVolume: oldVolume,
447
+ currentVolume: this.volume,
448
+ isGradual: false,
449
+ },
450
+ });
451
+ }
419
452
  return this;
420
453
  }
421
454
  /**
@@ -901,5 +934,13 @@ class Player {
901
934
  }
902
935
  return result;
903
936
  }
937
+ /**
938
+ * Sleeps for a specified amount of time.
939
+ * @param ms The amount of time to sleep in milliseconds.
940
+ * @returns A promise that resolves after the specified amount of time.
941
+ */
942
+ sleep(ms) {
943
+ return new Promise((resolve) => setTimeout(resolve, ms));
944
+ }
904
945
  }
905
946
  exports.Player = Player;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magmastream",
3
- "version": "2.9.0-dev.23",
3
+ "version": "2.9.0-dev.25",
4
4
  "description": "A user-friendly Lavalink client designed for NodeJS.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",