From 3d9a03ff4f1e542339950be6a77cb4c59a46ab77 Mon Sep 17 00:00:00 2001 From: hannibal2 <24389977+hannibal002@users.noreply.github.com> Date: Mon, 13 Feb 2023 14:03:22 +0100 Subject: Fix Muscle Memory (#581) * Added old SkyBlock Menu. * Execution! * Add cache. * Bingo has already enough to do. * Typo. * Revert "Typo." This reverts commit b4a1c385e0c410b1e111797b8d39e7ff64b09ef5. * Revert "Bingo has already enough to do." This reverts commit 6e004d2d65dff47ea3bee5c5789cb725724df6ed. * I am lazy. * The map is lazy too. * Hypixel moving features behind paywall. * Add red text to the setting too. * SEALED * Fixed Booster Cookie checks. Reworked CookieWarning, kept same logic but accidentally added profile switch support. * /trades does not require booster cookie. * Allowing middle clicks (and any other mouse click combination) --------- Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com> --- .../miscfeatures/CookieWarning.java | 211 +++++++++++++-------- .../options/seperateSections/Misc.java | 9 + .../moulberry/notenoughupdates/util/SBInfo.java | 3 +- .../moulberry/notenoughupdates/util/Utils.java | 41 ++-- 4 files changed, 164 insertions(+), 100 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CookieWarning.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CookieWarning.java index 80751371..f130a993 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CookieWarning.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/CookieWarning.java @@ -31,9 +31,13 @@ public class CookieWarning { private static boolean hasNotified; private static boolean hasErrorMessage; + private static long cookieEndTime = 0; + private static boolean hasCookie = true; + private static long lastChecked = 0; public static void resetNotification() { hasNotified = false; + hasCookie = true; NotificationHandler.cancelNotification(); } @@ -41,96 +45,135 @@ public class CookieWarning { * Checks the tab list for a cookie timer, and sends a notification if the timer is within the tolerance */ public static void checkCookie() { - if (NotEnoughUpdates.INSTANCE.config.notifications.doBoosterNotif && - NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { - String[] lines; - try { - lines = ((AccessorGuiPlayerTabOverlay) Minecraft.getMinecraft().ingameGUI.getTabList()) - .getFooter() - .getUnformattedText() - .split("\n"); - } catch (NullPointerException e) { - return; // if the footer is null or somehow doesn't exist, stop + if (!NotEnoughUpdates.INSTANCE.config.notifications.doBoosterNotif || + !NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { + return; + } + String timeLine = getTimeLine(); + if (!hasCookie) { + if (!hasNotified) { + NotificationHandler.displayNotification(Lists.newArrayList( + "§cBooster Cookie Ran Out!", + "§7Your Booster Cookie expired!", + "§7", + "§7Press X on your keyboard to close this notification" + ), true, true); + hasNotified = true; } - boolean hasCookie = true; - String timeLine = null; // the line that contains the cookie timer - for (int i = 0; i < lines.length; i++) { - if (lines[i].startsWith("Cookie Buff")) { - timeLine = lines[i + 1]; // the line after the "Cookie Buff" line - } - if (lines[i].startsWith("Not active! Obtain booster cookies from the")) { - hasCookie = false; - } + return; + } + if (timeLine == null) return; + + int minutes = getMinutesRemaining(timeLine); + if (minutes < NotEnoughUpdates.INSTANCE.config.notifications.boosterCookieWarningMins && !hasNotified) { + NotificationHandler.displayNotification(Lists.newArrayList( + "§cBooster Cookie Running Low!", + "§7Your Booster Cookie will expire in " + timeLine, + "§7", + "§7Press X on your keyboard to close this notification" + ), true, true); + hasNotified = true; + } + } + + private static int getMinutesRemaining(String timeLine) { + String clean = timeLine.replaceAll("(§.)", ""); + clean = clean.replaceAll("(\\d)([smhdy])", "$1 $2"); + String[] digits = clean.split(" "); + int minutes = 0; + try { + for (int i = 0; i < digits.length; i++) { + if (i % 2 == 1) continue; + + String number = digits[i]; + String unit = digits[i + 1]; + long val = Integer.parseInt(number); + switch (unit) { + case "Years": + case "Year": + minutes += val * 525600; + break; + case "Months": + case "Month": + minutes += val * 43200; + break; + case "Days": + case "Day": + minutes += val * 1440; + break; + case "Hours": + case "Hour": + case "h": + minutes += val * 60; + break; + case "Minutes": + case "Minute": + case "m": + minutes += val; + break; + } // ignore seconds } - if (!hasCookie) { - if (!hasNotified) { - NotificationHandler.displayNotification(Lists.newArrayList( - "\u00a7cBooster Cookie Ran Out!", - "\u00a77Your Booster Cookie expired!", - "\u00a77", - "\u00a77Press X on your keyboard to close this notification" - ), true, true); - hasNotified = true; - } - return; + } catch (NumberFormatException e) { + if (!hasErrorMessage) { + e.printStackTrace(); + Utils.addChatMessage(EnumChatFormatting.RED + + "NEU ran into an issue when retrieving the Booster Cookie Timer. Check the logs for details."); + hasErrorMessage = true; } - if (timeLine != null) { - String clean = timeLine.replaceAll("(\u00a7.)", ""); - clean = clean.replaceAll("(\\d)([smhdy])", "$1 $2"); - String[] digits = clean.split(" "); - int minutes = 0; - try { - for (int i = 0; i < digits.length; i++) { - if (i % 2 == 1) continue; + hasNotified = true; + } + return minutes; + } - String number = digits[i]; - String unit = digits[i + 1]; - long val = Integer.parseInt(number); - switch (unit) { - case "Years": - case "Year": - minutes += val * 525600; - break; - case "Months": - case "Month": - minutes += val * 43200; - break; - case "Days": - case "Day": - minutes += val * 1440; - break; - case "Hours": - case "Hour": - case "h": - minutes += val * 60; - break; - case "Minutes": - case "Minute": - case "m": - minutes += val; - break; - } // ignore seconds - } - } catch (NumberFormatException e) { - if (!hasErrorMessage) { - e.printStackTrace(); - Utils.addChatMessage(EnumChatFormatting.RED + - "NEU ran into an issue when retrieving the Booster Cookie Timer. Check the logs for details."); - hasErrorMessage = true; - } - hasNotified = true; - } - if (minutes < NotEnoughUpdates.INSTANCE.config.notifications.boosterCookieWarningMins && !hasNotified) { - NotificationHandler.displayNotification(Lists.newArrayList( - "\u00a7cBooster Cookie Running Low!", - "\u00a77Your Booster Cookie will expire in " + timeLine, - "\u00a77", - "\u00a77Press X on your keyboard to close this notification" - ), true, true); - hasNotified = true; - } + private static String getTimeLine() { + String[] lines; + try { + lines = ((AccessorGuiPlayerTabOverlay) Minecraft.getMinecraft().ingameGUI.getTabList()) + .getFooter() + .getUnformattedText() + .split("\n"); + } catch (NullPointerException ignored) { + return null; + } + String timeLine = null; // the line that contains the cookie timer + for (int i = 0; i < lines.length; i++) { + if (lines[i].startsWith("Cookie Buff")) { + timeLine = lines[i + 1]; // the line after the "Cookie Buff" line + } + if (lines[i].startsWith("Not active! Obtain booster cookies from the")) { + hasCookie = false; } } + return timeLine; + } + + public static boolean hasActiveBoosterCookie() { + long cookieEndTime = getCookieEndTime(); + return cookieEndTime > System.currentTimeMillis(); + } + + private static long getCookieEndTime() { + // Only updating every 10 seconds +// if (System.currentTimeMillis() > lastChecked + 10_000) return cookieEndTime; + if (lastChecked + 3_000 > System.currentTimeMillis()) return cookieEndTime; + + String timeLine = getTimeLine(); + if (hasCookie && timeLine != null) { + int minutes = getMinutesRemaining(timeLine); + cookieEndTime = System.currentTimeMillis() + (long) minutes * 60 * 1000; + } else { + cookieEndTime = 0; + } + + lastChecked = System.currentTimeMillis(); + return cookieEndTime; + } + public static void onProfileSwitch() { + resetNotification(); + hasErrorMessage = false; + cookieEndTime = 0; + hasCookie = true; + lastChecked = 0; } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java index 47e51eec..affaa68a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java @@ -311,4 +311,13 @@ public class Misc { @ConfigEditorBoolean public boolean dungeonGroupsPV = true; + @Expose + @ConfigOption( + name = "Old SkyBlock Menu", + desc = "Show old buttons in the SkyBlock Menu: Trade, Accessories, Potions, Quiver, Fishing and Sacks. " + + "§cOnly works with the booster cookie effect active." + ) + @ConfigEditorBoolean + public boolean oldSkyBlockMenu = false; + } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java index d0af9091..a89b281d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java @@ -24,6 +24,7 @@ import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe; import io.github.moulberry.notenoughupdates.listener.ScoreboardLocationChangeListener; +import io.github.moulberry.notenoughupdates.miscfeatures.CookieWarning; import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.LocationChangeEvent; import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; import io.github.moulberry.notenoughupdates.overlays.OverlayManager; @@ -477,7 +478,6 @@ public class SBInfo { .thenAccept(newJson -> mayorJson = newJson); } - public JsonObject getMayorJson() { return mayorJson; } @@ -486,6 +486,7 @@ public class SBInfo { if (!newProfile.equals(currentProfile)) { currentProfile = newProfile; MinionHelperManager.getInstance().onProfileSwitch(); + CookieWarning.onProfileSwitch(); } } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java index d5abcb77..38debbbc 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java @@ -925,6 +925,10 @@ public class Utils { return createItemStack(item, displayName, 0, lore); } + public static ItemStack createItemStackArray(Item item, String displayName, String[] lore) { + return createItemStack(item, displayName, 0, lore); + } + public static ItemStack createItemStack(Block item, String displayName, String... lore) { return createItemStack(Item.getItemFromBlock(item), displayName, lore); } @@ -932,17 +936,7 @@ public class Utils { public static ItemStack createItemStack(Item item, String displayName, int damage, String... lore) { ItemStack stack = new ItemStack(item, 1, damage); NBTTagCompound tag = new NBTTagCompound(); - NBTTagCompound display = new NBTTagCompound(); - NBTTagList Lore = new NBTTagList(); - - for (String line : lore) { - Lore.appendTag(new NBTTagString(line)); - } - - display.setString("Name", displayName); - display.setTag("Lore", Lore); - - tag.setTag("display", display); + addNameAndLore(tag, displayName, lore); tag.setInteger("HideFlags", 254); stack.setTagCompound(tag); @@ -950,6 +944,22 @@ public class Utils { return stack; } + private static void addNameAndLore(NBTTagCompound tag, String displayName, String[] lore) { + NBTTagCompound display = new NBTTagCompound(); + + display.setString("Name", displayName); + + if (lore != null) { + NBTTagList tagLore = new NBTTagList(); + for (String line : lore) { + tagLore.appendTag(new NBTTagString(line)); + } + display.setTag("Lore", tagLore); + } + + tag.setTag("display", display); + } + public static ItemStack editItemStackInfo( ItemStack itemStack, String displayName, @@ -979,15 +989,17 @@ public class Utils { return itemStack; } - public static ItemStack createSkull(String displayName, String uuid, String value) { + return createSkull(displayName, uuid, value, null); + } + + public static ItemStack createSkull(String displayName, String uuid, String value, String[] lore) { ItemStack render = new ItemStack(Items.skull, 1, 3); NBTTagCompound tag = new NBTTagCompound(); NBTTagCompound skullOwner = new NBTTagCompound(); NBTTagCompound properties = new NBTTagCompound(); NBTTagList textures = new NBTTagList(); NBTTagCompound textures_0 = new NBTTagCompound(); - NBTTagCompound display = new NBTTagCompound(); skullOwner.setString("Id", uuid); skullOwner.setString("Name", uuid); @@ -995,8 +1007,7 @@ public class Utils { textures_0.setString("Value", value); textures.appendTag(textures_0); - display.setString("Name", displayName); - tag.setTag("display", display); + addNameAndLore(tag, displayName, lore); properties.setTag("textures", textures); skullOwner.setTag("Properties", properties); -- cgit From b6d88d2cbb5985c56a28e9b3cadf1e111af14564 Mon Sep 17 00:00:00 2001 From: efefury <69400149+efefury@users.noreply.github.com> Date: Tue, 14 Feb 2023 06:07:21 +0000 Subject: Add event task & other things in Level Page (#607) Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com> --- .../profileviewer/level/LevelPage.java | 15 +-- .../profileviewer/level/task/CoreTaskLevel.java | 48 +++++++--- .../profileviewer/level/task/DungeonTaskLevel.java | 14 +-- .../profileviewer/level/task/EssenceTaskLevel.java | 16 ++-- .../profileviewer/level/task/EventTaskLevel.java | 106 +++++++++++++++++++++ .../profileviewer/level/task/MiscTaskLevel.java | 46 +++++---- .../level/task/SkillRelatedTaskLevel.java | 90 ++++++++--------- .../profileviewer/level/task/SlayingTaskLevel.java | 13 +-- .../profileviewer/level/task/StoryTaskLevel.java | 6 +- 9 files changed, 243 insertions(+), 111 deletions(-) create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/EventTaskLevel.java (limited to 'src/main/java') diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/LevelPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/LevelPage.java index 16abf251..770b295a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/LevelPage.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/LevelPage.java @@ -26,6 +26,7 @@ import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer; import io.github.moulberry.notenoughupdates.profileviewer.level.task.CoreTaskLevel; import io.github.moulberry.notenoughupdates.profileviewer.level.task.DungeonTaskLevel; import io.github.moulberry.notenoughupdates.profileviewer.level.task.EssenceTaskLevel; +import io.github.moulberry.notenoughupdates.profileviewer.level.task.EventTaskLevel; import io.github.moulberry.notenoughupdates.profileviewer.level.task.MiscTaskLevel; import io.github.moulberry.notenoughupdates.profileviewer.level.task.SkillRelatedTaskLevel; import io.github.moulberry.notenoughupdates.profileviewer.level.task.SlayingTaskLevel; @@ -61,6 +62,8 @@ public class LevelPage { private final SlayingTaskLevel slayingTaskLevel; private final StoryTaskLevel storyTaskLevel; + private final EventTaskLevel eventTaskLevel; + private static final ResourceLocation pv_levels = new ResourceLocation("notenoughupdates:pv_levels.png"); public LevelPage(GuiProfileViewer instance, BasicPage basicPage) { @@ -75,6 +78,7 @@ public class LevelPage { skillRelatedTaskLevel = new SkillRelatedTaskLevel(this); slayingTaskLevel = new SlayingTaskLevel(this); storyTaskLevel = new StoryTaskLevel(this); + eventTaskLevel = new EventTaskLevel(this); } public void drawPage(int mouseX, int mouseY) { @@ -97,13 +101,14 @@ public class LevelPage { JsonObject profileInfo = profile.getProfileInformation(profileId); drawMainBar(skyblockLevel, mouseX, mouseY, guiLeft, guiTop); - coreTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop); dungeonTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop); essenceTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop); miscTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop); skillRelatedTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop); slayingTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop); storyTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop); + eventTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop); + coreTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop); } public void renderLevelBar( @@ -175,14 +180,12 @@ public class LevelPage { renderLevelBar( "Level", BasicPage.skull, - guiLeft + 163, - guiTop + 30, + guiLeft + 163, guiTop + 30, 110, skyblockLevel, - (skyblockLevel - (long) skyblockLevel) * 100, + Math.round((skyblockLevel - (long) skyblockLevel) * 100), 100, - mouseX, - mouseY, + mouseX, mouseY, false, Collections.emptyList() ); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/CoreTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/CoreTaskLevel.java index be333359..fde43cd1 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/CoreTaskLevel.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/CoreTaskLevel.java @@ -19,8 +19,9 @@ package io.github.moulberry.notenoughupdates.profileviewer.level.task; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import io.github.moulberry.notenoughupdates.profileviewer.PlayerStats; import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer; import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage; import io.github.moulberry.notenoughupdates.util.Constants; @@ -80,11 +81,18 @@ public class CoreTaskLevel { } // mp acc - int sbXpGainedMp = levelPage.getProfile().getMagicalPower(levelPage.getProfileId()); + int sbXpGainedMp = 0; + if (object.has("accessory_bag_storage")) { + sbXpGainedMp = object.getAsJsonObject("accessory_bag_storage").get("highest_magical_power").getAsInt(); + } // pets - int petScore = PlayerStats.getPetScore(object); + int petScore = 0; + if (object.has("leveling") && object.getAsJsonObject("leveling").has("highest_pet_score")) { + petScore = object.getAsJsonObject("leveling").get("highest_pet_score").getAsInt(); + + } int sbXpPetScore = petScore * coreTask.get("pet_score_xp").getAsInt(); // museum is not possible @@ -116,13 +124,32 @@ public class CoreTaskLevel { } } } + + int sbXpBankUpgrades = 0; + + JsonArray completedTasks = object.getAsJsonObject("leveling").get("completed_tasks").getAsJsonArray(); + JsonObject bankUpgradesXp = coreTask.getAsJsonObject("bank_upgrades_xp"); + for (JsonElement completedTask : completedTasks) { + String name = completedTask.getAsString(); + if (bankUpgradesXp.has(name)) { + sbXpBankUpgrades += bankUpgradesXp.get(name).getAsInt(); + } + } + List lore = new ArrayList<>(); lore.add(levelPage.buildLore("Skill Level Up", sbXpGainedSkillLVL, coreTask.get("skill_level_up").getAsInt(), false )); - lore.add(levelPage.buildLore("Museum Progression", - 0, 0, false + + int totalXp = sbXpGainedSkillLVL + sbXpGainedFairy + + sbXpCollection + sbXpMinionTier + sbXpBankUpgrades; + + lore.add(levelPage.buildLore( + "Museum Progression", + 0, + 0, + false )); lore.add(levelPage.buildLore( "Fairy Soul", @@ -141,21 +168,18 @@ public class CoreTaskLevel { sbXpMinionTier, coreTask.get("craft_minions").getAsInt(), false )); lore.add(levelPage.buildLore("Bank Upgrade", - 0, 0, false + sbXpBankUpgrades, coreTask.get("bank_upgrades").getAsInt(), false )); levelPage.renderLevelBar( "Core Task", new ItemStack(Items.nether_star), - guiLeft + 23, - guiTop + 25, + guiLeft + 23, guiTop + 25, 110, 0, - sbXpGainedSkillLVL + sbXpGainedFairy + - sbXpCollection + sbXpMinionTier, + totalXp, levelPage.getConstant().getAsJsonObject("category_xp").get("core_task").getAsInt(), - mouseX, - mouseY, + mouseX, mouseY, true, lore ); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/DungeonTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/DungeonTaskLevel.java index 6f0a029f..6900cdf3 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/DungeonTaskLevel.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/DungeonTaskLevel.java @@ -44,9 +44,9 @@ public class DungeonTaskLevel { Map skyblockInfo = levelPage.getProfile().getSkyblockInfo(levelPage.getProfileId()); - double sbLevelGainedFloor = 0; - double sbXpGainedClass = 0; - double sbXpGainedLvl = 0; + int sbLevelGainedFloor = 0; + int sbXpGainedClass = 0; + int sbXpGainedLvl = 0; int catacombsLvl = 0; if (skyblockInfo != null && skyblockInfo.containsKey("catacombs")) { ProfileViewer.Level catacombs = skyblockInfo.get("catacombs"); @@ -105,20 +105,20 @@ public class DungeonTaskLevel { lore.add(levelPage.buildLore("Class Level Up", sbXpGainedClass, classLevelUp, false)); lore.add(levelPage.buildLore("Complete Dungeons", sbLevelGainedFloor, completeDungeon, false)); + int totalSbXpGain = sbXpGainedLvl + sbXpGainedClass + sbLevelGainedFloor; + levelPage.renderLevelBar( "Dungeon Task", NotEnoughUpdates.INSTANCE.manager .createItemResolutionQuery() .withKnownInternalName("WITHER_RELIC") .resolveToItemStack(), - guiLeft + 23, - guiTop + 55, + guiLeft + 23, guiTop + 55, 110, catacombsLvl, totalXp, totalGainful, - mouseX, - mouseY, + mouseX, mouseY, true, lore ); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/EssenceTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/EssenceTaskLevel.java index 11e291b0..c6df6fc1 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/EssenceTaskLevel.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/EssenceTaskLevel.java @@ -25,6 +25,7 @@ import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage; import io.github.moulberry.notenoughupdates.util.Constants; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.util.EnumChatFormatting; import java.util.ArrayList; @@ -88,10 +89,15 @@ public class EssenceTaskLevel { for (Map.Entry stringEssenceShopEntry : loreMap.entrySet()) { String key = stringEssenceShopEntry.getKey(); EssenceShop value = stringEssenceShopEntry.getValue(); - value.name = NotEnoughUpdates.INSTANCE.manager + JsonObject jsonObject = NotEnoughUpdates.INSTANCE.manager .createItemResolutionQuery() .withKnownInternalName(key) - .resolveToItemListJson() + .resolveToItemListJson(); + if (jsonObject == null){ + Utils.showOutdatedRepoNotification(); + continue; + } + value.name = jsonObject .get("displayname") .getAsString(); String name = key.toLowerCase() + "_shop"; @@ -111,14 +117,12 @@ public class EssenceTaskLevel { NotEnoughUpdates.INSTANCE.manager.createItemResolutionQuery() .withKnownInternalName("ESSENCE_WITHER") .resolveToItemStack(), - guiLeft + 299, - guiTop + 25, + guiLeft + 299, guiTop + 25, 110, total, total, categoryXp.get("essence_shop_task").getAsInt(), - mouseX, - mouseY, + mouseX, mouseY, true, lore ); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/EventTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/EventTaskLevel.java new file mode 100644 index 00000000..04ace872 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/EventTaskLevel.java @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2023 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package io.github.moulberry.notenoughupdates.profileviewer.level.task; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; + +import java.util.ArrayList; +import java.util.List; + +public class EventTaskLevel { + + private final LevelPage levelPage; + + public EventTaskLevel(LevelPage levelPage) {this.levelPage = levelPage;} + + public void drawTask(JsonObject object, int mouseX, int mouseY, int guiLeft, int guiTop) { + List lore = new ArrayList<>(); + + int sbXpMiningFiesta = 0; + int sbXpFishingFestival = 0; + int sbXpSpookyFestival = 0; + JsonObject constant = levelPage.getConstant(); + JsonObject eventTask = constant.getAsJsonObject("event_task"); + + if (object.has("leveling")) { + JsonObject leveling = object.getAsJsonObject("leveling"); + int miningFiestaOresMined = 0; + int fishingFestivalSharksKilled = 0; + if (leveling.has("mining_fiesta_ores_mined")) + miningFiestaOresMined = leveling.get("mining_fiesta_ores_mined").getAsInt(); + if (leveling.has("fishing_festival_sharks_killed")) fishingFestivalSharksKilled = leveling.get( + "fishing_festival_sharks_killed").getAsInt(); + + sbXpMiningFiesta = getCapOrAmount(miningFiestaOresMined, 1_000_000, 5_000); + sbXpFishingFestival = getCapOrAmount(fishingFestivalSharksKilled, 5_000, 50); + + JsonArray completedTasks = leveling.get("completed_tasks").getAsJsonArray(); + JsonObject spookyFestivalXp = eventTask.getAsJsonObject("spooky_festival_xp"); + for (JsonElement completedTask : completedTasks) { + String name = completedTask.getAsString(); + if (spookyFestivalXp.has(name)) { + sbXpSpookyFestival += spookyFestivalXp.get(name).getAsInt(); + } + } + } + + lore.add(levelPage.buildLore("Mining Fiesta", sbXpMiningFiesta, eventTask.get("mining_fiesta").getAsInt(), false)); + lore.add(levelPage.buildLore( + "Fishing Festival", + sbXpFishingFestival, + eventTask.get("fishing_festival").getAsInt(), + false + )); + lore.add(levelPage.buildLore( + "Spooky Festival", + sbXpSpookyFestival, + eventTask.get("spooky_festival").getAsInt(), + false + )); + + int totalXp = sbXpMiningFiesta + sbXpSpookyFestival + + sbXpFishingFestival; + levelPage.renderLevelBar( + "Event Task", + new ItemStack(Items.clock), + guiLeft + 299, guiTop + 115, + 110, + 0, + totalXp, + levelPage.getConstant().getAsJsonObject("category_xp").get("event_task").getAsInt(), + mouseX, mouseY, + true, + lore + ); + } + + private int getCapOrAmount(int miningFiestaOresMined, int cap, int per) { + if (miningFiestaOresMined == 0) return 0; + if (miningFiestaOresMined > cap) { + return cap / per; + } + return miningFiestaOresMined / per; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/MiscTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/MiscTaskLevel.java index e0ea89b3..8b7b9d2b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/MiscTaskLevel.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/MiscTaskLevel.java @@ -27,12 +27,13 @@ import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumChatFormatting; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; public class MiscTaskLevel { @@ -86,24 +87,27 @@ public class MiscTaskLevel { } // abiphone - if (netherIslandPlayerData.has("abiphone")) { - JsonObject abiphone = netherIslandPlayerData.getAsJsonObject("abiphone"); - if (abiphone.has("active_contacts")) sbXpAbiphone = - abiphone.getAsJsonArray("active_contacts").size() * miscellaneousTask.get("abiphone_contacts_xp").getAsInt(); + JsonObject leveling = object.getAsJsonObject("leveling"); + JsonArray completedTask = leveling.get("completed_tasks").getAsJsonArray(); + Stream stream = StreamSupport.stream(completedTask.spliterator(), true); + long activeContacts = stream.map(JsonElement::getAsString).filter(s -> s.startsWith("ABIPHONE_")).count(); + JsonObject abiphone = netherIslandPlayerData.getAsJsonObject("abiphone"); + if (abiphone.has("active_contacts")) { + sbXpAbiphone = (int) activeContacts * miscellaneousTask.get("abiphone_contacts_xp").getAsInt(); } } // harp int sbXpGainedHarp = 0; JsonObject harpSongsNames = miscellaneousTask.get("harp_songs_names").getAsJsonObject(); - if (object.has("harp_quest")) { - JsonObject harpQuest = object.get("harp_quest").getAsJsonObject(); - for (Map.Entry stringJsonElementEntry : harpSongsNames.entrySet()) { - String key = stringJsonElementEntry.getKey(); - int value = stringJsonElementEntry.getValue().getAsInt(); - if (harpQuest.has(key)) { - sbXpGainedHarp += value; - } + + JsonObject leveling = object.get("leveling").getAsJsonObject(); + if (leveling.has("completed_tasks")) { + JsonArray completedTasks = leveling.get("completed_tasks").getAsJsonArray(); + for (JsonElement completedTask : completedTasks) { + String name = completedTask.getAsString(); + String harpName = name.substring(0, name.lastIndexOf("_")); + if(harpSongsNames.has(harpName))sbXpGainedHarp += harpSongsNames.get(harpName).getAsInt() / 4; } } @@ -158,10 +162,10 @@ public class MiscTaskLevel { sbXpDojo, miscellaneousTask.get("the_dojo").getAsInt(), false )); lore.add(levelPage.buildLore( - EnumChatFormatting.ITALIC + "Harp Songs", + "Harp Songs", sbXpGainedHarp, miscellaneousTask.get("harp_songs").getAsInt(), false )); - lore.add(levelPage.buildLore(EnumChatFormatting.ITALIC + "Abiphone Contacts", + lore.add(levelPage.buildLore("Abiphone Contacts", sbXpAbiphone, miscellaneousTask.get("abiphone_contacts").getAsInt(), false )); lore.add(levelPage.buildLore("Community Shop Upgrades", @@ -171,22 +175,22 @@ public class MiscTaskLevel { sbXpPersonalBank, miscellaneousTask.get("personal_bank_upgrades").getAsInt(), false )); + int totalXp = sbXpReaperPeppers + sbXpDojo + sbXpGainedHarp + sbXpAbiphone + + sbXpCommunityUpgrade + sbXpPersonalBank; levelPage.renderLevelBar( "Misc. Task", new ItemStack(Items.map), - guiLeft + 299, - guiTop + 55, + guiLeft + 299, guiTop + 55, 110, 0, - sbXpReaperPeppers + sbXpDojo + sbXpGainedHarp + sbXpAbiphone + - sbXpCommunityUpgrade + sbXpPersonalBank, + totalXp, levelPage.getConstant().getAsJsonObject("category_xp").get("miscellaneous_task").getAsInt(), - mouseX, - mouseY, + mouseX, mouseY, true, lore ); + totalXp += sbXpAccessoryUpgrade + sbXpUnlockedPowers; } private int getRankIndex(int pointsTotal) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SkillRelatedTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SkillRelatedTaskLevel.java index 4ba7951c..06ab6f8c 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SkillRelatedTaskLevel.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SkillRelatedTaskLevel.java @@ -43,13 +43,6 @@ public class SkillRelatedTaskLevel { JsonObject skillRelatedTask = levelPage.getConstant().get("skill_related_task").getAsJsonObject(); JsonObject miningObj = skillRelatedTask.get("mining").getAsJsonObject(); - float mithrilPowder = Utils.getElementAsFloat(Utils.getElement(object, "mining_core.powder_mithril"), 0); - float gemstonePowder = Utils.getElementAsFloat(Utils.getElement(object, "mining_core.powder_gemstone"), 0); - float mithril = Utils.getElementAsFloat(Utils.getElement(object, "mining_core.powder_spent_mithril"), 0) + - mithrilPowder; - float gemstone = (Utils.getElementAsFloat(Utils.getElement(object, "mining_core.powder_spent_gemstone"), 0)) + - gemstonePowder; - float hotmXp = Utils.getElementAsFloat(Utils.getElement(object, "mining_core.experience"), 0); ProfileViewer.Level levelObjHotm = ProfileViewer.getLevel( @@ -66,29 +59,31 @@ public class SkillRelatedTaskLevel { hotmXP += hotmXpArray.get(i - 1).getAsInt(); } - int gainByFirstMithrilThing; - if (mithril >= 350_000) { - gainByFirstMithrilThing = (int) (350000 / 2400d); - mithril -= 350_000; - } else { - gainByFirstMithrilThing = (int) (mithril / 2400d); - mithril = 0; - } + float mithrilPowder = Utils.getElementAsFloat(Utils.getElement(object, "mining_core.powder_mithril"), 0); + float gemstonePowder = Utils.getElementAsFloat(Utils.getElement(object, "mining_core.powder_gemstone"), 0); + float mithril = Utils.getElementAsFloat(Utils.getElement(object, "mining_core.powder_spent_mithril"), 0) + + mithrilPowder; + float gemstone = (Utils.getElementAsFloat(Utils.getElement(object, "mining_core.powder_spent_gemstone"), 0)) + + gemstonePowder; - int gainByFirstGemstoneThing; - if (gemstone >= 350_000) { - gainByFirstGemstoneThing = (int) (350_000 / 2500d); - gemstone -= 350_000; - } else { - gainByFirstGemstoneThing = (int) (gemstone / 2500d); - gemstone = 0; - } + // PUNKT NULL + + double totalMithril = mithril + mithrilPowder; + double totalGemstone = gemstone + gemstonePowder; + double mithrilUnder = Math.min(350000.0, totalMithril); + double mithrilOver = Math.max(0, Math.min(totalMithril, 12_500_000.0) - 350000.0); + double gemstoneUnder = Math.min(350000.0, totalGemstone); + double gemstoneOver = Math.max(0, Math.min(totalGemstone, 20_000_000.0) - 350000.0); - int sbXpMithrilPowder = (int) powder(3.75, mithril, 12_500_000); - int sbXpGemstonePowder = (int) powder(4.25, gemstone, 20_000_000); + double mithrilXP = Math.floor(mithrilUnder / 2400.0); + double gemstoneXP = Math.floor(gemstoneUnder / 2500.0); + double mithrilExcess = Math.floor( + 3.75 * (Math.sqrt(1 + 8 * Math.sqrt((1758267.0 / 12_500_000.0) * mithrilOver + 9)) - 3)); + double gemstoneExcess = Math.floor( + 4.25 * (Math.sqrt(1 + 8 * Math.sqrt((1758267.0 / 20_000_000.0) * gemstoneOver + 9)) - 3)); double sbXpHotmTier = - (sbXpMithrilPowder + gainByFirstMithrilThing) + (sbXpGemstonePowder + gainByFirstGemstoneThing) + (mithrilXP + mithrilExcess) + (gemstoneXP + gemstoneExcess) + hotmXP; int sbXpPotmTier = 0; @@ -171,6 +166,18 @@ public class SkillRelatedTaskLevel { } } + int sbXpNucleus = 0; + JsonObject leveling = object.get("leveling").getAsJsonObject(); + if (leveling.has("completions") && leveling.getAsJsonObject("completions").has("NUCLEUS_RUNS")) { + int nucleusRuns = leveling.getAsJsonObject("completions").get("NUCLEUS_RUNS").getAsInt(); + JsonElement nucleusXp = miningObj.get("crystal_nucleus_xp"); + if (nucleusXp == null) { + Utils.showOutdatedRepoNotification(); + } else { + sbXpNucleus += nucleusRuns * nucleusXp.getAsInt(); + } + } + List lore = new ArrayList<>(); lore.add(levelPage.buildLore("Heart of the Mountain", sbXpHotmTier, miningObj.get("hotm").getAsInt(), false)); lore.add(levelPage.buildLore( @@ -179,7 +186,7 @@ public class SkillRelatedTaskLevel { miningObj.get("commission_milestone").getAsInt(), false )); - lore.add(levelPage.buildLore("Crystal Nucleus", 0, 0, false)); + lore.add(levelPage.buildLore("Crystal Nucleus", sbXpNucleus, miningObj.get("crystal_nucleus").getAsInt(), false)); lore.add(levelPage.buildLore( "Anita's Shop Upgrade", sbXpGainedByAnita, @@ -189,37 +196,22 @@ public class SkillRelatedTaskLevel { lore.add(levelPage.buildLore("Peak of the Mountain", sbXpPotmTier, miningObj.get("potm").getAsInt(), false)); lore.add(levelPage.buildLore("Trophy Fish", sbXpTrophyFish, fishingObj.get("trophy_fish").getAsInt(), false)); lore.add(levelPage.buildLore("Rock Milestone", sbXpRockPet, miningObj.get("rock_milestone").getAsInt(), false)); - lore.add(levelPage.buildLore( - "Dolphin Milestone", - sbXpDolphinPet, - fishingObj.get("dolphin_milestone").getAsInt(), - false - )); + lore.add(levelPage.buildLore("Dolphin Milestone", sbXpDolphinPet, fishingObj.get("dolphin_milestone").getAsInt(), false)); + int totalXp = + (int) (sbXpHotmTier + sbXpCommissionMilestone + sbXpGainedByAnita + sbXpPotmTier + sbXpTrophyFish + sbXpRockPet + + sbXpDolphinPet + sbXpNucleus); levelPage.renderLevelBar( "Skill Related Task", new ItemStack(Items.diamond_sword), - guiLeft + 23, - guiTop + 115, + guiLeft + 23, guiTop + 115, 110, 0, - sbXpHotmTier + sbXpCommissionMilestone + sbXpGainedByAnita + sbXpPotmTier + sbXpTrophyFish + sbXpRockPet + - sbXpDolphinPet, + totalXp, levelPage.getConstant().getAsJsonObject("category_xp").get("skill_related_task").getAsInt(), - mouseX, - mouseY, + mouseX, mouseY, true, lore ); } - - private static double powder(double multiplier, float left, int CAP) { - double cons = 1758267; - if (left <= 0) return 0; - - left = Math.min(CAP, left); - - return multiplier * (Math.sqrt(1 + 8 * (Math.sqrt((cons / CAP) * left + 9))) - 3); - } - } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SlayingTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SlayingTaskLevel.java index 3aded435..6b624a52 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SlayingTaskLevel.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SlayingTaskLevel.java @@ -233,20 +233,21 @@ public class SlayingTaskLevel { int slayingTaskMax = levelPage.getConstant().getAsJsonObject("category_xp").get("slaying_task").getAsInt(); + int totalXp = sbXpGainedSlayer + bossCollectionXp + mythologicalKillsXp + + sbXpFromDragonKills + sbXpFromSlayerDefeat + sbXpDefeatKuudra + sbXpGainedArachne; levelPage.renderLevelBar( "Slaying Task", new ItemStack(Items.golden_sword), - guiLeft + 23, - guiTop + 85, + guiLeft + 23, guiTop + 85, 110, - 0, sbXpGainedSlayer + bossCollectionXp + mythologicalKillsXp + - sbXpFromDragonKills + sbXpFromSlayerDefeat + sbXpDefeatKuudra + sbXpGainedArachne, + 0, + totalXp, slayingTaskMax, - mouseX, - mouseY, + mouseX, mouseY, true, lore ); + totalXp += sbXpBestiary; } private int loopThroughCollection(int[] array, double value, JsonArray jsonArray) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/StoryTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/StoryTaskLevel.java index 2b1b59cb..3846db5f 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/StoryTaskLevel.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/StoryTaskLevel.java @@ -61,14 +61,12 @@ public class StoryTaskLevel { levelPage.renderLevelBar( "Story Task", new ItemStack(Items.map), - guiLeft + 299, - guiTop + 85, + guiLeft + 299, guiTop + 85, 110, 0, sbXpStory, levelPage.getConstant().getAsJsonObject("category_xp").get("story_task").getAsInt(), - mouseX, - mouseY, + mouseX, mouseY, true, lore ); -- cgit From cd219f19da268c5697081c092d35c9b1f5198058 Mon Sep 17 00:00:00 2001 From: NopoTheGamer <40329022+NopoTheGamer@users.noreply.github.com> Date: Tue, 14 Feb 2023 11:18:13 +0000 Subject: Revert nw location (#606) --- .../notenoughupdates/profileviewer/BasicPage.java | 63 +++++++++++++--------- 1 file changed, 39 insertions(+), 24 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java index 265177fc..5939e122 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java @@ -313,17 +313,25 @@ public class BasicPage extends GuiProfileViewerPage { } else if (networth == -1) { networth = profile.getNetWorth(profileId); } - + int fontWidth = fr.getStringWidth("Net Worth: " + GuiProfileViewer.numberFormat.format(networth)); + int offset = (fontWidth >= 117 ? 63 + (fontWidth - 117) : 63); if (networth > 0) { - Utils.drawStringCentered( - EnumChatFormatting.GREEN + "Net Worth: " + EnumChatFormatting.GOLD + - GuiProfileViewer.numberFormat.format(networth), - fr, - guiLeft + 165, - guiTop + 38, - true, - 0 - ); + if (fontWidth >= 117) { + + fr.drawString(EnumChatFormatting.GREEN + "Net Worth: " + EnumChatFormatting.GOLD + + GuiProfileViewer.numberFormat.format(networth), guiLeft + 8, guiTop + 38 - fr.FONT_HEIGHT / 2f, 0, true); + + } else { + Utils.drawStringCentered( + EnumChatFormatting.GREEN + "Net Worth: " + EnumChatFormatting.GOLD + + GuiProfileViewer.numberFormat.format(networth), + fr, + guiLeft + 68, + guiTop + 38, + true, + 0 + ); + } if (NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("BOOSTER_COOKIE") != null && NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo("BOOSTER_COOKIE").has("avg_buy")) { double networthInCookies = @@ -337,8 +345,8 @@ public class BasicPage extends GuiProfileViewerPage { String networthIRLMoney = GuiProfileViewer.numberFormat.format(Math.round( ((networthInCookies * 325) / 675) * 4.99)); - int fontWidth = fr.getStringWidth("Net Worth: " + GuiProfileViewer.numberFormat.format(networth)); - if (mouseX > guiLeft + 165 - fontWidth / 2 && mouseX < guiLeft + 165 + fontWidth / 2) { + + if (mouseX > guiLeft + offset - fontWidth / 2 && mouseX < guiLeft + offset + fontWidth / 2) { if (mouseY > guiTop + 32 && mouseY < guiTop + 38 + fr.FONT_HEIGHT) { getInstance().tooltipToDisplay = new ArrayList<>(); getInstance() @@ -384,14 +392,21 @@ public class BasicPage extends GuiProfileViewerPage { } } } else { - Utils.drawStringCentered( - EnumChatFormatting.GREEN + "Net Worth: " + stateStr, - fr, - guiLeft + 165, - guiTop + 38, - true, - 0 - ); + int errFontWidth = fr.getStringWidth("Net Worth: " + stateStr); + if (errFontWidth >= 117) { + fr.drawString(EnumChatFormatting.GREEN + "Net Worth: " + stateStr, + guiLeft + 8, guiTop + 38 - fr.FONT_HEIGHT / 2f, 0, true + ); + } else { + Utils.drawStringCentered( + EnumChatFormatting.GREEN + "Net Worth: " + stateStr, + fr, + guiLeft + 63, + guiTop + 38, + true, + 0 + ); + } } if (status != null) { @@ -794,7 +809,7 @@ public class BasicPage extends GuiProfileViewerPage { EnumChatFormatting.GOLD + GuiProfileViewer.numberFormat.format(roundToNearestInt(senitherWeight.getTotalWeight().getRaw())), fr, - guiLeft + 165, + guiLeft + 63, guiTop + 18, true, 0 @@ -804,7 +819,7 @@ public class BasicPage extends GuiProfileViewerPage { "Senither Weight: " + GuiProfileViewer.numberFormat.format(roundToNearestInt(senitherWeight.getTotalWeight().getRaw())) ); - if (mouseX > guiLeft + 165 - textWidth / 2 && mouseX < guiLeft + 165 + textWidth / 2) { + if (mouseX > guiLeft + 63 - textWidth / 2 && mouseX < guiLeft + 63 + textWidth / 2) { if (mouseY > guiTop + 12 && mouseY < guiTop + 12 + fr.FONT_HEIGHT) { getInstance().tooltipToDisplay = new ArrayList<>(); getInstance() @@ -862,7 +877,7 @@ public class BasicPage extends GuiProfileViewerPage { EnumChatFormatting.GOLD + GuiProfileViewer.numberFormat.format(roundToNearestInt(lilyWeight.getTotalWeight().getRaw())), fr, - guiLeft + 165, + guiLeft + 63, guiTop + 28, true, 0 @@ -871,7 +886,7 @@ public class BasicPage extends GuiProfileViewerPage { int fontWidth = fr.getStringWidth( "Lily Weight: " + GuiProfileViewer.numberFormat.format(roundToNearestInt(lilyWeight.getTotalWeight().getRaw())) ); - if (mouseX > guiLeft + 165 - fontWidth / 2 && mouseX < guiLeft + 165 + fontWidth / 2) { + if (mouseX > guiLeft + 63 - fontWidth / 2 && mouseX < guiLeft + 63 + fontWidth / 2) { if (mouseY > guiTop + 22 && mouseY < guiTop + 22 + fr.FONT_HEIGHT) { getInstance().tooltipToDisplay = new ArrayList<>(); getInstance() -- cgit From 5c58e19436f2935ae20cfb351ac6661b2dab1992 Mon Sep 17 00:00:00 2001 From: hannibal2 <24389977+hannibal002@users.noreply.github.com> Date: Wed, 15 Feb 2023 18:48:11 +0100 Subject: API errors in console (#610) * Print api errors in console. * No reason not to just append. * Censor API Key --------- Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com> Co-authored-by: nea --- .../notenoughupdates/core/config/annotations/ConfigOption.java | 1 + .../java/io/github/moulberry/notenoughupdates/util/ApiUtil.java | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'src/main/java') diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigOption.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigOption.java index 920cb326..ddd1e71f 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigOption.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigOption.java @@ -30,6 +30,7 @@ public @interface ConfigOption { String name(); String desc(); + String[] searchTags() default ""; int subcategoryId() default -1; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java index 023be060..45522329 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java @@ -213,7 +213,12 @@ public class ApiUtil { } catch (IOException e) { throw new RuntimeException(e); // We can rethrow, since supplyAsync catches exceptions. } - }, executorService); + }, executorService).handle((obj, t) -> { + if (t != null) { + System.err.println(ErrorUtil.printStackTraceWithoutApiKey(t)); + } + return obj; + }); } public CompletableFuture requestJson() { -- cgit From e0ab2af457daf50b838248afbc4110c97a0c8b4a Mon Sep 17 00:00:00 2001 From: hannibal2 <24389977+hannibal002@users.noreply.github.com> Date: Wed, 15 Feb 2023 18:50:09 +0100 Subject: Workaround for NEUOverlay crash (#615) * Workaround for IndexOutOfBoundsException in NEUOverlay * -1 line --------- Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com> --- .../java/io/github/moulberry/notenoughupdates/NEUOverlay.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/main/java') diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java index 7159ef89..927b5e76 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java @@ -1500,7 +1500,14 @@ public class NEUOverlay extends Gui { int actualIndex = index + getSlotsXSize() * getSlotsYSize() * page; List searchedItems = getSearchedItems(); if (0 <= actualIndex && actualIndex < searchedItems.size()) { - return searchedItems.get(actualIndex); + try { + return searchedItems.get(actualIndex); + } catch (IndexOutOfBoundsException e) { + System.out.println("searchedItems size: " + searchedItems.size()); + System.out.println("actualIndex: " + actualIndex); + e.printStackTrace(); + return null; + } } else { return null; } -- cgit From d3ca199f904cd72e419c6320eda261f023c71937 Mon Sep 17 00:00:00 2001 From: Roman / Linnea Gräf Date: Wed, 15 Feb 2023 18:50:56 +0100 Subject: ApiUtil: Add cache with per request timeout and per class histogram (#592) * ApiUtil: Add cache with per request timeout and per class histogram * MinionHelper: Only load minion helper data when needed * Api: Make api response processing more async. * Lower cache for /pv to 30 seconds and rename cacheDuration to max age * Disk cache for the API --- .../notenoughupdates/auction/APIManager.java | 14 ++++---- .../commands/dev/DevTestCommand.java | 20 ++++++++++++ .../commands/misc/PronounsCommand.java | 2 +- .../notenoughupdates/cosmetics/CapeManager.java | 4 +-- .../loaders/MinionHelperApiLoader.java | 7 +--- .../options/customtypes/NEUDebugFlag.java | 5 +++ .../profileviewer/ProfileViewer.java | 2 ++ .../moulberry/notenoughupdates/util/ApiUtil.java | 38 ++++++++++++++++++++-- .../notenoughupdates/util/MinecraftExecutor.java | 37 --------------------- 9 files changed, 73 insertions(+), 56 deletions(-) delete mode 100644 src/main/java/io/github/moulberry/notenoughupdates/util/MinecraftExecutor.java (limited to 'src/main/java') diff --git a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java index 5ec3724a..ac60ffd9 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java @@ -292,7 +292,7 @@ public class APIManager { .newMoulberryRequest("lowestbin.json.gz") .gunzip() .requestJson() - .thenAccept(jsonObject -> { + .thenAcceptAsync(jsonObject -> { if (lowestBins == null) { lowestBins = new JsonObject(); } @@ -465,12 +465,12 @@ public class APIManager { }; manager.apiUtils.newMoulberryRequest("auctionLast.json.gz") - .gunzip().requestJson().thenAccept(process); + .gunzip().requestJson().thenAcceptAsync(process); manager.apiUtils .newMoulberryRequest("auction.json.gz") .gunzip().requestJson() - .thenAccept(jsonObject -> { + .thenAcceptAsync(jsonObject -> { if (jsonObject.get("success").getAsBoolean()) { long apiUpdate = (long) jsonObject.get("time").getAsFloat(); if (lastApiUpdate == apiUpdate) { @@ -683,7 +683,7 @@ public class APIManager { manager.apiUtils .newAnonymousHypixelApiRequest("skyblock/auctions") .requestJson() - .thenAccept(jsonObject -> { + .thenAcceptAsync(jsonObject -> { if (jsonObject == null) return; if (jsonObject.get("success").getAsBoolean()) { @@ -733,7 +733,7 @@ public class APIManager { manager.apiUtils .newAnonymousHypixelApiRequest("skyblock/bazaar") .requestJson() - .thenAccept(jsonObject -> { + .thenAcceptAsync(jsonObject -> { if (!jsonObject.get("success").getAsBoolean()) return; craftCost.clear(); @@ -789,7 +789,7 @@ public class APIManager { public void updateAvgPrices() { manager.apiUtils .newMoulberryRequest("auction_averages/3day.json.gz") - .gunzip().requestJson().thenAccept((jsonObject) -> { + .gunzip().requestJson().thenAcceptAsync((jsonObject) -> { craftCost.clear(); auctionPricesJson = jsonObject; lastAuctionAvgUpdate = System.currentTimeMillis(); @@ -797,7 +797,7 @@ public class APIManager { manager.apiUtils .newMoulberryRequest("auction_averages_lbin/1day.json.gz") .gunzip().requestJson() - .thenAccept((jsonObject) -> { + .thenAcceptAsync((jsonObject) -> { auctionPricesAvgLowestBinJson = jsonObject; }); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java index 35474ff3..8dda864a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java @@ -33,11 +33,13 @@ import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.Locati import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.SpecialBlockZone; import io.github.moulberry.notenoughupdates.miscgui.GuiPriceGraph; import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; +import io.github.moulberry.notenoughupdates.util.ApiCache; import io.github.moulberry.notenoughupdates.util.PronounDB; import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.TabListUtils; import io.github.moulberry.notenoughupdates.util.Utils; import io.github.moulberry.notenoughupdates.util.hypixelapi.ProfileCollectionInfo; +import lombok.var; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; import net.minecraft.command.CommandException; @@ -126,6 +128,24 @@ public class DevTestCommand extends ClientCommandBase { Utils.addChatMessage(EnumChatFormatting.RED + DEV_FAIL_STRINGS[devFailIndex++]); return; } + if (args.length == 1 && args[0].equalsIgnoreCase("dumpapihistogram")) { + synchronized (ApiCache.INSTANCE) { + Utils.addChatMessage("§e[NEU] API Request Histogram"); + Utils.addChatMessage("§e[NEU] §bClass Name§e: §aCached§e/§cNonCached§e/§dTotal"); + ApiCache.INSTANCE.getHistogramTotalRequests().forEach((className, totalRequests) -> { + var nonCachedRequests = ApiCache.INSTANCE.getHistogramNonCachedRequests().getOrDefault(className, 0); + var cachedRequests = totalRequests - nonCachedRequests; + Utils.addChatMessage( + String.format( + "§e[NEU] §b%s §a%d§e/§c%d§e/§d%d", + className, + cachedRequests, + nonCachedRequests, + totalRequests + )); + }); + } + } if (args.length == 1 && args[0].equalsIgnoreCase("testprofile")) { NotEnoughUpdates.INSTANCE.manager.apiUtils.newHypixelApiRequest("skyblock/profiles") .queryArgument( diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/PronounsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/PronounsCommand.java index 5a4f1400..cf0d0c56 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/PronounsCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/PronounsCommand.java @@ -88,7 +88,7 @@ public class PronounsCommand extends ClientCommandBase { "§e[NEU] Pronouns for §b" + user + " §eon §b" + platform + "§e:"), id); betterPronounChoice.render().forEach(it -> nc.printChatMessage(new ChatComponentText("§e[NEU] §a" + it))); return null; - }, MinecraftExecutor.INSTANCE); + }, MinecraftExecutor.OnThread); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java index 4a7c1939..984a7931 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java @@ -150,7 +150,7 @@ public class CapeManager { NotEnoughUpdates.INSTANCE.manager.apiUtils .newMoulberryRequest("activecapes.json") .requestJson() - .thenAccept(jsonObject -> { + .thenAcceptAsync(jsonObject -> { if (jsonObject.get("success").getAsBoolean()) { lastJsonSync = jsonObject; @@ -171,7 +171,7 @@ public class CapeManager { NotEnoughUpdates.INSTANCE.manager.apiUtils .newMoulberryRequest("permscapes.json") .requestJson() - .thenAccept(jsonObject -> { + .thenAcceptAsync(jsonObject -> { if (!jsonObject.get("success").getAsBoolean()) return; permSyncTries = 0; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperApiLoader.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperApiLoader.java index aaa398f4..ecf02236 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperApiLoader.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/minionhelper/loaders/MinionHelperApiLoader.java @@ -47,7 +47,6 @@ import java.util.Map; public class MinionHelperApiLoader { private final MinionHelperManager manager; private boolean dirty = true; - private int ticks = 0; private boolean collectionApiEnabled = true; private boolean ignoreWorldSwitches = false; private boolean readyToUse = false; @@ -72,11 +71,7 @@ public class MinionHelperApiLoader { if (Minecraft.getMinecraft().thePlayer == null) return; if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return; if (!NotEnoughUpdates.INSTANCE.config.minionHelper.gui) return; - ticks++; - - if (ticks % 20 != 0) return; - - if (dirty) { + if (dirty && "Crafted Minions".equals(Utils.getOpenChestName())) { load(); } else { if (System.currentTimeMillis() > lastLoaded + 60_000 * 3) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/customtypes/NEUDebugFlag.java b/src/main/java/io/github/moulberry/notenoughupdates/options/customtypes/NEUDebugFlag.java index 50f459c0..90ef93bb 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/customtypes/NEUDebugFlag.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/customtypes/NEUDebugFlag.java @@ -31,6 +31,7 @@ public enum NEUDebugFlag { WISHING("Wishing Compass Solver"), MAP("Dungeon Map Player Information"), SEARCH("SearchString Matches"), + API_CACHE("Api Cache"), ; private final String description; @@ -43,6 +44,10 @@ public enum NEUDebugFlag { return description; } + public void log(String message) { + NEUDebugLogger.log(this, message); + } + public boolean isSet() { return NEUDebugLogger.isFlagEnabled(this); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java index 17a14d1f..6f8427ae 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java @@ -42,6 +42,7 @@ import net.minecraft.util.EnumChatFormatting; import javax.annotation.Nullable; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; @@ -537,6 +538,7 @@ public class ProfileViewer { manager.apiUtils .newHypixelApiRequest("player") .queryArgument("name", nameF) + .maxCacheAge(Duration.ofSeconds(30)) .requestJson() .thenAccept(jsonObject -> { if ( diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java index 45522329..28298fe0 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ApiUtil.java @@ -48,18 +48,26 @@ import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; +import java.time.Duration; import java.util.ArrayList; import java.util.Collection; +import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.zip.GZIPInputStream; public class ApiUtil { private static final Gson gson = new Gson(); + + private static final Comparator nameValuePairComparator = Comparator + .comparing(NameValuePair::getName) + .thenComparing(NameValuePair::getValue); + private static final ExecutorService executorService = Executors.newFixedThreadPool(3); private static String getUserAgent() { if (NotEnoughUpdates.INSTANCE.config.hidden.customUserAgent != null) { @@ -110,6 +118,7 @@ public class ApiUtil { private final List queryArguments = new ArrayList<>(); private String baseUrl = null; private boolean shouldGunzip = false; + private Duration maxCacheAge = Duration.ofSeconds(500); private String method = "GET"; private String postData = null; private String postContentType = null; @@ -119,6 +128,15 @@ public class ApiUtil { return this; } + /** + * Specify a cache timeout of {@code null} to signify an uncacheable request. + * Non {@code GET} requests are always uncacheable. + */ + public Request maxCacheAge(Duration maxCacheAge) { + this.maxCacheAge = maxCacheAge; + return this; + } + public Request url(String baseUrl) { this.baseUrl = baseUrl; return this; @@ -160,7 +178,17 @@ public class ApiUtil { return fut; } - public CompletableFuture requestString() { + public String getBaseUrl() { + return baseUrl; + } + + private ApiCache.CacheKey getCacheKey() { + if (!"GET".equals(method)) return null; + queryArguments.sort(nameValuePairComparator); + return new ApiCache.CacheKey(baseUrl, queryArguments, shouldGunzip); + } + + private CompletableFuture requestString0() { return buildUrl().thenApplyAsync(url -> { try { InputStream inputStream = null; @@ -183,7 +211,7 @@ public class ApiUtil { conn.setDoOutput(true); OutputStream os = conn.getOutputStream(); try { - os.write(this.postData.getBytes("utf-8")); + os.write(this.postData.getBytes(StandardCharsets.UTF_8)); } finally { os.close(); } @@ -221,12 +249,16 @@ public class ApiUtil { }); } + public CompletableFuture requestString() { + return ApiCache.INSTANCE.cacheRequest(this, getCacheKey(), this::reque