Update advanced example to include more commands

This commit is contained in:
cloudwithax 2021-12-13 18:04:40 -05:00
parent d6186cb20d
commit 3ef98104ce
1 changed files with 164 additions and 36 deletions

View File

@ -8,6 +8,8 @@ from a queue system, advanced queue control and more.
import discord import discord
import pomice import pomice
import asyncio import asyncio
import math
import random
from discord.ext import commands from discord.ext import commands
from contextlib import suppress from contextlib import suppress
@ -101,6 +103,24 @@ class Music(commands.Cog):
) )
print(f"Node is ready!") print(f"Node is ready!")
async def required(self, ctx: commands.Context):
"""Method which returns required votes based on amount of members in a channel."""
player: Player = ctx.voice_client
channel = self.bot.get_channel(int(player.channel.id))
required = math.ceil((len(channel.members) - 1) / 2.5)
if ctx.command.name == 'stop':
if len(channel.members) == 3:
required = 2
return required
async def is_privileged(self, ctx: commands.Context):
"""Check whether the user is an Admin or DJ."""
player: Player = ctx.voice_client
return player.dj == ctx.author or ctx.author.guild_permissions.kick_members
# The following are events from pomice.events # The following are events from pomice.events
# We are using these so that if the track either stops or errors, # We are using these so that if the track either stops or errors,
@ -120,7 +140,7 @@ class Music(commands.Cog):
async def on_pomice_track_exception(self, player: Player, track, _): async def on_pomice_track_exception(self, player: Player, track, _):
await player.do_next() await player.do_next()
@commands.command(aliases=["connect"]) @commands.command(aliases=['join', 'joi', 'j', 'summon', 'su', 'con'])
async def join(self, ctx: commands.Context, *, channel: discord.VoiceChannel = None) -> None: async def join(self, ctx: commands.Context, *, channel: discord.VoiceChannel = None) -> None:
if not channel: if not channel:
channel = getattr(ctx.author.voice, "channel", None) channel = getattr(ctx.author.voice, "channel", None)
@ -132,27 +152,24 @@ class Music(commands.Cog):
# This library takes advantage of that and is how you initialize a player. # This library takes advantage of that and is how you initialize a player.
await ctx.author.voice.channel.connect(cls=Player) await ctx.author.voice.channel.connect(cls=Player)
player: Player = ctx.voice_client player: Player = ctx.voice_client
# Set the player context so we can use it so send messages # Set the player context so we can use it so send messages
player.set_context(ctx=ctx) player.set_context(ctx=ctx)
await ctx.send(f"Joined the voice channel `{channel.name}`") await ctx.send(f"Joined the voice channel `{channel.name}`")
@commands.command(aliases=["dc", "disconnect"]) @commands.command(aliases=['disconnect', 'dc', 'disc', 'lv', 'fuckoff'])
async def leave(self, ctx: commands.Context): async def leave(self, ctx: commands.Context):
if not ctx.voice_client: if not (player := ctx.voice_client):
return await ctx.send("You must be in a voice channel in order to use this command!") return await ctx.send("You must have the bot in a channel in order to use this command", delete_after=7)
player: pomice.Player = ctx.voice_client
await player.destroy() await player.destroy()
await ctx.send("Player has left the channel.") await ctx.send("Player has left the channel.")
@commands.command(aliases=["p"]) @commands.command(aliases=['pla', 'p'])
async def play(self, ctx: commands.Context, *, search: str) -> None: async def play(self, ctx: commands.Context, *, search: str) -> None:
# Checks if the player is in the channel before we play anything # Checks if the player is in the channel before we play anything
if not ctx.voice_client: if not (player := ctx.voice_client):
await ctx.invoke(self.join) await ctx.invoke(self.join)
player: Player = ctx.voice_client
# If you search a keyword, Pomice will automagically search the result using YouTube # If you search a keyword, Pomice will automagically search the result using YouTube
# You can pass in "search_type=" as an argument to change the search type # You can pass in "search_type=" as an argument to change the search type
@ -163,7 +180,7 @@ class Music(commands.Cog):
results = await player.get_tracks(search, ctx=ctx) results = await player.get_tracks(search, ctx=ctx)
if not results: if not results:
raise commands.CommandError("No results were found for that search term.") return await ctx.send("No results were found for that search term", delete_after=7)
if isinstance(results, pomice.Playlist): if isinstance(results, pomice.Playlist):
for track in results.tracks: for track in results.tracks:
@ -173,48 +190,159 @@ class Music(commands.Cog):
await player.queue.put(track) await player.queue.put(track)
if not player.is_playing: if not player.is_playing:
await player.play await player.do_next()
@commands.command() @commands.command(aliases=['pau', 'pa'])
async def pause(self, ctx: commands.Context): async def pause(self, ctx: commands.Context):
if not ctx.voice_client: """Pause the currently playing song."""
raise commands.CommandError("No player detected") if not (player := ctx.voice_client):
return await ctx.send("You must have the bot in a channel in order to use this command", delete_after=7)
player: pomice.Player = ctx.voice_client if player.is_paused or not player.is_connected:
return
if player.is_paused: if self.is_privileged(ctx):
return await ctx.send("Player is already paused!") await ctx.send('An admin or DJ has paused the player.', delete_after=10)
player.pause_votes.clear()
await player.set_pause(pause=True) return await player.set_pause(True)
await ctx.send("Player has been paused")
@commands.command() required = self.required(ctx)
player.pause_votes.add(ctx.author)
if len(player.pause_votes) >= required:
await ctx.send('Vote to pause passed. Pausing player.', delete_after=10)
player.pause_votes.clear()
await player.set_pause(True)
else:
await ctx.send(f'{ctx.author.mention} has voted to pause the player. Votes: {len(player.pause_votes)}/{required}', delete_after=15)
@commands.command(aliases=['res', 'r'])
async def resume(self, ctx: commands.Context): async def resume(self, ctx: commands.Context):
if not ctx.voice_client: """Resume a currently paused player."""
raise commands.CommandError("No player detected") if not (player := ctx.voice_client):
return await ctx.send("You must have the bot in a channel in order to use this command", delete_after=7)
player: pomice.Player = ctx.voice_client if not player.is_paused or not player.is_connected:
return
if not player.is_paused: if self.is_privileged(ctx):
return await ctx.send("Player is already playing!") await ctx.send('An admin or DJ has resumed the player.', delete_after=10)
player.resume_votes.clear()
await player.set_pause(pause=False) return await player.set_pause(False)
await ctx.send("Player has been resumed")
required = self.required(ctx)
player.resume_votes.add(ctx.author)
if len(player.resume_votes) >= required:
await ctx.send('Vote to resume passed. Resuming player.', delete_after=10)
player.resume_votes.clear()
await player.set_pause(False)
else:
await ctx.send(f'{ctx.author.mention} has voted to resume the player. Votes: {len(player.resume_votes)}/{required}', delete_after=15)
@commands.command(aliases=['n', 'nex', 'next', 'sk'])
async def skip(self, ctx: commands.Context):
"""Skip the currently playing song."""
if not (player := ctx.voice_client):
return await ctx.send("You must have the bot in a channel in order to use this command", delete_after=7)
if not player.is_connected:
return
if self.is_privileged(ctx):
await ctx.send('An admin or DJ has skipped the song.', delete_after=10)
player.skip_votes.clear()
return await player.stop()
if ctx.author == player.current.requester:
await ctx.send('The song requester has skipped the song.', delete_after=10)
player.skip_votes.clear()
return await player.stop()
required = self.required(ctx)
player.skip_votes.add(ctx.author)
if len(player.skip_votes) >= required:
await ctx.send('Vote to skip passed. Skipping song.', delete_after=10)
player.skip_votes.clear()
await player.stop()
else:
await ctx.send(f'{ctx.author.mention} has voted to skip the song. Votes: {len(player.skip_votes)}/{required} ', delete_after=15)
@commands.command() @commands.command()
async def stop(self, ctx: commands.Context): async def stop(self, ctx: commands.Context):
if not ctx.voice_client: """Stop the player and clear all internal states."""
raise commands.CommandError("No player detected") if not (player := ctx.voice_client):
return await ctx.send("You must have the bot in a channel in order to use this command", delete_after=7)
player: pomice.Player = ctx.voice_client if not player.is_connected:
return
if not player.is_playing: if self.is_privileged(ctx):
return await ctx.send("Player is already stopped!") await ctx.send('An admin or DJ has stopped the player.', delete_after=10)
return await player.teardown()
await player.stop() required = self.required(ctx)
await ctx.send("Player has been stopped") player.stop_votes.add(ctx.author)
if len(player.stop_votes) >= required:
await ctx.send('Vote to stop passed. Stopping the player.', delete_after=10)
await player.teardown()
else:
await ctx.send(f'{ctx.author.mention} has voted to stop the player. Votes: {len(player.stop_votes)}/{required}', delete_after=15)
@commands.command(aliases=['mix', 'shuf'])
async def shuffle(self, ctx: commands.Context):
"""Shuffle the players queue."""
if not (player := ctx.voice_client):
return await ctx.send("You must have the bot in a channel in order to use this command", delete_after=7)
if not player.is_connected:
return
if player.queue.qsize() < 3:
return await ctx.send('The queue is empty. Add some songs to shuffle the queue.', delete_after=15)
if self.is_privileged(ctx):
await ctx.send('An admin or DJ has shuffled the queue.', delete_after=10)
player.shuffle_votes.clear()
return random.shuffle(player.queue._queue)
required = self.required(ctx)
player.shuffle_votes.add(ctx.author)
if len(player.shuffle_votes) >= required:
await ctx.send('Vote to shuffle passed. Shuffling the queue.', delete_after=10)
player.shuffle_votes.clear()
random.shuffle(player.queue._queue)
else:
await ctx.send(f'{ctx.author.mention} has voted to shuffle the queue. Votes: {len(player.shuffle_votes)}/{required}', delete_after=15)
@commands.command(aliases=['v', 'vol'])
async def volume(self, ctx: commands.Context, *, vol: int):
"""Change the players volume, between 1 and 100."""
if not (player := ctx.voice_client):
return await ctx.send("You must have the bot in a channel in order to use this command", delete_after=7)
if not player.is_connected:
return
if not self.is_privileged(ctx):
return await ctx.send('Only the DJ or admins may change the volume.')
if not 0 < vol < 101:
return await ctx.send('Please enter a value between 1 and 100.')
await player.set_volume(vol)
await ctx.send(f'Set the volume to **{vol}**%', delete_after=7)
def setup(bot: commands.Bot): def setup(bot: commands.Bot):