aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/io/github/moulberry/notenoughupdates/util/XPInformation.java
diff options
context:
space:
mode:
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.java246
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();
}