Skip to content

Commit

Permalink
Updates & fixes
Browse files Browse the repository at this point in the history
- Fix issue of sound being cut off when joining channel
  • Loading branch information
DRSchlaubi committed Dec 25, 2023
1 parent 822c2f9 commit a5f5bd9
Show file tree
Hide file tree
Showing 14 changed files with 67 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions app/web/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ kotlin {
@OptIn(ExperimentalComposeLibrary::class)
implementation(compose.components.resources)
implementation(compose.materialIconsExtended)
implementation(libs.ktor.sse)
}
}
}
Expand Down
2 changes: 0 additions & 2 deletions bot/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import dev.schlaubi.mikbot.gradle.mikbot
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
import kotlin.io.path.div

plugins {
alias(libs.plugins.ksp)
Expand All @@ -12,7 +11,6 @@ plugins {
dependencies {
implementation(projects.common)
ktorDependency(libs.ktor.server.auth)
ktorDependency(libs.ktor.server.websockets)
ktorDependency(libs.ktor.server.cors)
ktorDependency(libs.ktor.server.auth.jwt)
implementation(libs.kmongo.id.serialization)
Expand Down
6 changes: 6 additions & 0 deletions bot/src/main/kotlin/dev/schlaubi/tonbrett/bot/Plugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@ import dev.schlaubi.mikbot.plugin.api.PluginMain
import dev.schlaubi.mikbot.plugin.api.module.SubCommandModule
import dev.schlaubi.tonbrett.bot.commands.*
import dev.schlaubi.tonbrett.bot.core.VoiceStateWatcher
import dev.schlaubi.tonbrett.common.TonbrettSerializersModule
import org.litote.kmongo.serialization.registerModule

@PluginMain
class Plugin(context: PluginContext) : Plugin(context) {
override fun start() {
registerModule(TonbrettSerializersModule)
}

override fun ExtensibleBotBuilder.ExtensionsBuilder.addExtensions() {
add(::Module)
add(::VoiceStateWatcher)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package dev.schlaubi.tonbrett.bot.commands

import dev.kord.rest.builder.message.create.actionRow
import dev.kord.rest.builder.message.actionRow
import dev.schlaubi.mikbot.plugin.api.module.SubCommandModule
import dev.schlaubi.mikbot.util_plugins.ktor.api.buildBotUrl
import io.ktor.http.*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import dev.schlaubi.tonbrett.bot.util.player
import dev.schlaubi.tonbrett.common.InterfaceAvailabilityChangeEvent
import dev.schlaubi.tonbrett.common.Snowflake
import dev.schlaubi.tonbrett.common.Sound
import io.ktor.http.path
import io.ktor.http.*
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterIsInstance
Expand Down Expand Up @@ -63,7 +63,7 @@ class SoundPlayer(guild: GuildBehavior) : CoroutineScope {
}

@Suppress("INVISIBLE_MEMBER", "SuspendFunctionOnCoroutineScope")
suspend fun playSound(sound: Sound, user: Snowflake) {
suspend fun playSound(sound: Sound, user: Snowflake, channelId: Snowflake?) {
val alreadyLocked = locked
locked = true
updateAvailability(false, sound, user)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fun Route.files() {
val path = Config.SOUNDS_FOLDER / sound.fileName

val contentType = contentTypeRaw?.let { ContentType.parse(contentTypeRaw) }
?: ContentType.defaultForFile(path)
?: ContentType.defaultForPath(path)

val content = LocalFileContent(
path.toFile(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,30 @@ import com.kotlindiscord.kord.extensions.koin.KordExContext
import dev.kord.common.annotation.KordExperimental
import dev.kord.common.annotation.KordUnsafe
import dev.kord.core.Kord
import dev.kord.core.event.guild.VoiceServerUpdateEvent
import dev.schlaubi.lavakord.kord.connectAudio
import dev.schlaubi.tonbrett.bot.core.soundPlayer
import dev.schlaubi.tonbrett.bot.core.voiceState
import dev.schlaubi.tonbrett.bot.io.*
import dev.schlaubi.tonbrett.bot.io.SoundBoardDatabase
import dev.schlaubi.tonbrett.bot.io.findAllTags
import dev.schlaubi.tonbrett.bot.io.findById
import dev.schlaubi.tonbrett.bot.io.searchGrouped
import dev.schlaubi.tonbrett.bot.util.badRequest
import dev.schlaubi.tonbrett.bot.util.soundNotFound
import dev.schlaubi.tonbrett.bot.util.translate
import dev.schlaubi.tonbrett.common.Route.*
import dev.schlaubi.tonbrett.common.Route.Tags
import dev.schlaubi.tonbrett.common.util.convertForNonJvmPlatforms
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.resources.*
import io.ktor.server.response.*
import io.ktor.server.routing.Route
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.withTimeout
import kotlin.time.Duration.Companion.seconds

@OptIn(KordUnsafe::class, KordExperimental::class)
fun Route.sounds() {
Expand Down Expand Up @@ -56,10 +64,19 @@ fun Route.sounds() {
@Suppress("INVISIBLE_MEMBER", "EQUALITY_NOT_APPLICABLE")
if (player.channelId == null) {
player.player.link.connectAudio(voiceState.channelId)
} else if (player.channelId != voiceState.channelId) {
withTimeout(5.seconds) {
kord.events
.filterIsInstance<VoiceServerUpdateEvent>()
.filter {
it.guildId == player.player.guildId
}
// wait for "Connect event"
.first()
}
} else if (player.channelId != null && player.channelId != voiceState.channelId) {
badRequest(call.translate("rest.errors.vc_mismatch"))
}
player.playSound(sound, user)
player.playSound(sound, user, voiceState.channelId?.takeIf { player.channelId == null })
call.respond(HttpStatusCode.Accepted)
}
}
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ plugins {

allprojects {
group = "dev.schlaubi.tonbrett"
version = "1.18.2"
version = "1.18.3"

repositories {
mavenCentral()
Expand Down
8 changes: 4 additions & 4 deletions client/src/commonMain/kotlin/WebSocketRetry.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ private val LOG = KotlinLogging.logger { }
*
* @see retryingWebSocket
*/
val WebSocketRetry = createClientPlugin("WebSocketRetry", { HttpRequestRetry.Configuration() }) {}
val WebSocketRetry = createClientPlugin("WebSocketRetry", { HttpRequestRetryConfig() }) {}

/**
* Exception used for logging WebSocket connection errors.
Expand All @@ -45,12 +45,12 @@ suspend fun HttpClient.retryingWebSocket(

private class WebSocketRetryContext(
val client: HttpClient,
val config: HttpRequestRetry.Configuration,
val config: HttpRequestRetryConfig,
val httpRequestBuilder: HttpRequestBuilder.() -> Unit,
val handler: suspend DefaultClientWebSocketSession.() -> Unit
) {
lateinit var session: DefaultClientWebSocketSession
private var delayContext: HttpRequestRetry.DelayContext? = null
private var delayContext: HttpRetryDelayContext? = null
private var tries = 1

fun reset() {
Expand All @@ -63,7 +63,7 @@ private class WebSocketRetryContext(

suspend fun reconnect(e: Throwable, isRetry: Boolean = true) {
if (!isRetry) {
delayContext = HttpRequestRetry.DelayContext(
delayContext = HttpRetryDelayContext(
HttpRequestBuilder(),
session.call.response,
e
Expand Down
1 change: 1 addition & 0 deletions common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ kotlin {
dependencies {
compileOnly(libs.kmongo.id.serialization)
compileOnly(libs.kord.common)
compileOnly(libs.kmongo.serialization)
}
}
}
Expand Down
25 changes: 21 additions & 4 deletions common/src/jvmMain/kotlin/dev/schlaubi/tonbrett/common/Id.kt
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
package dev.schlaubi.tonbrett.common

import com.github.jershell.kbson.BsonEncoder
import com.github.jershell.kbson.BsonFlexibleDecoder
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import org.bson.types.ObjectId
import org.litote.kmongo.id.toId
import org.litote.kmongo.toId


// d8 can't understand k2 meta yet, so we can't use type-aliases
@Serializable(with = IdSerializer::class)
@Suppress("ACTUAL_CLASSIFIER_MUST_HAVE_THE_SAME_SUPERTYPES_AS_NON_FINAL_EXPECT_CLASSIFIER_WARNING")
public actual interface Id<T> : org.litote.kmongo.Id<T>

@Serializable(with = IdSerializer::class)
@JvmInline
private value class WrappedId<T>(private val id: org.litote.kmongo.Id<T>) : Id<T>,
@Suppress("SERIALIZER_TYPE_INCOMPATIBLE") // because of the serializers semantics, this is irrelevant
internal value class WrappedId<T>(private val id: org.litote.kmongo.Id<T>) : Id<T>,
org.litote.kmongo.Id<T> by id {
override fun toString(): String = id.toString()
}
Expand All @@ -26,9 +33,19 @@ public object IdSerializer : KSerializer<Id<*>> {
override val descriptor: SerialDescriptor =
PrimitiveSerialDescriptor("MongoID", PrimitiveKind.STRING)

override fun deserialize(decoder: Decoder): Id<*> =
WrappedId(decoder.decodeString().toId<Any>())
override fun deserialize(decoder: Decoder): Id<*> {
return if (decoder is BsonFlexibleDecoder) {
WrappedId<Any>(decoder.reader.readObjectId().toId())
} else {
WrappedId<Any>(decoder.decodeString().toId())
}
}

override fun serialize(encoder: Encoder, value: Id<*>): Unit =
encoder.encodeString(value.toString())
if (encoder is BsonEncoder) {
val objectId = ObjectId(value.toString())
encoder.encodeObjectId(objectId)
} else {
encoder.encodeString(value.toString())
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package dev.schlaubi.tonbrett.common

import kotlinx.serialization.KSerializer
import kotlinx.serialization.modules.SerializersModule
import org.litote.kmongo.id.StringId

public actual val TonbrettSerializersModule: SerializersModule = SerializersModule {
contextual(Id::class, IdSerializer)
@Suppress("UNCHECKED_CAST") // because of the serializers semantics, we know that this will work
contextual(WrappedId::class, IdSerializer as KSerializer<WrappedId<*>>)
}
6 changes: 4 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[versions]
kotlin = "2.0.0-Beta1"
ktor = "2.3.7"
ktor = "3.0.0-beta-1"
kmongo = "4.10.0"
kord = "0.12.0"
mikbot = "3.26.0"
mikbot = "3.27.0"
ksp = "2.0.0-Beta1-1.0.14"
kordex = "1.6.0-SNAPSHOT"
android = "8.2.0"
Expand All @@ -21,6 +21,7 @@ coil = "3.0.0-20231208.205440-1"
[libraries]
kotlinx-serialization = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version = "1.6.1" }
kmongo-id-serialization = { group = "org.litote.kmongo", name = "kmongo-id-serialization", version.ref = "kmongo" }
kmongo-serialization = { group = "org.litote.kmongo", name = "kmongo-serialization", version.ref = "kmongo" }
kord-common = { group = "dev.kord", name = "kord-common", version.ref = "kord" }
kordex-processor = { group = "com.kotlindiscord.kord.extensions", name = "annotation-processor", version.ref = "kordex" }

Expand All @@ -45,6 +46,7 @@ ktor-client-winhttp = { group = "io.ktor", name = "ktor-client-winhttp", version
ktor-client-okhttp = { group = "io.ktor", name = "ktor-client-okhttp", version.ref = "ktor" }
ktor-client-content-negotiation = { group = "io.ktor", name = "ktor-client-content-negotiation", version.ref = "ktor" }
ktor-client-auth = { group = "io.ktor", name = "ktor-client-auth", version.ref = "ktor" }
ktor-sse = { group = "io.ktor", name = "ktor-sse", version.ref = "ktor" }
ktor-serialization-kotlinx-json = { group = "io.ktor", name = "ktor-serialization-kotlinx-json", version.ref = "ktor" }

mikbot-ktor = { group = "dev.schlaubi", name = "mikbot-ktor", version.ref = "mikbot" }
Expand Down

0 comments on commit a5f5bd9

Please sign in to comment.