diff options
author | HiZe_ <superhize@hotmail.com> | 2023-07-04 13:02:14 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-04 13:02:14 +0200 |
commit | dd1dc872a97dcc14fe7842fc69c1bd34b44223fe (patch) | |
tree | 9b7d0d84b3503b164e8a6bb21d66f9ad56fe3640 | |
parent | eb8a96099565844940b2d2614768406af5697239 (diff) | |
download | skyhanni-dd1dc872a97dcc14fe7842fc69c1bd34b44223fe.tar.gz skyhanni-dd1dc872a97dcc14fe7842fc69c1bd34b44223fe.tar.bz2 skyhanni-dd1dc872a97dcc14fe7842fc69c1bd34b44223fe.zip |
Trying to fix ghost counter (#275)
Ghost Counter fixes
4 files changed, 182 insertions, 70 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt index b91bf4252..4bfa37ede 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt +++ b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt @@ -69,6 +69,7 @@ object Commands { registerCommand("shclearslayerprofits") { SlayerItemProfitTracker.clearProfitCommand(it) } registerCommand("shimportghostcounterdata") { GhostCounter.importCTGhostCounterData() } registerCommand("shclearfarmingitems") { clearFarmingItems() } + registerCommand("shresetghostcounter") { GhostCounter.reset() } // for users - fix bugs registerCommand("shupdaterepo") { SkyHanniMod.repo.updateRepo() } @@ -87,7 +88,7 @@ object Commands { registerCommand("shtestcomposter") { ComposterOverlay.onCommand(it) } registerCommand("shtestinquisitor") { InquisitorWaypointShare.test() } registerCommand("shshowcropmoneycalculation") { CropMoneyDisplay.toggleShowCalculation() } - registerCommand("shstoprepowarnings") { stopRepoWarnings()} + registerCommand("shstoprepowarnings") { stopRepoWarnings() } // for developers - coding help registerCommand("shreloadlocalrepo") { SkyHanniMod.repo.reloadLocalRepo() } diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/GhostCounter.java b/src/main/java/at/hannibal2/skyhanni/config/features/GhostCounter.java index 955253f96..84b6e99d3 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/GhostCounter.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/GhostCounter.java @@ -255,6 +255,14 @@ public class GhostCounter { "when you are doing nothing for a given amount of seconds") @ConfigEditorText public String paused = "&c(PAUSED)"; + + @Expose + @ConfigOption(name = "Time", desc = "§e%days% §7is replaced with days remaining.\n" + + "§e%hours% §7is replaced with hours remaining.\n" + + "§e%minutes% §7is replaced with minutes remaining.\n" + + "§e%seconds% §7is replaced with seconds remaining.") + @ConfigEditorText + public String time = "&6%days%%hours%%minutes%%seconds%"; } @ConfigOption(name = "Kill Per Hour Formatting", desc = "") @@ -280,6 +288,7 @@ public class GhostCounter { public String paused = "&c(PAUSED)"; } + @Expose @ConfigOption(name = "Money Per Hour", desc = "Money Per Hour.\n§e%value% §7is replaced with\nEstimated money you get per hour\n" + "Calculated with your kill per hour and your average magic find.") diff --git a/src/main/java/at/hannibal2/skyhanni/data/SkillExperience.kt b/src/main/java/at/hannibal2/skyhanni/data/SkillExperience.kt index 11435ae96..2928c84f2 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/SkillExperience.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/SkillExperience.kt @@ -98,6 +98,8 @@ class SkillExperience { return 0 } + fun getExpForNextLevel(requestedLevel: Int) = levelingExp[requestedLevel] + fun getExpForLevel(requestedLevel: Int): Long { var total = 0L var level = 0 diff --git a/src/main/java/at/hannibal2/skyhanni/features/misc/GhostCounter.kt b/src/main/java/at/hannibal2/skyhanni/features/misc/GhostCounter.kt index 265c819dd..490ec110b 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/misc/GhostCounter.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/misc/GhostCounter.kt @@ -4,6 +4,7 @@ import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigManager import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.data.ProfileStorageData +import at.hannibal2.skyhanni.data.SkillExperience import at.hannibal2.skyhanni.events.* import at.hannibal2.skyhanni.features.bazaar.BazaarApi import at.hannibal2.skyhanni.features.misc.GhostCounter.Option.* @@ -34,8 +35,8 @@ import com.google.gson.JsonArray import com.google.gson.JsonParser import com.google.gson.JsonPrimitive import io.github.moulberry.notenoughupdates.util.Utils +import io.github.moulberry.notenoughupdates.util.XPInformation import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent import java.awt.Toolkit import java.awt.datatransfer.DataFlavor import java.awt.datatransfer.StringSelection @@ -54,13 +55,19 @@ object GhostCounter { val hidden get() = ProfileStorageData.profileSpecific?.ghostCounter private var display = emptyList<List<Any>>() private var ghostCounterV3File = File("." + File.separator + "config" + File.separator + "ChatTriggers" + File.separator + "modules" + File.separator + "GhostCounterV3" + File.separator + ".persistantData.json") - private val skillXPPattern = ".*§3\\+(?<gained>.*).*\\((?<total>.*)\\/(?<current>.*)\\).*".toPattern() + private val skillXPPattern = "[+](?<gained>[0-9,.]+) \\((?<current>[0-9,.]+)(?:\\/(?<total>[0-9,.]+))?\\)".toPattern() + private val combatSectionPattern = ".*[+](?<gained>[0-9,.]+) (?<skillName>[A-Za-z]+) \\((?<progress>(?:(?:(?:(?<current>[0-9.,]+)\\/(?<total>[0-9.,]+))|(?:(?<percent>[0-9.]+)%))))\\).*".toPattern() private val killComboExpiredPattern = "§cYour Kill Combo has expired! You reached a (?<combo>.*) Kill Combo!".toPattern() private val ghostXPPattern = "(?<current>\\d+(?:\\.\\d+)?(?:,\\d+)?[kK]?)\\/(?<total>\\d+(?:\\.\\d+)?(?:,\\d+)?[kKmM]?)".toPattern() private val bestiaryPattern = "BESTIARY Ghost .*➜(?<newLevel>.*)".toPattern() - private val format = NumberFormat.getIntegerInstance() + private val format = NumberFormat.getInstance() + private var percent: Float = 0.0f + private var totalSkillXp = 0 + private var currentSkillXp = 0.0f + private var skillText = "" + private var lastParsedSkillSection = "" + private var lastSkillProgressString: String? = null private const val exportPrefix = "gc/" - private var tick = 0 private var lastXp: String = "0" private var gain: Int = 0 private var num: Double = 0.0 @@ -122,6 +129,32 @@ object GhostCounter { display = formatDisplay(drawDisplay()) } + private fun prettyTime(millis: Long): Map<String, String> { + val seconds = millis / 1000 % 60 + val minutes = millis / 1000 / 60 % 60 + val hours = millis / 1000 / 60 / 60 % 24 + val days = millis / 1000 / 60 / 60 / 24 + return buildMap { + if (millis < 0) { + clear() + } else if (minutes == 0L && hours == 0L && days == 0L) { + put("seconds", seconds.toString()) + } else if (hours == 0L && days == 0L) { + put("seconds", seconds.toString()) + put("minutes", minutes.toString()) + } else if (days == 0L) { + put("seconds", seconds.toString()) + put("minutes", minutes.toString()) + put("hours", hours.toString()) + } else { + put("seconds", seconds.toString()) + put("minutes", minutes.toString()) + put("hours", hours.toString()) + put("days", days.toString()) + } + } + } + private fun drawDisplay() = buildList<List<Any>> { val value: Int = when (SORROWCOUNT.get()) { 0.0 -> 0 @@ -139,20 +172,20 @@ object GhostCounter { xp = xpHourFormatting.noData } else { xpInterp = interp(xpGainHour, xpGainHourLast, lastUpdate) - xp = "${format.format(xpInterp)} ${if (isKilling) "" else xpHourFormatting.paused}" + val part = "([0-9]{3,}[^,]+)".toRegex().find(format.format(xpInterp))?.groupValues?.get(1) ?: "N/A" + xp = "$part ${if (isKilling) "" else xpHourFormatting.paused}" } val killHourFormatting = config.textFormatting.killHourFormatting - val killh: String + val killHour: String var killInterp: Long = 0 if (killGainHourLast == killGainHour && killGainHour <= 0) { - killh = killHourFormatting.noData + killHour = killHourFormatting.noData } else { killInterp = interp(killGainHour.toFloat(), killGainHourLast.toFloat(), lastKillUpdate).toLong() - killh = "${format.format(killInterp)} ${if (_isKilling) "" else killHourFormatting.paused}" + killHour = "${format.format(killInterp)} ${if (_isKilling) "" else killHourFormatting.paused}" } - val bestiaryFormatting = config.textFormatting.bestiaryFormatting val currentKill = hidden?.bestiaryCurrentKill?.toInt() ?: 0 val killNeeded = hidden?.bestiaryKillNeeded?.toInt() ?: 0 @@ -189,7 +222,27 @@ object GhostCounter { if (killGainHour < 1) { etaFormatting.noData } else { - killETA = Utils.prettyTime(remaining.toLong() * 1000 * 60 * 60 / killInterp) + val timeMap = prettyTime(remaining.toLong() * 1000 * 60 * 60 / killInterp) + val time = buildString { + if (timeMap.isNotEmpty()) { + val formatMap = mapOf( + "%days%" to "days", + "%hours%" to "hours", + "%minutes%" to "minutes", + "%seconds%" to "seconds" + ) + for ((format, key) in formatMap) { + if (etaFormatting.time.contains(format)) { + timeMap[key]?.let { value -> + append("$value${format[1]}") + } + } + } + } else { + append("§cEnded!") + } + } + killETA = time etaFormatting.progress + if (_isKilling) "" else etaFormatting.paused } } @@ -210,45 +263,111 @@ object GhostCounter { addAsSingletonList(config.textFormatting.skillXPGainFormat.formatText(SKILLXPGAINED.get(), SKILLXPGAINED.get(true))) addAsSingletonList(bestiaryFormatting.base.formatText(bestiary).formatBestiary(currentKill, killNeeded)) addAsSingletonList(xpHourFormatting.base.formatText(xp)) - addAsSingletonList(killHourFormatting.base.formatText(killh)) + addAsSingletonList(killHourFormatting.base.formatText(killHour)) addAsSingletonList(etaFormatting.base.formatText(eta).formatText(killETA)) - /* - I'm very not sure about all that - */ - val rate = 0.12 * (1 + (mgc.toDouble()/100)) - val price = (BazaarApi.getBazaarDataByInternalName("SORROW")?.sellPrice ?: 0).toLong() - val final: String = (killInterp * price * (rate/100)).toLong().addSeparators() + val rate = 0.12 * (1 + (mgc.toDouble() / 100)) + val price = (BazaarApi.getBazaarDataByInternalName("SORROW")?.sellPrice ?: 0).toLong() + val final: String = (killInterp * price * (rate / 100)).toLong().addSeparators() addAsSingletonList(config.textFormatting.moneyHourFormat.formatText(final)) } + @SubscribeEvent + fun onTick(event: LorenzTickEvent) { + if (!isEnabled()) return + if (event.isMod(20)) { + skillXPPattern.matchMatcher(skillText) { + val gained = group("gained").formatNumber().toDouble() + val current = group("current") + if (current != lastXp) { + val res = if (current.contains(".")) { + "(?:[0-9,]+){3,}".toRegex().find(current)?.groupValues?.get(1) ?: "0" + } else { + current.replace("\\D".toRegex(), "") + } + gain = (res.toLong() - lastXp.toLong()).toDouble().roundToInt() + num = (gain.toDouble() / gained) + if (gained in 150.0..450.0) { + if (lastXp != "0") { + if (num >= 0) { + KILLS.add(num) + KILLS.add(num, true) + GHOSTSINCESORROW.add(num) + KILLCOMBO.add(num) + SKILLXPGAINED.add(gained * num.roundToLong()) + SKILLXPGAINED.add(gained * num.roundToLong(), true) + hidden?.bestiaryCurrentKill = hidden?.bestiaryCurrentKill?.plus(num) ?: num + } + } + } + lastXp = res + } + } + if (notifyCTModule && ProfileStorageData.profileSpecific?.ghostCounter?.ctDataImported != true) { + notifyCTModule = false + if (isUsingCTGhostCounter()) { + clickableChat("§6[SkyHanni] GhostCounterV3 ChatTriggers module has been detected, do you want to import saved data ? Click here to import data", "shimportghostcounterdata") + } + } + inMist = LorenzUtils.skyBlockArea == "The Mist" + update() + } + if (event.isMod(40)) { + calculateXP() + calculateETA() + } + } - // Part of this was taken from GhostCounterV3 CT module - // maybe replace this with a SkillXpGainEvent ? @SubscribeEvent fun onActionBar(event: LorenzActionBarEvent) { if (!isEnabled()) return - skillXPPattern.matchMatcher(event.message) { - val gained = group("gained").formatNumber().toDouble() - val total = group("total") - if (total != lastXp) { - val res = total.replace("\\D".toRegex(), "") - gain = (res.toLong() - lastXp.toLong()).toDouble().roundToInt() - num = (gain.toDouble() / gained) - if (gained in 150.0..450.0) { - if (lastXp != "0") { - if (num >= 0) { - KILLS.add(num) - KILLS.add(num, true) - GHOSTSINCESORROW.add(num) - KILLCOMBO.add(num) - SKILLXPGAINED.add(gained * num.roundToLong()) - SKILLXPGAINED.add(gained * num.roundToLong(), true) - hidden?.bestiaryCurrentKill = hidden?.bestiaryCurrentKill?.plus(num) ?: num - } + combatSectionPattern.matchMatcher(event.message) { + if (group("skillName").lowercase() != "combat") return + parseCombatSection(event.message) + } + } + + private fun parseCombatSection(section: String) { + val sb = StringBuilder() + val nf = NumberFormat.getInstance(Locale.US) + nf.maximumFractionDigits = 2 + if (lastParsedSkillSection == section) { + sb.append(lastSkillProgressString) + } else if (combatSectionPattern.matcher(section).find()) { + combatSectionPattern.matchMatcher(section) { + sb.append("+").append(group("gained")) + val skillName = group("skillName") + val skillPercent = group("percent") != null + var parse = true + if (skillPercent) { + percent = nf.parse(group("percent")).toFloat() + val level = XPInformation.getInstance().getSkillInfo(skillName).level + if (level > 0) { + totalSkillXp = SkillExperience.getExpForNextLevel(level) + currentSkillXp = totalSkillXp * percent / 100 + } else { + parse = false + } + } else { + currentSkillXp = nf.parse(group("current")).toFloat() + totalSkillXp = nf.parse(group("total")).toInt() + } + percent = 100f.coerceAtMost(percent) + if (!parse) { + sb.append(" (").append(String.format("%.2f", percent)).append("%)") + } else { + sb.append(" (").append(nf.format(currentSkillXp)) + if (totalSkillXp != 0) { + sb.append("/") + sb.append(nf.format(totalSkillXp)) } + sb.append(")") } - lastXp = res + lastParsedSkillSection = section + lastSkillProgressString = sb.toString() + } + if (sb.toString().isNotEmpty()) { + skillText = sb.toString() } } } @@ -267,6 +386,8 @@ object GhostCounter { hidden?.totalMF = hidden?.totalMF?.plus(group("mf").substring(4).toDouble()) ?: group("mf").substring(4).toDouble() TOTALDROPS.add(1.0) + if (opt == SORROWCOUNT) + GHOSTSINCESORROW.set(0.0) update() } @@ -284,7 +405,6 @@ object GhostCounter { else -> {} } } - } killComboExpiredPattern.matchMatcher(event.message) { if (KILLCOMBO.getInt() > MAXKILLCOMBO.getInt()) { @@ -329,28 +449,6 @@ object GhostCounter { } @SubscribeEvent - fun onTick(event: TickEvent.ClientTickEvent) { - if (!isEnabled()) return - tick++ - if (tick % 20 == 0) { - inMist = LorenzUtils.skyBlockArea == "The Mist" - update() - } - - if (tick % 40 == 20) { - calculateXP() - calculateETA() - } - - if (notifyCTModule && ProfileStorageData.profileSpecific?.ghostCounter?.ctDataImported == true) { - notifyCTModule = false - if (isUsingCTGhostCounter()) { - clickableChat("§6[SkyHanni] GhostCounterV3 ChatTriggers module has been detected, do you want to import saved data ? Click here to import data", "shimportghostcounterdata") - } - } - } - - @SubscribeEvent fun onInventoryOpen(event: InventoryOpenEvent) { if (!LorenzUtils.inSkyBlock) return val inventoryName = event.inventoryName @@ -359,7 +457,6 @@ object GhostCounter { val ghostStack = stacks[13] ?: return val bestiaryNextLevel = if (ghostStack.displayName == "§cGhost") 1 else Utils.parseIntOrRomanNumeral(ghostStack.displayName.substring(8)) + 1 hidden?.bestiaryNextLevel = bestiaryNextLevel.toDouble() - for (line in ghostStack.getLore()) { ghostXPPattern.matchMatcher(line.removeColor().trim()) { hidden?.bestiaryCurrentKill = group("current").formatNumber().toDouble() @@ -373,8 +470,8 @@ object GhostCounter { return LorenzUtils.inSkyBlock && config.enabled && LorenzUtils.skyBlockIsland == IslandType.DWARVEN_MINES } - private fun percent(number: Double, total: Double): String { - return "${((number / total) * 100).roundToPrecision(4)}" + private fun percent(number: Double): String { + return "${((number / 3_000_000) * 100).roundToPrecision(4)}" } fun reset() { @@ -382,6 +479,7 @@ object GhostCounter { opt.set(0.0) opt.set(0.0, true) } + hidden?.totalMF = 0.0 update() } @@ -432,7 +530,7 @@ object GhostCounter { private fun String.formatBestiary(currentKill: Int, killNeeded: Int): String { return Utils.chromaStringByColourCode( this.replace("%currentKill%", if (config.showMax) bestiaryCurrentKill.addSeparators() else currentKill.addSeparators()) - .replace("%percentNumber%", percent(bestiaryCurrentKill.toDouble(), 3_000_000.0)) + .replace("%percentNumber%", percent(bestiaryCurrentKill.toDouble())) .replace("%killNeeded%", NumberUtil.format(killNeeded)) .replace("%currentLevel%", if (hidden?.bestiaryNextLevel?.toInt()!! < 0) "46" else "${hidden?.bestiaryNextLevel?.toInt()!! - 1}") .replace("%nextLevel%", if (config.showMax) "46" else "${hidden?.bestiaryNextLevel?.toInt()!!}") @@ -491,7 +589,6 @@ object GhostCounter { } if (base64.length <= exportPrefix.length) return - val jsonString = try { val t = String(Base64.getDecoder().decode(base64.trim())) if (!t.startsWith(exportPrefix)) return @@ -508,7 +605,7 @@ object GhostCounter { return } - if (list.size == 30) { + if (list.isNotEmpty()) { with(config.textFormatting) { titleFormat = list[0] ghostKilledFormat = list[1] @@ -546,8 +643,9 @@ object GhostCounter { maxed = list[26] noData = list[27] progress = list[28] + time = list[29] } - moneyHourFormat = list[29] + moneyHourFormat = list[30] } } } @@ -591,6 +689,7 @@ object GhostCounter { list.add(maxed) list.add(noData) list.add(progress) + list.add(time) } list.add(moneyHourFormat) } @@ -640,8 +739,9 @@ object GhostCounter { maxed = "§c§lMAXED!" noData = "§bN/A" progress = "§b%value%" + time = "&6%days%%hours%%minutes%%seconds%" } moneyHourFormat = " &6$/h: &b%value%" } } -} +}
\ No newline at end of file |