diff --git a/discord/gateway.py b/discord/gateway.py index f88305f8d..2ed93f9b3 100644 --- a/discord/gateway.py +++ b/discord/gateway.py @@ -943,7 +943,7 @@ class DiscordVoiceWebSocket: _log.debug('Voice websocket frame received: %s', msg) op = msg['op'] data = msg['d'] # According to Discord this key is always given - self.seq_ack = msg.get('seq', self.seq_ack) # this key may not be given + self.seq_ack = msg.get('seq', self.seq_ack) # this key could not be given if op == self.READY: await self.initial_connection(data) diff --git a/discord/voice_state.py b/discord/voice_state.py index d3092d861..57cce010f 100644 --- a/discord/voice_state.py +++ b/discord/voice_state.py @@ -603,8 +603,8 @@ class VoiceConnectionState: # The following close codes are undocumented so I will document them here. # 1000 - normal closure (obviously) # 4014 - we were externally disconnected (voice channel deleted, we were moved, etc) - # 4015 - voice server has crashed - if exc.code in (1000, 4015): + # 4015 - voice server has crashed, we should resume + if exc.code == 1000: # Don't call disconnect a second time if the websocket closed from a disconnect call if not self._expecting_disconnect: _log.info('Disconnecting from voice normally, close code %d.', exc.code) @@ -631,6 +631,21 @@ class VoiceConnectionState: else: continue + if exc.code == 4015: + try: + await self._connect( + reconnect=reconnect, + timeout=self.timeout, + self_deaf=(self.self_voice_state or self).self_deaf, + self_mute=(self.self_voice_state or self).self_mute, + resume=True, + ) + except asyncio.TimeoutError: + _log.warning('Could not resume the voice connection... Disconnecting...') + if self.state is not ConnectionFlowState.disconnected: + await self.disconnect() + break + _log.debug('Not handling close code %s (%s)', exc.code, exc.reason or 'no reason') if not reconnect: