magmastream 2.9.2-dev.1 → 2.9.2-dev.10
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 +103 -23
- package/dist/index.js +1 -0
- package/dist/statestorage/JsonQueue.js +332 -176
- package/dist/statestorage/MemoryQueue.js +288 -203
- package/dist/statestorage/RedisQueue.js +482 -204
- 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 +351 -219
- package/dist/structures/Node.js +227 -66
- package/dist/structures/Player.js +199 -58
- package/dist/structures/Rest.js +23 -12
- package/dist/structures/Utils.js +83 -67
- package/dist/utils/managerCheck.js +99 -21
- package/dist/utils/nodeCheck.js +59 -34
- package/dist/utils/playerCheck.js +47 -28
- package/package.json +3 -2
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.MemoryQueue = void 0;
|
|
4
4
|
const Enums_1 = require("../structures/Enums");
|
|
5
5
|
const Utils_1 = require("../structures/Utils");
|
|
6
|
+
const MagmastreamError_1 = require("../structures/MagmastreamError");
|
|
6
7
|
/**
|
|
7
8
|
* The player's queue, the `current` property is the currently playing track, think of the rest as the up-coming tracks.
|
|
8
9
|
*/
|
|
@@ -34,96 +35,120 @@ class MemoryQueue extends Array {
|
|
|
34
35
|
* @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.
|
|
35
36
|
*/
|
|
36
37
|
async add(track, offset) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (
|
|
47
|
-
this.current = tracks.shift() || null;
|
|
48
|
-
this.push(...tracks);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
this.current = track;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
// If an offset is provided, add the track(s) at that position
|
|
56
|
-
if (typeof offset !== "undefined" && typeof offset === "number") {
|
|
57
|
-
// Validate the offset
|
|
58
|
-
if (isNaN(offset)) {
|
|
59
|
-
throw new RangeError("Offset must be a number.");
|
|
60
|
-
}
|
|
61
|
-
// Make sure the offset is between 0 and the length of the queue
|
|
62
|
-
if (offset < 0 || offset > this.length) {
|
|
63
|
-
throw new RangeError(`Offset must be between 0 and ${this.length}.`);
|
|
64
|
-
}
|
|
65
|
-
// Add the track(s) at the offset position
|
|
38
|
+
try {
|
|
39
|
+
const isArray = Array.isArray(track);
|
|
40
|
+
const tracks = isArray ? [...track] : [track];
|
|
41
|
+
// Get the track info as a string
|
|
42
|
+
const trackInfo = isArray ? tracks.map((t) => Utils_1.JSONUtils.safe(t, 2)).join(", ") : Utils_1.JSONUtils.safe(track, 2);
|
|
43
|
+
// Emit a debug message
|
|
44
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[MEMORYQUEUE] Added ${tracks.length} track(s) to queue: ${trackInfo}`);
|
|
45
|
+
const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
|
|
46
|
+
// If the queue is empty, set the track as the current track
|
|
47
|
+
if (!this.current) {
|
|
66
48
|
if (isArray) {
|
|
67
|
-
this.
|
|
49
|
+
this.current = tracks.shift() || null;
|
|
50
|
+
this.push(...tracks);
|
|
68
51
|
}
|
|
69
52
|
else {
|
|
70
|
-
this.
|
|
53
|
+
this.current = track;
|
|
71
54
|
}
|
|
72
55
|
}
|
|
73
56
|
else {
|
|
74
|
-
// If
|
|
75
|
-
if (
|
|
76
|
-
|
|
57
|
+
// If an offset is provided, add the track(s) at that position
|
|
58
|
+
if (typeof offset !== "undefined" && typeof offset === "number") {
|
|
59
|
+
// Validate the offset
|
|
60
|
+
if (isNaN(offset)) {
|
|
61
|
+
throw new RangeError("Offset must be a number.");
|
|
62
|
+
}
|
|
63
|
+
// Make sure the offset is between 0 and the length of the queue
|
|
64
|
+
if (offset < 0 || offset > this.length) {
|
|
65
|
+
throw new RangeError(`Offset must be between 0 and ${this.length}.`);
|
|
66
|
+
}
|
|
67
|
+
// Add the track(s) at the offset position
|
|
68
|
+
if (isArray) {
|
|
69
|
+
this.splice(offset, 0, ...tracks);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
this.splice(offset, 0, track);
|
|
73
|
+
}
|
|
77
74
|
}
|
|
78
75
|
else {
|
|
79
|
-
|
|
76
|
+
// If no offset is provided, add the track(s) at the end of the queue
|
|
77
|
+
if (isArray) {
|
|
78
|
+
this.push(...tracks);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
this.push(track);
|
|
82
|
+
}
|
|
80
83
|
}
|
|
81
84
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
|
|
85
|
+
if (this.manager.players.has(this.guildId) && this.manager.players.get(this.guildId).isAutoplay) {
|
|
86
|
+
if (!isArray) {
|
|
87
|
+
const AutoplayUser = this.manager.players.get(this.guildId).get("Internal_AutoplayUser");
|
|
88
|
+
if (AutoplayUser && AutoplayUser.id === track.requester.id) {
|
|
89
|
+
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
90
|
+
changeType: Enums_1.PlayerStateEventTypes.QueueChange,
|
|
91
|
+
details: {
|
|
92
|
+
type: "queue",
|
|
93
|
+
action: "autoPlayAdd",
|
|
94
|
+
tracks: [track],
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
96
99
|
}
|
|
97
100
|
}
|
|
101
|
+
// Emit a player state update event with the added track(s)
|
|
102
|
+
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
103
|
+
changeType: Enums_1.PlayerStateEventTypes.QueueChange,
|
|
104
|
+
details: {
|
|
105
|
+
type: "queue",
|
|
106
|
+
action: "add",
|
|
107
|
+
tracks: isArray ? tracks : [track],
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
113
|
+
? err
|
|
114
|
+
: new MagmastreamError_1.MagmaStreamError({
|
|
115
|
+
code: Enums_1.MagmaStreamErrorCode.QUEUE_MEMORY_ERROR,
|
|
116
|
+
message: `Failed to add tracks to queue for guild ${this.guildId}: ${err.message}`,
|
|
117
|
+
cause: err,
|
|
118
|
+
});
|
|
119
|
+
console.error(error);
|
|
98
120
|
}
|
|
99
|
-
// Emit a player state update event with the added track(s)
|
|
100
|
-
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
101
|
-
changeType: Enums_1.PlayerStateEventTypes.QueueChange,
|
|
102
|
-
details: {
|
|
103
|
-
type: "queue",
|
|
104
|
-
action: "add",
|
|
105
|
-
tracks: isArray ? tracks : [track],
|
|
106
|
-
},
|
|
107
|
-
});
|
|
108
121
|
}
|
|
109
122
|
/**
|
|
110
123
|
* Adds a track to the previous tracks.
|
|
111
124
|
* @param track The track or tracks to add. Can be a single `Track` or an array of `Track`s.
|
|
112
125
|
*/
|
|
113
126
|
async addPrevious(track) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
127
|
+
try {
|
|
128
|
+
const max = this.manager.options.maxPreviousTracks;
|
|
129
|
+
if (Array.isArray(track)) {
|
|
130
|
+
const newTracks = track.filter((t) => !this.previous.some((p) => p.identifier === t.identifier));
|
|
131
|
+
this.previous.push(...newTracks);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
const exists = this.previous.some((p) => p.identifier === track.identifier);
|
|
135
|
+
if (!exists) {
|
|
136
|
+
this.previous.push(track);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (this.previous.length > max) {
|
|
140
|
+
this.previous = this.previous.slice(-max);
|
|
123
141
|
}
|
|
124
142
|
}
|
|
125
|
-
|
|
126
|
-
|
|
143
|
+
catch (err) {
|
|
144
|
+
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
145
|
+
? err
|
|
146
|
+
: new MagmastreamError_1.MagmaStreamError({
|
|
147
|
+
code: Enums_1.MagmaStreamErrorCode.QUEUE_MEMORY_ERROR,
|
|
148
|
+
message: `Failed to add tracks to previous tracks for guild ${this.guildId}: ${err.message}`,
|
|
149
|
+
cause: err,
|
|
150
|
+
});
|
|
151
|
+
console.error(error);
|
|
127
152
|
}
|
|
128
153
|
}
|
|
129
154
|
/**
|
|
@@ -131,21 +156,33 @@ class MemoryQueue extends Array {
|
|
|
131
156
|
* This will remove all tracks from the queue and emit a state update event.
|
|
132
157
|
*/
|
|
133
158
|
async clear() {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
159
|
+
try {
|
|
160
|
+
// Capture the current state of the player for event emission.
|
|
161
|
+
const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
|
|
162
|
+
// Remove all items from the queue.
|
|
163
|
+
this.splice(0);
|
|
164
|
+
// Emit an event to update the player state indicating the queue has been cleared.
|
|
165
|
+
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
166
|
+
changeType: Enums_1.PlayerStateEventTypes.QueueChange,
|
|
167
|
+
details: {
|
|
168
|
+
type: "queue",
|
|
169
|
+
action: "clear",
|
|
170
|
+
tracks: [], // No tracks are left after clearing
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
// Emit a debug message indicating the queue has been cleared for a specific guild ID.
|
|
174
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[MEMORYQUEUE] Cleared the queue for: ${this.guildId}`);
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
178
|
+
? err
|
|
179
|
+
: new MagmastreamError_1.MagmaStreamError({
|
|
180
|
+
code: Enums_1.MagmaStreamErrorCode.QUEUE_MEMORY_ERROR,
|
|
181
|
+
message: `Failed to clear queue for guild ${this.guildId}: ${err.message}`,
|
|
182
|
+
cause: err,
|
|
183
|
+
});
|
|
184
|
+
console.error(error);
|
|
185
|
+
}
|
|
149
186
|
}
|
|
150
187
|
/**
|
|
151
188
|
* Clears the previous tracks.
|
|
@@ -241,95 +278,119 @@ class MemoryQueue extends Array {
|
|
|
241
278
|
* @returns The newest track.
|
|
242
279
|
*/
|
|
243
280
|
async popPrevious() {
|
|
244
|
-
return this.previous.
|
|
281
|
+
return this.previous.pop() || null; // get newest track
|
|
245
282
|
}
|
|
246
283
|
async remove(startOrPosition = 0, end) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
284
|
+
try {
|
|
285
|
+
const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
|
|
286
|
+
if (typeof end !== "undefined") {
|
|
287
|
+
// Validate input for `start` and `end`
|
|
288
|
+
if (isNaN(Number(startOrPosition)) || isNaN(Number(end))) {
|
|
289
|
+
throw new RangeError(`Invalid "start" or "end" parameter: start = ${startOrPosition}, end = ${end}`);
|
|
290
|
+
}
|
|
291
|
+
if (startOrPosition >= end || startOrPosition >= this.length) {
|
|
292
|
+
throw new RangeError("Invalid range: start should be less than end and within queue length.");
|
|
293
|
+
}
|
|
294
|
+
const removedTracks = this.splice(startOrPosition, end - startOrPosition);
|
|
295
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[MEMORYQUEUE] Removed ${removedTracks.length} track(s) from player: ${this.guildId} from position ${startOrPosition} to ${end}.`);
|
|
296
|
+
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
297
|
+
changeType: Enums_1.PlayerStateEventTypes.QueueChange,
|
|
298
|
+
details: {
|
|
299
|
+
type: "queue",
|
|
300
|
+
action: "remove",
|
|
301
|
+
tracks: removedTracks,
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
return removedTracks;
|
|
255
305
|
}
|
|
256
|
-
|
|
257
|
-
|
|
306
|
+
// Single item removal when no end specified
|
|
307
|
+
const removedTrack = this.splice(startOrPosition, 1);
|
|
308
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[MEMORYQUEUE] Removed 1 track from player: ${this.guildId} from position ${startOrPosition}: ${Utils_1.JSONUtils.safe(removedTrack[0], 2)}`);
|
|
309
|
+
// Ensure removedTrack is an array for consistency
|
|
310
|
+
const tracksToEmit = removedTrack.length > 0 ? removedTrack : [];
|
|
258
311
|
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
259
312
|
changeType: Enums_1.PlayerStateEventTypes.QueueChange,
|
|
260
313
|
details: {
|
|
261
314
|
type: "queue",
|
|
262
315
|
action: "remove",
|
|
263
|
-
tracks:
|
|
316
|
+
tracks: tracksToEmit,
|
|
264
317
|
},
|
|
265
318
|
});
|
|
266
|
-
return
|
|
319
|
+
return removedTrack;
|
|
320
|
+
}
|
|
321
|
+
catch (err) {
|
|
322
|
+
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
323
|
+
? err
|
|
324
|
+
: new MagmastreamError_1.MagmaStreamError({
|
|
325
|
+
code: Enums_1.MagmaStreamErrorCode.QUEUE_MEMORY_ERROR,
|
|
326
|
+
message: `Failed to remove track(s) from queue for guild ${this.guildId}: ${err.message}`,
|
|
327
|
+
cause: err,
|
|
328
|
+
});
|
|
329
|
+
console.error(error);
|
|
267
330
|
}
|
|
268
|
-
// Single item removal when no end specified
|
|
269
|
-
const removedTrack = this.splice(startOrPosition, 1);
|
|
270
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] Removed 1 track from player: ${this.guildId} from position ${startOrPosition}: ${Utils_1.JSONUtils.safe(removedTrack[0], 2)}`);
|
|
271
|
-
// Ensure removedTrack is an array for consistency
|
|
272
|
-
const tracksToEmit = removedTrack.length > 0 ? removedTrack : [];
|
|
273
|
-
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
274
|
-
changeType: Enums_1.PlayerStateEventTypes.QueueChange,
|
|
275
|
-
details: {
|
|
276
|
-
type: "queue",
|
|
277
|
-
action: "remove",
|
|
278
|
-
tracks: tracksToEmit,
|
|
279
|
-
},
|
|
280
|
-
});
|
|
281
|
-
return removedTrack;
|
|
282
331
|
}
|
|
283
332
|
/**
|
|
284
333
|
* Shuffles the queue to play tracks requested by each user one by one.
|
|
285
334
|
*/
|
|
286
335
|
async roundRobinShuffle() {
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
userTracks.
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
336
|
+
try {
|
|
337
|
+
// Capture the current state of the player for event emission.
|
|
338
|
+
const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
|
|
339
|
+
// Group the tracks in the queue by the user that requested them.
|
|
340
|
+
const userTracks = new Map();
|
|
341
|
+
// Group the tracks in the queue by the user that requested them.
|
|
342
|
+
this.forEach((track) => {
|
|
343
|
+
const user = track.requester.id;
|
|
344
|
+
if (!userTracks.has(user)) {
|
|
345
|
+
userTracks.set(user, []);
|
|
346
|
+
}
|
|
347
|
+
userTracks.get(user).push(track);
|
|
348
|
+
});
|
|
349
|
+
// Shuffle the tracks of each user.
|
|
350
|
+
userTracks.forEach((tracks) => {
|
|
351
|
+
for (let i = tracks.length - 1; i > 0; i--) {
|
|
352
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
353
|
+
[tracks[i], tracks[j]] = [tracks[j], tracks[i]];
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
// Create a new array for the shuffled queue.
|
|
357
|
+
const shuffledQueue = [];
|
|
358
|
+
// Add the shuffled tracks to the queue in a round-robin fashion.
|
|
359
|
+
const users = Array.from(userTracks.keys());
|
|
360
|
+
const userQueues = users.map((user) => userTracks.get(user));
|
|
361
|
+
const userCount = users.length;
|
|
362
|
+
while (userQueues.some((queue) => queue.length > 0)) {
|
|
363
|
+
for (let i = 0; i < userCount; i++) {
|
|
364
|
+
const queue = userQueues[i];
|
|
365
|
+
if (queue.length > 0) {
|
|
366
|
+
shuffledQueue.push(queue.shift());
|
|
367
|
+
}
|
|
317
368
|
}
|
|
318
369
|
}
|
|
370
|
+
// Clear the queue and add the shuffled tracks.
|
|
371
|
+
this.splice(0);
|
|
372
|
+
this.add(shuffledQueue);
|
|
373
|
+
// Emit an event to update the player state indicating the queue has been shuffled.
|
|
374
|
+
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
375
|
+
changeType: Enums_1.PlayerStateEventTypes.QueueChange,
|
|
376
|
+
details: {
|
|
377
|
+
type: "queue",
|
|
378
|
+
action: "roundRobin",
|
|
379
|
+
},
|
|
380
|
+
});
|
|
381
|
+
// Emit a debug message indicating the queue has been shuffled for a specific guild ID.
|
|
382
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[MEMORYQUEUE] roundRobinShuffled the queue for: ${this.guildId}`);
|
|
383
|
+
}
|
|
384
|
+
catch (err) {
|
|
385
|
+
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
386
|
+
? err
|
|
387
|
+
: new MagmastreamError_1.MagmaStreamError({
|
|
388
|
+
code: Enums_1.MagmaStreamErrorCode.QUEUE_MEMORY_ERROR,
|
|
389
|
+
message: `Failed to shuffle queue for guild ${this.guildId}: ${err.message}`,
|
|
390
|
+
cause: err,
|
|
391
|
+
});
|
|
392
|
+
console.error(error);
|
|
319
393
|
}
|
|
320
|
-
// Clear the queue and add the shuffled tracks.
|
|
321
|
-
this.splice(0);
|
|
322
|
-
this.add(shuffledQueue);
|
|
323
|
-
// Emit an event to update the player state indicating the queue has been shuffled.
|
|
324
|
-
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
325
|
-
changeType: Enums_1.PlayerStateEventTypes.QueueChange,
|
|
326
|
-
details: {
|
|
327
|
-
type: "queue",
|
|
328
|
-
action: "roundRobin",
|
|
329
|
-
},
|
|
330
|
-
});
|
|
331
|
-
// Emit a debug message indicating the queue has been shuffled for a specific guild ID.
|
|
332
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] roundRobinShuffled the queue for: ${this.guildId}`);
|
|
333
394
|
}
|
|
334
395
|
/**
|
|
335
396
|
* @param track The track to set.
|
|
@@ -348,23 +409,35 @@ class MemoryQueue extends Array {
|
|
|
348
409
|
* This will randomize the order of the tracks in the queue and emit a state update event.
|
|
349
410
|
*/
|
|
350
411
|
async shuffle() {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
412
|
+
try {
|
|
413
|
+
// Capture the current state of the player for event emission.
|
|
414
|
+
const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
|
|
415
|
+
// Shuffle the queue.
|
|
416
|
+
for (let i = this.length - 1; i > 0; i--) {
|
|
417
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
418
|
+
[this[i], this[j]] = [this[j], this[i]];
|
|
419
|
+
}
|
|
420
|
+
// Emit an event to update the player state indicating the queue has been shuffled.
|
|
421
|
+
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
422
|
+
changeType: Enums_1.PlayerStateEventTypes.QueueChange,
|
|
423
|
+
details: {
|
|
424
|
+
type: "queue",
|
|
425
|
+
action: "shuffle",
|
|
426
|
+
},
|
|
427
|
+
});
|
|
428
|
+
// Emit a debug message indicating the queue has been shuffled for a specific guild ID.
|
|
429
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[MEMORYQUEUE] Shuffled the queue for: ${this.guildId}`);
|
|
430
|
+
}
|
|
431
|
+
catch (err) {
|
|
432
|
+
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
433
|
+
? err
|
|
434
|
+
: new MagmastreamError_1.MagmaStreamError({
|
|
435
|
+
code: Enums_1.MagmaStreamErrorCode.QUEUE_MEMORY_ERROR,
|
|
436
|
+
message: `Failed to shuffle queue for guild ${this.guildId}: ${err.message}`,
|
|
437
|
+
cause: err,
|
|
438
|
+
});
|
|
439
|
+
console.error(error);
|
|
357
440
|
}
|
|
358
|
-
// Emit an event to update the player state indicating the queue has been shuffled.
|
|
359
|
-
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
360
|
-
changeType: Enums_1.PlayerStateEventTypes.QueueChange,
|
|
361
|
-
details: {
|
|
362
|
-
type: "queue",
|
|
363
|
-
action: "shuffle",
|
|
364
|
-
},
|
|
365
|
-
});
|
|
366
|
-
// Emit a debug message indicating the queue has been shuffled for a specific guild ID.
|
|
367
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] Shuffled the queue for: ${this.guildId}`);
|
|
368
441
|
}
|
|
369
442
|
/**
|
|
370
443
|
* The size of tracks in the queue.
|
|
@@ -392,42 +465,54 @@ class MemoryQueue extends Array {
|
|
|
392
465
|
* Shuffles the queue to play tracks requested by each user one block at a time.
|
|
393
466
|
*/
|
|
394
467
|
async userBlockShuffle() {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
userTracks.
|
|
403
|
-
|
|
404
|
-
userTracks.get(user).push(track);
|
|
405
|
-
});
|
|
406
|
-
// Create a new array for the shuffled queue.
|
|
407
|
-
const shuffledQueue = [];
|
|
408
|
-
// Iterate over the user tracks and add one track from each user to the shuffled queue.
|
|
409
|
-
// This will ensure that all the tracks requested by each user are played in a block order.
|
|
410
|
-
while (shuffledQueue.length < this.length) {
|
|
411
|
-
userTracks.forEach((tracks) => {
|
|
412
|
-
const track = tracks.shift();
|
|
413
|
-
if (track) {
|
|
414
|
-
shuffledQueue.push(track);
|
|
468
|
+
try {
|
|
469
|
+
// Capture the current state of the player for event emission.
|
|
470
|
+
const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
|
|
471
|
+
// Group the tracks in the queue by the user that requested them.
|
|
472
|
+
const userTracks = new Map();
|
|
473
|
+
this.forEach((track) => {
|
|
474
|
+
const user = track.requester.id;
|
|
475
|
+
if (!userTracks.has(user)) {
|
|
476
|
+
userTracks.set(user, []);
|
|
415
477
|
}
|
|
478
|
+
userTracks.get(user).push(track);
|
|
416
479
|
});
|
|
480
|
+
// Create a new array for the shuffled queue.
|
|
481
|
+
const shuffledQueue = [];
|
|
482
|
+
// Iterate over the user tracks and add one track from each user to the shuffled queue.
|
|
483
|
+
// This will ensure that all the tracks requested by each user are played in a block order.
|
|
484
|
+
while (shuffledQueue.length < this.length) {
|
|
485
|
+
userTracks.forEach((tracks) => {
|
|
486
|
+
const track = tracks.shift();
|
|
487
|
+
if (track) {
|
|
488
|
+
shuffledQueue.push(track);
|
|
489
|
+
}
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
// Clear the queue and add the shuffled tracks.
|
|
493
|
+
this.splice(0);
|
|
494
|
+
this.add(shuffledQueue);
|
|
495
|
+
// Emit an event to update the player state indicating the queue has been shuffled.
|
|
496
|
+
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
497
|
+
changeType: Enums_1.PlayerStateEventTypes.QueueChange,
|
|
498
|
+
details: {
|
|
499
|
+
type: "queue",
|
|
500
|
+
action: "userBlock",
|
|
501
|
+
},
|
|
502
|
+
});
|
|
503
|
+
// Emit a debug message indicating the queue has been shuffled for a specific guild ID.
|
|
504
|
+
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[MEMORYQUEUE] userBlockShuffled the queue for: ${this.guildId}`);
|
|
505
|
+
}
|
|
506
|
+
catch (err) {
|
|
507
|
+
const error = err instanceof MagmastreamError_1.MagmaStreamError
|
|
508
|
+
? err
|
|
509
|
+
: new MagmastreamError_1.MagmaStreamError({
|
|
510
|
+
code: Enums_1.MagmaStreamErrorCode.QUEUE_MEMORY_ERROR,
|
|
511
|
+
message: `Failed to add tracks to queue for guild ${this.guildId}: ${err.message}`,
|
|
512
|
+
cause: err,
|
|
513
|
+
});
|
|
514
|
+
console.error(error);
|
|
417
515
|
}
|
|
418
|
-
// Clear the queue and add the shuffled tracks.
|
|
419
|
-
this.splice(0);
|
|
420
|
-
this.add(shuffledQueue);
|
|
421
|
-
// Emit an event to update the player state indicating the queue has been shuffled.
|
|
422
|
-
this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
423
|
-
changeType: Enums_1.PlayerStateEventTypes.QueueChange,
|
|
424
|
-
details: {
|
|
425
|
-
type: "queue",
|
|
426
|
-
action: "userBlock",
|
|
427
|
-
},
|
|
428
|
-
});
|
|
429
|
-
// Emit a debug message indicating the queue has been shuffled for a specific guild ID.
|
|
430
|
-
this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] userBlockShuffled the queue for: ${this.guildId}`);
|
|
431
516
|
}
|
|
432
517
|
}
|
|
433
518
|
exports.MemoryQueue = MemoryQueue;
|