magmastream 2.9.0-dev.18 → 2.9.0-dev.19
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 +11 -1
- package/dist/storage/CollectionPlayerStore.js +1 -4
- package/dist/storage/RedisPlayerStore.js +4 -7
- package/dist/structures/Manager.js +366 -164
- package/dist/structures/Node.js +5 -8
- package/dist/structures/Player.js +16 -6
- package/dist/structures/Queue.js +213 -259
- package/dist/structures/RedisQueue.js +208 -250
- package/dist/structures/Utils.js +56 -0
- package/package.json +1 -1
- package/dist/utils/logExecutionTime.js +0 -11
package/dist/structures/Queue.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Queue = void 0;
|
|
4
4
|
const Manager_1 = require("./Manager"); // Import Manager to access emit method
|
|
5
|
-
const logExecutionTime_1 = require("../utils/logExecutionTime");
|
|
6
5
|
/**
|
|
7
6
|
* The player's queue, the `current` property is the currently playing track, think of the rest as the up-coming tracks.
|
|
8
7
|
*/
|
|
@@ -28,44 +27,35 @@ class Queue extends Array {
|
|
|
28
27
|
this.guildId = guildId;
|
|
29
28
|
}
|
|
30
29
|
async getCurrent() {
|
|
31
|
-
return
|
|
32
|
-
return this.current;
|
|
33
|
-
});
|
|
30
|
+
return this.current;
|
|
34
31
|
}
|
|
35
32
|
async setCurrent(track) {
|
|
36
|
-
|
|
37
|
-
this.current = track;
|
|
38
|
-
});
|
|
33
|
+
this.current = track;
|
|
39
34
|
}
|
|
40
35
|
async getPrevious() {
|
|
41
|
-
return
|
|
42
|
-
return this.previous;
|
|
43
|
-
});
|
|
36
|
+
return this.previous;
|
|
44
37
|
}
|
|
45
38
|
async addPrevious(track) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
39
|
+
if (Array.isArray(track)) {
|
|
40
|
+
this.previous.unshift(...track);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
this.previous.unshift(track);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async setPrevious(tracks) {
|
|
47
|
+
this.previous = [...tracks];
|
|
54
48
|
}
|
|
55
49
|
async clearPrevious() {
|
|
56
|
-
|
|
57
|
-
this.previous = [];
|
|
58
|
-
});
|
|
50
|
+
this.previous = [];
|
|
59
51
|
}
|
|
60
52
|
/**
|
|
61
53
|
* The total duration of the queue in milliseconds.
|
|
62
54
|
* This includes the duration of the currently playing track.
|
|
63
55
|
*/
|
|
64
56
|
async duration() {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return this.reduce((acc, cur) => acc + (cur.duration || 0), current);
|
|
68
|
-
});
|
|
57
|
+
const current = this.current?.duration ?? 0;
|
|
58
|
+
return this.reduce((acc, cur) => acc + (cur.duration || 0), current);
|
|
69
59
|
}
|
|
70
60
|
/**
|
|
71
61
|
* The total size of tracks in the queue including the current track.
|
|
@@ -73,9 +63,7 @@ class Queue extends Array {
|
|
|
73
63
|
* @returns The total size of tracks in the queue including the current track.
|
|
74
64
|
*/
|
|
75
65
|
async totalSize() {
|
|
76
|
-
return
|
|
77
|
-
return this.length + (this.current ? 1 : 0);
|
|
78
|
-
});
|
|
66
|
+
return this.length + (this.current ? 1 : 0);
|
|
79
67
|
}
|
|
80
68
|
/**
|
|
81
69
|
* The size of tracks in the queue.
|
|
@@ -83,9 +71,7 @@ class Queue extends Array {
|
|
|
83
71
|
* @returns The size of tracks in the queue.
|
|
84
72
|
*/
|
|
85
73
|
async size() {
|
|
86
|
-
return
|
|
87
|
-
return this.length;
|
|
88
|
-
});
|
|
74
|
+
return this.length;
|
|
89
75
|
}
|
|
90
76
|
/**
|
|
91
77
|
* Adds a track to the queue.
|
|
@@ -93,307 +79,275 @@ class Queue extends Array {
|
|
|
93
79
|
* @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.
|
|
94
80
|
*/
|
|
95
81
|
async add(track, offset) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if (
|
|
82
|
+
// Get the track info as a string
|
|
83
|
+
const trackInfo = Array.isArray(track) ? track.map((t) => JSON.stringify(t, null, 2)).join(", ") : JSON.stringify(track, null, 2);
|
|
84
|
+
// Emit a debug message
|
|
85
|
+
this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Added ${Array.isArray(track) ? track.length : 1} track(s) to queue: ${trackInfo}`);
|
|
86
|
+
const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
|
|
87
|
+
// If the queue is empty, set the track as the current track
|
|
88
|
+
if (!this.current) {
|
|
89
|
+
if (Array.isArray(track)) {
|
|
90
|
+
this.current = track.shift() || null;
|
|
91
|
+
this.push(...track);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
this.current = track;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
// If an offset is provided, add the track(s) at that position
|
|
99
|
+
if (typeof offset !== "undefined" && typeof offset === "number") {
|
|
100
|
+
// Validate the offset
|
|
101
|
+
if (isNaN(offset)) {
|
|
102
|
+
throw new RangeError("Offset must be a number.");
|
|
103
|
+
}
|
|
104
|
+
// Make sure the offset is between 0 and the length of the queue
|
|
105
|
+
if (offset < 0 || offset > this.length) {
|
|
106
|
+
throw new RangeError(`Offset must be between 0 and ${this.length}.`);
|
|
107
|
+
}
|
|
108
|
+
// Add the track(s) at the offset position
|
|
104
109
|
if (Array.isArray(track)) {
|
|
105
|
-
this.
|
|
106
|
-
this.push(...track);
|
|
110
|
+
this.splice(offset, 0, ...track);
|
|
107
111
|
}
|
|
108
112
|
else {
|
|
109
|
-
this.
|
|
113
|
+
this.splice(offset, 0, track);
|
|
110
114
|
}
|
|
111
115
|
}
|
|
112
116
|
else {
|
|
113
|
-
// If
|
|
114
|
-
if (
|
|
115
|
-
|
|
116
|
-
if (isNaN(offset)) {
|
|
117
|
-
throw new RangeError("Offset must be a number.");
|
|
118
|
-
}
|
|
119
|
-
// Make sure the offset is between 0 and the length of the queue
|
|
120
|
-
if (offset < 0 || offset > this.length) {
|
|
121
|
-
throw new RangeError(`Offset must be between 0 and ${this.length}.`);
|
|
122
|
-
}
|
|
123
|
-
// Add the track(s) at the offset position
|
|
124
|
-
if (Array.isArray(track)) {
|
|
125
|
-
this.splice(offset, 0, ...track);
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
this.splice(offset, 0, track);
|
|
129
|
-
}
|
|
117
|
+
// If no offset is provided, add the track(s) at the end of the queue
|
|
118
|
+
if (Array.isArray(track)) {
|
|
119
|
+
this.push(...track);
|
|
130
120
|
}
|
|
131
121
|
else {
|
|
132
|
-
|
|
133
|
-
if (Array.isArray(track)) {
|
|
134
|
-
this.push(...track);
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
this.push(track);
|
|
138
|
-
}
|
|
122
|
+
this.push(track);
|
|
139
123
|
}
|
|
140
124
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
|
|
125
|
+
}
|
|
126
|
+
if (this.manager.players.has(this.guildId) && this.manager.players.get(this.guildId).isAutoplay) {
|
|
127
|
+
if (!Array.isArray(track)) {
|
|
128
|
+
const botUser = this.manager.players.get(this.guildId).get("Internal_BotUser");
|
|
129
|
+
if (botUser && botUser.id === track.requester.id) {
|
|
130
|
+
this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
131
|
+
changeType: Manager_1.PlayerStateEventTypes.QueueChange,
|
|
132
|
+
details: {
|
|
133
|
+
changeType: "autoPlayAdd",
|
|
134
|
+
tracks: Array.isArray(track) ? track : [track],
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
return;
|
|
154
138
|
}
|
|
155
139
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
140
|
+
}
|
|
141
|
+
// Emit a player state update event with the added track(s)
|
|
142
|
+
this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
143
|
+
changeType: Manager_1.PlayerStateEventTypes.QueueChange,
|
|
144
|
+
details: {
|
|
145
|
+
changeType: "add",
|
|
146
|
+
tracks: Array.isArray(track) ? track : [track],
|
|
147
|
+
},
|
|
164
148
|
});
|
|
165
149
|
}
|
|
166
150
|
async remove(startOrPosition = 0, end) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
throw new RangeError("Invalid range: start should be less than end and within queue length.");
|
|
176
|
-
}
|
|
177
|
-
const removedTracks = this.splice(startOrPosition, end - startOrPosition);
|
|
178
|
-
this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Removed ${removedTracks.length} track(s) from player: ${this.guildId} from position ${startOrPosition} to ${end}.`);
|
|
179
|
-
this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
180
|
-
changeType: Manager_1.PlayerStateEventTypes.QueueChange,
|
|
181
|
-
details: {
|
|
182
|
-
changeType: "remove",
|
|
183
|
-
tracks: removedTracks,
|
|
184
|
-
},
|
|
185
|
-
});
|
|
186
|
-
return removedTracks;
|
|
151
|
+
const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
|
|
152
|
+
if (typeof end !== "undefined") {
|
|
153
|
+
// Validate input for `start` and `end`
|
|
154
|
+
if (isNaN(Number(startOrPosition)) || isNaN(Number(end))) {
|
|
155
|
+
throw new RangeError(`Invalid "start" or "end" parameter: start = ${startOrPosition}, end = ${end}`);
|
|
156
|
+
}
|
|
157
|
+
if (startOrPosition >= end || startOrPosition >= this.length) {
|
|
158
|
+
throw new RangeError("Invalid range: start should be less than end and within queue length.");
|
|
187
159
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Removed 1 track from player: ${this.guildId} from position ${startOrPosition}: ${JSON.stringify(removedTrack[0], null, 2)}`);
|
|
191
|
-
// Ensure removedTrack is an array for consistency
|
|
192
|
-
const tracksToEmit = removedTrack.length > 0 ? removedTrack : [];
|
|
160
|
+
const removedTracks = this.splice(startOrPosition, end - startOrPosition);
|
|
161
|
+
this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Removed ${removedTracks.length} track(s) from player: ${this.guildId} from position ${startOrPosition} to ${end}.`);
|
|
193
162
|
this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
194
163
|
changeType: Manager_1.PlayerStateEventTypes.QueueChange,
|
|
195
164
|
details: {
|
|
196
165
|
changeType: "remove",
|
|
197
|
-
tracks:
|
|
166
|
+
tracks: removedTracks,
|
|
198
167
|
},
|
|
199
168
|
});
|
|
200
|
-
return
|
|
169
|
+
return removedTracks;
|
|
170
|
+
}
|
|
171
|
+
// Single item removal when no end specified
|
|
172
|
+
const removedTrack = this.splice(startOrPosition, 1);
|
|
173
|
+
this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Removed 1 track from player: ${this.guildId} from position ${startOrPosition}: ${JSON.stringify(removedTrack[0], null, 2)}`);
|
|
174
|
+
// Ensure removedTrack is an array for consistency
|
|
175
|
+
const tracksToEmit = removedTrack.length > 0 ? removedTrack : [];
|
|
176
|
+
this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
177
|
+
changeType: Manager_1.PlayerStateEventTypes.QueueChange,
|
|
178
|
+
details: {
|
|
179
|
+
changeType: "remove",
|
|
180
|
+
tracks: tracksToEmit,
|
|
181
|
+
},
|
|
201
182
|
});
|
|
183
|
+
return removedTrack;
|
|
202
184
|
}
|
|
203
185
|
/**
|
|
204
186
|
* Clears the queue.
|
|
205
187
|
* This will remove all tracks from the queue and emit a state update event.
|
|
206
188
|
*/
|
|
207
189
|
async clear() {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
},
|
|
220
|
-
});
|
|
221
|
-
// Emit a debug message indicating the queue has been cleared for a specific guild ID.
|
|
222
|
-
this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Cleared the queue for: ${this.guildId}`);
|
|
190
|
+
// Capture the current state of the player for event emission.
|
|
191
|
+
const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
|
|
192
|
+
// Remove all items from the queue.
|
|
193
|
+
this.splice(0);
|
|
194
|
+
// Emit an event to update the player state indicating the queue has been cleared.
|
|
195
|
+
this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
196
|
+
changeType: Manager_1.PlayerStateEventTypes.QueueChange,
|
|
197
|
+
details: {
|
|
198
|
+
changeType: "clear",
|
|
199
|
+
tracks: [], // No tracks are left after clearing
|
|
200
|
+
},
|
|
223
201
|
});
|
|
202
|
+
// Emit a debug message indicating the queue has been cleared for a specific guild ID.
|
|
203
|
+
this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Cleared the queue for: ${this.guildId}`);
|
|
224
204
|
}
|
|
225
205
|
/**
|
|
226
206
|
* Shuffles the queue.
|
|
227
207
|
* This will randomize the order of the tracks in the queue and emit a state update event.
|
|
228
208
|
*/
|
|
229
209
|
async shuffle() {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
},
|
|
244
|
-
});
|
|
245
|
-
// Emit a debug message indicating the queue has been shuffled for a specific guild ID.
|
|
246
|
-
this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Shuffled the queue for: ${this.guildId}`);
|
|
210
|
+
// Capture the current state of the player for event emission.
|
|
211
|
+
const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
|
|
212
|
+
// Shuffle the queue.
|
|
213
|
+
for (let i = this.length - 1; i > 0; i--) {
|
|
214
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
215
|
+
[this[i], this[j]] = [this[j], this[i]];
|
|
216
|
+
}
|
|
217
|
+
// Emit an event to update the player state indicating the queue has been shuffled.
|
|
218
|
+
this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
219
|
+
changeType: Manager_1.PlayerStateEventTypes.QueueChange,
|
|
220
|
+
details: {
|
|
221
|
+
changeType: "shuffle",
|
|
222
|
+
},
|
|
247
223
|
});
|
|
224
|
+
// Emit a debug message indicating the queue has been shuffled for a specific guild ID.
|
|
225
|
+
this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] Shuffled the queue for: ${this.guildId}`);
|
|
248
226
|
}
|
|
249
227
|
/**
|
|
250
228
|
* Shuffles the queue to play tracks requested by each user one block at a time.
|
|
251
229
|
*/
|
|
252
230
|
async userBlockShuffle() {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
userTracks.set(user, []);
|
|
262
|
-
}
|
|
263
|
-
userTracks.get(user).push(track);
|
|
264
|
-
});
|
|
265
|
-
// Create a new array for the shuffled queue.
|
|
266
|
-
const shuffledQueue = [];
|
|
267
|
-
// Iterate over the user tracks and add one track from each user to the shuffled queue.
|
|
268
|
-
// This will ensure that all the tracks requested by each user are played in a block order.
|
|
269
|
-
while (shuffledQueue.length < this.length) {
|
|
270
|
-
userTracks.forEach((tracks) => {
|
|
271
|
-
const track = tracks.shift();
|
|
272
|
-
if (track) {
|
|
273
|
-
shuffledQueue.push(track);
|
|
274
|
-
}
|
|
275
|
-
});
|
|
231
|
+
// Capture the current state of the player for event emission.
|
|
232
|
+
const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
|
|
233
|
+
// Group the tracks in the queue by the user that requested them.
|
|
234
|
+
const userTracks = new Map();
|
|
235
|
+
this.forEach((track) => {
|
|
236
|
+
const user = track.requester.id;
|
|
237
|
+
if (!userTracks.has(user)) {
|
|
238
|
+
userTracks.set(user, []);
|
|
276
239
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
240
|
+
userTracks.get(user).push(track);
|
|
241
|
+
});
|
|
242
|
+
// Create a new array for the shuffled queue.
|
|
243
|
+
const shuffledQueue = [];
|
|
244
|
+
// Iterate over the user tracks and add one track from each user to the shuffled queue.
|
|
245
|
+
// This will ensure that all the tracks requested by each user are played in a block order.
|
|
246
|
+
while (shuffledQueue.length < this.length) {
|
|
247
|
+
userTracks.forEach((tracks) => {
|
|
248
|
+
const track = tracks.shift();
|
|
249
|
+
if (track) {
|
|
250
|
+
shuffledQueue.push(track);
|
|
251
|
+
}
|
|
286
252
|
});
|
|
287
|
-
|
|
288
|
-
|
|
253
|
+
}
|
|
254
|
+
// Clear the queue and add the shuffled tracks.
|
|
255
|
+
this.splice(0);
|
|
256
|
+
this.add(shuffledQueue);
|
|
257
|
+
// Emit an event to update the player state indicating the queue has been shuffled.
|
|
258
|
+
this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
259
|
+
changeType: Manager_1.PlayerStateEventTypes.QueueChange,
|
|
260
|
+
details: {
|
|
261
|
+
changeType: "userBlock",
|
|
262
|
+
},
|
|
289
263
|
});
|
|
264
|
+
// Emit a debug message indicating the queue has been shuffled for a specific guild ID.
|
|
265
|
+
this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] userBlockShuffled the queue for: ${this.guildId}`);
|
|
290
266
|
}
|
|
291
267
|
/**
|
|
292
268
|
* Shuffles the queue to play tracks requested by each user one by one.
|
|
293
269
|
*/
|
|
294
270
|
async roundRobinShuffle() {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
shuffledQueue.push(queue.shift());
|
|
326
|
-
}
|
|
271
|
+
// Capture the current state of the player for event emission.
|
|
272
|
+
const oldPlayer = this.manager.players.get(this.guildId) ? { ...this.manager.players.get(this.guildId) } : null;
|
|
273
|
+
// Group the tracks in the queue by the user that requested them.
|
|
274
|
+
const userTracks = new Map();
|
|
275
|
+
// Group the tracks in the queue by the user that requested them.
|
|
276
|
+
this.forEach((track) => {
|
|
277
|
+
const user = track.requester.id;
|
|
278
|
+
if (!userTracks.has(user)) {
|
|
279
|
+
userTracks.set(user, []);
|
|
280
|
+
}
|
|
281
|
+
userTracks.get(user).push(track);
|
|
282
|
+
});
|
|
283
|
+
// Shuffle the tracks of each user.
|
|
284
|
+
userTracks.forEach((tracks) => {
|
|
285
|
+
for (let i = tracks.length - 1; i > 0; i--) {
|
|
286
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
287
|
+
[tracks[i], tracks[j]] = [tracks[j], tracks[i]];
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
// Create a new array for the shuffled queue.
|
|
291
|
+
const shuffledQueue = [];
|
|
292
|
+
// Add the shuffled tracks to the queue in a round-robin fashion.
|
|
293
|
+
const users = Array.from(userTracks.keys());
|
|
294
|
+
const userQueues = users.map((user) => userTracks.get(user));
|
|
295
|
+
const userCount = users.length;
|
|
296
|
+
while (userQueues.some((queue) => queue.length > 0)) {
|
|
297
|
+
for (let i = 0; i < userCount; i++) {
|
|
298
|
+
const queue = userQueues[i];
|
|
299
|
+
if (queue.length > 0) {
|
|
300
|
+
shuffledQueue.push(queue.shift());
|
|
327
301
|
}
|
|
328
302
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
339
|
-
// Emit a debug message indicating the queue has been shuffled for a specific guild ID.
|
|
340
|
-
this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] roundRobinShuffled the queue for: ${this.guildId}`);
|
|
303
|
+
}
|
|
304
|
+
// Clear the queue and add the shuffled tracks.
|
|
305
|
+
this.splice(0);
|
|
306
|
+
this.add(shuffledQueue);
|
|
307
|
+
// Emit an event to update the player state indicating the queue has been shuffled.
|
|
308
|
+
this.manager.emit(Manager_1.ManagerEventTypes.PlayerStateUpdate, oldPlayer, this.manager.players.get(this.guildId), {
|
|
309
|
+
changeType: Manager_1.PlayerStateEventTypes.QueueChange,
|
|
310
|
+
details: {
|
|
311
|
+
changeType: "roundRobin",
|
|
312
|
+
},
|
|
341
313
|
});
|
|
314
|
+
// Emit a debug message indicating the queue has been shuffled for a specific guild ID.
|
|
315
|
+
this.manager.emit(Manager_1.ManagerEventTypes.Debug, `[QUEUE] roundRobinShuffled the queue for: ${this.guildId}`);
|
|
342
316
|
}
|
|
343
317
|
async dequeue() {
|
|
344
|
-
return
|
|
345
|
-
return super.shift();
|
|
346
|
-
});
|
|
318
|
+
return super.shift();
|
|
347
319
|
}
|
|
348
320
|
async enqueueFront(track) {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
}
|
|
356
|
-
});
|
|
321
|
+
if (Array.isArray(track)) {
|
|
322
|
+
this.unshift(...track);
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
this.unshift(track);
|
|
326
|
+
}
|
|
357
327
|
}
|
|
358
328
|
async getTracks() {
|
|
359
|
-
return
|
|
360
|
-
return [...this]; // clone to avoid direct mutation
|
|
361
|
-
});
|
|
329
|
+
return [...this]; // clone to avoid direct mutation
|
|
362
330
|
}
|
|
363
331
|
async getSlice(start, end) {
|
|
364
|
-
return (
|
|
365
|
-
return this.slice(start, end); // Native sync method, still wrapped in a Promise
|
|
366
|
-
});
|
|
332
|
+
return this.slice(start, end); // Native sync method, still wrapped in a Promise
|
|
367
333
|
}
|
|
368
334
|
async modifyAt(start, deleteCount = 0, ...items) {
|
|
369
|
-
return (
|
|
370
|
-
return super.splice(start, deleteCount, ...items);
|
|
371
|
-
});
|
|
335
|
+
return super.splice(start, deleteCount, ...items);
|
|
372
336
|
}
|
|
373
337
|
async mapAsync(callback) {
|
|
374
|
-
return
|
|
375
|
-
return this.map(callback);
|
|
376
|
-
});
|
|
338
|
+
return this.map(callback);
|
|
377
339
|
}
|
|
378
340
|
async filterAsync(callback) {
|
|
379
|
-
return
|
|
380
|
-
return this.filter(callback);
|
|
381
|
-
});
|
|
341
|
+
return this.filter(callback);
|
|
382
342
|
}
|
|
383
343
|
async findAsync(callback) {
|
|
384
|
-
return
|
|
385
|
-
return this.find(callback);
|
|
386
|
-
});
|
|
344
|
+
return this.find(callback);
|
|
387
345
|
}
|
|
388
346
|
async someAsync(callback) {
|
|
389
|
-
return
|
|
390
|
-
return this.some(callback);
|
|
391
|
-
});
|
|
347
|
+
return this.some(callback);
|
|
392
348
|
}
|
|
393
349
|
async everyAsync(callback) {
|
|
394
|
-
return
|
|
395
|
-
return this.every(callback);
|
|
396
|
-
});
|
|
350
|
+
return this.every(callback);
|
|
397
351
|
}
|
|
398
352
|
}
|
|
399
353
|
exports.Queue = Queue;
|