Skip to content

Commit

Permalink
Bugfixes
Browse files Browse the repository at this point in the history
- Add reconnecting
- add debug logging for stats updates
- Fix ci naming
  • Loading branch information
DRSchlaubi committed Feb 19, 2025
1 parent 06588c4 commit 97e86ec
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 28 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/client.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
java-version: "23"
- uses: gradle/actions/setup-gradle@v4
- run: ./gradlew client:packageReleaseDistributionForCurrentOS
- run: mv client-*.msi client.msi
- run: mv GTA.Killer-*.msi client.msi
working-directory: client/build/compose/binaries/main-release/msi/
- name: Release
uses: softprops/action-gh-release@v2
Expand Down
6 changes: 4 additions & 2 deletions client/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ plugins {
alias(libs.plugins.compose)
}

version = "1.0.0"
version = "1.1.0"

repositories {
mavenCentral()
Expand All @@ -20,14 +20,16 @@ dependencies {
implementation(libs.kotlinx.serialization.json)
implementation(libs.jnativehook)
implementation(libs.ktor.serialization.kotlinx.json)
implementation(libs.ktor.client.okhttp)
implementation(libs.ktor.client.cio)
implementation(libs.ktor.client.websockets)
implementation(libs.ktor.client.resources)
implementation(libs.ktor.client.content.negotiation)
implementation(libs.ktor.serialization.kotlinx.json)
implementation(libs.kotlin.logging)
implementation(libs.logback.classic)

implementation(libs.kord.gateway)

implementation(compose.desktop.currentOs)
implementation(compose.foundation)
implementation(compose.runtime)
Expand Down
54 changes: 32 additions & 22 deletions client/src/main/kotlin/core/APIClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@ package dev.schlaubi.mastermind.core
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import dev.schlaubi.gtakiller.common.Event
import dev.schlaubi.gtakiller.common.KillGtaEvent
import dev.schlaubi.gtakiller.common.Route
import dev.schlaubi.gtakiller.common.Status
import dev.schlaubi.gtakiller.common.Username
import dev.kord.gateway.retry.LinearRetry
import dev.schlaubi.gtakiller.common.*
import dev.schlaubi.mastermind.core.settings.settings
import io.github.oshai.kotlinlogging.KotlinLogging
import io.ktor.client.*
Expand All @@ -17,6 +14,7 @@ import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.client.plugins.resources.*
import io.ktor.client.plugins.websocket.*
import io.ktor.http.*
import io.ktor.serialization.*
import io.ktor.serialization.kotlinx.*
import io.ktor.serialization.kotlinx.json.*
import io.ktor.websocket.*
Expand All @@ -25,6 +23,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.serialization.json.Json
import kotlin.coroutines.CoroutineContext
import kotlin.time.Duration.Companion.seconds

var currentApi by mutableStateOf<APIClient?>(null)

Expand All @@ -40,6 +39,7 @@ class APIClient(val url: Url) : CoroutineScope {
json()
}
install(WebSockets) {
pingInterval = 2.seconds
contentConverter = KotlinxWebsocketSerializationConverter(Json)
}
install(Resources)
Expand All @@ -52,38 +52,48 @@ class APIClient(val url: Url) : CoroutineScope {
private var webSocketSession: DefaultClientWebSocketSession? = null
private val _events = MutableSharedFlow<Event>()
val events = _events.asSharedFlow()
private val retry = LinearRetry(2.seconds, 20.seconds, 10)

suspend fun connectToWebSocket() {
suspend fun connectToWebSocket(isRetry: Boolean = false) {
webSocketSession?.close()
val session = client.webSocketSession {
url {
url.takeFrom(this@APIClient.url)
protocol = if (url.protocol.isSecure()) {
URLProtocol.WSS
} else {
URLProtocol.WS
val session = try {
client.webSocketSession {
url {
url.takeFrom(this@APIClient.url)
protocol = if (url.protocol.isSecure()) {
URLProtocol.WSS
} else {
URLProtocol.WS
}

client.href(Route.Events(), this)
}

client.href(Route.Events(), this)
headers.append(HttpHeaders.Username, settings.userName)
}

headers.append(HttpHeaders.Username, settings.userName)
} catch (e: Exception) {
LOG.error(e) { "Could not connect to websocket" }
if (isRetry) {
retry.retry()
LOG.warn { "Retrying ..." }
connectToWebSocket(isRetry = true)
}
return
}
retry.reset()

webSocketSession = session

session.launch {
launch {
while (isActive) {
val event = session.receiveDeserialized<Event>()
for (message in session.incoming) {
val event = client.plugin(WebSockets).contentConverter!!.deserialize<Event>(message)
LOG.debug { "Received event: $event" }
_events.emit(event)
handleEvent(event)
}
}

val reason = session.closeReason.await()
LOG.info { "Lost connection to websocket: ${reason?.message}" }
LOG.info { "Lost connection to websocket" }
connectToWebSocket(isRetry = true)
}
}

Expand Down
4 changes: 3 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ kotlinx-io-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-io-core", v
ktor-resources = { group = "io.ktor", name = "ktor-resources", version.ref = "ktor" }
ktor-http = { group = "io.ktor", name = "ktor-http", version.ref = "ktor" }
ktor-serialization-kotlinx-json = { group = "io.ktor", name = "ktor-serialization-kotlinx-json", version.ref = "ktor" }
ktor-client-okhttp = { group = "io.ktor", name = "ktor-client-okhttp", version.ref = "ktor" }
ktor-client-cio = { group = "io.ktor", name = "ktor-client-cio", version.ref = "ktor" }
ktor-client-resources = { group = "io.ktor", name = "ktor-client-resources", version.ref = "ktor" }
ktor-client-websockets = { group = "io.ktor", name = "ktor-client-websockets", version.ref = "ktor" }
ktor-client-content-negotiation = { group = "io.ktor", name = "ktor-client-content-negotiation", version.ref = "ktor" }
Expand All @@ -33,6 +33,8 @@ compose-navigation = { group = "org.jetbrains.androidx.navigation", name = "navi
kotlin-logging = { group = "io.github.oshai", name = "kotlin-logging", version = "7.0.4" }
logback-classic = { group = "ch.qos.logback", name = "logback-classic", version = "1.5.16" }

kord-gateway = { group = "dev.kord", name = "kord-gateway", version = "0.15.0" }

[plugins]
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
Expand Down
9 changes: 7 additions & 2 deletions server/src/main/kotlin/Server.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package dev.schlaubi.gtakiller

import dev.schlaubi.gtakiller.common.*
import dev.schlaubi.gtakiller.common.Route
import dev.schlaubi.gtakiller.util.hashIpAddress
import io.github.oshai.kotlinlogging.KotlinLogging
import io.ktor.http.*
import io.ktor.serialization.kotlinx.*
import io.ktor.serialization.kotlinx.json.*
import io.ktor.server.application.*
import io.ktor.server.engine.*
import io.ktor.server.routing.Route as KtorRoute
import io.ktor.server.netty.*
import io.ktor.server.plugins.*
import io.ktor.server.plugins.contentnegotiation.*
Expand All @@ -24,6 +24,7 @@ import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import kotlinx.serialization.json.Json
import kotlin.time.Duration.Companion.seconds
import io.ktor.server.routing.Route as KtorRoute

private val LOG = KotlinLogging.logger { }

Expand Down Expand Up @@ -79,7 +80,9 @@ private fun KtorRoute.websocketHandler() {
}

sessions.forEach {
it.send(event)
if (it != this@websocketHandler) {
it.send(event)
}
}

if (event is KillGtaEvent) {
Expand All @@ -92,6 +95,8 @@ private fun KtorRoute.websocketHandler() {
count = stats.count + 1
)
)
} else {
LOG.debug { "Ignoring kill, last kill was $timeSinceLastKill ago" }
}
sessions.forEach {
it.send(UpdateKillCounterEvent(stats.count, kill))
Expand Down

0 comments on commit 97e86ec

Please sign in to comment.