magmastream 2.9.2-dev.1 → 2.9.2-dev.2
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 +63 -4
- package/dist/index.js +1 -0
- package/dist/statestorage/JsonQueue.js +273 -171
- package/dist/statestorage/MemoryQueue.js +260 -203
- package/dist/statestorage/RedisQueue.js +396 -203
- package/dist/structures/Enums.js +110 -1
- package/dist/structures/Filters.js +27 -13
- package/dist/structures/MagmastreamError.js +19 -0
- package/dist/structures/Manager.js +345 -219
- package/dist/structures/Node.js +222 -64
- package/dist/structures/Player.js +169 -56
- package/dist/structures/Rest.js +23 -12
- package/dist/structures/Utils.js +66 -65
- package/dist/utils/managerCheck.js +99 -21
- package/dist/utils/nodeCheck.js +59 -34
- package/dist/utils/playerCheck.js +47 -28
- package/package.json +1 -1
|
@@ -11,6 +11,7 @@ const RedisQueue_1 = require("../statestorage/RedisQueue");
|
|
|
11
11
|
const Enums_1 = require("./Enums");
|
|
12
12
|
const ws_1 = require("ws");
|
|
13
13
|
const JsonQueue_1 = require("../statestorage/JsonQueue");
|
|
14
|
+
const MagmastreamError_1 = require("./MagmastreamError");
|
|
14
15
|
class Player {
|
|
15
16
|
options;
|
|
16
17
|
/** The Queue for the Player. */
|
|
@@ -75,8 +76,12 @@ class Player {
|
|
|
75
76
|
// If the Manager is not initiated, throw an error.
|
|
76
77
|
if (!this.manager)
|
|
77
78
|
this.manager = Utils_1.Structure.get("Player")._manager;
|
|
78
|
-
if (!this.manager)
|
|
79
|
-
throw new
|
|
79
|
+
if (!this.manager) {
|
|
80
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
81
|
+
code: Enums_1.MagmaStreamErrorCode.GENERAL_INVALID_MANAGER,
|
|
82
|
+
message: "Manager instance is required.",
|
|
83
|
+
});
|
|
84
|
+
}
|
|
80
85
|
this.clusterId = this.manager.options.clusterId || 0;
|
|
81
86
|
// Check the player options for errors.
|
|
82
87
|
(0, playerCheck_1.default)(options);
|
|
@@ -102,8 +107,13 @@ class Player {
|
|
|
102
107
|
const node = this.manager.nodes.get(options.nodeIdentifier);
|
|
103
108
|
this.node = node || this.manager.useableNode;
|
|
104
109
|
// If no node is available, throw an error.
|
|
105
|
-
if (!this.node)
|
|
106
|
-
throw new
|
|
110
|
+
if (!this.node) {
|
|
111
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
112
|
+
code: Enums_1.MagmaStreamErrorCode.MANAGER_NO_NODES,
|
|
113
|
+
message: "No available nodes for the player found.",
|
|
114
|
+
context: { guildId: this.guildId },
|
|
115
|
+
});
|
|
116
|
+
}
|
|
107
117
|
// Initialize the queue with the guild ID and manager.
|
|
108
118
|
switch (this.manager.options.stateStorage.type) {
|
|
109
119
|
case Enums_1.StateStorageType.Redis:
|
|
@@ -169,7 +179,11 @@ class Player {
|
|
|
169
179
|
connect() {
|
|
170
180
|
// Check if the voice channel has been set.
|
|
171
181
|
if (!this.voiceChannelId) {
|
|
172
|
-
throw new
|
|
182
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
183
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_CONFIG,
|
|
184
|
+
message: "No voice channel has been set. You must set the voice channel before connecting.",
|
|
185
|
+
context: { voiceChannelId: this.voiceChannelId },
|
|
186
|
+
});
|
|
173
187
|
}
|
|
174
188
|
// Set the player state to connecting.
|
|
175
189
|
this.state = Enums_1.StateTypes.Connecting;
|
|
@@ -268,8 +282,12 @@ class Player {
|
|
|
268
282
|
*/
|
|
269
283
|
setVoiceChannelId(channel) {
|
|
270
284
|
// Validate the channel parameter
|
|
271
|
-
if (typeof channel !== "string")
|
|
272
|
-
throw new
|
|
285
|
+
if (typeof channel !== "string") {
|
|
286
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
287
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_CONFIG,
|
|
288
|
+
message: "Channel must be a non-empty string.",
|
|
289
|
+
});
|
|
290
|
+
}
|
|
273
291
|
// Clone the current player state for comparison
|
|
274
292
|
const oldPlayer = this ? { ...this } : null;
|
|
275
293
|
// Update the player voice channel
|
|
@@ -300,8 +318,12 @@ class Player {
|
|
|
300
318
|
*/
|
|
301
319
|
setTextChannelId(channel) {
|
|
302
320
|
// Validate the channel parameter
|
|
303
|
-
if (typeof channel !== "string")
|
|
304
|
-
throw new
|
|
321
|
+
if (typeof channel !== "string") {
|
|
322
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
323
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_CONFIG,
|
|
324
|
+
message: "Channel must be a non-empty string.",
|
|
325
|
+
});
|
|
326
|
+
}
|
|
305
327
|
// Clone the current player state for comparison
|
|
306
328
|
const oldPlayer = this ? { ...this } : null;
|
|
307
329
|
// Update the text channel property
|
|
@@ -328,7 +350,10 @@ class Player {
|
|
|
328
350
|
*/
|
|
329
351
|
setNowPlayingMessage(message) {
|
|
330
352
|
if (!message) {
|
|
331
|
-
throw new
|
|
353
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
354
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_NOW_PLAYING_MESSAGE,
|
|
355
|
+
message: "You must provide the message of the now playing message.",
|
|
356
|
+
});
|
|
332
357
|
}
|
|
333
358
|
this.nowPlayingMessage = message;
|
|
334
359
|
return this.nowPlayingMessage;
|
|
@@ -337,8 +362,12 @@ class Player {
|
|
|
337
362
|
if (typeof optionsOrTrack !== "undefined" && Utils_1.TrackUtils.validate(optionsOrTrack)) {
|
|
338
363
|
await this.queue.setCurrent(optionsOrTrack);
|
|
339
364
|
}
|
|
340
|
-
if (!(await this.queue.getCurrent()))
|
|
341
|
-
throw new
|
|
365
|
+
if (!(await this.queue.getCurrent())) {
|
|
366
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
367
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_QUEUE_EMPTY,
|
|
368
|
+
message: "The queue is empty.",
|
|
369
|
+
});
|
|
370
|
+
}
|
|
342
371
|
const finalOptions = playOptions
|
|
343
372
|
? playOptions
|
|
344
373
|
: ["startTime", "endTime", "noReplace"].every((v) => Object.keys(optionsOrTrack || {}).includes(v))
|
|
@@ -369,11 +398,17 @@ class Player {
|
|
|
369
398
|
*/
|
|
370
399
|
setAutoplay(autoplayState, AutoplayUser, tries) {
|
|
371
400
|
if (typeof autoplayState !== "boolean") {
|
|
372
|
-
throw new
|
|
401
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
402
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_AUTOPLAY,
|
|
403
|
+
message: "autoplayState must be a boolean.",
|
|
404
|
+
});
|
|
373
405
|
}
|
|
374
406
|
if (autoplayState) {
|
|
375
407
|
if (!AutoplayUser) {
|
|
376
|
-
throw new
|
|
408
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
409
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_AUTOPLAY,
|
|
410
|
+
message: "AutoplayUser must be provided when enabling autoplay.",
|
|
411
|
+
});
|
|
377
412
|
}
|
|
378
413
|
this.autoplayTries = tries && typeof tries === "number" && tries > 0 ? tries : 3; // Default to 3 if invalid
|
|
379
414
|
this.isAutoplay = true;
|
|
@@ -416,16 +451,26 @@ class Player {
|
|
|
416
451
|
* player.setVolume(50);
|
|
417
452
|
*/
|
|
418
453
|
async setVolume(volume) {
|
|
419
|
-
if (isNaN(volume))
|
|
420
|
-
throw new
|
|
454
|
+
if (isNaN(volume)) {
|
|
455
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
456
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_VOLUME,
|
|
457
|
+
message: "Volume must be a number.",
|
|
458
|
+
});
|
|
459
|
+
}
|
|
421
460
|
if (this.options.applyVolumeAsFilter) {
|
|
422
461
|
if (volume < 0 || volume > 500) {
|
|
423
|
-
throw new
|
|
462
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
463
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_VOLUME,
|
|
464
|
+
message: "Volume must be between 0 and 500 when using filter mode (100 = 100%).",
|
|
465
|
+
});
|
|
424
466
|
}
|
|
425
467
|
}
|
|
426
468
|
else {
|
|
427
469
|
if (volume < 0 || volume > 1000) {
|
|
428
|
-
throw new
|
|
470
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
471
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_VOLUME,
|
|
472
|
+
message: "Volume must be between 0 and 1000.",
|
|
473
|
+
});
|
|
429
474
|
}
|
|
430
475
|
}
|
|
431
476
|
const oldVolume = this.volume;
|
|
@@ -481,8 +526,12 @@ class Player {
|
|
|
481
526
|
*/
|
|
482
527
|
setTrackRepeat(repeat) {
|
|
483
528
|
// Ensure the repeat parameter is a boolean
|
|
484
|
-
if (typeof repeat !== "boolean")
|
|
485
|
-
throw new
|
|
529
|
+
if (typeof repeat !== "boolean") {
|
|
530
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
531
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_REPEAT,
|
|
532
|
+
message: "Repeat must be a boolean.",
|
|
533
|
+
});
|
|
534
|
+
}
|
|
486
535
|
// Clone the current player state for event emission
|
|
487
536
|
const oldPlayer = this ? { ...this } : null;
|
|
488
537
|
if (repeat) {
|
|
@@ -517,8 +566,12 @@ class Player {
|
|
|
517
566
|
*/
|
|
518
567
|
setQueueRepeat(repeat) {
|
|
519
568
|
// Ensure the repeat parameter is a boolean
|
|
520
|
-
if (typeof repeat !== "boolean")
|
|
521
|
-
throw new
|
|
569
|
+
if (typeof repeat !== "boolean") {
|
|
570
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
571
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_REPEAT,
|
|
572
|
+
message: "Repeat must be a boolean.",
|
|
573
|
+
});
|
|
574
|
+
}
|
|
522
575
|
// Get the current player state
|
|
523
576
|
const oldPlayer = this ? { ...this } : null;
|
|
524
577
|
// Update the player state
|
|
@@ -555,11 +608,17 @@ class Player {
|
|
|
555
608
|
async setDynamicRepeat(repeat, ms) {
|
|
556
609
|
// Validate the repeat parameter
|
|
557
610
|
if (typeof repeat !== "boolean") {
|
|
558
|
-
throw new
|
|
611
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
612
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_REPEAT,
|
|
613
|
+
message: "Repeat must be a boolean.",
|
|
614
|
+
});
|
|
559
615
|
}
|
|
560
616
|
// Ensure the queue has more than one track for dynamic repeat
|
|
561
617
|
if ((await this.queue.size()) <= 1) {
|
|
562
|
-
throw new
|
|
618
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
619
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_REPEAT,
|
|
620
|
+
message: "The queue size must be greater than 1.",
|
|
621
|
+
});
|
|
563
622
|
}
|
|
564
623
|
// Clone the current player state for comparison
|
|
565
624
|
const oldPlayer = this ? { ...this } : null;
|
|
@@ -634,8 +693,12 @@ class Player {
|
|
|
634
693
|
const oldPlayer = { ...this };
|
|
635
694
|
let removedTracks = [];
|
|
636
695
|
if (typeof amount === "number" && amount > 1) {
|
|
637
|
-
if (amount > (await this.queue.size()))
|
|
638
|
-
throw new
|
|
696
|
+
if (amount > (await this.queue.size())) {
|
|
697
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
698
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_QUEUE_EMPTY,
|
|
699
|
+
message: "The queue size must be greater than 1.",
|
|
700
|
+
});
|
|
701
|
+
}
|
|
639
702
|
removedTracks = await this.queue.getSlice(0, amount - 1);
|
|
640
703
|
await this.queue.modifyAt(0, amount - 1);
|
|
641
704
|
}
|
|
@@ -663,8 +726,12 @@ class Player {
|
|
|
663
726
|
*/
|
|
664
727
|
async pause(pause) {
|
|
665
728
|
// Validate the pause parameter to ensure it's a boolean.
|
|
666
|
-
if (typeof pause !== "boolean")
|
|
667
|
-
throw new
|
|
729
|
+
if (typeof pause !== "boolean") {
|
|
730
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
731
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_PAUSE,
|
|
732
|
+
message: "Pause must be a boolean.",
|
|
733
|
+
});
|
|
734
|
+
}
|
|
668
735
|
// If the pause state is already as desired or there are no tracks, return early.
|
|
669
736
|
if (this.paused === pause || !this.queue.totalSize)
|
|
670
737
|
return this;
|
|
@@ -699,18 +766,20 @@ class Player {
|
|
|
699
766
|
* @emits {PlayerStateUpdate} - With {@link PlayerStateEventTypes.TrackChange} as the change type.
|
|
700
767
|
*/
|
|
701
768
|
async previous() {
|
|
702
|
-
//
|
|
769
|
+
// Pop the most recent previous track (from tail)
|
|
703
770
|
const lastTrack = await this.queue.popPrevious();
|
|
704
771
|
if (!lastTrack) {
|
|
705
772
|
await this.queue.clearPrevious();
|
|
706
|
-
throw new
|
|
773
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
774
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_PREVIOUS_EMPTY,
|
|
775
|
+
message: "Previous queue is empty.",
|
|
776
|
+
});
|
|
707
777
|
}
|
|
708
778
|
// Capture the current state of the player before making changes.
|
|
709
779
|
const oldPlayer = { ...this };
|
|
710
|
-
//
|
|
780
|
+
// Prevent re-adding the current track
|
|
711
781
|
this.set("skipFlag", true);
|
|
712
782
|
await this.play(lastTrack);
|
|
713
|
-
// Emit state update
|
|
714
783
|
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this, {
|
|
715
784
|
changeType: Enums_1.PlayerStateEventTypes.TrackChange,
|
|
716
785
|
details: {
|
|
@@ -734,7 +803,10 @@ class Player {
|
|
|
734
803
|
position = Number(position);
|
|
735
804
|
// Check if the position is valid.
|
|
736
805
|
if (isNaN(position)) {
|
|
737
|
-
throw new
|
|
806
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
807
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_SEEK,
|
|
808
|
+
message: "Position must be a number.",
|
|
809
|
+
});
|
|
738
810
|
}
|
|
739
811
|
// Get the old player state.
|
|
740
812
|
const oldPlayer = this ? { ...this } : null;
|
|
@@ -798,8 +870,14 @@ class Player {
|
|
|
798
870
|
*/
|
|
799
871
|
async moveNode(identifier) {
|
|
800
872
|
const node = this.manager.nodes.get(identifier);
|
|
801
|
-
if (!node)
|
|
802
|
-
|
|
873
|
+
if (!node) {
|
|
874
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Tried to move to non-existent node: ${identifier}`);
|
|
875
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
876
|
+
code: Enums_1.MagmaStreamErrorCode.MANAGER_NODE_NOT_FOUND,
|
|
877
|
+
message: "Node not found.",
|
|
878
|
+
context: { identifier },
|
|
879
|
+
});
|
|
880
|
+
}
|
|
803
881
|
if (this.state !== Enums_1.StateTypes.Connected) {
|
|
804
882
|
return this;
|
|
805
883
|
}
|
|
@@ -814,7 +892,12 @@ class Player {
|
|
|
814
892
|
const token = this.voiceState?.event?.token;
|
|
815
893
|
const endpoint = this.voiceState?.event?.endpoint;
|
|
816
894
|
if (!sessionId || !token || !endpoint) {
|
|
817
|
-
|
|
895
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Voice state is not properly initialized for player ${this.guildId}. The bot might not be connected to a voice channel.`);
|
|
896
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
897
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_STATE_INVALID,
|
|
898
|
+
message: `Voice state is not properly initialized. The bot might not be connected to a voice channel.`,
|
|
899
|
+
context: { guildId: this.guildId },
|
|
900
|
+
});
|
|
818
901
|
}
|
|
819
902
|
await this.node.rest.destroyPlayer(this.guildId).catch(() => { });
|
|
820
903
|
this.manager.players.delete(this.guildId);
|
|
@@ -826,8 +909,17 @@ class Player {
|
|
|
826
909
|
});
|
|
827
910
|
await this.filters.updateFilters();
|
|
828
911
|
}
|
|
829
|
-
catch (
|
|
830
|
-
|
|
912
|
+
catch (err) {
|
|
913
|
+
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
914
|
+
? err
|
|
915
|
+
: new MagmastreamError_1.MagmaStreamError({
|
|
916
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_MOVE_FAILED,
|
|
917
|
+
message: "Error moving player to node.",
|
|
918
|
+
cause: err,
|
|
919
|
+
context: { guildId: this.guildId },
|
|
920
|
+
});
|
|
921
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, error);
|
|
922
|
+
console.error(error);
|
|
831
923
|
}
|
|
832
924
|
}
|
|
833
925
|
/**
|
|
@@ -839,12 +931,24 @@ class Player {
|
|
|
839
931
|
* @returns {Promise<Player>} - The new player instance.
|
|
840
932
|
*/
|
|
841
933
|
async switchGuild(newOptions, force = false) {
|
|
842
|
-
if (!newOptions.guildId)
|
|
843
|
-
throw new
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
934
|
+
if (!newOptions.guildId) {
|
|
935
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
936
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_CONFIG,
|
|
937
|
+
message: "guildId is required for switchGuild",
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
if (!newOptions.voiceChannelId) {
|
|
941
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
942
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_CONFIG,
|
|
943
|
+
message: "voiceChannelId is required for switchGuild",
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
if (!newOptions.textChannelId) {
|
|
947
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
948
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_INVALID_CONFIG,
|
|
949
|
+
message: "textChannelId is required for switchGuild",
|
|
950
|
+
});
|
|
951
|
+
}
|
|
848
952
|
// Check if a player already exists for the new guild
|
|
849
953
|
let newPlayer = this.manager.getPlayer(newOptions.guildId);
|
|
850
954
|
// If the player already exists and force is false, return the existing player
|
|
@@ -943,14 +1047,8 @@ class Player {
|
|
|
943
1047
|
* Retrieves the current lyrics for the playing track.
|
|
944
1048
|
* @param skipTrackSource - Indicates whether to skip the track source when fetching lyrics.
|
|
945
1049
|
* @returns {Promise<Lyrics>} - The lyrics of the current track.
|
|
946
|
-
* @throws {RangeError} - If the 'lavalyrics-plugin' is not available on the Lavalink node.
|
|
947
1050
|
*/
|
|
948
1051
|
async getCurrentLyrics(skipTrackSource = false) {
|
|
949
|
-
// Check if the 'lavalyrics-plugin' is available on the node
|
|
950
|
-
const hasLyricsPlugin = this.node.info.plugins.some((plugin) => plugin.name === "lavalyrics-plugin");
|
|
951
|
-
if (!hasLyricsPlugin) {
|
|
952
|
-
throw new RangeError(`There is no lavalyrics-plugin available in the Lavalink node: ${this.node.options.identifier}`);
|
|
953
|
-
}
|
|
954
1052
|
// Fetch the lyrics for the current track from the Lavalink node
|
|
955
1053
|
let result = (await this.node.getLyrics(await this.queue.getCurrent(), skipTrackSource));
|
|
956
1054
|
// If no lyrics are found, return a default empty lyrics object
|
|
@@ -971,8 +1069,13 @@ class Player {
|
|
|
971
1069
|
* @throws {Error} - If the node is not a NodeLink.
|
|
972
1070
|
*/
|
|
973
1071
|
async setupVoiceReceiver() {
|
|
974
|
-
if (!this.node.isNodeLink)
|
|
975
|
-
throw new
|
|
1072
|
+
if (!this.node.isNodeLink) {
|
|
1073
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
1074
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PROTOCOL_ERROR,
|
|
1075
|
+
message: `The node is not a NodeLink, cannot setup voice receiver.`,
|
|
1076
|
+
context: { identifier: this.node.options.identifier },
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
976
1079
|
if (this.voiceReceiverWsClient)
|
|
977
1080
|
await this.removeVoiceReceiver();
|
|
978
1081
|
const headers = {
|
|
@@ -994,8 +1097,13 @@ class Player {
|
|
|
994
1097
|
* @throws {Error} - If the node is not a NodeLink.
|
|
995
1098
|
*/
|
|
996
1099
|
async removeVoiceReceiver() {
|
|
997
|
-
if (!this.node.isNodeLink)
|
|
998
|
-
throw new
|
|
1100
|
+
if (!this.node.isNodeLink) {
|
|
1101
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
1102
|
+
code: Enums_1.MagmaStreamErrorCode.NODE_PROTOCOL_ERROR,
|
|
1103
|
+
message: `The node is not a NodeLink, cannot remove voice receiver.`,
|
|
1104
|
+
context: { identifier: this.node.options.identifier },
|
|
1105
|
+
});
|
|
1106
|
+
}
|
|
999
1107
|
if (this.voiceReceiverWsClient) {
|
|
1000
1108
|
this.voiceReceiverWsClient.close(1000, "destroy");
|
|
1001
1109
|
this.voiceReceiverWsClient.removeAllListeners();
|
|
@@ -1021,8 +1129,13 @@ class Player {
|
|
|
1021
1129
|
*/
|
|
1022
1130
|
async reconnectVoiceReceiver() {
|
|
1023
1131
|
this.voiceReceiverReconnectTimeout = setTimeout(async () => {
|
|
1024
|
-
if (this.voiceReceiverAttempt > this.voiceReceiverReconnectTries)
|
|
1025
|
-
throw new
|
|
1132
|
+
if (this.voiceReceiverAttempt > this.voiceReceiverReconnectTries) {
|
|
1133
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
1134
|
+
code: Enums_1.MagmaStreamErrorCode.PLAYER_VOICE_RECEIVER_ERROR,
|
|
1135
|
+
message: `Failed to reconnect to voice receiver for player ${this.guildId}`,
|
|
1136
|
+
context: { identifier: this.node.options.identifier },
|
|
1137
|
+
});
|
|
1138
|
+
}
|
|
1026
1139
|
this.voiceReceiverWsClient?.removeAllListeners();
|
|
1027
1140
|
this.voiceReceiverWsClient = null;
|
|
1028
1141
|
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[PLAYER] Reconnecting to voice receiver for player ${this.guildId}`);
|
package/dist/structures/Rest.js
CHANGED
|
@@ -5,6 +5,7 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const axios_1 = tslib_1.__importDefault(require("axios"));
|
|
6
6
|
const Enums_1 = require("./Enums");
|
|
7
7
|
const Utils_1 = require("./Utils");
|
|
8
|
+
const MagmastreamError_1 = require("./MagmastreamError");
|
|
8
9
|
/** Handles the requests sent to the Lavalink REST API. */
|
|
9
10
|
class Rest {
|
|
10
11
|
/** The Node that this Rest instance is connected to. */
|
|
@@ -38,12 +39,12 @@ class Rest {
|
|
|
38
39
|
return this.sessionId;
|
|
39
40
|
}
|
|
40
41
|
/**
|
|
41
|
-
* Retrieves
|
|
42
|
+
* Retrieves one the player that is currently running on the node.
|
|
42
43
|
* @returns {Promise<unknown>} Returns the result of the GET request.
|
|
43
44
|
*/
|
|
44
|
-
async
|
|
45
|
+
async getPlayer(guildId) {
|
|
45
46
|
// Send a GET request to the Lavalink Node to retrieve all the players.
|
|
46
|
-
const result = await this.get(`/v4/sessions/${this.sessionId}/players`);
|
|
47
|
+
const result = (await this.get(`/v4/sessions/${this.sessionId}/players/${guildId}`));
|
|
47
48
|
// Log the result of the request.
|
|
48
49
|
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] Getting all players on node: ${this.node.options.identifier} : ${Utils_1.JSONUtils.safe(result, 2)}`);
|
|
49
50
|
// Return the result of the request.
|
|
@@ -93,7 +94,7 @@ class Rest {
|
|
|
93
94
|
* @returns {Promise<unknown>} The response data of the request.
|
|
94
95
|
*/
|
|
95
96
|
async request(method, endpoint, body) {
|
|
96
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] ${method}
|
|
97
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[REST] ${method} request to ${endpoint} with body: ${Utils_1.JSONUtils.safe(body, 2)}`);
|
|
97
98
|
const config = {
|
|
98
99
|
method,
|
|
99
100
|
url: this.url + endpoint,
|
|
@@ -108,19 +109,29 @@ class Rest {
|
|
|
108
109
|
const response = await (0, axios_1.default)(config);
|
|
109
110
|
return response.data;
|
|
110
111
|
}
|
|
111
|
-
catch (
|
|
112
|
+
catch (err) {
|
|
113
|
+
const error = err;
|
|
112
114
|
if (!error.response) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
116
|
+
code: Enums_1.MagmaStreamErrorCode.REST_REQUEST_FAILED,
|
|
117
|
+
message: `No response from node ${this.node.options.identifier}: ${error.message}`,
|
|
118
|
+
});
|
|
115
119
|
}
|
|
116
|
-
|
|
120
|
+
const data = error.response.data;
|
|
121
|
+
if (data?.message === "Guild not found") {
|
|
117
122
|
return [];
|
|
118
123
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
124
|
+
if (error.response.status === 401) {
|
|
125
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
126
|
+
code: Enums_1.MagmaStreamErrorCode.REST_UNAUTHORIZED,
|
|
127
|
+
message: `Unauthorized access to node ${this.node.options.identifier}`,
|
|
128
|
+
});
|
|
122
129
|
}
|
|
123
|
-
|
|
130
|
+
const dataMessage = typeof data === "string" ? data : data?.message ? data.message : Utils_1.JSONUtils.safe(data, 2);
|
|
131
|
+
throw new MagmastreamError_1.MagmaStreamError({
|
|
132
|
+
code: Enums_1.MagmaStreamErrorCode.REST_REQUEST_FAILED,
|
|
133
|
+
message: `Request to node ${this.node.options.identifier} failed with status ${error.response.status}: ${dataMessage}`,
|
|
134
|
+
});
|
|
124
135
|
}
|
|
125
136
|
}
|
|
126
137
|
/**
|