magmastream 2.9.3-dev.13 → 2.9.3-dev.15

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
@@ -3,12 +3,11 @@ import { GatewayVoiceStateUpdate } from 'discord-api-types/v10';
3
3
  import { EventEmitter } from 'events';
4
4
  import { User, ClientUser, Message, Client } from 'discord.js';
5
5
  import { User as User$1, Message as Message$1, Client as Client$2 } from 'oceanic.js';
6
- import { User as User$2, Message as Message$2 } from 'detritus-client/lib/structures';
6
+ import { User as User$2, Message as Message$2, Bot } from '@discordeno/bot';
7
7
  import { User as User$3, Message as Message$3, Client as Client$1 } from 'eris';
8
8
  import { User as User$4, ClientUser as ClientUser$1, Message as Message$4, Client as Client$3, WorkerClient } from 'seyfert';
9
9
  import WebSocket$1, { WebSocket } from 'ws';
10
10
  import { Redis } from 'ioredis';
11
- import { ClusterClient, ShardClient } from 'detritus-client';
12
11
 
13
12
  /** Represents an equalizer band. */
14
13
  interface Band {
@@ -286,6 +285,7 @@ declare enum MagmaStreamErrorCode {
286
285
  GENERAL_UNKNOWN = "MS_GENERAL_UNKNOWN",
287
286
  GENERAL_TIMEOUT = "MS_GENERAL_TIMEOUT",
288
287
  GENERAL_INVALID_MANAGER = "MS_GENERAL_INVALID_MANAGER",
288
+ INTENT_MISSING = "MS_INTENT_MISSING",
289
289
  MANAGER_INIT_FAILED = "MS_MANAGER_INIT_FAILED",
290
290
  MANAGER_INVALID_CONFIG = "MS_MANAGER_INVALID_CONFIG",
291
291
  MANAGER_SHUTDOWN_FAILED = "MS_MANAGER_SHUTDOWN_FAILED",
@@ -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
  }
@@ -920,6 +921,12 @@ interface ManagerOptions {
920
921
  * @param payload The payload to send.
921
922
  */
922
923
  send?: (packet: DiscordPacket) => unknown;
924
+ /**
925
+ * Optional user cache getter.
926
+ * When resolving a user from a partial ID, this function will be called first.
927
+ * Should return the full user object if cached, or undefined if not.
928
+ */
929
+ getUser?: (id: string) => AnyUser | undefined;
923
930
  }
924
931
  /**
925
932
  * State Storage Options
@@ -2355,6 +2362,11 @@ declare class Player {
2355
2362
  * @returns {NodeJS.Timeout | null} - The dynamic loop interval of the player.
2356
2363
  */
2357
2364
  getDynamicLoopIntervalPublic(): NodeJS.Timeout | null;
2365
+ /**
2366
+ * Retrieves the data associated with the player.
2367
+ * @returns {Record<string, unknown>} - The data associated with the player.
2368
+ */
2369
+ getSerializableData(): Record<string, unknown>;
2358
2370
  /**
2359
2371
  * Retrieves the current lyrics for the playing track.
2360
2372
  * @param skipTrackSource - Indicates whether to skip the track source when fetching lyrics.
@@ -2899,6 +2911,7 @@ declare class Manager extends EventEmitter {
2899
2911
  initiated: boolean;
2900
2912
  redis?: Redis;
2901
2913
  private _send;
2914
+ private _getUser?;
2902
2915
  private loadedPlugins;
2903
2916
  /**
2904
2917
  * Initiates the Manager class.
@@ -3121,6 +3134,7 @@ declare class Manager extends EventEmitter {
3121
3134
  */
3122
3135
  private get priorityNode();
3123
3136
  protected send(packet: GatewayVoiceStateUpdate): unknown;
3137
+ protected getUserFromCache(id: string): AnyUser | undefined;
3124
3138
  sendPacket(packet: GatewayVoiceStateUpdate): unknown;
3125
3139
  /**
3126
3140
  * Resolves a PortableUser or ID to a real user object.
@@ -3594,7 +3608,7 @@ declare abstract class PlayerUtils {
3594
3608
  * @param player The Player instance to serialize
3595
3609
  * @returns The serialized Player instance
3596
3610
  */
3597
- static serializePlayer(player: Player): Promise<Record<string, unknown>>;
3611
+ static serializePlayer(player: Player): Promise<Record<string, unknown> | null>;
3598
3612
  /**
3599
3613
  * Gets the base directory for player data.
3600
3614
  */
@@ -3652,6 +3666,20 @@ declare class MagmaStreamError<T = unknown> extends Error {
3652
3666
  constructor({ code, message, cause, context }: MagmaStreamErrorOptions<T>);
3653
3667
  }
3654
3668
 
3669
+ /**
3670
+ * Discordeno wrapper for Magmastream.
3671
+ */
3672
+ declare class DiscordenoManager extends Manager {
3673
+ readonly client: Bot;
3674
+ constructor(client: Bot, options?: ManagerOptions);
3675
+ protected send(packet: GatewayVoiceStateUpdate): void;
3676
+ /**
3677
+ * Resolve a user by ID or partial info.
3678
+ * Uses user-provided cache getter if available, otherwise falls back to minimal info.
3679
+ */
3680
+ resolveUser(user: AnyUser | string): Promise<User$2 | AnyUser>;
3681
+ }
3682
+
3655
3683
  /**
3656
3684
  * Discord.js wrapper for Magmastream.
3657
3685
  */
@@ -3672,16 +3700,6 @@ declare class ErisManager extends Manager {
3672
3700
  resolveUser(user: AnyUser | string): Promise<User$3 | AnyUser>;
3673
3701
  }
3674
3702
 
3675
- /**
3676
- * Detritus wrapper for Magmastream.
3677
- */
3678
- declare class DetritusManager extends Manager {
3679
- readonly client: ClusterClient | ShardClient;
3680
- constructor(client: ClusterClient | ShardClient, options?: ManagerOptions);
3681
- protected send(packet: GatewayVoiceStateUpdate): void;
3682
- resolveUser(user: AnyUser | string): Promise<AnyUser>;
3683
- }
3684
-
3685
3703
  /**
3686
3704
  * Oceanic wrapper for Magmastream.
3687
3705
  */
@@ -3724,5 +3742,5 @@ declare class SeyfertManager extends Manager {
3724
3742
  resolveUser(user: AnyUser | string): Promise<User$4 | AnyUser>;
3725
3743
  }
3726
3744
 
3727
- export { AutoPlayPlatform, AutoPlayUtils, AvailableFilters, DetritusManager, DiscordJSManager, ErisManager, Filters, JSONUtils, JsonQueue, LoadTypes, MagmaStreamError, MagmaStreamErrorCode, MagmaStreamErrorNumbers, Manager, ManagerEventTypes, MemoryQueue, Node, OceanicManager, Player, PlayerStateEventTypes, PlayerUtils, Plugin, RedisQueue, Rest, SearchPlatform, SeverityTypes, SeyfertManager, SponsorBlockSegment, StateStorageType, StateTypes, Structure, TrackEndReasonTypes, TrackPartial, TrackSourceTypes, TrackUtils, UseNodeOptions };
3745
+ export { AutoPlayPlatform, AutoPlayUtils, AvailableFilters, DiscordJSManager, DiscordenoManager, ErisManager, Filters, JSONUtils, JsonQueue, LoadTypes, MagmaStreamError, MagmaStreamErrorCode, MagmaStreamErrorNumbers, Manager, ManagerEventTypes, MemoryQueue, Node, OceanicManager, Player, PlayerStateEventTypes, PlayerUtils, Plugin, RedisQueue, Rest, SearchPlatform, SeverityTypes, SeyfertManager, SponsorBlockSegment, StateStorageType, StateTypes, Structure, TrackEndReasonTypes, TrackPartial, TrackSourceTypes, TrackUtils, UseNodeOptions };
3728
3746
  export type { AlbumSearchResult, AnyMessage, AnyUser, ArtistSearchResult, CPUStats, DiscordPacket, DistortionOptions, EndSpeakingEventVoiceReceiver, EndSpeakingEventVoiceReceiverData, EqualizerBand, ErrorOrEmptySearchResult, Exception, Extendable, FrameStats, IQueue, JsonConfig, KaraokeOptions, LavaPlayer, LavalinkInfo, LavalinkResponse, LoadType, Lyrics, LyricsEvent, LyricsEventType, LyricsFoundEvent, LyricsLine, LyricsLineEvent, LyricsNotFoundEvent, ManagerEvents, ManagerInitOptions, ManagerOptions, MemoryStats, NodeLinkGetLyrics, NodeLinkGetLyricsEmpty, NodeLinkGetLyricsError, NodeLinkGetLyricsMultiple, NodeLinkGetLyricsSingle, NodeMessage, NodeOptions, NodeStats, PlayOptions, PlayerEvent, PlayerEventType, PlayerEvents, PlayerOptions, PlayerStateUpdateEvent, PlayerUpdateVoiceState, PlaylistData, PlaylistInfoData, PlaylistRawData, PlaylistSearchResult, PodcastSearchResult, PortableMessage, PortableUser, RedisConfig, RestPlayOptions, ReverbOptions, RotationOptions, SearchQuery, SearchResult, SearchSearchResult, Severity, ShortSearchResult, ShowSearchResult, Sizes, SponsorBlockChapterStarted, SponsorBlockChaptersLoaded, SponsorBlockSegmentEventType, SponsorBlockSegmentEvents, SponsorBlockSegmentSkipped, SponsorBlockSegmentsLoaded, StartSpeakingEventVoiceReceiver, StartSpeakingEventVoiceReceiverData, StateStorageOptions, StationSearchResult, TimescaleOptions, Track, TrackData, TrackDataInfo, TrackEndEvent, TrackEndReason, TrackExceptionEvent, TrackPluginInfo, TrackSearchResult, TrackSourceName, TrackStartEvent, TrackStuckEvent, UseNodeOption, VibratoOptions, VoicePacket, VoiceReceiverEvent, VoiceServer, VoiceServerUpdate, VoiceState, WebSocketClosedEvent };
package/dist/index.js CHANGED
@@ -11,9 +11,9 @@ tslib_1.__exportStar(require("./structures/Rest"), exports);
11
11
  tslib_1.__exportStar(require("./structures/Utils"), exports);
12
12
  tslib_1.__exportStar(require("./structures/MagmastreamError"), exports);
13
13
  // wrappers
14
+ tslib_1.__exportStar(require("./wrappers/discordeno"), exports);
14
15
  tslib_1.__exportStar(require("./wrappers/discord.js"), exports);
15
16
  tslib_1.__exportStar(require("./wrappers/eris"), exports);
16
- tslib_1.__exportStar(require("./wrappers/detritus"), exports);
17
17
  tslib_1.__exportStar(require("./wrappers/oceanic"), exports);
18
18
  tslib_1.__exportStar(require("./wrappers/seyfert"), exports);
19
19
  // types
@@ -373,7 +373,7 @@ class JsonQueue {
373
373
  const queue = await this.getQueue();
374
374
  const userMap = new Map();
375
375
  for (const track of queue) {
376
- const userId = track.requester.id;
376
+ const userId = track.requester.id.toString();
377
377
  if (!userMap.has(userId))
378
378
  userMap.set(userId, []);
379
379
  userMap.get(userId).push(track);
@@ -498,7 +498,7 @@ class JsonQueue {
498
498
  const queue = await this.getQueue();
499
499
  const userMap = new Map();
500
500
  for (const track of queue) {
501
- const userId = track.requester.id;
501
+ const userId = track.requester.id.toString();
502
502
  if (!userMap.has(userId))
503
503
  userMap.set(userId, []);
504
504
  userMap.get(userId).push(track);
@@ -355,11 +355,11 @@ class MemoryQueue extends Array {
355
355
  const userTracks = new Map();
356
356
  // Group the tracks in the queue by the user that requested them.
357
357
  this.forEach((track) => {
358
- const user = track.requester.id;
359
- if (!userTracks.has(user)) {
360
- userTracks.set(user, []);
358
+ const userId = track.requester.id.toString();
359
+ if (!userTracks.has(userId)) {
360
+ userTracks.set(userId, []);
361
361
  }
362
- userTracks.get(user).push(track);
362
+ userTracks.get(userId).push(track);
363
363
  });
364
364
  // Shuffle the tracks of each user.
365
365
  userTracks.forEach((tracks) => {
@@ -486,11 +486,11 @@ class MemoryQueue extends Array {
486
486
  // Group the tracks in the queue by the user that requested them.
487
487
  const userTracks = new Map();
488
488
  this.forEach((track) => {
489
- const user = track.requester.id;
490
- if (!userTracks.has(user)) {
491
- userTracks.set(user, []);
489
+ const userId = track.requester.id.toString();
490
+ if (!userTracks.has(userId)) {
491
+ userTracks.set(userId, []);
492
492
  }
493
- userTracks.get(user).push(track);
493
+ userTracks.get(userId).push(track);
494
494
  });
495
495
  // Create a new array for the shuffled queue.
496
496
  const shuffledQueue = [];
@@ -513,7 +513,7 @@ class RedisQueue {
513
513
  const deserialized = rawTracks.map(this.deserialize);
514
514
  const userMap = new Map();
515
515
  for (const track of deserialized) {
516
- const userId = track.requester.id;
516
+ const userId = track.requester.id.toString();
517
517
  if (!userMap.has(userId))
518
518
  userMap.set(userId, []);
519
519
  userMap.get(userId).push(track);
@@ -684,7 +684,7 @@ class RedisQueue {
684
684
  const deserialized = rawTracks.map(this.deserialize);
685
685
  const userMap = new Map();
686
686
  for (const track of deserialized) {
687
- const userId = track.requester.id;
687
+ const userId = track.requester.id.toString();
688
688
  if (!userMap.has(userId))
689
689
  userMap.set(userId, []);
690
690
  userMap.get(userId).push(track);
@@ -285,6 +285,7 @@ var MagmaStreamErrorCode;
285
285
  MagmaStreamErrorCode["GENERAL_UNKNOWN"] = "MS_GENERAL_UNKNOWN";
286
286
  MagmaStreamErrorCode["GENERAL_TIMEOUT"] = "MS_GENERAL_TIMEOUT";
287
287
  MagmaStreamErrorCode["GENERAL_INVALID_MANAGER"] = "MS_GENERAL_INVALID_MANAGER";
288
+ MagmaStreamErrorCode["INTENT_MISSING"] = "MS_INTENT_MISSING";
288
289
  // MANAGER (1100)
289
290
  MagmaStreamErrorCode["MANAGER_INIT_FAILED"] = "MS_MANAGER_INIT_FAILED";
290
291
  MagmaStreamErrorCode["MANAGER_INVALID_CONFIG"] = "MS_MANAGER_INVALID_CONFIG";
@@ -328,6 +329,7 @@ var MagmaStreamErrorCode;
328
329
  MagmaStreamErrorCode["UTILS_TRACK_PARTIAL_INVALID"] = "MS_UTILS_TRACK_PARTIAL_INVALID";
329
330
  MagmaStreamErrorCode["UTILS_TRACK_BUILD_FAILED"] = "MS_UTILS_TRACK_BUILD_FAILED";
330
331
  MagmaStreamErrorCode["UTILS_AUTOPLAY_BUILD_FAILED"] = "MS_UTILS_AUTOPLAY_BUILD_FAILED";
332
+ MagmaStreamErrorCode["UTILS_PLAYER_SERIALIZE_FAILED"] = "MS_UTILS_PLAYER_SERIALIZE_FAILED";
331
333
  // PLUGIN (1800)
332
334
  MagmaStreamErrorCode["PLUGIN_LOAD_FAILED"] = "MS_PLUGIN_LOAD_FAILED";
333
335
  MagmaStreamErrorCode["PLUGIN_RUNTIME_ERROR"] = "MS_PLUGIN_RUNTIME_ERROR";
@@ -338,6 +340,7 @@ exports.MagmaStreamErrorNumbers = {
338
340
  [MagmaStreamErrorCode.GENERAL_UNKNOWN]: 1000,
339
341
  [MagmaStreamErrorCode.GENERAL_TIMEOUT]: 1001,
340
342
  [MagmaStreamErrorCode.GENERAL_INVALID_MANAGER]: 1002,
343
+ [MagmaStreamErrorCode.INTENT_MISSING]: 1003,
341
344
  // MANAGER
342
345
  [MagmaStreamErrorCode.MANAGER_INIT_FAILED]: 1100,
343
346
  [MagmaStreamErrorCode.MANAGER_INVALID_CONFIG]: 1101,
@@ -381,6 +384,7 @@ exports.MagmaStreamErrorNumbers = {
381
384
  [MagmaStreamErrorCode.UTILS_TRACK_PARTIAL_INVALID]: 1700,
382
385
  [MagmaStreamErrorCode.UTILS_TRACK_BUILD_FAILED]: 1701,
383
386
  [MagmaStreamErrorCode.UTILS_AUTOPLAY_BUILD_FAILED]: 1702,
387
+ [MagmaStreamErrorCode.UTILS_PLAYER_SERIALIZE_FAILED]: 1703,
384
388
  // PLUGIN
385
389
  [MagmaStreamErrorCode.PLUGIN_LOAD_FAILED]: 1800,
386
390
  [MagmaStreamErrorCode.PLUGIN_RUNTIME_ERROR]: 1801,
@@ -28,6 +28,7 @@ class Manager extends events_1.EventEmitter {
28
28
  initiated = false;
29
29
  redis;
30
30
  _send;
31
+ _getUser;
31
32
  loadedPlugins = new Set();
32
33
  /**
33
34
  * Initiates the Manager class.
@@ -61,6 +62,8 @@ class Manager extends events_1.EventEmitter {
61
62
  this.options.clusterId = options.clusterId;
62
63
  if (options.send && !this._send)
63
64
  this._send = options.send;
65
+ if (options.getUser && !this._getUser)
66
+ this._getUser = options.getUser;
64
67
  this.options = {
65
68
  ...options,
66
69
  enabledPlugins: options.enabledPlugins ?? [],
@@ -1439,6 +1442,9 @@ class Manager extends events_1.EventEmitter {
1439
1442
  }
1440
1443
  return this._send(packet);
1441
1444
  }
1445
+ getUserFromCache(id) {
1446
+ return this._getUser?.(id);
1447
+ }
1442
1448
  sendPacket(packet) {
1443
1449
  return this.send(packet);
1444
1450
  }
@@ -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.
@@ -4,7 +4,10 @@ exports.DiscordJSManager = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const Manager_1 = require("../structures/Manager");
6
6
  const discord_js_1 = require("discord.js");
7
- const [major, minor] = discord_js_1.version.split(".").map(Number);
7
+ const discord_js_2 = require("discord.js");
8
+ const MagmastreamError_1 = require("../structures/MagmastreamError");
9
+ const Enums_1 = require("../structures/Enums");
10
+ const [major, minor] = discord_js_2.version.split(".").map(Number);
8
11
  tslib_1.__exportStar(require("../index"), exports);
9
12
  /**
10
13
  * Discord.js wrapper for Magmastream.
@@ -14,6 +17,12 @@ class DiscordJSManager extends Manager_1.Manager {
14
17
  constructor(client, options) {
15
18
  super(options);
16
19
  this.client = client;
20
+ if (!this.client.options.intents.has(discord_js_1.GatewayIntentBits.GuildVoiceStates)) {
21
+ throw new MagmastreamError_1.MagmaStreamError({
22
+ code: Enums_1.MagmaStreamErrorCode.INTENT_MISSING,
23
+ message: "[Custom Wrapper] Your Discord.js client must have the GuildVoiceStates intent enabled.",
24
+ });
25
+ }
17
26
  const attachReadyHandler = () => {
18
27
  const handler = () => {
19
28
  if (!this.options.clientId)
@@ -21,11 +30,11 @@ class DiscordJSManager extends Manager_1.Manager {
21
30
  };
22
31
  // Only attach clientReady if Discord.js >= 14.22.0
23
32
  if (major > 14 || (major === 14 && minor >= 22)) {
24
- client.once("clientReady", handler);
33
+ this.client.once("clientReady", handler);
25
34
  }
26
35
  // Only attach ready if Discord.js < 14.22.0
27
36
  if (major < 14 || (major === 14 && minor < 22)) {
28
- client.once("ready", handler);
37
+ this.client.once("ready", handler);
29
38
  }
30
39
  };
31
40
  attachReadyHandler();
@@ -39,7 +48,7 @@ class DiscordJSManager extends Manager_1.Manager {
39
48
  guild.shard.send(packet);
40
49
  }
41
50
  async resolveUser(user) {
42
- const id = typeof user === "string" ? user : user.id;
51
+ const id = typeof user === "string" ? user : String(user.id);
43
52
  const cached = this.client.users.cache.get(id);
44
53
  if (cached)
45
54
  return cached;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DiscordenoManager = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const Manager_1 = require("../structures/Manager");
6
+ const bot_1 = require("@discordeno/bot");
7
+ const Enums_1 = require("../structures/Enums");
8
+ const MagmastreamError_1 = require("../structures/MagmastreamError");
9
+ tslib_1.__exportStar(require("../index"), exports);
10
+ /**
11
+ * Discordeno wrapper for Magmastream.
12
+ */
13
+ class DiscordenoManager extends Manager_1.Manager {
14
+ client;
15
+ constructor(client, options) {
16
+ super(options);
17
+ this.client = client;
18
+ // Ensure GuildVoiceStates intent is enabled
19
+ const intents = this.client.gateway.intents;
20
+ if (!(intents & bot_1.GatewayIntents.GuildVoiceStates)) {
21
+ throw new MagmastreamError_1.MagmaStreamError({
22
+ code: Enums_1.MagmaStreamErrorCode.INTENT_MISSING,
23
+ message: "[Custom Wrapper] Your Discordeno client must have the GuildVoiceStates intent enabled.",
24
+ });
25
+ }
26
+ // Chain READY event
27
+ const oldReady = this.client.handlers.READY;
28
+ this.client.handlers.READY = (bot, payload, shardId) => {
29
+ if (oldReady)
30
+ oldReady(bot, payload, shardId);
31
+ if (!this.options?.clientId)
32
+ this.options.clientId = this.client.applicationId.toString();
33
+ };
34
+ // Chain VOICE_STATE_UPDATE event
35
+ const oldVoiceState = this.client.handlers.VOICE_STATE_UPDATE;
36
+ this.client.handlers.VOICE_STATE_UPDATE = (bot, payload, shardId) => {
37
+ if (oldVoiceState)
38
+ oldVoiceState(bot, payload, shardId);
39
+ this.updateVoiceState(payload);
40
+ };
41
+ // Chain VOICE_SERVER_UPDATE event
42
+ const oldVoiceServer = this.client.handlers.VOICE_SERVER_UPDATE;
43
+ this.client.handlers.VOICE_SERVER_UPDATE = (bot, payload, shardId) => {
44
+ if (oldVoiceServer)
45
+ oldVoiceServer(bot, payload, shardId);
46
+ this.updateVoiceState(payload);
47
+ };
48
+ }
49
+ // Send voice state updates to the guild shard
50
+ send(packet) {
51
+ this.client.gateway.sendPayload(this.client.gateway.calculateShardId(packet.d.guild_id), {
52
+ op: bot_1.GatewayOpcodes.VoiceStateUpdate,
53
+ d: packet.d,
54
+ });
55
+ }
56
+ /**
57
+ * Resolve a user by ID or partial info.
58
+ * Uses user-provided cache getter if available, otherwise falls back to minimal info.
59
+ */
60
+ async resolveUser(user) {
61
+ const id = typeof user === "string" ? user : String(user.id);
62
+ // Try user-provided cache getter
63
+ const cached = this.getUserFromCache(id);
64
+ if (cached)
65
+ return cached;
66
+ // Fallback: return minimal info
67
+ return {
68
+ id,
69
+ username: typeof user === "string" ? undefined : user.username,
70
+ };
71
+ }
72
+ }
73
+ exports.DiscordenoManager = DiscordenoManager;
@@ -2,7 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ErisManager = void 0;
4
4
  const tslib_1 = require("tslib");
5
+ const v10_1 = require("discord-api-types/v10");
5
6
  const Manager_1 = require("../structures/Manager");
7
+ const Enums_1 = require("../structures/Enums");
8
+ const MagmastreamError_1 = require("../structures/MagmastreamError");
6
9
  tslib_1.__exportStar(require("../index"), exports);
7
10
  /**
8
11
  * Eris wrapper for Magmastream.
@@ -12,11 +15,19 @@ class ErisManager extends Manager_1.Manager {
12
15
  constructor(client, options) {
13
16
  super(options);
14
17
  this.client = client;
15
- client.once("ready", () => {
18
+ const intents = this.client.options.intents;
19
+ const hasGuildVoiceStates = typeof intents === "number" ? (intents & v10_1.GatewayIntentBits.GuildVoiceStates) === v10_1.GatewayIntentBits.GuildVoiceStates : intents.includes("guildVoiceStates");
20
+ if (!hasGuildVoiceStates) {
21
+ throw new MagmastreamError_1.MagmaStreamError({
22
+ code: Enums_1.MagmaStreamErrorCode.INTENT_MISSING,
23
+ message: "[Custom Wrapper] Your Eris client must have the guildVoiceStates intent enabled.",
24
+ });
25
+ }
26
+ this.client.once("ready", () => {
16
27
  if (!this.options.clientId)
17
28
  this.options.clientId = client.user.id;
18
29
  });
19
- client.on("rawWS", async (packet) => {
30
+ this.client.on("rawWS", async (packet) => {
20
31
  await this.updateVoiceState(packet);
21
32
  });
22
33
  }
@@ -26,7 +37,7 @@ class ErisManager extends Manager_1.Manager {
26
37
  guild.shard.sendWS(packet.op, packet.d);
27
38
  }
28
39
  async resolveUser(user) {
29
- const id = typeof user === "string" ? user : user.id;
40
+ const id = typeof user === "string" ? user : String(user.id);
30
41
  const cached = this.client.users.get(id);
31
42
  if (cached)
32
43
  return cached;
@@ -3,6 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OceanicManager = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const Manager_1 = require("../structures/Manager");
6
+ const oceanic_js_1 = require("oceanic.js");
7
+ const Enums_1 = require("../structures/Enums");
8
+ const MagmastreamError_1 = require("../structures/MagmastreamError");
6
9
  tslib_1.__exportStar(require("../index"), exports);
7
10
  /**
8
11
  * Oceanic wrapper for Magmastream.
@@ -12,11 +15,20 @@ class OceanicManager extends Manager_1.Manager {
12
15
  constructor(client, options) {
13
16
  super(options);
14
17
  this.client = client;
15
- client.once("ready", () => {
18
+ const intents = this.client.shards.options.intents;
19
+ const { Intents } = oceanic_js_1.Constants;
20
+ const hasGuildVoiceStates = typeof intents === "number" ? (intents & Intents.GUILD_VOICE_STATES) === Intents.GUILD_VOICE_STATES : intents.includes("GUILD_VOICE_STATES");
21
+ if (!hasGuildVoiceStates) {
22
+ throw new MagmastreamError_1.MagmaStreamError({
23
+ code: Enums_1.MagmaStreamErrorCode.INTENT_MISSING,
24
+ message: "[Custom Wrapper] Your Oceanic client must have the GUILD_VOICE_STATES intent enabled.",
25
+ });
26
+ }
27
+ this.client.once("ready", () => {
16
28
  if (!this.options.clientId)
17
- this.options.clientId = client.user.id;
29
+ this.options.clientId = this.client.user.id;
18
30
  });
19
- client.on("packet", async (packet) => {
31
+ this.client.on("packet", async (packet) => {
20
32
  await this.updateVoiceState(packet);
21
33
  });
22
34
  }
@@ -26,7 +38,7 @@ class OceanicManager extends Manager_1.Manager {
26
38
  guild.shard.send(packet.op, packet.d);
27
39
  }
28
40
  async resolveUser(user) {
29
- const id = typeof user === "string" ? user : user.id;
41
+ const id = typeof user === "string" ? user : String(user.id);
30
42
  const cached = this.client.users.get(id);
31
43
  if (cached)
32
44
  return cached;
@@ -4,7 +4,10 @@ exports.SeyfertManager = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const Manager_1 = require("../structures/Manager");
6
6
  const seyfert_1 = require("seyfert");
7
+ const types_1 = require("seyfert/lib/types");
7
8
  const common_1 = require("seyfert/lib/common");
9
+ const MagmastreamError_1 = require("../structures/MagmastreamError");
10
+ const Enums_1 = require("../structures/Enums");
8
11
  tslib_1.__exportStar(require("../index"), exports);
9
12
  /**
10
13
  * Seyfert wrapper for Magmastream.
@@ -36,6 +39,21 @@ class SeyfertManager extends Manager_1.Manager {
36
39
  constructor(client, options) {
37
40
  super(options);
38
41
  this.client = client;
42
+ this.client
43
+ .getRC()
44
+ .then((rc) => {
45
+ if (!(rc.intents & types_1.GatewayIntentBits.GuildVoiceStates)) {
46
+ throw new MagmastreamError_1.MagmaStreamError({
47
+ code: Enums_1.MagmaStreamErrorCode.INTENT_MISSING,
48
+ message: "[Custom Wrapper] Your Seyfert client must have the GuildVoiceStates intent enabled.",
49
+ });
50
+ }
51
+ })
52
+ .catch((error) => {
53
+ queueMicrotask(() => {
54
+ throw error;
55
+ });
56
+ });
39
57
  }
40
58
  send(packet) {
41
59
  if (this.client instanceof seyfert_1.Client) {
@@ -46,7 +64,7 @@ class SeyfertManager extends Manager_1.Manager {
46
64
  }
47
65
  }
48
66
  async resolveUser(user) {
49
- const id = typeof user === "string" ? user : user.id;
67
+ const id = typeof user === "string" ? user : String(user.id);
50
68
  const cached = this.client.cache.users?.get(id);
51
69
  if (cached)
52
70
  return cached;
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.15",
4
4
  "description": "A user-friendly Lavalink client designed for NodeJS.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -44,7 +44,7 @@
44
44
  "ws": "^8.19.0"
45
45
  },
46
46
  "optionalDependencies": {
47
- "detritus-client": "0.16.x",
47
+ "discordeno": "21.x",
48
48
  "discord.js": "14.x",
49
49
  "eris": "0.18.x",
50
50
  "oceanic.js": "^1.13.0",
@@ -1,52 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DetritusManager = void 0;
4
- const tslib_1 = require("tslib");
5
- const Manager_1 = require("../structures/Manager");
6
- const detritus_client_1 = require("detritus-client");
7
- tslib_1.__exportStar(require("../index"), exports);
8
- /**
9
- * Detritus wrapper for Magmastream.
10
- */
11
- class DetritusManager extends Manager_1.Manager {
12
- client;
13
- constructor(client, options) {
14
- super(options);
15
- this.client = client;
16
- client.once("ready", () => {
17
- if (!this.options.clientId)
18
- this.options.clientId = client instanceof detritus_client_1.ClusterClient ? client.applicationId : client.clientId;
19
- });
20
- client.on("raw", async (packet) => {
21
- await this.updateVoiceState(packet);
22
- });
23
- }
24
- send(packet) {
25
- const asCluster = this.client;
26
- const asShard = this.client;
27
- if (asShard.guilds)
28
- return asShard.gateway.send(packet.op, packet.d);
29
- if (asCluster.shards) {
30
- const shard = asCluster.shards.find((c) => c.guilds.has(packet.d.guild_id));
31
- if (shard)
32
- shard.gateway.send(packet.op, packet.d);
33
- }
34
- }
35
- async resolveUser(user) {
36
- const id = typeof user === "string" ? user : user.id;
37
- if (this.client instanceof detritus_client_1.ShardClient) {
38
- const cached = this.client.users.get(id);
39
- if (cached)
40
- return { id: cached.id, username: cached.username };
41
- }
42
- else if (this.client instanceof detritus_client_1.ClusterClient) {
43
- for (const [, shard] of this.client.shards) {
44
- const cached = shard.users.get(id);
45
- if (cached)
46
- return { id: cached.id, username: cached.username };
47
- }
48
- }
49
- return typeof user === "string" ? { id: user } : user;
50
- }
51
- }
52
- exports.DetritusManager = DetritusManager;