mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-17 03:53:29 +01:00
fix(voice): handle multiple transitions simultaneously (#11100)
* fix(voice): handle multiple transitions simultaneously * fix: fix execute transition return --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
@@ -105,9 +105,9 @@ export class DAVESession extends EventEmitter {
|
|||||||
public lastTransitionId?: number | undefined;
|
public lastTransitionId?: number | undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The pending transition.
|
* The pending transitions, mapped by their ID and the protocol version.
|
||||||
*/
|
*/
|
||||||
private pendingTransition?: VoiceDavePrepareTransitionData | undefined;
|
private pendingTransitions = new Map<number, number>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this session was downgraded previously.
|
* Whether this session was downgraded previously.
|
||||||
@@ -210,7 +210,7 @@ export class DAVESession extends EventEmitter {
|
|||||||
*/
|
*/
|
||||||
public prepareTransition(data: VoiceDavePrepareTransitionData) {
|
public prepareTransition(data: VoiceDavePrepareTransitionData) {
|
||||||
this.emit('debug', `Preparing for transition (${data.transition_id}, v${data.protocol_version})`);
|
this.emit('debug', `Preparing for transition (${data.transition_id}, v${data.protocol_version})`);
|
||||||
this.pendingTransition = data;
|
this.pendingTransitions.set(data.transition_id, data.protocol_version);
|
||||||
|
|
||||||
// When the included transition id is 0, the transition is for (re)initialization and it can be executed immediately.
|
// When the included transition id is 0, the transition is for (re)initialization and it can be executed immediately.
|
||||||
if (data.transition_id === 0) {
|
if (data.transition_id === 0) {
|
||||||
@@ -230,40 +230,31 @@ export class DAVESession extends EventEmitter {
|
|||||||
*/
|
*/
|
||||||
public executeTransition(transitionId: number) {
|
public executeTransition(transitionId: number) {
|
||||||
this.emit('debug', `Executing transition (${transitionId})`);
|
this.emit('debug', `Executing transition (${transitionId})`);
|
||||||
if (!this.pendingTransition) {
|
if (!this.pendingTransitions.has(transitionId)) {
|
||||||
this.emit('debug', `Received execute transition, but we don't have a pending transition for ${transitionId}`);
|
this.emit('debug', `Received execute transition, but we don't have a pending transition for ${transitionId}`);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let transitioned = false;
|
const oldVersion = this.protocolVersion;
|
||||||
if (transitionId === this.pendingTransition.transition_id) {
|
this.protocolVersion = this.pendingTransitions.get(transitionId)!;
|
||||||
const oldVersion = this.protocolVersion;
|
|
||||||
this.protocolVersion = this.pendingTransition.protocol_version;
|
|
||||||
|
|
||||||
// Handle upgrades & defer downgrades
|
// Handle upgrades & defer downgrades
|
||||||
if (oldVersion !== this.protocolVersion && this.protocolVersion === 0) {
|
if (oldVersion !== this.protocolVersion && this.protocolVersion === 0) {
|
||||||
this.downgraded = true;
|
this.downgraded = true;
|
||||||
this.emit('debug', 'Session downgraded');
|
this.emit('debug', 'Session downgraded');
|
||||||
} else if (transitionId > 0 && this.downgraded) {
|
} else if (transitionId > 0 && this.downgraded) {
|
||||||
this.downgraded = false;
|
this.downgraded = false;
|
||||||
this.session?.setPassthroughMode(true, TRANSITION_EXPIRY);
|
this.session?.setPassthroughMode(true, TRANSITION_EXPIRY);
|
||||||
this.emit('debug', 'Session upgraded');
|
this.emit('debug', 'Session upgraded');
|
||||||
}
|
|
||||||
|
|
||||||
// In the future we'd want to signal to the DAVESession to transition also, but it only supports v1 at this time
|
|
||||||
transitioned = true;
|
|
||||||
this.reinitializing = false;
|
|
||||||
this.lastTransitionId = transitionId;
|
|
||||||
this.emit('debug', `Transition executed (v${oldVersion} -> v${this.protocolVersion}, id: ${transitionId})`);
|
|
||||||
} else {
|
|
||||||
this.emit(
|
|
||||||
'debug',
|
|
||||||
`Received execute transition for an unexpected transition id (expected: ${this.pendingTransition.transition_id}, actual: ${transitionId})`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.pendingTransition = undefined;
|
// In the future we'd want to signal to the DAVESession to transition also, but it only supports v1 at this time
|
||||||
return transitioned;
|
this.reinitializing = false;
|
||||||
|
this.lastTransitionId = transitionId;
|
||||||
|
this.emit('debug', `Transition executed (v${oldVersion} -> v${this.protocolVersion}, id: ${transitionId})`);
|
||||||
|
|
||||||
|
this.pendingTransitions.delete(transitionId);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -328,7 +319,7 @@ export class DAVESession extends EventEmitter {
|
|||||||
this.reinitializing = false;
|
this.reinitializing = false;
|
||||||
this.lastTransitionId = transitionId;
|
this.lastTransitionId = transitionId;
|
||||||
} else {
|
} else {
|
||||||
this.pendingTransition = { transition_id: transitionId, protocol_version: this.protocolVersion };
|
this.pendingTransitions.set(transitionId, this.protocolVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emit('debug', `MLS commit processed (transition id: ${transitionId})`);
|
this.emit('debug', `MLS commit processed (transition id: ${transitionId})`);
|
||||||
@@ -355,7 +346,7 @@ export class DAVESession extends EventEmitter {
|
|||||||
this.reinitializing = false;
|
this.reinitializing = false;
|
||||||
this.lastTransitionId = transitionId;
|
this.lastTransitionId = transitionId;
|
||||||
} else {
|
} else {
|
||||||
this.pendingTransition = { transition_id: transitionId, protocol_version: this.protocolVersion };
|
this.pendingTransitions.set(transitionId, this.protocolVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emit('debug', `MLS welcome processed (transition id: ${transitionId})`);
|
this.emit('debug', `MLS welcome processed (transition id: ${transitionId})`);
|
||||||
@@ -392,7 +383,7 @@ export class DAVESession extends EventEmitter {
|
|||||||
this.consecutiveFailures = 0;
|
this.consecutiveFailures = 0;
|
||||||
return buffer;
|
return buffer;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (!this.reinitializing && !this.pendingTransition) {
|
if (!this.reinitializing && this.pendingTransitions.size === 0) {
|
||||||
this.consecutiveFailures++;
|
this.consecutiveFailures++;
|
||||||
this.emit('debug', `Failed to decrypt a packet (${this.consecutiveFailures} consecutive fails)`);
|
this.emit('debug', `Failed to decrypt a packet (${this.consecutiveFailures} consecutive fails)`);
|
||||||
if (this.consecutiveFailures > this.failureTolerance) {
|
if (this.consecutiveFailures > this.failureTolerance) {
|
||||||
@@ -401,11 +392,8 @@ export class DAVESession extends EventEmitter {
|
|||||||
}
|
}
|
||||||
} else if (this.reinitializing) {
|
} else if (this.reinitializing) {
|
||||||
this.emit('debug', 'Failed to decrypt a packet (reinitializing session)');
|
this.emit('debug', 'Failed to decrypt a packet (reinitializing session)');
|
||||||
} else if (this.pendingTransition) {
|
} else if (this.pendingTransitions.size > 0) {
|
||||||
this.emit(
|
this.emit('debug', `Failed to decrypt a packet (${this.pendingTransitions.size} pending transition[s])`);
|
||||||
'debug',
|
|
||||||
`Failed to decrypt a packet (pending transition ${this.pendingTransition.transition_id} to v${this.pendingTransition.protocol_version})`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user