magmastream 2.9.3-dev.13 → 2.9.3-dev.14

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
@@ -322,6 +322,7 @@ declare enum MagmaStreamErrorCode {
322
322
  UTILS_TRACK_PARTIAL_INVALID = "MS_UTILS_TRACK_PARTIAL_INVALID",
323
323
  UTILS_TRACK_BUILD_FAILED = "MS_UTILS_TRACK_BUILD_FAILED",
324
324
  UTILS_AUTOPLAY_BUILD_FAILED = "MS_UTILS_AUTOPLAY_BUILD_FAILED",
325
+ UTILS_PLAYER_SERIALIZE_FAILED = "MS_UTILS_PLAYER_SERIALIZE_FAILED",
325
326
  PLUGIN_LOAD_FAILED = "MS_PLUGIN_LOAD_FAILED",
326
327
  PLUGIN_RUNTIME_ERROR = "MS_PLUGIN_RUNTIME_ERROR"
327
328
  }
@@ -2355,6 +2356,11 @@ declare class Player {
2355
2356
  * @returns {NodeJS.Timeout | null} - The dynamic loop interval of the player.
2356
2357
  */
2357
2358
  getDynamicLoopIntervalPublic(): NodeJS.Timeout | null;
2359
+ /**
2360
+ * Retrieves the data associated with the player.
2361
+ * @returns {Record<string, unknown>} - The data associated with the player.
2362
+ */
2363
+ getSerializableData(): Record<string, unknown>;
2358
2364
  /**
2359
2365
  * Retrieves the current lyrics for the playing track.
2360
2366
  * @param skipTrackSource - Indicates whether to skip the track source when fetching lyrics.
@@ -3594,7 +3600,7 @@ declare abstract class PlayerUtils {
3594
3600
  * @param player The Player instance to serialize
3595
3601
  * @returns The serialized Player instance
3596
3602
  */
3597
- static serializePlayer(player: Player): Promise<Record<string, unknown>>;
3603
+ static serializePlayer(player: Player): Promise<Record<string, unknown> | null>;
3598
3604
  /**
3599
3605
  * Gets the base directory for player data.
3600
3606
  */
@@ -328,6 +328,7 @@ var MagmaStreamErrorCode;
328
328
  MagmaStreamErrorCode["UTILS_TRACK_PARTIAL_INVALID"] = "MS_UTILS_TRACK_PARTIAL_INVALID";
329
329
  MagmaStreamErrorCode["UTILS_TRACK_BUILD_FAILED"] = "MS_UTILS_TRACK_BUILD_FAILED";
330
330
  MagmaStreamErrorCode["UTILS_AUTOPLAY_BUILD_FAILED"] = "MS_UTILS_AUTOPLAY_BUILD_FAILED";
331
+ MagmaStreamErrorCode["UTILS_PLAYER_SERIALIZE_FAILED"] = "MS_UTILS_PLAYER_SERIALIZE_FAILED";
331
332
  // PLUGIN (1800)
332
333
  MagmaStreamErrorCode["PLUGIN_LOAD_FAILED"] = "MS_PLUGIN_LOAD_FAILED";
333
334
  MagmaStreamErrorCode["PLUGIN_RUNTIME_ERROR"] = "MS_PLUGIN_RUNTIME_ERROR";
@@ -381,6 +382,7 @@ exports.MagmaStreamErrorNumbers = {
381
382
  [MagmaStreamErrorCode.UTILS_TRACK_PARTIAL_INVALID]: 1700,
382
383
  [MagmaStreamErrorCode.UTILS_TRACK_BUILD_FAILED]: 1701,
383
384
  [MagmaStreamErrorCode.UTILS_AUTOPLAY_BUILD_FAILED]: 1702,
385
+ [MagmaStreamErrorCode.UTILS_PLAYER_SERIALIZE_FAILED]: 1703,
384
386
  // PLUGIN
385
387
  [MagmaStreamErrorCode.PLUGIN_LOAD_FAILED]: 1800,
386
388
  [MagmaStreamErrorCode.PLUGIN_RUNTIME_ERROR]: 1801,
@@ -1082,6 +1082,13 @@ class Player {
1082
1082
  getDynamicLoopIntervalPublic() {
1083
1083
  return this.dynamicLoopInterval;
1084
1084
  }
1085
+ /**
1086
+ * Retrieves the data associated with the player.
1087
+ * @returns {Record<string, unknown>} - The data associated with the player.
1088
+ */
1089
+ getSerializableData() {
1090
+ return { ...this.data };
1091
+ }
1085
1092
  /**
1086
1093
  * Retrieves the current lyrics for the playing track.
1087
1094
  * @param skipTrackSource - Indicates whether to skip the track source when fetching lyrics.
@@ -9,7 +9,7 @@ const Enums_1 = require("./Enums");
9
9
  const path_1 = tslib_1.__importDefault(require("path"));
10
10
  const safe_stable_stringify_1 = tslib_1.__importDefault(require("safe-stable-stringify"));
11
11
  const MagmastreamError_1 = require("./MagmastreamError");
12
- const lodash_1 = require("lodash");
12
+ // import { isPlainObject } from "lodash";
13
13
  // import playwright from "playwright";
14
14
  /** @hidden */
15
15
  const SIZES = ["0", "1", "2", "3", "default", "mqdefault", "hqdefault", "maxresdefault"];
@@ -623,20 +623,6 @@ class PlayerUtils {
623
623
  * @returns The serialized Player instance
624
624
  */
625
625
  static async serializePlayer(player) {
626
- const current = await player.queue.getCurrent();
627
- const tracks = await player.queue.getTracks();
628
- const previous = await player.queue.getPrevious();
629
- const serializeTrack = (track) => ({
630
- ...track,
631
- requester: track.requester ? { id: track.requester.id, username: track.requester.username } : null,
632
- });
633
- const safeNode = player.node
634
- ? JSON.parse(JSON.stringify(player.node, (key, value) => {
635
- if (key === "rest" || key === "players" || key === "shards" || key === "manager")
636
- return undefined;
637
- return value;
638
- }))
639
- : null;
640
626
  const isNonSerializable = (value) => {
641
627
  if (typeof value === "function" || typeof value === "symbol")
642
628
  return true;
@@ -653,59 +639,99 @@ class PlayerUtils {
653
639
  }
654
640
  return false;
655
641
  };
656
- const safeReplacer = (key, value) => {
657
- if (isNonSerializable(value))
658
- return undefined;
659
- if (key === "manager")
660
- return null;
661
- if (key === "node")
662
- return safeNode;
663
- if (key === "filters") {
664
- const filters = { ...value };
665
- delete filters.player;
666
- return {
667
- distortion: filters["distortion"] ?? null,
668
- equalizer: filters["equalizer"] ?? [],
669
- karaoke: filters["karaoke"] ?? null,
670
- rotation: filters["rotation"] ?? null,
671
- timescale: value["timescale"] ?? null,
672
- vibrato: value["vibrato"] ?? null,
673
- reverb: value["reverb"] ?? null,
674
- volume: value["volume"] ?? 1.0,
675
- bassBoostlevel: value["bassBoostlevel"] ?? null,
676
- filterStatus: (0, lodash_1.isPlainObject)(value["filtersStatus"]) ? { ...value["filtersStatus"] } : {},
677
- };
678
- }
679
- if (key === "queue") {
680
- return {
681
- current: current ? serializeTrack(current) : null,
682
- tracks: tracks.map(serializeTrack),
683
- previous: previous.map(serializeTrack),
684
- };
685
- }
686
- if (key === "data" && (0, lodash_1.isPlainObject)(value)) {
687
- return {
688
- clientUser: value["Internal_AutoplayUser"] ?? null,
689
- nowPlayingMessage: value["nowPlayingMessage"] ?? null,
690
- };
642
+ const safeSerialize = (obj) => {
643
+ if (!obj || typeof obj !== "object")
644
+ return obj;
645
+ const result = {};
646
+ for (const [k, v] of Object.entries(obj)) {
647
+ if (!isNonSerializable(v)) {
648
+ result[k] = v;
649
+ }
691
650
  }
692
- return value;
651
+ return result;
693
652
  };
694
- let serialized;
695
653
  try {
696
- serialized = JSON.stringify(player, safeReplacer);
654
+ const [current, tracks, previous] = await Promise.all([player.queue.getCurrent(), player.queue.getTracks(), player.queue.getPrevious()]);
655
+ const serializeTrack = (track) => {
656
+ try {
657
+ return {
658
+ ...track,
659
+ requester: track.requester ? { id: track.requester.id, username: track.requester.username } : null,
660
+ };
661
+ }
662
+ catch {
663
+ return null;
664
+ }
665
+ };
666
+ const safeCurrent = current ? serializeTrack(current) : null;
667
+ const safeTracks = tracks.map(serializeTrack).filter((t) => t !== null);
668
+ const safePrevious = previous.map(serializeTrack).filter((t) => t !== null);
669
+ let safeNode = null;
670
+ if (player.node) {
671
+ try {
672
+ safeNode = JSON.parse(JSON.stringify(player.node, (key, value) => {
673
+ if (["rest", "players", "shards", "manager"].includes(key))
674
+ return undefined;
675
+ if (isNonSerializable(value))
676
+ return undefined;
677
+ return value;
678
+ }));
679
+ }
680
+ catch {
681
+ safeNode = null;
682
+ }
683
+ }
684
+ const snapshot = {
685
+ options: player.options,
686
+ voiceState: player.voiceState,
687
+ clusterId: player.clusterId,
688
+ guildId: player.guildId,
689
+ voiceChannelId: player.voiceChannelId ?? null,
690
+ textChannelId: player.textChannelId ?? null,
691
+ volume: player.volume,
692
+ paused: player.paused,
693
+ playing: player.playing,
694
+ position: player.position,
695
+ trackRepeat: player.trackRepeat,
696
+ queueRepeat: player.queueRepeat,
697
+ dynamicRepeat: player.dynamicRepeat,
698
+ node: safeNode,
699
+ queue: {
700
+ current: safeCurrent,
701
+ tracks: safeTracks,
702
+ previous: safePrevious,
703
+ },
704
+ filters: player.filters
705
+ ? {
706
+ distortion: player.filters.distortion ?? null,
707
+ equalizer: player.filters.equalizer ?? [],
708
+ karaoke: player.filters.karaoke ?? null,
709
+ rotation: player.filters.rotation ?? null,
710
+ timescale: player.filters.timescale ?? null,
711
+ vibrato: player.filters.vibrato ?? null,
712
+ reverb: player.filters.reverb ?? null,
713
+ volume: player.filters.volume ?? 1.0,
714
+ bassBoostlevel: player.filters.bassBoostlevel ?? null,
715
+ filterStatus: { ...player.filters.filtersStatus },
716
+ }
717
+ : null,
718
+ data: safeSerialize(player.getSerializableData()),
719
+ };
720
+ // Sanity check
721
+ JSON.stringify(snapshot);
722
+ return snapshot;
697
723
  }
698
724
  catch (err) {
699
725
  const error = err instanceof MagmastreamError_1.MagmaStreamError
700
726
  ? err
701
727
  : new MagmastreamError_1.MagmaStreamError({
702
- code: Enums_1.MagmaStreamErrorCode.MANAGER_SEARCH_FAILED,
703
- message: `An error occurred while searching: ${err instanceof Error ? err.message : String(err)}`,
728
+ code: Enums_1.MagmaStreamErrorCode.UTILS_PLAYER_SERIALIZE_FAILED,
729
+ message: `An error occurred while serializing player: ${err instanceof Error ? err.message : String(err)}`,
704
730
  cause: err instanceof Error ? err : undefined,
705
731
  });
706
732
  console.error(error);
733
+ return null;
707
734
  }
708
- return JSON.parse(serialized);
709
735
  }
710
736
  /**
711
737
  * Gets the base directory for player data.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magmastream",
3
- "version": "2.9.3-dev.13",
3
+ "version": "2.9.3-dev.14",
4
4
  "description": "A user-friendly Lavalink client designed for NodeJS.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",