diff options
author | nea <nea@nea.moe> | 2023-08-15 19:34:56 +0200 |
---|---|---|
committer | nea <nea@nea.moe> | 2023-08-15 19:38:27 +0200 |
commit | 8c5570bfe6ab93855e24e6924fac1105fe8342ff (patch) | |
tree | 71c412ffefede775f36411531fed089d21b6d49d /src/main/kotlin/moe/nea/firmament/apis | |
parent | b32f5da88c355645a9eaf343987f10506aa25bee (diff) | |
download | Firmament-8c5570bfe6ab93855e24e6924fac1105fe8342ff.tar.gz Firmament-8c5570bfe6ab93855e24e6924fac1105fe8342ff.tar.bz2 Firmament-8c5570bfe6ab93855e24e6924fac1105fe8342ff.zip |
Add ursa client
Diffstat (limited to 'src/main/kotlin/moe/nea/firmament/apis')
-rw-r--r-- | src/main/kotlin/moe/nea/firmament/apis/UrsaManager.kt | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/main/kotlin/moe/nea/firmament/apis/UrsaManager.kt b/src/main/kotlin/moe/nea/firmament/apis/UrsaManager.kt new file mode 100644 index 0000000..a72d633 --- /dev/null +++ b/src/main/kotlin/moe/nea/firmament/apis/UrsaManager.kt @@ -0,0 +1,73 @@ +/* + * 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.request.* +import io.ktor.client.statement.* +import io.ktor.http.* +import java.time.Duration +import java.time.Instant +import java.util.* +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.withContext +import net.minecraft.client.MinecraftClient +import moe.nea.firmament.Firmament + +object UrsaManager { + private data class Token( + val validUntil: Instant, + val token: String, + val obtainedFrom: String, + ) { + fun isValid(host: String) = Instant.now().plusSeconds(60) < validUntil && obtainedFrom == host + } + + private var currentToken: Token? = null + private val lock = Mutex() + private fun getToken(host: String) = currentToken?.takeIf { it.isValid(host) } + + suspend fun request(path: List<String>): HttpResponse { + var didLock = false + try { + val host = "ursa.notenoughupdates.org" + var token = getToken(host) + if (token == null) { + lock.lock() + didLock = true + token = getToken(host) + } + val response = Firmament.httpClient.get { + url { + this.host = host + appendPathSegments(path, encodeSlash = true) + } + if (token == null) { + withContext(Dispatchers.IO) { + val mc = MinecraftClient.getInstance() + val serverId = UUID.randomUUID().toString() + mc.sessionService.joinServer(mc.session.profile, mc.session.accessToken, serverId) + header("x-ursa-username", mc.session.profile.name) + header("x-ursa-serverid", serverId) + } + } else { + header("x-ursa-token", token.token) + } + } + val savedToken = response.headers["x-ursa-token"] + if (savedToken != null) { + val validUntil = response.headers["x-ursa-expires"]?.toLongOrNull()?.let { Instant.ofEpochMilli(it) } + ?: (Instant.now() + Duration.ofMinutes(55)) + currentToken = Token(validUntil, savedToken, host) + } + return response + } finally { + if (didLock) + lock.unlock() + } + } +} |