From 72abc43db8f732743c65d6f6a820369ab8665766 Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 4 Feb 2026 16:19:22 +0100 Subject: more asynchronous work and other minor improvements --- cogs/voice.py | 78 +++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 26 deletions(-) (limited to 'cogs/voice.py') diff --git a/cogs/voice.py b/cogs/voice.py index 261af49..dd5b74a 100644 --- a/cogs/voice.py +++ b/cogs/voice.py @@ -14,43 +14,69 @@ class Voice(commands.Cog): def __init__(self, bot): self.bot = bot - async def ensure_voice_client(self, ctx): - """Ensure we have a valid voice client connection.""" + async def _validate_user_voice_state(self, ctx): + """Validate that user is in a voice channel.""" if not ctx.author.voice or not ctx.author.voice.channel: await ctx.send("You need to be in a voice channel first!") + return False + return True + + async def _create_voice_client(self, ctx): + """Create a new voice client connection.""" + try: + voice_client = await ctx.author.voice.channel.connect(timeout=30.0, reconnect=True) + logger.info(f"Connected to voice channel: {ctx.author.voice.channel}") + return voice_client + except asyncio.TimeoutError: + await ctx.send("Connection to voice channel timed out.") + return None + except discord.ClientException as e: + logger.error(f"Failed to connect to voice channel: {e}") + await ctx.send("Failed to connect to voice channel. Please try again.", ephemeral=True) + return None + + async def _move_voice_client(self, voice_client, ctx): + """Move existing voice client to user's channel.""" + try: + await voice_client.move_to(ctx.author.voice.channel) + logger.info(f"Moved to voice channel: {ctx.author.voice.channel}") + return voice_client + except asyncio.TimeoutError: + await ctx.send("Connection to voice channel timed out.") + return None + except discord.ClientException as e: + logger.error(f"Failed to move to voice channel: {e}") + await ctx.send("Failed to move to your voice channel. Please try again.", ephemeral=True) + return None + + async def _verify_connection(self, voice_client): + """Verify and repair voice client connection if needed.""" + if not voice_client.is_connected(): + try: + await voice_client.connect(reconnect=True, timeout=10.0) + return voice_client + except Exception as e: + logger.error(f"Failed to reconnect to voice: {e}") + return None + return voice_client + + async def ensure_voice_client(self, ctx): + """Ensure we have a valid voice client connection.""" + if not await self._validate_user_voice_state(ctx): return None voice_client = discord.utils.get(self.bot.voice_clients, guild=ctx.guild) # If no voice client exists, create one if not voice_client or not voice_client.is_connected(): - try: - voice_client = await ctx.author.voice.channel.connect(timeout=30.0, reconnect=True) - logger.info(f"Connected to voice channel: {ctx.author.voice.channel}") - except asyncio.TimeoutError: - await ctx.send("Connection to voice channel timed out.") - except discord.ClientException as e: - logger.error(f"Failed to connect to voice channel: {e}") - await ctx.send("Failed to connect to voice channel. Please try again.", ephemeral=True) + return await self._create_voice_client(ctx) + # If we're in a different channel, move to the user's channel - elif voice_client.channel != ctx.author.voice.channel: - try: - await voice_client.move_to(ctx.author.voice.channel) - logger.info(f"Moved to voice channel: {ctx.author.voice.channel}") - except asyncio.TimeoutError: - await ctx.send("Connection to voice channel timed out.") - except discord.ClientException as e: - logger.error(f"Failed to move to voice channel: {e}") - await ctx.send("Failed to move to your voice channel. Please try again.", ephemeral=True) + if voice_client.channel != ctx.author.voice.channel: + return await self._move_voice_client(voice_client, ctx) # Verify the connection is healthy - if not voice_client.is_connected(): - try: - await voice_client.connect(reconnect=True, timeout=10.0) - except Exception as e: - logger.error(f"Failed to reconnect to voice: {e}") - await ctx.send("Failed to establish voice connection. Please try again.") - return None + return await self._verify_connection(voice_client) async def connect(self, ctx): """Connect to the user's voice channel with improved connection handling.""" -- cgit v1.2.3