Update advanced example to include more commands
This commit is contained in:
parent
d6186cb20d
commit
3ef98104ce
|
|
@ -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,28 +152,25 @@ 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
|
||||||
# i.e: player.get_tracks("query", search_type=SearchType.ytmsearch)
|
# i.e: player.get_tracks("query", search_type=SearchType.ytmsearch)
|
||||||
|
|
@ -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 self.is_privileged(ctx):
|
||||||
|
await ctx.send('An admin or DJ has stopped the player.', delete_after=10)
|
||||||
|
return await player.teardown()
|
||||||
|
|
||||||
|
required = self.required(ctx)
|
||||||
|
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)
|
||||||
|
|
||||||
if not player.is_playing:
|
|
||||||
return await ctx.send("Player is already stopped!")
|
|
||||||
|
|
||||||
await player.stop()
|
|
||||||
await ctx.send("Player has been stopped")
|
|
||||||
|
|
||||||
|
|
||||||
def setup(bot: commands.Bot):
|
def setup(bot: commands.Bot):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue