Browse Source

Moved a lot of checks to before_invokes for less clutter and easier maintainability.

tags/v2.0.0
Roxie Gibson 5 years ago
parent
commit
7b43468893
1 changed files with 62 additions and 64 deletions
  1. +62
    -64
      roxbot/cogs/voice.py

+ 62
- 64
roxbot/cogs/voice.py View File

# Just invoke the play command with the stream argument as true. Deals with everything else anyway. # Just invoke the play command with the stream argument as true. Deals with everything else anyway.
return await ctx.invoke(self.play, url=url, stream=True) return await ctx.invoke(self.play, url=url, stream=True)


@play.before_invoke
@stream.before_invoke
async def ensure_voice(self, ctx):
"""Ensures the bot is in a voice channel before continuing and if it cannot auto join, raise an error."""
if ctx.voice_client is None:
if ctx.author.voice:
await ctx.author.voice.channel.connect()
else:
raise commands.CommandError("Roxbot is not connected to a voice channel and couldn't auto-join a voice channel.")

@volume_perms() @volume_perms()
@commands.guild_only() @commands.guild_only()
@commands.command() @commands.command()
async def volume(self, ctx, volume): async def volume(self, ctx, volume):
"""Changes the player's volume. Only accepts integers representing x% between 0-100% or "show", which will show the current volume.""" """Changes the player's volume. Only accepts integers representing x% between 0-100% or "show", which will show the current volume."""
if ctx.voice_client is None:
raise commands.CommandError("Roxbot is not in a voice channel.")

try: try:
volume = int(volume) volume = int(volume)
except ValueError: except ValueError:
@commands.command() @commands.command()
async def pause(self, ctx): async def pause(self, ctx):
"""Pauses the current video, if playing.""" """Pauses the current video, if playing."""
if ctx.voice_client is None:
raise commands.CommandError("Roxbot is not in a voice channel.")
if ctx.voice_client.is_paused():
return await ctx.send("I already am paused!")
else: else:
if not ctx.voice_client.is_playing():
return await ctx.send("Nothing is playing.")
elif ctx.voice_client.is_paused():
return await ctx.send("I already am paused!")
else:
ctx.voice_client.pause()
return await ctx.send("Paused '{}'".format(ctx.voice_client.source.title))
ctx.voice_client.pause()
return await ctx.send("Paused '{}'".format(ctx.voice_client.source.title))


@commands.guild_only() @commands.guild_only()
@commands.command() @commands.command()
async def resume(self, ctx): async def resume(self, ctx):
"""Resumes the bot if paused. Also will play the next thing in the queue if the bot is stuck.""" """Resumes the bot if paused. Also will play the next thing in the queue if the bot is stuck."""
if ctx.voice_client is None:
if len(self.playlist[ctx.guild.id]) < 1:
raise commands.CommandError("Roxbot is not in a voice channel.")
else:
video = self.playlist[ctx.guild.id].pop(0)
await ctx.invoke(self.play, url=video)
if ctx.voice_client.is_paused():
ctx.voice_client.resume()
return await ctx.send("Resumed '{}'".format(ctx.voice_client.source.title))
else: else:
if ctx.voice_client.is_paused():
ctx.voice_client.resume()
return await ctx.send("Resumed '{}'".format(ctx.voice_client.source.title))
if ctx.voice_client.is_playing():
return await ctx.send("Can't resume if I'm already playing something!")
else: else:
if ctx.voice_client.is_playing():
return await ctx.send("Can't resume if I'm already playing something!")
else:
return await ctx.send("Nothing to resume.")
return await ctx.send("Nothing to resume.")


@commands.guild_only() @commands.guild_only()
@commands.command() @commands.command()
async def skip(self, ctx, option=""): async def skip(self, ctx, option=""):
"""Skips or votes to skip the current video. Can use option "--force" if you have manage_channels permission. """ """Skips or votes to skip the current video. Can use option "--force" if you have manage_channels permission. """
voice = roxbot.guild_settings.get(ctx.guild)["voice"] voice = roxbot.guild_settings.get(ctx.guild)["voice"]
if ctx.voice_client.is_playing():
if voice["skip_voting"] and not (option == "--force" and ctx.author.guild_permissions.manage_channels): # Admin force skipping
if ctx.author in self.skip_votes[ctx.guild.id]:
return await ctx.send("You have already voted to skip the current track.")
else:
self.skip_votes[ctx.guild.id].append(ctx.author)
# -1 due to the bot being counted in the members generator
ratio = len(self.skip_votes[ctx.guild.id]) / (len(ctx.voice_client.channel.members) - 1)
needed_users = ceil((len(ctx.voice_client.channel.members) - 1) * voice["skip_ratio"])
if ratio >= voice["skip_ratio"]:
await ctx.send("{} voted the skip the video.".format(ctx.author))
await ctx.send("Votes to skip now playing has been met. Skipping video...")
self.skip_votes[ctx.guild.id] = []
else:
await ctx.send("{} voted the skip the song.".format(ctx.author))
return await ctx.send("{}/{} votes required to skip the video. To vote, use the command `{}skip`".format(len(self.skip_votes[ctx.guild.id]), needed_users, ctx.prefix))
if voice["skip_voting"] and not (option == "--force" and ctx.author.guild_permissions.manage_channels): # Admin force skipping
if ctx.author in self.skip_votes[ctx.guild.id]:
return await ctx.send("You have already voted to skip the current track.")
else: else:
await ctx.send("Skipped video")

# This should be fine as the queue_logic function should handle moving to the next song and all that.
self.now_playing[ctx.guild.id] = None
ctx.voice_client.stop()
self.skip_votes[ctx.guild.id].append(ctx.author)
# -1 due to the bot being counted in the members generator
ratio = len(self.skip_votes[ctx.guild.id]) / (len(ctx.voice_client.channel.members) - 1)
needed_users = ceil((len(ctx.voice_client.channel.members) - 1) * voice["skip_ratio"])
if ratio >= voice["skip_ratio"]:
await ctx.send("{} voted the skip the video.".format(ctx.author))
await ctx.send("Votes to skip now playing has been met. Skipping video...")
self.skip_votes[ctx.guild.id] = []
else:
await ctx.send("{} voted the skip the song.".format(ctx.author))
return await ctx.send("{}/{} votes required to skip the video. To vote, use the command `{}skip`".format(len(self.skip_votes[ctx.guild.id]), needed_users, ctx.prefix))
else: else:
await ctx.send("I'm not playing anything.")
await ctx.send("Skipped video")

# This should be fine as the queue_logic function should handle moving to the next song and all that.
self.now_playing[ctx.guild.id] = None
ctx.voice_client.stop()



@commands.guild_only() @commands.guild_only()
@commands.command(aliases=["np"]) @commands.command(aliases=["np"])
@commands.command(alaises=["disconnect"]) @commands.command(alaises=["disconnect"])
async def stop(self, ctx): async def stop(self, ctx):
"""Stops and disconnects the bot from voice. Requires the Manage Channels permission""" """Stops and disconnects the bot from voice. Requires the Manage Channels permission"""
# Clear up variables before stopping.
self.playlist[ctx.guild.id] = []
self.now_playing[ctx.guild.id] = None
self.queue_logic[ctx.guild.id].cancel()
await ctx.voice_client.disconnect()
return await ctx.send(":wave:")

@play.before_invoke
@stream.before_invoke
async def ensure_voice(self, ctx):
"""Ensures the bot is in a voice channel before continuing and if it cannot auto join, raise an error."""
if ctx.voice_client is None:
if ctx.author.voice:
await ctx.author.voice.channel.connect()
else:
raise commands.CommandError("Roxbot is not connected to a voice channel and couldn't auto-join a voice channel.")

@skip.before_invoke
@stop.before_invoke
@pause.before_invoke
@resume.before_invoke
@volume.before_invoke
async def check_in_voice(self, ctx):
if ctx.voice_client is None: if ctx.voice_client is None:
raise commands.CommandError("Roxbot is not in a voice channel.") raise commands.CommandError("Roxbot is not in a voice channel.")
else:
# Clear up variables before stopping.
self.playlist[ctx.guild.id] = []
self.now_playing[ctx.guild.id] = None
self.queue_logic[ctx.guild.id].cancel()
await ctx.voice_client.disconnect()
return await ctx.send(":wave:")

@skip.before_invoke
@pause.before_invoke
async def check_playing(self, ctx):
try:
if not ctx.voice_client.is_playing():
raise commands.CommandError("I'm not playing anything.")
except AttributeError:
raise commands.CommandError("I'm not playing anything.")


@commands.has_permissions(manage_channels=True) @commands.has_permissions(manage_channels=True)
@commands.command() @commands.command()

Loading…
Cancel
Save