Merge pull request #7 from strNophix/lavalink-redis

Lavalink redis
This commit is contained in:
2021-11-02 20:49:50 +01:00
committed by GitHub
4 changed files with 74 additions and 36 deletions
+4 -2
View File
@@ -43,7 +43,9 @@ class InformationCog(commands.Cog, name="Information"):
@commands.cooldown(rate=1, per=5, type=commands.BucketType.user) @commands.cooldown(rate=1, per=5, type=commands.BucketType.user)
async def invite(self, ctx: Context): async def invite(self, ctx: Context):
"""Gets the invite link!""" """Gets the invite link!"""
await EmbedGenerator.Message(ctx, "Add our bot to your server:", self.bot.invite_link) await EmbedGenerator.Message(
ctx, "Add our bot to your server:", self.bot.invite_link
)
@commands.command( @commands.command(
name="wlinfo", name="wlinfo",
@@ -77,7 +79,7 @@ class InformationCog(commands.Cog, name="Information"):
@commands.command(name="help", aliases=["about", "info"], slash_command=True) @commands.command(name="help", aliases=["about", "info"], slash_command=True)
@commands.cooldown(1, 1, commands.BucketType.user) @commands.cooldown(1, 1, commands.BucketType.user)
async def about(self, ctx: Context): async def about(self, ctx: Context):
"""Exobot command list""" """ChristmasBot command list"""
if None: if None:
entity = self.bot.get_cog(command) or self.bot.get_command(command) entity = self.bot.get_cog(command) or self.bot.get_command(command)
+67 -32
View File
@@ -1,13 +1,18 @@
import asyncio
import re import re
from aioredis.client import Redis
import discord import discord
from discord.channel import TextChannel
from discord.ext.commands.context import Context from discord.ext.commands.context import Context
import lavalink import lavalink
from discord.ext import commands from discord.ext import commands
from lavalink.models import DefaultPlayer from lavalink.models import AudioTrack, DefaultPlayer
from bot import ChristmasBot from bot import ChristmasBot
from utils.EmbedGenerator import EmbedGenerator from utils.EmbedGenerator import EmbedGenerator
from context import CustomContext
from discord import Embed
url_rx = re.compile(r"https?://(?:www\.)?.+") url_rx = re.compile(r"https?://(?:www\.)?.+")
@@ -16,15 +21,7 @@ class LavalinkVoiceClient(discord.VoiceClient):
def __init__(self, client: discord.Client, channel: discord.abc.Connectable): def __init__(self, client: discord.Client, channel: discord.abc.Connectable):
self.client = client self.client = client
self.channel = channel self.channel = channel
# ensure there exists a client already self.lavalink = self.client.lavalink
if hasattr(self.client, "lavalink"):
self.lavalink = self.client.lavalink
else:
self.client.lavalink = lavalink.Client(client.user.id)
self.client.lavalink.add_node(
"localhost", 2333, "youshallnotpass", "us", "default-node"
)
self.lavalink = self.client.lavalink
async def on_voice_server_update(self, data): async def on_voice_server_update(self, data):
# the data needs to be transformed before being handed down to # the data needs to be transformed before being handed down to
@@ -94,9 +91,13 @@ class Music(commands.Cog):
async def cog_before_invoke(self, ctx): async def cog_before_invoke(self, ctx):
"""Command before-invoke handler.""" """Command before-invoke handler."""
guild_check = ctx.guild is not None guild_check = ctx.guild is not None
# This is essentially the same as `@commands.guild_only()` # This is essentially the same as `@commands.guild_only()`
# except it saves us repeating ourselves (and also a few lines). # except it saves us repeating ourselves (and also a few lines).
if not hasattr(self.bot, "lavalink"):
await ctx.send("Still starting please wait a moment.")
if guild_check: if guild_check:
await self.ensure_voice(ctx) await self.ensure_voice(ctx)
# Ensure that the bot and command author share a mutual voicechannel. # Ensure that the bot and command author share a mutual voicechannel.
@@ -124,7 +125,7 @@ class Music(commands.Cog):
# These are commands that require the bot to join a voicechannel (i.e. initiating playback). # These are commands that require the bot to join a voicechannel (i.e. initiating playback).
# Commands such as volume/skip etc don't require the bot to be in a voicechannel so don't need listing here. # Commands such as volume/skip etc don't require the bot to be in a voicechannel so don't need listing here.
should_connect = ctx.command.name in ("play",) should_connect = ctx.command.name in ("connect",)
if not ctx.author.voice or not ctx.author.voice.channel: if not ctx.author.voice or not ctx.author.voice.channel:
# Our cog_command_error handler catches this and sends it to the voicechannel. # Our cog_command_error handler catches this and sends it to the voicechannel.
@@ -159,39 +160,73 @@ class Music(commands.Cog):
guild_id = int(event.player.guild_id) guild_id = int(event.player.guild_id)
guild = self.bot.get_guild(guild_id) guild = self.bot.get_guild(guild_id)
await guild.voice_client.disconnect(force=True) await guild.voice_client.disconnect(force=True)
elif isinstance(event, lavalink.events.TrackStartEvent):
channel_id = int(event.player.fetch("channel"))
channel: TextChannel = self.bot.get_channel(channel_id)
@commands.command(name="play", aliases=["p", "connect", "join"]) color = self.bot.colors["embed"]
@commands.guild_only() current_track: AudioTrack = event.player.current
async def play(self, ctx: Context): embed = Embed(
"""Searches and plays a song from a given query.""" title="Now playing:",
description=f"[{current_track.title}]({current_track.uri})",
color=color,
)
await channel.send(embed=embed)
elif isinstance(event, lavalink.events.TrackEndEvent):
query = await self.bot._redis_client.randomkey()
result = await event.player.node.get_tracks(query)
if not result or not result["tracks"]:
return
track = lavalink.models.AudioTrack(
result["tracks"][0], self.bot.user.id, recommended=False
)
event.player.add(requester=self.bot.user.id, track=track)
@commands.command(name="connect", aliases=["p", "play", "join"])
async def play(self, ctx: CustomContext):
"""Starts playing Christmas bangers"""
# Get the player for this guild from cache. # Get the player for this guild from cache.
player: DefaultPlayer = self.bot.lavalink.player_manager.get(ctx.guild.id) player: DefaultPlayer = self.bot.lavalink.player_manager.get(ctx.guild.id)
query = "https://youtu.be/VcIt_AcOPjs" redis_client: Redis = ctx.get_redis()
pipeline = redis_client.pipeline()
for _ in range(self.bot.config["queue_buffer_size"]):
pipeline.randomkey()
queries = await pipeline.execute()
# Get the results for the query from Lavalink. # Get the results for the query from Lavalink.
results = await player.node.get_tracks(query) for query in queries:
result = await player.node.get_tracks(query)
if not result or not result["tracks"]:
continue
# Results could be None if Lavalink returns an invalid response (non-JSON/non-200 (OK)). track = lavalink.models.AudioTrack(
# ALternatively, resullts['tracks'] could be an empty array if the query yielded no tracks. result["tracks"][0], ctx.author.id, recommended=False
if not results or not results["tracks"]: )
return await EmbedGenerator.Title(ctx, "Nothing found!") player.add(requester=ctx.author.id, track=track)
# Theoretically songs will always be TRACK_LOADED
track = results["tracks"][0]
await EmbedGenerator.Message(
ctx, "Track Enqueued", f'[{track["info"]["title"]}]({track["info"]["uri"]})'
)
track = lavalink.models.AudioTrack(track, ctx.author.id, recommended=True)
player.add(requester=ctx.author.id, track=track)
if not player.is_playing: if not player.is_playing:
await player.play() await player.play()
await ctx.send("Started playing")
@commands.command(name="skip", aliases=["next"])
async def skip(self, ctx: Context):
"""I heard this song way too often"""
player: DefaultPlayer = self.bot.lavalink.player_manager.get(ctx.guild.id)
await player.skip()
await ctx.send("Skipped current song")
@commands.command(name="queue")
async def queue(self, ctx: Context):
"""Ghetto queue"""
player: DefaultPlayer = self.bot.lavalink.player_manager.get(ctx.guild.id)
await EmbedGenerator.Message(ctx, "Queue:", player.queue)
@commands.command(name="disconnect", aliases=["dc", "stop"]) @commands.command(name="disconnect", aliases=["dc", "stop"])
@commands.guild_only()
async def disconnect(self, ctx: Context): async def disconnect(self, ctx: Context):
"""Disconnects the player from the voice channel and clears its queue.""" """Disconnects ChristmasBot"""
player: DefaultPlayer = self.bot.lavalink.player_manager.get(ctx.guild.id) player: DefaultPlayer = self.bot.lavalink.player_manager.get(ctx.guild.id)
if not player.is_connected: if not player.is_connected:
+2 -1
View File
@@ -18,5 +18,6 @@
"description": "A sample bot description" "description": "A sample bot description"
}, },
"cogs": ["cogs.owner", "cogs.settings", "cogs.information", "cogs.music"], "cogs": ["cogs.owner", "cogs.settings", "cogs.information", "cogs.music"],
"slash_command_guilds": [] "slash_command_guilds": [],
"queue_buffer_size": 5
} }
+1 -1
View File
@@ -39,4 +39,4 @@ class EmbedGenerator:
em.set_footer(text=f"Requested by: {ctx.author}", icon_url=avatar) em.set_footer(text=f"Requested by: {ctx.author}", icon_url=avatar)
if kwargs.get("no_send", False): if kwargs.get("no_send", False):
return em return em
return await ctx.send(embed=em, **kwargs) return await ctx.send(embed=em, **kwargs)