diff options
Diffstat (limited to 'cogs/voice.py')
| -rw-r--r-- | cogs/voice.py | 78 |
1 files changed, 52 insertions, 26 deletions
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): | |||
| 14 | def __init__(self, bot): | 14 | def __init__(self, bot): |
| 15 | self.bot = bot | 15 | self.bot = bot |
| 16 | 16 | ||
| 17 | async def ensure_voice_client(self, ctx): | 17 | async def _validate_user_voice_state(self, ctx): |
| 18 | """Ensure we have a valid voice client connection.""" | 18 | """Validate that user is in a voice channel.""" |
| 19 | if not ctx.author.voice or not ctx.author.voice.channel: | 19 | if not ctx.author.voice or not ctx.author.voice.channel: |
| 20 | await ctx.send("You need to be in a voice channel first!") | 20 | await ctx.send("You need to be in a voice channel first!") |
| 21 | return False | ||
| 22 | return True | ||
| 23 | |||
| 24 | async def _create_voice_client(self, ctx): | ||
| 25 | """Create a new voice client connection.""" | ||
| 26 | try: | ||
| 27 | voice_client = await ctx.author.voice.channel.connect(timeout=30.0, reconnect=True) | ||
| 28 | logger.info(f"Connected to voice channel: {ctx.author.voice.channel}") | ||
| 29 | return voice_client | ||
| 30 | except asyncio.TimeoutError: | ||
| 31 | await ctx.send("Connection to voice channel timed out.") | ||
| 32 | return None | ||
| 33 | except discord.ClientException as e: | ||
| 34 | logger.error(f"Failed to connect to voice channel: {e}") | ||
| 35 | await ctx.send("Failed to connect to voice channel. Please try again.", ephemeral=True) | ||
| 36 | return None | ||
| 37 | |||
| 38 | async def _move_voice_client(self, voice_client, ctx): | ||
| 39 | """Move existing voice client to user's channel.""" | ||
| 40 | try: | ||
| 41 | await voice_client.move_to(ctx.author.voice.channel) | ||
| 42 | logger.info(f"Moved to voice channel: {ctx.author.voice.channel}") | ||
| 43 | return voice_client | ||
| 44 | except asyncio.TimeoutError: | ||
| 45 | await ctx.send("Connection to voice channel timed out.") | ||
| 46 | return None | ||
| 47 | except discord.ClientException as e: | ||
| 48 | logger.error(f"Failed to move to voice channel: {e}") | ||
| 49 | await ctx.send("Failed to move to your voice channel. Please try again.", ephemeral=True) | ||
| 50 | return None | ||
| 51 | |||
| 52 | async def _verify_connection(self, voice_client): | ||
| 53 | """Verify and repair voice client connection if needed.""" | ||
| 54 | if not voice_client.is_connected(): | ||
| 55 | try: | ||
| 56 | await voice_client.connect(reconnect=True, timeout=10.0) | ||
| 57 | return voice_client | ||
| 58 | except Exception as e: | ||
| 59 | logger.error(f"Failed to reconnect to voice: {e}") | ||
| 60 | return None | ||
| 61 | return voice_client | ||
| 62 | |||
| 63 | async def ensure_voice_client(self, ctx): | ||
| 64 | """Ensure we have a valid voice client connection.""" | ||
| 65 | if not await self._validate_user_voice_state(ctx): | ||
| 21 | return None | 66 | return None |
| 22 | 67 | ||
| 23 | voice_client = discord.utils.get(self.bot.voice_clients, guild=ctx.guild) | 68 | voice_client = discord.utils.get(self.bot.voice_clients, guild=ctx.guild) |
| 24 | 69 | ||
| 25 | # If no voice client exists, create one | 70 | # If no voice client exists, create one |
| 26 | if not voice_client or not voice_client.is_connected(): | 71 | if not voice_client or not voice_client.is_connected(): |
| 27 | try: | 72 | return await self._create_voice_client(ctx) |
| 28 | voice_client = await ctx.author.voice.channel.connect(timeout=30.0, reconnect=True) | 73 | |
| 29 | logger.info(f"Connected to voice channel: {ctx.author.voice.channel}") | ||
| 30 | except asyncio.TimeoutError: | ||
| 31 | await ctx.send("Connection to voice channel timed out.") | ||
| 32 | except discord.ClientException as e: | ||
| 33 | logger.error(f"Failed to connect to voice channel: {e}") | ||
| 34 | await ctx.send("Failed to connect to voice channel. Please try again.", ephemeral=True) | ||
| 35 | # If we're in a different channel, move to the user's channel | 74 | # If we're in a different channel, move to the user's channel |
| 36 | elif voice_client.channel != ctx.author.voice.channel: | 75 | if voice_client.channel != ctx.author.voice.channel: |
| 37 | try: | 76 | return await self._move_voice_client(voice_client, ctx) |
| 38 | await voice_client.move_to(ctx.author.voice.channel) | ||
| 39 | logger.info(f"Moved to voice channel: {ctx.author.voice.channel}") | ||
| 40 | except asyncio.TimeoutError: | ||
| 41 | await ctx.send("Connection to voice channel timed out.") | ||
| 42 | except discord.ClientException as e: | ||
| 43 | logger.error(f"Failed to move to voice channel: {e}") | ||
| 44 | await ctx.send("Failed to move to your voice channel. Please try again.", ephemeral=True) | ||
| 45 | 77 | ||
| 46 | # Verify the connection is healthy | 78 | # Verify the connection is healthy |
| 47 | if not voice_client.is_connected(): | 79 | return await self._verify_connection(voice_client) |
| 48 | try: | ||
| 49 | await voice_client.connect(reconnect=True, timeout=10.0) | ||
| 50 | except Exception as e: | ||
| 51 | logger.error(f"Failed to reconnect to voice: {e}") | ||
| 52 | await ctx.send("Failed to establish voice connection. Please try again.") | ||
| 53 | return None | ||
| 54 | 80 | ||
| 55 | async def connect(self, ctx): | 81 | async def connect(self, ctx): |
| 56 | """Connect to the user's voice channel with improved connection handling.""" | 82 | """Connect to the user's voice channel with improved connection handling.""" |
