Skip to content

Commit

Permalink
Update voice client for newer d.py versions
Browse files Browse the repository at this point in the history
  • Loading branch information
Ev-1 committed Mar 19, 2024
1 parent b0b4005 commit c5c246e
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 9 deletions.
4 changes: 2 additions & 2 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ run: venv
{{python}} bot.py

# Run with debug logging enabled
debug: run
--debug
debug: venv
{{python}} bot.py --debug

clean:
rm -rf {{env_name}}
Expand Down
10 changes: 8 additions & 2 deletions musicbot/cogs/music/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -507,15 +507,15 @@ async def _disconnect(self, ctx):
@commands.command(name='reconnect')
@require_voice_connection()
@voteable(DJ_override=True, react_to_vote=True)
async def _reconnect(self, ctx):
async def _reconnect(self, ctx, force: bool = False):
"""Tries to disconnect then reconnect the player in case the bot gets stuck on a song."""
player = self.get_player(ctx.guild)
current_channel = player.channel_id

async def inner_reconnect():
await player.stop()
if ctx.voice_client:
await ctx.voice_client.disconnect()
await ctx.voice_client.disconnect(force)
await asyncio.sleep(1) # Pretend stuff is happening/give everything some time to reset.
channel = ctx.guild.get_channel(current_channel)
await channel.connect(cls=BasicVoiceClient)
Expand Down Expand Up @@ -833,6 +833,7 @@ async def track_hook(self, event):
@commands.Cog.listener()
async def on_voice_state_update(self, member: discord.Member, _: discord.VoiceState, after: discord.VoiceState):
"""Updates listeners when the bot or a user changes voice state."""
self.logger.debug("Voice state update, member: %s, new_state: %s", member, after)
if self.bot.user is None:
return # Bot not logged in
if member.id == self.bot.user.id and after.channel is not None:
Expand All @@ -846,6 +847,11 @@ async def on_voice_state_update(self, member: discord.Member, _: discord.VoiceSt
if not member.bot:
player.update_listeners(member, member.voice)

if member.id == self.bot.user.id and after.channel is None:
voice_client: BasicVoiceClient
if voice_client := member.guild.voice_client:
await voice_client.disconnect(force=True)

if not member.bot:
try:
player = self.get_player(member.guild)
Expand Down
29 changes: 24 additions & 5 deletions musicbot/cogs/music/voice_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,43 @@
from musicbot.cogs.music.music_errors import MusicError


class BasicVoiceClient(discord.VoiceClient):
class BasicVoiceClient(discord.VoiceProtocol):
def __init__(self, client: MusicBot, channel: discord.VoiceChannel):
# Needs to be named client in order for base class to work
# in most cases lavalink handles disconnects, but if we force it then we'll get an error.
# during self.cleanup()
self.client = client
self.channel = channel
self.logger = self.client.main_logger.bot_logger.getChild("VoiceClient")
if self.client.lavalink:
self.lavalink = self.client.lavalink
else:
self.logger.debug("Client did not have defined lavalink before connect.")
raise MusicError("client did not have defined lavalink before connect")

async def on_voice_server_update(self, data):
await self.lavalink.voice_update_handler({'t': 'VOICE_SERVER_UPDATE', 'd': data})
self.logger.debug("BasicVoiceClient server update, %s", data)
await self.lavalink.voice_update_handler({"t": "VOICE_SERVER_UPDATE", "d": data})

async def on_voice_state_update(self, data):
await self.lavalink.voice_update_handler({'t': 'VOICE_STATE_UPDATE', 'd': data})
self.logger.debug("BasicVoiceClient state update, %s", data)
channel_id = data['channel_id']

async def connect(self, *, timeout: float, reconnect: bool, self_deaf: bool = False,
self_mute: bool = False) -> None:
if not channel_id:
self.cleanup()
return

self.channel = self.client.get_channel(int(channel_id))
await self.lavalink.voice_update_handler({"t": "VOICE_STATE_UPDATE", "d": data})

async def connect(
self, *, timeout: float, reconnect: bool, self_deaf: bool = False, self_mute: bool = False
) -> None:
self.logger.debug("Connecting to %s", self.channel)
await self.channel.guild.change_voice_state(channel=self.channel, self_mute=self_mute, self_deaf=self_deaf)

async def disconnect(self, *, force: bool = False) -> None:
self.logger.debug("Disconnecting from voice. Force: %s", force)
player = self.lavalink.player_manager.get(self.channel.guild.id)

if player:
Expand All @@ -35,6 +49,11 @@ async def disconnect(self, *, force: bool = False) -> None:
return

# None means disconnect
self.logger.debug("Player found, disconnecting and resetting player channel")
await self.channel.guild.change_voice_state(channel=None)
player.channel_id = None
self.cleanup()
elif force:
self.logger.debug("No player found, disconnecting")
await self.channel.guild.change_voice_state(channel=None)
self.cleanup()

0 comments on commit c5c246e

Please sign in to comment.