diff --git a/bom/build.gradle.kts b/bom/build.gradle.kts index 830d202c..2ff90615 100644 --- a/bom/build.gradle.kts +++ b/bom/build.gradle.kts @@ -1,10 +1,9 @@ plugins { + `lavalink-publishing` `java-platform` `maven-publish` } -applyPublishing() - val me = project // Without Gradle won't find any project with the publish plugin applied diff --git a/build.gradle.kts b/build.gradle.kts index 5f03bed5..8efcc5b5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,16 +1,13 @@ import org.ajoberstar.gradle.git.publish.GitPublishExtension plugins { - `maven-publish` - kotlin("multiplatform") version Versions.kotlin apply false - kotlin("plugin.serialization") version Versions.kotlin apply false - id("org.jetbrains.dokka") version "1.5.0" - id("kotlinx-atomicfu") version Versions.atomicFu apply false + id("org.jetbrains.dokka") + id("kotlinx-atomicfu") version "0.16.3" apply false id("org.ajoberstar.git-publish") version "2.1.3" } group = "dev.schlaubi.lavakord" -version = "2.1.0" +version = "3.0.0" allprojects { repositories { diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index fff27d92..59afb9b8 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -4,7 +4,7 @@ plugins { } group = "me.schlaubi" -version = "2.1.0" +version = "3.0.0" repositories { mavenCentral() @@ -12,6 +12,9 @@ repositories { } dependencies { + implementation(kotlin("gradle-plugin", version = "1.5.31")) + implementation(kotlin("serialization", version = "1.5.31")) + implementation("org.jetbrains.dokka", "dokka-gradle-plugin", "1.5.30") implementation(kotlin("gradle-plugin-api", version = "1.5.30")) implementation(gradleApi()) implementation(localGroovy()) diff --git a/buildSrc/src/main/kotlin/Compiler.kt b/buildSrc/src/main/kotlin/Compiler.kt deleted file mode 100644 index 51a59224..00000000 --- a/buildSrc/src/main/kotlin/Compiler.kt +++ /dev/null @@ -1,9 +0,0 @@ -object ExpermientalAnnotations { - const val requiresOptIn = "kotlin.RequiresOptIn" - const val experimentalTime = "kotlin.time.ExperimentalTime" - const val experimentalSerialization = "kotlinx.serialization.ExperimentalSerializationApi" -} - -object Jvm { - const val target = "1.8" -} diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt deleted file mode 100644 index f3ad645b..00000000 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ /dev/null @@ -1,46 +0,0 @@ -import org.gradle.api.artifacts.dsl.RepositoryHandler -import org.gradle.kotlin.dsl.maven - -object Versions { - const val kotlin = "1.5.31" - const val ktor = "1.6.3" - const val coroutines = "1.5.2" - const val kotlinxSerialization = "1.3.0" - const val kotlinLogging = "2.0.11" - const val kord = "0.8.0-M5" - const val atomicFu = "0.16.3" - - const val junit5 = "5.8.0" - const val junitJupiterEngine = junit5 - const val coroutinesTest = coroutines - const val slf4j = "1.7.30" -} - -object Dependencies { - const val coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core:${Versions.coroutines}" - const val coroutinesJdk8 = "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:${Versions.coroutines}" - const val coroutinesTest = "org.jetbrains.kotlinx:kotlinx-coroutines-test:${Versions.coroutinesTest}" - const val kotlinxSerialization = "org.jetbrains.kotlinx:kotlinx-serialization-json:${Versions.kotlinxSerialization}" - - const val `ktor-io` = "io.ktor:ktor-io:${Versions.ktor}" - const val `ktor-utils` = "io.ktor:ktor-utils:${Versions.ktor}" - const val `ktor-client-websockets` = "io.ktor:ktor-client-websockets:${Versions.ktor}" - const val `ktor-client-core` = "io.ktor:ktor-client-core:${Versions.ktor}" - const val `ktor-client-serialization` = "io.ktor:ktor-client-serialization:${Versions.ktor}" - const val `ktor-client-logging` = "io.ktor:ktor-client-logging:${Versions.ktor}" - const val `ktor-client-cio` = "io.ktor:ktor-client-cio:${Versions.ktor}" - const val `ktor-client-js` = "io.ktor:ktor-client-js:${Versions.ktor}" - const val `ktor-client-mock` = "io.ktor:ktor-client-mock:${Versions.ktor}" - - const val kotlinLogging = "io.github.microutils:kotlin-logging:${Versions.kotlinLogging}" - - const val kord = "dev.kord:kord-core:${Versions.kord}" - - const val `junit-jupiter-engine` = "org.junit.jupiter:junit-jupiter-engine:${Versions.junitJupiterEngine}" - - const val slf4jSimple = "org.slf4j:slf4j-simple:${Versions.slf4j}" -} - -fun RepositoryHandler.jitpack() = maven("https://jitpack.io") -fun RepositoryHandler.kord() = maven("https://dl.bintray.com/kordlib/Kord") -fun RepositoryHandler.sonatype() = maven("https://oss.sonatype.org/content/repositories/snapshots/") diff --git a/buildSrc/src/main/kotlin/Projects.kt b/buildSrc/src/main/kotlin/Projects.kt index cc2f2950..dceca394 100644 --- a/buildSrc/src/main/kotlin/Projects.kt +++ b/buildSrc/src/main/kotlin/Projects.kt @@ -1,12 +1,7 @@ import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.NamedDomainObjectProvider -import org.gradle.api.artifacts.Dependency -import org.gradle.api.artifacts.ProjectDependency -import org.gradle.api.artifacts.dsl.DependencyHandler import org.gradle.kotlin.dsl.named -import org.gradle.kotlin.dsl.project import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet -import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler val NamedDomainObjectContainer.jvmMain: NamedDomainObjectProvider get() = named("jvmMain") @@ -19,9 +14,3 @@ val NamedDomainObjectContainer.jsMain: NamedDomainObjectProvide val NamedDomainObjectContainer.jsTest: NamedDomainObjectProvider get() = named("jsTest") - -val KotlinDependencyHandler.root: ProjectDependency - get() = project(":core") - -val DependencyHandler.root: Dependency - get() = project(":core") \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/Publishing.kt b/buildSrc/src/main/kotlin/Publishing.kt deleted file mode 100644 index 0a9a2523..00000000 --- a/buildSrc/src/main/kotlin/Publishing.kt +++ /dev/null @@ -1,9 +0,0 @@ -import org.gradle.api.Project -import org.gradle.api.publish.PublishingExtension -import org.gradle.kotlin.dsl.apply - -fun Project.applyPublishing(): Unit = apply(from = "../publishing.gradle.kts") - -val Project.publishing: PublishingExtension - get() = - (this as org.gradle.api.plugins.ExtensionAware).extensions.getByName("publishing") as PublishingExtension diff --git a/buildSrc/src/main/kotlin/lavalink-module.gradle.kts b/buildSrc/src/main/kotlin/lavalink-module.gradle.kts new file mode 100644 index 00000000..a31eee11 --- /dev/null +++ b/buildSrc/src/main/kotlin/lavalink-module.gradle.kts @@ -0,0 +1,46 @@ +plugins { + kotlin("multiplatform") + `maven-publish` +} + +group = rootProject.group +version = rootProject.version + +repositories { + mavenCentral() +} + +kotlin { + explicitApi() + + jvm { + compilations.all { + kotlinOptions { + jvmTarget = "1.8" + } + } + + tasks { + withType { + useJUnitPlatform() + } + } + } + + // See https://github.com/DRSchlaubi/Lavakord/issues/2 + js(IR) { + nodejs() + // browser() doesn't work because the js websocket client does not allowed you to set headers + // Apart from that why would you need Lavalink in your browser? + } + + sourceSets { + all { + languageSettings { + optIn("kotlin.RequiresOptIn") + optIn("kotlin.time.ExperimentalTime") + optIn("kotlinx.serialization.ExperimentalSerializationApi") + } + } + } +} diff --git a/publishing.gradle.kts b/buildSrc/src/main/kotlin/lavalink-publishing.gradle.kts similarity index 51% rename from publishing.gradle.kts rename to buildSrc/src/main/kotlin/lavalink-publishing.gradle.kts index 7a60ae1a..14698c47 100644 --- a/publishing.gradle.kts +++ b/buildSrc/src/main/kotlin/lavalink-publishing.gradle.kts @@ -1,13 +1,12 @@ -import java.util.* - -apply(plugin = "org.gradle.maven-publish") -apply(plugin = "org.gradle.signing") +plugins { + `maven-publish` + signing +} -val configurePublishing: PublishingExtension.() -> Unit = { +publishing { repositories { maven { setUrl("https://schlaubi.jfrog.io/artifactory/lavakord") - credentials { username = System.getenv("BINTRAY_USER") password = System.getenv("BINTRAY_KEY") @@ -16,16 +15,16 @@ val configurePublishing: PublishingExtension.() -> Unit = { } publications { - filterIsInstance().forEach { publication -> - publication.pom { + withType() { + pom { name.set(project.name) - description.set("Kotlin library which can, fetch, find, parse and analyze JVM exception stacktraces") - url.set("https://github.com/DRSchlaubi/furry-okto-rotary-phone") + description.set("Coroutine based client for Lavalink (Kotlin and Java)") + url.set("https://github.com/DRSchlaubi/Lavalink.kt") licenses { license { - name.set("Apache-2.0 License") - url.set("https://github.com/DRSchlaubi/furry-okto-rotary-phone/blob/main/LICENSE") + name.set("MIT License") + url.set("https://github.com/DRSchlaubi/Lavalink.kt/blob/main/LICENSE") } } @@ -38,21 +37,21 @@ val configurePublishing: PublishingExtension.() -> Unit = { } scm { - connection.set("scm:git:https://github.com/DRSchlaubi/furry-okto-rotary-phone.git") - developerConnection.set("scm:git:https://github.com/DRSchlaubi/furry-okto-rotary-phone.git") - url.set("https://github.com/DRSchlaubi/furry-okto-rotary-phone") + connection.set("scm:git:https://github.com/DRSchlaubi/Lavalink.kt.git") + developerConnection.set("scm:git:https://github.com/DRSchlaubi/Lavalink.kt.git") + url.set("https://github.com/DRSchlaubi/Lavalink.kt") } } } } } -val configureSigning: SigningExtension.() -> Unit = { +signing { val signingKey = findProperty("signingKey")?.toString() val signingPassword = findProperty("signingPassword")?.toString() if (signingKey != null && signingPassword != null) { useInMemoryPgpKeys( - String(Base64.getDecoder().decode(signingKey.toByteArray())), + String(java.util.Base64.getDecoder().decode(signingKey.toByteArray())), signingPassword ) } @@ -61,10 +60,3 @@ val configureSigning: SigningExtension.() -> Unit = { sign(this) } } - -extensions.configure("signing", configureSigning) -extensions.configure("publishing", configurePublishing) - -val Project.publishing: PublishingExtension - get() = - (this as ExtensionAware).extensions.getByName("publishing") as PublishingExtension diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 94d33c95..a079ef88 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,61 +1,27 @@ plugins { - kotlin("multiplatform") + `lavalink-module` + `lavalink-publishing` kotlin("plugin.serialization") - id("kotlinx-atomicfu") id("org.jetbrains.dokka") - `maven-publish` + id("kotlinx-atomicfu") } -version = "2.1.0" - kotlin { - explicitApi() - - jvm { - compilations.all { - kotlinOptions { - jvmTarget = Jvm.target - } - } - - tasks { - withType { - useJUnitPlatform() - } - } - } - - // See https://github.com/DRSchlaubi/Lavakord/issues/2 - js(IR) { - nodejs() - // browser() doesn't work because the js websocket client does not allowed you to set headers - // Apart from that why would you need Lavalink in your browser? - } - sourceSets { - all { - languageSettings.optIn(ExpermientalAnnotations.requiresOptIn) - languageSettings.optIn(ExpermientalAnnotations.experimentalTime) - languageSettings.optIn(ExpermientalAnnotations.experimentalSerialization) - repositories { - mavenCentral() - } - } - commonMain { dependencies { - api(Dependencies.coroutines) - api(Dependencies.kotlinxSerialization) - api("org.jetbrains.kotlinx:kotlinx-datetime:0.3.0") - - implementation(Dependencies.`ktor-io`) - implementation(Dependencies.`ktor-utils`) - implementation(Dependencies.`ktor-client-websockets`) - implementation(Dependencies.`ktor-client-core`) - implementation(Dependencies.`ktor-client-serialization`) - implementation(Dependencies.`ktor-client-logging`) - - implementation(Dependencies.kotlinLogging) + api(libs.kotlinx.coroutines.core) + api(libs.kotlinx.serialization.json) + api(libs.kotlinx.datetime) + + implementation(libs.ktor.io) + implementation(libs.ktor.utils) + implementation(libs.ktor.client.websockets) + implementation(libs.ktor.client.core) + implementation(libs.ktor.client.serialization) + implementation(libs.ktor.client.logging) + + implementation(libs.kotlinlogging) } } @@ -63,13 +29,13 @@ kotlin { dependencies { implementation(kotlin("test-common")) implementation(kotlin("test-annotations-common")) - implementation(Dependencies.`ktor-client-mock`) + implementation(libs.ktor.client.mock) } } jvmMain { dependencies { - implementation(Dependencies.`ktor-client-cio`) + implementation(libs.ktor.client.cio) } } @@ -77,15 +43,15 @@ kotlin { dependencies { implementation(kotlin("test")) implementation(kotlin("test-junit5")) - runtimeOnly(Dependencies.`junit-jupiter-engine`) - runtimeOnly(Dependencies.slf4jSimple) - implementation(Dependencies.coroutinesTest) + runtimeOnly(libs.junit.jupiter.engine) + runtimeOnly(libs.sl4fj.simple) + implementation(libs.kotlinx.coroutines.test) } } jsMain { dependencies { - implementation(Dependencies.`ktor-client-js`) + implementation(libs.ktor.client.js) } } @@ -97,5 +63,3 @@ kotlin { } } } - -applyPublishing() diff --git a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/LavaKord.kt b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/LavaKord.kt index fdb2ff55..36b67fa5 100644 --- a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/LavaKord.kt +++ b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/LavaKord.kt @@ -15,19 +15,19 @@ import kotlinx.coroutines.CoroutineScope */ public interface LavaKord : CoroutineScope { public val nodes: List - public val userId: Long + public val userId: ULong public val shardsTotal: Int public val options: LavaKordOptions /** * Returns the corresponding [Link] for the [guildId]. */ - public fun getLink(guildId: Long): Link + public fun getLink(guildId: ULong): Link /** * Returns the corresponding [Link] for the [guildId]. */ - public fun getLink(guildId: String): Link = getLink(guildId.toLong()) + public fun getLink(guildId: String): Link = getLink(guildId.toULong()) /** * Adds a new node to this cluster. diff --git a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/Events.kt b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/Events.kt index 33fcdc15..61751f9e 100644 --- a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/Events.kt +++ b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/Events.kt @@ -20,7 +20,7 @@ import kotlin.time.toDuration * @property track the [Track] the even is about */ public sealed class TrackEvent { - public abstract val guildId: Long + public abstract val guildId: ULong public abstract val track: Track } @@ -29,11 +29,11 @@ public sealed class TrackEvent { * * @see TrackEvent */ -public data class TrackStartEvent(override val guildId: Long, override val track: Track) : TrackEvent() { +public data class TrackStartEvent(override val guildId: ULong, override val track: Track) : TrackEvent() { internal companion object { suspend operator fun invoke(event: GatewayPayload.EmittedEvent): TrackStartEvent { require(event.type == GatewayPayload.EmittedEvent.Type.TRACK_START_EVENT && event.track != null) { "Event needs to be track start event" } - return TrackStartEvent(event.guildId.toLong(), Track.fromLavalink(event.track)) + return TrackStartEvent(event.guildId.toULong(), Track.fromLavalink(event.track)) } } } @@ -45,7 +45,7 @@ public data class TrackStartEvent(override val guildId: Long, override val track * @see TrackEvent */ public data class TrackEndEvent( - override val guildId: Long, + override val guildId: ULong, override val track: Track, public val reason: EndReason ) : TrackEvent() { @@ -97,7 +97,7 @@ public data class TrackEndEvent( suspend operator fun invoke(event: GatewayPayload.EmittedEvent): TrackEndEvent { require(event.type == GatewayPayload.EmittedEvent.Type.TRACK_END_EVENT && event.reason != null && event.track != null) { "Event needs to be track end event" } return TrackEndEvent( - event.guildId.toLong(), + event.guildId.toULong(), Track.fromLavalink(event.track), EndReason.valueOf(event.reason) ) @@ -112,7 +112,7 @@ public data class TrackEndEvent( * @see TrackEvent */ public data class TrackExceptionEvent( - override val guildId: Long, + override val guildId: ULong, override val track: Track, public val exception: RemoteTrackException ) : TrackEvent() { @@ -121,7 +121,7 @@ public data class TrackExceptionEvent( suspend operator fun invoke(event: GatewayPayload.EmittedEvent): TrackExceptionEvent { require(event.type == GatewayPayload.EmittedEvent.Type.TRACK_EXCEPTION_EVENT && event.error != null && event.track != null) { "Event has to be track exception event" } return TrackExceptionEvent( - event.guildId.toLong(), + event.guildId.toULong(), Track.fromLavalink(event.track), RemoteTrackException(event.error) ) @@ -130,21 +130,21 @@ public data class TrackExceptionEvent( } /** - * Event that is fired when a track was started, but no audio frames from it have arrived in a long time + * Event that is fired when a track was started, but no audio frames from it have arrived in a ULong time * * @property threshold The wait threshold that was exceeded for this event to trigger * @see TrackEvent */ @OptIn(ExperimentalTime::class) public data class TrackStuckEvent( - override val guildId: Long, override val track: Track, public val threshold: Duration + override val guildId: ULong, override val track: Track, public val threshold: Duration ) : TrackEvent() { internal companion object { suspend operator fun invoke(event: GatewayPayload.EmittedEvent): TrackStuckEvent { require(event.type == GatewayPayload.EmittedEvent.Type.TRACK_STUCK_EVENT && event.thresholdMs != null && event.track != null) { "Event has to be track stuck event" } return TrackStuckEvent( - event.guildId.toLong(), + event.guildId.toULong(), Track.fromLavalink(event.track), event.thresholdMs.toDuration(DurationUnit.MILLISECONDS) ) @@ -160,7 +160,7 @@ public data class TrackStuckEvent( * @property byRemote whether the connection was closed by the remote or not */ public data class WebsocketClosedEvent( - override val guildId: Long, + override val guildId: ULong, public val code: Int, public val reason: String, public val byRemote: Boolean @@ -172,7 +172,7 @@ public data class WebsocketClosedEvent( operator fun invoke(event: GatewayPayload.EmittedEvent): WebsocketClosedEvent { require(event.type == GatewayPayload.EmittedEvent.Type.WEBSOCKET_CLOSED_EVENT && event.code != null && event.reason != null && event.byRemote != null) { "Event has to be track stuck event" } return WebsocketClosedEvent( - event.guildId.toLong(), + event.guildId.toULong(), event.code, event.reason, event.byRemote diff --git a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/Link.kt b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/Link.kt index 22b1858e..dc40b8e1 100644 --- a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/Link.kt +++ b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/Link.kt @@ -19,22 +19,22 @@ public interface Link { public val player: Player public val lavakord: LavaKord public val state: State - public val guildId: Long - public val lastChannelId: Long? + public val guildId: ULong + public val lastChannelId: ULong? /** * Connects this link to the voice channel with the specified [voiceChannelId] * * Throws is only valid for kord implementation - * @throws me.schlaubi.lavakord.InsufficientPermissionException if the bot does not have the permission to join the voice channel or override user limit if needed + * @throws dev.schlaubi.lavakord.InsufficientPermissionException if the bot does not have the permission to join the voice channel or override user limit if needed * @throws NullPointerException If the [voiceChannelId] does not resolve to a valid voice channel */ - public suspend fun connectAudio(voiceChannelId: Long) + public suspend fun connectAudio(voiceChannelId: ULong) /** * Connects this link to the voice channel with the specified [voiceChannelId]. */ - public suspend fun Link.connect(voiceChannelId: String): Unit = connectAudio(voiceChannelId.toLong()) + public suspend fun Link.connect(voiceChannelId: String): Unit = connectAudio(voiceChannelId.toULong()) /** * Disconnects from the currently connected voice channel. diff --git a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/AbstractLavakord.kt b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/AbstractLavakord.kt index 327e8b2a..d58ece19 100644 --- a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/AbstractLavakord.kt +++ b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/AbstractLavakord.kt @@ -15,7 +15,6 @@ import io.ktor.client.features.json.serializer.* import io.ktor.client.features.logging.* import io.ktor.client.features.websocket.* import io.ktor.http.* -import io.ktor.util.* import kotlinx.atomicfu.atomic import kotlinx.coroutines.launch import kotlinx.serialization.modules.plus @@ -27,7 +26,7 @@ import kotlinx.serialization.modules.plus * @property linksMap [Map] all [Link]s are stored in */ public abstract class AbstractLavakord internal constructor( - override val userId: Long, + override val userId: ULong, override val shardsTotal: Int, httpClientEngine: HttpClientEngineFactory, override val options: LavaKordOptions @@ -40,14 +39,14 @@ public abstract class AbstractLavakord internal constructor( * @property linksMap [Map] all [Link]s are stored in */ public constructor( - userId: Long, + userId: ULong, shardsTotal: Int, options: LavaKordOptions ) : this(userId, shardsTotal, HttpEngine, options) private val nodeCounter = atomic(0) private val nodesMap = mutableMapOf() - protected val linksMap: MutableMap = mutableMapOf() + protected val linksMap: MutableMap = mutableMapOf() internal val json = kotlinx.serialization.json.Json { serializersModule = RoutePlannerModule + GatewayModule @@ -95,7 +94,7 @@ public abstract class AbstractLavakord internal constructor( internal fun removeDestroyedLink(link: Link) = linksMap.remove(link.guildId) - override fun getLink(guildId: Long): Link { + override fun getLink(guildId: ULong): Link { return linksMap.computeIfAbsent(guildId) { val node = loadBalancer.determineBestNode(guildId) as NodeImpl buildNewLink(guildId, node) @@ -142,5 +141,5 @@ public abstract class AbstractLavakord internal constructor( /** * Abstract function to create a new [Link] for this [guild][guildId] using this [node]. */ - protected abstract fun buildNewLink(guildId: Long, node: Node): Link + protected abstract fun buildNewLink(guildId: ULong, node: Node): Link } diff --git a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/AbstractLink.kt b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/AbstractLink.kt index d2f95d61..c9f13292 100644 --- a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/AbstractLink.kt +++ b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/AbstractLink.kt @@ -7,10 +7,10 @@ import dev.schlaubi.lavakord.audio.player.Player /** * Abstract implementation of [Link]. */ -public abstract class AbstractLink(final override val node: Node, final override val guildId: Long) : Link { +public abstract class AbstractLink(final override val node: Node, final override val guildId: ULong) : Link { override val player: Player = WebsocketPlayer(node as NodeImpl, guildId) abstract override val lavakord: AbstractLavakord - override var lastChannelId: Long? = null + override var lastChannelId: ULong? = null override var state: Link.State = Link.State.NOT_CONNECTED override suspend fun onDisconnected() { diff --git a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/LoadBalancer.kt b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/LoadBalancer.kt index 9caa6b02..12f24e05 100644 --- a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/LoadBalancer.kt +++ b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/LoadBalancer.kt @@ -9,7 +9,7 @@ internal class LoadBalancer( private val lavakord: LavaKord ) { - fun determineBestNode(guildId: Long): Node { + fun determineBestNode(guildId: ULong): Node { val leastPenalty = lavakord.nodes .asSequence() .filter(Node::available) @@ -24,7 +24,7 @@ internal class LoadBalancer( private fun calculatePenalties( node: Node, penaltyProviders: List, - guildId: Long + guildId: ULong ): Int { val playerPenalty: Int val cpuPenalty: Int @@ -71,5 +71,5 @@ public fun interface PenaltyProvider { * @see Node.lastStatsEvent * @return total penalty to add to this node. */ - public fun getPenalty(node: Node, guildId: Long): Int -} \ No newline at end of file + public fun getPenalty(node: Node, guildId: ULong): Int +} diff --git a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/WebsocketPlayer.kt b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/WebsocketPlayer.kt index 6ce563b2..ffba935a 100644 --- a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/WebsocketPlayer.kt +++ b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/internal/WebsocketPlayer.kt @@ -15,7 +15,7 @@ import kotlinx.datetime.Clock import kotlinx.datetime.Instant import kotlin.time.Duration -internal class WebsocketPlayer(internal val node: NodeImpl, internal val guildId: Long) : Player { +internal class WebsocketPlayer(internal val node: NodeImpl, internal val guildId: ULong) : Player { override var playingTrack: Track? = null override val coroutineScope: CoroutineScope get() = node.coroutineScope diff --git a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/player/Equalizer.kt b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/player/Equalizer.kt index f202c236..c68b9010 100644 --- a/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/player/Equalizer.kt +++ b/core/src/commonMain/kotlin/dev/schlaubi/lavakord/audio/player/Equalizer.kt @@ -20,7 +20,7 @@ public const val DEFAULT_GAIN: Float = 0F * } * ``` */ -public class EqualizerBuilder internal constructor(private val guildId: Long) { +public class EqualizerBuilder internal constructor(private val guildId: ULong) { internal val bands = mutableListOf() /** diff --git a/core/src/commonTest/kotlin/TestLavakord.kt b/core/src/commonTest/kotlin/TestLavakord.kt index 8b342de8..b72090a9 100644 --- a/core/src/commonTest/kotlin/TestLavakord.kt +++ b/core/src/commonTest/kotlin/TestLavakord.kt @@ -11,8 +11,8 @@ const val AUTH_HEADER = "RANDOM_AUTH" class RestTestLavakord( httpClientEngine: HttpClientEngineFactory, -) : AbstractLavakord(0L, 0, httpClientEngine, MutableLavaKordOptions().seal()), CoroutineScope by Tests { - override fun buildNewLink(guildId: Long, node: Node): Link { +) : AbstractLavakord(0UL, 0, httpClientEngine, MutableLavaKordOptions().seal()), CoroutineScope by Tests { + override fun buildNewLink(guildId: ULong, node: Node): Link { throw UnsupportedOperationException() } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index af7be50b..a0f7639f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/java/build.gradle.kts b/java/build.gradle.kts index 7501eb5c..1cc0c730 100644 --- a/java/build.gradle.kts +++ b/java/build.gradle.kts @@ -1,54 +1,31 @@ plugins { - kotlin("multiplatform") - `maven-publish` -} - -group = "dev.schlaubi.lavakord" -version = "2.1.0" - -repositories { - mavenCentral() - + `lavalink-module` + `lavalink-publishing` + id("org.jetbrains.dokka") } kotlin { - explicitApi() - - jvm { - compilations.all { - kotlinOptions.jvmTarget = "1.8" - } - } - sourceSets { - all { - languageSettings.optIn(ExpermientalAnnotations.requiresOptIn) - } - commonMain { dependencies { - api(root) - api(project(":jda")) + api(projects.core) + api(projects.jda) } } jvmMain { - kotlin.srcDir("main") repositories { mavenCentral() - maven("https://jitpack.io") maven("https://m2.dv8tion.net/releases") } dependencies { - api(root) - api(project(":jda")) + api(projects.core) + api(projects.jda) api("net.dv8tion:JDA:4.2.1_253") { exclude(module = "opus-java") } - implementation(Dependencies.coroutinesJdk8) + implementation(libs.kotlinx.coroutines.jdk8) } } } } - -applyPublishing() diff --git a/java/src/jvmMain/kotlin/dev/schlaubi/lavakord/interop/JavaLavakord.kt b/java/src/jvmMain/kotlin/dev/schlaubi/lavakord/interop/JavaLavakord.kt index 9b2fcda6..bc070548 100644 --- a/java/src/jvmMain/kotlin/dev/schlaubi/lavakord/interop/JavaLavakord.kt +++ b/java/src/jvmMain/kotlin/dev/schlaubi/lavakord/interop/JavaLavakord.kt @@ -20,7 +20,7 @@ public class JavaLavakord(private val parent: LavaKord) { * @see LavaKord.userId */ public val userId: Long - get() = parent.userId + get() = parent.userId.toLong() /** * @see LavaKord.shardsTotal @@ -40,7 +40,7 @@ public class JavaLavakord(private val parent: LavaKord) { * @see JavaLink */ public fun getLink(guildId: Long): JavaLink { - val link = parent.getLink(guildId) + val link = parent.getLink(guildId.toULong()) return JavaLink(link) } diff --git a/java/src/jvmMain/kotlin/dev/schlaubi/lavakord/interop/JavaLink.kt b/java/src/jvmMain/kotlin/dev/schlaubi/lavakord/interop/JavaLink.kt index edc27dbf..906e310c 100644 --- a/java/src/jvmMain/kotlin/dev/schlaubi/lavakord/interop/JavaLink.kt +++ b/java/src/jvmMain/kotlin/dev/schlaubi/lavakord/interop/JavaLink.kt @@ -31,9 +31,9 @@ public class JavaLink(internal val suspendingLink: Link) : CoroutineScope { public val state: State get() = suspendingLink.state public val guildId: Long - get() = suspendingLink.guildId + get() = suspendingLink.guildId.toLong() public val lastChannelId: Long? - get() = suspendingLink.lastChannelId + get() = suspendingLink.lastChannelId?.toLong() /** @@ -44,7 +44,7 @@ public class JavaLink(internal val suspendingLink: Link) : CoroutineScope { * @throws NullPointerException If the [voiceChannelId] does not resolve to a valid voice channel */ public fun connectAudio(voiceChannelId: Long): CompletableFuture = - run { suspendingLink.connectAudio(voiceChannelId) } + run { suspendingLink.connectAudio(voiceChannelId.toULong()) } /** * Disconnects from the currently connected voice channel. diff --git a/jda-java/build.gradle.kts b/jda-java/build.gradle.kts index fcc7d816..bffd319a 100644 --- a/jda-java/build.gradle.kts +++ b/jda-java/build.gradle.kts @@ -1,22 +1,10 @@ plugins { - kotlin("multiplatform") + `lavalink-module` + `lavalink-publishing` id("org.jetbrains.dokka") - `maven-publish` } -group = "dev.schlaubi.lavakord" -version = "2.1.0" - - kotlin { - explicitApi() - - jvm { - compilations.all { - kotlinOptions.jvmTarget = "1.8" - } - } - sourceSets { jvmMain { repositories { @@ -25,11 +13,9 @@ kotlin { } dependencies { - api(project(":jda")) - api(project(":java")) + api(projects.jda) + api(projects.java) } } } } - -applyPublishing() diff --git a/jda/build.gradle.kts b/jda/build.gradle.kts index 58db00da..4d507c58 100644 --- a/jda/build.gradle.kts +++ b/jda/build.gradle.kts @@ -1,35 +1,19 @@ plugins { - kotlin("multiplatform") - `maven-publish` + `lavalink-module` + `lavalink-publishing` id("org.jetbrains.dokka") } -group = "dev.schlaubi.lavakord" -version = "2.1.0" - repositories { mavenCentral() maven("https://m2.dv8tion.net/releases") } kotlin { - explicitApi() - - jvm { - compilations.all { - kotlinOptions.jvmTarget = "1.8" - } - } - sourceSets { jvmMain { - repositories { - maven("https://jitpack.io") - maven("https://m2.dv8tion.net/releases") - } - dependencies { - api(root) + api(projects.core) implementation("net.dv8tion:JDA:4.3.0_296") { exclude(module = "opus-java") } @@ -37,5 +21,3 @@ kotlin { } } } - -applyPublishing() 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 b9bd1ae3..4b79ec43 100644 --- a/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/Builder.kt +++ b/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/Builder.kt @@ -37,7 +37,7 @@ public fun JDABuilder.buildWithLavakord( val lavakord = JDALavakord( jdaProvider, coroutineContext, - jda.selfUser.idLong, + jda.selfUser.idLong.toULong(), jda.shardInfo.shardTotal, settings ) @@ -70,8 +70,8 @@ public fun DefaultShardManagerBuilder.buildWithLavakord( { shardId -> shardManager.getShardById(shardId) ?: error("Could not find shard with id: $shardId") } val lavakord = JDALavakord( jdaProvider, - executor ?: Dispatchers.IO + Job(), - shardManager.retrieveApplicationInfo().complete().idLong, + executor ?: (Dispatchers.IO + Job()), + shardManager.retrieveApplicationInfo().complete().idLong.toULong(), shardManager.shardsTotal, settings ) diff --git a/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/LavaKordImpl.kt b/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/LavaKordImpl.kt index 50d793ad..65d660b3 100644 --- a/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/LavaKordImpl.kt +++ b/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/LavaKordImpl.kt @@ -17,15 +17,15 @@ import kotlin.coroutines.CoroutineContext internal class JDALavakord( internal val jdaProvider: (Int) -> JDA, override val coroutineContext: CoroutineContext, - userId: Long, + userId: ULong, shardsTotal: Int, options: LavaKordOptions ) : AbstractLavakord(userId, shardsTotal, options), VoiceDispatchInterceptor, EventListener { - override fun buildNewLink(guildId: Long, node: Node): Link = JDALink(this, node, guildId) + override fun buildNewLink(guildId: ULong, node: Node): Link = JDALink(this, node, guildId) override fun onVoiceServerUpdate(update: VoiceDispatchInterceptor.VoiceServerUpdate) { - val link = getLink(update.guildIdLong) + val link = getLink(update.guildIdLong.toULong()) launch { forwardVoiceEvent( @@ -43,7 +43,7 @@ internal class JDALavakord( override fun onVoiceStateUpdate(update: VoiceDispatchInterceptor.VoiceStateUpdate): Boolean { val channel = update.channel - val link = getLink(update.guildIdLong) + val link = getLink(update.guildIdLong.toULong()) require(link is JDALink) // Null channel means disconnected @@ -52,7 +52,7 @@ internal class JDALavakord( link.state = Link.State.DESTROYED } } else { - link.lastChannelId = channel.idLong + link.lastChannelId = channel.idLong.toULong() link.state = Link.State.CONNECTED } @@ -66,8 +66,8 @@ internal class JDALavakord( if (options.link.autoReconnect) { linksMap.forEach { (_, link) -> val lastChannel = link.lastChannelId - if (lastChannel != null && event.jda.getVoiceChannelById(lastChannel) != null) { - link.connectAudio(lastChannel.toLong()) + if (lastChannel != null && event.jda.getVoiceChannelById(lastChannel.toLong()) != null) { + link.connectAudio(lastChannel) } } } diff --git a/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/LinkImpl.kt b/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/LinkImpl.kt index 96346dfc..883b2fe8 100644 --- a/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/LinkImpl.kt +++ b/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/LinkImpl.kt @@ -5,19 +5,19 @@ import dev.schlaubi.lavakord.audio.internal.AbstractLink import net.dv8tion.jda.api.JDA import net.dv8tion.jda.api.entities.Guild -internal class JDALink(override val lavakord: JDALavakord, node: Node, guildId: Long) : AbstractLink(node, guildId) { +internal class JDALink(override val lavakord: JDALavakord, node: Node, guildId: ULong) : AbstractLink(node, guildId) { private val shardId: Int get() = lavakord.getShardIdForGuild(guildId) private val jda: JDA get() = lavakord.jdaProvider(shardId) private val guild: Guild - get() = jda.getGuildById(guildId) ?: error("Could not find guild: $guildId") + get() = jda.getGuildById(guildId.toLong()) ?: error("Could not find guild: $guildId") - override suspend fun connectAudio(voiceChannelId: Long) { + override suspend fun connectAudio(voiceChannelId: ULong) { val guild = guild val channel = - guild.getVoiceChannelById(voiceChannelId) ?: error("Could not find voice channel: $voiceChannelId") + guild.getVoiceChannelById(voiceChannelId.toLong()) ?: error("Could not find voice channel: $voiceChannelId") jda.directAudioController.connect(channel) } diff --git a/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/Utils.kt b/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/Utils.kt index d59a0e7c..ee9be792 100644 --- a/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/Utils.kt +++ b/jda/src/jvmMain/kotlin/dev/schlaubi/lavakord/jda/Utils.kt @@ -5,5 +5,5 @@ import dev.schlaubi.lavakord.LavaKord /** * Calculates the shard id for the guild with [snowflake] as its id. */ -public fun LavaKord.getShardIdForGuild(snowflake: Long): Int = - ((snowflake shr 22) % shardsTotal).toInt() +public fun LavaKord.getShardIdForGuild(snowflake: ULong): Int = + ((snowflake shr 22) % shardsTotal.toUInt()).toInt() diff --git a/kord/build.gradle.kts b/kord/build.gradle.kts index ef9f9d86..dfcbbc14 100644 --- a/kord/build.gradle.kts +++ b/kord/build.gradle.kts @@ -1,40 +1,18 @@ plugins { - kotlin("multiplatform") + `lavalink-module` + `lavalink-publishing` id("org.jetbrains.dokka") - `maven-publish` -} - -version = "2.1.0" - -repositories { - mavenCentral() } kotlin { - explicitApi() - - jvm { - compilations.all { - kotlinOptions.jvmTarget = "1.8" - } - } - sourceSets { - all { - languageSettings.optIn(ExpermientalAnnotations.requiresOptIn) - } - commonMain { dependencies { - api(root) + api(projects.core) } } commonTest { - repositories { - mavenCentral() - } - dependencies { implementation(kotlin("test-common")) implementation(kotlin("test-annotations-common")) @@ -42,15 +20,9 @@ kotlin { } jvmMain { - repositories { - jitpack() - } - dependencies { - implementation(Dependencies.kord) + implementation(libs.kord.core) } } } } - -applyPublishing() diff --git a/kord/src/jvmMain/kotlin/dev/schlaubi/lavakord/kord/LavaKordImpl.kt b/kord/src/jvmMain/kotlin/dev/schlaubi/lavakord/kord/LavaKordImpl.kt index 8f50bcda..6d49dc05 100644 --- a/kord/src/jvmMain/kotlin/dev/schlaubi/lavakord/kord/LavaKordImpl.kt +++ b/kord/src/jvmMain/kotlin/dev/schlaubi/lavakord/kord/LavaKordImpl.kt @@ -18,7 +18,7 @@ import kotlin.coroutines.CoroutineContext internal class KordLavaKord( internal val kord: Kord, - userId: Long, + userId: ULong, shardsTotal: Int, options: LavaKordOptions ) : AbstractLavakord(userId, shardsTotal, options) { @@ -38,7 +38,7 @@ internal class KordLavaKord( val lastChannel = link.lastChannelId if (lastChannel != null && event.kord.getGuild(Snowflake(guildId)) != null) { try { - link.connectAudio(lastChannel.toLong()) + link.connectAudio(lastChannel) } catch (e: Exception) { e.printStackTrace() } @@ -50,7 +50,7 @@ internal class KordLavaKord( private suspend fun handleVoiceStateUpdate(event: VoiceStateUpdateEvent) { - if(event.kord.selfId != event.state.userId) return + if (event.kord.selfId != event.state.userId) return val channel = event.state.getChannelOrNull() val link = event.state.guildId.let { linksMap[it.value] } ?: return require(link is KordLink) @@ -66,7 +66,7 @@ internal class KordLavaKord( } } - override fun buildNewLink(guildId: Long, node: Node): Link = + override fun buildNewLink(guildId: ULong, node: Node): Link = KordLink(guildId, node, this) private suspend fun handleVoiceServerUpdate(event: VoiceServerUpdateEvent) { diff --git a/kord/src/jvmMain/kotlin/dev/schlaubi/lavakord/kord/LinkImpl.kt b/kord/src/jvmMain/kotlin/dev/schlaubi/lavakord/kord/LinkImpl.kt index d5d401da..9c321fa2 100644 --- a/kord/src/jvmMain/kotlin/dev/schlaubi/lavakord/kord/LinkImpl.kt +++ b/kord/src/jvmMain/kotlin/dev/schlaubi/lavakord/kord/LinkImpl.kt @@ -8,19 +8,17 @@ import dev.kord.gateway.UpdateVoiceStatus import dev.schlaubi.lavakord.audio.Link import dev.schlaubi.lavakord.audio.Node import dev.schlaubi.lavakord.audio.internal.AbstractLink -import dev.schlaubi.lavakord.audio.player.Player -import dev.schlaubi.lavakord.audio.player.applyFilters import kotlinx.coroutines.flow.count import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract internal class KordLink( - guildId: Long, + guildId: ULong, node: Node, override val lavakord: KordLavaKord ) : AbstractLink(node, guildId) { - override suspend fun connectAudio(voiceChannelId: Long) { + override suspend fun connectAudio(voiceChannelId: ULong) { lastChannelId = voiceChannelId val channel = lavakord.kord.getChannel(Snowflake(voiceChannelId)) as VoiceChannel? checkChannel(channel) diff --git a/settings.gradle.kts b/settings.gradle.kts index ebd2b4ac..64a7505f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,3 +1,5 @@ +@file:Suppress("UnstableApiUsage") + rootProject.name = "lavakord" //include("example") include("kord") // GitHub Actions gets mad about this and I can't reproduce this locally @@ -8,6 +10,9 @@ include("jda") include("jda-java") include("bom") +enableFeaturePreview("VERSION_CATALOGS") +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") + pluginManagement { resolutionStrategy { repositories { @@ -21,3 +26,38 @@ pluginManagement { } } } + +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + kotlinx() + ktor() + alias("kord-core").to("dev.kord", "kord-core").version("0.8.0-M6") + alias("junit-jupiter-engine").to("org.junit.jupiter", "junit-jupiter-engine").version("5.8.0") + alias("kotlinlogging").to("io.github.microutils", "kotlin-logging").version("2.0.11") + alias("sl4fj-simple").to("org.slf4j", "slf4j-simple").version("1.7.30") + } + } +} + +fun VersionCatalogBuilder.kotlinx() { + val coroutines = version("coroutines", "1.5.2") + alias("kotlinx-coroutines-core").to("org.jetbrains.kotlinx", "kotlinx-coroutines-core").versionRef(coroutines) + alias("kotlinx-coroutines-jdk8").to("org.jetbrains.kotlinx", "kotlinx-coroutines-jdk8").versionRef(coroutines) + alias("kotlinx-coroutines-test").to("org.jetbrains.kotlinx", "kotlinx-coroutines-test").versionRef(coroutines) + alias("kotlinx-serialization-json").to("org.jetbrains.kotlinx", "kotlinx-serialization-json").version("1.3.0") + alias("kotlinx-datetime").to("org.jetbrains.kotlinx", "kotlinx-datetime").version("0.3.0") +} + +fun VersionCatalogBuilder.ktor() { + val ktor = version("ktor", "1.6.3") + alias("ktor-io").to("io.ktor", "ktor-io").versionRef(ktor) + alias("ktor-utils").to("io.ktor", "ktor-utils").versionRef(ktor) + alias("ktor-client-websockets").to("io.ktor", "ktor-client-websockets").versionRef(ktor) + alias("ktor-client-core").to("io.ktor", "ktor-client-core").versionRef(ktor) + alias("ktor-client-serialization").to("io.ktor", "ktor-client-serialization").versionRef(ktor) + alias("ktor-client-logging").to("io.ktor", "ktor-client-logging").versionRef(ktor) + alias("ktor-client-cio").to("io.ktor", "ktor-client-cio").versionRef(ktor) + alias("ktor-client-js").to("io.ktor", "ktor-client-js").versionRef(ktor) + alias("ktor-client-mock").to("io.ktor", "ktor-client-mock").versionRef(ktor) +}