package net.taehui.twilight.system import com.fasterxml.jackson.databind.ObjectMapper import net.dv8tion.jda.api.JDA import net.dv8tion.jda.api.JDA.Status import net.dv8tion.jda.api.JDABuilder import net.dv8tion.jda.api.entities.Guild import net.dv8tion.jda.api.entities.Member import net.dv8tion.jda.api.entities.channel.concrete.TextChannel import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent import net.dv8tion.jda.api.events.guild.member.GuildMemberUpdateEvent import net.dv8tion.jda.api.events.guild.member.update.GuildMemberUpdateAvatarEvent import net.dv8tion.jda.api.events.message.MessageDeleteEvent import net.dv8tion.jda.api.events.message.MessageReceivedEvent import net.dv8tion.jda.api.events.message.MessageUpdateEvent import net.dv8tion.jda.api.hooks.ListenerAdapter import net.dv8tion.jda.api.requests.GatewayIntent import net.taehui.twilight.* import org.apache.hc.client5.http.classic.methods.HttpGet import org.apache.hc.client5.http.impl.classic.HttpClients import java.text.NumberFormat import java.util.* import java.util.concurrent.CompletableFuture import java.util.concurrent.ConcurrentHashMap object PlatformSystem : Logger { class Client { var platform = "" var qwilight = 0L var siteComment = 0L var siteDefault = 0L var sitePlatform = 0L var siteAudio = 0L var siteYellDefault = "" var siteYellEnter = "" var siteYellQuit = "" var siteYellTaehui = "" var siteYellComment = "" var siteYellAbility = "" var siteYellAbilityMini = "" var siteYellLevel = "" var siteYellInvite = "" var siteYellTV = "" } private val drawingStore = ConcurrentHashMap<String, ByteArray>() private lateinit var platformClient: Client private var platform: JDA? = null private var qwilightPlatform: Guild? = null var platformAvatars = emptyList<Member>() fun handleSystem() { if (Configure.mode.platform) { try { fun doCallPlatformAvatars() { qwilightPlatform?.loadMembers()?.onSuccess { avatars -> platformAvatars = avatars.filter { !it.user.isBot && !it.user.isSystem } CompletableFuture.allOf( *platformAvatars.map { putDrawing("$${it.id}", it.effectiveAvatarUrl) }.toTypedArray() ) }?.onSuccess { SiteHandler.doCallSiteAvatar( SiteHandler.platformSiteID, platformAvatars ) } } platformClient = ObjectMapper().readValue( Twilight::class.java.classLoader.getResourceAsStream("Client.json"), Client::class.java ) platform = JDABuilder.createDefault(platformClient.platform) .enableIntents(GatewayIntent.MESSAGE_CONTENT, GatewayIntent.GUILD_MEMBERS) .addEventListeners(object : ListenerAdapter() { override fun onMessageReceived(event: MessageReceivedEvent) { event.member?.let { if (!event.author.isBot && !event.author.isSystem) { if (event.channel.idLong == platformClient.siteDefault) { event.message.delete().queue() SiteHandler.putSiteYell(SiteHandler.defaultSiteID, it, event) } else if (event.channel.idLong == platformClient.sitePlatform) { SiteHandler.putSiteYell(SiteHandler.platformSiteID, it, event) } } } } override fun onMessageUpdate(event: MessageUpdateEvent) { if (event.channel.idLong == platformClient.sitePlatform) { event.member?.let { SiteHandler.doModifySIteYell(SiteHandler.platformSiteID, it, event) } } } override fun onMessageDelete(event: MessageDeleteEvent) { if (event.channel.idLong == platformClient.sitePlatform) { SiteHandler.wipeSiteYell(SiteHandler.platformSiteID, event) } } override fun onGuildMemberJoin(event: GuildMemberJoinEvent) { doCallPlatformAvatars() } override fun onGuildMemberRemove(event: GuildMemberRemoveEvent) { doCallPlatformAvatars() } override fun onGuildMemberUpdateAvatar(event: GuildMemberUpdateAvatarEvent) { doCallPlatformAvatars() } override fun onGuildMemberUpdate(event: GuildMemberUpdateEvent) { doCallPlatformAvatars() } }).build().awaitReady() qwilightPlatform = platform?.getGuildById(platformClient.qwilight) doCallPlatformAvatars() qwilightPlatform?.audioManager?.openAudioConnection(qwilightPlatform?.getVoiceChannelById(platformClient.siteAudio)) } catch (e: Throwable) { logFault(e) } } } val platformStatus: String get() = (platform?.status ?: Status.SHUTDOWN).toString() fun dispose() { platform?.shutdown() } fun sendSiteYell(siteYellData: JSON.TwilightSiteYell) { try { var site: TextChannel? = null when (UUID.fromString(siteYellData.siteID)) { SiteHandler.commentSiteID -> site = qwilightPlatform?.getTextChannelById(platformClient.siteComment) SiteHandler.defaultSiteID -> site = qwilightPlatform?.getTextChannelById(platformClient.siteDefault) } when (siteYellData.avatarName) { "@Enter" -> site?.sendMessage(String.format(platformClient.siteYellEnter, siteYellData.siteYell)) "@Quit" -> site?.sendMessage(String.format(platformClient.siteYellQuit, siteYellData.siteYell)) "@Notify" -> site?.sendMessage( String.format( platformClient.siteYellTaehui, siteYellData.siteYell ) ) "@Comment" -> { val twilightCommentSiteYell = ObjectMapper().readValue(siteYellData.siteYell, JSON.TwilightCommentSiteYell::class.java) site?.sendMessage( String.format( platformClient.siteYellComment, twilightCommentSiteYell.avatarName, twilightCommentSiteYell.levelText, twilightCommentSiteYell.artist, twilightCommentSiteYell.title, if (twilightCommentSiteYell.genre.isEmpty()) "" else "#${twilightCommentSiteYell.genre}", NumberFormat.getInstance().format(twilightCommentSiteYell.stand.toLong()) ) ) } "@Ability" -> { val twilightAbilitySiteYell = ObjectMapper().readValue(siteYellData.siteYell, JSON.TwilightAbilitySiteYell::class.java) val inputMode = when (twilightAbilitySiteYell.inputMode) { Component.InputMode.INPUT_MODE_5_1 -> "⑤K" Component.InputMode.INPUT_MODE_7_1 -> "⑦K" Component.InputMode.INPUT_MODE_9 -> "9K" else -> "" } val ability = twilightAbilitySiteYell.ability site?.sendMessage( if (ability < 0.01) String.format( platformClient.siteYellAbilityMini, twilightAbilitySiteYell.avatarName, inputMode ) else String.format( platformClient.siteYellAbility, twilightAbilitySiteYell.avatarName, inputMode, ability ) ) } "@Level" -> { val twilightLevelSiteYell = ObjectMapper().readValue(siteYellData.siteYell, JSON.TwilightLevelSiteYell::class.java) site?.sendMessage( String.format( platformClient.siteYellLevel, twilightLevelSiteYell.avatarName, twilightLevelSiteYell.title ) ) } "@Invite" -> { val twilightInviteSiteYell = ObjectMapper().readValue(siteYellData.siteYell, JSON.TwilightInviteSiteYell::class.java) site?.sendMessage( String.format( platformClient.siteYellInvite, twilightInviteSiteYell.avatarName, twilightInviteSiteYell.siteName ) ) } "@TV" -> { val twilightTVSiteYell = ObjectMapper().readValue(siteYellData.siteYell, JSON.TwilightTVSiteYell::class.java) site?.sendMessage( String.format( platformClient.siteYellTV, twilightTVSiteYell.text, twilightTVSiteYell.title ) ) } else -> { site?.sendMessage( String.format( platformClient.siteYellDefault, siteYellData.avatarName, siteYellData.siteYell ) ) } }?.queue() } catch (e: Throwable) { logFault(e) } } fun putDrawing(avatarID: String, platformDrawing: String): CompletableFuture<Void> { return if (drawingStore.containsKey(avatarID)) { CompletableFuture.completedFuture(null) } else { logFuture { HttpClients.createDefault() .use { drawingStore[avatarID] = it.execute(HttpGet(platformDrawing), HCDataHandler()) } } } } fun getDrawing(avatarID: String): ByteArray? { return drawingStore[avatarID] } }