aqualink 2.20.1 → 3.0.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.
@@ -102,10 +102,10 @@ class Node {
102
102
  this.host = connOptions.host || 'localhost'
103
103
  this.name = connOptions.name || this.host
104
104
  this.port = connOptions.port || 2333
105
- this.auth = connOptions.auth || 'youshallnotpass'
105
+ this.auth = connOptions.auth || connOptions.password || 'youshallnotpass'
106
106
  this.sessionId = connOptions.sessionId || null
107
107
  this.regions = connOptions.regions || []
108
- this.ssl = !!connOptions.ssl
108
+ this.ssl = !!connOptions.ssl || !!connOptions.secure || false
109
109
  this.wsUrl = _functions.buildWsUrl(this.host, this.port, this.ssl)
110
110
 
111
111
  this.rest = new Rest(aqua, this)
@@ -187,10 +187,12 @@ class Node {
187
187
  this._isConnecting = false
188
188
  this.reconnectAttempted = 0
189
189
  this._emitDebug('WebSocket connection established')
190
- this.aqua?._trace?.('node.ws.open', {
191
- node: this.name,
192
- reconnectAttempted: this.reconnectAttempted
193
- })
190
+ if (this.aqua?.debugTrace) {
191
+ this.aqua._trace('node.ws.open', {
192
+ node: this.name,
193
+ reconnectAttempted: this.reconnectAttempted
194
+ })
195
+ }
194
196
 
195
197
  if (!this.aqua?.bypassChecks?.nodeFetchInfo && !this.info) {
196
198
  const timeoutId = setTimeout(() => {
@@ -272,12 +274,14 @@ class Node {
272
274
  code,
273
275
  reason: _functions.reasonToString(reason)
274
276
  })
275
- this.aqua?._trace?.('node.ws.close', {
276
- node: this.name,
277
- code,
278
- reason: _functions.reasonToString(reason),
279
- hasSessionId: !!this.sessionId
280
- })
277
+ if (this.aqua?.debugTrace) {
278
+ this.aqua._trace('node.ws.close', {
279
+ node: this.name,
280
+ code,
281
+ reason: _functions.reasonToString(reason),
282
+ hasSessionId: !!this.sessionId
283
+ })
284
+ }
281
285
 
282
286
  if (this.isDestroyed) return
283
287
 
@@ -311,11 +315,13 @@ class Node {
311
315
  this._clearReconnectTimeout()
312
316
 
313
317
  const attempt = ++this.reconnectAttempted
314
- this.aqua?._trace?.('node.ws.reconnect.scheduled', {
315
- node: this.name,
316
- attempt,
317
- infinite: !!this.infiniteReconnects
318
- })
318
+ if (this.aqua?.debugTrace) {
319
+ this.aqua._trace('node.ws.reconnect.scheduled', {
320
+ node: this.name,
321
+ attempt,
322
+ infinite: !!this.infiniteReconnects
323
+ })
324
+ }
319
325
 
320
326
  if (this.infiniteReconnects) {
321
327
  this.aqua.emit(AqualinkEvents.NodeReconnect, this, {
@@ -384,10 +390,12 @@ class Node {
384
390
  this._isConnecting = true
385
391
  this.state = NODE_STATE.CONNECTING
386
392
  this._cleanup()
387
- this.aqua?._trace?.('node.ws.connect', {
388
- node: this.name,
389
- url: this.wsUrl
390
- })
393
+ if (this.aqua?.debugTrace) {
394
+ this.aqua._trace('node.ws.connect', {
395
+ node: this.name,
396
+ url: this.wsUrl
397
+ })
398
+ }
391
399
 
392
400
  try {
393
401
  const h = this._boundHandlers
@@ -453,7 +461,7 @@ class Node {
453
461
 
454
462
  const ws = new WebSocketImpl(this.wsUrl, {
455
463
  headers: this._headers,
456
- perMessageDeflate: true,
464
+ perMessageDeflate: false,
457
465
  handshakeTimeout: this.timeout,
458
466
  maxPayload: this.maxPayload,
459
467
  skipUTF8Validation: this.skipUTF8Validation
@@ -588,12 +596,14 @@ class Node {
588
596
  oldSessionId && oldSessionId !== sessionId && !payload.resumed
589
597
 
590
598
  this.sessionId = sessionId
591
- this.aqua?._trace?.('node.ready.packet', {
592
- node: this.name,
593
- resumed: !!payload.resumed,
594
- oldSessionId,
595
- newSessionId: sessionId
596
- })
599
+ if (this.aqua?.debugTrace) {
600
+ this.aqua._trace('node.ready.packet', {
601
+ node: this.name,
602
+ resumed: !!payload.resumed,
603
+ oldSessionId,
604
+ newSessionId: sessionId
605
+ })
606
+ }
597
607
  this.rest.setSessionId(sessionId)
598
608
  this._headers['Session-Id'] = sessionId
599
609
 
@@ -601,19 +611,38 @@ class Node {
601
611
  this._emitDebug(
602
612
  `Session changed from ${oldSessionId} to ${sessionId}, invalidating stale players`
603
613
  )
614
+ try {
615
+ await this.aqua._storeBrokenPlayers?.(this)
616
+ } catch (e) {
617
+ this._emitDebug(
618
+ `Failed to snapshot stale players before invalidation: ${e?.message || e}`
619
+ )
620
+ }
604
621
  const playersToDestroy = []
605
622
  for (const [guildId, player] of this.aqua.players) {
606
623
  if (player?.nodes === this || player?.nodes?.name === this.name) {
607
- playersToDestroy.push(guildId)
624
+ playersToDestroy.push({ guildId, player })
608
625
  }
609
626
  }
610
- for (const guildId of playersToDestroy) {
627
+ for (const { guildId, player } of playersToDestroy) {
611
628
  try {
612
- this._emitDebug(`Destroying stale player for guild ${guildId}`)
613
- await this.aqua.destroyPlayer(guildId)
629
+ this._emitDebug(
630
+ `Invalidating stale player for guild ${guildId} without voice disconnect`
631
+ )
632
+ player?.destroy?.({
633
+ preserveClient: true,
634
+ skipRemote: true,
635
+ preserveMessage: true,
636
+ preserveTracks: true,
637
+ preserveReconnecting: true
638
+ })
639
+ if (this.aqua.players.get(String(guildId)) === player) {
640
+ this.aqua.players.delete(String(guildId))
641
+ }
642
+ this.players?.delete?.(player)
614
643
  } catch (e) {
615
644
  this._emitDebug(
616
- `Failed to destroy stale player ${guildId}: ${e?.message || e}`
645
+ `Failed to invalidate stale player ${guildId}: ${e?.message || e}`
617
646
  )
618
647
  }
619
648
  }
@@ -635,11 +664,13 @@ class Node {
635
664
 
636
665
  async _resumePlayers() {
637
666
  if (!this.sessionId) return
638
- this.aqua?._trace?.('node.resume.begin', {
639
- node: this.name,
640
- sessionId: this.sessionId,
641
- players: this.aqua?.players?.size || 0
642
- })
667
+ if (this.aqua?.debugTrace) {
668
+ this.aqua._trace('node.resume.begin', {
669
+ node: this.name,
670
+ sessionId: this.sessionId,
671
+ players: this.aqua?.players?.size || 0
672
+ })
673
+ }
643
674
 
644
675
  try {
645
676
  await this.rest.makeRequest('PATCH', `/v4/sessions/${this.sessionId}`, {
@@ -653,18 +684,24 @@ class Node {
653
684
  (player?.nodes === this || player?.nodes?.name === this.name) &&
654
685
  player.voiceChannel
655
686
  ) {
656
- try {
657
- this._emitDebug(`Rejoining voice for guild ${guildId} on resume`)
658
- this.aqua?._trace?.('node.resume.rejoin', {
659
- node: this.name,
660
- guildId,
661
- voiceChannel: player.voiceChannel
662
- })
663
- player.connect({
664
- voiceChannel: player.voiceChannel,
665
- deaf: player.deaf,
666
- mute: player.mute
667
- })
687
+ try {
688
+ const recoveryToken = player._claimVoiceRecovery?.(
689
+ 'node_resume_rejoin'
690
+ )
691
+ this._emitDebug(`Rejoining voice for guild ${guildId} on resume`)
692
+ if (this.aqua?.debugTrace) {
693
+ this.aqua._trace('node.resume.rejoin', {
694
+ node: this.name,
695
+ guildId,
696
+ voiceChannel: player.voiceChannel
697
+ })
698
+ }
699
+ if (player._isVoiceRecoveryActive?.(recoveryToken))
700
+ player.connect({
701
+ voiceChannel: player.voiceChannel,
702
+ deaf: player.deaf,
703
+ mute: player.mute
704
+ })
668
705
  } catch (e) {
669
706
  this._emitDebug(
670
707
  `Failed to rejoin voice for ${guildId}: ${e?.message || e}`
@@ -678,10 +715,12 @@ class Node {
678
715
  await this.aqua.loadPlayers()
679
716
  }
680
717
  } catch (err) {
681
- this.aqua?._trace?.('node.resume.error', {
682
- node: this.name,
683
- error: _functions.errMsg(err)
684
- })
718
+ if (this.aqua?.debugTrace) {
719
+ this.aqua._trace('node.resume.error', {
720
+ node: this.name,
721
+ error: _functions.errMsg(err)
722
+ })
723
+ }
685
724
  this._emitError(`Failed to resume session: ${_functions.errMsg(err)}`)
686
725
  throw err
687
726
  }