diff --git a/src/main/java/lel/flummi/skilloverlay/api/ApiSkills.java b/src/main/java/lel/flummi/skilloverlay/api/ApiSkills.java deleted file mode 100644 index 747e4b3..0000000 --- a/src/main/java/lel/flummi/skilloverlay/api/ApiSkills.java +++ /dev/null @@ -1,48 +0,0 @@ -package lel.flummi.skilloverlay.api; - -import java.io.InputStreamReader; -import java.net.URL; -import java.util.HashMap; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; - -import lel.flummi.skilloverlay.api.records.Skills; -import lel.flummi.skilloverlay.api.records.Skills.Skill; -import lel.flummi.skilloverlay.config.skilloverlayconfig; - -public class ApiSkills { - public static HashMap SKILLS; - - public static void init() { - String apikey = skilloverlayconfig.get().general.apiKey; - String apiurl = "https://api.hypixel.net/resources/skyblock/skills?key=" + apikey; - - if(apikey.length() > 0) { - Skills skills = ApiSkills.updateSkills(apiurl); - if(skills != null) { - SKILLS = skills.skills(); - } - else { - System.out.println("leer uff"); - } - } - } - - public static Skills updateSkills(String apiurl) { - if(apiurl.length() == 0) - return null; - - try { - URL url = new URL(apiurl); - InputStreamReader reader = new InputStreamReader(url.openStream()); - Gson gson = new GsonBuilder() - .serializeNulls() - .create(); - return gson.fromJson(reader, Skills.class); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } -} diff --git a/src/main/java/lel/flummi/skilloverlay/api/PlayerProfile.java b/src/main/java/lel/flummi/skilloverlay/api/PlayerProfile.java index 687c192..aedeb16 100644 --- a/src/main/java/lel/flummi/skilloverlay/api/PlayerProfile.java +++ b/src/main/java/lel/flummi/skilloverlay/api/PlayerProfile.java @@ -4,6 +4,8 @@ import net.minecraft.client.MinecraftClient; import java.io.InputStreamReader; import java.net.URL; +import java.util.Timer; +import java.util.TimerTask; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -13,39 +15,52 @@ import lel.flummi.skilloverlay.api.records.Profile.Profiles.Member; import lel.flummi.skilloverlay.config.skilloverlayconfig; public class PlayerProfile { - public static Member PROFILE; + public static Member PROFILE; + private static Timer timerTask; + private static boolean timerSet; - public static void init() { - 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; + public static void init(Boolean timer) { + if (timer && !timerSet) { + timerTask = new Timer("Timer"); + timerTask.scheduleAtFixedRate(new TimerTask() { + public void run() { + PlayerProfile.init(false); + } + }, 1000L, 1000L * 60L); + timerSet = true; + } - 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"); - } - } - } + 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; - public static Profile updateProfile(String apiurl) { - if(apiurl.length() == 0) - return null; + 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"); + } + } - try { - URL url = new URL(apiurl); - InputStreamReader reader = new InputStreamReader(url.openStream()); - Gson gson = new GsonBuilder() - .serializeNulls() - .create(); - return gson.fromJson(reader, Profile.class); - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } + System.out.println("API update! (every minute)"); + } + + public static Profile updateProfile(String apiurl) { + if (apiurl.length() == 0) + return null; + + try { + URL url = new URL(apiurl); + InputStreamReader reader = new InputStreamReader(url.openStream()); + Gson gson = new GsonBuilder() + .serializeNulls() + .create(); + return gson.fromJson(reader, Profile.class); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } } diff --git a/src/main/java/lel/flummi/skilloverlay/api/PlayerSkills.java b/src/main/java/lel/flummi/skilloverlay/api/PlayerSkills.java new file mode 100644 index 0000000..8632d88 --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/api/PlayerSkills.java @@ -0,0 +1,47 @@ +package lel.flummi.skilloverlay.api; + +import java.io.InputStreamReader; +import java.net.URL; +import java.util.HashMap; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import lel.flummi.skilloverlay.api.records.Skills; +import lel.flummi.skilloverlay.api.records.Skills.Skill; +import lel.flummi.skilloverlay.config.skilloverlayconfig; + +public class PlayerSkills { + public static HashMap SKILLS; + + public static void init() { + String apikey = skilloverlayconfig.get().general.apiKey; + String apiurl = "https://api.hypixel.net/resources/skyblock/skills?key=" + apikey; + + if (apikey.length() > 0) { + Skills skills = PlayerSkills.updateSkills(apiurl); + if (skills != null) { + SKILLS = skills.skills(); + } else { + System.out.println("leer uff"); + } + } + } + + public static Skills updateSkills(String apiurl) { + if (apiurl.length() == 0) + return null; + + try { + URL url = new URL(apiurl); + InputStreamReader reader = new InputStreamReader(url.openStream()); + Gson gson = new GsonBuilder() + .serializeNulls() + .create(); + return gson.fromJson(reader, Skills.class); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/src/main/java/lel/flummi/skilloverlay/api/records/Profile.java b/src/main/java/lel/flummi/skilloverlay/api/records/Profile.java index f638ba1..64db4f5 100644 --- a/src/main/java/lel/flummi/skilloverlay/api/records/Profile.java +++ b/src/main/java/lel/flummi/skilloverlay/api/records/Profile.java @@ -6,17 +6,15 @@ import java.util.HashMap; import com.google.gson.annotations.SerializedName; public record Profile( - boolean success, - List profiles -) { - public record Profiles( - @SerializedName("profile_id") String profileId, - @SerializedName("last_save") long lastSave, - HashMap members, - boolean selected - ) { - public record Member( - double experience_skill_farming - ){} - } + boolean success, + List profiles) { + public record Profiles( + @SerializedName("profile_id") String profileId, + @SerializedName("last_save") long lastSave, + HashMap members, + boolean selected) { + public record Member( + float experience_skill_farming) { + } + } } 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 219d09c..537b24b 100644 --- a/src/main/java/lel/flummi/skilloverlay/api/records/Skills.java +++ b/src/main/java/lel/flummi/skilloverlay/api/records/Skills.java @@ -3,31 +3,32 @@ package lel.flummi.skilloverlay.api.records; import java.util.HashMap; import java.util.List; +import lel.flummi.skilloverlay.utils.SkillInfo; + public record Skills( - HashMap skills -) { - public record Skill( - String name, - int maxLevel, - List levels - ) { - public record Level( - int level, - long totalExpRequired - ) {} + HashMap skills) { + public record Skill( + String name, + int maxLevel, + List levels) { + public record Level( + int level, + float totalExpRequired) { + } - public int getLevel(double exp) { - int aktLevel = 0; + public SkillInfo getLevel(float exp) { + int aktLevel = 0; - for(Level tmp: this.levels()) { - System.out.println((exp > tmp.totalExpRequired) + "; exp: " + exp + "; ter: " + tmp.totalExpRequired); - if(exp < tmp.totalExpRequired) { - return aktLevel; - } - aktLevel = tmp.level; - } + 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); + } + aktLevel = tmp.level; + } - return 0; - } - } + return null; + } + + } } diff --git a/src/main/java/lel/flummi/skilloverlay/config/skilloverlayconfig.java b/src/main/java/lel/flummi/skilloverlay/config/skilloverlayconfig.java index f9bb554..00b919d 100644 --- a/src/main/java/lel/flummi/skilloverlay/config/skilloverlayconfig.java +++ b/src/main/java/lel/flummi/skilloverlay/config/skilloverlayconfig.java @@ -8,19 +8,19 @@ import me.shedaniel.autoconfig.serializer.GsonConfigSerializer; @Config(name = "skilloverlay") public class skilloverlayconfig implements ConfigData { - @ConfigEntry.Category("general") - @ConfigEntry.Gui.TransitiveObject - public General general = new General(); + @ConfigEntry.Category("general") + @ConfigEntry.Gui.TransitiveObject + public General general = new General(); - public static class General { - public String apiKey = ""; - } + public static class General { + public String apiKey = ""; + } - public static void init() { - AutoConfig.register(skilloverlayconfig.class, GsonConfigSerializer::new); - } + public static void init() { + AutoConfig.register(skilloverlayconfig.class, GsonConfigSerializer::new); + } - public static skilloverlayconfig get() { - return AutoConfig.getConfigHolder(skilloverlayconfig.class).getConfig(); - } + public static skilloverlayconfig get() { + return AutoConfig.getConfigHolder(skilloverlayconfig.class).getConfig(); + } } diff --git a/src/main/java/lel/flummi/skilloverlay/mixin/GameRenderMixin.java b/src/main/java/lel/flummi/skilloverlay/mixin/GameRenderMixin.java index 1c1a957..6417509 100644 --- a/src/main/java/lel/flummi/skilloverlay/mixin/GameRenderMixin.java +++ b/src/main/java/lel/flummi/skilloverlay/mixin/GameRenderMixin.java @@ -6,7 +6,9 @@ import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.gui.hud.InGameHud; import net.minecraft.client.util.math.MatrixStack; + import org.spongepowered.asm.mixin.Mixin; + import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -16,10 +18,12 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Environment(EnvType.CLIENT) @Mixin(InGameHud.class) public abstract class GameRenderMixin { - @Shadow @Final private MinecraftClient client; + @Shadow + @Final + private MinecraftClient client; - @Inject(at = @At("RETURN"), method = "render") - private void render(MatrixStack matrices, float tickDelta, CallbackInfo ci) { - skilloverlay.OVERLAY.render(matrices, client); - } + @Inject(method = "render", at = @At("RETURN")) + private void render(MatrixStack matrices, float tickDelta, CallbackInfo ci) { + skilloverlay.OVERLAY.render(matrices, client); + } } diff --git a/src/main/java/lel/flummi/skilloverlay/overlays/FarmingOverlay.java b/src/main/java/lel/flummi/skilloverlay/overlays/FarmingOverlay.java index 6d3e929..f1a8085 100644 --- a/src/main/java/lel/flummi/skilloverlay/overlays/FarmingOverlay.java +++ b/src/main/java/lel/flummi/skilloverlay/overlays/FarmingOverlay.java @@ -8,8 +8,10 @@ import net.minecraft.util.Formatting; import net.minecraft.client.gui.DrawableHelper; import com.mojang.blaze3d.systems.RenderSystem; -//import lel.flummi.skilloverlay.skilloverlay; +import lel.flummi.skilloverlay.api.PlayerProfile; +import lel.flummi.skilloverlay.api.PlayerSkills; import lel.flummi.skilloverlay.utils.LerpUtils; +import lel.flummi.skilloverlay.utils.SkillInfo; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; @@ -20,256 +22,370 @@ import java.util.LinkedList; @Environment(EnvType.CLIENT) public class FarmingOverlay extends DrawableHelper { - private MinecraftClient client; - private MatrixStack matrixStack; + private MinecraftClient client; + private MatrixStack matrixStack; - private long lastUpdate = -1; - private final LinkedList counterQueue = new LinkedList<>(); - private int cultivatingTier = -1; - private String cultivatingTierAmount = "1"; - private long counter = -1; - private int cultivating = -1; - private int cultivatingLast = -1; - private float cropsPerSecondLast = 0; - private float cropsPerSecond = 0; - private ArrayList cropsOverLastXSeconds = new ArrayList<>(); - private String cropName; + private long lastUpdate = -1; + private final LinkedList counterQueue = new LinkedList<>(); + private int cultivatingTier = -1; + private String cultivatingTierAmount = "1"; + private long counter = -1; + private int cultivating = -1; + private int cultivatingLast = -1; + private float cropsPerSecondLast = 0; + private float cropsPerSecond = 0; + private ArrayList cropsOverLastXSeconds = new ArrayList<>(); + private String cropName; - public FarmingOverlay() { - /*HudRenderCallback.EVENT.register((matrixStack, tickDelta) -> { - if(client.player == null) - return; - this.render(matrixStack, client); - });*/ - } + private SkillInfo skillInfo = null; + private SkillInfo skillInfoLast = null; + private float lastTotalXp = -1; + private boolean isFarming = false; + private final LinkedList xpGainQueue = new LinkedList<>(); + private float xpGainHourLast = -1; + private float xpGainHour = -1; + private int xpGainTimer = 0; - public void render(MatrixStack matrixStack, MinecraftClient client) { - if (client.player == null) - return; + public FarmingOverlay() { + /* + * HudRenderCallback.EVENT.register((matrixStack, tickDelta) -> { + * if(client.player == null) + * return; + * this.render(matrixStack, client); + * }); + */ + } - this.matrixStack = matrixStack; - this.client = MinecraftClient.getInstance(); + public void render(MatrixStack matrixStack, MinecraftClient client) { + if (client.player == null) + return; - RenderSystem.enableBlend(); - this.renderOverlay(); + this.matrixStack = matrixStack; + this.client = MinecraftClient.getInstance(); - this.client.getProfiler().pop(); - } + RenderSystem.enableBlend(); + this.renderOverlay(); - public void renderOverlay() { - this.lastUpdate = System.currentTimeMillis(); - ItemStack heldItem = client.player.getMainHandStack(); - String internalName = ""; - this.counter = 0; - boolean holdingFarmItem = false; - this.cultivatingLast = cultivating; - this.cultivating = 0; + this.client.getProfiler().pop(); + } - //System.out.println(skilloverlay.PROFILE.data().skills().get("farming").level()); + public void renderOverlay() { + this.lastUpdate = System.currentTimeMillis(); + ItemStack heldItem = client.player.getMainHandStack(); + String internalName = ""; + this.counter = -1; + boolean holdingFarmItem = false; + this.cultivatingLast = cultivating; + this.cultivating = 0; + xpGainHourLast = xpGainHour; - if (heldItem != null) { - NbtCompound tag = heldItem.getNbt(); + // System.out.println(skilloverlay.PROFILE.data().skills().get("farming").level()); - if (tag != null && tag.contains("ExtraAttributes", 10)) { - NbtCompound ea = tag.getCompound("ExtraAttributes"); - internalName = ea.getString("id"); + if (heldItem != null) { + NbtCompound tag = heldItem.getNbt(); - for (CropType crop : CropType.values()) { + if (tag != null && tag.contains("ExtraAttributes", 10)) { + NbtCompound ea = tag.getCompound("ExtraAttributes"); + internalName = ea.getString("id"); + + for (CropType crop : CropType.values()) { if (internalName.startsWith(crop.toolName)) { this.cropName = crop.item; - holdingFarmItem = true; + holdingFarmItem = true; } } - if(holdingFarmItem) { - if (ea.contains("mined_crops", 99)) { - this.counter = ea.getLong("mined_crops"); - cultivating = ea.getInt("farmed_cultivating"); - this.counterQueue.add(0, this.counter); - } else if (ea.contains("farmed_cultivating", 99)) { - this.counter = ea.getInt("farmed_cultivating"); - cultivating = ea.getInt("farmed_cultivating"); - this.counterQueue.add(0, this.counter); - } - } - else - holdingFarmItem = false; - } + if (holdingFarmItem) { + if (ea.contains("mined_crops", 99)) { + this.counter = ea.getLong("mined_crops"); + cultivating = ea.getInt("farmed_cultivating"); + this.counterQueue.add(0, this.counter); + } else if (ea.contains("farmed_cultivating", 99)) { + this.counter = ea.getInt("farmed_cultivating"); + cultivating = ea.getInt("farmed_cultivating"); + this.counterQueue.add(0, this.counter); + } + } else + holdingFarmItem = false; + } - if (this.cultivating < 1000) { - this.cultivatingTier = 1; - this.cultivatingTierAmount = "1,000"; - } else if (this.cultivating < 5000) { - this.cultivatingTier = 2; - this.cultivatingTierAmount = "5,000"; - } else if (this.cultivating < 25000) { - this.cultivatingTier = 3; - this.cultivatingTierAmount = "25,000"; - } else if (this.cultivating < 100000) { - this.cultivatingTier = 4; - this.cultivatingTierAmount = "100,000"; - } else if (this.cultivating < 300000) { - this.cultivatingTier = 5; - this.cultivatingTierAmount = "300,000"; - } else if (this.cultivating < 1500000) { - this.cultivatingTier = 6; - this.cultivatingTierAmount = "1,500,000"; - } else if (this.cultivating < 5000000) { - this.cultivatingTier = 7; - this.cultivatingTierAmount = "5,000,000"; - } else if (this.cultivating < 20000000) { - this.cultivatingTier = 8; - this.cultivatingTierAmount = "20,000,000"; - } else if (this.cultivating < 100000000) { - this.cultivatingTier = 9; - this.cultivatingTierAmount = "100,000,000"; - } else if (this.cultivating > 100000000) { - this.cultivatingTier = 10; - this.cultivatingTierAmount = "Maxed"; - } - } + if (this.cultivating < 1000) { + this.cultivatingTier = 1; + this.cultivatingTierAmount = "1,000"; + } else if (this.cultivating < 5000) { + this.cultivatingTier = 2; + this.cultivatingTierAmount = "5,000"; + } else if (this.cultivating < 25000) { + this.cultivatingTier = 3; + this.cultivatingTierAmount = "25,000"; + } else if (this.cultivating < 100000) { + this.cultivatingTier = 4; + this.cultivatingTierAmount = "100,000"; + } else if (this.cultivating < 300000) { + this.cultivatingTier = 5; + this.cultivatingTierAmount = "300,000"; + } else if (this.cultivating < 1500000) { + this.cultivatingTier = 6; + this.cultivatingTierAmount = "1,500,000"; + } else if (this.cultivating < 5000000) { + this.cultivatingTier = 7; + this.cultivatingTierAmount = "5,000,000"; + } else if (this.cultivating < 20000000) { + this.cultivatingTier = 8; + this.cultivatingTierAmount = "20,000,000"; + } else if (this.cultivating < 100000000) { + this.cultivatingTier = 9; + this.cultivatingTierAmount = "100,000,000"; + } else if (this.cultivating > 100000000) { + this.cultivatingTier = 10; + this.cultivatingTierAmount = "Maxed"; + } + } - while (this.counterQueue.size() >= 4) { - this.counterQueue.removeLast(); - } + skillInfoLast = skillInfo; + skillInfo = PlayerSkills.SKILLS.get("FARMING").getLevel(PlayerProfile.PROFILE.experience_skill_farming()); + if (skillInfo != null) { + float totalXp = skillInfo.totalXp; + if (lastTotalXp > 0) { + float delta = totalXp - lastTotalXp; + if (delta > 0 && delta < 1000) { + xpGainTimer = 3; - if (this.counterQueue.isEmpty()) { - this.cropsPerSecond = -1; - this.cropsPerSecondLast = 0; - } else { - this.cropsPerSecondLast = this.cropsPerSecond; - long last = this.counterQueue.getLast(); - long first = this.counterQueue.getFirst(); - while (this.cropsOverLastXSeconds.size() > 60) { - this.cropsOverLastXSeconds.remove(0); - } - if ((first - last) / 2f != 0) { - this.cropsOverLastXSeconds.add((first - last) / 2f); - } else { - if (this.cropsPerSecondLast == 0) { - int i = 12; - while (i > 0) { - i--; - if (this.cropsOverLastXSeconds.size() > 0) { - this.cropsOverLastXSeconds.remove(0); - } else { - break; - } - } - } - } + xpGainQueue.add(0, delta); + while (xpGainQueue.size() > 30) { + xpGainQueue.removeLast(); + } - if (!holdingFarmItem) { - this.cropsOverLastXSeconds.clear(); - this.cropsPerSecond = -1; - this.cropsPerSecondLast = 0; - } + float totalGain = 0; + for (float f : xpGainQueue) + totalGain += f; - ArrayList temp = new ArrayList<>(cropsOverLastXSeconds); - if (this.cropsOverLastXSeconds.size() >= 3) { - temp.remove(Collections.min(temp)); - } - if (this.cropsOverLastXSeconds.size() >= 6) { - temp.remove(Collections.min(temp)); - temp.remove(Collections.max(temp)); - } - if (this.cropsOverLastXSeconds.size() >= 10) { - temp.remove(Collections.max(temp)); - } + xpGainHour = totalGain * (60 * 60) / xpGainQueue.size(); - float cropsOverLastXSecondsTotal = 0; - for (Float crops : temp) { - cropsOverLastXSecondsTotal += crops; - } - this.cropsPerSecond = temp.size() != 0 && cropsOverLastXSecondsTotal != 0 - ? cropsOverLastXSecondsTotal / temp.size() - : 0; - } + isFarming = true; + } else if (xpGainTimer > 0) { + xpGainTimer--; - ArrayList overlayStringList = new ArrayList<>(); - NumberFormat format = NumberFormat.getIntegerInstance(); + xpGainQueue.add(0, 0f); + while (xpGainQueue.size() > 30) { + xpGainQueue.removeLast(); + } - // Add all the lines to the array - if (this.counter >= 0 && this.cultivating != this.counter) { - overlayStringList.add(new OverlayString("Counter", format.format(this.counter))); - } + float totalGain = 0; + for (float f : xpGainQueue) + totalGain += f; - if (this.counter >= 0) { - if (this.cropsPerSecondLast == this.cropsPerSecond && this.cropsPerSecond <= 0) { - overlayStringList.add(new OverlayString(this.cropName + "/m", "N/A")); - } else { - float cpsInterp = interp(this.cropsPerSecond, this.cropsPerSecondLast); - overlayStringList.add(new OverlayString(this.cropName + "/m", String.format("%,.2f", cpsInterp * 60 * 30))); - } - } + xpGainHour = totalGain * (60 * 60) / xpGainQueue.size(); - if (this.cultivatingTier <= 9 && this.cultivating > 0) { - int counterInterp = (int) interp(this.cultivating, this.cultivatingLast); - overlayStringList.add(new OverlayString("Cultivating", format.format(counterInterp) + "/" + this.cultivatingTierAmount)); - } - if (this.cultivatingTier == 10) { - int counterInterp = (int) interp(this.cultivating, this.cultivatingLast); - overlayStringList.add(new OverlayString("Cultivating", format.format(counterInterp))); - } + isFarming = true; + } else if (delta <= 0) { + isFarming = false; + } - float yaw = client.player.getYaw(); - float pitch = client.player.getPitch(); - yaw %= 360; - if (yaw < 0) - yaw += 360; - if (yaw > 180) - yaw -= 360; - pitch %= 360; - if (pitch < 0) - pitch += 360; - if (pitch > 180) - pitch -= 360; + lastTotalXp = totalXp; + } + } - overlayStringList.add(new OverlayString("Yaw", String.format("%.2f", yaw) + Formatting.BOLD + "\u1D52")); - overlayStringList.add(new OverlayString("Pitch", String.format("%.2f", pitch) + Formatting.BOLD + "\u1D52")); + while (this.counterQueue.size() >= 4) { + this.counterQueue.removeLast(); + } - if (!holdingFarmItem) { - overlayStringList.clear(); - } + if (this.counterQueue.isEmpty()) { + this.cropsPerSecond = -1; + this.cropsPerSecondLast = 0; + } else { + this.cropsPerSecondLast = this.cropsPerSecond; + long last = this.counterQueue.getLast(); + long first = this.counterQueue.getFirst(); + while (this.cropsOverLastXSeconds.size() > 60) { + this.cropsOverLastXSeconds.remove(0); + } + if ((first - last) / 2f != 0) { + this.cropsOverLastXSeconds.add((first - last) / 2f); + } else { + if (this.cropsPerSecondLast == 0) { + int i = 12; + while (i > 0) { + i--; + if (this.cropsOverLastXSeconds.size() > 0) { + this.cropsOverLastXSeconds.remove(0); + } else { + break; + } + } + } + } - // Draw HUD - int xAxis = 10; - int yAxis = 200; + if (!holdingFarmItem) { + this.cropsOverLastXSeconds.clear(); + this.cropsPerSecond = -1; + this.cropsPerSecondLast = 0; + } - // Get the longest string in the array - int longestString = 0; - int BoxWidth = 0; - for (OverlayString s : overlayStringList) { - String combined = s.toString(); - if (combined.length() > longestString) { - longestString = combined.length(); - BoxWidth = this.client.textRenderer.getWidth(combined); - } - } + ArrayList temp = new ArrayList<>(cropsOverLastXSeconds); + if (this.cropsOverLastXSeconds.size() >= 3) { + temp.remove(Collections.min(temp)); + } + if (this.cropsOverLastXSeconds.size() >= 6) { + temp.remove(Collections.min(temp)); + temp.remove(Collections.max(temp)); + } + if (this.cropsOverLastXSeconds.size() >= 10) { + temp.remove(Collections.max(temp)); + } - int lineHeight = this.client.textRenderer.fontHeight + 2; + float cropsOverLastXSecondsTotal = 0; + for (Float crops : temp) { + cropsOverLastXSecondsTotal += crops; + } + this.cropsPerSecond = temp.size() != 0 && cropsOverLastXSecondsTotal != 0 + ? cropsOverLastXSecondsTotal / temp.size() + : 0; + } - DrawableHelper.fill(matrixStack, xAxis, yAxis, xAxis + BoxWidth + 10, - yAxis + ((lineHeight + 1) * overlayStringList.size()), 0x64000000); + ArrayList overlayStringList = new ArrayList<>(); + NumberFormat format = NumberFormat.getIntegerInstance(); - for (OverlayString line : overlayStringList) { - int offset = 5; + // Add all the lines to the array + if (this.counter >= 0 && this.cultivating != this.counter) { + overlayStringList.add(new OverlayString("Counter", format.format(this.counter))); + } - this.client.textRenderer.drawWithShadow(this.matrixStack, line.toString(), xAxis + offset, yAxis + offset, 0xFFFFFF); - yAxis += lineHeight; - } - } + if (this.counter >= 0) { + if (this.cropsPerSecondLast == this.cropsPerSecond && this.cropsPerSecond <= 0) { + overlayStringList.add(new OverlayString(this.cropName + "/m", "N/A")); + } else { + float cpsInterp = interp(this.cropsPerSecond, this.cropsPerSecondLast); + overlayStringList + .add(new OverlayString(this.cropName + "/m", String.format("%,.2f", cpsInterp * 60 * 30))); + } + } - private float interp(float now, float last) { - float interp = now; - if (last >= 0 && last != now) { - float factor = (System.currentTimeMillis() - this.lastUpdate) / 1000f; - factor = LerpUtils.clampZeroOne(factor); - interp = last + (now - last) * factor; - } - return interp; - } + if (this.cultivatingTier <= 9 && this.cultivating > 0) { + int counterInterp = (int) interp(this.cultivating, this.cultivatingLast); + overlayStringList.add( + new OverlayString("Cultivating", format.format(counterInterp) + "/" + this.cultivatingTierAmount)); + } + if (this.cultivatingTier == 10) { + int counterInterp = (int) interp(this.cultivating, this.cultivatingLast); + overlayStringList.add(new OverlayString("Cultivating", format.format(counterInterp))); + } - private enum CropType { + // xp + float xpInterp = xpGainHour; + if (xpGainHourLast == xpGainHour && xpGainHour <= 0) { + overlayStringList.add(new OverlayString("XP/h", "N/A")); + } else { + xpInterp = interp(xpGainHour, xpGainHourLast); + overlayStringList.add(new OverlayString("XP/h", + format.format(xpInterp) + (isFarming ? "" : Formatting.RED + " (PAUSED)"))); + } + + // skillinfo + if (skillInfo != null && skillInfo.level < 60) { + StringBuilder levelStr = new StringBuilder(skillInfo.level); + levelStr.append(Formatting.GRAY) + .append("["); + + float progress = skillInfo.currentXp / skillInfo.currentXpMax; + if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) { + progress = interp(progress, skillInfoLast.currentXp / skillInfoLast.currentXpMax); + } + + float lines = 25; + for (int i = 0; i < lines; i++) { + if (i / lines < progress) { + levelStr.append(Formatting.YELLOW); + } else { + levelStr.append(Formatting.DARK_GRAY); + } + levelStr.append('|'); + } + + levelStr.append(Formatting.GRAY) + .append("] ") + .append(Formatting.YELLOW) + .append((int) (progress * 100)) + .append("%"); + + int current = (int) skillInfo.currentXp; + if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) { + current = (int) interp(current, skillInfoLast.currentXp); + } + + int remaining = (int) (skillInfo.currentXpMax - skillInfo.currentXp); + if (skillInfoLast != null && skillInfo.currentXpMax == skillInfoLast.currentXpMax) { + remaining = (int) interp(remaining, (int) (skillInfoLast.currentXpMax - skillInfoLast.currentXp)); + } + + overlayStringList.add(new OverlayString("Farming", levelStr.toString())); + overlayStringList.add(new OverlayString("Current XP", format.format(current))); + + if (remaining < 0) { + overlayStringList.add(new OverlayString("Remaining XP", "Maxed!")); + // overlayStringList.add(new OverlayString("ETA", "Maxed!")); + } else { + overlayStringList.add(new OverlayString("Remaining XP", format.format(remaining))); + if (xpGainHour < 1000) { + // overlayStringList.add(new OverlayString("ETA", "N/A")); + } else { + // overlayStringList.add(new OverlayString("ETA", ); + } + } + } + + float yaw = client.player.getYaw(); + float pitch = client.player.getPitch(); + yaw %= 360; + if (yaw < 0) + yaw += 360; + if (yaw > 180) + yaw -= 360; + pitch %= 360; + if (pitch < 0) + pitch += 360; + if (pitch > 180) + pitch -= 360; + + overlayStringList.add(new OverlayString("Yaw", String.format("%.2f", yaw) + Formatting.BOLD + "\u1D52")); + overlayStringList.add(new OverlayString("Pitch", String.format("%.2f", pitch) + Formatting.BOLD + "\u1D52")); + + if (!holdingFarmItem) { + overlayStringList.clear(); + } + + // Draw HUD + int xAxis = 10; + int yAxis = 200; + + if (!overlayStringList.isEmpty()) { + int BoxWidth = overlayStringList.stream().map(t -> this.client.textRenderer.getWidth(t.toString())) + .max(Integer::compareTo).get(); + int lineHeight = this.client.textRenderer.fontHeight + 2; + int offset = 5; + + DrawableHelper.fill(matrixStack, xAxis, yAxis, xAxis + BoxWidth + (offset * 2), + yAxis + ((lineHeight + 1) * overlayStringList.size()), 0x64000000); + + for (OverlayString line : overlayStringList) { + this.client.textRenderer.drawWithShadow(this.matrixStack, line.toString(), xAxis + offset, + yAxis + offset, + 0xFFFFFF); + yAxis += lineHeight; + } + } + } + + private float interp(float now, float last) { + float interp = now; + if (last >= 0 && last != now) { + float factor = (System.currentTimeMillis() - this.lastUpdate) / 1000f; + factor = LerpUtils.clampZeroOne(factor); + interp = last + (now - last) * factor; + } + return interp; + } + + private enum CropType { WHEAT("THEORETICAL_HOE_WHEAT", "Wheat"), NETHER_WART("THEORETICAL_HOE_WARTS", "Warts"), SUGAR_CANE("THEORETICAL_HOE_CANE", "Sugar"), @@ -290,17 +406,17 @@ public class FarmingOverlay extends DrawableHelper { } } - private class OverlayString { - final String type; - final String text; + private class OverlayString { + final String type; + final String text; - private OverlayString(String type, String text) { - this.type = type; - this.text = text; - } + private OverlayString(String type, String text) { + this.type = type; + this.text = text; + } - public String toString() { - return Formatting.AQUA + this.type + ": " + Formatting.YELLOW + this.text; - } - } + public String toString() { + return Formatting.AQUA + this.type + ": " + Formatting.YELLOW + this.text; + } + } } diff --git a/src/main/java/lel/flummi/skilloverlay/skilloverlay.java b/src/main/java/lel/flummi/skilloverlay/skilloverlay.java index 6cd2b80..1d0e509 100644 --- a/src/main/java/lel/flummi/skilloverlay/skilloverlay.java +++ b/src/main/java/lel/flummi/skilloverlay/skilloverlay.java @@ -1,24 +1,33 @@ package lel.flummi.skilloverlay; import net.fabricmc.api.ModInitializer; - +//import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents; import lel.flummi.skilloverlay.overlays.FarmingOverlay; + import lel.flummi.skilloverlay.api.PlayerProfile; -import lel.flummi.skilloverlay.api.ApiSkills; -import lel.flummi.skilloverlay.config.skilloverlayconfig; +import lel.flummi.skilloverlay.api.PlayerSkills; +import lel.flummi.skilloverlay.config.skilloverlayconfig; public class skilloverlay implements ModInitializer { - public static FarmingOverlay OVERLAY; - public static PlayerProfile API; + public static FarmingOverlay OVERLAY; + public static PlayerProfile API; - @Override - public void onInitialize() { - System.out.println("Skilloverlay started."); + @Override + public void onInitialize() { + System.out.println("Skilloverlay started."); - skilloverlayconfig.init(); - OVERLAY = new FarmingOverlay(); + skilloverlayconfig.init(); + OVERLAY = new FarmingOverlay(); - ApiSkills.init(); - PlayerProfile.init(); - } + PlayerSkills.init(); + PlayerProfile.init(false); + + /* + * ClientReceiveMessageEvents.ALLOW_GAME.register((message, overlay) -> { + * System.out.println("message: " + message.getContent() + "; overlay: " + + * overlay); + * return true; + * }); + */ + } } diff --git a/src/main/java/lel/flummi/skilloverlay/utils/LerpUtils.java b/src/main/java/lel/flummi/skilloverlay/utils/LerpUtils.java index 4b04b5b..84b0224 100644 --- a/src/main/java/lel/flummi/skilloverlay/utils/LerpUtils.java +++ b/src/main/java/lel/flummi/skilloverlay/utils/LerpUtils.java @@ -1,24 +1,24 @@ package lel.flummi.skilloverlay.utils; public class LerpUtils { - public static float clampZeroOne(float f) { - return Math.max(0, Math.min(1, f)); - } + public static float clampZeroOne(float f) { + return Math.max(0, Math.min(1, f)); + } - public static float sigmoid(float val) { - return (float) (1 / (1 + Math.exp(-val))); - } + public static float sigmoid(float val) { + return (float) (1 / (1 + Math.exp(-val))); + } - private static final float sigmoidStr = 8; - private static final float sigmoidA = -1 / (sigmoid(-0.5f * sigmoidStr) - sigmoid(0.5f * sigmoidStr)); - private static final float sigmoidB = sigmoidA * sigmoid(-0.5f * sigmoidStr); + private static final float sigmoidStr = 8; + private static final float sigmoidA = -1 / (sigmoid(-0.5f * sigmoidStr) - sigmoid(0.5f * sigmoidStr)); + private static final float sigmoidB = sigmoidA * sigmoid(-0.5f * sigmoidStr); - public static float sigmoidZeroOne(float f) { - f = clampZeroOne(f); - return sigmoidA * sigmoid(sigmoidStr * (f - 0.5f)) - sigmoidB; - } + public static float sigmoidZeroOne(float f) { + f = clampZeroOne(f); + return sigmoidA * sigmoid(sigmoidStr * (f - 0.5f)) - sigmoidB; + } - public static float lerp(float a, float b, float amount) { - return b + (a - b) * clampZeroOne(amount); - } + public static float lerp(float a, float b, float amount) { + return b + (a - b) * clampZeroOne(amount); + } } diff --git a/src/main/java/lel/flummi/skilloverlay/utils/SkillInfo.java b/src/main/java/lel/flummi/skilloverlay/utils/SkillInfo.java new file mode 100644 index 0000000..5060182 --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/utils/SkillInfo.java @@ -0,0 +1,16 @@ +package lel.flummi.skilloverlay.utils; + +public class SkillInfo { + public final int 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) { + this.level = level; + this.totalXp = totalXp; + this.currentXp = currentXp; + this.currentXpMax = currentXpMax; + } +} diff --git a/src/main/java/lel/flummi/skilloverlay/utils/XPInformation.java b/src/main/java/lel/flummi/skilloverlay/utils/XPInformation.java new file mode 100644 index 0000000..234f8f9 --- /dev/null +++ b/src/main/java/lel/flummi/skilloverlay/utils/XPInformation.java @@ -0,0 +1,17 @@ +package lel.flummi.skilloverlay.utils; + +public class XPInformation { + private static final XPInformation INSTANCE = new XPInformation(); + + public static XPInformation getInstance() { + return INSTANCE; + } + + public static class SkillInfo { + public int level; + public float totalXp; + public float currentXp; + public float currentXpMax; + public boolean fromApi = false; + } +}