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