diff --git a/src/main/java/lel/flummi/skilloverlay/api/PlayerProfile.java b/src/main/java/lel/flummi/skilloverlay/api/PlayerProfile.java index aedeb16..54f1941 100644 --- a/src/main/java/lel/flummi/skilloverlay/api/PlayerProfile.java +++ b/src/main/java/lel/flummi/skilloverlay/api/PlayerProfile.java @@ -18,38 +18,30 @@ public class PlayerProfile { public static Member PROFILE; private static Timer timerTask; private static boolean timerSet; + private static String apikey; + private static String uuid; public static void init(Boolean timer) { if (timer && !timerSet) { timerTask = new Timer("Timer"); timerTask.scheduleAtFixedRate(new TimerTask() { public void run() { - PlayerProfile.init(false); + PlayerProfile.updateProfile(); } - }, 1000L, 1000L * 60L); + }, 0, 1000L * 60L * 3); timerSet = true; } - String apikey = skilloverlayconfig.get().general.apiKey; - String uuid = MinecraftClient.getInstance().getSession().getUuidOrNull().toString().replace("-", ""); - String apiurl = "https://api.hypixel.net/skyblock/profiles?key=" + apikey + "&uuid=" + uuid; + uuid = MinecraftClient.getInstance().getSession().getUuidOrNull().toString().replace("-", ""); + apikey = skilloverlayconfig.get().general.apiKey; - if (apikey.length() > 0) { - Profile profile = PlayerProfile.updateProfile(apiurl); - if (profile != null) { - profile.profiles().removeIf(p -> !p.selected()); - PROFILE = profile.profiles().get(0).members().get(uuid); - } else { - System.out.println("leer uff"); - } - } - - System.out.println("API update! (every minute)"); + PlayerProfile.updateProfile(); } - public static Profile updateProfile(String apiurl) { + public static void updateProfile() { + String apiurl = "https://api.hypixel.net/skyblock/profiles?key=" + apikey + "&uuid=" + uuid; if (apiurl.length() == 0) - return null; + return; try { URL url = new URL(apiurl); @@ -57,10 +49,16 @@ public class PlayerProfile { Gson gson = new GsonBuilder() .serializeNulls() .create(); - return gson.fromJson(reader, Profile.class); + Profile profile = gson.fromJson(reader, Profile.class); + if (profile != null) { + profile.profiles().removeIf(p -> !p.selected()); + PROFILE = profile.profiles().get(0).members().get(uuid); + } else { + System.out.println("leer uff"); + } } catch (Exception e) { e.printStackTrace(); } - return null; + return; } } diff --git a/src/main/java/lel/flummi/skilloverlay/api/PlayerSkills.java b/src/main/java/lel/flummi/skilloverlay/api/PlayerSkills.java index 8632d88..2c75e38 100644 --- a/src/main/java/lel/flummi/skilloverlay/api/PlayerSkills.java +++ b/src/main/java/lel/flummi/skilloverlay/api/PlayerSkills.java @@ -13,24 +13,18 @@ import lel.flummi.skilloverlay.config.skilloverlayconfig; public class PlayerSkills { public static HashMap SKILLS; + private static String apikey; public static void init() { - String apikey = skilloverlayconfig.get().general.apiKey; - String apiurl = "https://api.hypixel.net/resources/skyblock/skills?key=" + apikey; + apikey = skilloverlayconfig.get().general.apiKey; - if (apikey.length() > 0) { - Skills skills = PlayerSkills.updateSkills(apiurl); - if (skills != null) { - SKILLS = skills.skills(); - } else { - System.out.println("leer uff"); - } - } + PlayerSkills.updateSkills(); } - public static Skills updateSkills(String apiurl) { + public static void updateSkills() { + String apiurl = "https://api.hypixel.net/resources/skyblock/skills?key=" + apikey; if (apiurl.length() == 0) - return null; + return; try { URL url = new URL(apiurl); @@ -38,10 +32,15 @@ public class PlayerSkills { Gson gson = new GsonBuilder() .serializeNulls() .create(); - return gson.fromJson(reader, Skills.class); + Skills skills = gson.fromJson(reader, Skills.class); + if (skills != null) { + SKILLS = skills.skills(); + } else { + System.out.println("leer uff"); + } } catch (Exception e) { e.printStackTrace(); } - return null; + return; } } diff --git a/src/main/java/lel/flummi/skilloverlay/api/records/Skills.java b/src/main/java/lel/flummi/skilloverlay/api/records/Skills.java index 537b24b..3de523f 100644 --- a/src/main/java/lel/flummi/skilloverlay/api/records/Skills.java +++ b/src/main/java/lel/flummi/skilloverlay/api/records/Skills.java @@ -17,17 +17,50 @@ public record Skills( } public SkillInfo getLevel(float exp) { - int aktLevel = 0; + LevelObj levelObj = new LevelObj(); + levelObj.totalXp = exp; + levelObj.maxLevel = 60; + boolean cumulative = true; - for (Level tmp : this.levels()) { - if (exp < tmp.totalExpRequired) { - // int level, float totalXp, float currentXp, float currentXpMax - return new SkillInfo(aktLevel, tmp.totalExpRequired, exp, tmp.totalExpRequired); + for (int level = 0; level < this.levels().size(); level++) { + float levelXp = this.levels().get(level).totalExpRequired; + + if (levelXp > exp) { + if (cumulative) { + float previous = level > 0 ? this.levels().get(level - 1).totalExpRequired : 0; + levelObj.maxXpForLevel = (levelXp - previous); + levelObj.level = 1 + level + (exp - levelXp) / levelObj.maxXpForLevel; + } else { + levelObj.maxXpForLevel = levelXp; + levelObj.level = level + exp / levelXp; + } + + if (levelObj.level > 60) { + levelObj.level = 60; + levelObj.maxed = true; + } + + return new SkillInfo(levelObj.level, levelObj.totalXp, (levelObj.level % 1) * levelObj.maxXpForLevel, levelObj.maxXpForLevel); + } + else { + if (!cumulative) { + exp -= levelXp; + } } - aktLevel = tmp.level; } - return null; + levelObj.level = Math.min(this.levels().size(), 60); + levelObj.maxed = true; + + return new SkillInfo(levelObj.level, levelObj.totalXp, (levelObj.level % 1) * levelObj.maxXpForLevel, levelObj.maxXpForLevel); + } + + public static class LevelObj { + public float level = 0; + public float maxXpForLevel = 0; + public boolean maxed = false; + public int maxLevel; + public float totalXp; } } diff --git a/src/main/java/lel/flummi/skilloverlay/overlays/FarmingOverlay.java b/src/main/java/lel/flummi/skilloverlay/overlays/FarmingOverlay.java index f1a8085..a8de2e3 100644 --- a/src/main/java/lel/flummi/skilloverlay/overlays/FarmingOverlay.java +++ b/src/main/java/lel/flummi/skilloverlay/overlays/FarmingOverlay.java @@ -15,6 +15,7 @@ import lel.flummi.skilloverlay.utils.SkillInfo; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; +import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.ArrayList; import java.util.Collections; @@ -79,6 +80,7 @@ public class FarmingOverlay extends DrawableHelper { this.cultivating = 0; xpGainHourLast = xpGainHour; + //System.out.println(XPInformation.getInstance().getSkillInfo("farming")); // System.out.println(skilloverlay.PROFILE.data().skills().get("farming").level()); if (heldItem != null) { @@ -282,9 +284,10 @@ public class FarmingOverlay extends DrawableHelper { // skillinfo if (skillInfo != null && skillInfo.level < 60) { - StringBuilder levelStr = new StringBuilder(skillInfo.level); + StringBuilder levelStr = new StringBuilder(); + levelStr.append((int) skillInfo.level); levelStr.append(Formatting.GRAY) - .append("["); + .append(" ["); float progress = skillInfo.currentXp / skillInfo.currentXpMax; if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) { @@ -304,7 +307,8 @@ public class FarmingOverlay extends DrawableHelper { levelStr.append(Formatting.GRAY) .append("] ") .append(Formatting.YELLOW) - .append((int) (progress * 100)) + .append(new DecimalFormat("##.00").format(progress * 100)) + //.append((int) (progress * 100)) .append("%"); int current = (int) skillInfo.currentXp; @@ -395,6 +399,7 @@ public class FarmingOverlay extends DrawableHelper { PUMPKIN("PUMPKIN_DICER", "Pumpkins"), MELON("MELON_DICER", "Melons"), CACTUS("CACTUS_KNIFE", "Cactus"), + MUSHROOM("FUNGHI_CUTTER", "Mushrooms"), ; private final String toolName; diff --git a/src/main/java/lel/flummi/skilloverlay/skilloverlay.java b/src/main/java/lel/flummi/skilloverlay/skilloverlay.java index 1d0e509..0029b6b 100644 --- a/src/main/java/lel/flummi/skilloverlay/skilloverlay.java +++ b/src/main/java/lel/flummi/skilloverlay/skilloverlay.java @@ -1,9 +1,9 @@ package lel.flummi.skilloverlay; import net.fabricmc.api.ModInitializer; -//import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; +import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; import lel.flummi.skilloverlay.overlays.FarmingOverlay; - +import lel.flummi.skilloverlay.utils.XPInformation; import lel.flummi.skilloverlay.api.PlayerProfile; import lel.flummi.skilloverlay.api.PlayerSkills; import lel.flummi.skilloverlay.config.skilloverlayconfig; @@ -11,6 +11,7 @@ import lel.flummi.skilloverlay.config.skilloverlayconfig; public class skilloverlay implements ModInitializer { public static FarmingOverlay OVERLAY; public static PlayerProfile API; + public static XPInformation XPINFO; @Override public void onInitialize() { @@ -18,16 +19,15 @@ public class skilloverlay implements ModInitializer { skilloverlayconfig.init(); OVERLAY = new FarmingOverlay(); + XPINFO = new XPInformation(); PlayerSkills.init(); - PlayerProfile.init(false); + PlayerProfile.init(true); - /* - * ClientReceiveMessageEvents.ALLOW_GAME.register((message, overlay) -> { - * System.out.println("message: " + message.getContent() + "; overlay: " + - * overlay); - * return true; - * }); - */ + ClientReceiveMessageEvents.GAME.register((message, overlay) -> { + //XPINFO.onChatReceived(message, overlay); + //System.out.println("message: " + message.getContent() + "; overlay: " + overlay); + //return true; + }); } } diff --git a/src/main/java/lel/flummi/skilloverlay/utils/SkillInfo.java b/src/main/java/lel/flummi/skilloverlay/utils/SkillInfo.java index 5060182..5f6fbdc 100644 --- a/src/main/java/lel/flummi/skilloverlay/utils/SkillInfo.java +++ b/src/main/java/lel/flummi/skilloverlay/utils/SkillInfo.java @@ -1,13 +1,13 @@ package lel.flummi.skilloverlay.utils; public class SkillInfo { - public final int level; + public final float level; public final float totalXp; public final float currentXp; public final float currentXpMax; public boolean fromApi = true; - public SkillInfo(int level, float totalXp, float currentXp, float currentXpMax) { + public SkillInfo(float level, float totalXp, float currentXp, float currentXpMax) { this.level = level; this.totalXp = totalXp; this.currentXp = currentXp; diff --git a/src/main/java/lel/flummi/skilloverlay/utils/StringUtils.java b/src/main/java/lel/flummi/skilloverlay/utils/StringUtils.java new file mode 100644 index 0000000..e881af2 --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/utils/StringUtils.java @@ -0,0 +1,7 @@ +package lel.flummi.skilloverlay.utils; + +public class StringUtils { + public static String cleanColour(String in) { + return in.replaceAll("(?i)\\u00A7.", ""); + } +} diff --git a/src/main/java/lel/flummi/skilloverlay/utils/XPInformation.java b/src/main/java/lel/flummi/skilloverlay/utils/XPInformation.java index 234f8f9..bf405da 100644 --- a/src/main/java/lel/flummi/skilloverlay/utils/XPInformation.java +++ b/src/main/java/lel/flummi/skilloverlay/utils/XPInformation.java @@ -1,7 +1,21 @@ package lel.flummi.skilloverlay.utils; +import lel.flummi.skilloverlay.api.PlayerProfile; +import lel.flummi.skilloverlay.api.PlayerSkills; +import lel.flummi.skilloverlay.api.records.Skills.Skill.Level; + +import java.util.HashMap; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.google.common.base.Splitter; + +import net.minecraft.text.Text; + public class XPInformation { private static final XPInformation INSTANCE = new XPInformation(); + private final HashMap skillInfoMap = new HashMap<>(); public static XPInformation getInstance() { return INSTANCE; @@ -14,4 +28,80 @@ public class XPInformation { public float currentXpMax; public boolean fromApi = false; } + + public HashMap updateWithPercentage = new HashMap<>(); + + public int correctionCounter = 0; + + private static final Splitter SPACE_SPLITTER = Splitter.on(" ").omitEmptyStrings().trimResults(); + private static final Pattern SKILL_PATTERN_PERCENTAGE = + Pattern.compile("\\+(\\d+(?:,\\d+)*(?:\\.\\d+)?) (.+) \\((\\d\\d?(?:\\.\\d\\d?)?)%\\)"); + + public HashMap getSkillInfoMap() { + return skillInfoMap; + } + + public SkillInfo getSkillInfo(String skillName) { + return skillInfoMap.get(skillName.toLowerCase()); + } + + private String lastActionBar = null; + + public void onChatReceived(Text message, boolean overlay) { + if (overlay) { + String actionBar = StringUtils.cleanColour(message.getString()); + if (lastActionBar != null && lastActionBar.equalsIgnoreCase(actionBar)) { + return; + } + lastActionBar = actionBar; + + List components = SPACE_SPLITTER.splitToList(actionBar); + + for (String component : components) { + Matcher matcher = SKILL_PATTERN_PERCENTAGE.matcher(component); + if (matcher.matches()) { + System.out.println(matcher); + String skillS = matcher.group(2); + String xpPercentageS = matcher.group(3).replace(",", ""); + + float xpPercentage = Float.parseFloat(xpPercentageS); + updateWithPercentage.put(skillS.toLowerCase(), xpPercentage); + } + } + } + } + + public void updateLevel(String skill, int level) { + if (updateWithPercentage.containsKey(skill)) { + SkillInfo skillInfo = new SkillInfo(); + skillInfo.totalXp = 0; + skillInfo.level = level; + + List levelingArray = PlayerSkills.SKILLS.get(skill).levels(); + for (int i = 0; i < levelingArray.size(); i++) { + float cap = levelingArray.get(i).level(); + if (i == level) { + skillInfo.currentXp += updateWithPercentage.get(skill) / 100f * cap; + skillInfo.totalXp += skillInfo.currentXp; + skillInfo.currentXpMax = cap; + break; + } else { + skillInfo.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); + } + } + updateWithPercentage.clear(); + } }