magmastream 2.9.3-dev.2 → 2.9.3-dev.20
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 +168 -101
- package/dist/index.js +1 -1
- package/dist/statestorage/JsonQueue.js +28 -4
- package/dist/statestorage/MemoryQueue.js +51 -36
- package/dist/statestorage/RedisQueue.js +30 -9
- package/dist/structures/Enums.js +6 -0
- package/dist/structures/Filters.js +5 -4
- package/dist/structures/Manager.js +62 -48
- package/dist/structures/Node.js +91 -145
- package/dist/structures/Player.js +31 -124
- package/dist/structures/Rest.js +41 -21
- package/dist/structures/Utils.js +139 -77
- package/dist/wrappers/discord.js.js +13 -4
- package/dist/wrappers/discordeno.js +73 -0
- package/dist/wrappers/eris.js +14 -3
- package/dist/wrappers/oceanic.js +16 -4
- package/dist/wrappers/seyfert.js +19 -1
- package/package.json +30 -23
- package/dist/wrappers/detritus.js +0 -52
|
@@ -16,6 +16,10 @@ class MemoryQueue extends Array {
|
|
|
16
16
|
manager;
|
|
17
17
|
/** The guild ID property. */
|
|
18
18
|
guildId;
|
|
19
|
+
/**
|
|
20
|
+
* Whether the queue has been destroyed.
|
|
21
|
+
*/
|
|
22
|
+
destroyed = false;
|
|
19
23
|
/**
|
|
20
24
|
* Constructs a new Queue.
|
|
21
25
|
* @param guildId The guild ID.
|
|
@@ -34,7 +38,7 @@ class MemoryQueue extends Array {
|
|
|
34
38
|
* @param track The track or tracks to add. Can be a single `Track` or an array of `Track`s.
|
|
35
39
|
* @param [offset=null] The position to add the track(s) at. If not provided, the track(s) will be added at the end of the queue.
|
|
36
40
|
*/
|
|
37
|
-
|
|
41
|
+
add(track, offset) {
|
|
38
42
|
try {
|
|
39
43
|
const isArray = Array.isArray(track);
|
|
40
44
|
const tracks = isArray ? [...track] : [track];
|
|
@@ -84,8 +88,7 @@ class MemoryQueue extends Array {
|
|
|
84
88
|
}
|
|
85
89
|
if (this.manager.players.has(this.guildId) && this.manager.players.get(this.guildId).isAutoplay) {
|
|
86
90
|
if (!isArray) {
|
|
87
|
-
|
|
88
|
-
if (AutoplayUser && AutoplayUser.id === track.requester.id) {
|
|
91
|
+
if (track.isAutoplay) {
|
|
89
92
|
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
90
93
|
changeType: Enums_1.PlayerStateEventTypes.QueueChange,
|
|
91
94
|
details: {
|
|
@@ -123,7 +126,7 @@ class MemoryQueue extends Array {
|
|
|
123
126
|
* Adds a track to the previous tracks.
|
|
124
127
|
* @param track The track or tracks to add. Can be a single `Track` or an array of `Track`s.
|
|
125
128
|
*/
|
|
126
|
-
|
|
129
|
+
addPrevious(track) {
|
|
127
130
|
try {
|
|
128
131
|
const max = this.manager.options.maxPreviousTracks;
|
|
129
132
|
if (Array.isArray(track)) {
|
|
@@ -155,7 +158,7 @@ class MemoryQueue extends Array {
|
|
|
155
158
|
* Clears the queue.
|
|
156
159
|
* This will remove all tracks from the queue and emit a state update event.
|
|
157
160
|
*/
|
|
158
|
-
|
|
161
|
+
clear() {
|
|
159
162
|
try {
|
|
160
163
|
// Capture the current state of the player for event emission.
|
|
161
164
|
const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
|
|
@@ -187,20 +190,32 @@ class MemoryQueue extends Array {
|
|
|
187
190
|
/**
|
|
188
191
|
* Clears the previous tracks.
|
|
189
192
|
*/
|
|
190
|
-
|
|
193
|
+
clearPrevious() {
|
|
191
194
|
this.previous = [];
|
|
192
195
|
}
|
|
193
196
|
/**
|
|
194
197
|
* Removes the first element from the queue.
|
|
195
198
|
*/
|
|
196
|
-
|
|
199
|
+
dequeue() {
|
|
197
200
|
return super.shift();
|
|
198
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* Destroys the queue and releases all resources.
|
|
204
|
+
* After calling this method, the queue must not be used again.
|
|
205
|
+
*/
|
|
206
|
+
destroy() {
|
|
207
|
+
if (this.destroyed)
|
|
208
|
+
return;
|
|
209
|
+
this.destroyed = true;
|
|
210
|
+
this.splice(0);
|
|
211
|
+
this.previous.length = 0;
|
|
212
|
+
this.current = null;
|
|
213
|
+
}
|
|
199
214
|
/**
|
|
200
215
|
* The total duration of the queue in milliseconds.
|
|
201
216
|
* This includes the duration of the currently playing track.
|
|
202
217
|
*/
|
|
203
|
-
|
|
218
|
+
duration() {
|
|
204
219
|
const current = this.current?.duration ?? 0;
|
|
205
220
|
return this.reduce((acc, cur) => acc + (cur.duration || 0), current);
|
|
206
221
|
}
|
|
@@ -208,7 +223,7 @@ class MemoryQueue extends Array {
|
|
|
208
223
|
* Adds the specified track or tracks to the front of the queue.
|
|
209
224
|
* @param track The track or tracks to add.
|
|
210
225
|
*/
|
|
211
|
-
|
|
226
|
+
enqueueFront(track) {
|
|
212
227
|
if (Array.isArray(track)) {
|
|
213
228
|
this.unshift(...track);
|
|
214
229
|
}
|
|
@@ -219,49 +234,49 @@ class MemoryQueue extends Array {
|
|
|
219
234
|
/**
|
|
220
235
|
* @returns Whether all elements in the queue satisfy the provided testing function.
|
|
221
236
|
*/
|
|
222
|
-
|
|
237
|
+
everyAsync(callback) {
|
|
223
238
|
return this.every(callback);
|
|
224
239
|
}
|
|
225
240
|
/**
|
|
226
241
|
* @returns A new array with all elements that pass the test implemented by the provided function.
|
|
227
242
|
*/
|
|
228
|
-
|
|
243
|
+
filterAsync(callback) {
|
|
229
244
|
return this.filter(callback);
|
|
230
245
|
}
|
|
231
246
|
/**
|
|
232
247
|
* @returns The first element in the queue that satisfies the provided testing function.
|
|
233
248
|
*/
|
|
234
|
-
|
|
249
|
+
findAsync(callback) {
|
|
235
250
|
return this.find(callback);
|
|
236
251
|
}
|
|
237
252
|
/**
|
|
238
253
|
* @returns The current track.
|
|
239
254
|
*/
|
|
240
|
-
|
|
255
|
+
getCurrent() {
|
|
241
256
|
return this.current;
|
|
242
257
|
}
|
|
243
258
|
/**
|
|
244
259
|
* @returns The previous tracks.
|
|
245
260
|
*/
|
|
246
|
-
|
|
261
|
+
getPrevious() {
|
|
247
262
|
return [...this.previous];
|
|
248
263
|
}
|
|
249
264
|
/**
|
|
250
265
|
* @returns The tracks in the queue from start to end.
|
|
251
266
|
*/
|
|
252
|
-
|
|
267
|
+
getSlice(start, end) {
|
|
253
268
|
return this.slice(start, end); // Native sync method, still wrapped in a Promise
|
|
254
269
|
}
|
|
255
270
|
/**
|
|
256
271
|
* @returns The tracks in the queue.
|
|
257
272
|
*/
|
|
258
|
-
|
|
273
|
+
getTracks() {
|
|
259
274
|
return [...this]; // clone to avoid direct mutation
|
|
260
275
|
}
|
|
261
276
|
/**
|
|
262
277
|
* @returns A new array with the results of calling a provided function on every element in the queue.
|
|
263
278
|
*/
|
|
264
|
-
|
|
279
|
+
mapAsync(callback) {
|
|
265
280
|
return this.map(callback);
|
|
266
281
|
}
|
|
267
282
|
/**
|
|
@@ -271,16 +286,16 @@ class MemoryQueue extends Array {
|
|
|
271
286
|
* @param items The elements to add to the queue.
|
|
272
287
|
* @returns The modified queue.
|
|
273
288
|
*/
|
|
274
|
-
|
|
289
|
+
modifyAt(start, deleteCount = 0, ...items) {
|
|
275
290
|
return super.splice(start, deleteCount, ...items);
|
|
276
291
|
}
|
|
277
292
|
/**
|
|
278
293
|
* @returns The newest track.
|
|
279
294
|
*/
|
|
280
|
-
|
|
295
|
+
popPrevious() {
|
|
281
296
|
return this.previous.pop() || null; // get newest track
|
|
282
297
|
}
|
|
283
|
-
|
|
298
|
+
remove(startOrPosition = 0, end) {
|
|
284
299
|
try {
|
|
285
300
|
const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
|
|
286
301
|
if (typeof end !== "undefined") {
|
|
@@ -332,7 +347,7 @@ class MemoryQueue extends Array {
|
|
|
332
347
|
/**
|
|
333
348
|
* Shuffles the queue to play tracks requested by each user one by one.
|
|
334
349
|
*/
|
|
335
|
-
|
|
350
|
+
roundRobinShuffle() {
|
|
336
351
|
try {
|
|
337
352
|
// Capture the current state of the player for event emission.
|
|
338
353
|
const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
|
|
@@ -340,11 +355,11 @@ class MemoryQueue extends Array {
|
|
|
340
355
|
const userTracks = new Map();
|
|
341
356
|
// Group the tracks in the queue by the user that requested them.
|
|
342
357
|
this.forEach((track) => {
|
|
343
|
-
const
|
|
344
|
-
if (!userTracks.has(
|
|
345
|
-
userTracks.set(
|
|
358
|
+
const userId = track.requester.id.toString();
|
|
359
|
+
if (!userTracks.has(userId)) {
|
|
360
|
+
userTracks.set(userId, []);
|
|
346
361
|
}
|
|
347
|
-
userTracks.get(
|
|
362
|
+
userTracks.get(userId).push(track);
|
|
348
363
|
});
|
|
349
364
|
// Shuffle the tracks of each user.
|
|
350
365
|
userTracks.forEach((tracks) => {
|
|
@@ -395,20 +410,20 @@ class MemoryQueue extends Array {
|
|
|
395
410
|
/**
|
|
396
411
|
* @param track The track to set.
|
|
397
412
|
*/
|
|
398
|
-
|
|
413
|
+
setCurrent(track) {
|
|
399
414
|
this.current = track;
|
|
400
415
|
}
|
|
401
416
|
/**
|
|
402
417
|
* @param tracks The tracks to set.
|
|
403
418
|
*/
|
|
404
|
-
|
|
419
|
+
setPrevious(tracks) {
|
|
405
420
|
this.previous = [...tracks];
|
|
406
421
|
}
|
|
407
422
|
/**
|
|
408
423
|
* Shuffles the queue.
|
|
409
424
|
* This will randomize the order of the tracks in the queue and emit a state update event.
|
|
410
425
|
*/
|
|
411
|
-
|
|
426
|
+
shuffle() {
|
|
412
427
|
try {
|
|
413
428
|
// Capture the current state of the player for event emission.
|
|
414
429
|
const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
|
|
@@ -444,13 +459,13 @@ class MemoryQueue extends Array {
|
|
|
444
459
|
* This does not include the currently playing track.
|
|
445
460
|
* @returns The size of tracks in the queue.
|
|
446
461
|
*/
|
|
447
|
-
|
|
462
|
+
size() {
|
|
448
463
|
return this.length;
|
|
449
464
|
}
|
|
450
465
|
/**
|
|
451
466
|
* @returns Whether at least one element in the queue satisfies the provided testing function.
|
|
452
467
|
*/
|
|
453
|
-
|
|
468
|
+
someAsync(callback) {
|
|
454
469
|
return this.some(callback);
|
|
455
470
|
}
|
|
456
471
|
/**
|
|
@@ -458,24 +473,24 @@ class MemoryQueue extends Array {
|
|
|
458
473
|
* This includes the current track if it is not null.
|
|
459
474
|
* @returns The total size of tracks in the queue including the current track.
|
|
460
475
|
*/
|
|
461
|
-
|
|
476
|
+
totalSize() {
|
|
462
477
|
return this.length + (this.current ? 1 : 0);
|
|
463
478
|
}
|
|
464
479
|
/**
|
|
465
480
|
* Shuffles the queue to play tracks requested by each user one block at a time.
|
|
466
481
|
*/
|
|
467
|
-
|
|
482
|
+
userBlockShuffle() {
|
|
468
483
|
try {
|
|
469
484
|
// Capture the current state of the player for event emission.
|
|
470
485
|
const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
|
|
471
486
|
// Group the tracks in the queue by the user that requested them.
|
|
472
487
|
const userTracks = new Map();
|
|
473
488
|
this.forEach((track) => {
|
|
474
|
-
const
|
|
475
|
-
if (!userTracks.has(
|
|
476
|
-
userTracks.set(
|
|
489
|
+
const userId = track.requester.id.toString();
|
|
490
|
+
if (!userTracks.has(userId)) {
|
|
491
|
+
userTracks.set(userId, []);
|
|
477
492
|
}
|
|
478
|
-
userTracks.get(
|
|
493
|
+
userTracks.get(userId).push(track);
|
|
479
494
|
});
|
|
480
495
|
// Create a new array for the shuffled queue.
|
|
481
496
|
const shuffledQueue = [];
|
|
@@ -18,6 +18,10 @@ class RedisQueue {
|
|
|
18
18
|
* The Redis instance.
|
|
19
19
|
*/
|
|
20
20
|
redis;
|
|
21
|
+
/**
|
|
22
|
+
* Whether the queue has been destroyed.
|
|
23
|
+
*/
|
|
24
|
+
destroyed = false;
|
|
21
25
|
/**
|
|
22
26
|
* Constructs a new RedisQueue.
|
|
23
27
|
* @param guildId The guild ID.
|
|
@@ -27,11 +31,7 @@ class RedisQueue {
|
|
|
27
31
|
this.guildId = guildId;
|
|
28
32
|
this.manager = manager;
|
|
29
33
|
this.redis = manager.redis;
|
|
30
|
-
|
|
31
|
-
let clean = typeof rawPrefix === "string" ? rawPrefix.trim() : "";
|
|
32
|
-
if (!clean.endsWith(":"))
|
|
33
|
-
clean = clean || "magmastream";
|
|
34
|
-
this.redisPrefix = `${clean}:`;
|
|
34
|
+
this.redisPrefix = Utils_1.PlayerUtils.getRedisKey();
|
|
35
35
|
}
|
|
36
36
|
// #region Public
|
|
37
37
|
/**
|
|
@@ -81,8 +81,7 @@ class RedisQueue {
|
|
|
81
81
|
// Autoplay logic
|
|
82
82
|
if (this.manager.players.has(this.guildId) && this.manager.players.get(this.guildId).isAutoplay) {
|
|
83
83
|
if (!Array.isArray(track)) {
|
|
84
|
-
|
|
85
|
-
if (AutoplayUser && AutoplayUser.id === track.requester.id) {
|
|
84
|
+
if (track.isAutoplay) {
|
|
86
85
|
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
87
86
|
changeType: Enums_1.PlayerStateEventTypes.QueueChange,
|
|
88
87
|
details: {
|
|
@@ -223,6 +222,28 @@ class RedisQueue {
|
|
|
223
222
|
console.error(error);
|
|
224
223
|
}
|
|
225
224
|
}
|
|
225
|
+
/**
|
|
226
|
+
* Destroys the queue and releases all resources.
|
|
227
|
+
* After calling this method, the queue must not be used again.
|
|
228
|
+
*/
|
|
229
|
+
async destroy() {
|
|
230
|
+
if (this.destroyed)
|
|
231
|
+
return;
|
|
232
|
+
this.destroyed = true;
|
|
233
|
+
try {
|
|
234
|
+
await this.redis.del(this.queueKey, this.previousKey, this.currentKey);
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
238
|
+
? err
|
|
239
|
+
: new MagmastreamError_1.MagmaStreamError({
|
|
240
|
+
code: Enums_1.MagmaStreamErrorCode.QUEUE_REDIS_ERROR,
|
|
241
|
+
message: `Failed to destroy RedisQueue for guild ${this.guildId}: ${err.message}`,
|
|
242
|
+
cause: err,
|
|
243
|
+
});
|
|
244
|
+
console.error(error);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
226
247
|
/**
|
|
227
248
|
* @returns The total duration of the queue in milliseconds.
|
|
228
249
|
* This includes the duration of the currently playing track.
|
|
@@ -488,7 +509,7 @@ class RedisQueue {
|
|
|
488
509
|
const deserialized = rawTracks.map(this.deserialize);
|
|
489
510
|
const userMap = new Map();
|
|
490
511
|
for (const track of deserialized) {
|
|
491
|
-
const userId = track.requester.id;
|
|
512
|
+
const userId = track.requester.id.toString();
|
|
492
513
|
if (!userMap.has(userId))
|
|
493
514
|
userMap.set(userId, []);
|
|
494
515
|
userMap.get(userId).push(track);
|
|
@@ -659,7 +680,7 @@ class RedisQueue {
|
|
|
659
680
|
const deserialized = rawTracks.map(this.deserialize);
|
|
660
681
|
const userMap = new Map();
|
|
661
682
|
for (const track of deserialized) {
|
|
662
|
-
const userId = track.requester.id;
|
|
683
|
+
const userId = track.requester.id.toString();
|
|
663
684
|
if (!userMap.has(userId))
|
|
664
685
|
userMap.set(userId, []);
|
|
665
686
|
userMap.get(userId).push(track);
|
package/dist/structures/Enums.js
CHANGED
|
@@ -163,6 +163,8 @@ var TrackPartial;
|
|
|
163
163
|
TrackPartial["PluginInfo"] = "pluginInfo";
|
|
164
164
|
/** The custom data of the track */
|
|
165
165
|
TrackPartial["CustomData"] = "customData";
|
|
166
|
+
/** Whether the track got autoplayed */
|
|
167
|
+
TrackPartial["IsAutoPlay"] = "isAutoplay";
|
|
166
168
|
})(TrackPartial || (exports.TrackPartial = TrackPartial = {}));
|
|
167
169
|
/**
|
|
168
170
|
* Manager Event Types Enum
|
|
@@ -283,6 +285,7 @@ var MagmaStreamErrorCode;
|
|
|
283
285
|
MagmaStreamErrorCode["GENERAL_UNKNOWN"] = "MS_GENERAL_UNKNOWN";
|
|
284
286
|
MagmaStreamErrorCode["GENERAL_TIMEOUT"] = "MS_GENERAL_TIMEOUT";
|
|
285
287
|
MagmaStreamErrorCode["GENERAL_INVALID_MANAGER"] = "MS_GENERAL_INVALID_MANAGER";
|
|
288
|
+
MagmaStreamErrorCode["INTENT_MISSING"] = "MS_INTENT_MISSING";
|
|
286
289
|
// MANAGER (1100)
|
|
287
290
|
MagmaStreamErrorCode["MANAGER_INIT_FAILED"] = "MS_MANAGER_INIT_FAILED";
|
|
288
291
|
MagmaStreamErrorCode["MANAGER_INVALID_CONFIG"] = "MS_MANAGER_INVALID_CONFIG";
|
|
@@ -326,6 +329,7 @@ var MagmaStreamErrorCode;
|
|
|
326
329
|
MagmaStreamErrorCode["UTILS_TRACK_PARTIAL_INVALID"] = "MS_UTILS_TRACK_PARTIAL_INVALID";
|
|
327
330
|
MagmaStreamErrorCode["UTILS_TRACK_BUILD_FAILED"] = "MS_UTILS_TRACK_BUILD_FAILED";
|
|
328
331
|
MagmaStreamErrorCode["UTILS_AUTOPLAY_BUILD_FAILED"] = "MS_UTILS_AUTOPLAY_BUILD_FAILED";
|
|
332
|
+
MagmaStreamErrorCode["UTILS_PLAYER_SERIALIZE_FAILED"] = "MS_UTILS_PLAYER_SERIALIZE_FAILED";
|
|
329
333
|
// PLUGIN (1800)
|
|
330
334
|
MagmaStreamErrorCode["PLUGIN_LOAD_FAILED"] = "MS_PLUGIN_LOAD_FAILED";
|
|
331
335
|
MagmaStreamErrorCode["PLUGIN_RUNTIME_ERROR"] = "MS_PLUGIN_RUNTIME_ERROR";
|
|
@@ -336,6 +340,7 @@ exports.MagmaStreamErrorNumbers = {
|
|
|
336
340
|
[MagmaStreamErrorCode.GENERAL_UNKNOWN]: 1000,
|
|
337
341
|
[MagmaStreamErrorCode.GENERAL_TIMEOUT]: 1001,
|
|
338
342
|
[MagmaStreamErrorCode.GENERAL_INVALID_MANAGER]: 1002,
|
|
343
|
+
[MagmaStreamErrorCode.INTENT_MISSING]: 1003,
|
|
339
344
|
// MANAGER
|
|
340
345
|
[MagmaStreamErrorCode.MANAGER_INIT_FAILED]: 1100,
|
|
341
346
|
[MagmaStreamErrorCode.MANAGER_INVALID_CONFIG]: 1101,
|
|
@@ -379,6 +384,7 @@ exports.MagmaStreamErrorNumbers = {
|
|
|
379
384
|
[MagmaStreamErrorCode.UTILS_TRACK_PARTIAL_INVALID]: 1700,
|
|
380
385
|
[MagmaStreamErrorCode.UTILS_TRACK_BUILD_FAILED]: 1701,
|
|
381
386
|
[MagmaStreamErrorCode.UTILS_AUTOPLAY_BUILD_FAILED]: 1702,
|
|
387
|
+
[MagmaStreamErrorCode.UTILS_PLAYER_SERIALIZE_FAILED]: 1703,
|
|
382
388
|
// PLUGIN
|
|
383
389
|
[MagmaStreamErrorCode.PLUGIN_LOAD_FAILED]: 1800,
|
|
384
390
|
[MagmaStreamErrorCode.PLUGIN_RUNTIME_ERROR]: 1801,
|
|
@@ -8,8 +8,6 @@ class Filters {
|
|
|
8
8
|
distortion;
|
|
9
9
|
equalizer;
|
|
10
10
|
karaoke;
|
|
11
|
-
manager;
|
|
12
|
-
player;
|
|
13
11
|
rotation;
|
|
14
12
|
timescale;
|
|
15
13
|
vibrato;
|
|
@@ -17,15 +15,16 @@ class Filters {
|
|
|
17
15
|
volume;
|
|
18
16
|
bassBoostlevel;
|
|
19
17
|
filtersStatus;
|
|
18
|
+
manager;
|
|
19
|
+
player;
|
|
20
20
|
constructor(player, manager) {
|
|
21
21
|
this.distortion = null;
|
|
22
22
|
this.equalizer = [];
|
|
23
23
|
this.karaoke = null;
|
|
24
|
-
this.manager = manager;
|
|
25
|
-
this.player = player;
|
|
26
24
|
this.rotation = null;
|
|
27
25
|
this.timescale = null;
|
|
28
26
|
this.vibrato = null;
|
|
27
|
+
this.reverb = null;
|
|
29
28
|
this.volume = 1.0;
|
|
30
29
|
this.bassBoostlevel = 0;
|
|
31
30
|
// Initialize filter status
|
|
@@ -33,6 +32,8 @@ class Filters {
|
|
|
33
32
|
acc[filter] = false;
|
|
34
33
|
return acc;
|
|
35
34
|
}, {});
|
|
35
|
+
this.manager = manager;
|
|
36
|
+
this.player = player;
|
|
36
37
|
}
|
|
37
38
|
/**
|
|
38
39
|
* Updates the player's audio filters.
|
|
@@ -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 ?? [],
|
|
@@ -177,11 +180,15 @@ class Manager extends events_1.EventEmitter {
|
|
|
177
180
|
db: config.db ?? 0,
|
|
178
181
|
});
|
|
179
182
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
183
|
+
const results = await Promise.allSettled([...this.nodes.values()].map(async (node) => {
|
|
184
|
+
await node.connect();
|
|
185
|
+
return node;
|
|
186
|
+
}));
|
|
187
|
+
for (let i = 0; i < results.length; i++) {
|
|
188
|
+
const result = results[i];
|
|
189
|
+
const node = [...this.nodes.values()][i];
|
|
190
|
+
if (result.status === "rejected") {
|
|
191
|
+
const err = result.reason;
|
|
185
192
|
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
186
193
|
? err
|
|
187
194
|
: new MagmastreamError_1.MagmaStreamError({
|
|
@@ -277,9 +284,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
277
284
|
result.playlist.tracks = result.playlist.tracks.map(processTrack);
|
|
278
285
|
}
|
|
279
286
|
}
|
|
280
|
-
const summary = "tracks" in result
|
|
281
|
-
? result.tracks.map((t) => Object.fromEntries(Object.entries(t).filter(([key]) => key !== "requester")))
|
|
282
|
-
: [];
|
|
287
|
+
const summary = "tracks" in result ? result.tracks.map((t) => Object.fromEntries(Object.entries(t).filter(([key]) => key !== "requester"))) : [];
|
|
283
288
|
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Result search for ${_query.query}: ${Utils_1.JSONUtils.safe(summary, 2)}`);
|
|
284
289
|
return result;
|
|
285
290
|
}
|
|
@@ -466,9 +471,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
466
471
|
case Enums_1.StateStorageType.Redis:
|
|
467
472
|
{
|
|
468
473
|
try {
|
|
469
|
-
const redisKey = `${
|
|
470
|
-
? this.options.stateStorage.redisConfig.prefix
|
|
471
|
-
: this.options.stateStorage.redisConfig.prefix ?? "magmastream:"}playerstore:${guildId}`;
|
|
474
|
+
const redisKey = `${Utils_1.PlayerUtils.getRedisKey()}playerstore:${guildId}`;
|
|
472
475
|
await this.redis.set(redisKey, JSON.stringify(serializedPlayer));
|
|
473
476
|
this.emit(Enums_1.ManagerEventTypes.Debug, `[MANAGER] Player state saved to Redis: ${guildId}`);
|
|
474
477
|
}
|
|
@@ -558,6 +561,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
558
561
|
token: state.voiceState.event.token,
|
|
559
562
|
endpoint: state.voiceState.event.endpoint,
|
|
560
563
|
sessionId: state.voiceState.sessionId,
|
|
564
|
+
channelId: state.voiceState.event.channel_id,
|
|
561
565
|
},
|
|
562
566
|
},
|
|
563
567
|
});
|
|
@@ -579,7 +583,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
579
583
|
if (lavaPlayer.track) {
|
|
580
584
|
await player.queue.clear();
|
|
581
585
|
if (currentTrack) {
|
|
582
|
-
await player.queue.add(Utils_1.TrackUtils.build(lavaPlayer.track, currentTrack.requester));
|
|
586
|
+
await player.queue.add(Utils_1.TrackUtils.build(lavaPlayer.track, currentTrack.requester, currentTrack.isAutoplay));
|
|
583
587
|
}
|
|
584
588
|
const remainingQueue = queueTracks.filter((t) => t.uri !== lavaPlayer.track.info.uri);
|
|
585
589
|
if (remainingQueue.length > 0) {
|
|
@@ -720,9 +724,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
720
724
|
{
|
|
721
725
|
try {
|
|
722
726
|
// Get all keys matching our pattern
|
|
723
|
-
const redisKeyPattern = `${
|
|
724
|
-
? this.options.stateStorage.redisConfig.prefix
|
|
725
|
-
: this.options.stateStorage.redisConfig.prefix ?? "magmastream:"}playerstore:*`;
|
|
727
|
+
const redisKeyPattern = `${Utils_1.PlayerUtils.getRedisKey()}playerstore:*`;
|
|
726
728
|
const keys = await this.redis.keys(redisKeyPattern);
|
|
727
729
|
for (const key of keys) {
|
|
728
730
|
try {
|
|
@@ -753,7 +755,14 @@ class Manager extends events_1.EventEmitter {
|
|
|
753
755
|
const player = this.create(playerOptions);
|
|
754
756
|
await player.node.rest.updatePlayer({
|
|
755
757
|
guildId: state.options.guildId,
|
|
756
|
-
data: {
|
|
758
|
+
data: {
|
|
759
|
+
voice: {
|
|
760
|
+
token: state.voiceState.event.token,
|
|
761
|
+
endpoint: state.voiceState.event.endpoint,
|
|
762
|
+
sessionId: state.voiceState.sessionId,
|
|
763
|
+
channelId: state.voiceState.event.channel_id,
|
|
764
|
+
},
|
|
765
|
+
},
|
|
757
766
|
});
|
|
758
767
|
player.connect();
|
|
759
768
|
// Rest of the player state restoration code (tracks, filters, etc.)
|
|
@@ -774,7 +783,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
774
783
|
if (lavaPlayer.track) {
|
|
775
784
|
await player.queue.clear();
|
|
776
785
|
if (currentTrack) {
|
|
777
|
-
await player.queue.add(Utils_1.TrackUtils.build(lavaPlayer.track, currentTrack.requester));
|
|
786
|
+
await player.queue.add(Utils_1.TrackUtils.build(lavaPlayer.track, currentTrack.requester, currentTrack.isAutoplay));
|
|
778
787
|
}
|
|
779
788
|
const remainingQueue = queueTracks.filter((t) => t.uri !== lavaPlayer.track.info.uri);
|
|
780
789
|
if (remainingQueue.length > 0) {
|
|
@@ -916,11 +925,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
916
925
|
* @returns {Node} The node to use.
|
|
917
926
|
*/
|
|
918
927
|
get useableNode() {
|
|
919
|
-
return this.options.enablePriorityMode
|
|
920
|
-
? this.priorityNode
|
|
921
|
-
: this.options.useNode === Enums_1.UseNodeOptions.LeastLoad
|
|
922
|
-
? this.leastLoadNode.first()
|
|
923
|
-
: this.leastPlayersNode.first();
|
|
928
|
+
return this.options.enablePriorityMode ? this.priorityNode : this.options.useNode === Enums_1.UseNodeOptions.LeastLoad ? this.leastLoadNode.first() : this.leastPlayersNode.first();
|
|
924
929
|
}
|
|
925
930
|
/**
|
|
926
931
|
* Handles the shutdown of the process by saving all active players' states and optionally cleaning up inactive players.
|
|
@@ -1079,13 +1084,17 @@ class Manager extends events_1.EventEmitter {
|
|
|
1079
1084
|
*/
|
|
1080
1085
|
async handleVoiceServerUpdate(player, update) {
|
|
1081
1086
|
player.voiceState.event = update;
|
|
1082
|
-
const
|
|
1087
|
+
const sessionId = player.voiceState.sessionId;
|
|
1088
|
+
const channelId = player.voiceState.channelId;
|
|
1089
|
+
const token = update.token;
|
|
1090
|
+
const endpoint = update.endpoint;
|
|
1091
|
+
this.emit(Enums_1.ManagerEventTypes.Debug, `Updated voice server for player ${player.guildId} with token ${token} | endpoint ${endpoint} | sessionId ${sessionId} | channelId ${channelId}`);
|
|
1092
|
+
if (!sessionId || !channelId)
|
|
1093
|
+
return;
|
|
1083
1094
|
await player.node.rest.updatePlayer({
|
|
1084
1095
|
guildId: player.guildId,
|
|
1085
|
-
data: { voice: { token, endpoint, sessionId } },
|
|
1096
|
+
data: { voice: { token, endpoint, sessionId, channelId } },
|
|
1086
1097
|
});
|
|
1087
|
-
this.emit(Enums_1.ManagerEventTypes.Debug, `Updated voice server for player ${player.guildId} with token ${token} and endpoint ${endpoint} and sessionId ${sessionId}`);
|
|
1088
|
-
return;
|
|
1089
1098
|
}
|
|
1090
1099
|
/**
|
|
1091
1100
|
* Handles a voice state update by updating the player's voice channel and session ID if provided, or by disconnecting and destroying the player if the channel ID is null.
|
|
@@ -1096,22 +1105,30 @@ class Manager extends events_1.EventEmitter {
|
|
|
1096
1105
|
*/
|
|
1097
1106
|
async handleVoiceStateUpdate(player, update) {
|
|
1098
1107
|
this.emit(Enums_1.ManagerEventTypes.Debug, `Updated voice state for player ${player.guildId} with channel id ${update.channel_id} and session id ${update.session_id}`);
|
|
1099
|
-
if (update.channel_id) {
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
player.voiceState
|
|
1104
|
-
player.
|
|
1105
|
-
|
|
1108
|
+
if (!update.channel_id) {
|
|
1109
|
+
this.emit(Enums_1.ManagerEventTypes.PlayerDisconnect, player, player.voiceChannelId);
|
|
1110
|
+
player.voiceChannelId = null;
|
|
1111
|
+
player.state = Enums_1.StateTypes.Disconnected;
|
|
1112
|
+
player.voiceState = Object.assign({});
|
|
1113
|
+
if (player.options.pauseOnDisconnect)
|
|
1114
|
+
await player.pause(true);
|
|
1106
1115
|
return;
|
|
1107
1116
|
}
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
player.voiceState = Object.assign({});
|
|
1111
|
-
if (player.options.pauseOnDisconnect) {
|
|
1112
|
-
await player.pause(true);
|
|
1117
|
+
if (player.voiceChannelId !== update.channel_id) {
|
|
1118
|
+
this.emit(Enums_1.ManagerEventTypes.PlayerMove, player, player.voiceChannelId, update.channel_id);
|
|
1113
1119
|
}
|
|
1114
|
-
|
|
1120
|
+
player.voiceState.sessionId = update.session_id;
|
|
1121
|
+
player.voiceState.channelId = update.channel_id;
|
|
1122
|
+
player.voiceChannelId = update.channel_id;
|
|
1123
|
+
player.options.voiceChannelId = update.channel_id;
|
|
1124
|
+
const token = player.voiceState.event?.token;
|
|
1125
|
+
const endpoint = player.voiceState.event?.endpoint;
|
|
1126
|
+
if (!token || !endpoint)
|
|
1127
|
+
return;
|
|
1128
|
+
await player.node.rest.updatePlayer({
|
|
1129
|
+
guildId: player.guildId,
|
|
1130
|
+
data: { voice: { token, endpoint, sessionId: update.session_id, channelId: update.channel_id } },
|
|
1131
|
+
});
|
|
1115
1132
|
}
|
|
1116
1133
|
/**
|
|
1117
1134
|
* Cleans up inactive players by removing their state files from the file system.
|
|
@@ -1154,9 +1171,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
1154
1171
|
break;
|
|
1155
1172
|
case Enums_1.StateStorageType.Redis:
|
|
1156
1173
|
{
|
|
1157
|
-
const prefix =
|
|
1158
|
-
? this.options.stateStorage.redisConfig.prefix
|
|
1159
|
-
: this.options.stateStorage.redisConfig.prefix ?? "magmastream:";
|
|
1174
|
+
const prefix = Utils_1.PlayerUtils.getRedisKey();
|
|
1160
1175
|
const pattern = `${prefix}queue:*:current`;
|
|
1161
1176
|
try {
|
|
1162
1177
|
const stream = this.redis.scanStream({
|
|
@@ -1229,9 +1244,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
1229
1244
|
{
|
|
1230
1245
|
try {
|
|
1231
1246
|
if (!player) {
|
|
1232
|
-
const prefix =
|
|
1233
|
-
? this.options.stateStorage.redisConfig.prefix
|
|
1234
|
-
: `${this.options.stateStorage.redisConfig.prefix ?? "magmastream"}:`;
|
|
1247
|
+
const prefix = Utils_1.PlayerUtils.getRedisKey();
|
|
1235
1248
|
const keysToDelete = [
|
|
1236
1249
|
`${prefix}playerstore:${guildId}`,
|
|
1237
1250
|
`${prefix}queue:${guildId}:tracks`,
|
|
@@ -1339,9 +1352,7 @@ class Manager extends events_1.EventEmitter {
|
|
|
1339
1352
|
break;
|
|
1340
1353
|
}
|
|
1341
1354
|
case Enums_1.StateStorageType.Redis: {
|
|
1342
|
-
const prefix =
|
|
1343
|
-
? this.options.stateStorage.redisConfig.prefix
|
|
1344
|
-
: this.options.stateStorage.redisConfig.prefix ?? "magmastream:";
|
|
1355
|
+
const prefix = Utils_1.PlayerUtils.getRedisKey();
|
|
1345
1356
|
const patterns = [`${prefix}playerstore:*`, `${prefix}queue:*`];
|
|
1346
1357
|
try {
|
|
1347
1358
|
for (const pattern of patterns) {
|
|
@@ -1440,6 +1451,9 @@ class Manager extends events_1.EventEmitter {
|
|
|
1440
1451
|
}
|
|
1441
1452
|
return this._send(packet);
|
|
1442
1453
|
}
|
|
1454
|
+
getUserFromCache(id) {
|
|
1455
|
+
return this._getUser?.(id);
|
|
1456
|
+
}
|
|
1443
1457
|
sendPacket(packet) {
|
|
1444
1458
|
return this.send(packet);
|
|
1445
1459
|
}
|