aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorKaeso <24925519+ptlthg@users.noreply.github.com>2023-03-23 06:18:05 -0400
committerGitHub <noreply@github.com>2023-03-23 11:18:05 +0100
commit2bb2939b5e66ba9951688de50be89a4cb82825b7 (patch)
tree25501a67e745849e57fd976bc515e50a9a439f78 /src/main
parentaedcb9548aeed556540a15dc3fb6c034a043510e (diff)
downloadskyhanni-2bb2939b5e66ba9951688de50be89a4cb82825b7.tar.gz
skyhanni-2bb2939b5e66ba9951688de50be89a4cb82825b7.tar.bz2
skyhanni-2bb2939b5e66ba9951688de50be89a4cb82825b7.zip
Farming Weight Leaderboard Overtake ETA (#18)
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/features/Garden.java7
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/EliteFarmingWeight.kt174
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,