mirror of
https://github.com/UiO-Gaming/ShiteMusicBot.git
synced 2026-11-05 13:56:51 +01:00
107 lines
4.5 KiB
Python
107 lines
4.5 KiB
Python
# Discord Packages
|
|
import lavalink
|
|
from discord.ext import commands
|
|
|
|
from ..utils import thumbnailer, timeformatter
|
|
from .music_errors import WrongTextChannelError
|
|
|
|
|
|
class Music(commands.Cog):
|
|
def __init__(self, bot):
|
|
self.bot = bot
|
|
self.logger = self.bot.main_logger.bot_logger.getChild("Music")
|
|
|
|
self.bot = bot
|
|
self.leave_timer.start()
|
|
self.logger = self.bot.main_logger.bot_logger.getChild("Errors")
|
|
bot.lavalink.add_event_hook(self.track_hook)
|
|
|
|
async def cog_check(self, ctx):
|
|
if not ctx.guild:
|
|
raise commands.NoPrivateMessage
|
|
if textchannels := self.bot.settings.get(ctx.guild, 'channels.text', []):
|
|
if ctx.channel.id not in textchannels:
|
|
raise WrongTextChannelError('You need to be in the right text channel', channels=textchannels)
|
|
return True
|
|
|
|
async def cog_before_invoke(self, ctx):
|
|
""" Ensures a valic player exists whenever a command is run """
|
|
region = ctx.guild.region if isinstance(ctx.guild.region, str) else ctx.guild.region.value
|
|
# Creates a new only if one doesn't exist, ensures a valid player for all checks.
|
|
self.bot.lavalink.player_manager.create(ctx.guild.id, endpoint=region)
|
|
|
|
async def connect_to(self, guild_id: int, channel_id: str):
|
|
""" Connects to the given voicechannel ID. A channel_id of `None` means disconnect. """
|
|
ws = self.bot._connection._get_websocket(guild_id)
|
|
await ws.voice_state(str(guild_id), channel_id)
|
|
|
|
async def enqueue(self, ctx, track, embed):
|
|
# TODO: rework
|
|
player = self.bot.lavalink.player_manager.get(ctx.guild.id)
|
|
|
|
maxlength = self.max_track_length(ctx.guild, player)
|
|
if maxlength and track['info']['length'] > maxlength:
|
|
embed.description = ctx.localizer.format_str("{enqueue.toolong}",
|
|
_length=timeformatter.format_ms(track['info']['length']),
|
|
_max=timeformatter.format_ms(maxlength))
|
|
return
|
|
|
|
# TODO: make use of track vs track dict more consistent
|
|
if isinstance(track, dict):
|
|
thumbnail_url = await thumbnailer.ThumbNailer.identify(
|
|
self, track['info']['identifier'], track['info']['uri'])
|
|
track = lavalink.models.AudioTrack(track, ctx.author.id, thumbnail_url=thumbnail_url)
|
|
|
|
track, pos_global, pos_local = player.add(requester=ctx.author.id, track=track)
|
|
|
|
if player.current is not None:
|
|
queue_duration = 0
|
|
for i, track in enumerate(player.queue):
|
|
if i == pos_global:
|
|
break
|
|
queue_duration += int(track.duration)
|
|
|
|
until_play = queue_duration + player.current.duration - player.position
|
|
until_play = timeformatter.format_ms(until_play)
|
|
embed.add_field(name="{enqueue.position}", value=f"`{pos_local + 1}({pos_global + 1})`", inline=True)
|
|
embed.add_field(name="{enqueue.playing_in}", value=f"`{until_play} ({{enqueue.estimated}})`", inline=True)
|
|
|
|
embed.title = '{enqueue.enqueued}'
|
|
thumbnail_url = track.extra["thumbnail_url"]
|
|
|
|
if thumbnail_url:
|
|
embed.set_thumbnail(url=thumbnail_url)
|
|
|
|
duration = timeformatter.format_ms(int(track.duration))
|
|
embed.description = f'[{track.title}]({track.uri})\n**{duration}**'
|
|
|
|
return embed
|
|
|
|
def max_track_length(self, guild, player):
|
|
# TODO: Move somewhere else
|
|
is_dynamic = self.bot.settings.get(guild, 'duration.is_dynamic', 'default_duration_type')
|
|
maxlength = self.bot.settings.get(guild, 'duration.max', None)
|
|
if maxlength is None:
|
|
return None
|
|
if len(player.listeners): # Avoid division by 0.
|
|
listeners = len(player.listeners)
|
|
else:
|
|
listeners = 1
|
|
if maxlength > 10 and is_dynamic:
|
|
return max(maxlength*60*1000/listeners, 60*10*1000)
|
|
else:
|
|
return maxlength*60*1000
|
|
|
|
# commands
|
|
from .basic_commands import (
|
|
_disconnect, _djremove, _move, _myqueue, _now, _pause, _play, _queue, _reconnect, _remove, _search, _seek,
|
|
_shuffle, _skip, _skip_to, _stop, _user_queue_remove, _volume)
|
|
# events
|
|
from .events import check_leave_voice, cog_unload, leave_check, leave_timer, on_voice_state_update, track_hook
|
|
# commands
|
|
from .extra_commands import _boost, _history, _lyrics, _normalize, _scrub
|
|
|
|
|
|
def setup(bot):
|
|
bot.add_cog(Music(bot))
|