Skip to content

Commit a6a30f0

Browse files
committed
feat: add support for InterChat player presence
1 parent c4d274c commit a6a30f0

3 files changed

Lines changed: 45 additions & 8 deletions

File tree

server/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ dependencies {
3737
implementation("io.ktor:ktor-client-cio-jvm:2.3.5")
3838
implementation("ch.qos.logback:logback-classic:$logbackVersion")
3939
implementation("redis.clients:jedis:4.2.3")
40-
implementation("net.azisaba.interchat:api:2.10.0")
40+
implementation("net.azisaba.interchat:api:2.12.0")
4141
implementation("net.kyori:adventure-api:$adventureVersion")
4242
implementation("net.kyori:adventure-text-serializer-legacy:$adventureVersion")
4343
implementation("net.kyori:adventure-text-serializer-gson:$adventureVersion")

server/src/main/kotlin/net/azisaba/api/server/TaskScheduler.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ import kotlinx.coroutines.runBlocking
66
import kotlinx.serialization.encodeToString
77
import kotlinx.serialization.json.Json
88
import net.azisaba.api.Logger
9+
import net.azisaba.api.server.interchat.InterChatPacketListener
10+
import net.azisaba.api.server.interchat.JedisBoxProvider
911
import net.azisaba.api.server.resources.punishments.RouteSearch
1012
import net.azisaba.api.server.schemas.SpicyAzisaBan
1113
import net.azisaba.api.server.vector.RawTextVector
14+
import net.azisaba.interchat.api.data.PlayerPresenceData
15+
import net.azisaba.interchat.api.network.RedisKeys
1216
import org.jetbrains.exposed.sql.transactions.transaction
1317
import java.io.File
1418
import java.util.*
@@ -26,6 +30,23 @@ object TaskScheduler : Timer("Async Task Scheduler", true) {
2630
}
2731
}
2832

33+
schedule(1000 * 30) {
34+
try {
35+
InterChatPacketListener.sockets.forEach { socket ->
36+
if (socket.uuid == null) return@forEach
37+
val existingData = JedisBoxProvider.get().getOptional(RedisKeys.playerPresence(socket.uuid!!.toString()), PlayerPresenceData.CODEC, 1000, true)
38+
if (existingData.isPresent && existingData.get().cause() == PlayerPresenceData.Cause.INTERCHAT && System.currentTimeMillis() - existingData.get().lastSeen() < 1000 * 60) {
39+
// skip if the player is connected to azisaba
40+
return@forEach
41+
}
42+
val presenceData = PlayerPresenceData(socket.uuid!!, socket.server, System.currentTimeMillis(), PlayerPresenceData.Cause.OTHER)
43+
JedisBoxProvider.get().set(RedisKeys.playerPresence(socket.uuid!!.toString()), PlayerPresenceData.CODEC, presenceData)
44+
}
45+
} catch (e: Exception) {
46+
Logger.currentLogger.error("Error updating InterChat player presence", e)
47+
}
48+
}
49+
2950
schedule(1000 * 3, 1000 * 60 * 10) {
3051
try {
3152
runBlocking {

server/src/main/kotlin/net/azisaba/api/server/resources/interchat/RouteIdentifiedGuilds.kt

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,17 @@ import io.ktor.server.application.*
66
import io.ktor.server.auth.*
77
import io.ktor.util.pipeline.*
88
import kotlinx.serialization.Serializable
9+
import kotlinx.serialization.json.JsonElement
10+
import kotlinx.serialization.json.JsonObject
11+
import kotlinx.serialization.json.JsonPrimitive
912
import net.azisaba.api.server.auth.APIKeyPrincipal
1013
import net.azisaba.api.server.interchat.InterChatApi
14+
import net.azisaba.api.server.interchat.JedisBoxProvider
1115
import net.azisaba.api.server.resources.RequestHandler
1216
import net.azisaba.api.server.resources.respondJson
1317
import net.azisaba.api.server.schemas.SpicyAzisaBan
18+
import net.azisaba.interchat.api.data.PlayerPresenceData
19+
import net.azisaba.interchat.api.network.RedisKeys
1420

1521
@Serializable
1622
@Resource("/interchat/guilds/{id}")
@@ -28,15 +34,25 @@ data class RouteIdentifiedGuilds(val id: Long) {
2834
return call.respondJson(mapOf("error" to "not found"), status = HttpStatusCode.NotFound)
2935
}
3036
call.respondJson(members.map {
31-
mapOf(
32-
"guild_id" to it.guildId(),
33-
"uuid" to it.uuid().toString(),
34-
"name" to SpicyAzisaBan.Players.getUsernameById(it.uuid()),
35-
"role" to it.role().name,
36-
"nickname" to it.nickname(),
37-
)
37+
val presenceData = JedisBoxProvider.get().getOptional(RedisKeys.playerPresence(it.uuid().toString()), PlayerPresenceData.CODEC, 100, true)
38+
val extraData = mutableMapOf<String, JsonElement>()
39+
if (presenceData.isPresent) {
40+
extraData["presence"] = JsonObject(mapOf(
41+
"server" to JsonPrimitive(presenceData.get().server()),
42+
"last_seen" to JsonPrimitive(presenceData.get().lastSeen()),
43+
"cause" to JsonPrimitive(presenceData.get().cause().name),
44+
))
45+
}
46+
JsonObject(mapOf(
47+
"guild_id" to JsonPrimitive(it.guildId()),
48+
"uuid" to JsonPrimitive(it.uuid().toString()),
49+
"name" to JsonPrimitive(SpicyAzisaBan.Players.getUsernameById(it.uuid())),
50+
"role" to JsonPrimitive(it.role().name),
51+
"nickname" to JsonPrimitive(it.nickname()),
52+
)) + JsonObject(extraData)
3853
})
3954
} catch (e: Exception) {
55+
e.printStackTrace()
4056
return call.respondJson(mapOf("error" to "not found"), status = HttpStatusCode.NotFound)
4157
}
4258
}

0 commit comments

Comments
 (0)