aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea/firmament/apis/Routes.kt
blob: 71802a5311808da60ff100347f509261f753fabd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
 * 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.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<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 = 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<PlayerResponse>().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<Profiles>()
                }
            }
        }.await()
    }

}