magmastream 2.9.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.
@@ -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,92 +35,112 @@ 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
- const isArray = Array.isArray(track);
38
- const tracks = isArray ? [...track] : [track];
39
- // Get the track info as a string
40
- const trackInfo = isArray ? tracks.map((t) => Utils_1.JSONUtils.safe(t, 2)).join(", ") : Utils_1.JSONUtils.safe(track, 2);
41
- // Emit a debug message
42
- this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] Added ${tracks.length} track(s) to queue: ${trackInfo}`);
43
- const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
44
- // If the queue is empty, set the track as the current track
45
- if (!this.current) {
46
- if (isArray) {
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, `[QUEUE] 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.splice(offset, 0, ...tracks);
49
+ this.current = tracks.shift() || null;
50
+ this.push(...tracks);
68
51
  }
69
52
  else {
70
- this.splice(offset, 0, track);
53
+ this.current = track;
71
54
  }
72
55
  }
73
56
  else {
74
- // If no offset is provided, add the track(s) at the end of the queue
75
- if (isArray) {
76
- this.push(...tracks);
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
- this.push(track);
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
- if (this.manager.players.has(this.guildId) && this.manager.players.get(this.guildId).isAutoplay) {
84
- if (!isArray) {
85
- const AutoplayUser = this.manager.players.get(this.guildId).get("Internal_AutoplayUser");
86
- if (AutoplayUser && AutoplayUser.id === track.requester.id) {
87
- this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
88
- changeType: Enums_1.PlayerStateEventTypes.QueueChange,
89
- details: {
90
- type: "queue",
91
- action: "autoPlayAdd",
92
- tracks: [track],
93
- },
94
- });
95
- return;
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
+ throw new MagmastreamError_1.MagmaStreamError({
113
+ code: Enums_1.MagmaStreamErrorCode.QUEUE_MEMORY_ERROR,
114
+ message: `Failed to add tracks to queue for guild ${this.guildId}: ${err.message}`,
115
+ });
98
116
  }
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
117
  }
109
118
  /**
110
119
  * Adds a track to the previous tracks.
111
120
  * @param track The track or tracks to add. Can be a single `Track` or an array of `Track`s.
112
121
  */
113
122
  async addPrevious(track) {
114
- if (Array.isArray(track)) {
115
- const newTracks = track.filter((t) => !this.previous.some((p) => p.identifier === t.identifier));
116
- this.previous.unshift(...newTracks);
117
- }
118
- else {
119
- const exists = this.previous.some((p) => p.identifier === track.identifier);
120
- if (!exists) {
121
- this.previous.unshift(track);
123
+ try {
124
+ const max = this.manager.options.maxPreviousTracks;
125
+ if (Array.isArray(track)) {
126
+ const newTracks = track.filter((t) => !this.previous.some((p) => p.identifier === t.identifier));
127
+ this.previous.push(...newTracks);
128
+ }
129
+ else {
130
+ const exists = this.previous.some((p) => p.identifier === track.identifier);
131
+ if (!exists) {
132
+ this.previous.push(track);
133
+ }
122
134
  }
135
+ if (this.previous.length > max) {
136
+ this.previous = this.previous.slice(-max);
137
+ }
138
+ }
139
+ catch (err) {
140
+ throw new MagmastreamError_1.MagmaStreamError({
141
+ code: Enums_1.MagmaStreamErrorCode.QUEUE_MEMORY_ERROR,
142
+ message: `Failed to add tracks to previous tracks for guild ${this.guildId}: ${err.message}`,
143
+ });
123
144
  }
124
145
  }
125
146
  /**
@@ -127,21 +148,29 @@ class MemoryQueue extends Array {
127
148
  * This will remove all tracks from the queue and emit a state update event.
128
149
  */
129
150
  async clear() {
130
- // Capture the current state of the player for event emission.
131
- const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
132
- // Remove all items from the queue.
133
- this.splice(0);
134
- // Emit an event to update the player state indicating the queue has been cleared.
135
- this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
136
- changeType: Enums_1.PlayerStateEventTypes.QueueChange,
137
- details: {
138
- type: "queue",
139
- action: "clear",
140
- tracks: [], // No tracks are left after clearing
141
- },
142
- });
143
- // Emit a debug message indicating the queue has been cleared for a specific guild ID.
144
- this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] Cleared the queue for: ${this.guildId}`);
151
+ try {
152
+ // Capture the current state of the player for event emission.
153
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
154
+ // Remove all items from the queue.
155
+ this.splice(0);
156
+ // Emit an event to update the player state indicating the queue has been cleared.
157
+ this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
158
+ changeType: Enums_1.PlayerStateEventTypes.QueueChange,
159
+ details: {
160
+ type: "queue",
161
+ action: "clear",
162
+ tracks: [], // No tracks are left after clearing
163
+ },
164
+ });
165
+ // Emit a debug message indicating the queue has been cleared for a specific guild ID.
166
+ this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] Cleared the queue for: ${this.guildId}`);
167
+ }
168
+ catch (err) {
169
+ throw new MagmastreamError_1.MagmaStreamError({
170
+ code: Enums_1.MagmaStreamErrorCode.QUEUE_MEMORY_ERROR,
171
+ message: `Failed to clear queue for guild ${this.guildId}: ${err.message}`,
172
+ });
173
+ }
145
174
  }
146
175
  /**
147
176
  * Clears the previous tracks.
@@ -237,95 +266,111 @@ class MemoryQueue extends Array {
237
266
  * @returns The newest track.
238
267
  */
239
268
  async popPrevious() {
240
- return this.previous.shift() || null; // get newest track
269
+ return this.previous.pop() || null; // get newest track
241
270
  }
242
271
  async remove(startOrPosition = 0, end) {
243
- const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
244
- if (typeof end !== "undefined") {
245
- // Validate input for `start` and `end`
246
- if (isNaN(Number(startOrPosition)) || isNaN(Number(end))) {
247
- throw new RangeError(`Invalid "start" or "end" parameter: start = ${startOrPosition}, end = ${end}`);
248
- }
249
- if (startOrPosition >= end || startOrPosition >= this.length) {
250
- throw new RangeError("Invalid range: start should be less than end and within queue length.");
272
+ try {
273
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
274
+ if (typeof end !== "undefined") {
275
+ // Validate input for `start` and `end`
276
+ if (isNaN(Number(startOrPosition)) || isNaN(Number(end))) {
277
+ throw new RangeError(`Invalid "start" or "end" parameter: start = ${startOrPosition}, end = ${end}`);
278
+ }
279
+ if (startOrPosition >= end || startOrPosition >= this.length) {
280
+ throw new RangeError("Invalid range: start should be less than end and within queue length.");
281
+ }
282
+ const removedTracks = this.splice(startOrPosition, end - startOrPosition);
283
+ this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] Removed ${removedTracks.length} track(s) from player: ${this.guildId} from position ${startOrPosition} to ${end}.`);
284
+ this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
285
+ changeType: Enums_1.PlayerStateEventTypes.QueueChange,
286
+ details: {
287
+ type: "queue",
288
+ action: "remove",
289
+ tracks: removedTracks,
290
+ },
291
+ });
292
+ return removedTracks;
251
293
  }
252
- const removedTracks = this.splice(startOrPosition, end - startOrPosition);
253
- this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] Removed ${removedTracks.length} track(s) from player: ${this.guildId} from position ${startOrPosition} to ${end}.`);
294
+ // Single item removal when no end specified
295
+ const removedTrack = this.splice(startOrPosition, 1);
296
+ 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)}`);
297
+ // Ensure removedTrack is an array for consistency
298
+ const tracksToEmit = removedTrack.length > 0 ? removedTrack : [];
254
299
  this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
255
300
  changeType: Enums_1.PlayerStateEventTypes.QueueChange,
256
301
  details: {
257
302
  type: "queue",
258
303
  action: "remove",
259
- tracks: removedTracks,
304
+ tracks: tracksToEmit,
260
305
  },
261
306
  });
262
- return removedTracks;
307
+ return removedTrack;
308
+ }
309
+ catch (err) {
310
+ throw new MagmastreamError_1.MagmaStreamError({
311
+ code: Enums_1.MagmaStreamErrorCode.QUEUE_MEMORY_ERROR,
312
+ message: `Failed to remove track(s) from queue for guild ${this.guildId}: ${err.message}`,
313
+ });
263
314
  }
264
- // Single item removal when no end specified
265
- const removedTrack = this.splice(startOrPosition, 1);
266
- 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)}`);
267
- // Ensure removedTrack is an array for consistency
268
- const tracksToEmit = removedTrack.length > 0 ? removedTrack : [];
269
- this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
270
- changeType: Enums_1.PlayerStateEventTypes.QueueChange,
271
- details: {
272
- type: "queue",
273
- action: "remove",
274
- tracks: tracksToEmit,
275
- },
276
- });
277
- return removedTrack;
278
315
  }
279
316
  /**
280
317
  * Shuffles the queue to play tracks requested by each user one by one.
281
318
  */
282
319
  async roundRobinShuffle() {
283
- // Capture the current state of the player for event emission.
284
- const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
285
- // Group the tracks in the queue by the user that requested them.
286
- const userTracks = new Map();
287
- // Group the tracks in the queue by the user that requested them.
288
- this.forEach((track) => {
289
- const user = track.requester.id;
290
- if (!userTracks.has(user)) {
291
- userTracks.set(user, []);
292
- }
293
- userTracks.get(user).push(track);
294
- });
295
- // Shuffle the tracks of each user.
296
- userTracks.forEach((tracks) => {
297
- for (let i = tracks.length - 1; i > 0; i--) {
298
- const j = Math.floor(Math.random() * (i + 1));
299
- [tracks[i], tracks[j]] = [tracks[j], tracks[i]];
300
- }
301
- });
302
- // Create a new array for the shuffled queue.
303
- const shuffledQueue = [];
304
- // Add the shuffled tracks to the queue in a round-robin fashion.
305
- const users = Array.from(userTracks.keys());
306
- const userQueues = users.map((user) => userTracks.get(user));
307
- const userCount = users.length;
308
- while (userQueues.some((queue) => queue.length > 0)) {
309
- for (let i = 0; i < userCount; i++) {
310
- const queue = userQueues[i];
311
- if (queue.length > 0) {
312
- shuffledQueue.push(queue.shift());
320
+ try {
321
+ // Capture the current state of the player for event emission.
322
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
323
+ // Group the tracks in the queue by the user that requested them.
324
+ const userTracks = new Map();
325
+ // Group the tracks in the queue by the user that requested them.
326
+ this.forEach((track) => {
327
+ const user = track.requester.id;
328
+ if (!userTracks.has(user)) {
329
+ userTracks.set(user, []);
330
+ }
331
+ userTracks.get(user).push(track);
332
+ });
333
+ // Shuffle the tracks of each user.
334
+ userTracks.forEach((tracks) => {
335
+ for (let i = tracks.length - 1; i > 0; i--) {
336
+ const j = Math.floor(Math.random() * (i + 1));
337
+ [tracks[i], tracks[j]] = [tracks[j], tracks[i]];
338
+ }
339
+ });
340
+ // Create a new array for the shuffled queue.
341
+ const shuffledQueue = [];
342
+ // Add the shuffled tracks to the queue in a round-robin fashion.
343
+ const users = Array.from(userTracks.keys());
344
+ const userQueues = users.map((user) => userTracks.get(user));
345
+ const userCount = users.length;
346
+ while (userQueues.some((queue) => queue.length > 0)) {
347
+ for (let i = 0; i < userCount; i++) {
348
+ const queue = userQueues[i];
349
+ if (queue.length > 0) {
350
+ shuffledQueue.push(queue.shift());
351
+ }
313
352
  }
314
353
  }
354
+ // Clear the queue and add the shuffled tracks.
355
+ this.splice(0);
356
+ this.add(shuffledQueue);
357
+ // Emit an event to update the player state indicating the queue has been shuffled.
358
+ this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
359
+ changeType: Enums_1.PlayerStateEventTypes.QueueChange,
360
+ details: {
361
+ type: "queue",
362
+ action: "roundRobin",
363
+ },
364
+ });
365
+ // Emit a debug message indicating the queue has been shuffled for a specific guild ID.
366
+ this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] roundRobinShuffled the queue for: ${this.guildId}`);
367
+ }
368
+ catch (err) {
369
+ throw new MagmastreamError_1.MagmaStreamError({
370
+ code: Enums_1.MagmaStreamErrorCode.QUEUE_MEMORY_ERROR,
371
+ message: `Failed to shuffle queue for guild ${this.guildId}: ${err.message}`,
372
+ });
315
373
  }
316
- // Clear the queue and add the shuffled tracks.
317
- this.splice(0);
318
- this.add(shuffledQueue);
319
- // Emit an event to update the player state indicating the queue has been shuffled.
320
- this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
321
- changeType: Enums_1.PlayerStateEventTypes.QueueChange,
322
- details: {
323
- type: "queue",
324
- action: "roundRobin",
325
- },
326
- });
327
- // Emit a debug message indicating the queue has been shuffled for a specific guild ID.
328
- this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] roundRobinShuffled the queue for: ${this.guildId}`);
329
374
  }
330
375
  /**
331
376
  * @param track The track to set.
@@ -344,23 +389,31 @@ class MemoryQueue extends Array {
344
389
  * This will randomize the order of the tracks in the queue and emit a state update event.
345
390
  */
346
391
  async shuffle() {
347
- // Capture the current state of the player for event emission.
348
- const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
349
- // Shuffle the queue.
350
- for (let i = this.length - 1; i > 0; i--) {
351
- const j = Math.floor(Math.random() * (i + 1));
352
- [this[i], this[j]] = [this[j], this[i]];
392
+ try {
393
+ // Capture the current state of the player for event emission.
394
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
395
+ // Shuffle the queue.
396
+ for (let i = this.length - 1; i > 0; i--) {
397
+ const j = Math.floor(Math.random() * (i + 1));
398
+ [this[i], this[j]] = [this[j], this[i]];
399
+ }
400
+ // Emit an event to update the player state indicating the queue has been shuffled.
401
+ this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
402
+ changeType: Enums_1.PlayerStateEventTypes.QueueChange,
403
+ details: {
404
+ type: "queue",
405
+ action: "shuffle",
406
+ },
407
+ });
408
+ // Emit a debug message indicating the queue has been shuffled for a specific guild ID.
409
+ this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] Shuffled the queue for: ${this.guildId}`);
410
+ }
411
+ catch (err) {
412
+ throw new MagmastreamError_1.MagmaStreamError({
413
+ code: Enums_1.MagmaStreamErrorCode.QUEUE_MEMORY_ERROR,
414
+ message: `Failed to shuffle queue for guild ${this.guildId}: ${err.message}`,
415
+ });
353
416
  }
354
- // Emit an event to update the player state indicating the queue has been shuffled.
355
- this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
356
- changeType: Enums_1.PlayerStateEventTypes.QueueChange,
357
- details: {
358
- type: "queue",
359
- action: "shuffle",
360
- },
361
- });
362
- // Emit a debug message indicating the queue has been shuffled for a specific guild ID.
363
- this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] Shuffled the queue for: ${this.guildId}`);
364
417
  }
365
418
  /**
366
419
  * The size of tracks in the queue.
@@ -388,42 +441,50 @@ class MemoryQueue extends Array {
388
441
  * Shuffles the queue to play tracks requested by each user one block at a time.
389
442
  */
390
443
  async userBlockShuffle() {
391
- // Capture the current state of the player for event emission.
392
- const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
393
- // Group the tracks in the queue by the user that requested them.
394
- const userTracks = new Map();
395
- this.forEach((track) => {
396
- const user = track.requester.id;
397
- if (!userTracks.has(user)) {
398
- userTracks.set(user, []);
399
- }
400
- userTracks.get(user).push(track);
401
- });
402
- // Create a new array for the shuffled queue.
403
- const shuffledQueue = [];
404
- // Iterate over the user tracks and add one track from each user to the shuffled queue.
405
- // This will ensure that all the tracks requested by each user are played in a block order.
406
- while (shuffledQueue.length < this.length) {
407
- userTracks.forEach((tracks) => {
408
- const track = tracks.shift();
409
- if (track) {
410
- shuffledQueue.push(track);
444
+ try {
445
+ // Capture the current state of the player for event emission.
446
+ const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
447
+ // Group the tracks in the queue by the user that requested them.
448
+ const userTracks = new Map();
449
+ this.forEach((track) => {
450
+ const user = track.requester.id;
451
+ if (!userTracks.has(user)) {
452
+ userTracks.set(user, []);
411
453
  }
454
+ userTracks.get(user).push(track);
455
+ });
456
+ // Create a new array for the shuffled queue.
457
+ const shuffledQueue = [];
458
+ // Iterate over the user tracks and add one track from each user to the shuffled queue.
459
+ // This will ensure that all the tracks requested by each user are played in a block order.
460
+ while (shuffledQueue.length < this.length) {
461
+ userTracks.forEach((tracks) => {
462
+ const track = tracks.shift();
463
+ if (track) {
464
+ shuffledQueue.push(track);
465
+ }
466
+ });
467
+ }
468
+ // Clear the queue and add the shuffled tracks.
469
+ this.splice(0);
470
+ this.add(shuffledQueue);
471
+ // Emit an event to update the player state indicating the queue has been shuffled.
472
+ this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
473
+ changeType: Enums_1.PlayerStateEventTypes.QueueChange,
474
+ details: {
475
+ type: "queue",
476
+ action: "userBlock",
477
+ },
478
+ });
479
+ // Emit a debug message indicating the queue has been shuffled for a specific guild ID.
480
+ this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] userBlockShuffled the queue for: ${this.guildId}`);
481
+ }
482
+ catch (err) {
483
+ throw new MagmastreamError_1.MagmaStreamError({
484
+ code: Enums_1.MagmaStreamErrorCode.QUEUE_MEMORY_ERROR,
485
+ message: `Failed to shuffle queue for guild ${this.guildId}: ${err.message}`,
412
486
  });
413
487
  }
414
- // Clear the queue and add the shuffled tracks.
415
- this.splice(0);
416
- this.add(shuffledQueue);
417
- // Emit an event to update the player state indicating the queue has been shuffled.
418
- this.manager.emit(Enums_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
419
- changeType: Enums_1.PlayerStateEventTypes.QueueChange,
420
- details: {
421
- type: "queue",
422
- action: "userBlock",
423
- },
424
- });
425
- // Emit a debug message indicating the queue has been shuffled for a specific guild ID.
426
- this.manager.emit(Enums_1.ManagerEventTypes.Debug, `[QUEUE] userBlockShuffled the queue for: ${this.guildId}`);
427
488
  }
428
489
  }
429
490
  exports.MemoryQueue = MemoryQueue;