From f2eb8c4dc898336f1ee44e62e18b4a7406464736 Mon Sep 17 00:00:00 2001 From: nea Date: Fri, 2 Jun 2023 23:01:09 +0200 Subject: Add more caching and fix some models --- src/main/kotlin/moe/nea/firmament/apis/Profiles.kt | 6 +- src/main/kotlin/moe/nea/firmament/apis/Routes.kt | 109 +++++++++++++++++++++ 2 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 src/main/kotlin/moe/nea/firmament/apis/Routes.kt (limited to 'src/main/kotlin/moe/nea/firmament/apis') diff --git a/src/main/kotlin/moe/nea/firmament/apis/Profiles.kt b/src/main/kotlin/moe/nea/firmament/apis/Profiles.kt index 4fd5704..7132147 100644 --- a/src/main/kotlin/moe/nea/firmament/apis/Profiles.kt +++ b/src/main/kotlin/moe/nea/firmament/apis/Profiles.kt @@ -21,7 +21,7 @@ import moe.nea.firmament.util.json.InstantAsLongSerializer @Serializable data class Profiles( val success: Boolean, - val profiles: List + val profiles: List? ) @Serializable @@ -120,12 +120,12 @@ data class PlayerResponse( data class PlayerData( val uuid: UUID, val firstLogin: Instant, - val lastLogin: Instant, + val lastLogin: Instant? = null, @SerialName("playername") val playerName: String, val achievementsOneTime: List = listOf(), @SerialName("newPackageRank") - val packageRank: String?, + val packageRank: String? = null, val monthlyPackageRank: String? = null, val rankPlusColor: String = "GOLD" ) { diff --git a/src/main/kotlin/moe/nea/firmament/apis/Routes.kt b/src/main/kotlin/moe/nea/firmament/apis/Routes.kt new file mode 100644 index 0000000..7785d90 --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/apis/Routes.kt @@ -0,0 +1,109 @@ +package moe.nea.firmament.apis + +import io.ktor.client.call.body +import io.ktor.client.request.get +import io.ktor.client.request.parameter +import io.ktor.http.URLProtocol +import io.ktor.http.isSuccess +import io.ktor.http.path +import io.ktor.util.CaseInsensitiveMap +import java.util.UUID +import kotlinx.coroutines.Deferred +import kotlinx.coroutines.async +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import moe.nea.firmament.Firmament +import moe.nea.firmament.util.MinecraftDispatcher + +object Routes { + val apiKey = "e721a103-96e0-400f-af2a-73b2a91007b1" + private val nameToUUID: MutableMap> = CaseInsensitiveMap() + private val profiles: MutableMap> = mutableMapOf() + private val accounts: MutableMap> = mutableMapOf() + private val UUIDToName: MutableMap> = mutableMapOf() + + suspend fun getPlayerNameForUUID(uuid: UUID): String? { + return withContext(MinecraftDispatcher) { + UUIDToName.computeIfAbsent(uuid) { + async(Firmament.coroutineScope.coroutineContext) { + val response = Firmament.httpClient.get("https://api.ashcon.app/mojang/v2/user/$uuid") + if (!response.status.isSuccess()) return@async null + val data = response.body() + launch(MinecraftDispatcher) { + nameToUUID[data.username] = async { data.uuid } + } + data.username + } + } + }.await() + } + + suspend fun getUUIDForPlayerName(name: String): UUID? { + return withContext(MinecraftDispatcher) { + nameToUUID.computeIfAbsent(name) { + async(Firmament.coroutineScope.coroutineContext) { + val response = Firmament.httpClient.get("https://api.ashcon.app/mojang/v2/user/$name") + if (!response.status.isSuccess()) return@async null + val data = response.body() + launch(MinecraftDispatcher) { + UUIDToName[data.uuid] = async { data.username } + } + data.uuid + } + } + }.await() + } + + suspend fun getAccountData(uuid: UUID): PlayerData? { + return withContext(MinecraftDispatcher) { + accounts.computeIfAbsent(uuid) { + async(Firmament.coroutineScope.coroutineContext) { + val response = Firmament.httpClient.get { + url { + protocol = URLProtocol.HTTPS + host = "api.hypixel.net" + path("player") + parameter("key", apiKey) + parameter("uuid", uuid) + } + } + if (!response.status.isSuccess()) { + launch(MinecraftDispatcher) { + @Suppress("DeferredResultUnused") + accounts.remove(uuid) + } + return@async null + } + response.body().player + } + } + }.await() + } + + suspend fun getProfiles(uuid: UUID): Profiles? { + return withContext(MinecraftDispatcher) { + profiles.computeIfAbsent(uuid) { + async(Firmament.coroutineScope.coroutineContext) { + val response = Firmament.httpClient.get { + url { + protocol = URLProtocol.HTTPS + host = "api.hypixel.net" + path("skyblock", "profiles") + parameter("key", apiKey) + parameter("uuid", uuid) + } + } + if (!response.status.isSuccess()) { + launch(MinecraftDispatcher) { + @Suppress("DeferredResultUnused") + profiles.remove(uuid) + } + return@async null + } + response.body() + } + } + }.await() + } + +} -- cgit