aqualink 2.17.2 → 2.18.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/build/structures/Aqua.js +81 -54
- package/build/structures/Connection.js +131 -56
- package/build/structures/Filters.js +35 -5
- package/build/structures/Node.js +106 -38
- package/build/structures/Player.js +63 -68
- package/build/structures/Queue.js +42 -21
- package/build/structures/Rest.js +118 -46
- package/build/structures/Track.js +7 -1
- package/package.json +5 -5
package/build/structures/Aqua.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('node:fs')
|
|
4
4
|
const readline = require('node:readline')
|
|
5
|
-
const {EventEmitter} = require('tseep')
|
|
6
|
-
const {AqualinkEvents} = require('./AqualinkEvents')
|
|
5
|
+
const { EventEmitter } = require('tseep')
|
|
6
|
+
const { AqualinkEvents } = require('./AqualinkEvents')
|
|
7
7
|
const Node = require('./Node')
|
|
8
8
|
const Player = require('./Player')
|
|
9
9
|
const Track = require('./Track')
|
|
10
|
-
const {version: pkgVersion} = require('../../package.json')
|
|
10
|
+
const { version: pkgVersion } = require('../../package.json')
|
|
11
11
|
|
|
12
12
|
const SEARCH_PREFIX = ':'
|
|
13
13
|
const EMPTY_ARRAY = Object.freeze([])
|
|
@@ -33,7 +33,6 @@ const MAX_REBUILD_LOCKS = 100
|
|
|
33
33
|
const WRITE_BUFFER_SIZE = 100
|
|
34
34
|
const MAX_QUEUE_SAVE = 10
|
|
35
35
|
const MAX_TRACKS_RESTORE = 20
|
|
36
|
-
const URL_PATTERN = /^https?:\/\//i
|
|
37
36
|
|
|
38
37
|
const DEFAULT_OPTIONS = Object.freeze({
|
|
39
38
|
shouldDeleteMessage: false,
|
|
@@ -53,14 +52,22 @@ const DEFAULT_OPTIONS = Object.freeze({
|
|
|
53
52
|
resumePlayback: true,
|
|
54
53
|
cooldownTime: 5000,
|
|
55
54
|
maxFailoverAttempts: 5
|
|
56
|
-
})
|
|
55
|
+
}),
|
|
56
|
+
maxQueueSave: 10,
|
|
57
|
+
maxTracksRestore: 20
|
|
57
58
|
})
|
|
58
59
|
|
|
59
|
-
// Shared helper functions
|
|
60
60
|
const _functions = {
|
|
61
|
-
delay: ms => new Promise(r =>
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
delay: ms => new Promise(r => {
|
|
62
|
+
const t = setTimeout(r, ms)
|
|
63
|
+
t.unref?.()
|
|
64
|
+
}),
|
|
65
|
+
noop: () => { },
|
|
66
|
+
isUrl: query => {
|
|
67
|
+
if (typeof query !== 'string' || query.length <= 8) return false
|
|
68
|
+
const q = query.trimStart()
|
|
69
|
+
return q.startsWith('http://') || q.startsWith('https://')
|
|
70
|
+
},
|
|
64
71
|
formatQuery(query, source) {
|
|
65
72
|
return this.isUrl(query) ? query : `${source}${SEARCH_PREFIX}${query}`
|
|
66
73
|
},
|
|
@@ -69,12 +76,17 @@ const _functions = {
|
|
|
69
76
|
try {
|
|
70
77
|
const result = fn()
|
|
71
78
|
return result?.then ? result.catch(this.noop) : result
|
|
72
|
-
} catch {}
|
|
79
|
+
} catch { }
|
|
73
80
|
},
|
|
74
81
|
parseRequester(str) {
|
|
75
82
|
if (!str || typeof str !== 'string') return null
|
|
76
83
|
const i = str.indexOf(':')
|
|
77
|
-
return i > 0 ? {id: str.substring(0, i), username: str.substring(i + 1)} : null
|
|
84
|
+
return i > 0 ? { id: str.substring(0, i), username: str.substring(i + 1) } : null
|
|
85
|
+
},
|
|
86
|
+
unrefTimeout: (fn, ms) => {
|
|
87
|
+
const t = setTimeout(fn, ms)
|
|
88
|
+
t.unref?.()
|
|
89
|
+
return t
|
|
78
90
|
}
|
|
79
91
|
}
|
|
80
92
|
|
|
@@ -92,9 +104,9 @@ class Aqua extends EventEmitter {
|
|
|
92
104
|
this.initiated = false
|
|
93
105
|
this.version = pkgVersion
|
|
94
106
|
|
|
95
|
-
const merged = {...DEFAULT_OPTIONS, ...options}
|
|
107
|
+
const merged = { ...DEFAULT_OPTIONS, ...options }
|
|
96
108
|
this.options = merged
|
|
97
|
-
this.failoverOptions = {...DEFAULT_OPTIONS.failoverOptions, ...options.failoverOptions}
|
|
109
|
+
this.failoverOptions = { ...DEFAULT_OPTIONS.failoverOptions, ...options.failoverOptions }
|
|
98
110
|
|
|
99
111
|
this.shouldDeleteMessage = merged.shouldDeleteMessage
|
|
100
112
|
this.defaultSearchPlatform = merged.defaultSearchPlatform
|
|
@@ -108,6 +120,8 @@ class Aqua extends EventEmitter {
|
|
|
108
120
|
this.allowedDomains = merged.allowedDomains || []
|
|
109
121
|
this.loadBalancer = merged.loadBalancer
|
|
110
122
|
this.useHttp2 = merged.useHttp2
|
|
123
|
+
this.maxQueueSave = merged.maxQueueSave
|
|
124
|
+
this.maxTracksRestore = merged.maxTracksRestore
|
|
111
125
|
this.send = merged.send || this._createDefaultSend()
|
|
112
126
|
|
|
113
127
|
this._nodeStates = new Map()
|
|
@@ -149,13 +163,13 @@ class Aqua extends EventEmitter {
|
|
|
149
163
|
this._performCleanup()
|
|
150
164
|
})
|
|
151
165
|
},
|
|
152
|
-
onNodeReady: (node, {resumed}) => {
|
|
166
|
+
onNodeReady: (node, { resumed }) => {
|
|
153
167
|
if (!resumed) return
|
|
154
168
|
const batch = []
|
|
155
169
|
for (const player of this.players.values()) {
|
|
156
170
|
if (player.nodes === node && player.connection) batch.push(player)
|
|
157
171
|
}
|
|
158
|
-
if (batch.length) queueMicrotask(() => batch.forEach(p => p.connection.resendVoiceUpdate(
|
|
172
|
+
if (batch.length) queueMicrotask(() => batch.forEach(p => p.connection.resendVoiceUpdate()))
|
|
159
173
|
}
|
|
160
174
|
}
|
|
161
175
|
this.on(AqualinkEvents.NodeConnect, this._eventHandlers.onNodeConnect)
|
|
@@ -171,8 +185,10 @@ class Aqua extends EventEmitter {
|
|
|
171
185
|
this._eventHandlers = null
|
|
172
186
|
}
|
|
173
187
|
this.removeAllListeners()
|
|
174
|
-
|
|
175
|
-
|
|
188
|
+
|
|
189
|
+
for (const id of Array.from(this.nodeMap.keys())) this._destroyNode(id)
|
|
190
|
+
for (const player of Array.from(this.players.values())) _functions.safeCall(() => player.destroy())
|
|
191
|
+
|
|
176
192
|
this.players.clear()
|
|
177
193
|
this._nodeStates.clear()
|
|
178
194
|
this._failoverQueue.clear()
|
|
@@ -220,7 +236,7 @@ class Aqua extends EventEmitter {
|
|
|
220
236
|
(stats.playingPlayers || 0) * 0.75 +
|
|
221
237
|
(stats.memory ? stats.memory.used / reservable : 0) * 40 +
|
|
222
238
|
(node.rest?.calls || 0) * 0.001
|
|
223
|
-
this._nodeLoadCache.set(id, {load, time: now})
|
|
239
|
+
this._nodeLoadCache.set(id, { load, time: now })
|
|
224
240
|
if (this._nodeLoadCache.size > MAX_CACHE_SIZE) {
|
|
225
241
|
const first = this._nodeLoadCache.keys().next().value
|
|
226
242
|
this._nodeLoadCache.delete(first)
|
|
@@ -233,7 +249,7 @@ class Aqua extends EventEmitter {
|
|
|
233
249
|
this.clientId = clientId
|
|
234
250
|
if (!this.clientId) return this
|
|
235
251
|
const results = await Promise.allSettled(
|
|
236
|
-
this.nodes.map(n => Promise.race([this._createNode(n), _functions.delay(NODE_TIMEOUT).then(() => {throw new Error('Timeout')})]))
|
|
252
|
+
this.nodes.map(n => Promise.race([this._createNode(n), _functions.delay(NODE_TIMEOUT).then(() => { throw new Error('Timeout') })]))
|
|
237
253
|
)
|
|
238
254
|
if (!results.some(r => r.status === 'fulfilled')) throw new Error('No nodes connected')
|
|
239
255
|
if (this.plugins?.length) {
|
|
@@ -249,10 +265,10 @@ class Aqua extends EventEmitter {
|
|
|
249
265
|
const node = new Node(this, options, this.options)
|
|
250
266
|
node.players = new Set()
|
|
251
267
|
this.nodeMap.set(id, node)
|
|
252
|
-
this._nodeStates.set(id, {connected: false, failoverInProgress: false})
|
|
268
|
+
this._nodeStates.set(id, { connected: false, failoverInProgress: false })
|
|
253
269
|
try {
|
|
254
270
|
await node.connect()
|
|
255
|
-
this._nodeStates.set(id, {connected: true, failoverInProgress: false})
|
|
271
|
+
this._nodeStates.set(id, { connected: true, failoverInProgress: false })
|
|
256
272
|
this._invalidateCache()
|
|
257
273
|
this.emit(AqualinkEvents.NodeCreate, node)
|
|
258
274
|
return node
|
|
@@ -304,7 +320,7 @@ class Aqua extends EventEmitter {
|
|
|
304
320
|
const now = Date.now()
|
|
305
321
|
for (const [guildId, state] of this._brokenPlayers) {
|
|
306
322
|
if (state.originalNodeId === id && (now - state.brokenAt) < BROKEN_PLAYER_TTL) {
|
|
307
|
-
rebuilds.push({guildId, state})
|
|
323
|
+
rebuilds.push({ guildId, state })
|
|
308
324
|
}
|
|
309
325
|
}
|
|
310
326
|
if (!rebuilds.length) return
|
|
@@ -312,7 +328,7 @@ class Aqua extends EventEmitter {
|
|
|
312
328
|
for (let i = 0; i < rebuilds.length; i += MAX_CONCURRENT_OPS) {
|
|
313
329
|
const batch = rebuilds.slice(i, i + MAX_CONCURRENT_OPS)
|
|
314
330
|
const results = await Promise.allSettled(
|
|
315
|
-
batch.map(({guildId, state}) => this._rebuildPlayer(state, node).then(() => guildId))
|
|
331
|
+
batch.map(({ guildId, state }) => this._rebuildPlayer(state, node).then(() => guildId))
|
|
316
332
|
)
|
|
317
333
|
for (const r of results) {
|
|
318
334
|
if (r.status === 'fulfilled') successes.push(r.value)
|
|
@@ -324,7 +340,7 @@ class Aqua extends EventEmitter {
|
|
|
324
340
|
}
|
|
325
341
|
|
|
326
342
|
async _rebuildPlayer(state, targetNode) {
|
|
327
|
-
const {guildId, textChannel, voiceChannel, current, volume = 65, deaf = true} = state
|
|
343
|
+
const { guildId, textChannel, voiceChannel, current, volume = 65, deaf = true } = state
|
|
328
344
|
const lockKey = `rebuild_${guildId}`
|
|
329
345
|
if (this._rebuildLocks.has(lockKey)) return
|
|
330
346
|
this._rebuildLocks.add(lockKey)
|
|
@@ -333,11 +349,11 @@ class Aqua extends EventEmitter {
|
|
|
333
349
|
await this.destroyPlayer(guildId)
|
|
334
350
|
await _functions.delay(RECONNECT_DELAY)
|
|
335
351
|
}
|
|
336
|
-
const player = this.createPlayer(targetNode, {guildId, textChannel, voiceChannel, defaultVolume: volume, deaf})
|
|
352
|
+
const player = this.createPlayer(targetNode, { guildId, textChannel, voiceChannel, defaultVolume: volume, deaf })
|
|
337
353
|
if (current && player?.queue?.add) {
|
|
338
354
|
player.queue.add(current)
|
|
339
355
|
await player.play()
|
|
340
|
-
if (state.position > 0)
|
|
356
|
+
if (state.position > 0) _functions.unrefTimeout(() => player.seek?.(state.position), SEEK_DELAY)
|
|
341
357
|
if (state.paused) player.pause(true)
|
|
342
358
|
}
|
|
343
359
|
return player
|
|
@@ -357,7 +373,7 @@ class Aqua extends EventEmitter {
|
|
|
357
373
|
const attempts = this._failoverQueue.get(id) || 0
|
|
358
374
|
if (attempts >= this.failoverOptions.maxFailoverAttempts) return
|
|
359
375
|
|
|
360
|
-
this._nodeStates.set(id, {connected: false, failoverInProgress: true})
|
|
376
|
+
this._nodeStates.set(id, { connected: false, failoverInProgress: true })
|
|
361
377
|
this._lastFailoverAttempt.set(id, now)
|
|
362
378
|
this._failoverQueue.set(id, attempts + 1)
|
|
363
379
|
|
|
@@ -379,7 +395,7 @@ class Aqua extends EventEmitter {
|
|
|
379
395
|
} catch (error) {
|
|
380
396
|
this.emit(AqualinkEvents.Error, null, error)
|
|
381
397
|
} finally {
|
|
382
|
-
this._nodeStates.set(id, {connected: false, failoverInProgress: false})
|
|
398
|
+
this._nodeStates.set(id, { connected: false, failoverInProgress: false })
|
|
383
399
|
}
|
|
384
400
|
}
|
|
385
401
|
|
|
@@ -403,7 +419,7 @@ class Aqua extends EventEmitter {
|
|
|
403
419
|
for (let i = 0; i < players.length; i += MAX_CONCURRENT_OPS) {
|
|
404
420
|
const batch = players.slice(i, i + MAX_CONCURRENT_OPS)
|
|
405
421
|
const batchResults = await Promise.allSettled(batch.map(p => this._migratePlayer(p, pickNode)))
|
|
406
|
-
for (const r of batchResults) results.push({success: r.status === 'fulfilled', error: r.reason})
|
|
422
|
+
for (const r of batchResults) results.push({ success: r.status === 'fulfilled', error: r.reason })
|
|
407
423
|
}
|
|
408
424
|
return results
|
|
409
425
|
}
|
|
@@ -411,7 +427,7 @@ class Aqua extends EventEmitter {
|
|
|
411
427
|
async _migratePlayer(player, pickNode) {
|
|
412
428
|
const state = this._capturePlayerState(player)
|
|
413
429
|
if (!state) throw new Error('Failed to capture state')
|
|
414
|
-
const {maxRetries, retryDelay} = this.failoverOptions
|
|
430
|
+
const { maxRetries, retryDelay } = this.failoverOptions
|
|
415
431
|
for (let retry = 0; retry < maxRetries; retry++) {
|
|
416
432
|
try {
|
|
417
433
|
const targetNode = pickNode()
|
|
@@ -462,10 +478,10 @@ class Aqua extends EventEmitter {
|
|
|
462
478
|
}
|
|
463
479
|
if (state.queue?.length && newPlayer.queue?.add) newPlayer.queue.add(...state.queue)
|
|
464
480
|
if (state.current && this.failoverOptions.preservePosition) {
|
|
465
|
-
newPlayer.queue?.add?.(state.current, {toFront: true})
|
|
481
|
+
newPlayer.queue?.add?.(state.current, { toFront: true })
|
|
466
482
|
if (this.failoverOptions.resumePlayback) {
|
|
467
483
|
ops.push(newPlayer.play())
|
|
468
|
-
if (state.position > 0)
|
|
484
|
+
if (state.position > 0) _functions.unrefTimeout(() => newPlayer.seek?.(state.position), SEEK_DELAY)
|
|
469
485
|
if (state.paused) ops.push(newPlayer.pause(true))
|
|
470
486
|
}
|
|
471
487
|
}
|
|
@@ -474,16 +490,21 @@ class Aqua extends EventEmitter {
|
|
|
474
490
|
await Promise.allSettled(ops)
|
|
475
491
|
}
|
|
476
492
|
|
|
477
|
-
updateVoiceState({d, t}) {
|
|
493
|
+
updateVoiceState({ d, t }) {
|
|
478
494
|
if (!d?.guild_id || (t !== 'VOICE_STATE_UPDATE' && t !== 'VOICE_SERVER_UPDATE')) return
|
|
479
495
|
const player = this.players.get(d.guild_id)
|
|
480
|
-
if (!player
|
|
496
|
+
if (!player) return
|
|
497
|
+
|
|
498
|
+
d.txId = player.txId
|
|
481
499
|
if (t === 'VOICE_STATE_UPDATE') {
|
|
482
500
|
if (d.user_id !== this.clientId) return
|
|
483
|
-
if (!d.channel_id) return void this.destroyPlayer(d.guild_id)
|
|
484
501
|
if (player.connection) {
|
|
485
|
-
player.connection.
|
|
486
|
-
|
|
502
|
+
if (!d.channel_id && player.connection.voiceChannel) {
|
|
503
|
+
player.connection.setStateUpdate(d)
|
|
504
|
+
} else {
|
|
505
|
+
player.connection.sessionId = d.session_id
|
|
506
|
+
player.connection.setStateUpdate(d)
|
|
507
|
+
}
|
|
487
508
|
}
|
|
488
509
|
} else {
|
|
489
510
|
player.connection?.setServerUpdate(d)
|
|
@@ -503,7 +524,7 @@ class Aqua extends EventEmitter {
|
|
|
503
524
|
createConnection(options) {
|
|
504
525
|
if (!this.initiated) throw new Error('Aqua not initialized')
|
|
505
526
|
const existing = this.players.get(options.guildId)
|
|
506
|
-
if (existing) {
|
|
527
|
+
if (existing && !existing.destroyed) {
|
|
507
528
|
if (options.voiceChannel && existing.voiceChannel !== options.voiceChannel) {
|
|
508
529
|
_functions.safeCall(() => existing.connect(options))
|
|
509
530
|
}
|
|
@@ -516,7 +537,12 @@ class Aqua extends EventEmitter {
|
|
|
516
537
|
|
|
517
538
|
createPlayer(node, options) {
|
|
518
539
|
const existing = this.players.get(options.guildId)
|
|
519
|
-
if (existing)
|
|
540
|
+
if (existing) {
|
|
541
|
+
_functions.safeCall(() => existing.destroy({
|
|
542
|
+
preserveMessage: options.preserveMessage || !!options.resuming || false,
|
|
543
|
+
preserveTracks: !!options.resuming || false
|
|
544
|
+
}))
|
|
545
|
+
}
|
|
520
546
|
const player = new Player(this, node, options)
|
|
521
547
|
this.players.set(options.guildId, player)
|
|
522
548
|
node?.players?.add?.(player)
|
|
@@ -540,7 +566,7 @@ class Aqua extends EventEmitter {
|
|
|
540
566
|
await _functions.safeCall(() => player.destroy())
|
|
541
567
|
}
|
|
542
568
|
|
|
543
|
-
async resolve({query, source, requester, nodes}) {
|
|
569
|
+
async resolve({ query, source, requester, nodes }) {
|
|
544
570
|
if (!this.initiated) throw new Error('Aqua not initialized')
|
|
545
571
|
const node = this._getRequestNode(nodes)
|
|
546
572
|
if (!node) throw new Error('No nodes available')
|
|
@@ -581,8 +607,8 @@ class Aqua extends EventEmitter {
|
|
|
581
607
|
}
|
|
582
608
|
|
|
583
609
|
_constructResponse(response, requester, node) {
|
|
584
|
-
const {loadType, data, pluginInfo: rootPlugin} = response || {}
|
|
585
|
-
const base = {loadType, exception: null, playlistInfo: null, pluginInfo: rootPlugin || {}, tracks: []}
|
|
610
|
+
const { loadType, data, pluginInfo: rootPlugin } = response || {}
|
|
611
|
+
const base = { loadType, exception: null, playlistInfo: null, pluginInfo: rootPlugin || {}, tracks: [] }
|
|
586
612
|
if (loadType === 'error' || loadType === 'LOAD_FAILED') {
|
|
587
613
|
base.exception = data || response.exception || null
|
|
588
614
|
return base
|
|
@@ -599,7 +625,7 @@ class Aqua extends EventEmitter {
|
|
|
599
625
|
...info
|
|
600
626
|
}
|
|
601
627
|
}
|
|
602
|
-
base.pluginInfo = data.pluginInfo || base.pluginInfo
|
|
628
|
+
base.pluginInfo = data.pluginInfo || rootPlugin || base.pluginInfo
|
|
603
629
|
base.tracks = Array.isArray(data.tracks) ? data.tracks.map(t => _functions.makeTrack(t, requester, node)) : []
|
|
604
630
|
} else if (loadType === 'search') {
|
|
605
631
|
base.tracks = Array.isArray(data) ? data.map(t => _functions.makeTrack(t, requester, node)) : []
|
|
@@ -616,7 +642,7 @@ class Aqua extends EventEmitter {
|
|
|
616
642
|
async search(query, requester, source) {
|
|
617
643
|
if (!query || !requester) return null
|
|
618
644
|
try {
|
|
619
|
-
const {tracks} = await this.resolve({query, source: source || this.defaultSearchPlatform, requester})
|
|
645
|
+
const { tracks } = await this.resolve({ query, source: source || this.defaultSearchPlatform, requester })
|
|
620
646
|
return tracks || null
|
|
621
647
|
} catch {
|
|
622
648
|
return null
|
|
@@ -628,8 +654,8 @@ class Aqua extends EventEmitter {
|
|
|
628
654
|
const tempFile = `${filePath}.tmp`
|
|
629
655
|
let ws = null
|
|
630
656
|
try {
|
|
631
|
-
await fs.promises.writeFile(lockFile, String(process.pid), {flag: 'wx'})
|
|
632
|
-
ws = fs.createWriteStream(tempFile, {encoding: 'utf8', flags: 'w'})
|
|
657
|
+
await fs.promises.writeFile(lockFile, String(process.pid), { flag: 'wx' })
|
|
658
|
+
ws = fs.createWriteStream(tempFile, { encoding: 'utf8', flags: 'w' })
|
|
633
659
|
const buffer = []
|
|
634
660
|
let drainPromise = Promise.resolve()
|
|
635
661
|
|
|
@@ -642,7 +668,7 @@ class Aqua extends EventEmitter {
|
|
|
642
668
|
u: player.current?.uri || null,
|
|
643
669
|
p: player.position || 0,
|
|
644
670
|
ts: player.timestamp || 0,
|
|
645
|
-
q: player.queue.slice(0,
|
|
671
|
+
q: player.queue.slice(0, this.maxQueueSave).map(tr => tr.uri),
|
|
646
672
|
r: requester ? `${requester.id}:${requester.username}` : null,
|
|
647
673
|
vol: player.volume,
|
|
648
674
|
pa: player.paused,
|
|
@@ -680,11 +706,11 @@ class Aqua extends EventEmitter {
|
|
|
680
706
|
let stream = null, rl = null
|
|
681
707
|
try {
|
|
682
708
|
await fs.promises.access(filePath)
|
|
683
|
-
await fs.promises.writeFile(lockFile, String(process.pid), {flag: 'wx'})
|
|
709
|
+
await fs.promises.writeFile(lockFile, String(process.pid), { flag: 'wx' })
|
|
684
710
|
await this._waitForFirstNode()
|
|
685
711
|
|
|
686
|
-
stream = fs.createReadStream(filePath, {encoding: 'utf8'})
|
|
687
|
-
rl = readline.createInterface({input: stream, crlfDelay: Infinity})
|
|
712
|
+
stream = fs.createReadStream(filePath, { encoding: 'utf8' })
|
|
713
|
+
rl = readline.createInterface({ input: stream, crlfDelay: Infinity })
|
|
688
714
|
|
|
689
715
|
const batch = []
|
|
690
716
|
for await (const line of rl) {
|
|
@@ -718,8 +744,8 @@ class Aqua extends EventEmitter {
|
|
|
718
744
|
})
|
|
719
745
|
player._resuming = !!p.resuming
|
|
720
746
|
const requester = _functions.parseRequester(p.r)
|
|
721
|
-
const tracksToResolve = [p.u, ...(p.q || [])].filter(Boolean).slice(0,
|
|
722
|
-
const resolved = await Promise.all(tracksToResolve.map(uri => this.resolve({query: uri, requester}).catch(() => null)))
|
|
747
|
+
const tracksToResolve = [p.u, ...(p.q || [])].filter(Boolean).slice(0, this.maxTracksRestore)
|
|
748
|
+
const resolved = await Promise.all(tracksToResolve.map(uri => this.resolve({ query: uri, requester }).catch(() => null)))
|
|
723
749
|
const validTracks = resolved.flatMap(r => r?.tracks || [])
|
|
724
750
|
if (validTracks.length && player.queue?.add) {
|
|
725
751
|
if (player.queue.length <= 2) player.queue.length = 0
|
|
@@ -731,14 +757,14 @@ class Aqua extends EventEmitter {
|
|
|
731
757
|
else player.volume = p.vol
|
|
732
758
|
}
|
|
733
759
|
await player.play()
|
|
734
|
-
if (p.p > 0)
|
|
760
|
+
if (p.p > 0) _functions.unrefTimeout(() => player.seek?.(p.p), SEEK_DELAY)
|
|
735
761
|
if (p.pa) await player.pause(true)
|
|
736
762
|
}
|
|
737
763
|
if (p.nw && p.t) {
|
|
738
764
|
const channel = this.client.channels?.cache?.get(p.t)
|
|
739
765
|
if (channel?.messages) player.nowPlayingMessage = await channel.messages.fetch(p.nw).catch(() => null)
|
|
740
766
|
}
|
|
741
|
-
} catch {}
|
|
767
|
+
} catch { }
|
|
742
768
|
}
|
|
743
769
|
|
|
744
770
|
async _waitForFirstNode(timeout = NODE_TIMEOUT) {
|
|
@@ -756,6 +782,7 @@ class Aqua extends EventEmitter {
|
|
|
756
782
|
if (this.leastUsedNodes.length) { cleanup(); resolve() }
|
|
757
783
|
}
|
|
758
784
|
const timer = setTimeout(() => { cleanup(); reject(new Error('Timeout waiting for first node')) }, timeout)
|
|
785
|
+
timer.unref?.()
|
|
759
786
|
this.on(AqualinkEvents.NodeConnect, onReady)
|
|
760
787
|
this.on(AqualinkEvents.NodeCreate, onReady)
|
|
761
788
|
onReady()
|