proper formatting
All checks were successful
build / build (push) Successful in 1m23s

This commit is contained in:
Flummi 2023-06-07 15:07:56 +02:00
parent d98070f7c0
commit 3358404a0f
Signed by: Flummi
GPG Key ID: AA2AEF822A6F4817
12 changed files with 562 additions and 387 deletions

View File

@ -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<String, Skill> 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;
}
}

View File

@ -4,6 +4,8 @@ import net.minecraft.client.MinecraftClient;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.URL; import java.net.URL;
import java.util.Timer;
import java.util.TimerTask;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
@ -13,39 +15,52 @@ import lel.flummi.skilloverlay.api.records.Profile.Profiles.Member;
import lel.flummi.skilloverlay.config.skilloverlayconfig; import lel.flummi.skilloverlay.config.skilloverlayconfig;
public class PlayerProfile { public class PlayerProfile {
public static Member PROFILE; public static Member PROFILE;
private static Timer timerTask;
private static boolean timerSet;
public static void init() { public static void init(Boolean timer) {
String apikey = skilloverlayconfig.get().general.apiKey; if (timer && !timerSet) {
String uuid = MinecraftClient.getInstance().getSession().getUuidOrNull().toString().replace("-", ""); timerTask = new Timer("Timer");
String apiurl = "https://api.hypixel.net/skyblock/profiles?key=" + apikey + "&uuid=" + uuid; timerTask.scheduleAtFixedRate(new TimerTask() {
public void run() {
PlayerProfile.init(false);
}
}, 1000L, 1000L * 60L);
timerSet = true;
}
if(apikey.length() > 0) { String apikey = skilloverlayconfig.get().general.apiKey;
Profile profile = PlayerProfile.updateProfile(apiurl); String uuid = MinecraftClient.getInstance().getSession().getUuidOrNull().toString().replace("-", "");
if(profile != null) { String apiurl = "https://api.hypixel.net/skyblock/profiles?key=" + apikey + "&uuid=" + uuid;
profile.profiles().removeIf(p -> !p.selected());
PROFILE = profile.profiles().get(0).members().get(uuid);
}
else {
System.out.println("leer uff");
}
}
}
public static Profile updateProfile(String apiurl) { if (apikey.length() > 0) {
if(apiurl.length() == 0) Profile profile = PlayerProfile.updateProfile(apiurl);
return null; if (profile != null) {
profile.profiles().removeIf(p -> !p.selected());
PROFILE = profile.profiles().get(0).members().get(uuid);
} else {
System.out.println("leer uff");
}
}
try { System.out.println("API update! (every minute)");
URL url = new URL(apiurl); }
InputStreamReader reader = new InputStreamReader(url.openStream());
Gson gson = new GsonBuilder() public static Profile updateProfile(String apiurl) {
.serializeNulls() if (apiurl.length() == 0)
.create(); return null;
return gson.fromJson(reader, Profile.class);
} catch (Exception e) { try {
e.printStackTrace(); URL url = new URL(apiurl);
} InputStreamReader reader = new InputStreamReader(url.openStream());
return null; Gson gson = new GsonBuilder()
} .serializeNulls()
.create();
return gson.fromJson(reader, Profile.class);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
} }

View File

@ -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<String, Skill> 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;
}
}

View File

@ -6,17 +6,15 @@ import java.util.HashMap;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
public record Profile( public record Profile(
boolean success, boolean success,
List<Profiles> profiles List<Profiles> profiles) {
) { public record Profiles(
public record Profiles( @SerializedName("profile_id") String profileId,
@SerializedName("profile_id") String profileId, @SerializedName("last_save") long lastSave,
@SerializedName("last_save") long lastSave, HashMap<String, Member> members,
HashMap<String, Member> members, boolean selected) {
boolean selected public record Member(
) { float experience_skill_farming) {
public record Member( }
double experience_skill_farming }
){}
}
} }

View File

@ -3,31 +3,32 @@ package lel.flummi.skilloverlay.api.records;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import lel.flummi.skilloverlay.utils.SkillInfo;
public record Skills( public record Skills(
HashMap<String, Skill> skills HashMap<String, Skill> skills) {
) { public record Skill(
public record Skill( String name,
String name, int maxLevel,
int maxLevel, List<Level> levels) {
List<Level> levels public record Level(
) { int level,
public record Level( float totalExpRequired) {
int level, }
long totalExpRequired
) {}
public int getLevel(double exp) { public SkillInfo getLevel(float exp) {
int aktLevel = 0; int aktLevel = 0;
for(Level tmp: this.levels()) { for (Level tmp : this.levels()) {
System.out.println((exp > tmp.totalExpRequired) + "; exp: " + exp + "; ter: " + tmp.totalExpRequired); if (exp < tmp.totalExpRequired) {
if(exp < tmp.totalExpRequired) { // int level, float totalXp, float currentXp, float currentXpMax
return aktLevel; return new SkillInfo(aktLevel, tmp.totalExpRequired, exp, tmp.totalExpRequired);
} }
aktLevel = tmp.level; aktLevel = tmp.level;
} }
return 0; return null;
} }
}
}
} }

View File

@ -8,19 +8,19 @@ import me.shedaniel.autoconfig.serializer.GsonConfigSerializer;
@Config(name = "skilloverlay") @Config(name = "skilloverlay")
public class skilloverlayconfig implements ConfigData { public class skilloverlayconfig implements ConfigData {
@ConfigEntry.Category("general") @ConfigEntry.Category("general")
@ConfigEntry.Gui.TransitiveObject @ConfigEntry.Gui.TransitiveObject
public General general = new General(); public General general = new General();
public static class General { public static class General {
public String apiKey = ""; public String apiKey = "";
} }
public static void init() { public static void init() {
AutoConfig.register(skilloverlayconfig.class, GsonConfigSerializer::new); AutoConfig.register(skilloverlayconfig.class, GsonConfigSerializer::new);
} }
public static skilloverlayconfig get() { public static skilloverlayconfig get() {
return AutoConfig.getConfigHolder(skilloverlayconfig.class).getConfig(); return AutoConfig.getConfigHolder(skilloverlayconfig.class).getConfig();
} }
} }

View File

@ -6,7 +6,9 @@ import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.minecraft.client.gui.hud.InGameHud; import net.minecraft.client.gui.hud.InGameHud;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@ -16,10 +18,12 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
@Mixin(InGameHud.class) @Mixin(InGameHud.class)
public abstract class GameRenderMixin { public abstract class GameRenderMixin {
@Shadow @Final private MinecraftClient client; @Shadow
@Final
private MinecraftClient client;
@Inject(at = @At("RETURN"), method = "render") @Inject(method = "render", at = @At("RETURN"))
private void render(MatrixStack matrices, float tickDelta, CallbackInfo ci) { private void render(MatrixStack matrices, float tickDelta, CallbackInfo ci) {
skilloverlay.OVERLAY.render(matrices, client); skilloverlay.OVERLAY.render(matrices, client);
} }
} }

View File

@ -8,8 +8,10 @@ import net.minecraft.util.Formatting;
import net.minecraft.client.gui.DrawableHelper; import net.minecraft.client.gui.DrawableHelper;
import com.mojang.blaze3d.systems.RenderSystem; 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.LerpUtils;
import lel.flummi.skilloverlay.utils.SkillInfo;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
@ -20,256 +22,370 @@ import java.util.LinkedList;
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public class FarmingOverlay extends DrawableHelper { public class FarmingOverlay extends DrawableHelper {
private MinecraftClient client; private MinecraftClient client;
private MatrixStack matrixStack; private MatrixStack matrixStack;
private long lastUpdate = -1; private long lastUpdate = -1;
private final LinkedList<Long> counterQueue = new LinkedList<>(); private final LinkedList<Long> counterQueue = new LinkedList<>();
private int cultivatingTier = -1; private int cultivatingTier = -1;
private String cultivatingTierAmount = "1"; private String cultivatingTierAmount = "1";
private long counter = -1; private long counter = -1;
private int cultivating = -1; private int cultivating = -1;
private int cultivatingLast = -1; private int cultivatingLast = -1;
private float cropsPerSecondLast = 0; private float cropsPerSecondLast = 0;
private float cropsPerSecond = 0; private float cropsPerSecond = 0;
private ArrayList<Float> cropsOverLastXSeconds = new ArrayList<>(); private ArrayList<Float> cropsOverLastXSeconds = new ArrayList<>();
private String cropName; private String cropName;
public FarmingOverlay() { private SkillInfo skillInfo = null;
/*HudRenderCallback.EVENT.register((matrixStack, tickDelta) -> { private SkillInfo skillInfoLast = null;
if(client.player == null) private float lastTotalXp = -1;
return; private boolean isFarming = false;
this.render(matrixStack, client); private final LinkedList<Float> xpGainQueue = new LinkedList<>();
});*/ private float xpGainHourLast = -1;
} private float xpGainHour = -1;
private int xpGainTimer = 0;
public void render(MatrixStack matrixStack, MinecraftClient client) { public FarmingOverlay() {
if (client.player == null) /*
return; * HudRenderCallback.EVENT.register((matrixStack, tickDelta) -> {
* if(client.player == null)
* return;
* this.render(matrixStack, client);
* });
*/
}
this.matrixStack = matrixStack; public void render(MatrixStack matrixStack, MinecraftClient client) {
this.client = MinecraftClient.getInstance(); if (client.player == null)
return;
RenderSystem.enableBlend(); this.matrixStack = matrixStack;
this.renderOverlay(); this.client = MinecraftClient.getInstance();
this.client.getProfiler().pop(); RenderSystem.enableBlend();
} this.renderOverlay();
public void renderOverlay() { this.client.getProfiler().pop();
this.lastUpdate = System.currentTimeMillis(); }
ItemStack heldItem = client.player.getMainHandStack();
String internalName = "";
this.counter = 0;
boolean holdingFarmItem = false;
this.cultivatingLast = cultivating;
this.cultivating = 0;
//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) { // System.out.println(skilloverlay.PROFILE.data().skills().get("farming").level());
NbtCompound tag = heldItem.getNbt();
if (tag != null && tag.contains("ExtraAttributes", 10)) { if (heldItem != null) {
NbtCompound ea = tag.getCompound("ExtraAttributes"); NbtCompound tag = heldItem.getNbt();
internalName = ea.getString("id");
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)) { if (internalName.startsWith(crop.toolName)) {
this.cropName = crop.item; this.cropName = crop.item;
holdingFarmItem = true; holdingFarmItem = true;
} }
} }
if(holdingFarmItem) { if (holdingFarmItem) {
if (ea.contains("mined_crops", 99)) { if (ea.contains("mined_crops", 99)) {
this.counter = ea.getLong("mined_crops"); this.counter = ea.getLong("mined_crops");
cultivating = ea.getInt("farmed_cultivating"); cultivating = ea.getInt("farmed_cultivating");
this.counterQueue.add(0, this.counter); this.counterQueue.add(0, this.counter);
} else if (ea.contains("farmed_cultivating", 99)) { } else if (ea.contains("farmed_cultivating", 99)) {
this.counter = ea.getInt("farmed_cultivating"); this.counter = ea.getInt("farmed_cultivating");
cultivating = ea.getInt("farmed_cultivating"); cultivating = ea.getInt("farmed_cultivating");
this.counterQueue.add(0, this.counter); this.counterQueue.add(0, this.counter);
} }
} } else
else holdingFarmItem = false;
holdingFarmItem = false; }
}
if (this.cultivating < 1000) { if (this.cultivating < 1000) {
this.cultivatingTier = 1; this.cultivatingTier = 1;
this.cultivatingTierAmount = "1,000"; this.cultivatingTierAmount = "1,000";
} else if (this.cultivating < 5000) { } else if (this.cultivating < 5000) {
this.cultivatingTier = 2; this.cultivatingTier = 2;
this.cultivatingTierAmount = "5,000"; this.cultivatingTierAmount = "5,000";
} else if (this.cultivating < 25000) { } else if (this.cultivating < 25000) {
this.cultivatingTier = 3; this.cultivatingTier = 3;
this.cultivatingTierAmount = "25,000"; this.cultivatingTierAmount = "25,000";
} else if (this.cultivating < 100000) { } else if (this.cultivating < 100000) {
this.cultivatingTier = 4; this.cultivatingTier = 4;
this.cultivatingTierAmount = "100,000"; this.cultivatingTierAmount = "100,000";
} else if (this.cultivating < 300000) { } else if (this.cultivating < 300000) {
this.cultivatingTier = 5; this.cultivatingTier = 5;
this.cultivatingTierAmount = "300,000"; this.cultivatingTierAmount = "300,000";
} else if (this.cultivating < 1500000) { } else if (this.cultivating < 1500000) {
this.cultivatingTier = 6; this.cultivatingTier = 6;
this.cultivatingTierAmount = "1,500,000"; this.cultivatingTierAmount = "1,500,000";
} else if (this.cultivating < 5000000) { } else if (this.cultivating < 5000000) {
this.cultivatingTier = 7; this.cultivatingTier = 7;
this.cultivatingTierAmount = "5,000,000"; this.cultivatingTierAmount = "5,000,000";
} else if (this.cultivating < 20000000) { } else if (this.cultivating < 20000000) {
this.cultivatingTier = 8; this.cultivatingTier = 8;
this.cultivatingTierAmount = "20,000,000"; this.cultivatingTierAmount = "20,000,000";
} else if (this.cultivating < 100000000) { } else if (this.cultivating < 100000000) {
this.cultivatingTier = 9; this.cultivatingTier = 9;
this.cultivatingTierAmount = "100,000,000"; this.cultivatingTierAmount = "100,000,000";
} else if (this.cultivating > 100000000) { } else if (this.cultivating > 100000000) {
this.cultivatingTier = 10; this.cultivatingTier = 10;
this.cultivatingTierAmount = "Maxed"; this.cultivatingTierAmount = "Maxed";
} }
} }
while (this.counterQueue.size() >= 4) { skillInfoLast = skillInfo;
this.counterQueue.removeLast(); 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()) { xpGainQueue.add(0, delta);
this.cropsPerSecond = -1; while (xpGainQueue.size() > 30) {
this.cropsPerSecondLast = 0; xpGainQueue.removeLast();
} 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;
}
}
}
}
if (!holdingFarmItem) { float totalGain = 0;
this.cropsOverLastXSeconds.clear(); for (float f : xpGainQueue)
this.cropsPerSecond = -1; totalGain += f;
this.cropsPerSecondLast = 0;
}
ArrayList<Float> temp = new ArrayList<>(cropsOverLastXSeconds); xpGainHour = totalGain * (60 * 60) / xpGainQueue.size();
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));
}
float cropsOverLastXSecondsTotal = 0; isFarming = true;
for (Float crops : temp) { } else if (xpGainTimer > 0) {
cropsOverLastXSecondsTotal += crops; xpGainTimer--;
}
this.cropsPerSecond = temp.size() != 0 && cropsOverLastXSecondsTotal != 0
? cropsOverLastXSecondsTotal / temp.size()
: 0;
}
ArrayList<OverlayString> overlayStringList = new ArrayList<>(); xpGainQueue.add(0, 0f);
NumberFormat format = NumberFormat.getIntegerInstance(); while (xpGainQueue.size() > 30) {
xpGainQueue.removeLast();
}
// Add all the lines to the array float totalGain = 0;
if (this.counter >= 0 && this.cultivating != this.counter) { for (float f : xpGainQueue)
overlayStringList.add(new OverlayString("Counter", format.format(this.counter))); totalGain += f;
}
if (this.counter >= 0) { xpGainHour = totalGain * (60 * 60) / xpGainQueue.size();
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)));
}
}
if (this.cultivatingTier <= 9 && this.cultivating > 0) { isFarming = true;
int counterInterp = (int) interp(this.cultivating, this.cultivatingLast); } else if (delta <= 0) {
overlayStringList.add(new OverlayString("Cultivating", format.format(counterInterp) + "/" + this.cultivatingTierAmount)); isFarming = false;
} }
if (this.cultivatingTier == 10) {
int counterInterp = (int) interp(this.cultivating, this.cultivatingLast);
overlayStringList.add(new OverlayString("Cultivating", format.format(counterInterp)));
}
float yaw = client.player.getYaw(); lastTotalXp = totalXp;
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")); while (this.counterQueue.size() >= 4) {
overlayStringList.add(new OverlayString("Pitch", String.format("%.2f", pitch) + Formatting.BOLD + "\u1D52")); this.counterQueue.removeLast();
}
if (!holdingFarmItem) { if (this.counterQueue.isEmpty()) {
overlayStringList.clear(); 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 if (!holdingFarmItem) {
int xAxis = 10; this.cropsOverLastXSeconds.clear();
int yAxis = 200; this.cropsPerSecond = -1;
this.cropsPerSecondLast = 0;
}
// Get the longest string in the array ArrayList<Float> temp = new ArrayList<>(cropsOverLastXSeconds);
int longestString = 0; if (this.cropsOverLastXSeconds.size() >= 3) {
int BoxWidth = 0; temp.remove(Collections.min(temp));
for (OverlayString s : overlayStringList) { }
String combined = s.toString(); if (this.cropsOverLastXSeconds.size() >= 6) {
if (combined.length() > longestString) { temp.remove(Collections.min(temp));
longestString = combined.length(); temp.remove(Collections.max(temp));
BoxWidth = this.client.textRenderer.getWidth(combined); }
} 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, ArrayList<OverlayString> overlayStringList = new ArrayList<>();
yAxis + ((lineHeight + 1) * overlayStringList.size()), 0x64000000); NumberFormat format = NumberFormat.getIntegerInstance();
for (OverlayString line : overlayStringList) { // Add all the lines to the array
int offset = 5; 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); if (this.counter >= 0) {
yAxis += lineHeight; 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) { if (this.cultivatingTier <= 9 && this.cultivating > 0) {
float interp = now; int counterInterp = (int) interp(this.cultivating, this.cultivatingLast);
if (last >= 0 && last != now) { overlayStringList.add(
float factor = (System.currentTimeMillis() - this.lastUpdate) / 1000f; new OverlayString("Cultivating", format.format(counterInterp) + "/" + this.cultivatingTierAmount));
factor = LerpUtils.clampZeroOne(factor); }
interp = last + (now - last) * factor; if (this.cultivatingTier == 10) {
} int counterInterp = (int) interp(this.cultivating, this.cultivatingLast);
return interp; 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"), WHEAT("THEORETICAL_HOE_WHEAT", "Wheat"),
NETHER_WART("THEORETICAL_HOE_WARTS", "Warts"), NETHER_WART("THEORETICAL_HOE_WARTS", "Warts"),
SUGAR_CANE("THEORETICAL_HOE_CANE", "Sugar"), SUGAR_CANE("THEORETICAL_HOE_CANE", "Sugar"),
@ -290,17 +406,17 @@ public class FarmingOverlay extends DrawableHelper {
} }
} }
private class OverlayString { private class OverlayString {
final String type; final String type;
final String text; final String text;
private OverlayString(String type, String text) { private OverlayString(String type, String text) {
this.type = type; this.type = type;
this.text = text; this.text = text;
} }
public String toString() { public String toString() {
return Formatting.AQUA + this.type + ": " + Formatting.YELLOW + this.text; return Formatting.AQUA + this.type + ": " + Formatting.YELLOW + this.text;
} }
} }
} }

View File

@ -1,24 +1,33 @@
package lel.flummi.skilloverlay; package lel.flummi.skilloverlay;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
//import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
import lel.flummi.skilloverlay.overlays.FarmingOverlay; import lel.flummi.skilloverlay.overlays.FarmingOverlay;
import lel.flummi.skilloverlay.api.PlayerProfile; import lel.flummi.skilloverlay.api.PlayerProfile;
import lel.flummi.skilloverlay.api.ApiSkills; import lel.flummi.skilloverlay.api.PlayerSkills;
import lel.flummi.skilloverlay.config.skilloverlayconfig; import lel.flummi.skilloverlay.config.skilloverlayconfig;
public class skilloverlay implements ModInitializer { public class skilloverlay implements ModInitializer {
public static FarmingOverlay OVERLAY; public static FarmingOverlay OVERLAY;
public static PlayerProfile API; public static PlayerProfile API;
@Override @Override
public void onInitialize() { public void onInitialize() {
System.out.println("Skilloverlay started."); System.out.println("Skilloverlay started.");
skilloverlayconfig.init(); skilloverlayconfig.init();
OVERLAY = new FarmingOverlay(); OVERLAY = new FarmingOverlay();
ApiSkills.init(); PlayerSkills.init();
PlayerProfile.init(); PlayerProfile.init(false);
}
/*
* ClientReceiveMessageEvents.ALLOW_GAME.register((message, overlay) -> {
* System.out.println("message: " + message.getContent() + "; overlay: " +
* overlay);
* return true;
* });
*/
}
} }

View File

@ -1,24 +1,24 @@
package lel.flummi.skilloverlay.utils; package lel.flummi.skilloverlay.utils;
public class LerpUtils { public class LerpUtils {
public static float clampZeroOne(float f) { public static float clampZeroOne(float f) {
return Math.max(0, Math.min(1, f)); return Math.max(0, Math.min(1, f));
} }
public static float sigmoid(float val) { public static float sigmoid(float val) {
return (float) (1 / (1 + Math.exp(-val))); return (float) (1 / (1 + Math.exp(-val)));
} }
private static final float sigmoidStr = 8; private static final float sigmoidStr = 8;
private static final float sigmoidA = -1 / (sigmoid(-0.5f * sigmoidStr) - sigmoid(0.5f * sigmoidStr)); 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 sigmoidB = sigmoidA * sigmoid(-0.5f * sigmoidStr);
public static float sigmoidZeroOne(float f) { public static float sigmoidZeroOne(float f) {
f = clampZeroOne(f); f = clampZeroOne(f);
return sigmoidA * sigmoid(sigmoidStr * (f - 0.5f)) - sigmoidB; return sigmoidA * sigmoid(sigmoidStr * (f - 0.5f)) - sigmoidB;
} }
public static float lerp(float a, float b, float amount) { public static float lerp(float a, float b, float amount) {
return b + (a - b) * clampZeroOne(amount); return b + (a - b) * clampZeroOne(amount);
} }
} }

View File

@ -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;
}
}

View File

@ -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;
}
}