From 960f936ef528f0c1581e5b99925bb423aa8cb8d4 Mon Sep 17 00:00:00 2001 From: Snazzah Date: Wed, 10 Sep 2025 13:25:34 -0400 Subject: [PATCH] Allow for multiple transitions to be handled --- discord/gateway.py | 12 +++--------- discord/voice_state.py | 39 +++++++++++++++------------------------ 2 files changed, 18 insertions(+), 33 deletions(-) diff --git a/discord/gateway.py b/discord/gateway.py index aa05cd59f..aadb516fb 100644 --- a/discord/gateway.py +++ b/discord/gateway.py @@ -1006,7 +1006,7 @@ class DiscordVoiceWebSocket: data['transition_id'], data['protocol_version'], ) - state.dave_pending_transition = data + state.dave_pending_transitions[data['transition_id']] = data['protocol_version'] if data['transition_id'] == 0: await state._execute_transition(data['transition_id']) else: @@ -1052,10 +1052,7 @@ class DiscordVoiceWebSocket: try: state.dave_session.process_commit(msg[5:]) if transition_id != 0: - state.dave_pending_transition = { - 'transition_id': transition_id, - 'protocol_version': state.dave_protocol_version, - } + state.dave_pending_transitions[transition_id] = state.dave_protocol_version await self.send_transition_ready(transition_id) _log.debug('MLS commit processed for transition id %d', transition_id) except Exception: @@ -1065,10 +1062,7 @@ class DiscordVoiceWebSocket: try: state.dave_session.process_welcome(msg[5:]) if transition_id != 0: - state.dave_pending_transition = { - 'transition_id': transition_id, - 'protocol_version': state.dave_protocol_version, - } + state.dave_pending_transitions[transition_id] = state.dave_protocol_version await self.send_transition_ready(transition_id) _log.debug('MLS welcome processed for transition id %d', transition_id) except Exception: diff --git a/discord/voice_state.py b/discord/voice_state.py index 5dced277f..cec745c86 100644 --- a/discord/voice_state.py +++ b/discord/voice_state.py @@ -218,7 +218,7 @@ class VoiceConnectionState: self.ws: DiscordVoiceWebSocket = MISSING self.dave_session: Optional[davey.DaveSession] = None self.dave_protocol_version: int = 0 - self.dave_pending_transition: Optional[Dict[str, Any]] = None + self.dave_pending_transitions: Dict[int, int] = {} self.dave_downgraded: bool = False self._state: ConnectionFlowState = ConnectionFlowState.disconnected @@ -301,33 +301,24 @@ class VoiceConnectionState: async def _execute_transition(self, transition_id: int) -> None: _log.debug('Executing transition id %d', transition_id) - if not self.dave_pending_transition: + if transition_id not in self.dave_pending_transitions: _log.warning("Received execute transition, but we don't have a pending transition for id %d", transition_id) return - if transition_id == self.dave_pending_transition['transition_id']: - old_version = self.dave_protocol_version - self.dave_protocol_version = self.dave_pending_transition['protocol_version'] - - if old_version != self.dave_protocol_version and self.dave_protocol_version == 0: - self.dave_downgraded = True - _log.debug('DAVE Session downgraded') - elif transition_id > 0 and self.dave_downgraded: - self.dave_downgraded = False - if self.dave_session: - self.dave_session.set_passthrough_mode(True, 10) - _log.debug('DAVE Session upgraded') - - # In the future, the session should be signaled too, but for now theres just v1 - _log.debug('Transition id %d executed', transition_id) - else: - _log.debug( - 'Received execute transition for an unexpected transition id %d when the expected transition id is %d', - transition_id, - self.dave_pending_transition['transition_id'], - ) + old_version = self.dave_protocol_version + self.dave_protocol_version = self.dave_pending_transitions.pop(transition_id) + + if old_version != self.dave_protocol_version and self.dave_protocol_version == 0: + self.dave_downgraded = True + _log.debug('DAVE Session downgraded') + elif transition_id > 0 and self.dave_downgraded: + self.dave_downgraded = False + if self.dave_session: + self.dave_session.set_passthrough_mode(True, 10) + _log.debug('DAVE Session upgraded') - self.dave_pending_transition = None + # In the future, the session should be signaled too, but for now theres just v1 + _log.debug('Transition id %d executed', transition_id) async def voice_state_update(self, data: GuildVoiceStatePayload) -> None: channel_id = data['channel_id']