diff options
Diffstat (limited to 'src/main/kotlin')
-rw-r--r-- | src/main/kotlin/io/github/moulberry/notenoughupdates/util/TabSkillInfoParser.kt | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/TabSkillInfoParser.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/TabSkillInfoParser.kt new file mode 100644 index 00000000..b4bfdf28 --- /dev/null +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/TabSkillInfoParser.kt @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2023 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.util + +import com.google.gson.JsonArray +import net.minecraft.util.EnumChatFormatting +import java.util.regex.Pattern +import kotlin.math.abs + +object TabSkillInfoParser { + private val skillTabPattern: Pattern = + Pattern.compile("^§r§e§lSkills: §r§a(?<type>\\w+) (?<level>\\d+): §r§3(?<progress>.+)%§r\$") + private val maxSkillTabPattern: Pattern = + Pattern.compile("^§r§e§lSkills: §r§a(?<type>\\w+) (?<level>\\d+): §r§c§lMAX§r\$") + private var sentErrorOnce = false + + private fun calculateLevelXp(levelingArray: JsonArray, level: Int): Double { + var totalXp = 0.0 + for (i in 0 until level + 1) { + val xp = levelingArray[i].asDouble + totalXp += xp + } + return totalXp + } + + private fun isWithinPercentageRange(xp: Double, existingXp: Double, percentage: Double): Boolean { + val diff = (abs(xp - existingXp) / existingXp) * 100 + return diff <= percentage + } + + private fun sendError(message: String) { + if (!sentErrorOnce) { + Utils.addChatMessage(message) + sentErrorOnce = true + } + } + + private fun levelArray(skillType: String) = + if (skillType == "runecrafting") Utils.getElement(Constants.LEVELING, "runecrafting_xp").asJsonArray + else Utils.getElement(Constants.LEVELING, "leveling_xp").asJsonArray + + @JvmStatic + fun parseSkillInfo() { + if (Constants.LEVELING == null) { + sendError("${EnumChatFormatting.RED}[NEU] There is an error with your repo, please report this in the discord at ${EnumChatFormatting.AQUA}discord.gg/moulberry") + return + } + + for (s in TabListUtils.getTabList()) { + val matcher = skillTabPattern.matcher(s) + val maxLevelMatcher = maxSkillTabPattern.matcher(s) + if (matcher.matches()) { + // All the groups are guaranteed to match + val name = matcher.group("type")!!.lowercase() + val level = matcher.group("level")!!.toInt() + val progress = matcher.group("progress")!!.toFloatOrNull() + if (progress == null) { + sendError("${EnumChatFormatting.RED}[NEU] Error while parsing skill level from tab list") + return + } + val levelingArray = levelArray(name) + val levelXp = calculateLevelXp(levelingArray, level - 1) + // This *should* not cause problems, since skills that are max Level won't be picked up + val nextLevelDiff = levelingArray[level].asDouble + val nextLevelProgress = nextLevelDiff * progress / 100 + + val totalXp = levelXp + nextLevelProgress + val existingLevel = XPInformation.getInstance().getSkillInfo(name) ?: XPInformation.SkillInfo() + + // Only update if the numbers are substantially different + if (!isWithinPercentageRange(totalXp, existingLevel.totalXp.toDouble(), 1.0)) { + existingLevel.level = level + existingLevel.totalXp = totalXp.toFloat() + existingLevel.currentXp = nextLevelProgress.toFloat() + existingLevel.currentXpMax = nextLevelDiff.toFloat() + XPInformation.getInstance().skillInfoMap[name] = existingLevel + } + + // There is only one skill at a time in the tab list + break + } else if (maxLevelMatcher.matches()) { + val name = maxLevelMatcher.group("type")!!.lowercase() + val level = maxLevelMatcher.group("level")!!.toInt() + + val existingLevel = XPInformation.getInstance().getSkillInfo(name) ?: XPInformation.SkillInfo() + if (existingLevel.level != level) { + existingLevel.level = level + val levelingArray = levelArray(name) + + val totalXp = calculateLevelXp(levelingArray, level - 1) + existingLevel.totalXp = totalXp.toFloat() + XPInformation.getInstance().skillInfoMap[name] = existingLevel + } + } + } + } +} |