Browse Source

Fix bad voice state when moving to a voice channel without permissions

pull/10109/head
Imayhaveborkedit 2 years ago
committed by dolfies
parent
commit
6d244db403
  1. 3
      discord/voice_client.py
  2. 28
      discord/voice_state.py

3
discord/voice_client.py

@ -356,8 +356,7 @@ class VoiceClient(VoiceProtocol):
asyncio.TimeoutError asyncio.TimeoutError
The move did not complete in time, but may still be ongoing. The move did not complete in time, but may still be ongoing.
""" """
await self._connection.move_to(channel) await self._connection.move_to(channel, timeout)
await self._connection.wait_async(timeout)
def is_connected(self) -> bool: def is_connected(self) -> bool:
"""Indicates if the voice client is connected to voice.""" """Indicates if the voice client is connected to voice."""

28
discord/voice_state.py

@ -459,16 +459,23 @@ class VoiceConnectionState:
if self.socket: if self.socket:
self.socket.close() self.socket.close()
async def move_to(self, channel: Optional[abc.Snowflake]) -> None: async def move_to(self, channel: Optional[abc.Snowflake], timeout: Optional[float]) -> None:
if channel is None: if channel is None:
await self.disconnect() await self.disconnect()
return return
if self.guild: previous_state = self.state
await self.guild.change_voice_state(channel=channel) # this is only an outgoing ws request
else: # if it fails, nothing happens and nothing changes (besides self.state)
await self.voice_client._state.client.change_voice_state(channel=channel) await self._move_to(channel)
self.state = ConnectionFlowState.set_guild_voice_state last_state = self.state
try:
await self.wait_async(timeout)
except asyncio.TimeoutError:
_log.warning('Timed out trying to move to channel %s in guild %s', channel.id, self.guild.id if self.guild else 'private')
if self.state is last_state:
_log.debug('Reverting to previous state %s', previous_state.name)
self.state = previous_state
def wait(self, timeout: Optional[float] = None) -> bool: def wait(self, timeout: Optional[float] = None) -> bool:
return self._connected.wait(timeout) return self._connected.wait(timeout)
@ -510,7 +517,7 @@ class VoiceConnectionState:
_log.info( _log.info(
'The voice handshake is being terminated for Channel ID %s (Guild ID %s)', 'The voice handshake is being terminated for Channel ID %s (Guild ID %s)',
self.voice_client.channel.id, self.voice_client.channel.id,
self.guild.id if self.guild else "private", self.guild.id if self.guild else 'private',
) )
self.state = ConnectionFlowState.disconnected self.state = ConnectionFlowState.disconnected
if self.guild: if self.guild:
@ -603,3 +610,10 @@ class VoiceConnectionState:
return False return False
else: else:
return True return True
async def _move_to(self, channel: abc.Snowflake) -> None:
if self.guild:
await self.guild.change_voice_state(channel=channel)
else:
await self.voice_client._state.client.change_voice_state(channel=channel)
self.state = ConnectionFlowState.set_guild_voice_state

Loading…
Cancel
Save