Skip to content

Commit 97e86ec

Browse files
committed
Bugfixes
- Add reconnecting - add debug logging for stats updates - Fix ci naming
1 parent 06588c4 commit 97e86ec

5 files changed

Lines changed: 47 additions & 28 deletions

File tree

.github/workflows/client.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
java-version: "23"
1515
- uses: gradle/actions/setup-gradle@v4
1616
- run: ./gradlew client:packageReleaseDistributionForCurrentOS
17-
- run: mv client-*.msi client.msi
17+
- run: mv GTA.Killer-*.msi client.msi
1818
working-directory: client/build/compose/binaries/main-release/msi/
1919
- name: Release
2020
uses: softprops/action-gh-release@v2

client/build.gradle.kts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ plugins {
77
alias(libs.plugins.compose)
88
}
99

10-
version = "1.0.0"
10+
version = "1.1.0"
1111

1212
repositories {
1313
mavenCentral()
@@ -20,14 +20,16 @@ dependencies {
2020
implementation(libs.kotlinx.serialization.json)
2121
implementation(libs.jnativehook)
2222
implementation(libs.ktor.serialization.kotlinx.json)
23-
implementation(libs.ktor.client.okhttp)
23+
implementation(libs.ktor.client.cio)
2424
implementation(libs.ktor.client.websockets)
2525
implementation(libs.ktor.client.resources)
2626
implementation(libs.ktor.client.content.negotiation)
2727
implementation(libs.ktor.serialization.kotlinx.json)
2828
implementation(libs.kotlin.logging)
2929
implementation(libs.logback.classic)
3030

31+
implementation(libs.kord.gateway)
32+
3133
implementation(compose.desktop.currentOs)
3234
implementation(compose.foundation)
3335
implementation(compose.runtime)

client/src/main/kotlin/core/APIClient.kt

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,8 @@ package dev.schlaubi.mastermind.core
33
import androidx.compose.runtime.getValue
44
import androidx.compose.runtime.mutableStateOf
55
import androidx.compose.runtime.setValue
6-
import dev.schlaubi.gtakiller.common.Event
7-
import dev.schlaubi.gtakiller.common.KillGtaEvent
8-
import dev.schlaubi.gtakiller.common.Route
9-
import dev.schlaubi.gtakiller.common.Status
10-
import dev.schlaubi.gtakiller.common.Username
6+
import dev.kord.gateway.retry.LinearRetry
7+
import dev.schlaubi.gtakiller.common.*
118
import dev.schlaubi.mastermind.core.settings.settings
129
import io.github.oshai.kotlinlogging.KotlinLogging
1310
import io.ktor.client.*
@@ -17,6 +14,7 @@ import io.ktor.client.plugins.contentnegotiation.*
1714
import io.ktor.client.plugins.resources.*
1815
import io.ktor.client.plugins.websocket.*
1916
import io.ktor.http.*
17+
import io.ktor.serialization.*
2018
import io.ktor.serialization.kotlinx.*
2119
import io.ktor.serialization.kotlinx.json.*
2220
import io.ktor.websocket.*
@@ -25,6 +23,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow
2523
import kotlinx.coroutines.flow.asSharedFlow
2624
import kotlinx.serialization.json.Json
2725
import kotlin.coroutines.CoroutineContext
26+
import kotlin.time.Duration.Companion.seconds
2827

2928
var currentApi by mutableStateOf<APIClient?>(null)
3029

@@ -40,6 +39,7 @@ class APIClient(val url: Url) : CoroutineScope {
4039
json()
4140
}
4241
install(WebSockets) {
42+
pingInterval = 2.seconds
4343
contentConverter = KotlinxWebsocketSerializationConverter(Json)
4444
}
4545
install(Resources)
@@ -52,38 +52,48 @@ class APIClient(val url: Url) : CoroutineScope {
5252
private var webSocketSession: DefaultClientWebSocketSession? = null
5353
private val _events = MutableSharedFlow<Event>()
5454
val events = _events.asSharedFlow()
55+
private val retry = LinearRetry(2.seconds, 20.seconds, 10)
5556

56-
suspend fun connectToWebSocket() {
57+
suspend fun connectToWebSocket(isRetry: Boolean = false) {
5758
webSocketSession?.close()
58-
val session = client.webSocketSession {
59-
url {
60-
url.takeFrom(this@APIClient.url)
61-
protocol = if (url.protocol.isSecure()) {
62-
URLProtocol.WSS
63-
} else {
64-
URLProtocol.WS
59+
val session = try {
60+
client.webSocketSession {
61+
url {
62+
url.takeFrom(this@APIClient.url)
63+
protocol = if (url.protocol.isSecure()) {
64+
URLProtocol.WSS
65+
} else {
66+
URLProtocol.WS
67+
}
68+
69+
client.href(Route.Events(), this)
6570
}
6671

67-
client.href(Route.Events(), this)
72+
headers.append(HttpHeaders.Username, settings.userName)
6873
}
69-
70-
headers.append(HttpHeaders.Username, settings.userName)
74+
} catch (e: Exception) {
75+
LOG.error(e) { "Could not connect to websocket" }
76+
if (isRetry) {
77+
retry.retry()
78+
LOG.warn { "Retrying ..." }
79+
connectToWebSocket(isRetry = true)
80+
}
81+
return
7182
}
83+
retry.reset()
7284

7385
webSocketSession = session
7486

7587
session.launch {
76-
launch {
77-
while (isActive) {
78-
val event = session.receiveDeserialized<Event>()
88+
for (message in session.incoming) {
89+
val event = client.plugin(WebSockets).contentConverter!!.deserialize<Event>(message)
7990
LOG.debug { "Received event: $event" }
8091
_events.emit(event)
8192
handleEvent(event)
8293
}
83-
}
8494

85-
val reason = session.closeReason.await()
86-
LOG.info { "Lost connection to websocket: ${reason?.message}" }
95+
LOG.info { "Lost connection to websocket" }
96+
connectToWebSocket(isRetry = true)
8797
}
8898
}
8999

gradle/libs.versions.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ kotlinx-io-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-io-core", v
1717
ktor-resources = { group = "io.ktor", name = "ktor-resources", version.ref = "ktor" }
1818
ktor-http = { group = "io.ktor", name = "ktor-http", version.ref = "ktor" }
1919
ktor-serialization-kotlinx-json = { group = "io.ktor", name = "ktor-serialization-kotlinx-json", version.ref = "ktor" }
20-
ktor-client-okhttp = { group = "io.ktor", name = "ktor-client-okhttp", version.ref = "ktor" }
20+
ktor-client-cio = { group = "io.ktor", name = "ktor-client-cio", version.ref = "ktor" }
2121
ktor-client-resources = { group = "io.ktor", name = "ktor-client-resources", version.ref = "ktor" }
2222
ktor-client-websockets = { group = "io.ktor", name = "ktor-client-websockets", version.ref = "ktor" }
2323
ktor-client-content-negotiation = { group = "io.ktor", name = "ktor-client-content-negotiation", version.ref = "ktor" }
@@ -33,6 +33,8 @@ compose-navigation = { group = "org.jetbrains.androidx.navigation", name = "navi
3333
kotlin-logging = { group = "io.github.oshai", name = "kotlin-logging", version = "7.0.4" }
3434
logback-classic = { group = "ch.qos.logback", name = "logback-classic", version = "1.5.16" }
3535

36+
kord-gateway = { group = "dev.kord", name = "kord-gateway", version = "0.15.0" }
37+
3638
[plugins]
3739
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
3840
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }

server/src/main/kotlin/Server.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
package dev.schlaubi.gtakiller
22

33
import dev.schlaubi.gtakiller.common.*
4+
import dev.schlaubi.gtakiller.common.Route
45
import dev.schlaubi.gtakiller.util.hashIpAddress
56
import io.github.oshai.kotlinlogging.KotlinLogging
67
import io.ktor.http.*
78
import io.ktor.serialization.kotlinx.*
89
import io.ktor.serialization.kotlinx.json.*
910
import io.ktor.server.application.*
1011
import io.ktor.server.engine.*
11-
import io.ktor.server.routing.Route as KtorRoute
1212
import io.ktor.server.netty.*
1313
import io.ktor.server.plugins.*
1414
import io.ktor.server.plugins.contentnegotiation.*
@@ -24,6 +24,7 @@ import kotlinx.datetime.Clock
2424
import kotlinx.datetime.Instant
2525
import kotlinx.serialization.json.Json
2626
import kotlin.time.Duration.Companion.seconds
27+
import io.ktor.server.routing.Route as KtorRoute
2728

2829
private val LOG = KotlinLogging.logger { }
2930

@@ -79,7 +80,9 @@ private fun KtorRoute.websocketHandler() {
7980
}
8081

8182
sessions.forEach {
82-
it.send(event)
83+
if (it != this@websocketHandler) {
84+
it.send(event)
85+
}
8386
}
8487

8588
if (event is KillGtaEvent) {
@@ -92,6 +95,8 @@ private fun KtorRoute.websocketHandler() {
9295
count = stats.count + 1
9396
)
9497
)
98+
} else {
99+
LOG.debug { "Ignoring kill, last kill was $timeSinceLastKill ago" }
95100
}
96101
sessions.forEach {
97102
it.send(UpdateKillCounterEvent(stats.count, kill))

0 commit comments

Comments
 (0)