aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/features
diff options
context:
space:
mode:
authorCalMWolfs <94038482+CalMWolfs@users.noreply.github.com>2024-06-14 05:49:38 +1000
committerGitHub <noreply@github.com>2024-06-13 21:49:38 +0200
commit5bd6a4cd3807d128ba55c336946531a8838c51c7 (patch)
tree3b3b4589cb4e47541f8d12602682a37f44b18a80 /src/main/java/at/hannibal2/skyhanni/features
parente9c12d363a45d7cc1581fd882f3701b5388f4a8e (diff)
downloadskyhanni-5bd6a4cd3807d128ba55c336946531a8838c51c7.tar.gz
skyhanni-5bd6a4cd3807d128ba55c336946531a8838c51c7.tar.bz2
skyhanni-5bd6a4cd3807d128ba55c336946531a8838c51c7.zip
Backend: Apply annotations to everything (#1983)
* add plugin Co-authored-by: ThatGravyBoat <thatgravyboat@gmail.com> * data and apis done * other stuff done * fix merge * Backend: Classes -> Objects with annotation * Backend: Apply annotations to everything * fix test * fix merge * fix merge * use annotation * use annotation * fix version number * fix space * bring back fix * work on companion again now that they are all done * oop * fixed merge conflicts --------- Co-authored-by: ThatGravyBoat <thatgravyboat@gmail.com> Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/features')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt185
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/DamageIndicatorManager.kt1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/event/diana/BurrowWarpHelper.kt1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt780
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/ScoreboardElements.kt4
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/misc/CollectionTracker.kt251
6 files changed, 610 insertions, 612 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt
index 683fe1857..2d3f3aa85 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/chat/Translator.kt
@@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.features.chat
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.SkyHanniMod.Companion.coroutineScope
import at.hannibal2.skyhanni.events.LorenzChatEvent
+import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.utils.APIUtil
import at.hannibal2.skyhanni.utils.ChatUtils
import at.hannibal2.skyhanni.utils.ConditionalUtils.transformIf
@@ -21,7 +22,8 @@ import java.net.URLDecoder
import java.net.URLEncoder
// TODO split into two classes: TranslatorCommand and GoogleTranslator. only communicates via getTranslationFromEnglish and getTranslationToEnglish
-class Translator {
+@SkyHanniModule
+object Translator {
private val messageContentRegex = Regex(".*: (.*)")
@@ -49,108 +51,105 @@ class Translator {
return style
}
- companion object {
-
- private val config get() = SkyHanniMod.feature.chat
-
- /*
- * Simplified version of the JSON response:
- * [
- * [
- * [
- * 'translated sentence one with a space after the punctuation. '
- * 'original sentence one without a space after the punctuation.'
- * ],
- * [
- * 'translated sentence two without punctuation bc it's last'
- * 'original sentence two without punctuation'
- * ]
- * ],
- * null,
- * '"target language as a two-letter code following ISO 639-1"',
- * ]
- */
-
- private fun getJSONResponse(urlString: String) =
- APIUtil.getJSONResponseAsElement(urlString, false, "Google Translate API")
-
- private fun getTranslationToEnglish(message: String): String {
- val url =
- "https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=en&dt=t&q=" +
- URLEncoder.encode(message, "UTF-8")
-
- var messageToSend = ""
- val layer1 = getJSONResponse(url).asJsonArray
- if (layer1.size() <= 2) return "Error!"
-
- val language = layer1[2].toString()
- if (language == "\"en\"") return "Unable to translate!"
- if (language.length != 4) return "Error!"
-
- val layer2 = try {
- layer1[0] as JsonArray
- } catch (_: Exception) {
- return "Error!"
- }
+ private val config get() = SkyHanniMod.feature.chat
+
+ /*
+ * Simplified version of the JSON response:
+ * [
+ * [
+ * [
+ * 'translated sentence one with a space after the punctuation. '
+ * 'original sentence one without a space after the punctuation.'
+ * ],
+ * [
+ * 'translated sentence two without punctuation bc it's last'
+ * 'original sentence two without punctuation'
+ * ]
+ * ],
+ * null,
+ * '"target language as a two-letter code following ISO 639-1"',
+ * ]
+ */
+
+ private fun getJSONResponse(urlString: String) =
+ APIUtil.getJSONResponseAsElement(urlString, false, "Google Translate API")
+
+ private fun getTranslationToEnglish(message: String): String {
+ val url =
+ "https://translate.googleapis.com/translate_a/single?client=gtx&sl=auto&tl=en&dt=t&q=" +
+ URLEncoder.encode(message, "UTF-8")
+
+ var messageToSend = ""
+ val layer1 = getJSONResponse(url).asJsonArray
+ if (layer1.size() <= 2) return "Error!"
+
+ val language = layer1[2].toString()
+ if (language == "\"en\"") return "Unable to translate!"
+ if (language.length != 4) return "Error!"
+
+ val layer2 = try {
+ layer1[0] as JsonArray
+ } catch (_: Exception) {
+ return "Error!"
+ }
- for (layer3 in layer2) {
- val arrayLayer3 = layer3 as? JsonArray ?: continue
- val sentence = arrayLayer3[0].toString()
+ for (layer3 in layer2) {
+ val arrayLayer3 = layer3 as? JsonArray ?: continue
+ val sentence = arrayLayer3[0].toString()
+ val sentenceWithoutQuotes = sentence.substring(1, sentence.length - 1)
+ messageToSend = "$messageToSend$sentenceWithoutQuotes"
+ }
+ messageToSend = "$messageToSend §7(Language: $language)"
+
+ return URLDecoder.decode(messageToSend, "UTF-8").replace("\\", "")
+ }
+
+ private fun getTranslationFromEnglish(message: String, lang: String): String {
+ val url =
+ "https://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=$lang&dt=t&q=" +
+ URLEncoder.encode(message, "UTF-8")
+
+ val layer1 = getJSONResponse(url).asJsonArray
+ if (layer1.size() < 1) return "Error!"
+ val layer2 = layer1[0] as? JsonArray
+
+ val firstSentence = (layer2?.get(0) as? JsonArray)?.get(0).toString()
+ var messageToSend = firstSentence.substring(0, firstSentence.length - 1)
+ if (layer2 != null) {
+ for (sentenceIndex in 1..<layer2.size()) {
+ val sentence = (layer2.get(sentenceIndex) as JsonArray).get(0).toString()
val sentenceWithoutQuotes = sentence.substring(1, sentence.length - 1)
messageToSend = "$messageToSend$sentenceWithoutQuotes"
}
- messageToSend = "$messageToSend §7(Language: $language)"
+ } // The first translated sentence only has 1 extra char at the end, but sentences after it need 1 at the front and 1 at the end removed in the substring
+ messageToSend = messageToSend.substring(1, messageToSend.length)
+ return URLDecoder.decode(messageToSend, "UTF-8").replace("\\", "")
+ }
- return URLDecoder.decode(messageToSend, "UTF-8").replace("\\", "")
- }
+ fun toEnglish(args: Array<String>) {
+ val message = args.joinToString(" ").removeColor()
- private fun getTranslationFromEnglish(message: String, lang: String): String {
- val url =
- "https://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=$lang&dt=t&q=" +
- URLEncoder.encode(message, "UTF-8")
-
- val layer1 = getJSONResponse(url).asJsonArray
- if (layer1.size() < 1) return "Error!"
- val layer2 = layer1[0] as? JsonArray
-
- val firstSentence = (layer2?.get(0) as? JsonArray)?.get(0).toString()
- var messageToSend = firstSentence.substring(0, firstSentence.length - 1)
- if (layer2 != null) {
- for (sentenceIndex in 1..<layer2.size()) {
- val sentence = (layer2.get(sentenceIndex) as JsonArray).get(0).toString()
- val sentenceWithoutQuotes = sentence.substring(1, sentence.length - 1)
- messageToSend = "$messageToSend$sentenceWithoutQuotes"
- }
- } // The first translated sentence only has 1 extra char at the end, but sentences after it need 1 at the front and 1 at the end removed in the substring
- messageToSend = messageToSend.substring(1, messageToSend.length)
- return URLDecoder.decode(messageToSend, "UTF-8").replace("\\", "")
+ coroutineScope.launch {
+ val translation = getTranslationToEnglish(message)
+ if (translation == "Unable to translate!") ChatUtils.userError("Unable to translate message :( (is it in English?)")
+ else ChatUtils.chat("Found translation: §f$translation")
}
+ }
- fun toEnglish(args: Array<String>) {
- val message = args.joinToString(" ").removeColor()
-
- coroutineScope.launch {
- val translation = getTranslationToEnglish(message)
- if (translation == "Unable to translate!") ChatUtils.userError("Unable to translate message :( (is it in English?)")
- else ChatUtils.chat("Found translation: §f$translation")
- }
+ fun fromEnglish(args: Array<String>) {
+ if (args.size < 2 || args[0].length != 2) { // args[0] is the language code
+ ChatUtils.userError("Usage: /shcopytranslation <two letter language code (at the end of a translation)> <message>")
+ return
}
+ val language = args[0]
+ val message = args.drop(1).joinToString(" ")
- fun fromEnglish(args: Array<String>) {
- if (args.size < 2 || args[0].length != 2) { // args[0] is the language code
- ChatUtils.userError("Usage: /shcopytranslation <two letter language code (at the end of a translation)> <message>")
- return
- }
- val language = args[0]
- val message = args.drop(1).joinToString(" ")
-
- coroutineScope.launch {
- val translation = getTranslationFromEnglish(message, language)
- ChatUtils.chat("Copied translation to clipboard: §f$translation")
- OSUtils.copyToClipboard(translation)
- }
+ coroutineScope.launch {
+ val translation = getTranslationFromEnglish(message, language)
+ ChatUtils.chat("Copied translation to clipboard: §f$translation")
+ OSUtils.copyToClipboard(translation)
}
-
- fun isEnabled() = config.translator
}
+
+ fun isEnabled() = config.translator
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/DamageIndicatorManager.kt b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/DamageIndicatorManager.kt
index 33bb20a52..d41431726 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/DamageIndicatorManager.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/combat/damageindicator/DamageIndicatorManager.kt
@@ -74,6 +74,7 @@ object DamageIndicatorManager {
private val enderSlayerHitsNumberPattern = ".* §[5fd]§l(?<hits>\\d+) Hits?".toPattern()
+
private var data = mapOf<UUID, EntityData>()
private val damagePattern = "[✧✯]?(\\d+[⚔+✧❤♞☄✷ﬗ✯]*)".toPattern()
diff --git a/src/main/java/at/hannibal2/skyhanni/features/event/diana/BurrowWarpHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/event/diana/BurrowWarpHelper.kt
index be8d77a6a..bf362d918 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/event/diana/BurrowWarpHelper.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/event/diana/BurrowWarpHelper.kt
@@ -23,6 +23,7 @@ import kotlin.time.Duration.Companion.seconds
object BurrowWarpHelper {
private val config get() = SkyHanniMod.feature.event.diana
+
var currentWarp: WarpPoint? = null
private var lastWarpTime = SimpleTimeMark.farPast()
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt
index 0aac3e747..03c35ce27 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt
@@ -18,6 +18,7 @@ import at.hannibal2.skyhanni.features.garden.CropType
import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.features.garden.farming.GardenCropSpeed.getSpeed
import at.hannibal2.skyhanni.features.garden.pests.PestType
+import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.test.command.ErrorManager
import at.hannibal2.skyhanni.utils.APIUtil
import at.hannibal2.skyhanni.utils.ChatUtils
@@ -39,7 +40,8 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.seconds
-class FarmingWeightDisplay {
+@SkyHanniModule
+object FarmingWeightDisplay {
@SubscribeEvent
fun onRenderOverlay(event: GuiRenderEvent) {
@@ -102,491 +104,487 @@ class FarmingWeightDisplay {
event.move(34, "garden.eliteFarmingWeights.ETAGoalRank", "garden.eliteFarmingWeights.etaGoalRank")
}
- companion object {
-
- private val config get() = GardenAPI.config.eliteFarmingWeights
- private val localCounter = mutableMapOf<CropType, Long>()
-
- private var display = emptyList<Renderable>()
- private var profileId = ""
- private var lastLeaderboardUpdate = SimpleTimeMark.farPast()
- private var apiError = false
- private var leaderboardPosition = -1
- private var weight = -1.0
- private var localWeight = 0.0
- private var weightPerSecond = -1.0
- private var weightNeedsRecalculating = false
- private var isLoadingWeight = false
- private var isLoadingLeaderboard = false
- private var rankGoal = -1
+ private val config get() = GardenAPI.config.eliteFarmingWeights
+ private val localCounter = mutableMapOf<CropType, Long>()
+
+ private var display = emptyList<Renderable>()
+ private var profileId = ""
+ private var lastLeaderboardUpdate = SimpleTimeMark.farPast()
+ private var apiError = false
+ private var leaderboardPosition = -1
+ private var weight = -1.0
+ private var localWeight = 0.0
+ private var weightPerSecond = -1.0
+ private var weightNeedsRecalculating = false
+ private var isLoadingWeight = false
+ private var isLoadingLeaderboard = false
+ private var rankGoal = -1
+
+ private var nextPlayers = mutableListOf<UpcomingLeaderboardPlayer>()
+ private val nextPlayer get() = nextPlayers.firstOrNull()
+
+ private val recalculate by lazy {
+ ({
+ resetData()
+ })
+ }
- private var nextPlayers = mutableListOf<UpcomingLeaderboardPlayer>()
- private val nextPlayer get() = nextPlayers.firstOrNull()
+ private val eliteWeightApiGson by lazy {
+ BaseGsonBuilder.gson()
+ .registerTypeAdapter(CropType::class.java, SkyHanniTypeAdapters.CROP_TYPE.nullSafe())
+ .registerTypeAdapter(PestType::class.java, SkyHanniTypeAdapters.PEST_TYPE.nullSafe())
+ .create()
+ }
- private val recalculate by lazy {
- ({
- resetData()
- })
- }
+ private val errorMessage by lazy {
+ listOf(
+ Renderable.clickAndHover(
+ "§cFarming Weight error: Cannot load",
+ listOf("§eClick here to reload the data right now!"),
+ onClick = recalculate
+ ), Renderable.clickAndHover(
+ "§cdata from Elite Farmers!",
+ listOf("§eClick here to reload the data right now!"),
+ onClick = recalculate
+ ), Renderable.clickAndHover(
+ "§eRejoin the garden or",
+ listOf("§eClick here to reload the data right now!"),
+ onClick = recalculate
+ ), Renderable.clickAndHover(
+ "§eclick here to fix it.",
+ listOf("§eClick here to reload the data right now!"),
+ onClick = recalculate
+ )
+ )
+ }
- private val eliteWeightApiGson by lazy {
- BaseGsonBuilder.gson()
- .registerTypeAdapter(CropType::class.java, SkyHanniTypeAdapters.CROP_TYPE.nullSafe())
- .registerTypeAdapter(PestType::class.java, SkyHanniTypeAdapters.PEST_TYPE.nullSafe())
- .create()
- }
+ private var lastOpenWebsite = SimpleTimeMark.farPast()
- private val errorMessage by lazy {
- listOf(
- Renderable.clickAndHover(
- "§cFarming Weight error: Cannot load",
- listOf("§eClick here to reload the data right now!"),
- onClick = recalculate
- ), Renderable.clickAndHover(
- "§cdata from Elite Farmers!",
- listOf("§eClick here to reload the data right now!"),
- onClick = recalculate
- ), Renderable.clickAndHover(
- "§eRejoin the garden or",
- listOf("§eClick here to reload the data right now!"),
- onClick = recalculate
- ), Renderable.clickAndHover(
- "§eclick here to fix it.",
- listOf("§eClick here to reload the data right now!"),
- onClick = recalculate
- )
- )
+ private fun update() {
+ if (!isEnabled()) return
+ if (apiError) {
+ display = errorMessage
+ return
}
- private var lastOpenWebsite = SimpleTimeMark.farPast()
-
- private fun update() {
- if (!isEnabled()) return
- if (apiError) {
- display = errorMessage
- return
- }
+ if (weight == -1.0) {
+ if (!isLoadingWeight) {
+ val localProfile = HypixelData.profileName
- if (weight == -1.0) {
- if (!isLoadingWeight) {
- val localProfile = HypixelData.profileName
-
- isLoadingWeight = true
- if (display.isEmpty()) {
- display = Renderable.singeltonString("§6Farming Weight§7: §eLoading..")
- }
- SkyHanniMod.coroutineScope.launch {
- loadWeight(localProfile)
- isLoadingWeight = false
- }
+ isLoadingWeight = true
+ if (display.isEmpty()) {
+ display = Renderable.singeltonString("§6Farming Weight§7: §eLoading..")
+ }
+ SkyHanniMod.coroutineScope.launch {
+ loadWeight(localProfile)
+ isLoadingWeight = false
}
- return
}
+ return
+ }
- val weight = getWeight()
+ val weight = getWeight()
- if (rankGoal == -1) rankGoal = getRankGoal()
- val leaderboard = getLeaderboard()
+ if (rankGoal == -1) rankGoal = getRankGoal()
+ val leaderboard = getLeaderboard()
- val list = mutableListOf<Renderable>()
- list.add(
- Renderable.clickAndHover(
- "§6Farming Weight§7: $weight$leaderboard",
- listOf("§eClick to open your Farming Profile."), onClick = {
- openWebsite(LorenzUtils.getPlayerName())
- }
- )
+ val list = mutableListOf<Renderable>()
+ list.add(
+ Renderable.clickAndHover(
+ "§6Farming Weight§7: $weight$leaderboard",
+ listOf("§eClick to open your Farming Profile."),
+ onClick = { openWebsite(LorenzUtils.getPlayerName()) }
)
+ )
- if (isEtaEnabled() && (weightPerSecond != -1.0 || config.overtakeETAAlways)) {
- getETA()?.let {
- list.add(it)
- }
+ if (isEtaEnabled() && (weightPerSecond != -1.0 || config.overtakeETAAlways)) {
+ getETA()?.let {
+ list.add(it)
}
- display = list
}
+ display = list
+ }
- private fun getLeaderboard(): String {
- if (!config.leaderboard) return ""
-
- // Fetching new leaderboard position every 10.5 minutes
- if (lastLeaderboardUpdate.passedSince() > 10.5.minutes) {
- loadLeaderboardIfAble()
- }
+ private fun getLeaderboard(): String {
+ if (!config.leaderboard) return ""
- return if (leaderboardPosition != -1) {
- val format = leaderboardPosition.addSeparators()
- " §7[§b#$format§7]"
- } else {
- if (isLoadingLeaderboard) " §7[§b#?§7]" else ""
- }
+ // Fetching new leaderboard position every 10.5 minutes
+ if (lastLeaderboardUpdate.passedSince() > 10.5.minutes) {
+ loadLeaderboardIfAble()
}
- private fun getWeight(): String {
- if (weightNeedsRecalculating) {
- val values = calculateCollectionWeight().values
- if (values.isNotEmpty()) {
- localWeight = values.sum()
- weightNeedsRecalculating = false
- }
- }
-
- val totalWeight = (localWeight + weight)
- return "§e" + totalWeight.round(2).addSeparators()
+ return if (leaderboardPosition != -1) {
+ val format = leaderboardPosition.addSeparators()
+ " §7[§b#$format§7]"
+ } else {
+ if (isLoadingLeaderboard) " §7[§b#?§7]" else ""
}
+ }
- private fun getRankGoal(): Int {
- val value = config.etaGoalRank
- var goal = 10000
-
- // Check that the provided string is valid
- val parsed = value.toIntOrNull() ?: 0
- if (parsed < 1 || parsed > goal) {
- ChatUtils.chatAndOpenConfig(
- "Invalid Farming Weight Overtake Goal! Click here to edit the Overtake Goal config value " +
- "to a valid number [1-10000] to use this feature!",
- GardenAPI.config.eliteFarmingWeights::etaGoalRank
- )
- config.etaGoalRank = goal.toString()
- } else {
- goal = parsed
- }
-
- // Fetch the positions again if the goal was changed
- if (rankGoal != goal) {
- loadLeaderboardIfAble()
+ private fun getWeight(): String {
+ if (weightNeedsRecalculating) {
+ val values = calculateCollectionWeight().values
+ if (values.isNotEmpty()) {
+ localWeight = values.sum()
+ weightNeedsRecalculating = false
}
-
- return goal
}
- private fun getETA(): Renderable? {
- if (weight < 0) return null
+ val totalWeight = (localWeight + weight)
+ return "§e" + totalWeight.round(2).addSeparators()
+ }
- val nextPlayer = nextPlayer ?: return Renderable.clickAndHover(
- "§cWaiting for leaderboard update...",
- listOf("§eClick here to load new data right now!"),
- onClick = recalculate
+ private fun getRankGoal(): Int {
+ val value = config.etaGoalRank
+ var goal = 10000
+
+ // Check that the provided string is valid
+ val parsed = value.toIntOrNull() ?: 0
+ if (parsed < 1 || parsed > goal) {
+ ChatUtils.chatAndOpenConfig(
+ "Invalid Farming Weight Overtake Goal! Click here to edit the Overtake Goal config value " +
+ "to a valid number [1-10000] to use this feature!",
+ GardenAPI.config.eliteFarmingWeights::etaGoalRank
)
- val showRankGoal = leaderboardPosition == -1 || leaderboardPosition > rankGoal
- var nextName =
- if (showRankGoal) "#$rankGoal" else nextPlayer.name
+ config.etaGoalRank = goal.toString()
+ } else {
+ goal = parsed
+ }
- val totalWeight = (localWeight + weight)
- var weightUntilOvertake = nextPlayer.weight - totalWeight
+ // Fetch the positions again if the goal was changed
+ if (rankGoal != goal) {
+ loadLeaderboardIfAble()
+ }
- if (weightUntilOvertake < 0) {
- if (weightPerSecond > 0) {
- farmingChatMessage("You passed §b$nextName §ein the Farming Weight Leaderboard!")
- }
+ return goal
+ }
- // Lower leaderboard position
- if (leaderboardPosition == -1) {
- leaderboardPosition = 10000
- } else {
- leaderboardPosition--
- }
- GardenAPI.storage?.farmingWeight?.lastFarmingWeightLeaderboard =
- leaderboardPosition
+ private fun getETA(): Renderable? {
+ if (weight < 0) return null
- // Remove passed player to present the next one
- nextPlayers.removeFirst()
+ val nextPlayer = nextPlayer ?: return Renderable.clickAndHover(
+ "§cWaiting for leaderboard update...",
+ listOf("§eClick here to load new data right now!"),
+ onClick = recalculate
+ )
+ val showRankGoal = leaderboardPosition == -1 || leaderboardPosition > rankGoal
+ var nextName =
+ if (showRankGoal) "#$rankGoal" else nextPlayer.name
- // Display waiting message if nextPlayers list is empty
- // Update values to next player
- nextName = nextPlayer.name
- weightUntilOvertake = nextPlayer.weight - totalWeight
- }
+ val totalWeight = (localWeight + weight)
+ var weightUntilOvertake = nextPlayer.weight - totalWeight
- if (nextPlayer.weight == 0.0) {
- return Renderable.clickAndHover(
- "§cRejoin the garden to show ETA!",
- listOf("Click here to calculate the data right now!"),
- onClick = recalculate
- )
+ if (weightUntilOvertake < 0) {
+ if (weightPerSecond > 0) {
+ farmingChatMessage("You passed §b$nextName §ein the Farming Weight Leaderboard!")
}
- val timeFormat = if (weightPerSecond != -1.0) {
- val timeTillOvertake = (weightUntilOvertake / weightPerSecond) * 1000
- val format = TimeUtils.formatDuration(timeTillOvertake.toLong())
- " §7(§b$format§7)"
- } else ""
-
- val weightFormat = weightUntilOvertake.round(2).addSeparators()
- val text = "§e$weightFormat$timeFormat §7behind §b$nextName"
- return if (showRankGoal) {
- Renderable.string(text)
+ // Lower leaderboard position
+ if (leaderboardPosition == -1) {
+ leaderboardPosition = 10000
} else {
- Renderable.clickAndHover(
- text,
- listOf("§eClick to open the Farming Profile of §b$nextName."),
- onClick = { openWebsite(nextName) }
- )
+ leaderboardPosition--
}
- }
+ GardenAPI.storage?.farmingWeight?.lastFarmingWeightLeaderboard =
+ leaderboardPosition
- private fun resetData() {
- apiError = false
- // We ask both api endpoints after every world switch
- weight = -1.0
- weightPerSecond = -1.0
+ // Remove passed player to present the next one
+ nextPlayers.removeFirst()
- leaderboardPosition = -1
- weightNeedsRecalculating = true
- lastLeaderboardUpdate = SimpleTimeMark.farPast()
-
- nextPlayers.clear()
- rankGoal = -1
+ // Display waiting message if nextPlayers list is empty
+ // Update values to next player
+ nextName = nextPlayer.name
+ weightUntilOvertake = nextPlayer.weight - totalWeight
+ }
- localCounter.clear()
+ if (nextPlayer.weight == 0.0) {
+ return Renderable.clickAndHover(
+ "§cRejoin the garden to show ETA!",
+ listOf("Click here to calculate the data right now!"),
+ onClick = recalculate
+ )
}
- private fun farmingChatMessage(message: String) {
- ChatUtils.hoverableChat(
- message,
- listOf(
- "§eClick to open your Farming Weight",
- "§eprofile on §celitebot.dev",
- ),
- "shfarmingprofile ${LorenzUtils.getPlayerName()}"
+ val timeFormat = if (weightPerSecond != -1.0) {
+ val timeTillOvertake = (weightUntilOvertake / weightPerSecond) * 1000
+ val format = TimeUtils.formatDuration(timeTillOvertake.toLong())
+ " §7(§b$format§7)"
+ } else ""
+
+ val weightFormat = weightUntilOvertake.round(2).addSeparators()
+ val text = "§e$weightFormat$timeFormat §7behind §b$nextName"
+ return if (showRankGoal) {
+ Renderable.string(text)
+ } else {
+ Renderable.clickAndHover(
+ text,
+ listOf("§eClick to open the Farming Profile of §b$nextName."),
+ onClick = { openWebsite(nextName) }
)
}
+ }
- private fun isEnabled() = ((OutsideSbFeature.FARMING_WEIGHT.isSelected() && !LorenzUtils.inSkyBlock) ||
- (LorenzUtils.inSkyBlock && (GardenAPI.inGarden() || config.showOutsideGarden))) && config.display
+ private fun resetData() {
+ apiError = false
+ // We ask both api endpoints after every world switch
+ weight = -1.0
+ weightPerSecond = -1.0
- private fun isEtaEnabled() = config.overtakeETA
+ leaderboardPosition = -1
+ weightNeedsRecalculating = true
+ lastLeaderboardUpdate = SimpleTimeMark.farPast()
+
+ nextPlayers.clear()
+ rankGoal = -1
- fun addCrop(crop: CropType, addedCounter: Int) {
- val before = getExactWeight()
- localCounter[crop] = crop.getLocalCounter() + addedCounter
- val after = getExactWeight()
+ localCounter.clear()
+ }
- updateWeightPerSecond(crop, before, after, addedCounter)
+ private fun farmingChatMessage(message: String) {
+ ChatUtils.hoverableChat(
+ message,
+ listOf(
+ "§eClick to open your Farming Weight",
+ "§eprofile on §celitebot.dev",
+ ),
+ "shfarmingprofile ${LorenzUtils.getPlayerName()}"
+ )
+ }
- weightNeedsRecalculating = true
- }
+ private fun isEnabled() = ((OutsideSbFeature.FARMING_WEIGHT.isSelected() && !LorenzUtils.inSkyBlock) ||
+ (LorenzUtils.inSkyBlock && (GardenAPI.inGarden() || config.showOutsideGarden))) && config.display
- private fun updateWeightPerSecond(crop: CropType, before: Double, after: Double, diff: Int) {
- val speed = crop.getSpeed() ?: return
- val weightDiff = (after - before) * 1000
- weightPerSecond = weightDiff / diff * speed / 1000
- }
+ private fun isEtaEnabled() = config.overtakeETA
- private fun getExactWeight(): Double {
- val values = calculateCollectionWeight().values
- return if (values.isNotEmpty()) {
- values.sum()
- } else 0.0
- }
+ fun addCrop(crop: CropType, addedCounter: Int) {
+ val before = getExactWeight()
+ localCounter[crop] = crop.getLocalCounter() + addedCounter
+ val after = getExactWeight()
- private fun loadLeaderboardIfAble() {
- if (isLoadingLeaderboard) return
- isLoadingLeaderboard = true
+ updateWeightPerSecond(crop, before, after, addedCounter)
- SkyHanniMod.coroutineScope.launch {
- val wasNotLoaded = leaderboardPosition == -1
- leaderboardPosition = loadLeaderboardPosition()
- if (wasNotLoaded && config.showLbChange) {
- checkOffScreenLeaderboardChanges()
- }
- GardenAPI.storage?.farmingWeight?.lastFarmingWeightLeaderboard =
- leaderboardPosition
- lastLeaderboardUpdate = SimpleTimeMark.now()
- isLoadingLeaderboard = false
- }
- }
+ weightNeedsRecalculating = true
+ }
- private fun checkOffScreenLeaderboardChanges() {
- val profileSpecific = ProfileStorageData.profileSpecific ?: return
- val oldPosition = profileSpecific.garden.farmingWeight.lastFarmingWeightLeaderboard
+ private fun updateWeightPerSecond(crop: CropType, before: Double, after: Double, diff: Int) {
+ val speed = crop.getSpeed() ?: return
+ val weightDiff = (after - before) * 1000
+ weightPerSecond = weightDiff / diff * speed / 1000
+ }
- if (oldPosition <= 0) return
- if (leaderboardPosition <= 0) return
+ private fun getExactWeight(): Double {
+ val values = calculateCollectionWeight().values
+ return if (values.isNotEmpty()) {
+ values.sum()
+ } else 0.0
+ }
- val diff = leaderboardPosition - oldPosition
- if (diff == 0) return
+ private fun loadLeaderboardIfAble() {
+ if (isLoadingLeaderboard) return
+ isLoadingLeaderboard = true
- if (diff > 0) {
- showLbChange("§cdropped ${StringUtils.pluralize(diff, "place", withNumber = true)}", oldPosition)
- } else {
- showLbChange("§arisen ${StringUtils.pluralize(-diff, "place", withNumber = true)}", oldPosition)
+ SkyHanniMod.coroutineScope.launch {
+ val wasNotLoaded = leaderboardPosition == -1
+ leaderboardPosition = loadLeaderboardPosition()
+ if (wasNotLoaded && config.showLbChange) {
+ checkOffScreenLeaderboardChanges()
}
+ GardenAPI.storage?.farmingWeight?.lastFarmingWeightLeaderboard =
+ leaderboardPosition
+ lastLeaderboardUpdate = SimpleTimeMark.now()
+ isLoadingLeaderboard = false
}
+ }
- private fun showLbChange(direction: String, oldPosition: Int) {
- farmingChatMessage(
- "§7Since your last visit to the §aGarden§7, " +
- "you have $direction §7on the §dFarming Leaderboard§7. " +
- "§7(§e#${oldPosition.addSeparators()} §7-> §e#${leaderboardPosition.addSeparators()}§7)"
- )
+ private fun checkOffScreenLeaderboardChanges() {
+ val profileSpecific = ProfileStorageData.profileSpecific ?: return
+ val oldPosition = profileSpecific.garden.farmingWeight.lastFarmingWeightLeaderboard
+
+ if (oldPosition <= 0) return
+ if (leaderboardPosition <= 0) return
+
+ val diff = leaderboardPosition - oldPosition
+ if (diff == 0) return
+
+ if (diff > 0) {
+ showLbChange("§cdropped ${StringUtils.pluralize(diff, "place", withNumber = true)}", oldPosition)
+ } else {
+ showLbChange("§arisen ${StringUtils.pluralize(-diff, "place", withNumber = true)}", oldPosition)
}
+ }
- private fun loadLeaderboardPosition(): Int {
- val uuid = LorenzUtils.getPlayerUuid()
+ private fun showLbChange(direction: String, oldPosition: Int) {
+ farmingChatMessage(
+ "§7Since your last visit to the §aGarden§7, " +
+ "you have $direction §7on the §dFarming Leaderboard§7. " +
+ "§7(§e#${oldPosition.addSeparators()} §7-> §e#${leaderboardPosition.addSeparators()}§7)"
+ )
+ }
- val includeUpcoming = if (isEtaEnabled()) "?includeUpcoming=true" else ""
- val goalRank = getRankGoal() + 1 // API returns upcoming players as if you were at this rank already
- val atRank = if (isEtaEnabled() && goalRank != 10001) "&atRank=$goalRank" else ""
+ private fun loadLeaderboardPosition(): Int {
+ val uuid = LorenzUtils.getPlayerUuid()
- val url = "https://api.elitebot.dev/leaderboard/rank/farmingweight/$uuid/$profileId$includeUpcoming$atRank"
- val apiResponse = APIUtil.getJSONResponse(url)
+ val includeUpcoming = if (isEtaEnabled()) "?includeUpcoming=true" else ""
+ val goalRank = getRankGoal() + 1 // API returns upcoming players as if you were at this rank already
+ val atRank = if (isEtaEnabled() && goalRank != 10001) "&atRank=$goalRank" else ""
- try {
- val apiData = toEliteLeaderboardJson(apiResponse).data
+ val url = "https://api.elitebot.dev/leaderboard/rank/farmingweight/$uuid/$profileId$includeUpcoming$atRank"
+ val apiResponse = APIUtil.getJSONResponse(url)
- if (isEtaEnabled()) {
- nextPlayers.clear()
- apiData.upcomingPlayers.forEach { nextPlayers.add(it) }
- }
+ try {
+ val apiData = toEliteLeaderboardJson(apiResponse).data
- return apiData.rank
- } catch (e: Exception) {
- ErrorManager.logErrorWithData(
- e, "Error getting weight leaderboard position",
- "url" to url,
- "apiResponse" to apiResponse
- )
+ if (isEtaEnabled()) {
+ nextPlayers.clear()
+ apiData.upcomingPlayers.forEach { nextPlayers.add(it) }
}
- return -1
- }
- private fun toEliteLeaderboardJson(obj: JsonObject): EliteLeaderboardJson {
- val jsonObject = JsonObject()
- jsonObject.add("data", obj)
- return eliteWeightApiGson.fromJson<EliteLeaderboardJson>(jsonObject)
+ return apiData.rank
+ } catch (e: Exception) {
+ ErrorManager.logErrorWithData(
+ e, "Error getting weight leaderboard position",
+ "url" to url,
+ "apiResponse" to apiResponse
+ )
}
+ return -1
+ }
- private fun loadWeight(localProfile: String) {
- val uuid = LorenzUtils.getPlayerUuid()
- val url = "https://api.elitebot.dev/weight/$uuid"
- val apiResponse = APIUtil.getJSONResponse(url)
+ private fun toEliteLeaderboardJson(obj: JsonObject): EliteLeaderboardJson {
+ val jsonObject = JsonObject()
+ jsonObject.add("data", obj)
+ return eliteWeightApiGson.fromJson<EliteLeaderboardJson>(jsonObject)
+ }
- var error: Throwable? = null
+ private fun loadWeight(localProfile: String) {
+ val uuid = LorenzUtils.getPlayerUuid()
+ val url = "https://api.elitebot.dev/weight/$uuid"
+ val apiResponse = APIUtil.getJSONResponse(url)
- try {
+ var error: Throwable? = null
- val apiData = eliteWeightApiGson.fromJson<ElitePlayerWeightJson>(apiResponse)
+ try {
- val selectedProfileId = apiData.selectedProfileId
- var selectedProfileEntry = apiData.profiles.find { it.profileId == selectedProfileId }
+ val apiData = eliteWeightApiGson.fromJson<ElitePlayerWeightJson>(apiResponse)
- if (selectedProfileEntry == null || (selectedProfileEntry.profileName.lowercase() != localProfile && localProfile != "")) {
- selectedProfileEntry = apiData.profiles.find { it.profileName.lowercase() == localProfile }
- }
+ val selectedProfileId = apiData.selectedProfileId
+ var selectedProfileEntry = apiData.profiles.find { it.profileId == selectedProfileId }
- if (selectedProfileEntry != null) {
- profileId = selectedProfileEntry.profileId
- weight = selectedProfileEntry.totalWeight
+ if (selectedProfileEntry == null || (selectedProfileEntry.profileName.lowercase() != localProfile && localProfile != "")) {
+ selectedProfileEntry = apiData.profiles.find { it.profileName.lowercase() == localProfile }
+ }
- localCounter.clear()
- weightNeedsRecalculating = true
- return
- }
+ if (selectedProfileEntry != null) {
+ profileId = selectedProfileEntry.profileId
+ weight = selectedProfileEntry.totalWeight
- } catch (e: Exception) {
- error = e
+ localCounter.clear()
+ weightNeedsRecalculating = true
+ return
}
- apiError = true
- ErrorManager.logErrorWithData(
- error ?: IllegalStateException("Error loading user farming weight"),
- "Error loading user farming weight\n" +
- "§eLoading the farming weight data from elitebot.dev failed!\n" +
- "§eYou can re-enter the garden to try to fix the problem.\n" +
- "§cIf this message repeats, please report it on Discord!\n",
- "url" to url,
- "apiResponse" to apiResponse,
- "localProfile" to localProfile
- )
+ } catch (e: Exception) {
+ error = e
}
+ apiError = true
+
+ ErrorManager.logErrorWithData(
+ error ?: IllegalStateException("Error loading user farming weight"),
+ "Error loading user farming weight\n" +
+ "§eLoading the farming weight data from elitebot.dev failed!\n" +
+ "§eYou can re-enter the garden to try to fix the problem.\n" +
+ "§cIf this message repeats, please report it on Discord!\n",
+ "url" to url,
+ "apiResponse" to apiResponse,
+ "localProfile" to localProfile
+ )
+ }
- private fun calculateCollectionWeight(): MutableMap<CropType, Double> {
- val weightPerCrop = mutableMapOf<CropType, Double>()
- var totalWeight = 0.0
- for (crop in CropType.entries) {
- val weight = crop.getLocalCounter() / crop.getFactor()
- weightPerCrop[crop] = weight
- totalWeight += weight
- }
- if (totalWeight > 0) {
- weightPerCrop[CropType.MUSHROOM] = specialMushroomWeight(weightPerCrop, totalWeight)
- }
- return weightPerCrop
+ private fun calculateCollectionWeight(): MutableMap<CropType, Double> {
+ val weightPerCrop = mutableMapOf<CropType, Double>()
+ var totalWeight = 0.0
+ for (crop in CropType.entries) {
+ val weight = crop.getLocalCounter() / crop.getFactor()
+ weightPerCrop[crop] = weight
+ totalWeight += weight
}
+ if (totalWeight > 0) {
+ weightPerCrop[CropType.MUSHROOM] = specialMushroomWeight(weightPerCrop, totalWeight)
+ }
+ return weightPerCrop
+ }
- private fun specialMushroomWeight(weightPerCrop: MutableMap<CropType, Double>, totalWeight: Double): Double {
- val cactusWeight = weightPerCrop[CropType.CACTUS]!!
- val sugarCaneWeight = weightPerCrop[CropType.SUGAR_CANE]!!
- val doubleBreakRatio = (cactusWeight + sugarCaneWeight) / totalWeight
- val normalRatio = (totalWeight - cactusWeight - sugarCaneWeight) / totalWeight
+ private fun specialMushroomWeight(weightPerCrop: MutableMap<CropType, Double>, totalWeight: Double): Double {
+ val cactusWeight = weightPerCrop[CropType.CACTUS]!!
+ val sugarCaneWeight = weightPerCrop[CropType.SUGAR_CANE]!!
+ val doubleBreakRatio = (cactusWeight + sugarCaneWeight) / totalWeight
+ val normalRatio = (totalWeight - cactusWeight - sugarCaneWeight) / totalWeight
- val mushroomFactor = CropType.MUSHROOM.getFactor()
- val mushroomCollection = CropType.MUSHROOM.getLocalCounter()
- return doubleBreakRatio * (mushroomCollection / (2 * mushroomFactor)) + normalRatio * (mushroomCollection / mushroomFactor)
- }
+ val mushroomFactor = CropType.MUSHROOM.getFactor()
+ val mushroomCollection = CropType.MUSHROOM.getLocalCounter()
+ return doubleBreakRatio * (mushroomCollection / (2 * mushroomFactor)) + normalRatio * (mushroomCollection / mushroomFactor)
+ }
- private fun CropType.getLocalCounter() = localCounter[this] ?: 0L
+ private fun CropType.getLocalCounter() = localCounter[this] ?: 0L
- private fun CropType.getFactor(): Double {
- return cropWeight[this] ?: backupCropWeights[this] ?: error("Crop $this not in backupFactors!")
- }
+ private fun CropType.getFactor(): Double {
+ return cropWeight[this] ?: backupCropWeights[this] ?: error("Crop $this not in backupFactors!")
+ }
- fun lookUpCommand(it: Array<String>) {
- val name = if (it.size == 1) it[0] else LorenzUtils.getPlayerName()
- openWebsite(name, ignoreCooldown = true)
- }
+ fun lookUpCommand(it: Array<String>) {
+ val name = if (it.size == 1) it[0] else LorenzUtils.getPlayerName()
+ openWebsite(name, ignoreCooldown = true)
+ }
- private var lastName = ""
+ private var lastName = ""
- private fun openWebsite(name: String, ignoreCooldown: Boolean = false) {
- if (!ignoreCooldown && lastOpenWebsite.passedSince() < 5.seconds && name == lastName) return
- lastOpenWebsite = SimpleTimeMark.now()
- lastName = name
+ private fun openWebsite(name: String, ignoreCooldown: Boolean = false) {
+ if (!ignoreCooldown && lastOpenWebsite.passedSince() < 5.seconds && name == lastName) return
+ lastOpenWebsite = SimpleTimeMark.now()
+ lastName = name
- OSUtils.openBrowser("https://elitebot.dev/@$name/")
- ChatUtils.chat("Opening Farming Profile of player §b$name")
- }
+ OSUtils.openBrowser("https://elitebot.dev/@$name/")
+ ChatUtils.chat("Opening Farming Profile of player §b$name")
+ }
- private val cropWeight = mutableMapOf<CropType, Double>()
- private var attemptingCropWeightFetch = false
- private var hasFetchedCropWeights = false
-
- private fun getCropWeights() {
- if (attemptingCropWeightFetch || hasFetchedCropWeights) return
- attemptingCropWeightFetch = true
- val url = "https://api.elitebot.dev/weights/all"
- val apiResponse = APIUtil.getJSONResponse(url)
-
- try {
- val apiData = eliteWeightApiGson.fromJson<EliteWeightsJson>(apiResponse)
- apiData.crops
- for (crop in apiData.crops) {
- cropWeight[crop.key] = crop.value
- }
- hasFetchedCropWeights = true
- } catch (e: Exception) {
- ErrorManager.logErrorWithData(
- e, "Error getting crop weights from elitebot.dev",
- "apiResponse" to apiResponse
- )
+ private val cropWeight = mutableMapOf<CropType, Double>()
+ private var attemptingCropWeightFetch = false
+ private var hasFetchedCropWeights = false
+
+ private fun getCropWeights() {
+ if (attemptingCropWeightFetch || hasFetchedCropWeights) return
+ attemptingCropWeightFetch = true
+ val url = "https://api.elitebot.dev/weights/all"
+ val apiResponse = APIUtil.getJSONResponse(url)
+
+ try {
+ val apiData = eliteWeightApiGson.fromJson<EliteWeightsJson>(apiResponse)
+ apiData.crops
+ for (crop in apiData.crops) {
+ cropWeight[crop.key] = crop.value
}
- }
-
- // still needed when first joining garden and if they cant make https requests
- private val backupCropWeights by lazy {
- mapOf(
- CropType.WHEAT to 100_000.0,
- CropType.CARROT to 302_061.86,
- CropType.POTATO to 300_000.0,
- CropType.SUGAR_CANE to 200_000.0,
- CropType.NETHER_WART to 250_000.0,
- CropType.PUMPKIN to 98_284.71,
- CropType.MELON to 485_308.47,
- CropType.MUSHROOM to 90_178.06,
- CropType.COCOA_BEANS to 267_174.04,
- CropType.CACTUS to 177_254.45,
+ hasFetchedCropWeights = true
+ } catch (e: Exception) {
+ ErrorManager.logErrorWithData(
+ e, "Error getting crop weights from elitebot.dev",
+ "apiResponse" to apiResponse
)
}
}
+
+ // still needed when first joining garden and if they cant make https requests
+ private val backupCropWeights by lazy {
+ mapOf(
+ CropType.WHEAT to 100_000.0,
+ CropType.CARROT to 302_061.86,
+ CropType.POTATO to 300_000.0,
+ CropType.SUGAR_CANE to 200_000.0,
+ CropType.NETHER_WART to 250_000.0,
+ CropType.PUMPKIN to 98_284.71,
+ CropType.MELON to 485_308.47,
+ CropType.MUSHROOM to 90_178.06,
+ CropType.COCOA_BEANS to 267_174.04,
+ CropType.CACTUS to 177_254.45,
+ )
+ }
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/ScoreboardElements.kt b/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/ScoreboardElements.kt
index 28e5151d4..aae1e7086 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/ScoreboardElements.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/gui/customscoreboard/ScoreboardElements.kt
@@ -5,8 +5,8 @@ import at.hannibal2.skyhanni.config.features.gui.customscoreboard.ArrowConfig.Ar
import at.hannibal2.skyhanni.config.features.gui.customscoreboard.DisplayConfig.PowderDisplay
import at.hannibal2.skyhanni.data.BitsAPI
import at.hannibal2.skyhanni.data.HypixelData
-import at.hannibal2.skyhanni.data.HypixelData.Companion.getMaxPlayersForCurrentServer
-import at.hannibal2.skyhanni.data.HypixelData.Companion.getPlayersOnCurrentServer
+import at.hannibal2.skyhanni.data.HypixelData.getMaxPlayersForCurrentServer
+import at.hannibal2.skyhanni.data.HypixelData.getPlayersOnCurrentServer
import at.hannibal2.skyhanni.data.IslandType
import at.hannibal2.skyhanni.data.MaxwellAPI
import at.hannibal2.skyhanni.data.MayorAPI
diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/CollectionTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/CollectionTracker.kt
index 2b749c3a6..ffc260723 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/misc/CollectionTracker.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/misc/CollectionTracker.kt
@@ -4,6 +4,7 @@ import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.api.CollectionAPI
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.LorenzTickEvent
+import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.utils.ChatUtils
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
@@ -23,165 +24,163 @@ import net.minecraft.client.Minecraft
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import java.util.Collections
-class CollectionTracker {
+@SkyHanniModule
+object CollectionTracker {
- private val RECENT_GAIN_TIME = 1_500
+ private const val RECENT_GAIN_TIME = 1_500
- companion object {
+ private var display = emptyList<List<Any>>()
- private var display = emptyList<List<Any>>()
+ private var itemName = ""
+ private var internalName: NEUInternalName? = null
+ private var itemAmount = -1L
+ private var goalAmount = -1L
- private var itemName = ""
- private var internalName: NEUInternalName? = null
- private var itemAmount = -1L
- private var goalAmount = -1L
+ private var lastAmountInInventory = -1
- private var lastAmountInInventory = -1
+ private var recentGain = 0
+ private var lastGainTime = -1L
- private var recentGain = 0
- private var lastGainTime = -1L
-
- fun command(args: Array<String>) {
- if (args.isEmpty()) {
- if (internalName == null) {
- ChatUtils.userError("/shtrackcollection <item name> [goal amount]")
- return
- }
- ChatUtils.chat("Stopped collection tracker.")
- resetData()
+ fun command(args: Array<String>) {
+ if (args.isEmpty()) {
+ if (internalName == null) {
+ ChatUtils.userError("/shtrackcollection <item name> [goal amount]")
return
}
+ ChatUtils.chat("Stopped collection tracker.")
+ resetData()
+ return
+ }
- val lastArg = args.last()
-
- val nameArgs = if (lastArg.isFormatNumber()) {
- val goal = lastArg.formatLong()
- if (goal <= 0) {
- ChatUtils.chat("Invalid Amount for Goal.")
- return
- }
- goalAmount = goal
- args.dropLast(1).toTypedArray()
- } else {
- goalAmount = -1L
- args
- }
+ val lastArg = args.last()
- val rawName = fixTypo(nameArgs.joinToString(" ").lowercase().replace("_", " "))
- if (rawName == "gemstone") {
- ChatUtils.userError("Gemstone collection is not supported!")
- return
- } else if (rawName == "mushroom") {
- ChatUtils.userError("Mushroom collection is not supported!")
+ val nameArgs = if (lastArg.isFormatNumber()) {
+ val goal = lastArg.formatLong()
+ if (goal <= 0) {
+ ChatUtils.chat("Invalid Amount for Goal.")
return
}
+ goalAmount = goal
+ args.dropLast(1).toTypedArray()
+ } else {
+ goalAmount = -1L
+ args
+ }
- val foundInternalName = NEUInternalName.fromItemNameOrNull(rawName)
- if (foundInternalName == null) {
- ChatUtils.userError("Item '$rawName' does not exist!")
- return
- }
+ val rawName = fixTypo(nameArgs.joinToString(" ").lowercase().replace("_", " "))
+ if (rawName == "gemstone") {
+ ChatUtils.userError("Gemstone collection is not supported!")
+ return
+ } else if (rawName == "mushroom") {
+ ChatUtils.userError("Mushroom collection is not supported!")
+ return
+ }
- val stack = foundInternalName.getItemStackOrNull()
- if (stack == null) {
- ChatUtils.userError("Item '$rawName' does not exist!")
- return
- }
- setNewCollection(foundInternalName, stack.name.removeColor())
+ val foundInternalName = NEUInternalName.fromItemNameOrNull(rawName)
+ if (foundInternalName == null) {
+ ChatUtils.userError("Item '$rawName' does not exist!")
+ return
}
- private fun fixTypo(rawName: String) = when (rawName) {
- "carrots" -> "carrot"
- "melons" -> "melon"
- "seed" -> "seeds"
- "iron" -> "iron ingot"
- "gold" -> "gold ingot"
- "sugar" -> "sugar cane"
- "cocoa bean", "cocoa" -> "cocoa beans"
- "lapis" -> "lapis lazuli"
- "cacti" -> "cactus"
- "pumpkins" -> "pumpkin"
- "potatoes" -> "potato"
- "nether warts", "wart", "warts" -> "nether wart"
- "stone" -> "cobblestone"
- "red mushroom", "brown mushroom", "mushrooms" -> "mushroom"
- "gemstones" -> "gemstone"
- "caducous" -> "caducous stem"
- "agaricus" -> "agaricus cap"
- "quartz" -> "nether quartz"
- "glowstone" -> "glowstone dust"
-
- else -> rawName
+ val stack = foundInternalName.getItemStackOrNull()
+ if (stack == null) {
+ ChatUtils.userError("Item '$rawName' does not exist!")
+ return
}
+ setNewCollection(foundInternalName, stack.name.removeColor())
+ }
- private fun setNewCollection(internalName: NEUInternalName, name: String) {
- val foundAmount = CollectionAPI.getCollectionCounter(internalName)
- if (foundAmount == null) {
- ChatUtils.userError("$name collection not found. Try to open the collection inventory!")
- return
- }
- this.internalName = internalName
- itemName = name
- itemAmount = foundAmount
+ private fun fixTypo(rawName: String) = when (rawName) {
+ "carrots" -> "carrot"
+ "melons" -> "melon"
+ "seed" -> "seeds"
+ "iron" -> "iron ingot"
+ "gold" -> "gold ingot"
+ "sugar" -> "sugar cane"
+ "cocoa bean", "cocoa" -> "cocoa beans"
+ "lapis" -> "lapis lazuli"
+ "cacti" -> "cactus"
+ "pumpkins" -> "pumpkin"
+ "potatoes" -> "potato"
+ "nether warts", "wart", "warts" -> "nether wart"
+ "stone" -> "cobblestone"
+ "red mushroom", "brown mushroom", "mushrooms" -> "mushroom"
+ "gemstones" -> "gemstone"
+ "caducous" -> "caducous stem"
+ "agaricus" -> "agaricus cap"
+ "quartz" -> "nether quartz"
+ "glowstone" -> "glowstone dust"
+
+ else -> rawName
+ }
- lastAmountInInventory = countCurrentlyInInventory()
- updateDisplay()
- ChatUtils.chat("Started tracking $itemName §ecollection.")
+ private fun setNewCollection(internalName: NEUInternalName, name: String) {
+ val foundAmount = CollectionAPI.getCollectionCounter(internalName)
+ if (foundAmount == null) {
+ ChatUtils.userError("$name collection not found. Try to open the collection inventory!")
+ return
}
+ this.internalName = internalName
+ itemName = name
+ itemAmount = foundAmount
- private fun resetData() {
- itemAmount = -1L
- goalAmount = -1L
- internalName = null
-
- lastAmountInInventory = -1
- display = emptyList()
+ lastAmountInInventory = countCurrentlyInInventory()
+ updateDisplay()
+ ChatUtils.chat("Started tracking $itemName §ecollection.")
+ }
- recentGain = 0
- }
+ private fun resetData() {
+ itemAmount = -1L
+ goalAmount = -1L
+ internalName = null
- private fun updateDisplay() {
- val format = itemAmount.addSeparators()
+ lastAmountInInventory = -1
+ display = emptyList()
- var gainText = ""
- if (recentGain != 0) {
- gainText = "§a+" + recentGain.addSeparators()
- }
+ recentGain = 0
+ }
- if (goalAmount != -1L && itemAmount >= goalAmount) {
- ChatUtils.chat("Collection goal of §a${goalAmount.addSeparators()} reached!")
- goalAmount = -1L
- }
+ private fun updateDisplay() {
+ val format = itemAmount.addSeparators()
- val goal = if (goalAmount == -1L) "" else " §f/ §b${goalAmount.addSeparators()} §f(§a${
- itemAmount.percentWithColorCode(goalAmount, 1)
- }§f)"
+ var gainText = ""
+ if (recentGain != 0) {
+ gainText = "§a+" + recentGain.addSeparators()
+ }
- display = Collections.singletonList(buildList {
- internalName?.let {
- add(it.getItemStack())
- }
- add("$itemName collection: §e$format$goal $gainText")
- })
+ if (goalAmount != -1L && itemAmount >= goalAmount) {
+ ChatUtils.chat("Collection goal of §a${goalAmount.addSeparators()} reached!")
+ goalAmount = -1L
}
- private fun countCurrentlyInInventory(): Int {
- val cactus = "CACTUS".asInternalName()
- val cactusGreen = "INK_SACK-2".asInternalName()
- return InventoryUtils.countItemsInLowerInventory {
- if (internalName == cactus && it.getInternalName() == cactusGreen) {
- return@countItemsInLowerInventory true
- }
- it.getInternalName() == internalName
+ val goal = if (goalAmount == -1L) "" else " §f/ §b${goalAmount.addSeparators()} §f(§a${
+ itemAmount.percentWithColorCode(goalAmount, 1)
+ }§f)"
+
+ display = Collections.singletonList(buildList {
+ internalName?.let {
+ add(it.getItemStack())
+ }
+ add("$itemName collection: §e$format$goal $gainText")
+ })
+ }
+
+ private fun countCurrentlyInInventory(): Int {
+ val cactus = "CACTUS".asInternalName()
+ val cactusGreen = "INK_SACK-2".asInternalName()
+ return InventoryUtils.countItemsInLowerInventory {
+ if (internalName == cactus && it.getInternalName() == cactusGreen) {
+ return@countItemsInLowerInventory true
}
+ it.getInternalName() == internalName
}
+ }
- fun handleTabComplete(command: String): List<String>? {
- if (command != "shtrackcollection") return null
+ fun handleTabComplete(command: String): List<String>? {
+ if (command != "shtrackcollection") return null
- return CollectionAPI.collectionValue.keys.mapNotNull { it.getItemStackOrNull() }
- .map { it.displayName.removeColor().replace(" ", "_") }
- }
+ return CollectionAPI.collectionValue.keys.mapNotNull { it.getItemStackOrNull() }
+ .map { it.displayName.removeColor().replace(" ", "_") }
}
@SubscribeEvent