diff options
Diffstat (limited to 'src/main/java/at/hannibal2')
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/config/features/Garden.java | 7 | ||||
-rw-r--r-- | src/main/java/at/hannibal2/skyhanni/features/garden/EliteFarmingWeight.kt | 174 |
2 files changed, 129 insertions, 52 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java index bfa578547..70e9907a9 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Garden.java @@ -353,6 +353,13 @@ public class Garden { public boolean eliteFarmingWeightLeaderboard = true; @Expose + @ConfigOption(name = "Overtake ETA", desc = "Show a timer estimating when you'll move up a spot in the leaderboard! " + + "Will show an ETA to rank #1000 if you're not on the leaderboard yet.") + @ConfigEditorBoolean + @ConfigAccordionId(id = 11) + public boolean eliteFarmingWeightOvertakeETA = false; + + @Expose @ConfigOption(name = "Dicer Counter", desc = "") @ConfigEditorAccordion(id = 12) public boolean dicerCounter = false; diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/EliteFarmingWeight.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/EliteFarmingWeight.kt index 863ce9efd..741e52921 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/garden/EliteFarmingWeight.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/garden/EliteFarmingWeight.kt @@ -1,15 +1,14 @@ package at.hannibal2.skyhanni.features.garden import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.api.CollectionAPI import at.hannibal2.skyhanni.data.HyPixelData +import at.hannibal2.skyhanni.events.GardenToolChangeEvent import at.hannibal2.skyhanni.events.GuiRenderEvent -import at.hannibal2.skyhanni.events.ProfileApiDataLoadedEvent -import at.hannibal2.skyhanni.events.ProfileJoinEvent import at.hannibal2.skyhanni.utils.APIUtil import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzUtils.round -import at.hannibal2.skyhanni.utils.RenderUtils.renderString +import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings +import at.hannibal2.skyhanni.utils.TimeUtils import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -17,27 +16,36 @@ import net.minecraft.client.Minecraft import net.minecraftforge.event.world.WorldEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import net.minecraftforge.fml.common.gameevent.TickEvent +import java.util.* class EliteFarmingWeight { @SubscribeEvent - fun onProfileDataLoad(event: ProfileApiDataLoadedEvent) { - // This is still not perfect, but it's definitely better than other alternatives for the moment. - extraCollection.clear() - dirtyCropWeight = true - } - - @SubscribeEvent fun onRenderOverlay(event: GuiRenderEvent.GameOverlayRenderEvent) { if (isEnabled()) { - config.eliteFarmingWeightPos.renderString(display, center = false) + config.eliteFarmingWeightPos.renderStrings(display, center = false) } } @SubscribeEvent + fun onGardenToolChange(event: GardenToolChangeEvent) { + // Reset speed + weightPerSecond = -1.0 + } + + @SubscribeEvent fun onWorldChange(event: WorldEvent.Load) { // We want to try to connect to the api again after a world switch. apiError = false + // We ask both api endpoints after every world switch + weight = -1.0 + weightPerSecond = -1.0 + + leaderboardPosition = -1 + dirtyCropWeight = true + lastLeaderboardUpdate = 0 + nextPlayerWeight = 0.0 + nextPlayerName = "" } var tick = 0 @@ -48,46 +56,44 @@ class EliteFarmingWeight { update() } - @SubscribeEvent - fun onProfileJoin(event: ProfileJoinEvent) { - // Supporting profile switches - leaderboardPosition = -1 - bonusWeight = -1 - dirtyCropWeight = true - lastLeaderboardUpdate = 0 - } - companion object { private val config get() = SkyHanniMod.feature.garden - private val extraCollection = mutableMapOf<String, Long>() + private val localCollection = mutableMapOf<String, Long>() - private var display = "" + private var display = mutableListOf<String>() private var profileId = "" private var lastLeaderboardUpdate = 0L private var apiError = false private var leaderboardPosition = -1 - private var bonusWeight = -2 - private var cropWeight = 0.0 + private var weight = -2.0 + private var localWeight = 0.0 + private var weightPerSecond = -1.0 private var dirtyCropWeight = false private var isLoadingWeight = false private var isLoadingLeaderboard = false + private var nextPlayerName = "" + private var nextPlayerWeight = 0.0 + private fun update() { if (!GardenAPI.inGarden()) return if (apiError) { - display = "§6Farming Weight§7: §cAPI Error!" + display = Collections.singletonList("§6Farming Weight§7: §cAPI Error!") return } - if (bonusWeight == -2) { - display = "§6Farming Weight§7: §eLoading.." + if (weight == -2.0) { + display = Collections.singletonList("§6Farming Weight§7: §eLoading..") return } - if (bonusWeight == -1) { + if (weight == -1.0) { if (!isLoadingWeight) { + val localProfile = HyPixelData.profileName + if (localProfile == "") return + isLoadingWeight = true SkyHanniMod.coroutineScope.launch { - loadBonusWeight() + loadWeight(localProfile) isLoadingWeight = false } } @@ -96,7 +102,13 @@ class EliteFarmingWeight { val weight = getWeight() val leaderboard = getLeaderboard() - display = "§6Farming Weight§7: $weight$leaderboard" + + val list = mutableListOf<String>() + list.add("§6Farming Weight§7: $weight$leaderboard") + if (isEtaEnabled() && weightPerSecond != -1.0) { + list.add(getETA()) + } + display = list } private fun getLeaderboard(): String { @@ -120,9 +132,7 @@ class EliteFarmingWeight { } else { if (isLoadingLeaderboard) { " §7[§b#?§7]" - } else { - "" - } + } else "" } } @@ -130,28 +140,78 @@ class EliteFarmingWeight { if (dirtyCropWeight) { val values = calculateCollectionWeight().values if (values.isNotEmpty()) { - cropWeight = values.sum() + localWeight = values.sum() dirtyCropWeight = false } } - val totalWeight = (cropWeight + bonusWeight) + val totalWeight = (localWeight + weight) return "§e" + LorenzUtils.formatDouble(totalWeight, 2) } + private fun getETA(): String { + if (weight < 0) return "" + + val totalWeight = (localWeight + weight) + if (nextPlayerWeight == 0.0) { + return "§cRejoin the garden to show ETA!" + } + + val weightUntilOvertake = nextPlayerWeight - totalWeight + val timeTillOvertake = (weightUntilOvertake / weightPerSecond) * 1000 + val timeFormat = TimeUtils.formatDuration(timeTillOvertake.toLong()) + + val format = LorenzUtils.formatDouble(weightUntilOvertake, 2) + + // TODO Maybe add next player name? +// val nextName = if (leaderboardPosition == -1) "#1000" else nextPlayerName + val nextName = if (leaderboardPosition == -1) "#1000" else "#" + (leaderboardPosition - 1) + return "§e$format §7(§b$timeFormat§7) §7behind §b$nextName" + } + private fun isEnabled() = GardenAPI.inGarden() && config.eliteFarmingWeightDisplay + private fun isEtaEnabled() = config.eliteFarmingWeightOvertakeETA fun addCrop(crop: String, diff: Int) { - val old = extraCollection[crop] ?: 0L - extraCollection[crop] = old + diff + val old = localCollection[crop] ?: 0L + + val before = calculateExactWeight() + localCollection[crop] = old + diff + val after = calculateExactWeight() + + updateWeightPerSecond(crop, before, after, diff) + dirtyCropWeight = true } + private fun updateWeightPerSecond(crop: String, before: Double, after: Double, diff: Int) { + val speed = GardenAPI.cropsPerSecond[crop]!! + if (speed != -1) { + val weightDiff = (after - before) * 1000 + weightPerSecond = weightDiff / diff * speed / 1000 + } + } + + private fun calculateExactWeight(): Double { + val values = calculateCollectionWeight(false).values + return if (values.isNotEmpty()) { + values.sum() + } else 0.0 + } + private suspend fun loadLeaderboardPosition() = try { val uuid = Minecraft.getMinecraft().thePlayer.uniqueID.toString().replace("-", "") - val url = "https://elitebot.dev/api/leaderboard/rank/weight/farming/$uuid/$profileId" + val showNext = if (isEtaEnabled()) "?showNext=true" else "" + val url = "https://elitebot.dev/api/leaderboard/rank/weight/farming/$uuid/$profileId$showNext" val result = withContext(Dispatchers.IO) { APIUtil.getJSONResponse(url) }.asJsonObject + if (isEtaEnabled()) { + result["next"]?.asJsonObject?.let { + nextPlayerName = it["ign"].asString + nextPlayerWeight = it["amount"].asDouble + } + } + result["rank"].asInt } catch (e: Exception) { apiError = true @@ -160,21 +220,33 @@ class EliteFarmingWeight { -1 } - private suspend fun loadBonusWeight() { - val uuid = Minecraft.getMinecraft().thePlayer.uniqueID.toString().replace("-", "") + private fun UUID.uuidToString(): String { + return "$this" + } + + private suspend fun loadWeight(localProfile: String) { + val thePlayer = Minecraft.getMinecraft().thePlayer + val uniqueID = thePlayer.uniqueID + val abc = uniqueID.uuidToString() + val uuid = abc.replace("-", "") val url = "https://elitebot.dev/api/weight/$uuid" + try { val result = withContext(Dispatchers.IO) { APIUtil.getJSONResponse(url) }.asJsonObject - val localProfile = HyPixelData.profileName for (profileEntry in result["profiles"].asJsonObject.entrySet()) { val profile = profileEntry.value.asJsonObject val profileName = profile["cute_name"].asString.lowercase() if (profileName == localProfile) { profileId = profileEntry.key - bonusWeight = profile["farming"].asJsonObject["bonus"].asInt + weight = profile["farming"].asJsonObject["total"].asDouble + + localCollection.clear() + dirtyCropWeight = true + return } } + println("localProfile: '$localProfile'") println("url: '$url'") println("result: '$result'") } catch (e: Exception) { @@ -185,12 +257,12 @@ class EliteFarmingWeight { LorenzUtils.error("[SkyHanni] Failed to load farming weight data from elitebot.dev! please report this on discord!") } - private fun calculateCollectionWeight(): MutableMap<String, Double> { + private fun calculateCollectionWeight(round: Boolean = true): MutableMap<String, Double> { val weightPerCrop = mutableMapOf<String, Double>() var totalWeight = 0.0 for ((cropName, factor) in factorPerCrop) { - val collection = getCollection(cropName) - val weight = (collection / factor).round(2) + val collection = getLocalCollection(cropName) + val weight = (collection / factor).also { if (round) weight.round(2) else weight } weightPerCrop[cropName] = weight totalWeight += weight } @@ -207,19 +279,17 @@ class EliteFarmingWeight { val normalRatio = (totalWeight - cactusWeight - sugarCaneWeight) / totalWeight; val mushroomFactor = factorPerCrop["Mushroom"]!! - val mushroomCollection = getCollection("Mushroom") + val mushroomCollection = getLocalCollection("Mushroom") return doubleBreakRatio * (mushroomCollection / (2 * mushroomFactor)) + normalRatio * (mushroomCollection / mushroomFactor) } - private fun getCollection(cropName: String): Double { - val real = CollectionAPI.getCollectionCounter(cropName)?.second ?: 0L - val extra = (extraCollection[cropName] ?: 0L) - return (real + extra).toDouble() + private fun getLocalCollection(cropName: String): Long { + return localCollection[cropName] ?: 0L } private val factorPerCrop by lazy { mapOf( - "wheat" to 100_000.0, + "Wheat" to 100_000.0, "Carrot" to 300_000.0, "Potato" to 300_000.0, "Sugar Cane" to 200_000.0, |