import discord from discord.ext import commands import logging import asyncio logger = logging.getLogger(__name__) 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.""" if not ctx.author.voice or not ctx.author.voice.channel: await ctx.send("You need to be in a voice channel first!") 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) # 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) # 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 async def connect(self, ctx): """Connect to the user's voice channel with improved connection handling.""" voice_client = await self.ensure_voice_client(ctx) if not voice_client: return None return voice_client def setup(bot): bot.add_cog(Voice(bot))