aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cogs/voice.py54
1 files changed, 43 insertions, 11 deletions
diff --git a/cogs/voice.py b/cogs/voice.py
index f079c6a..a224336 100644
--- a/cogs/voice.py
+++ b/cogs/voice.py
@@ -80,17 +80,29 @@ class VoiceManager:
80 logger.info(f"Already connected to {channel}") 80 logger.info(f"Already connected to {channel}")
81 return vc 81 return vc
82 logger.warning(f"Stale connection to {channel}, reconnecting") 82 logger.warning(f"Stale connection to {channel}, reconnecting")
83 # Disconnect resets the state machine to 'disconnected'
84 # but keeps the VoiceClient alive. Reusing it avoids a
85 # race where Discord sends VOICE_SERVER_UPDATE between
86 # the destroy and the fresh-connect below, causing the
87 # new client to timeout waiting for the event (since the
88 # old one already consumed it).
83 try: 89 try:
84 await vc.disconnect() 90 await vc.disconnect()
85 except Exception: 91 except Exception:
86 pass 92 pass
87 # Forcefully clear stale internal state so the fresh
88 # connect doesn't hang for 30s waiting for Discord.
89 try: 93 try:
90 channel._state._remove_voice_client(guild.id) 94 await vc.connect(
91 except Exception: 95 reconnect=False, timeout=10.0, self_deaf=False, self_mute=False
92 pass 96 )
93 vc = None 97 logger.info(f"Reconnected to voice channel: {channel}")
98 return vc
99 except Exception as e:
100 logger.error(f"Failed to reconnect stale voice client: {e}")
101 try:
102 channel._state._remove_voice_client(guild.id)
103 except Exception:
104 pass
105 vc = None
94 else: 106 else:
95 try: 107 try:
96 await vc.move_to(channel) 108 await vc.move_to(channel)
@@ -102,18 +114,38 @@ class VoiceManager:
102 await vc.disconnect() 114 await vc.disconnect()
103 except Exception: 115 except Exception:
104 pass 116 pass
117 try:
118 await vc.connect(
119 reconnect=False, timeout=10.0, self_deaf=False, self_mute=False
120 )
121 logger.info(f"Reconnected after failed move: {channel}")
122 return vc
123 except Exception:
124 pass
125 try:
126 channel._state._remove_voice_client(guild.id)
127 except Exception:
128 pass
105 vc = None 129 vc = None
106 else: 130 else:
107 logger.info("Voice client exists but disconnected, cleaning up stale entry") 131 logger.info("Voice client exists but disconnected, reconnecting")
108 try: 132 try:
109 await vc.disconnect() 133 await vc.disconnect()
110 except Exception: 134 except Exception:
111 pass 135 pass
112 try: 136 try:
113 channel._state._remove_voice_client(guild.id) 137 await vc.connect(
114 except Exception: 138 reconnect=False, timeout=10.0, self_deaf=False, self_mute=False
115 pass 139 )
116 vc = None 140 logger.info(f"Reconnected disconnected client: {channel}")
141 return vc
142 except Exception as e:
143 logger.error(f"Failed to reconnect disconnected client: {e}")
144 try:
145 channel._state._remove_voice_client(guild.id)
146 except Exception:
147 pass
148 vc = None
117 149
118 # --- create fresh connection -------------------------------------- 150 # --- create fresh connection --------------------------------------
119 self._connecting.add(guild_id) 151 self._connecting.add(guild_id)