diff options
Diffstat (limited to 'src/main/java/io/github/moulberry/notenoughupdates/util/XPInformation.java')
| -rw-r--r-- | src/main/java/io/github/moulberry/notenoughupdates/util/XPInformation.java | 246 |
1 files changed, 148 insertions, 98 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/XPInformation.java b/src/main/java/io/github/moulberry/notenoughupdates/util/XPInformation.java index 117545c9..e474f348 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/XPInformation.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/XPInformation.java @@ -24,12 +24,18 @@ import com.google.gson.JsonArray; import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe; import io.github.moulberry.notenoughupdates.core.util.StringUtils; +import io.github.moulberry.notenoughupdates.miscfeatures.tablisttutorial.TablistAPI; +import lombok.var; import net.minecraftforge.client.event.ClientChatReceivedEvent; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; +import org.jetbrains.annotations.Nullable; import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -43,16 +49,15 @@ public class XPInformation { public static class SkillInfo { public int level; - public float totalXp; - public float currentXp; - public float currentXpMax; + public double totalXp; + public double currentXp; + public double currentXpMax; public boolean fromApi = false; } private final HashMap<String, SkillInfo> skillInfoMap = new HashMap<>(); public HashMap<String, Float> updateWithPercentage = new HashMap<>(); - - public int correctionCounter = 0; + public HashMap<String, Float> increment = new HashMap<>(); private static final Splitter SPACE_SPLITTER = Splitter.on(" ").omitEmptyStrings().trimResults(); private static final Pattern SKILL_PATTERN = Pattern.compile( @@ -66,144 +71,189 @@ public class XPInformation { return skillInfoMap; } - public SkillInfo getSkillInfo(String skillName) { - return skillInfoMap.get(skillName.toLowerCase()); + private Set<String> failedSkills = new HashSet<>(); + + public @Nullable SkillInfo getSkillInfo(String skillName, boolean isHighlyInterested) { + var obj = skillInfoMap.get(skillName.toLowerCase()); + if (isHighlyInterested && failedSkills.contains(skillName.toLowerCase())) { + TablistAPI.getWidgetLines(TablistAPI.WidgetNames.SKILLS); + } + return obj; } private String lastActionBar = null; @SubscribeEvent(priority = EventPriority.HIGHEST, receiveCanceled = true) public void onChatReceived(ClientChatReceivedEvent event) { - if (event.type == 2) { - JsonObject leveling = Constants.LEVELING; - if (leveling == null) return; + if (event.type != 2) { + return; + } + JsonObject leveling = Constants.LEVELING; + if (leveling == null) return; - String actionBar = StringUtils.cleanColour(event.message.getUnformattedText()); + String actionBar = StringUtils.cleanColour(event.message.getUnformattedText()); - if (lastActionBar != null && lastActionBar.equalsIgnoreCase(actionBar)) { - return; - } - lastActionBar = actionBar; + if (lastActionBar != null && lastActionBar.equalsIgnoreCase(actionBar)) { + return; + } + lastActionBar = actionBar; + + List<String> components = SPACE_SPLITTER.splitToList(actionBar); + + for (String component : components) { + Matcher matcher = SKILL_PATTERN.matcher(component); + if (matcher.matches()) { + String skillS = matcher.group(2); + String currentXpS = matcher.group(3).replace(",", ""); + String maxXpS = matcher.group(4).replace(",", ""); + + float currentXp = Float.parseFloat(currentXpS); + float maxXp = Float.parseFloat(maxXpS); + + SkillInfo skillInfo = new SkillInfo(); + skillInfo.currentXp = currentXp; + skillInfo.currentXpMax = maxXp; + skillInfo.totalXp = currentXp; + + JsonArray levelingArray = leveling.getAsJsonArray("leveling_xp"); + for (int i = 0; i < levelingArray.size(); i++) { + float cap = levelingArray.get(i).getAsFloat(); + if (maxXp > 0 && maxXp <= cap) { + break; + } - List<String> components = SPACE_SPLITTER.splitToList(actionBar); + skillInfo.totalXp += cap; + skillInfo.level++; + } - for (String component : components) { - Matcher matcher = SKILL_PATTERN.matcher(component); + skillInfoMap.put(skillS.toLowerCase(), skillInfo); + return; + } else { + matcher = SKILL_PATTERN_PERCENTAGE.matcher(component); if (matcher.matches()) { String skillS = matcher.group(2); - String currentXpS = matcher.group(3).replace(",", ""); - String maxXpS = matcher.group(4).replace(",", ""); - - float currentXp = Float.parseFloat(currentXpS); - float maxXp = Float.parseFloat(maxXpS); - - SkillInfo skillInfo = new SkillInfo(); - skillInfo.currentXp = currentXp; - skillInfo.currentXpMax = maxXp; - skillInfo.totalXp = currentXp; - - JsonArray levelingArray = leveling.getAsJsonArray("leveling_xp"); - for (int i = 0; i < levelingArray.size(); i++) { - float cap = levelingArray.get(i).getAsFloat(); - if (maxXp > 0 && maxXp <= cap) { - break; - } + String xpPercentageS = matcher.group(3).replace(",", ""); - skillInfo.totalXp += cap; - skillInfo.level++; + float xpPercentage = Float.parseFloat(xpPercentageS); + if (updateWithPercentage.containsKey(skillS.toLowerCase())) { + failedSkills.add(skillS.toLowerCase()); } - - skillInfoMap.put(skillS.toLowerCase(), skillInfo); - return; + updateWithPercentage.put(skillS.toLowerCase(), xpPercentage); + increment.put(skillS.toLowerCase(), Float.parseFloat(matcher.group(1).replace(",", ""))); } else { - matcher = SKILL_PATTERN_PERCENTAGE.matcher(component); + matcher = SKILL_PATTERN_MULTIPLIER.matcher(component); + if (matcher.matches()) { String skillS = matcher.group(2); - String xpPercentageS = matcher.group(3).replace(",", ""); - - float xpPercentage = Float.parseFloat(xpPercentageS); - updateWithPercentage.put(skillS.toLowerCase(), xpPercentage); - } else { - matcher = SKILL_PATTERN_MULTIPLIER.matcher(component); - - if (matcher.matches()) { - String skillS = matcher.group(2); - String currentXpS = matcher.group(3).replace(",", ""); - String maxXpS = matcher.group(4).replace(",", ""); - - float maxMult = 1; - if (maxXpS.endsWith("k")) { - maxMult = 1000; - maxXpS = maxXpS.substring(0, maxXpS.length() - 1); - } else if (maxXpS.endsWith("m")) { - maxMult = 1000000; - maxXpS = maxXpS.substring(0, maxXpS.length() - 1); - } else if (maxXpS.endsWith("b")) { - maxMult = 1000000000; - maxXpS = maxXpS.substring(0, maxXpS.length() - 1); - } - - float currentXp = Float.parseFloat(currentXpS); - float maxXp = Float.parseFloat(maxXpS) * maxMult; + String currentXpS = matcher.group(3).replace(",", ""); + String maxXpS = matcher.group(4).replace(",", ""); + + float maxMult = 1; + if (maxXpS.endsWith("k")) { + maxMult = 1000; + maxXpS = maxXpS.substring(0, maxXpS.length() - 1); + } else if (maxXpS.endsWith("m")) { + maxMult = 1000000; + maxXpS = maxXpS.substring(0, maxXpS.length() - 1); + } else if (maxXpS.endsWith("b")) { + maxMult = 1000000000; + maxXpS = maxXpS.substring(0, maxXpS.length() - 1); + } - SkillInfo skillInfo = new SkillInfo(); - skillInfo.currentXp = currentXp; - skillInfo.currentXpMax = maxXp; - skillInfo.totalXp = currentXp; + float currentXp = Float.parseFloat(currentXpS); + float maxXp = Float.parseFloat(maxXpS) * maxMult; - JsonArray levelingArray = leveling.getAsJsonArray("leveling_xp"); - for (int i = 0; i < levelingArray.size(); i++) { - float cap = levelingArray.get(i).getAsFloat(); - if (maxXp > 0 && maxXp <= cap) { - break; - } + SkillInfo skillInfo = new SkillInfo(); + skillInfo.currentXp = currentXp; + skillInfo.currentXpMax = maxXp; + skillInfo.totalXp = currentXp; - skillInfo.totalXp += cap; - skillInfo.level++; + JsonArray levelingArray = leveling.getAsJsonArray("leveling_xp"); + for (int i = 0; i < levelingArray.size(); i++) { + float cap = levelingArray.get(i).getAsFloat(); + if (maxXp > 0 && maxXp <= cap) { + break; } - skillInfoMap.put(skillS.toLowerCase(), skillInfo); - return; + skillInfo.totalXp += cap; + skillInfo.level++; } + + skillInfoMap.put(skillS.toLowerCase(), skillInfo); + return; } } } } } + private Pattern tablistSkillPattern = + Pattern.compile( + " (?<type>[^ ]+) (?<level>\\d+): (?:(?<percentage>\\d+(\\.\\d+)?)%|(?<amount>[0-9,]+(\\.\\d+)?)/.*|(?<max>MAX))"); + + // Car Pentry + @SubscribeEvent + public void onTick(TickEvent.ClientTickEvent event) { + if (event.phase != TickEvent.Phase.END) return; + var widgetLines = TablistAPI.getOptionalWidgetLines(TablistAPI.WidgetNames.SKILLS); + for (String widgetLine : widgetLines) { + Matcher matcher = tablistSkillPattern.matcher(Utils.cleanColour(widgetLine)); + if (!matcher.matches()) + continue; + var type = matcher.group("type"); + assert type != null; + var level = Integer.parseInt(matcher.group("level")); + var percentage = matcher.group("percentage"); + var percentageAsNumber = percentage != null ? Double.parseDouble(percentage) / 100 : null; + var amount = matcher.group("amount"); + var amountAsNumber = amount != null ? Double.parseDouble(amount.replace(",", "")) : null; + var isMax = matcher.group("max") != null; + // TODO: use this extra information for good (not evil) + updateLevel(type.toLowerCase(), level); + } + } + public void updateLevel(String skill, int level) { if (updateWithPercentage.containsKey(skill)) { JsonObject leveling = Constants.LEVELING; if (leveling == null) return; - SkillInfo skillInfo = new SkillInfo(); - skillInfo.totalXp = 0; - skillInfo.level = level; + SkillInfo newSkillInfo = new SkillInfo(); + newSkillInfo.totalXp = 0; + newSkillInfo.level = level; JsonArray levelingArray = leveling.getAsJsonArray("leveling_xp"); for (int i = 0; i < levelingArray.size(); i++) { float cap = levelingArray.get(i).getAsFloat(); if (i == level) { - skillInfo.currentXp += updateWithPercentage.get(skill) / 100f * cap; - skillInfo.totalXp += skillInfo.currentXp; - skillInfo.currentXpMax = cap; + newSkillInfo.currentXp += updateWithPercentage.get(skill) / 100f * cap; + newSkillInfo.totalXp += newSkillInfo.currentXp; + newSkillInfo.currentXpMax = cap; break; } else { - skillInfo.totalXp += cap; + newSkillInfo.totalXp += cap; } } - SkillInfo old = skillInfoMap.get(skill.toLowerCase()); - - if (old.totalXp <= skillInfo.totalXp) { - correctionCounter--; - if (correctionCounter < 0) correctionCounter = 0; - - skillInfoMap.put(skill.toLowerCase(), skillInfo); - } else if (++correctionCounter >= 10) { - correctionCounter = 0; - skillInfoMap.put(skill.toLowerCase(), skillInfo); + SkillInfo oldSkillInfo = skillInfoMap.get(skill.toLowerCase()); + float inc = increment.getOrDefault(skill.toLowerCase(), 0F); + if (oldSkillInfo != null && oldSkillInfo.totalXp + inc > newSkillInfo.totalXp && oldSkillInfo.totalXp - inc * 5 < newSkillInfo.totalXp) { + SkillInfo incrementedSkillInfo = new SkillInfo(); + incrementedSkillInfo.totalXp = oldSkillInfo.totalXp + inc; + boolean isNotLevelUp = oldSkillInfo.currentXp + inc < oldSkillInfo.currentXpMax; + incrementedSkillInfo.level = + (isNotLevelUp) ? oldSkillInfo.level : oldSkillInfo.level + 1; + incrementedSkillInfo.currentXp = + isNotLevelUp ? oldSkillInfo.currentXp + inc : oldSkillInfo.currentXp + inc - oldSkillInfo.currentXpMax; + incrementedSkillInfo.currentXpMax = + incrementedSkillInfo.level < levelingArray.size() && incrementedSkillInfo.level >= 0 + ? levelingArray.get(incrementedSkillInfo.level).getAsFloat() + : 0F; + skillInfoMap.put(skill.toLowerCase(), incrementedSkillInfo); + } else { + skillInfoMap.put(skill.toLowerCase(), newSkillInfo); } + failedSkills.remove(skill.toLowerCase()); } updateWithPercentage.clear(); } |
