package net.mysterio.api.lavaplayer import com.github.kaktushose.jda.commands.dispatching.interactions.commands.CommandEvent import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers import com.sedmelluq.discord.lavaplayer.source.youtube.YoutubeAudioSourceManager import com.sedmelluq.discord.lavaplayer.tools.FriendlyException import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist import com.sedmelluq.discord.lavaplayer.track.AudioTrack import net.dv8tion.jda.api.EmbedBuilder import net.dv8tion.jda.api.entities.Guild import net.dv8tion.jda.api.interactions.components.buttons.Button import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder import net.mysterio.api.internal.EmbedColor import java.text.SimpleDateFormat import java.util.* import java.util.concurrent.TimeUnit object PlayerManager { private val musicManagers = mutableMapOf() private val audioPlayerManager = DefaultAudioPlayerManager().apply { registerSourceManager(YoutubeAudioSourceManager()) } private val dateFormat = SimpleDateFormat("MM-dd-yyyy HH:mm:ss", Locale.US) private fun getFooterText(): String { return "Castor Developed By: Devan Mysterio • ${dateFormat.format(Date())}" } fun getMusicManager(guild: Guild): GuildMusicManager = musicManagers.getOrPut(guild.idLong) { GuildMusicManager(audioPlayerManager) } fun loadAndPlay(channel: CommandEvent, trackUrl: String, guild: Guild) { val musicManager = getMusicManager(guild) audioPlayerManager.loadItemOrdered(musicManager, trackUrl, object : AudioLoadResultHandler { override fun trackLoaded(track: AudioTrack) { musicManager.scheduler.queue(track) sendNowPlayingEmbed(channel, track) } override fun playlistLoaded(playlist: AudioPlaylist) { channel.reply("Sorry, I don't support playing playlists directly. Please provide a single video URL or search for a song.") } override fun noMatches() { channel.reply("No matches found for: $trackUrl") } override fun loadFailed(exception: FriendlyException) { channel.reply("Failed to load: ${exception.message}") } }) } fun searchAndPlay(channel: CommandEvent, searchQuery: String, guild: Guild) { val musicManager = getMusicManager(guild) audioPlayerManager.loadItemOrdered(musicManager, "ytsearch:$searchQuery", object : AudioLoadResultHandler { override fun trackLoaded(track: AudioTrack) { musicManager.scheduler.queue(track) sendNowPlayingEmbed(channel, track) } override fun playlistLoaded(playlist: AudioPlaylist) { val tracks = playlist.tracks.take(5) val description = buildString { appendLine("Select a song to play:") tracks.forEachIndexed { index, track -> appendLine("${index + 1}. ${track.info.title} by ${track.info.author} [${formatTime(track.duration)}]") } } val embedBuilder = EmbedBuilder() .setColor(EmbedColor.INFO.color) .setTitle("\uD83C\uDFB5 Search Results") .setDescription(description) .setFooter(getFooterText(), "https://cdn.discordapp.com/app-icons/880863250034593883/c92f688b4ad4b4c25c9b729d882cd048.png?size=64") val buttons = List(tracks.size) { index -> Button.success("play_$index", "${index + 1}") } val message = MessageCreateBuilder() .addEmbeds(embedBuilder.build()) .addActionRow(buttons) .build() channel.setEphemeral(true).reply("I've sent the search results in the channel. Please select a song to play!") channel.messageChannel.sendMessage(message).queue() musicManager.lastSearchResults = tracks } override fun noMatches() { channel.reply("No matches found for: $searchQuery") } override fun loadFailed(exception: FriendlyException) { channel.reply("Failed to load: ${exception.message}") } }) } fun sendNowPlayingEmbed(channel: CommandEvent, track: AudioTrack) { val embedBuilder = EmbedBuilder() .setColor(EmbedColor.SUCCESS.color) .setTitle("\uD83C\uDFB5 Now Playing") .addField("Title", track.info.title, false) .addField("Author", track.info.author, false) .addField("Duration", formatTime(track.duration), false) .addField("URL", track.info.uri, false) .setThumbnail("https://img.youtube.com/vi/${track.info.identifier}/0.jpg") .setFooter(getFooterText(), "https://cdn.discordapp.com/app-icons/880863250034593883/c92f688b4ad4b4c25c9b729d882cd048.png?size=64") channel.messageChannel.sendMessageEmbeds(embedBuilder.build()).queue() } private fun formatTime(timeInMillis: Long): String { val hours = TimeUnit.MILLISECONDS.toHours(timeInMillis) val minutes = TimeUnit.MILLISECONDS.toMinutes(timeInMillis) % 60 val seconds = TimeUnit.MILLISECONDS.toSeconds(timeInMillis) % 60 return String.format("%02d:%02d:%02d", hours, minutes, seconds) } }