aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de
diff options
context:
space:
mode:
authorAaron <51387595+AzureAaron@users.noreply.github.com>2024-08-12 03:08:48 -0400
committerGitHub <noreply@github.com>2024-08-12 03:08:48 -0400
commit9b95005a58c28324a2ec6eee851e7722c52ee0c4 (patch)
tree9596cd098a6bdc98a8e2e1d27b90368a0cb3acce /src/main/java/de
parent50d735bd4cdbad755b24242ba9a8abd02cb8ff28 (diff)
parent61c13167db42e945c87bc5e10e2ae3caf7f306c0 (diff)
downloadSkyblocker-9b95005a58c28324a2ec6eee851e7722c52ee0c4.tar.gz
Skyblocker-9b95005a58c28324a2ec6eee851e7722c52ee0c4.tar.bz2
Skyblocker-9b95005a58c28324a2ec6eee851e7722c52ee0c4.zip
Merge pull request #806 from SkyblockerMod/networth
Networth
Diffstat (limited to 'src/main/java/de')
-rw-r--r--src/main/java/de/hysky/skyblocker/SkyblockerMod.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java8
-rw-r--r--src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java3
-rw-r--r--src/main/java/de/hysky/skyblocker/debug/Debug.java26
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java3
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/PlayerHeadHashCache.java11
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemData.java40
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java8
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java7
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipManager.java13
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/EstimatedItemValueTooltip.java38
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/ItemUtils.java33
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/networth/NetworthCalculator.java26
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/networth/NetworthDataSuppliers.java33
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/networth/SkyblockItemMetadataRetriever.java42
15 files changed, 253 insertions, 40 deletions
diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
index 7ede3c63..5e573598 100644
--- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
+++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
@@ -118,7 +118,7 @@ public class SkyblockerMod implements ClientModInitializer {
NEURepoManager.init();
//ImageRepoLoader.init();
ItemRepository.init();
- PlayerHeadHashCache.init();
+ SkyblockItemData.init();
HotbarSlotLock.init();
ItemTooltip.init();
AccessoriesHelper.init();
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java
index 5bb8396f..ff089432 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java
@@ -229,6 +229,14 @@ public class GeneralCategory {
newValue -> config.general.itemTooltip.showEssenceCost = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("skyblocker.config.general.itemTooltip.enableEstimatedItemValue"))
+ .description(OptionDescription.of(Text.translatable("skyblocker.config.general.itemTooltip.enableEstimatedItemValue.@Tooltip")))
+ .binding(defaults.general.itemTooltip.enableEstimatedItemValue,
+ () -> config.general.itemTooltip.enableEstimatedItemValue,
+ newValue -> config.general.itemTooltip.enableEstimatedItemValue = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
.build())
//Item Info Display
diff --git a/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java
index 6327e6ab..92206c49 100644
--- a/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java
+++ b/src/main/java/de/hysky/skyblocker/config/configs/GeneralConfig.java
@@ -135,6 +135,9 @@ public class GeneralConfig {
@SerialEntry
public boolean showEssenceCost = false;
+
+ @SerialEntry
+ public boolean enableEstimatedItemValue = true;
}
public enum Average {
diff --git a/src/main/java/de/hysky/skyblocker/debug/Debug.java b/src/main/java/de/hysky/skyblocker/debug/Debug.java
index f1240a1c..fff12619 100644
--- a/src/main/java/de/hysky/skyblocker/debug/Debug.java
+++ b/src/main/java/de/hysky/skyblocker/debug/Debug.java
@@ -8,11 +8,14 @@ import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor;
import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.ItemUtils;
import de.hysky.skyblocker.utils.datafixer.ItemStackComponentizationFixer;
+import de.hysky.skyblocker.utils.networth.NetworthCalculator;
+import net.azureaaron.networth.Calculation;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
import net.fabricmc.fabric.api.client.screen.v1.ScreenKeyboardEvents;
import net.fabricmc.loader.api.FabricLoader;
+import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.item.ItemStack;
@@ -49,20 +52,25 @@ public class Debug {
ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(literal(SkyblockerMod.NAMESPACE).then(literal("debug")
.then(dumpPlayersCommand())
.then(ItemUtils.dumpHeldItemCommand())
+ .then(ItemUtils.dumpHeldItemNetworthCalculationsCommand())
.then(toggleShowingInvisibleArmorStands())
.then(dumpArmorStandHeadTextures())
.then(toggleWebSocketDebug())
)));
ScreenEvents.BEFORE_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
if (screen instanceof HandledScreen<?> handledScreen) {
- ScreenKeyboardEvents.afterKeyPress(screen).register((_screen, key, scancode, modifier) -> {
- Slot focusedSlot = ((HandledScreenAccessor) handledScreen).getFocusedSlot();
- if (key == GLFW.GLFW_KEY_U && client.player != null && focusedSlot != null && focusedSlot.hasStack()) {
- client.player.sendMessage(Text.literal("[Skyblocker Debug] Hovered Item: " + SkyblockerMod.GSON_COMPACT.toJson(ItemStack.CODEC.encodeStart(ItemStackComponentizationFixer.getRegistryLookup().getOps(JsonOps.INSTANCE), focusedSlot.getStack()).getOrThrow())));
- }
- });
- }
- });
+ ScreenKeyboardEvents.afterKeyPress(screen).register((_screen, key, scancode, modifier) -> {
+ Slot focusedSlot = ((HandledScreenAccessor) handledScreen).getFocusedSlot();
+ if (key == GLFW.GLFW_KEY_U && client.player != null && focusedSlot != null && focusedSlot.hasStack()) {
+ if (!Screen.hasShiftDown()) {
+ client.player.sendMessage(Text.literal("[Skyblocker Debug] Hovered Item: " + SkyblockerMod.GSON_COMPACT.toJson(ItemStack.CODEC.encodeStart(ItemStackComponentizationFixer.getRegistryLookup().getOps(JsonOps.INSTANCE), focusedSlot.getStack()).getOrThrow())));
+ } else {
+ client.player.sendMessage(Text.literal("[Skyblocker Debug] Held Item NW Calcs: " + SkyblockerMod.GSON_COMPACT.toJson(Calculation.LIST_CODEC.encodeStart(JsonOps.INSTANCE, NetworthCalculator.getItemNetworth(focusedSlot.getStack()).calculations()).getOrThrow())));
+ }
+ }
+ });
+ }
+ });
}
}
@@ -108,4 +116,4 @@ public class Debug {
return Command.SINGLE_SUCCESS;
});
}
-}
+} \ No newline at end of file
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java b/src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java
index 67928b07..0b188a37 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/ChestValue.java
@@ -7,6 +7,7 @@ import de.hysky.skyblocker.mixins.accessors.HandledScreenAccessor;
import de.hysky.skyblocker.mixins.accessors.ScreenAccessor;
import de.hysky.skyblocker.utils.ItemUtils;
import de.hysky.skyblocker.utils.Utils;
+import de.hysky.skyblocker.utils.networth.NetworthCalculator;
import it.unimi.dsi.fastutil.doubles.DoubleBooleanPair;
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents;
import net.fabricmc.fabric.api.client.screen.v1.Screens;
@@ -192,7 +193,7 @@ public class ChestValue {
if (!priceData.rightBoolean()) hasIncompleteData = true;
- value += priceData.leftDouble() * stack.getCount();
+ value += NetworthCalculator.getItemNetworth(stack).price();
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/PlayerHeadHashCache.java b/src/main/java/de/hysky/skyblocker/skyblock/item/PlayerHeadHashCache.java
index da832164..b751aa73 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/PlayerHeadHashCache.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/PlayerHeadHashCache.java
@@ -2,7 +2,6 @@ package de.hysky.skyblocker.skyblock.item;
import java.net.URI;
import java.util.Base64;
-import java.util.concurrent.CompletableFuture;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
@@ -12,22 +11,14 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.mojang.logging.LogUtils;
-import de.hysky.skyblocker.utils.Http;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
public class PlayerHeadHashCache {
private static final Logger LOGGER = LogUtils.getLogger();
private static final IntOpenHashSet CACHE = new IntOpenHashSet();
- public static void init() {
- CompletableFuture.runAsync(PlayerHeadHashCache::loadSkins);
- }
-
- private static void loadSkins() {
+ static void loadSkins(JsonArray items) {
try {
- String response = Http.sendGetRequest("https://api.hypixel.net/v2/resources/skyblock/items");
- JsonArray items = JsonParser.parseString(response).getAsJsonObject().getAsJsonArray("items");
-
items.asList().stream()
.map(JsonElement::getAsJsonObject)
.filter(item -> item.get("material").getAsString().equals("SKULL_ITEM"))
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemData.java b/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemData.java
new file mode 100644
index 00000000..8a34685c
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemData.java
@@ -0,0 +1,40 @@
+package de.hysky.skyblocker.skyblock.item;
+
+import java.util.concurrent.CompletableFuture;
+
+import org.slf4j.Logger;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import com.mojang.logging.LogUtils;
+
+import de.hysky.skyblocker.utils.Http;
+import de.hysky.skyblocker.utils.networth.NetworthDataSuppliers;
+
+public class SkyblockItemData {
+ private static final Logger LOGGER = LogUtils.getLogger();
+
+ public static void init() {
+ updateItems().thenAcceptAsync(items -> {
+ PlayerHeadHashCache.loadSkins(items);
+ NetworthDataSuppliers.updateSkyblockItemData(items);
+ });
+ }
+
+ private static CompletableFuture<JsonArray> updateItems() {
+ return CompletableFuture.supplyAsync(() -> {
+ try {
+ String response = Http.sendGetRequest("https://api.hypixel.net/v2/resources/skyblock/items");
+ JsonObject itemsData = JsonParser.parseString(response).getAsJsonObject();
+
+ return itemsData.getAsJsonArray("items");
+ } catch (Exception e) {
+ LOGGER.error("[Skyblocker Item Data Loader] Failed to load items data from the Hypixel API!", e);
+ }
+
+ //Complete the future exceptionally so that the other things don't run
+ throw new IllegalStateException();
+ });
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java
index 79f1f650..60a03118 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java
@@ -42,8 +42,12 @@ public class ItemTooltip {
}
public static Text getCoinsMessage(double price, int count) {
+ return getCoinsMessage(price, count, false);
+ }
+
+ public static Text getCoinsMessage(double price, int count, boolean preCounted) {
// Format the price string once
- String priceString = String.format(Locale.ENGLISH, "%1$,.1f", price);
+ String priceString = String.format(Locale.ENGLISH, "%1$,.1f", preCounted ? price / count : price);
// If count is 1, return a simple message
if (count == 1) {
@@ -51,7 +55,7 @@ public class ItemTooltip {
}
// If count is greater than 1, include the "each" information
- String priceStringTotal = String.format(Locale.ENGLISH, "%1$,.1f", price * count);
+ String priceStringTotal = String.format(Locale.ENGLISH, "%1$,.1f", preCounted ? price : price * count);
return Text.literal(priceStringTotal + " Coins ").formatted(Formatting.DARK_AQUA)
.append(Text.literal("(" + priceString + " each)").formatted(Formatting.GRAY));
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java
index d8327383..04d0d81c 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java
@@ -17,15 +17,16 @@ import java.util.function.Predicate;
public enum TooltipInfoType implements Runnable {
NPC("https://hysky.de/api/npcprice", itemTooltip -> itemTooltip.enableNPCPrice, true),
- BAZAAR("https://hysky.de/api/bazaar", itemTooltip -> itemTooltip.enableBazaarPrice || itemTooltip.enableCraftingCost.getOrder() != null || SkyblockerConfigManager.get().dungeons.dungeonChestProfit.enableProfitCalculator || SkyblockerConfigManager.get().dungeons.dungeonChestProfit.croesusProfit || SkyblockerConfigManager.get().uiAndVisuals.chestValue.enableChestValue || itemTooltip.showEssenceCost, itemTooltip -> itemTooltip.enableBazaarPrice, false, EssenceShopPrice::refreshEssencePrices),
- LOWEST_BINS("https://hysky.de/api/auctions/lowestbins", itemTooltip -> itemTooltip.enableLowestBIN || itemTooltip.enableCraftingCost.getOrder() != null || SkyblockerConfigManager.get().dungeons.dungeonChestProfit.enableProfitCalculator || SkyblockerConfigManager.get().dungeons.dungeonChestProfit.croesusProfit || SkyblockerConfigManager.get().uiAndVisuals.chestValue.enableChestValue, itemTooltip -> itemTooltip.enableLowestBIN, false),
+ BAZAAR("https://hysky.de/api/bazaar", itemTooltip -> itemTooltip.enableBazaarPrice || itemTooltip.enableCraftingCost.getOrder() != null || itemTooltip.enableEstimatedItemValue || SkyblockerConfigManager.get().dungeons.dungeonChestProfit.enableProfitCalculator || SkyblockerConfigManager.get().dungeons.dungeonChestProfit.croesusProfit || SkyblockerConfigManager.get().uiAndVisuals.chestValue.enableChestValue || itemTooltip.showEssenceCost, itemTooltip -> itemTooltip.enableBazaarPrice, false, EssenceShopPrice::refreshEssencePrices),
+ LOWEST_BINS("https://hysky.de/api/auctions/lowestbins", itemTooltip -> itemTooltip.enableLowestBIN || itemTooltip.enableCraftingCost.getOrder() != null || itemTooltip.enableEstimatedItemValue || SkyblockerConfigManager.get().dungeons.dungeonChestProfit.enableProfitCalculator || SkyblockerConfigManager.get().dungeons.dungeonChestProfit.croesusProfit || SkyblockerConfigManager.get().uiAndVisuals.chestValue.enableChestValue, itemTooltip -> itemTooltip.enableLowestBIN, false),
ONE_DAY_AVERAGE("https://hysky.de/api/auctions/lowestbins/average/1day.json", itemTooltip -> itemTooltip.enableAvgBIN, false),
THREE_DAY_AVERAGE("https://hysky.de/api/auctions/lowestbins/average/3day.json", itemTooltip -> itemTooltip.enableAvgBIN || SkyblockerConfigManager.get().uiAndVisuals.searchOverlay.enableAuctionHouse, itemTooltip -> itemTooltip.enableAvgBIN, false),
MOTES("https://hysky.de/api/motesprice", itemTooltip -> itemTooltip.enableMotesPrice, itemTooltip -> itemTooltip.enableMotesPrice && Utils.isInTheRift(), true),
OBTAINED(itemTooltip -> itemTooltip.enableObtainedDate),
MUSEUM("https://hysky.de/api/museum", itemTooltip -> itemTooltip.enableMuseumInfo, true),
COLOR("https://hysky.de/api/color", itemTooltip -> itemTooltip.enableExoticTooltip, true),
- ACCESSORIES("https://hysky.de/api/accessories", itemTooltip -> itemTooltip.enableAccessoriesHelper, true, AccessoriesHelper::refreshData);
+ ACCESSORIES("https://hysky.de/api/accessories", itemTooltip -> itemTooltip.enableAccessoriesHelper, true, AccessoriesHelper::refreshData),
+ ESTIMATED_ITEM_VALUE(itemTooltip -> itemTooltip.enableEstimatedItemValue);
private final String address;
private final Predicate<GeneralConfig.ItemTooltip> dataEnabled;
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipManager.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipManager.java
index ce8f2b9d..18307a02 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipManager.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipManager.java
@@ -34,12 +34,13 @@ public class TooltipManager {
new AvgBinTooltip(4),
new EssenceShopPrice(5),
new CraftPriceTooltip(6),
- new DungeonQualityTooltip(7),
- new MotesTooltip(8),
- new ObtainedDateTooltip(9),
- new MuseumTooltip(10),
- new ColorTooltip(11),
- new AccessoryTooltip(12),
+ new EstimatedItemValueTooltip(7),
+ new DungeonQualityTooltip(8),
+ new MotesTooltip(9),
+ new ObtainedDateTooltip(10),
+ new MuseumTooltip(11),
+ new ColorTooltip(12),
+ new AccessoryTooltip(13),
};
private static final ArrayList<TooltipAdder> currentScreenAdders = new ArrayList<>();
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/EstimatedItemValueTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/EstimatedItemValueTooltip.java
new file mode 100644
index 00000000..cd2c587a
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/EstimatedItemValueTooltip.java
@@ -0,0 +1,38 @@
+package de.hysky.skyblocker.skyblock.item.tooltip.adders;
+
+import java.util.List;
+
+import org.jetbrains.annotations.Nullable;
+
+import de.hysky.skyblocker.skyblock.item.tooltip.ItemTooltip;
+import de.hysky.skyblocker.skyblock.item.tooltip.SimpleTooltipAdder;
+import de.hysky.skyblocker.skyblock.item.tooltip.TooltipInfoType;
+import de.hysky.skyblocker.utils.networth.NetworthCalculator;
+import net.azureaaron.networth.NetworthResult;
+import net.minecraft.item.ItemStack;
+import net.minecraft.screen.slot.Slot;
+import net.minecraft.text.Text;
+import net.minecraft.util.Formatting;
+
+public class EstimatedItemValueTooltip extends SimpleTooltipAdder {
+
+ public EstimatedItemValueTooltip(int priority) {
+ super(priority);
+ }
+
+ @Override
+ public void addToTooltip(@Nullable Slot focusedSlot, ItemStack stack, List<Text> lines) {
+ NetworthResult result = NetworthCalculator.getItemNetworth(stack);
+
+ if (result.price() > 0) {
+ lines.add(Text.literal(String.format("%-20s", "Est. Item Value:"))
+ .formatted(Formatting.GOLD)
+ .append(ItemTooltip.getCoinsMessage(result.price(), stack.getCount(), true)));
+ }
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return TooltipInfoType.ESTIMATED_ITEM_VALUE.isTooltipEnabled();
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java
index f91bae40..da4bf873 100644
--- a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java
+++ b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java
@@ -10,14 +10,17 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.serialization.Codec;
import com.mojang.serialization.JsonOps;
import com.mojang.serialization.codecs.RecordCodecBuilder;
+
+import de.hysky.skyblocker.skyblock.item.tooltip.adders.ObtainedDateTooltip;
+import de.hysky.skyblocker.utils.datafixer.ItemStackComponentizationFixer;
+import de.hysky.skyblocker.utils.networth.NetworthCalculator;
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.skyblock.PetCache;
import de.hysky.skyblocker.skyblock.item.tooltip.TooltipInfoType;
-import de.hysky.skyblocker.skyblock.item.tooltip.adders.ObtainedDateTooltip;
-import de.hysky.skyblocker.utils.datafixer.ItemStackComponentizationFixer;
import it.unimi.dsi.fastutil.doubles.DoubleBooleanPair;
import it.unimi.dsi.fastutil.ints.IntIntPair;
import it.unimi.dsi.fastutil.longs.LongBooleanPair;
+import net.azureaaron.networth.Calculation;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.component.ComponentChanges;
import net.minecraft.component.ComponentHolder;
@@ -67,6 +70,13 @@ public final class ItemUtils {
});
}
+ public static LiteralArgumentBuilder<FabricClientCommandSource> dumpHeldItemNetworthCalculationsCommand() {
+ return literal("dumpHeldItemNetworthCalcs").executes(context -> {
+ context.getSource().sendFeedback(Text.literal("[Skyblocker Debug] Held Item NW Calcs: " + SkyblockerMod.GSON_COMPACT.toJson(Calculation.LIST_CODEC.encodeStart(JsonOps.INSTANCE, NetworthCalculator.getItemNetworth(context.getSource().getPlayer().getMainHandStack()).calculations()).getOrThrow())));
+ return Command.SINGLE_SUCCESS;
+ });
+ }
+
/**
* Gets the nbt in the custom data component of the item stack.
* @return The {@link DataComponentTypes#CUSTOM_DATA custom data} of the itemstack,
@@ -268,7 +278,14 @@ public final class ItemUtils {
* and the {@code right boolean} indicating if the price was based on complete data.
*/
public static @NotNull DoubleBooleanPair getItemPrice(@NotNull ItemStack stack) {
- return getItemPrice(stack.getSkyblockApiId());
+ return getItemPrice(stack.getSkyblockApiId(), false);
+ }
+
+ /**
+ * @see #getItemPrice(String, boolean)
+ */
+ public static @NotNull DoubleBooleanPair getItemPrice(@Nullable String skyblockApiId) {
+ return getItemPrice(skyblockApiId, false);
}
/**
@@ -277,16 +294,16 @@ public final class ItemUtils {
* @return An {@link LongBooleanPair} with the {@code left long} representing the item's price,
* and the {@code right boolean} indicating if the price was based on complete data.
*/
- public static @NotNull DoubleBooleanPair getItemPrice(@Nullable String skyblockApiId) {
+ public static @NotNull DoubleBooleanPair getItemPrice(@Nullable String skyblockApiId, boolean useBazaarBuyPrice) {
JsonObject bazaarPrices = TooltipInfoType.BAZAAR.getData();
JsonObject lowestBinPrices = TooltipInfoType.LOWEST_BINS.getData();
if (skyblockApiId == null || skyblockApiId.isEmpty() || bazaarPrices == null || lowestBinPrices == null) return DoubleBooleanPair.of(0, false);
if (bazaarPrices.has(skyblockApiId)) {
- JsonElement sellPrice = bazaarPrices.get(skyblockApiId).getAsJsonObject().get("sellPrice");
- boolean isPriceNull = sellPrice.isJsonNull();
- return DoubleBooleanPair.of(isPriceNull ? 0 : sellPrice.getAsDouble(), !isPriceNull);
+ JsonElement price = bazaarPrices.get(skyblockApiId).getAsJsonObject().get(useBazaarBuyPrice ? "buyPrice" : "sellPrice");
+ boolean isPriceNull = price.isJsonNull();
+ return DoubleBooleanPair.of(isPriceNull ? 0 : price.getAsDouble(), !isPriceNull);
}
if (lowestBinPrices.has(skyblockApiId)) {
@@ -449,4 +466,4 @@ public final class ItemUtils {
}
return stringBuilder.toString();
}
-}
+} \ No newline at end of file
diff --git a/src/main/java/de/hysky/skyblocker/utils/networth/NetworthCalculator.java b/src/main/java/de/hysky/skyblocker/utils/networth/NetworthCalculator.java
new file mode 100644
index 00000000..2b4094e0
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/networth/NetworthCalculator.java
@@ -0,0 +1,26 @@
+package de.hysky.skyblocker.utils.networth;
+
+import com.mojang.serialization.Dynamic;
+
+import de.hysky.skyblocker.utils.ItemUtils;
+import net.azureaaron.networth.ItemCalculator;
+import net.azureaaron.networth.NetworthResult;
+import net.azureaaron.networth.item.SkyblockItemStack;
+import net.minecraft.component.DataComponentTypes;
+import net.minecraft.component.type.NbtComponent;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NbtCompound;
+import net.minecraft.nbt.NbtElement;
+import net.minecraft.nbt.NbtOps;
+
+public class NetworthCalculator {
+
+ public static NetworthResult getItemNetworth(ItemStack stack) {
+ String itemId = ItemUtils.getItemId(stack);
+ NbtCompound customData = stack.getOrDefault(DataComponentTypes.CUSTOM_DATA, NbtComponent.DEFAULT).copyNbt();
+ Dynamic<NbtElement> customDataDynamic = new Dynamic<>(NbtOps.INSTANCE, customData);
+ SkyblockItemStack skyblockItemStack = SkyblockItemStack.of(itemId, stack.getCount(), customDataDynamic, SkyblockItemMetadataRetriever.of(customData, itemId));
+
+ return ItemCalculator.calculate(skyblockItemStack, NetworthDataSuppliers::getPrice, NetworthDataSuppliers.getSkyblockItemData());
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/networth/NetworthDataSuppliers.java b/src/main/java/de/hysky/skyblocker/utils/networth/NetworthDataSuppliers.java
new file mode 100644
index 00000000..9980d65b
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/networth/NetworthDataSuppliers.java
@@ -0,0 +1,33 @@
+package de.hysky.skyblocker.utils.networth;
+
+import org.slf4j.Logger;
+
+import com.google.gson.JsonArray;
+import com.mojang.logging.LogUtils;
+import com.mojang.serialization.JsonOps;
+
+import de.hysky.skyblocker.utils.ItemUtils;
+import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
+import it.unimi.dsi.fastutil.objects.Object2ObjectMaps;
+import net.azureaaron.networth.data.SkyblockItemData;
+
+public class NetworthDataSuppliers {
+ private static final Logger LOGGER = LogUtils.getLogger();
+ private static Object2ObjectMap<String, SkyblockItemData> itemData = Object2ObjectMaps.emptyMap();
+
+ public static void updateSkyblockItemData(JsonArray items) {
+ try {
+ itemData = SkyblockItemData.MAP_CODEC.parse(JsonOps.INSTANCE, items).getOrThrow();
+ } catch (Exception e) {
+ LOGGER.error("[Skyblocker Networth Data Supplier] Failed to parse items data!", e);
+ }
+ }
+
+ static Object2ObjectMap<String, SkyblockItemData> getSkyblockItemData() {
+ return itemData;
+ }
+
+ static double getPrice(String id) {
+ return ItemUtils.getItemPrice(id, true).leftDouble(); //Use bazaar buy price because sell price can be heavily skewed sometimes
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/networth/SkyblockItemMetadataRetriever.java b/src/main/java/de/hysky/skyblocker/utils/networth/SkyblockItemMetadataRetriever.java
new file mode 100644
index 00000000..5cb0644f
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/networth/SkyblockItemMetadataRetriever.java
@@ -0,0 +1,42 @@
+package de.hysky.skyblocker.utils.networth;
+
+import java.io.ByteArrayInputStream;
+
+import it.unimi.dsi.fastutil.ints.IntArrayList;
+import it.unimi.dsi.fastutil.ints.IntList;
+import net.azureaaron.networth.item.ItemMetadataRetriever;
+import net.minecraft.nbt.NbtCompound;
+import net.minecraft.nbt.NbtElement;
+import net.minecraft.nbt.NbtIo;
+import net.minecraft.nbt.NbtList;
+import net.minecraft.nbt.NbtSizeTracker;
+
+record SkyblockItemMetadataRetriever(IntList cakeBagCakeYears) implements ItemMetadataRetriever {
+
+ static SkyblockItemMetadataRetriever of(NbtCompound customData, String itemId) {
+ return new SkyblockItemMetadataRetriever(getCakeBagCakeYears(customData, itemId));
+ }
+
+ private static IntList getCakeBagCakeYears(NbtCompound customData, String itemId) {
+ if (itemId.equals("NEW_YEAR_CAKE_BAG") && customData.contains("new_year_cake_bag_data")) {
+ try {
+ NbtCompound uncompressed = NbtIo.readCompressed(new ByteArrayInputStream(customData.getByteArray("new_year_cake_bag_data")), NbtSizeTracker.ofUnlimitedBytes());
+ NbtList items = uncompressed.getList("i", NbtElement.COMPOUND_TYPE);
+ IntList cakeYears = new IntArrayList();
+
+ for (NbtElement element : items) {
+ if (element instanceof NbtCompound compound && compound.getCompound("tag").contains("ExtraAttributes")) {
+ NbtCompound extraAttributes = compound.getCompound("tag").getCompound("ExtraAttributes");
+ int cakeYear = extraAttributes.getInt("new_years_cake"); //You can only put new year cakes in the bag so we don't need to check for it being one
+
+ cakeYears.add(cakeYear);
+ }
+ }
+
+ return cakeYears;
+ } catch (Exception ignored) {}
+ }
+
+ return IntList.of();
+ }
+}