magmastream 2.9.0-dev.16 → 2.9.0-dev.18

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
@@ -1055,12 +1055,6 @@ declare class Manager extends EventEmitter {
1055
1055
  * @param {string} guildId - The guild ID of the player to save
1056
1056
  */
1057
1057
  savePlayerState(guildId: string): Promise<void>;
1058
- /**
1059
- * Sleeps for a specified amount of time.
1060
- * @param ms The amount of time to sleep in milliseconds.
1061
- * @returns A promise that resolves after the specified amount of time.
1062
- */
1063
- private sleep;
1064
1058
  /**
1065
1059
  * Loads player states from the JSON file.
1066
1060
  * @param nodeId The ID of the node to load player states from.
@@ -1287,7 +1281,6 @@ declare enum SearchPlatform {
1287
1281
  Bandcamp = "bcsearch",
1288
1282
  Deezer = "dzsearch",
1289
1283
  Jiosaavn = "jssearch",
1290
- Qobuz = "qbsearch",
1291
1284
  SoundCloud = "scsearch",
1292
1285
  Spotify = "spsearch",
1293
1286
  Tidal = "tdsearch",
@@ -1301,7 +1294,6 @@ declare enum AutoPlayPlatform {
1301
1294
  SoundCloud = "soundcloud",
1302
1295
  Tidal = "tidal",
1303
1296
  VKMusic = "vkmusic",
1304
- Qobuz = "qobuz",
1305
1297
  YouTube = "youtube"
1306
1298
  }
1307
1299
  declare enum PlayerStateEventTypes {
@@ -313,9 +313,8 @@ 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) {
316
+ if (!player.voiceState.sessionId && player.voiceState.event) {
317
+ if (player.state !== Utils_1.StateTypes.Disconnected) {
319
318
  await player.destroy();
320
319
  }
321
320
  return;
@@ -358,56 +357,20 @@ class Manager extends events_1.EventEmitter {
358
357
  * @param {string} guildId - The guild ID of the player to save
359
358
  */
360
359
  async savePlayerState(guildId) {
361
- switch (this.options.stateStorage.type) {
362
- case StateStorageType.Collection:
363
- {
364
- try {
365
- const playerStateFilePath = await this.getPlayerFilePath(guildId);
366
- const player = this.getPlayer(guildId);
367
- if (!player || player.state === Utils_1.StateTypes.Disconnected || !player.voiceChannelId) {
368
- console.warn(`Skipping save for inactive player: ${guildId}`);
369
- return;
370
- }
371
- const serializedPlayer = this.serializePlayer(player);
372
- await promises_1.default.writeFile(playerStateFilePath, JSON.stringify(serializedPlayer, null, 2), "utf-8");
373
- this.emit(ManagerEventTypes.Debug, `[MANAGER] Player state saved: ${guildId}`);
374
- }
375
- catch (error) {
376
- console.error(`Error saving player state for guild ${guildId}:`, error);
377
- }
378
- }
379
- break;
380
- case StateStorageType.Redis:
381
- {
382
- try {
383
- const player = this.getPlayer(guildId);
384
- if (!player || player.state === Utils_1.StateTypes.Disconnected || !player.voiceChannelId) {
385
- console.warn(`Skipping save for inactive player: ${guildId}`);
386
- return;
387
- }
388
- const serializedPlayer = this.serializePlayer(player);
389
- const redisKey = `${this.options.stateStorage.redisConfig.prefix?.endsWith(":")
390
- ? this.options.stateStorage.redisConfig.prefix
391
- : this.options.stateStorage.redisConfig.prefix ?? "magmastream:"}playerstore:${guildId}`;
392
- await this.redis.set(redisKey, JSON.stringify(serializedPlayer));
393
- this.emit(ManagerEventTypes.Debug, `[MANAGER] Player state saved to Redis: ${guildId}`);
394
- }
395
- catch (error) {
396
- console.error(`Error saving player state to Redis for guild ${guildId}:`, error);
397
- }
398
- }
399
- break;
400
- default:
360
+ try {
361
+ const playerStateFilePath = await this.getPlayerFilePath(guildId);
362
+ const player = this.getPlayer(guildId);
363
+ if (!player || player.state === Utils_1.StateTypes.Disconnected || !player.voiceChannelId) {
364
+ console.warn(`Skipping save for inactive player: ${guildId}`);
401
365
  return;
366
+ }
367
+ const serializedPlayer = this.serializePlayer(player);
368
+ await promises_1.default.writeFile(playerStateFilePath, JSON.stringify(serializedPlayer, null, 2), "utf-8");
369
+ this.emit(ManagerEventTypes.Debug, `[MANAGER] Player state saved: ${guildId}`);
370
+ }
371
+ catch (error) {
372
+ console.error(`Error saving player state for guild ${guildId}:`, error);
402
373
  }
403
- }
404
- /**
405
- * Sleeps for a specified amount of time.
406
- * @param ms The amount of time to sleep in milliseconds.
407
- * @returns A promise that resolves after the specified amount of time.
408
- */
409
- async sleep(ms) {
410
- return new Promise((resolve) => setTimeout(resolve, ms));
411
374
  }
412
375
  /**
413
376
  * Loads player states from the JSON file.
@@ -420,332 +383,169 @@ class Manager extends events_1.EventEmitter {
420
383
  if (!node)
421
384
  throw new Error(`Could not find node: ${nodeId}`);
422
385
  const info = (await node.rest.getAllPlayers());
423
- switch (this.options.stateStorage.type) {
424
- case StateStorageType.Collection:
425
- {
426
- const playerStatesDir = path_1.default.join(process.cwd(), "magmastream", "dist", "sessionData", "players");
427
- try {
428
- // Check if the directory exists, and create it if it doesn't
429
- await promises_1.default.access(playerStatesDir).catch(async () => {
430
- await promises_1.default.mkdir(playerStatesDir, { recursive: true });
431
- this.emit(ManagerEventTypes.Debug, `[MANAGER] Created directory: ${playerStatesDir}`);
386
+ const playerStatesDir = path_1.default.join(process.cwd(), "magmastream", "dist", "sessionData", "players");
387
+ try {
388
+ // Check if the directory exists, and create it if it doesn't
389
+ await promises_1.default.access(playerStatesDir).catch(async () => {
390
+ await promises_1.default.mkdir(playerStatesDir, { recursive: true });
391
+ this.emit(ManagerEventTypes.Debug, `[MANAGER] Created directory: ${playerStatesDir}`);
392
+ });
393
+ // Read the contents of the directory
394
+ const playerFiles = await promises_1.default.readdir(playerStatesDir);
395
+ // Process each file in the directory
396
+ for (const file of playerFiles) {
397
+ const filePath = path_1.default.join(playerStatesDir, file);
398
+ try {
399
+ // Check if the file exists (though readdir should only return valid files)
400
+ await promises_1.default.access(filePath);
401
+ // Read the file asynchronously
402
+ const data = await promises_1.default.readFile(filePath, "utf-8");
403
+ const state = JSON.parse(data);
404
+ if (state && typeof state === "object" && state.guildId && state.node.options.identifier === nodeId) {
405
+ const lavaPlayer = info.find((player) => player.guildId === state.guildId);
406
+ if (!lavaPlayer) {
407
+ await this.destroy(state.guildId);
408
+ }
409
+ const playerOptions = {
410
+ guildId: state.options.guildId,
411
+ textChannelId: state.options.textChannelId,
412
+ voiceChannelId: state.options.voiceChannelId,
413
+ selfDeafen: state.options.selfDeafen,
414
+ volume: lavaPlayer.volume || state.options.volume,
415
+ node: nodeId,
416
+ };
417
+ this.emit(ManagerEventTypes.Debug, `[MANAGER] Recreating player: ${state.guildId} from saved file: ${JSON.stringify(state.options)}`);
418
+ const player = this.create(playerOptions);
419
+ await player.node.rest.updatePlayer({
420
+ guildId: state.options.guildId,
421
+ data: { voice: { token: state.voiceState.event.token, endpoint: state.voiceState.event.endpoint, sessionId: state.voiceState.sessionId } },
432
422
  });
433
- // Read the contents of the directory
434
- const playerFiles = await promises_1.default.readdir(playerStatesDir);
435
- // Process each file in the directory
436
- for (const file of playerFiles) {
437
- const filePath = path_1.default.join(playerStatesDir, file);
438
- try {
439
- // Check if the file exists (though readdir should only return valid files)
440
- await promises_1.default.access(filePath); // Check if the file exists
441
- const data = await promises_1.default.readFile(filePath, "utf-8");
442
- const state = JSON.parse(data);
443
- if (state && typeof state === "object" && state.guildId && state.node.options.identifier === nodeId) {
444
- const lavaPlayer = info.find((player) => player.guildId === state.guildId);
445
- if (!lavaPlayer) {
446
- await this.destroy(state.guildId);
447
- }
448
- const playerOptions = {
449
- guildId: state.options.guildId,
450
- textChannelId: state.options.textChannelId,
451
- voiceChannelId: state.options.voiceChannelId,
452
- selfDeafen: state.options.selfDeafen,
453
- volume: lavaPlayer.volume || state.options.volume,
454
- node: nodeId,
455
- };
456
- this.emit(ManagerEventTypes.Debug, `[MANAGER] Recreating player: ${state.guildId} from saved file: ${JSON.stringify(state.options)}`);
457
- const player = this.create(playerOptions);
458
- await player.node.rest.updatePlayer({
459
- guildId: state.options.guildId,
460
- data: { voice: { token: state.voiceState.event.token, endpoint: state.voiceState.event.endpoint, sessionId: state.voiceState.sessionId } },
461
- });
462
- player.connect();
463
- const tracks = [];
464
- const currentTrack = state.queue.current;
465
- const queueTracks = state.queue.tracks;
466
- if (lavaPlayer) {
467
- if (lavaPlayer.track) {
468
- tracks.push(...queueTracks);
469
- if (currentTrack && currentTrack.uri === lavaPlayer.track.info.uri) {
470
- await player.queue.setCurrent(Utils_1.TrackUtils.build(lavaPlayer.track, currentTrack.requester));
471
- }
472
- }
473
- else {
474
- if (!currentTrack) {
475
- const payload = {
476
- reason: Utils_1.TrackEndReasonTypes.Finished,
477
- };
478
- await node.queueEnd(player, currentTrack, payload);
479
- }
480
- else {
481
- tracks.push(currentTrack, ...queueTracks);
482
- }
483
- }
484
- }
485
- else {
486
- if (!currentTrack) {
487
- const payload = {
488
- reason: Utils_1.TrackEndReasonTypes.Finished,
489
- };
490
- await node.queueEnd(player, currentTrack, payload);
491
- }
492
- else {
493
- tracks.push(currentTrack, ...queueTracks);
494
- }
495
- }
496
- if (tracks.length > 0) {
497
- await player.queue.add(tracks);
498
- }
499
- if (state.queue.previous.length > 0) {
500
- await player.queue.addPrevious(state.queue.previous);
501
- }
502
- else {
503
- await player.queue.clearPrevious();
504
- }
505
- if (state.paused) {
506
- await player.pause(true);
507
- }
508
- else {
509
- player.paused = false;
510
- }
511
- if (state.trackRepeat)
512
- player.setTrackRepeat(true);
513
- if (state.queueRepeat)
514
- player.setQueueRepeat(true);
515
- if (state.dynamicRepeat) {
516
- player.setDynamicRepeat(state.dynamicRepeat, state.dynamicLoopInterval._idleTimeout);
517
- }
518
- if (state.isAutoplay) {
519
- Object.setPrototypeOf(state.data.clientUser, { constructor: { name: "User" } });
520
- player.setAutoplay(true, state.data.clientUser, state.autoplayTries);
521
- }
522
- if (state.data) {
523
- for (const [name, value] of Object.entries(state.data)) {
524
- player.set(name, value);
525
- }
526
- }
527
- const filterActions = {
528
- bassboost: () => player.filters.bassBoost(state.filters.bassBoostlevel),
529
- distort: (enabled) => player.filters.distort(enabled),
530
- setDistortion: () => player.filters.setDistortion(state.filters.distortion),
531
- eightD: (enabled) => player.filters.eightD(enabled),
532
- setKaraoke: () => player.filters.setKaraoke(state.filters.karaoke),
533
- nightcore: (enabled) => player.filters.nightcore(enabled),
534
- slowmo: (enabled) => player.filters.slowmo(enabled),
535
- soft: (enabled) => player.filters.soft(enabled),
536
- trebleBass: (enabled) => player.filters.trebleBass(enabled),
537
- setTimescale: () => player.filters.setTimescale(state.filters.timescale),
538
- tv: (enabled) => player.filters.tv(enabled),
539
- vibrato: () => player.filters.setVibrato(state.filters.vibrato),
540
- vaporwave: (enabled) => player.filters.vaporwave(enabled),
541
- pop: (enabled) => player.filters.pop(enabled),
542
- party: (enabled) => player.filters.party(enabled),
543
- earrape: (enabled) => player.filters.earrape(enabled),
544
- electronic: (enabled) => player.filters.electronic(enabled),
545
- radio: (enabled) => player.filters.radio(enabled),
546
- setRotation: () => player.filters.setRotation(state.filters.rotation),
547
- tremolo: (enabled) => player.filters.tremolo(enabled),
548
- china: (enabled) => player.filters.china(enabled),
549
- chipmunk: (enabled) => player.filters.chipmunk(enabled),
550
- darthvader: (enabled) => player.filters.darthvader(enabled),
551
- daycore: (enabled) => player.filters.daycore(enabled),
552
- doubletime: (enabled) => player.filters.doubletime(enabled),
553
- demon: (enabled) => player.filters.demon(enabled),
554
- };
555
- // Iterate through filterStatus and apply the enabled filters
556
- for (const [filter, isEnabled] of Object.entries(state.filters.filterStatus)) {
557
- if (isEnabled && filterActions[filter]) {
558
- filterActions[filter](true);
559
- }
560
- }
561
- await this.sleep(1000);
423
+ player.connect();
424
+ const tracks = [];
425
+ const currentTrack = state.queue.current;
426
+ const queueTracks = state.queue.tracks;
427
+ if (lavaPlayer) {
428
+ if (lavaPlayer.track) {
429
+ tracks.push(...queueTracks);
430
+ if (currentTrack && currentTrack.uri === lavaPlayer.track.info.uri) {
431
+ await player.queue.setCurrent(Utils_1.TrackUtils.build(lavaPlayer.track, currentTrack.requester));
562
432
  }
563
433
  }
564
- catch (error) {
565
- this.emit(ManagerEventTypes.Debug, `[MANAGER] Error processing file ${filePath}: ${error}`);
566
- continue; // Skip to the next file if there's an error
434
+ else {
435
+ if (!currentTrack) {
436
+ const payload = {
437
+ reason: Utils_1.TrackEndReasonTypes.Finished,
438
+ };
439
+ await node.queueEnd(player, currentTrack, payload);
440
+ }
441
+ else {
442
+ tracks.push(currentTrack, ...queueTracks);
443
+ }
567
444
  }
568
445
  }
569
- // Delete all files inside playerStatesDir where nodeId matches
570
- for (const file of playerFiles) {
571
- const filePath = path_1.default.join(playerStatesDir, file);
572
- try {
573
- await promises_1.default.access(filePath); // Check if the file exists
574
- const data = await promises_1.default.readFile(filePath, "utf-8");
575
- const state = JSON.parse(data);
576
- if (state && typeof state === "object" && state.node.options.identifier === nodeId) {
577
- await promises_1.default.unlink(filePath); // Delete the file asynchronously
578
- this.emit(ManagerEventTypes.Debug, `[MANAGER] Deleted player state file: ${filePath}`);
579
- }
446
+ else {
447
+ if (!currentTrack) {
448
+ const payload = {
449
+ reason: Utils_1.TrackEndReasonTypes.Finished,
450
+ };
451
+ await node.queueEnd(player, currentTrack, payload);
580
452
  }
581
- catch (error) {
582
- this.emit(ManagerEventTypes.Debug, `[MANAGER] Error deleting file ${filePath}: ${error}`);
583
- continue; // Skip to the next file if there's an error
453
+ else {
454
+ tracks.push(currentTrack, ...queueTracks);
584
455
  }
585
456
  }
586
- }
587
- catch (error) {
588
- this.emit(ManagerEventTypes.Debug, `[MANAGER] Error loading player states: ${error}`);
589
- }
590
- }
591
- break;
592
- case StateStorageType.Redis:
593
- {
594
- try {
595
- // Get all keys matching our pattern
596
- const redisKeyPattern = `${this.options.stateStorage.redisConfig.prefix?.endsWith(":")
597
- ? this.options.stateStorage.redisConfig.prefix
598
- : this.options.stateStorage.redisConfig.prefix ?? "magmastream:"}playerstore:*`;
599
- const keys = await this.redis.keys(redisKeyPattern);
600
- for (const key of keys) {
601
- try {
602
- const data = await this.redis.get(key);
603
- if (!data)
604
- continue;
605
- const state = JSON.parse(data);
606
- if (!state || typeof state !== "object")
607
- continue;
608
- const guildId = key.split(":").pop();
609
- if (!guildId)
610
- continue;
611
- if (state.node?.options?.identifier === nodeId) {
612
- const lavaPlayer = info.find((player) => player.guildId === guildId);
613
- if (!lavaPlayer) {
614
- await this.destroy(guildId);
615
- }
616
- const playerOptions = {
617
- guildId: state.options.guildId,
618
- textChannelId: state.options.textChannelId,
619
- voiceChannelId: state.options.voiceChannelId,
620
- selfDeafen: state.options.selfDeafen,
621
- volume: lavaPlayer?.volume || state.options.volume,
622
- node: nodeId,
623
- };
624
- this.emit(ManagerEventTypes.Debug, `[MANAGER] Recreating player: ${guildId} from Redis`);
625
- const player = this.create(playerOptions);
626
- await player.node.rest.updatePlayer({
627
- guildId: state.options.guildId,
628
- data: { voice: { token: state.voiceState.event.token, endpoint: state.voiceState.event.endpoint, sessionId: state.voiceState.sessionId } },
629
- });
630
- player.connect();
631
- // Rest of the player state restoration code (tracks, filters, etc.)
632
- const tracks = [];
633
- const currentTrack = state.queue.current;
634
- const queueTracks = state.queue.tracks;
635
- if (lavaPlayer) {
636
- if (lavaPlayer.track) {
637
- tracks.push(...queueTracks);
638
- if (currentTrack && currentTrack.uri === lavaPlayer.track.info.uri) {
639
- await player.queue.setCurrent(Utils_1.TrackUtils.build(lavaPlayer.track, currentTrack.requester));
640
- }
641
- }
642
- else {
643
- if (!currentTrack) {
644
- const payload = {
645
- reason: Utils_1.TrackEndReasonTypes.Finished,
646
- };
647
- await node.queueEnd(player, currentTrack, payload);
648
- }
649
- else {
650
- tracks.push(currentTrack, ...queueTracks);
651
- }
652
- }
653
- }
654
- else {
655
- if (!currentTrack) {
656
- const payload = {
657
- reason: Utils_1.TrackEndReasonTypes.Finished,
658
- };
659
- await node.queueEnd(player, currentTrack, payload);
660
- }
661
- else {
662
- tracks.push(currentTrack, ...queueTracks);
663
- }
664
- }
665
- if (tracks.length > 0) {
666
- await player.queue.add(tracks);
667
- }
668
- if (state.queue.previous.length > 0) {
669
- await player.queue.addPrevious(state.queue.previous);
670
- }
671
- else {
672
- await player.queue.clearPrevious();
673
- }
674
- if (state.paused) {
675
- await player.pause(true);
676
- }
677
- else {
678
- player.paused = false;
679
- }
680
- if (state.trackRepeat)
681
- player.setTrackRepeat(true);
682
- if (state.queueRepeat)
683
- player.setQueueRepeat(true);
684
- if (state.dynamicRepeat) {
685
- player.setDynamicRepeat(state.dynamicRepeat, state.dynamicLoopInterval._idleTimeout);
686
- }
687
- if (state.isAutoplay) {
688
- Object.setPrototypeOf(state.data.clientUser, { constructor: { name: "User" } });
689
- player.setAutoplay(true, state.data.clientUser, state.autoplayTries);
690
- }
691
- if (state.data) {
692
- for (const [name, value] of Object.entries(state.data)) {
693
- player.set(name, value);
694
- }
695
- }
696
- const filterActions = {
697
- bassboost: () => player.filters.bassBoost(state.filters.bassBoostlevel),
698
- distort: (enabled) => player.filters.distort(enabled),
699
- setDistortion: () => player.filters.setDistortion(state.filters.distortion),
700
- eightD: (enabled) => player.filters.eightD(enabled),
701
- setKaraoke: () => player.filters.setKaraoke(state.filters.karaoke),
702
- nightcore: (enabled) => player.filters.nightcore(enabled),
703
- slowmo: (enabled) => player.filters.slowmo(enabled),
704
- soft: (enabled) => player.filters.soft(enabled),
705
- trebleBass: (enabled) => player.filters.trebleBass(enabled),
706
- setTimescale: () => player.filters.setTimescale(state.filters.timescale),
707
- tv: (enabled) => player.filters.tv(enabled),
708
- vibrato: () => player.filters.setVibrato(state.filters.vibrato),
709
- vaporwave: (enabled) => player.filters.vaporwave(enabled),
710
- pop: (enabled) => player.filters.pop(enabled),
711
- party: (enabled) => player.filters.party(enabled),
712
- earrape: (enabled) => player.filters.earrape(enabled),
713
- electronic: (enabled) => player.filters.electronic(enabled),
714
- radio: (enabled) => player.filters.radio(enabled),
715
- setRotation: () => player.filters.setRotation(state.filters.rotation),
716
- tremolo: (enabled) => player.filters.tremolo(enabled),
717
- china: (enabled) => player.filters.china(enabled),
718
- chipmunk: (enabled) => player.filters.chipmunk(enabled),
719
- darthvader: (enabled) => player.filters.darthvader(enabled),
720
- daycore: (enabled) => player.filters.daycore(enabled),
721
- doubletime: (enabled) => player.filters.doubletime(enabled),
722
- demon: (enabled) => player.filters.demon(enabled),
723
- };
724
- // Iterate through filterStatus and apply the enabled filters
725
- for (const [filter, isEnabled] of Object.entries(state.filters.filterStatus)) {
726
- if (isEnabled && filterActions[filter]) {
727
- filterActions[filter](true);
728
- }
729
- }
730
- // After processing, delete the Redis key
731
- await this.redis.del(key);
732
- this.emit(ManagerEventTypes.Debug, `[MANAGER] Deleted player state from Redis: ${key}`);
733
- await this.sleep(1000);
734
- }
457
+ if (tracks.length > 0) {
458
+ await player.queue.add(tracks);
459
+ }
460
+ if (state.queue.previous.length > 0) {
461
+ await player.queue.addPrevious(state.queue.previous);
462
+ }
463
+ else {
464
+ await player.queue.clearPrevious();
465
+ }
466
+ if (state.paused) {
467
+ await player.pause(true);
468
+ }
469
+ else {
470
+ player.paused = false;
471
+ }
472
+ if (state.trackRepeat)
473
+ player.setTrackRepeat(true);
474
+ if (state.queueRepeat)
475
+ player.setQueueRepeat(true);
476
+ if (state.dynamicRepeat) {
477
+ player.setDynamicRepeat(state.dynamicRepeat, state.dynamicLoopInterval._idleTimeout);
478
+ }
479
+ if (state.isAutoplay) {
480
+ Object.setPrototypeOf(state.data.clientUser, { constructor: { name: "User" } });
481
+ player.setAutoplay(true, state.data.clientUser, state.autoplayTries);
482
+ }
483
+ if (state.data) {
484
+ for (const [name, value] of Object.entries(state.data)) {
485
+ player.set(name, value);
735
486
  }
736
- catch (error) {
737
- this.emit(ManagerEventTypes.Debug, `[MANAGER] Error processing Redis key ${key}: ${error}`);
738
- continue;
487
+ }
488
+ const filterActions = {
489
+ bassboost: () => player.filters.bassBoost(state.filters.bassBoostlevel),
490
+ distort: (enabled) => player.filters.distort(enabled),
491
+ setDistortion: () => player.filters.setDistortion(state.filters.distortion),
492
+ eightD: (enabled) => player.filters.eightD(enabled),
493
+ setKaraoke: () => player.filters.setKaraoke(state.filters.karaoke),
494
+ nightcore: (enabled) => player.filters.nightcore(enabled),
495
+ slowmo: (enabled) => player.filters.slowmo(enabled),
496
+ soft: (enabled) => player.filters.soft(enabled),
497
+ trebleBass: (enabled) => player.filters.trebleBass(enabled),
498
+ setTimescale: () => player.filters.setTimescale(state.filters.timescale),
499
+ tv: (enabled) => player.filters.tv(enabled),
500
+ vibrato: () => player.filters.setVibrato(state.filters.vibrato),
501
+ vaporwave: (enabled) => player.filters.vaporwave(enabled),
502
+ pop: (enabled) => player.filters.pop(enabled),
503
+ party: (enabled) => player.filters.party(enabled),
504
+ earrape: (enabled) => player.filters.earrape(enabled),
505
+ electronic: (enabled) => player.filters.electronic(enabled),
506
+ radio: (enabled) => player.filters.radio(enabled),
507
+ setRotation: () => player.filters.setRotation(state.filters.rotation),
508
+ tremolo: (enabled) => player.filters.tremolo(enabled),
509
+ china: (enabled) => player.filters.china(enabled),
510
+ chipmunk: (enabled) => player.filters.chipmunk(enabled),
511
+ darthvader: (enabled) => player.filters.darthvader(enabled),
512
+ daycore: (enabled) => player.filters.daycore(enabled),
513
+ doubletime: (enabled) => player.filters.doubletime(enabled),
514
+ demon: (enabled) => player.filters.demon(enabled),
515
+ };
516
+ // Iterate through filterStatus and apply the enabled filters
517
+ for (const [filter, isEnabled] of Object.entries(state.filters.filterStatus)) {
518
+ if (isEnabled && filterActions[filter]) {
519
+ filterActions[filter](true);
739
520
  }
740
521
  }
741
522
  }
742
- catch (error) {
743
- this.emit(ManagerEventTypes.Debug, `[MANAGER] Error loading player states from Redis: ${error}`);
523
+ }
524
+ catch (error) {
525
+ this.emit(ManagerEventTypes.Debug, `[MANAGER] Error processing file ${filePath}: ${error}`);
526
+ continue; // Skip to the next file if there's an error
527
+ }
528
+ }
529
+ // Delete all files inside playerStatesDir where nodeId matches
530
+ for (const file of playerFiles) {
531
+ const filePath = path_1.default.join(playerStatesDir, file);
532
+ try {
533
+ await promises_1.default.access(filePath); // Check if the file exists
534
+ const data = await promises_1.default.readFile(filePath, "utf-8");
535
+ const state = JSON.parse(data);
536
+ if (state && typeof state === "object" && state.node.options.identifier === nodeId) {
537
+ await promises_1.default.unlink(filePath); // Delete the file asynchronously
538
+ this.emit(ManagerEventTypes.Debug, `[MANAGER] Deleted player state file: ${filePath}`);
744
539
  }
745
540
  }
746
- break;
747
- default:
748
- break;
541
+ catch (error) {
542
+ this.emit(ManagerEventTypes.Debug, `[MANAGER] Error deleting file ${filePath}: ${error}`);
543
+ continue; // Skip to the next file if there's an error
544
+ }
545
+ }
546
+ }
547
+ catch (error) {
548
+ this.emit(ManagerEventTypes.Debug, `[MANAGER] Error loading player states: ${error}`);
749
549
  }
750
550
  this.emit(ManagerEventTypes.Debug, "[MANAGER] Finished loading saved players.");
751
551
  }
@@ -996,7 +796,7 @@ class Manager extends events_1.EventEmitter {
996
796
  }
997
797
  if (key === "data") {
998
798
  return {
999
- clientUser: value?.Internal_BotUser ?? null,
799
+ clientUser: value.Internal_BotUser ?? null,
1000
800
  };
1001
801
  }
1002
802
  return serialize(value);
@@ -1145,7 +945,6 @@ var SearchPlatform;
1145
945
  SearchPlatform["Bandcamp"] = "bcsearch";
1146
946
  SearchPlatform["Deezer"] = "dzsearch";
1147
947
  SearchPlatform["Jiosaavn"] = "jssearch";
1148
- SearchPlatform["Qobuz"] = "qbsearch";
1149
948
  SearchPlatform["SoundCloud"] = "scsearch";
1150
949
  SearchPlatform["Spotify"] = "spsearch";
1151
950
  SearchPlatform["Tidal"] = "tdsearch";
@@ -1160,7 +959,6 @@ var AutoPlayPlatform;
1160
959
  AutoPlayPlatform["SoundCloud"] = "soundcloud";
1161
960
  AutoPlayPlatform["Tidal"] = "tidal";
1162
961
  AutoPlayPlatform["VKMusic"] = "vkmusic";
1163
- AutoPlayPlatform["Qobuz"] = "qobuz";
1164
962
  AutoPlayPlatform["YouTube"] = "youtube";
1165
963
  })(AutoPlayPlatform || (exports.AutoPlayPlatform = AutoPlayPlatform = {}));
1166
964
  var PlayerStateEventTypes;
@@ -350,7 +350,7 @@ class Node {
350
350
  this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[NODE] Disconnected node: ${JSON.stringify(debugInfo)}`);
351
351
  // Try moving all players connected to that node to a useable one
352
352
  if (this.manager.useableNode) {
353
- const players = this.manager.players.filter((p) => p.node.options.identifier == this.options.identifier);
353
+ const players = await this.manager.players.filter((p) => p.node.options.identifier == this.options.identifier);
354
354
  if (players.size) {
355
355
  await Promise.all(Array.from(players.values(), (player) => player.autoMoveNode()));
356
356
  }
@@ -224,27 +224,20 @@ class Player {
224
224
  */
225
225
  async destroy(disconnect = true) {
226
226
  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
227
  this.state = Utils_1.StateTypes.Destroying;
232
228
  if (disconnect) {
233
- await this.disconnect().catch((err) => {
234
- console.warn(`[Player#destroy] Failed to disconnect player ${this.guildId}:`, err);
235
- });
229
+ await this.disconnect();
236
230
  }
237
- await this.node.rest.destroyPlayer(this.guildId).catch((err) => {
238
- console.warn(`[Player#destroy] REST failed to destroy player ${this.guildId}:`, err);
239
- });
231
+ await this.node.rest.destroyPlayer(this.guildId);
240
232
  await this.queue.clear();
241
- await this.queue.clearPrevious();
242
- await this.queue.setCurrent(null);
243
233
  this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, null, {
244
234
  changeType: Manager_1.PlayerStateEventTypes.PlayerDestroy,
245
235
  });
246
236
  this.manager.emit(Manager_1.ManagerEventTypes.PlayerDestroy, this);
247
237
  const deleted = this.manager.players.delete(this.guildId);
238
+ if (!deleted) {
239
+ console.warn(`Failed to delete player with guildId: ${this.guildId}`);
240
+ }
248
241
  return deleted;
249
242
  }
250
243
  /**
@@ -603,62 +603,6 @@ class AutoPlayUtils {
603
603
  return result.tracks;
604
604
  }
605
605
  break;
606
- case "qobuz":
607
- {
608
- if (!track.uri.includes("qobuz.com")) {
609
- const res = await this.manager.search({ query: `${track.author} - ${track.title}`, source: Manager_1.SearchPlatform.Qobuz }, track.requester);
610
- if (res.loadType === LoadTypes.Empty || res.loadType === LoadTypes.Error) {
611
- return [];
612
- }
613
- if (res.loadType === LoadTypes.Playlist) {
614
- res.tracks = res.playlist.tracks;
615
- }
616
- if (!res.tracks.length) {
617
- return [];
618
- }
619
- track = res.tracks[0];
620
- }
621
- const identifier = `qbrec:${track.identifier}`;
622
- const recommendedResult = (await this.manager.useableNode.rest.get(`/v4/loadtracks?identifier=${encodeURIComponent(identifier)}`));
623
- if (!recommendedResult) {
624
- return [];
625
- }
626
- let tracks = [];
627
- let playlist = null;
628
- const requester = track.requester;
629
- switch (recommendedResult.loadType) {
630
- case LoadTypes.Search:
631
- tracks = recommendedResult.data.map((track) => TrackUtils.build(track, requester));
632
- break;
633
- case LoadTypes.Track:
634
- tracks = [TrackUtils.build(recommendedResult.data, requester)];
635
- break;
636
- case LoadTypes.Playlist: {
637
- const playlistData = recommendedResult.data;
638
- tracks = playlistData.tracks.map((track) => TrackUtils.build(track, requester));
639
- playlist = {
640
- name: playlistData.info.name,
641
- playlistInfo: playlistData.pluginInfo,
642
- requester: requester,
643
- tracks,
644
- duration: tracks.reduce((acc, cur) => acc + (cur.duration || 0), 0),
645
- };
646
- break;
647
- }
648
- }
649
- const result = { loadType: recommendedResult.loadType, tracks, playlist };
650
- if (result.loadType === LoadTypes.Empty || result.loadType === LoadTypes.Error) {
651
- return [];
652
- }
653
- if (result.loadType === LoadTypes.Playlist) {
654
- result.tracks = result.playlist.tracks;
655
- }
656
- if (!result.tracks.length) {
657
- return [];
658
- }
659
- return result.tracks;
660
- }
661
- break;
662
606
  default:
663
607
  return [];
664
608
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "magmastream",
3
- "version": "2.9.0-dev.16",
3
+ "version": "2.9.0-dev.18",
4
4
  "description": "A user-friendly Lavalink client designed for NodeJS.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -90,4 +90,4 @@
90
90
  "homepage": "https://docs.magmastream.com",
91
91
  "author": "Abel Purnwasy",
92
92
  "license": "Apache-2.0"
93
- }
93
+ }