magmastream 2.9.1-dev.1 → 2.9.1-dev.3

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
@@ -120,6 +120,7 @@ Want to showcase your bot? Feel free to create a pull request and add it to our
120
120
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/Vexify4103"><img src="https://avatars.githubusercontent.com/u/47192617?v=4?s=100" width="100px;" alt="Vexify4103"/><br /><sub><b>Vexify4103</b></sub></a><br /><a href="#code-Vexify4103" title="Code">💻</a> <a href="#doc-Vexify4103" title="Documentation">📖</a></td>
121
121
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/ItzRandom23"><img src="https://avatars.githubusercontent.com/u/100831398?v=4?s=100" width="100px;" alt="Itz Random"/><br /><sub><b>Itz Random</b></sub></a><br /><a href="#code-ItzRandom23" title="Code">💻</a></td>
122
122
  <td align="center" valign="top" width="14.28%"><a href="https://github.com/Yanishamburger"><img src="https://avatars.githubusercontent.com/u/121449519?v=4?s=100" width="100px;" alt="Yanis_Hamburger"/><br /><sub><b>Yanis_Hamburger</b></sub></a><br /><a href="#bug-Yanishamburger" title="Bug reports">🐛</a></td>
123
+ <td align="center" valign="top" width="14.28%"><a href="https://github.com/Kenver123"><img src="https://avatars.githubusercontent.com/u/165576302?v=4?s=100" width="100px;" alt="Kenver"/><br /><sub><b>Kenver</b></sub></a><br /><a href="#platform-Kenver123" title="Packaging/porting to new platform">📦</a></td>
123
124
  </tr>
124
125
  </tbody>
125
126
  </table>
package/dist/index.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  import { Collection } from '@discordjs/collection';
2
2
  import { GatewayVoiceStateUpdate } from 'discord-api-types/v10';
3
3
  import { EventEmitter } from 'events';
4
- import { User, ClientUser, Message, Client } from 'discord.js';
4
+ import { Message, User, ClientUser, Client } from 'discord.js';
5
5
  import WebSocket$1, { WebSocket } from 'ws';
6
6
  import { Redis } from 'ioredis';
7
- import { Client as Client$1 } from 'eris';
7
+ import { Client as Client$1, User as User$1 } from 'eris';
8
8
  import { ClusterClient, ShardClient } from 'detritus-client';
9
- import { Client as Client$2 } from 'oceanic.js';
10
- import { Client as Client$3 } from 'seyfert';
9
+ import { Client as Client$2, User as User$2 } from 'oceanic.js';
10
+ import { Client as Client$3, WorkerClient, User as User$3 } from 'seyfert';
11
11
 
12
12
  /** Represents an equalizer band. */
13
13
  interface Band {
@@ -74,6 +74,7 @@ declare enum LoadTypes {
74
74
  */
75
75
  declare enum SearchPlatform {
76
76
  AppleMusic = "amsearch",
77
+ Audius = "audsearch",
77
78
  Bandcamp = "bcsearch",
78
79
  Deezer = "dzsearch",
79
80
  Jiosaavn = "jssearch",
@@ -106,6 +107,7 @@ declare enum PlayerStateEventTypes {
106
107
  */
107
108
  declare enum TrackSourceTypes {
108
109
  AppleMusic = "applemusic",
110
+ Audius = "audius",
109
111
  Bandcamp = "bandcamp",
110
112
  Deezer = "deezer",
111
113
  Jiosaavn = "jiosaavn",
@@ -895,6 +897,13 @@ interface NodeOptions {
895
897
  */
896
898
  isBackup?: boolean;
897
899
  }
900
+ /**
901
+ * Portable User
902
+ */
903
+ interface PortableUser {
904
+ id: string;
905
+ username?: string;
906
+ }
898
907
  /**
899
908
  * Discord Packet
900
909
  */
@@ -1100,7 +1109,7 @@ interface Track {
1100
1109
  /** The thumbnail of the track or null if it's a unsupported source. */
1101
1110
  readonly thumbnail: string | null;
1102
1111
  /** The user that requested the track. */
1103
- requester?: User | ClientUser;
1112
+ requester?: PortableUser;
1104
1113
  /** Displays the track thumbnail with optional size or null if it's a unsupported source. */
1105
1114
  displayThumbnail(size?: Sizes): string;
1106
1115
  /** Additional track info provided by plugins. */
@@ -1285,7 +1294,7 @@ interface PlaylistData {
1285
1294
  /** The playlist name. */
1286
1295
  name: string;
1287
1296
  /** Requester of playlist. */
1288
- requester: User | ClientUser;
1297
+ requester: PortableUser;
1289
1298
  /** More playlist information. */
1290
1299
  playlistInfo: PlaylistInfoData[];
1291
1300
  /** The length of the playlist. */
@@ -2101,12 +2110,12 @@ declare class Player {
2101
2110
  * track when the current track ends.
2102
2111
  *
2103
2112
  * @param {boolean} autoplayState - Whether or not autoplay should be enabled.
2104
- * @param {object} botUser - The user-object that should be used as the bot-user.
2113
+ * @param {object} AutoplayUser - The user-object that should be used as the bot-user.
2105
2114
  * @param {number} [tries=3] - The number of times the player should try to find a
2106
2115
  * recommended track if the first one doesn't work.
2107
2116
  * @returns {this} - The player instance.
2108
2117
  */
2109
- setAutoplay<T = unknown>(autoplayState: boolean, botUser?: T, tries?: number): this;
2118
+ setAutoplay<T = unknown>(autoplayState: boolean, AutoplayUser?: T, tries?: number): this;
2110
2119
  /**
2111
2120
  * Gets recommended tracks and returns an array of tracks.
2112
2121
  * @param {Track} track - The track to find recommendations for.
@@ -2996,6 +3005,11 @@ declare class Manager extends EventEmitter {
2996
3005
  private get priorityNode();
2997
3006
  protected send(packet: GatewayVoiceStateUpdate): unknown;
2998
3007
  sendPacket(packet: GatewayVoiceStateUpdate): unknown;
3008
+ /**
3009
+ * Resolves a PortableUser or ID to a real user object.
3010
+ * Can be overridden by wrapper managers to return wrapper-specific User classes.
3011
+ */
3012
+ resolveUser(user: PortableUser | string): Promise<PortableUser>;
2999
3013
  }
3000
3014
 
3001
3015
  declare class Filters {
@@ -3374,7 +3388,7 @@ declare abstract class TrackUtils {
3374
3388
  * @param requester The user who requested the track, if any.
3375
3389
  * @returns The built Track.
3376
3390
  */
3377
- static build<T = User | ClientUser>(data: TrackData, requester?: T): Track;
3391
+ static build<T = PortableUser | User | ClientUser>(data: TrackData, requester?: T): Track;
3378
3392
  /**
3379
3393
  * Validates a search result.
3380
3394
  * @param result The search result to validate.
@@ -3493,6 +3507,7 @@ declare class DiscordJSManager extends Manager {
3493
3507
  readonly client: Client;
3494
3508
  constructor(client: Client, options?: ManagerOptions);
3495
3509
  protected send(packet: GatewayVoiceStateUpdate): void;
3510
+ resolveUser(user: PortableUser | string): Promise<User | PortableUser>;
3496
3511
  }
3497
3512
 
3498
3513
  /**
@@ -3502,6 +3517,7 @@ declare class ErisManager extends Manager {
3502
3517
  readonly client: Client$1;
3503
3518
  constructor(client: Client$1, options?: ManagerOptions);
3504
3519
  protected send(packet: GatewayVoiceStateUpdate): void;
3520
+ resolveUser(user: PortableUser | string): Promise<User$1 | PortableUser>;
3505
3521
  }
3506
3522
 
3507
3523
  /**
@@ -3511,6 +3527,7 @@ declare class DetritusManager extends Manager {
3511
3527
  readonly client: ClusterClient | ShardClient;
3512
3528
  constructor(client: ClusterClient | ShardClient, options?: ManagerOptions);
3513
3529
  protected send(packet: GatewayVoiceStateUpdate): void;
3530
+ resolveUser(user: PortableUser | string): Promise<PortableUser>;
3514
3531
  }
3515
3532
 
3516
3533
  /**
@@ -3520,6 +3537,7 @@ declare class OceanicManager extends Manager {
3520
3537
  readonly client: Client$2;
3521
3538
  constructor(client: Client$2, options?: ManagerOptions);
3522
3539
  protected send(packet: GatewayVoiceStateUpdate): void;
3540
+ resolveUser(user: PortableUser | string): Promise<User$2 | PortableUser>;
3523
3541
  }
3524
3542
 
3525
3543
  /**
@@ -3548,10 +3566,11 @@ declare class OceanicManager extends Manager {
3548
3566
  * ```
3549
3567
  */
3550
3568
  declare class SeyfertManager extends Manager {
3551
- readonly client: Client$3;
3552
- constructor(client: Client$3, options?: ManagerOptions);
3569
+ readonly client: Client$3 | WorkerClient;
3570
+ constructor(client: Client$3 | WorkerClient, options?: ManagerOptions);
3553
3571
  protected send(packet: GatewayVoiceStateUpdate): void;
3572
+ resolveUser(user: PortableUser | string): Promise<User$3 | PortableUser>;
3554
3573
  }
3555
3574
 
3556
3575
  export { AutoPlayPlatform, AutoPlayUtils, AvailableFilters, DetritusManager, DiscordJSManager, ErisManager, Filters, JsonQueue, LoadTypes, Manager, ManagerEventTypes, MemoryQueue, Node, OceanicManager, Player, PlayerStateEventTypes, PlayerUtils, Plugin, RedisQueue, Rest, SearchPlatform, SeverityTypes, SeyfertManager, SponsorBlockSegment, StateStorageType, StateTypes, Structure, TrackEndReasonTypes, TrackPartial, TrackSourceTypes, TrackUtils, UseNodeOptions };
3557
- export type { AlbumSearchResult, 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, 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 };
3576
+ export type { AlbumSearchResult, 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, 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 };
@@ -53,8 +53,8 @@ class JsonQueue {
53
53
  this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[JSONQUEUE] Added ${tracks.length} track(s) to queue`);
54
54
  if (this.manager.players.has(this.guildId) && this.manager.players.get(this.guildId).isAutoplay) {
55
55
  if (!isArray) {
56
- const botUser = (await this.manager.players.get(this.guildId).get("Internal_BotUser"));
57
- if (botUser && botUser.id === track.requester.id) {
56
+ const AutoplayUser = (await this.manager.players.get(this.guildId).get("Internal_AutoplayUser"));
57
+ if (AutoplayUser && AutoplayUser.id === track.requester.id) {
58
58
  this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
59
59
  changeType: Enums_1.PlayerStateEventTypes.QueueChange,
60
60
  details: {
@@ -81,8 +81,8 @@ class MemoryQueue extends Array {
81
81
  }
82
82
  if (this.manager.players.has(this.guildId) && this.manager.players.get(this.guildId).isAutoplay) {
83
83
  if (!isArray) {
84
- const botUser = this.manager.players.get(this.guildId).get("Internal_BotUser");
85
- if (botUser && botUser.id === track.requester.id) {
84
+ const AutoplayUser = this.manager.players.get(this.guildId).get("Internal_AutoplayUser");
85
+ if (AutoplayUser && AutoplayUser.id === track.requester.id) {
86
86
  this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
87
87
  changeType: Enums_1.PlayerStateEventTypes.QueueChange,
88
88
  details: {
@@ -61,8 +61,8 @@ class RedisQueue {
61
61
  this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] Added ${tracks.length} track(s) to queue`);
62
62
  if (this.manager.players.has(this.guildId) && this.manager.players.get(this.guildId).isAutoplay) {
63
63
  if (!Array.isArray(track)) {
64
- const botUser = (await this.manager.players.get(this.guildId).get("Internal_BotUser"));
65
- if (botUser && botUser.id === track.requester.id) {
64
+ const AutoplayUser = (await this.manager.players.get(this.guildId).get("Internal_AutoplayUser"));
65
+ if (AutoplayUser && AutoplayUser.id === track.requester.id) {
66
66
  this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
67
67
  changeType: Enums_1.PlayerStateEventTypes.QueueChange,
68
68
  details: {
@@ -63,6 +63,7 @@ var LoadTypes;
63
63
  var SearchPlatform;
64
64
  (function (SearchPlatform) {
65
65
  SearchPlatform["AppleMusic"] = "amsearch";
66
+ SearchPlatform["Audius"] = "audsearch";
66
67
  SearchPlatform["Bandcamp"] = "bcsearch";
67
68
  SearchPlatform["Deezer"] = "dzsearch";
68
69
  SearchPlatform["Jiosaavn"] = "jssearch";
@@ -97,6 +98,7 @@ var PlayerStateEventTypes;
97
98
  var TrackSourceTypes;
98
99
  (function (TrackSourceTypes) {
99
100
  TrackSourceTypes["AppleMusic"] = "applemusic";
101
+ TrackSourceTypes["Audius"] = "audius";
100
102
  TrackSourceTypes["Bandcamp"] = "bandcamp";
101
103
  TrackSourceTypes["Deezer"] = "deezer";
102
104
  TrackSourceTypes["Jiosaavn"] = "jiosaavn";
@@ -180,22 +180,26 @@ class Manager extends events_1.EventEmitter {
180
180
  throw new Error("No available nodes.");
181
181
  const _query = typeof query === "string" ? { query } : query;
182
182
  const _source = _query.source ?? this.options.defaultSearchPlatform;
183
- let search = /^https?:\/\//.test(_query.query) ? _query.query : `${_source}:${_query.query}`;
184
- this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Performing ${_source} search for: ${_query.query}`);
183
+ const isUrl = /^https?:\/\//.test(_query.query);
184
+ const search = isUrl ? _query.query : `${_source}:${_query.query}`;
185
+ this.emit(Enums_1.ManagerEventTypes.Debug, isUrl ? `[MANAGER] Performing search for: ${_query.query}` : `[MANAGER] Performing ${_source} search for: ${_query.query}`);
185
186
  try {
186
187
  const res = (await node.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(search)}`));
187
188
  if (!res)
188
189
  throw new Error("Query not found.");
189
- let tracks = [];
190
- let playlist = null;
190
+ let result;
191
191
  switch (res.loadType) {
192
- case Enums_1.LoadTypes.Search:
193
- tracks = res.data.map((track) => Utils_1.TrackUtils.build(track, requester));
192
+ case Enums_1.LoadTypes.Search: {
193
+ const tracks = res.data.map((t) => Utils_1.TrackUtils.build(t, requester));
194
+ result = { loadType: res.loadType, tracks };
194
195
  break;
196
+ }
195
197
  case Enums_1.LoadTypes.Short:
196
- case Enums_1.LoadTypes.Track:
197
- tracks = [Utils_1.TrackUtils.build(res.data, requester)];
198
+ case Enums_1.LoadTypes.Track: {
199
+ const track = Utils_1.TrackUtils.build(res.data, requester);
200
+ result = { loadType: res.loadType, tracks: [track] };
198
201
  break;
202
+ }
199
203
  case Enums_1.LoadTypes.Album:
200
204
  case Enums_1.LoadTypes.Artist:
201
205
  case Enums_1.LoadTypes.Station:
@@ -203,18 +207,24 @@ class Manager extends events_1.EventEmitter {
203
207
  case Enums_1.LoadTypes.Show:
204
208
  case Enums_1.LoadTypes.Playlist: {
205
209
  const playlistData = res.data;
206
- tracks = playlistData.tracks.map((track) => Utils_1.TrackUtils.build(track, requester));
207
- playlist = {
208
- name: playlistData.info.name,
209
- playlistInfo: playlistData.pluginInfo,
210
- requester: requester,
210
+ const tracks = playlistData.tracks.map((t) => Utils_1.TrackUtils.build(t, requester));
211
+ result = {
212
+ loadType: res.loadType,
211
213
  tracks,
212
- duration: tracks.reduce((acc, cur) => acc + (cur.duration || 0), 0),
214
+ playlist: {
215
+ name: playlistData.info.name,
216
+ playlistInfo: playlistData.pluginInfo,
217
+ requester: requester,
218
+ tracks,
219
+ duration: tracks.reduce((acc, cur) => acc + (cur.duration || 0), 0),
220
+ },
213
221
  };
214
222
  break;
215
223
  }
224
+ default:
225
+ result = { loadType: res.loadType };
216
226
  }
217
- if (this.options.normalizeYouTubeTitles) {
227
+ if (this.options.normalizeYouTubeTitles && "tracks" in result) {
218
228
  const processTrack = (track) => {
219
229
  if (!/(youtube\.com|youtu\.be)/.test(track.uri))
220
230
  return track;
@@ -223,34 +233,15 @@ class Manager extends events_1.EventEmitter {
223
233
  track.author = cleanAuthor;
224
234
  return track;
225
235
  };
226
- if (playlist) {
227
- playlist.tracks = playlist.tracks.map(processTrack);
228
- }
229
- else {
230
- tracks = tracks.map(processTrack);
236
+ result.tracks = result.tracks.map(processTrack);
237
+ if ("playlist" in result && result.playlist) {
238
+ result.playlist.tracks = result.playlist.tracks.map(processTrack);
231
239
  }
232
240
  }
233
- let result;
234
- switch (res.loadType) {
235
- case Enums_1.LoadTypes.Album:
236
- case Enums_1.LoadTypes.Artist:
237
- case Enums_1.LoadTypes.Station:
238
- case Enums_1.LoadTypes.Podcast:
239
- case Enums_1.LoadTypes.Show:
240
- case Enums_1.LoadTypes.Playlist:
241
- result = { loadType: res.loadType, tracks, playlist };
242
- break;
243
- case Enums_1.LoadTypes.Search:
244
- result = { loadType: res.loadType, tracks };
245
- break;
246
- case Enums_1.LoadTypes.Short:
247
- case Enums_1.LoadTypes.Track:
248
- result = { loadType: res.loadType, tracks: [tracks[0]] };
249
- break;
250
- default:
251
- return { loadType: res.loadType };
252
- }
253
- this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Result ${_source} search for: ${_query.query}: ${JSON.stringify(result)}`);
241
+ const summary = "tracks" in result
242
+ ? result.tracks.map((t) => Object.fromEntries(Object.entries(t).filter(([key]) => key !== "requester")))
243
+ : [];
244
+ this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Result search for ${_query.query}: ${JSON.stringify(summary, null, 2)}`);
254
245
  return result;
255
246
  }
256
247
  catch (err) {
@@ -514,8 +505,11 @@ class Manager extends events_1.EventEmitter {
514
505
  const currentTrack = state.queue.current;
515
506
  const queueTracks = state.queue.tracks;
516
507
  if (state.isAutoplay) {
517
- Object.setPrototypeOf(state.data.clientUser, { constructor: { name: "User" } });
518
- player.setAutoplay(true, state.data.clientUser, state.autoplayTries);
508
+ const savedUser = state.data.clientUser;
509
+ if (savedUser) {
510
+ const autoPlayUser = await player.manager.resolveUser(savedUser);
511
+ player.setAutoplay(true, autoPlayUser, state.autoplayTries);
512
+ }
519
513
  }
520
514
  if (lavaPlayer?.track) {
521
515
  tracks.push(...queueTracks);
@@ -705,8 +699,11 @@ class Manager extends events_1.EventEmitter {
705
699
  const currentTrack = state.queue.current;
706
700
  const queueTracks = state.queue.tracks;
707
701
  if (state.isAutoplay) {
708
- Object.setPrototypeOf(state.data.clientUser, { constructor: { name: "User" } });
709
- player.setAutoplay(true, state.data.clientUser, state.autoplayTries);
702
+ const savedUser = state.data.clientUser;
703
+ if (savedUser) {
704
+ const autoPlayUser = await player.manager.resolveUser(savedUser);
705
+ player.setAutoplay(true, autoPlayUser, state.autoplayTries);
706
+ }
710
707
  }
711
708
  if (lavaPlayer?.track) {
712
709
  // If lavaPlayer has a track, push all queue tracks
@@ -1310,5 +1307,16 @@ class Manager extends events_1.EventEmitter {
1310
1307
  sendPacket(packet) {
1311
1308
  return this.send(packet);
1312
1309
  }
1310
+ /**
1311
+ * Resolves a PortableUser or ID to a real user object.
1312
+ * Can be overridden by wrapper managers to return wrapper-specific User classes.
1313
+ */
1314
+ async resolveUser(user) {
1315
+ if (!user)
1316
+ return null;
1317
+ if (typeof user === "string")
1318
+ return { id: user }; // fallback by ID only
1319
+ return user; // default: just return the portable user
1320
+ }
1313
1321
  }
1314
1322
  exports.Manager = Manager;
@@ -378,7 +378,7 @@ class Node {
378
378
  this.socket?.removeAllListeners();
379
379
  this.socket = null;
380
380
  this.manager.emit(Enums_1.ManagerEventTypes.NodeReconnect, this);
381
- this.connect();
381
+ await this.connect();
382
382
  this.reconnectAttempts++;
383
383
  }, this.options.retryDelayMs);
384
384
  }
@@ -601,8 +601,8 @@ class Node {
601
601
  player.playing = true;
602
602
  player.paused = false;
603
603
  this.manager.emit(Enums_1.ManagerEventTypes.TrackStart, player, track, payload);
604
- const botUser = player.get("Internal_BotUser");
605
- if (botUser && botUser.id === track.requester.id) {
604
+ const AutoplayUser = player.get("Internal_AutoplayUser");
605
+ if (AutoplayUser && AutoplayUser.id === track.requester.id) {
606
606
  this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, player, {
607
607
  changeType: Enums_1.PlayerStateEventTypes.TrackChange,
608
608
  details: {
@@ -702,7 +702,7 @@ class Node {
702
702
  return false;
703
703
  const PreviousQueue = await player.queue.getPrevious();
704
704
  const lastTrack = PreviousQueue?.at(-1);
705
- lastTrack.requester = player.get("Internal_BotUser");
705
+ lastTrack.requester = player.get("Internal_AutoplayUser");
706
706
  if (!lastTrack)
707
707
  return false;
708
708
  const tracks = await Utils_1.AutoPlayUtils.getRecommendedTracks(lastTrack);
@@ -355,30 +355,27 @@ class Player {
355
355
  * track when the current track ends.
356
356
  *
357
357
  * @param {boolean} autoplayState - Whether or not autoplay should be enabled.
358
- * @param {object} botUser - The user-object that should be used as the bot-user.
358
+ * @param {object} AutoplayUser - The user-object that should be used as the bot-user.
359
359
  * @param {number} [tries=3] - The number of times the player should try to find a
360
360
  * recommended track if the first one doesn't work.
361
361
  * @returns {this} - The player instance.
362
362
  */
363
- setAutoplay(autoplayState, botUser, tries) {
363
+ setAutoplay(autoplayState, AutoplayUser, tries) {
364
364
  if (typeof autoplayState !== "boolean") {
365
365
  throw new Error("autoplayState must be a boolean.");
366
366
  }
367
367
  if (autoplayState) {
368
- if (!botUser) {
369
- throw new Error("botUser must be provided when enabling autoplay.");
370
- }
371
- if (!["ClientUser", "User"].includes(botUser.constructor.name)) {
372
- throw new Error("botUser must be a user-object.");
368
+ if (!AutoplayUser) {
369
+ throw new Error("AutoplayUser must be provided when enabling autoplay.");
373
370
  }
374
371
  this.autoplayTries = tries && typeof tries === "number" && tries > 0 ? tries : 3; // Default to 3 if invalid
375
372
  this.isAutoplay = true;
376
- this.set("Internal_BotUser", botUser);
373
+ this.set("Internal_AutoplayUser", AutoplayUser);
377
374
  }
378
375
  else {
379
376
  this.isAutoplay = false;
380
377
  this.autoplayTries = null;
381
- this.set("Internal_BotUser", null);
378
+ this.set("Internal_AutoplayUser", null);
382
379
  }
383
380
  const oldPlayer = { ...this };
384
381
  this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this, {
@@ -852,7 +849,7 @@ class Player {
852
849
  queueRepeat: this.queueRepeat,
853
850
  dynamicRepeat: this.dynamicRepeat,
854
851
  dynamicRepeatIntervalMs: this.dynamicRepeatIntervalMs,
855
- ClientUser: this.get("Internal_BotUser"),
852
+ ClientUser: this.get("Internal_AutoplayUser"),
856
853
  filters: this.filters,
857
854
  nowPlayingMessage: this.nowPlayingMessage,
858
855
  isAutoplay: this.isAutoplay,
@@ -889,7 +886,7 @@ class Player {
889
886
  clonedPlayer.queueRepeat = oldPlayerProperties.queueRepeat;
890
887
  clonedPlayer.dynamicRepeat = oldPlayerProperties.dynamicRepeat;
891
888
  clonedPlayer.dynamicRepeatIntervalMs = oldPlayerProperties.dynamicRepeatIntervalMs;
892
- clonedPlayer.set("Internal_BotUser", oldPlayerProperties.ClientUser);
889
+ clonedPlayer.set("Internal_AutoplayUser", oldPlayerProperties.ClientUser);
893
890
  clonedPlayer.paused = oldPlayerProperties.paused;
894
891
  // Update filters for the cloned player
895
892
  await clonedPlayer.filters.updateFilters();
@@ -117,7 +117,7 @@ class Rest {
117
117
  }
118
118
  else if (error.response.status === 404) {
119
119
  await this.node.destroy();
120
- this.node.manager.createNode(this.node.options).connect();
120
+ await this.node.manager.createNode(this.node.options).connect();
121
121
  }
122
122
  return null;
123
123
  }
@@ -87,6 +87,7 @@ class TrackUtils {
87
87
  try {
88
88
  const sourceNameMap = {
89
89
  applemusic: "AppleMusic",
90
+ audius: "Audius",
90
91
  bandcamp: "Bandcamp",
91
92
  deezer: "Deezer",
92
93
  jiosaavn: "Jiosaavn",
@@ -95,6 +96,7 @@ class TrackUtils {
95
96
  tidal: "Tidal",
96
97
  youtube: "YouTube",
97
98
  vkmusic: "VKMusic",
99
+ qobuz: "Qobuz",
98
100
  };
99
101
  const track = {
100
102
  track: data.encoded,
@@ -645,8 +647,11 @@ class PlayerUtils {
645
647
  };
646
648
  }
647
649
  if (key === "data") {
650
+ const AutoplayUser = value?.Internal_AutoplayUser;
651
+ const serializedUser = AutoplayUser ? { id: AutoplayUser.id, username: AutoplayUser.username } : null;
648
652
  return {
649
- clientUser: value?.Internal_BotUser ?? null,
653
+ clientUser: serializedUser,
654
+ autoplayTries: value?.autoplayTries ?? null,
650
655
  };
651
656
  }
652
657
  return serialize(value);
@@ -32,5 +32,21 @@ class DetritusManager extends Manager_1.Manager {
32
32
  shard.gateway.send(packet.op, packet.d);
33
33
  }
34
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
+ }
35
51
  }
36
52
  exports.DetritusManager = DetritusManager;
@@ -4,7 +4,7 @@ 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 [major, minor] = discord_js_1.version.split(".").map(Number);
8
8
  tslib_1.__exportStar(require("../index"), exports);
9
9
  /**
10
10
  * Discord.js wrapper for Magmastream.
@@ -21,11 +21,11 @@ class DiscordJSManager extends Manager_1.Manager {
21
21
  };
22
22
  // Only attach clientReady if Discord.js >= 14.22.0
23
23
  if (major > 14 || (major === 14 && minor >= 22)) {
24
- client.once('clientReady', handler);
24
+ client.once("clientReady", handler);
25
25
  }
26
26
  // Only attach ready if Discord.js < 14.22.0
27
27
  if (major < 14 || (major === 14 && minor < 22)) {
28
- client.once('ready', handler);
28
+ client.once("ready", handler);
29
29
  }
30
30
  };
31
31
  attachReadyHandler();
@@ -38,5 +38,18 @@ class DiscordJSManager extends Manager_1.Manager {
38
38
  if (guild)
39
39
  guild.shard.send(packet);
40
40
  }
41
+ async resolveUser(user) {
42
+ const id = typeof user === "string" ? user : user.id;
43
+ const cached = this.client.users.cache.get(id);
44
+ if (cached)
45
+ return cached;
46
+ try {
47
+ const fetched = await this.client.users.fetch(id);
48
+ return fetched;
49
+ }
50
+ catch {
51
+ return { id, username: typeof user === "string" ? undefined : user.username };
52
+ }
53
+ }
41
54
  }
42
55
  exports.DiscordJSManager = DiscordJSManager;
@@ -25,5 +25,15 @@ class ErisManager extends Manager_1.Manager {
25
25
  if (guild)
26
26
  guild.shard.sendWS(packet.op, packet.d);
27
27
  }
28
+ async resolveUser(user) {
29
+ const id = typeof user === "string" ? user : user.id;
30
+ const cached = this.client.users.get(id);
31
+ if (cached)
32
+ return cached;
33
+ return {
34
+ id,
35
+ username: typeof user === "string" ? undefined : user.username,
36
+ };
37
+ }
28
38
  }
29
39
  exports.ErisManager = ErisManager;
@@ -25,5 +25,15 @@ class OceanicManager extends Manager_1.Manager {
25
25
  if (guild)
26
26
  guild.shard.send(packet.op, packet.d);
27
27
  }
28
+ async resolveUser(user) {
29
+ const id = typeof user === "string" ? user : user.id;
30
+ const cached = this.client.users.get(id);
31
+ if (cached)
32
+ return cached;
33
+ return {
34
+ id,
35
+ username: typeof user === "string" ? undefined : user.username,
36
+ };
37
+ }
28
38
  }
29
39
  exports.OceanicManager = OceanicManager;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SeyfertManager = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const Manager_1 = require("../structures/Manager");
6
+ const seyfert_1 = require("seyfert");
6
7
  const common_1 = require("seyfert/lib/common");
7
8
  tslib_1.__exportStar(require("../index"), exports);
8
9
  /**
@@ -37,7 +38,24 @@ class SeyfertManager extends Manager_1.Manager {
37
38
  this.client = client;
38
39
  }
39
40
  send(packet) {
40
- this.client.gateway.send((0, common_1.calculateShardId)(packet.d.guild_id), packet);
41
+ if (this.client instanceof seyfert_1.Client) {
42
+ this.client.gateway.send((0, common_1.calculateShardId)(packet.d.guild_id), packet);
43
+ }
44
+ else {
45
+ this.client.shards.get((0, common_1.calculateShardId)(packet.d.guild_id))?.send(true, packet);
46
+ }
47
+ }
48
+ async resolveUser(user) {
49
+ const id = typeof user === "string" ? user : user.id;
50
+ const cached = this.client.cache.users?.get(id);
51
+ if (cached)
52
+ return cached;
53
+ try {
54
+ return await this.client.users.fetch(id);
55
+ }
56
+ catch {
57
+ return { id, username: typeof user === "string" ? undefined : user.username };
58
+ }
41
59
  }
42
60
  }
43
61
  exports.SeyfertManager = SeyfertManager;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magmastream",
3
- "version": "2.9.1-dev.1",
3
+ "version": "2.9.1-dev.3",
4
4
  "description": "A user-friendly Lavalink client designed for NodeJS.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",