100 lines
3.8 KiB
Kotlin
100 lines
3.8 KiB
Kotlin
/*
|
|
* SPDX-FileCopyrightText: 2023 Linnea Gräf <nea@nea.moe>
|
|
*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
*/
|
|
|
|
package moe.nea.firmament.apis
|
|
|
|
import io.ktor.client.call.*
|
|
import io.ktor.client.request.*
|
|
import io.ktor.http.*
|
|
import io.ktor.util.*
|
|
import java.util.*
|
|
import kotlinx.coroutines.Deferred
|
|
import kotlinx.coroutines.async
|
|
import kotlinx.coroutines.launch
|
|
import kotlinx.coroutines.withContext
|
|
import kotlin.collections.MutableMap
|
|
import kotlin.collections.listOf
|
|
import kotlin.collections.mutableMapOf
|
|
import kotlin.collections.set
|
|
import moe.nea.firmament.Firmament
|
|
import moe.nea.firmament.util.MinecraftDispatcher
|
|
|
|
object Routes {
|
|
private val nameToUUID: MutableMap<String, Deferred<UUID?>> = CaseInsensitiveMap()
|
|
private val profiles: MutableMap<UUID, Deferred<Profiles?>> = mutableMapOf()
|
|
private val accounts: MutableMap<UUID, Deferred<PlayerData?>> = mutableMapOf()
|
|
private val UUIDToName: MutableMap<UUID, Deferred<String?>> = 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<AshconNameLookup>()
|
|
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<AshconNameLookup>()
|
|
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 = UrsaManager.request(listOf("v1", "hypixel","player", uuid.toString()))
|
|
if (!response.status.isSuccess()) {
|
|
launch(MinecraftDispatcher) {
|
|
@Suppress("DeferredResultUnused")
|
|
accounts.remove(uuid)
|
|
}
|
|
return@async null
|
|
}
|
|
response.body<PlayerResponse>().player
|
|
}
|
|
}
|
|
}.await()
|
|
}
|
|
|
|
suspend fun getProfiles(uuid: UUID): Profiles? {
|
|
return withContext(MinecraftDispatcher) {
|
|
profiles.computeIfAbsent(uuid) {
|
|
async(Firmament.coroutineScope.coroutineContext) {
|
|
val response = UrsaManager.request(listOf("v1", "hypixel","profiles", uuid.toString()))
|
|
if (!response.status.isSuccess()) {
|
|
launch(MinecraftDispatcher) {
|
|
@Suppress("DeferredResultUnused")
|
|
profiles.remove(uuid)
|
|
}
|
|
return@async null
|
|
}
|
|
response.body<Profiles>()
|
|
}
|
|
}
|
|
}.await()
|
|
}
|
|
|
|
}
|