From c4ad2998258d47ce712860360b60b9f28aaea8ad Mon Sep 17 00:00:00 2001 From: Michael Rittmeister Date: Thu, 20 Jan 2022 15:43:05 +0100 Subject: [PATCH] Make instantiating JDA implementation more flexible --- build.gradle.kts | 2 +- jda/build.gradle.kts | 2 + .../dev/schlaubi/lavakord/jda/Builder.kt | 135 ++++++++++++++---- .../kotlin/dev/schlaubi/lavakord/jda/JDA.kt | 6 +- 4 files changed, 111 insertions(+), 34 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9458b5e4..ea79c6cd 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -7,7 +7,7 @@ plugins { } group = "dev.schlaubi.lavakord" -version = "3.3.0" +version = "3.4.0" allprojects { repositories { diff --git a/jda/build.gradle.kts b/jda/build.gradle.kts index 1025c46d..f4c9f9c5 100644 --- a/jda/build.gradle.kts +++ b/jda/build.gradle.kts @@ -13,6 +13,8 @@ kotlin { jvmMain { dependencies { api(projects.core) + api(libs.kotlinlogging) + api(libs.kotlinx.coroutines.jdk8) implementation("net.dv8tion:JDA:5.0.0-alpha.4") { exclude(module = "opus-java") } diff --git a/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/Builder.kt b/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/Builder.kt index e311549d..6a5fbb8c 100644 --- a/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/Builder.kt +++ b/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/Builder.kt @@ -1,18 +1,22 @@ package dev.schlaubi.lavakord.jda +import dev.schlaubi.lavakord.LavaKord import dev.schlaubi.lavakord.LavaKordOptions import dev.schlaubi.lavakord.MutableLavaKordOptions import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.asCoroutineDispatcher +import kotlinx.coroutines.future.await +import mu.KotlinLogging import net.dv8tion.jda.api.JDA import net.dv8tion.jda.api.JDABuilder import net.dv8tion.jda.api.hooks.EventListener import net.dv8tion.jda.api.hooks.VoiceDispatchInterceptor import net.dv8tion.jda.api.sharding.DefaultShardManagerBuilder +import net.dv8tion.jda.api.sharding.ShardManager import kotlin.coroutines.CoroutineContext +private val LOG = KotlinLogging.logger { } + /** * Builds a new [LavaKordJDA] and applies [builder] to it. * @@ -22,29 +26,111 @@ import kotlin.coroutines.CoroutineContext * * @see LavaKordJDA */ -public fun JDABuilder.buildWithLavakord( +public suspend fun JDABuilder.buildWithLavakord( executor: CoroutineContext? = null, options: MutableLavaKordOptions = MutableLavaKordOptions(), builder: LavaKordOptions.() -> Unit = {} ): LJDA { + val lavaKordJDA = LavaKordJDA() + applyLavakord(lavaKordJDA) + + build().lavakord(lavaKordJDA, executor, options, builder) + + return lavaKordJDA +} + +/** + * Applies all needed options of this [shardManager] to this [DefaultShardManagerBuilder]. + * + * @see buildWithLavakord + */ +public fun DefaultShardManagerBuilder.applyLavakord(shardManager: LavaKordShardManager): DefaultShardManagerBuilder = + apply { + addEventListeners(shardManager) + setVoiceDispatchInterceptor(shardManager) + } + +/** + * Applies all needed options of this [jda] to this [JDABuilder]. + * + * @see buildWithLavakord + */ +public fun JDABuilder.applyLavakord(jda: LavaKordJDA): JDABuilder = + apply { + addEventListeners(jda) + setVoiceDispatchInterceptor(jda) + } + +/** + * Builds the [LavaKord] instance for this [ShardManager]. + * + * Example usage: + * ```kotlin + * val lavakordShardManager = LavaKordShardManager() + * val shardManager = DefaultShardManagerBuilder.createDefault(token) + * // you don't need to call this and add "lavakordShardManager" as an event listener and VoiceDispatchInterceptor yourself + * .applyLavakord(lavakordShardManager) + * .build() + * + * val lavakord = shardManager.lavakord(lavakordShardManager) + */ +public suspend fun ShardManager.lavakord( + shardManager: LavaKordShardManager, + executor: CoroutineContext? = null, + options: MutableLavaKordOptions = MutableLavaKordOptions(), + builder: LavaKordOptions.() -> Unit = {} +): LavaKord { + shardManager.shardManager = this + val jdaProvider: (Int) -> JDA = + { shardId -> getShardById(shardId) ?: error("Could not find shard with id: $shardId") } + val settings = options.apply(builder).seal() - val lavakordJda = LavaKordJDA() - addEventListeners(lavakordJda) - setVoiceDispatchInterceptor(lavakordJda) - val jda = build() - val coroutineContext = executor ?: jda.gatewayPool.asCoroutineDispatcher() - lavakordJda.jda = jda - val jdaProvider: (Int) -> JDA = { jda } val lavakord = JDALavakord( jdaProvider, - coroutineContext, - jda.selfUser.idLong.toULong(), - jda.shardInfo.shardTotal, + executor ?: (Dispatchers.IO + SupervisorJob()), + retrieveApplicationInfo().submit().await().idLong.toULong(), + shardsTotal, settings ) - lavakordJda.internalLavakord = lavakord + shardManager.internalLavakord = lavakord + return lavakord +} + +/** + * Builds the [LavaKord] instance for this [ShardManager]. + * + * Example usage: + * ```kotlin + * val lavakordJDA = LavaKordJDA() + * val jda = JDABuilder.createDefault(token) + * // you don't need to call this and add "LavaKordJDA" as an event listener and VoiceDispatchInterceptor yourself + * .applyLavakord(lavakordShardManager) + * .build() + * + * val lavakord = jda.lavakord(lavakordJDA) + */ +public suspend fun JDA.lavakord( + jda: LavaKordJDA, + executor: CoroutineContext? = null, + options: MutableLavaKordOptions = MutableLavaKordOptions(), + builder: LavaKordOptions.() -> Unit = {} +): LavaKord { + if (shardManager != null) { + LOG.warn { "JDA.lavakord() was called on a shard managed instance, consider using ShardManager.lavakord()" } + } + jda.jda = this + val jdaProvider: (Int) -> JDA = { this } - return lavakordJda + val settings = options.apply(builder).seal() + val lavakord = JDALavakord( + jdaProvider, + executor ?: (Dispatchers.IO + SupervisorJob()), + retrieveApplicationInfo().submit().await().idLong.toULong(), + 1, + settings + ) + jda.internalLavakord = lavakord + return lavakord } /** @@ -56,27 +142,16 @@ public fun JDABuilder.buildWithLavakord( * * @see LavaKordShardManager */ -public fun DefaultShardManagerBuilder.buildWithLavakord( +public suspend fun DefaultShardManagerBuilder.buildWithLavakord( executor: CoroutineContext? = null, options: MutableLavaKordOptions = MutableLavaKordOptions(), builder: LavaKordOptions.() -> Unit = {} ): LShardManager { - val settings = options.apply(builder).seal() val lavakordShardManager = LavaKordShardManager() - addEventListeners(lavakordShardManager) - setVoiceDispatchInterceptor(lavakordShardManager) + applyLavakord(lavakordShardManager) val shardManager = build() - lavakordShardManager.shardManager = shardManager - val jdaProvider: (Int) -> JDA = - { shardId -> shardManager.getShardById(shardId) ?: error("Could not find shard with id: $shardId") } - val lavakord = JDALavakord( - jdaProvider, - executor ?: (Dispatchers.IO + SupervisorJob()), - shardManager.retrieveApplicationInfo().complete().idLong.toULong(), - shardManager.shardsTotal, - settings - ) - lavakordShardManager.internalLavakord = lavakord + shardManager.lavakord(lavakordShardManager, executor, options, builder) + return lavakordShardManager } diff --git a/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/JDA.kt b/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/JDA.kt index afdc1bca..dbf23375 100644 --- a/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/JDA.kt +++ b/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/JDA.kt @@ -37,7 +37,7 @@ public interface LShardManager : LavakordJdaBase { /** * Internal class. */ -internal sealed class AbstractLavakordJda : VoiceDispatchInterceptor, EventListener, LavakordJdaBase { +public sealed class AbstractLavakordJda : VoiceDispatchInterceptor, EventListener, LavakordJdaBase { /** * The [LavaKord] instance that for this [JDA]/[ShardManager]. */ @@ -69,7 +69,7 @@ internal sealed class AbstractLavakordJda : VoiceDispatchInterceptor, EventListe * * @property jda the [JDA] instance that has been built */ -internal class LavaKordJDA : AbstractLavakordJda(), LJDA { +public class LavaKordJDA : AbstractLavakordJda(), LJDA { override lateinit var jda: JDA internal set } @@ -81,7 +81,7 @@ internal class LavaKordJDA : AbstractLavakordJda(), LJDA { * * @property shardManager the [ShardManager] instance that has been built */ -internal class LavaKordShardManager : AbstractLavakordJda(), LShardManager { +public class LavaKordShardManager : AbstractLavakordJda(), LShardManager { override lateinit var shardManager: ShardManager internal set }