Skip to content

Commit

Permalink
Update dependencies
Browse files Browse the repository at this point in the history
* Gradle 8.10 -> 8.10.2
* Kotlin 2.0.20 -> 2.0.21
* Ktor 2.3.12 -> 3.0.0
* kotlinx.coroutines 1.8.1 -> 1.9.0
* kotlinx.serialization 1.7.2 -> 1.7.3
* kotlin-node 20.14.10-pre.800 -> 22.5.4-pre.818
* KSP 2.0.20-1.0.24 -> 2.0.21-1.0.25
* JUnit Jupiter 5.11.0 -> 5.11.2
* JUnit Platform 1.11.0 -> 1.11.2
* MockK 1.13.12 -> 1.13.13
* gradle-buildconfig-plugin 5.4.0 -> 5.5.0

io.ktor:ktor-client-websockets is an empty artifact, support for
WebSockets is included in io.ktor:ktor-client-core, so the dependency
was removed from kord-gateway.
  • Loading branch information
lukellmann committed Oct 12, 2024
1 parent 3ef564c commit 249630a
Show file tree
Hide file tree
Showing 11 changed files with 62 additions and 55 deletions.
1 change: 0 additions & 1 deletion common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ kotlin {
}
nonJvmMain {
dependencies {
implementation(libs.ktor.utils)
implementation(libs.bignum)
implementation(libs.stately.collections)
}
Expand Down
23 changes: 17 additions & 6 deletions common/src/nonJvmMain/kotlin/DiscordBitSet.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,25 @@ package dev.kord.common

import com.ionspin.kotlin.bignum.integer.BigInteger
import com.ionspin.kotlin.bignum.integer.Sign
import io.ktor.utils.io.core.*

internal actual fun formatIntegerFromLittleEndianLongArray(data: LongArray) =
withBuffer(data.size * Long.SIZE_BYTES) {
// need to convert from little-endian data to big-endian expected by BigInteger
writeFully(data.reversedArray())
BigInteger.fromByteArray(readBytes(), Sign.POSITIVE).toString()
internal actual fun formatIntegerFromLittleEndianLongArray(data: LongArray): String {
// need to convert from little-endian data to big-endian expected by BigInteger
val bytes = ByteArray(size = data.size * Long.SIZE_BYTES)
val lastIndex = data.lastIndex
for (i in 0..lastIndex) {
val offset = (lastIndex - i) * Long.SIZE_BYTES
val long = data[i]
bytes[offset] = (long ushr 56).toByte()
bytes[offset + 1] = (long ushr 48).toByte()
bytes[offset + 2] = (long ushr 40).toByte()
bytes[offset + 3] = (long ushr 32).toByte()
bytes[offset + 4] = (long ushr 24).toByte()
bytes[offset + 5] = (long ushr 16).toByte()
bytes[offset + 6] = (long ushr 8).toByte()
bytes[offset + 7] = long.toByte()
}
return BigInteger.fromByteArray(bytes, Sign.POSITIVE).toString()
}

internal actual fun parseNonNegativeIntegerToBigEndianByteArray(value: String): ByteArray = BigInteger
.parseString(value)
Expand Down
1 change: 0 additions & 1 deletion gateway/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ kotlin {
api(projects.common)

api(libs.bundles.ktor.client.serialization)
api(libs.ktor.client.websockets)

implementation(libs.kotlin.logging)

Expand Down
23 changes: 11 additions & 12 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
[versions]

# api dependencies
kotlin = "2.0.20" # https://github.com/JetBrains/kotlin
ktor = "2.3.12" # https://github.com/ktorio/ktor
kotlinx-coroutines = "1.8.1" # https://github.com/Kotlin/kotlinx.coroutines
kotlinx-serialization = "1.7.2" # https://github.com/Kotlin/kotlinx.serialization
kotlin = "2.0.21" # https://github.com/JetBrains/kotlin
ktor = "3.0.0" # https://github.com/ktorio/ktor
kotlinx-coroutines = "1.9.0" # https://github.com/Kotlin/kotlinx.coroutines
kotlinx-serialization = "1.7.3" # https://github.com/Kotlin/kotlinx.serialization
kotlinx-datetime = "0.6.1" # https://github.com/Kotlin/kotlinx-datetime
kord-cache = "0.5.4" # https://github.com/kordlib/cache

# implementation dependencies
kotlin-logging = "7.0.0" # https://github.com/oshai/kotlin-logging
kotlin-logging-old = "3.0.5" # TODO remove after dependency is removed in rest, gateway, voice and core
slf4j = "2.0.16" # https://www.slf4j.org
kotlin-node = "20.14.10-pre.800" # https://github.com/JetBrains/kotlin-wrappers
kotlin-node = "22.5.4-pre.818" # https://github.com/JetBrains/kotlin-wrappers
bignum = "0.3.10" # https://github.com/ionspin/kotlin-multiplatform-bignum
stately = "2.1.0" # https://github.com/touchlab/Stately
fastZlib = "2.0.1" # https://github.com/timotejroiko/fast-zlib

# code generation
ksp = "2.0.20-1.0.24" # https://github.com/google/ksp
ksp = "2.0.21-1.0.25" # https://github.com/google/ksp
kotlinpoet = "1.18.1" # https://github.com/square/kotlinpoet

# tests
junit-jupiter = "5.11.0" # https://github.com/junit-team/junit5
junit-platform = "1.11.0"
mockk = "1.13.12" # https://github.com/mockk/mockk
junit-jupiter = "5.11.2" # https://github.com/junit-team/junit5
junit-platform = "1.11.2"
mockk = "1.13.13" # https://github.com/mockk/mockk
kbson = "0.4.0" # https://github.com/mongodb/kbson

# plugins
dokka = "2.0.0-Beta" # https://github.com/Kotlin/dokka
kotlinx-atomicfu = "0.25.0" # https://github.com/Kotlin/kotlinx-atomicfu
binary-compatibility-validator = "0.16.3" # https://github.com/Kotlin/binary-compatibility-validator
buildconfig = "5.4.0" # https://github.com/gmazzo/gradle-buildconfig-plugin
buildconfig = "5.5.0" # https://github.com/gmazzo/gradle-buildconfig-plugin


[libraries]
Expand All @@ -46,10 +46,9 @@ ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-js = { module = "io.ktor:ktor-client-js", version.ref = "ktor" }
ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" }
ktor-client-websockets = { module = "io.ktor:ktor-client-websockets", version.ref = "ktor" }
ktor-client-mock = { module = "io.ktor:ktor-client-mock", version.ref = "ktor" }
ktor-network = { module = "io.ktor:ktor-network", version.ref = "ktor" }
ktor-utils = { module = "io.ktor:ktor-utils", version.ref = "ktor" }
ktor-io = { module = "io.ktor:ktor-io", version.ref = "ktor" }

# kotlinx
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
Expand Down
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=5b9c5eb3f9fc2c94abaea57d90bd78747ca117ddbbf96c859d3741181a12bf2a
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip
distributionSha256Sum=31c55713e40233a8303827ceb42ca48a47267a0ad4bab9177123121e71524c26
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
1 change: 0 additions & 1 deletion rest/src/commonMain/kotlin/request/KtorRequestHandler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import io.ktor.client.*
import io.ktor.client.request.*
import io.ktor.client.request.forms.*
import io.ktor.client.statement.*
import io.ktor.content.TextContent
import io.ktor.http.*
import io.ktor.http.content.*
import kotlinx.datetime.Clock
Expand Down
6 changes: 2 additions & 4 deletions rest/src/commonTest/kotlin/request/MessageRequests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import dev.kord.common.entity.Snowflake
import dev.kord.common.entity.optional.Optional
import dev.kord.rest.json.readFile
import dev.kord.rest.service.ChannelService
import dev.kord.test.Platform
import io.ktor.client.*
import io.ktor.client.engine.mock.*
import io.ktor.client.request.forms.*
import io.ktor.utils.io.*
import kotlinx.coroutines.test.runTest
import kotlinx.datetime.Clock
import kotlinx.serialization.encodeToString
Expand Down Expand Up @@ -62,10 +62,9 @@ class MessageRequests {

val channelService = ChannelService(KtorRequestHandler(client = HttpClient(mockEngine), token = ""))

val fileChannel = readFile("images/kord.png")
val fileChannel = readFile("images/kord.png").counted()

with(fileChannel) {
if (Platform.IS_JVM) assertFalse(isClosedForWrite) // only read lazily on jvm
assertFalse(isClosedForRead)
assertEquals(0L, totalBytesRead)

Expand All @@ -74,7 +73,6 @@ class MessageRequests {
}
assertEquals(mockMessage, createdMessage)

assertTrue(isClosedForWrite)
assertTrue(isClosedForRead)
assertTrue(totalBytesRead > 0L)
}
Expand Down
2 changes: 1 addition & 1 deletion test-kit/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ kotlin {
commonMain {
dependencies {
api(libs.bundles.test.common)
api(libs.ktor.utils)
api(libs.ktor.io)
}
}
jsMain {
Expand Down
2 changes: 1 addition & 1 deletion voice/api/voice.api
Original file line number Diff line number Diff line change
Expand Up @@ -1232,7 +1232,7 @@ public final class dev/kord/voice/udp/RTPPacket$Builder {
}

public final class dev/kord/voice/udp/RTPPacket$Companion {
public final fun fromPacket (Lio/ktor/utils/io/core/ByteReadPacket;)Ldev/kord/voice/udp/RTPPacket;
public final fun fromPacket (Lkotlinx/io/Source;)Ldev/kord/voice/udp/RTPPacket;
}

public final class dev/kord/voice/udp/RTPPacketKt {
Expand Down
35 changes: 17 additions & 18 deletions voice/src/main/kotlin/udp/GlobalVoiceUdpSocket.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import io.github.oshai.kotlinlogging.KotlinLogging
import io.ktor.network.selector.*
import io.ktor.network.sockets.*
import io.ktor.utils.io.core.*
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.*
import kotlin.text.String
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.emitAll
import kotlinx.io.Sink
import kotlinx.io.readString
import kotlinx.io.readUShort

private val globalVoiceSocketLogger = KotlinLogging.logger { }

Expand All @@ -32,47 +33,45 @@ public object GlobalVoiceUdpSocket : VoiceUdpSocket {
private val _incoming: MutableSharedFlow<Datagram> = MutableSharedFlow()
override val incoming: SharedFlow<Datagram> = _incoming

private val socket = aSocket(ActorSelectorManager(socketScope.coroutineContext)).udp().bind()
private val socket = socketScope.async {
aSocket(ActorSelectorManager(socketScope.coroutineContext)).udp().bind()
}

private val EMPTY_DATA = ByteArray(DISCOVERY_DATA_SIZE)

init {
socket.incoming
.consumeAsFlow()
.onEach { _incoming.emit(it) }
.launchIn(socketScope)
socketScope.launch { _incoming.emitAll(socket.await().incoming) }
}

@OptIn(ExperimentalUnsignedTypes::class)
override suspend fun discoverIp(address: InetSocketAddress, ssrc: Int): InetSocketAddress {
globalVoiceSocketLogger.trace { "discovering ip" }

send(packet(address) {
writeShort(REQUEST)
writeShort(MESSAGE_LENGTH)
writeInt(ssrc)
writeFully(EMPTY_DATA)
write(EMPTY_DATA)
})

return with(receiveFrom(address).packet) {
require(readShort() == RESPONSE) { "did not receive a response." }
require(readShort() == MESSAGE_LENGTH) { "expected $MESSAGE_LENGTH bytes of data."}
discardExact(4) // ssrc
require(readShort() == MESSAGE_LENGTH) { "expected $MESSAGE_LENGTH bytes of data." }
skip(byteCount = 4) // ssrc

val ip = String(readBytes(64)).trimEnd(0.toChar())
val ip = readString(byteCount = 64).trimEnd(0.toChar())
val port = readUShort().toInt()

InetSocketAddress(ip, port)
}
}

override suspend fun send(packet: Datagram) {
socket.send(packet)
socket.await().send(packet)
}

override suspend fun stop() { /* this doesn't stop until the end of the process */ }

private fun packet(address: SocketAddress, builder: BytePacketBuilder.() -> Unit): Datagram {
private fun packet(address: SocketAddress, builder: Sink.() -> Unit): Datagram {
return Datagram(buildPacket(block = builder), address)
}
}
19 changes: 11 additions & 8 deletions voice/src/main/kotlin/udp/RTPPacket.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import dev.kord.voice.io.ByteArrayView
import dev.kord.voice.io.MutableByteArrayCursor
import dev.kord.voice.io.mutableCursor
import dev.kord.voice.io.view
import io.ktor.utils.io.core.*
import kotlinx.io.Source
import kotlinx.io.readByteArray
import kotlinx.io.readUInt
import kotlinx.io.readUShort
import kotlin.experimental.and

internal const val RTP_HEADER_LENGTH = 12
Expand Down Expand Up @@ -38,8 +41,8 @@ public data class RTPPacket(
public companion object {
internal const val VERSION = 2

public fun fromPacket(packet: ByteReadPacket): RTPPacket? = with(packet) base@{
if (remaining <= 13) return@base null
public fun fromPacket(packet: Source): RTPPacket? = with(packet) base@{
if (!request(byteCount = 14)) return@base null

/*
* first byte | bit table
Expand Down Expand Up @@ -72,15 +75,15 @@ public data class RTPPacket(
payloadType = this and 0x7F
}

val sequence = readShort().toUShort()
val timestamp = readInt().toUInt()
val ssrc = readInt().toUInt()
val sequence = readUShort()
val timestamp = readUInt()
val ssrc = readUInt()

// each csrc takes up 4 bytes, plus more data is required
if (remaining <= csrcCount * 4 + 1) return@base null
if (!request(byteCount = csrcCount * 4L + 2)) return@base null
val csrcIdentifiers = UIntArray(csrcCount.toInt()) { readUInt() }

val payload = readBytes().view()
val payload = readByteArray().view()

val paddingBytes = if (hasPadding) { payload[payload.viewSize - 1] } else 0

Expand Down

0 comments on commit 249630a

Please sign in to comment.