diff options
author | Linnea Gräf <nea@nea.moe> | 2024-08-28 19:04:24 +0200 |
---|---|---|
committer | Linnea Gräf <nea@nea.moe> | 2024-08-28 19:04:24 +0200 |
commit | d2f240ff0ca0d27f417f837e706c781a98c31311 (patch) | |
tree | 0db7aff6cc14deaf36eed83889d59fd6b3a6f599 /src/main/kotlin/moe/nea/firmament/apis | |
parent | a6906308163aa3b2d18fa1dc1aa71ac9bbcc83ab (diff) | |
download | firmament-d2f240ff0ca0d27f417f837e706c781a98c31311.tar.gz firmament-d2f240ff0ca0d27f417f837e706c781a98c31311.tar.bz2 firmament-d2f240ff0ca0d27f417f837e706c781a98c31311.zip |
Refactor source layout
Introduce compat source sets and move all kotlin sources to the main directory
[no changelog]
Diffstat (limited to 'src/main/kotlin/moe/nea/firmament/apis')
-rw-r--r-- | src/main/kotlin/moe/nea/firmament/apis/Profiles.kt | 194 | ||||
-rw-r--r-- | src/main/kotlin/moe/nea/firmament/apis/Routes.kt | 95 | ||||
-rw-r--r-- | src/main/kotlin/moe/nea/firmament/apis/UrsaManager.kt | 72 |
3 files changed, 0 insertions, 361 deletions
diff --git a/src/main/kotlin/moe/nea/firmament/apis/Profiles.kt b/src/main/kotlin/moe/nea/firmament/apis/Profiles.kt deleted file mode 100644 index 789364a..0000000 --- a/src/main/kotlin/moe/nea/firmament/apis/Profiles.kt +++ /dev/null @@ -1,194 +0,0 @@ - - -@file:UseSerializers(DashlessUUIDSerializer::class, InstantAsLongSerializer::class) - -package moe.nea.firmament.apis - -import io.github.moulberry.repo.constants.Leveling -import io.github.moulberry.repo.data.Rarity -import kotlinx.datetime.Instant -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import kotlinx.serialization.UseSerializers -import moe.nea.firmament.repo.RepoManager -import moe.nea.firmament.util.LegacyFormattingCode -import moe.nea.firmament.util.SkyblockId -import moe.nea.firmament.util.assertNotNullOr -import moe.nea.firmament.util.json.DashlessUUIDSerializer -import moe.nea.firmament.util.json.InstantAsLongSerializer -import net.minecraft.util.DyeColor -import net.minecraft.util.Formatting -import java.util.* -import kotlin.reflect.KProperty1 - - -@Serializable -data class CollectionSkillData( - val items: Map<CollectionType, CollectionInfo> -) - -@Serializable -data class CollectionResponse( - val success: Boolean, - val collections: Map<String, CollectionSkillData> -) - -@Serializable -data class CollectionInfo( - val name: String, - val maxTiers: Int, - val tiers: List<CollectionTier> -) - -@Serializable -data class CollectionTier( - val tier: Int, - val amountRequired: Long, - val unlocks: List<String>, -) - - -@Serializable -data class Profiles( - val success: Boolean, - val profiles: List<Profile>? -) - -@Serializable -data class Profile( - @SerialName("profile_id") - val profileId: UUID, - @SerialName("cute_name") - val cuteName: String, - val selected: Boolean = false, - val members: Map<UUID, Member>, -) - -enum class Skill(val accessor: KProperty1<Member, Double>, val color: DyeColor, val icon: SkyblockId) { - FARMING(Member::experienceSkillFarming, DyeColor.YELLOW, SkyblockId("ROOKIE_HOE")), - FORAGING(Member::experienceSkillForaging, DyeColor.BROWN, SkyblockId("TREECAPITATOR_AXE")), - MINING(Member::experienceSkillMining, DyeColor.LIGHT_GRAY, SkyblockId("DIAMOND_PICKAXE")), - ALCHEMY(Member::experienceSkillAlchemy, DyeColor.PURPLE, SkyblockId("BREWING_STAND")), - TAMING(Member::experienceSkillTaming, DyeColor.GREEN, SkyblockId("SUPER_EGG")), - FISHING(Member::experienceSkillFishing, DyeColor.BLUE, SkyblockId("FARMER_ROD")), - RUNECRAFTING(Member::experienceSkillRunecrafting, DyeColor.PINK, SkyblockId("MUSIC_RUNE;1")), - CARPENTRY(Member::experienceSkillCarpentry, DyeColor.ORANGE, SkyblockId("WORKBENCH")), - COMBAT(Member::experienceSkillCombat, DyeColor.RED, SkyblockId("UNDEAD_SWORD")), - SOCIAL(Member::experienceSkillSocial, DyeColor.WHITE, SkyblockId("EGG_HUNT")), - ENCHANTING(Member::experienceSkillEnchanting, DyeColor.MAGENTA, SkyblockId("ENCHANTMENT_TABLE")), - ; - - fun getMaximumLevel(leveling: Leveling) = assertNotNullOr(leveling.maximumLevels[name.lowercase()]) { 50 } - - fun getLadder(leveling: Leveling): List<Int> { - if (this == SOCIAL) return leveling.socialExperienceRequiredPerLevel - if (this == RUNECRAFTING) return leveling.runecraftingExperienceRequiredPerLevel - return leveling.skillExperienceRequiredPerLevel - } -} - -enum class CollectionCategory(val skill: Skill?, val color: DyeColor, val icon: SkyblockId) { - FARMING(Skill.FARMING, DyeColor.YELLOW, SkyblockId("ROOKIE_HOE")), - FORAGING(Skill.FORAGING, DyeColor.BROWN, SkyblockId("TREECAPITATOR_AXE")), - MINING(Skill.MINING, DyeColor.LIGHT_GRAY, SkyblockId("DIAMOND_PICKAXE")), - FISHING(Skill.FISHING, DyeColor.BLUE, SkyblockId("FARMER_ROD")), - COMBAT(Skill.COMBAT, DyeColor.RED, SkyblockId("UNDEAD_SWORD")), - RIFT(null, DyeColor.PURPLE, SkyblockId("SKYBLOCK_MOTE")), -} - -@Serializable -@JvmInline -value class CollectionType(val string: String) { - val skyblockId get() = SkyblockId(string.replace(":", "-").replace("MUSHROOM_COLLECTION", "HUGE_MUSHROOM_2")) -} - -@Serializable -data class Member( - val pets: List<Pet> = listOf(), - @SerialName("coop_invitation") - val coopInvitation: CoopInvitation? = null, - @SerialName("experience_skill_farming") - val experienceSkillFarming: Double = 0.0, - @SerialName("experience_skill_alchemy") - val experienceSkillAlchemy: Double = 0.0, - @SerialName("experience_skill_combat") - val experienceSkillCombat: Double = 0.0, - @SerialName("experience_skill_taming") - val experienceSkillTaming: Double = 0.0, - @SerialName("experience_skill_social2") - val experienceSkillSocial: Double = 0.0, - @SerialName("experience_skill_enchanting") - val experienceSkillEnchanting: Double = 0.0, - @SerialName("experience_skill_fishing") - val experienceSkillFishing: Double = 0.0, - @SerialName("experience_skill_foraging") - val experienceSkillForaging: Double = 0.0, - @SerialName("experience_skill_mining") - val experienceSkillMining: Double = 0.0, - @SerialName("experience_skill_runecrafting") - val experienceSkillRunecrafting: Double = 0.0, - @SerialName("experience_skill_carpentry") - val experienceSkillCarpentry: Double = 0.0, - val collection: Map<CollectionType, Long> = mapOf() -) - -@Serializable -data class CoopInvitation( - val timestamp: Instant, - @SerialName("invited_by") - val invitedBy: UUID? = null, - val confirmed: Boolean, -) - -@JvmInline -@Serializable -value class PetType(val name: String) - -@Serializable -data class Pet( - val uuid: UUID? = null, - val type: PetType, - val exp: Double = 0.0, - val active: Boolean = false, - val tier: Rarity, - val candyUsed: Int = 0, - val heldItem: String? = null, - val skin: String? = null, -) { - val itemId get() = SkyblockId("${type.name};${tier.ordinal}") -} - -@Serializable -data class PlayerResponse( - val success: Boolean, - val player: PlayerData, -) - -@Serializable -data class PlayerData( - val uuid: UUID, - val firstLogin: Instant, - val lastLogin: Instant? = null, - @SerialName("playername") - val playerName: String, - val achievementsOneTime: List<String> = listOf(), - @SerialName("newPackageRank") - val packageRank: String? = null, - val monthlyPackageRank: String? = null, - val rankPlusColor: String = "GOLD" -) { - val rankPlusDyeColor = LegacyFormattingCode.values().find { it.name == rankPlusColor } ?: LegacyFormattingCode.GOLD - val rankData get() = RepoManager.neuRepo.constants.misc.ranks[if (monthlyPackageRank == "NONE" || monthlyPackageRank == null) packageRank else monthlyPackageRank] - fun getDisplayName(name: String = playerName) = rankData?.let { - ("§${it.color}[${it.tag}${rankPlusDyeColor.modern}" + - "${it.plus ?: ""}§${it.color}] $name") - } ?: "${Formatting.GRAY}$name" - - -} - -@Serializable -data class AshconNameLookup( - val username: String, - val uuid: UUID, -) diff --git a/src/main/kotlin/moe/nea/firmament/apis/Routes.kt b/src/main/kotlin/moe/nea/firmament/apis/Routes.kt deleted file mode 100644 index bf55a2d..0000000 --- a/src/main/kotlin/moe/nea/firmament/apis/Routes.kt +++ /dev/null @@ -1,95 +0,0 @@ - - -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() - } - -} diff --git a/src/main/kotlin/moe/nea/firmament/apis/UrsaManager.kt b/src/main/kotlin/moe/nea/firmament/apis/UrsaManager.kt deleted file mode 100644 index 13f7aef..0000000 --- a/src/main/kotlin/moe/nea/firmament/apis/UrsaManager.kt +++ /dev/null @@ -1,72 +0,0 @@ - - -package moe.nea.firmament.apis - -import io.ktor.client.request.* -import io.ktor.client.statement.* -import io.ktor.http.* -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.withContext -import moe.nea.firmament.Firmament -import net.minecraft.client.MinecraftClient -import java.time.Duration -import java.time.Instant -import java.util.* - -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.uuidOrNull, mc.session.accessToken, serverId) - header("x-ursa-username", mc.session.username) - 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) - } - if (response.status.value != 200) { - Firmament.logger.error("Failed to contact ursa minor: ${response.bodyAsText()}") - } - return response - } finally { - if (didLock) - lock.unlock() - } - } -} |