aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/de
diff options
context:
space:
mode:
authorAaron <51387595+AzureAaron@users.noreply.github.com>2024-06-24 16:26:28 -0400
committerAaron <51387595+AzureAaron@users.noreply.github.com>2024-08-05 17:33:45 -0400
commit1f87d71bda093d5df82b870da2976384d2dc9126 (patch)
tree57206253d5bdf8cbe0cff78254b78e62eed772c3 /src/main/java/de
parent088583a5a5fff6758748e152d30de0adbbb12388 (diff)
downloadSkyblocker-1f87d71bda093d5df82b870da2976384d2dc9126.tar.gz
Skyblocker-1f87d71bda093d5df82b870da2976384d2dc9126.tar.bz2
Skyblocker-1f87d71bda093d5df82b870da2976384d2dc9126.zip
Estimated Item Value
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.java24
-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.java35
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/CodecUtils.java22
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/ItemUtils.java27
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/networth/NetworthCalculator.java19
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/networth/NetworthDataSuppliers.java33
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/networth/SkyblockItemMetadata.java57
16 files changed, 274 insertions, 38 deletions
diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
index 4e110e15..7c738c12 100644
--- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
+++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
@@ -115,7 +115,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 bea570e5..32f99e3f 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 61386452..49396f54 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..d35c58fa 100644
--- a/src/main/java/de/hysky/skyblocker/debug/Debug.java
+++ b/src/main/java/de/hysky/skyblocker/debug/Debug.java
@@ -8,11 +8,13 @@ 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.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;
@@ -55,14 +57,18 @@ public class Debug {
)));
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 +114,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 40655bd1..4eaa295e 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
@@ -33,12 +33,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..83282f7a
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/EstimatedItemValueTooltip.java
@@ -0,0 +1,35 @@
+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) {
+ if (TooltipInfoType.ESTIMATED_ITEM_VALUE.isTooltipEnabled()) {
+ 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)));
+ }
+ }
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/CodecUtils.java b/src/main/java/de/hysky/skyblocker/utils/CodecUtils.java
new file mode 100644
index 00000000..d40559a3
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/CodecUtils.java
@@ -0,0 +1,22 @@
+package de.hysky.skyblocker.utils;
+
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.DataResult;
+
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
+import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
+
+public class CodecUtils {
+
+ public static <K> Codec<Object2IntMap<K>> createObject2IntMapCodec(Codec<K> keyCodec) {
+ return Codec.unboundedMap(keyCodec, Codec.INT)
+ .flatComapMap(Object2IntOpenHashMap::new, map -> DataResult.success(new Object2IntOpenHashMap<>(map)));
+ }
+
+ public static <K, V> Codec<Object2ObjectMap<K, V>> createObject2ObjectMapCodec(Codec<K> keyCodec, Codec<V> valueCodec) {
+ return Codec.unboundedMap(keyCodec, valueCodec)
+ .flatComapMap(Object2ObjectOpenHashMap::new, map -> DataResult.success(new Object2ObjectOpenHashMap<>(map)));
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java
index 8ddfbf1b..5869315f 100644
--- a/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java
+++ b/src/main/java/de/hysky/skyblocker/utils/ItemUtils.java
@@ -15,6 +15,7 @@ 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 de.hysky.skyblocker.utils.networth.NetworthCalculator;
import it.unimi.dsi.fastutil.doubles.DoubleBooleanPair;
import it.unimi.dsi.fastutil.ints.IntIntPair;
import it.unimi.dsi.fastutil.longs.LongBooleanPair;
@@ -67,6 +68,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 +276,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 +292,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)) {
@@ -448,4 +463,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..0baa5ad7
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/networth/NetworthCalculator.java
@@ -0,0 +1,19 @@
+package de.hysky.skyblocker.utils.networth;
+
+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;
+
+public class NetworthCalculator {
+
+ public static NetworthResult getItemNetworth(ItemStack stack) {
+ String itemId = ItemUtils.getItemId(stack);
+ SkyblockItemStack skyblockItemStack = SkyblockItemStack.of(itemId, stack.getCount(), SkyblockItemMetadata.of(stack.getOrDefault(DataComponentTypes.CUSTOM_DATA, NbtComponent.DEFAULT).copyNbt(), 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..86e9ed9f
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/networth/NetworthDataSuppliers.java
@@ -0,0 +1,33 @@
+package de.hysky.skyblocker.utils.networth;
+
+import java.util.List;
+
+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 net.azureaaron.networth.data.SkyblockItemData;
+
+public class NetworthDataSuppliers {
+ private static final Logger LOGGER = LogUtils.getLogger();
+ private static List<SkyblockItemData> itemData = List.of();
+
+ public static void updateSkyblockItemData(JsonArray items) {
+ try {
+ itemData = SkyblockItemData.LIST_CODEC.parse(JsonOps.INSTANCE, items).getOrThrow();
+ } catch (Exception e) {
+ LOGGER.error("[Skyblocker Networth Data Supplier] Failed to parse items data!", e);
+ }
+ }
+
+ static List<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/SkyblockItemMetadata.java b/src/main/java/de/hysky/skyblocker/utils/networth/SkyblockItemMetadata.java
new file mode 100644
index 00000000..0eea3971
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/networth/SkyblockItemMetadata.java
@@ -0,0 +1,57 @@
+package de.hysky.skyblocker.utils.networth;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import com.google.gson.JsonParser;
+import com.mojang.datafixers.util.Either;
+import com.mojang.serialization.Codec;
+import com.mojang.serialization.JsonOps;
+
+import de.hysky.skyblocker.utils.CodecUtils;
+import it.unimi.dsi.fastutil.ints.IntList;
+import it.unimi.dsi.fastutil.objects.Object2IntMap;
+import net.azureaaron.networth.item.AccessoryUpgrades;
+import net.azureaaron.networth.item.AuctionBidInfo;
+import net.azureaaron.networth.item.Cosmetics;
+import net.azureaaron.networth.item.DrillInfo;
+import net.azureaaron.networth.item.DungeonUpgrades;
+import net.azureaaron.networth.item.GearUpgrades;
+import net.azureaaron.networth.item.Gemstone;
+import net.azureaaron.networth.item.ItemMetadata;
+import net.azureaaron.networth.item.LimitedEditionInfo;
+import net.azureaaron.networth.item.MiscModifiers;
+import net.azureaaron.networth.item.PetInfo;
+import net.minecraft.nbt.NbtCompound;
+import net.minecraft.nbt.NbtElement;
+import net.minecraft.nbt.NbtOps;
+import net.minecraft.util.Util;
+
+public record SkyblockItemMetadata(Object2IntMap<String> enchantments, int rarityUpgrades, Optional<String> reforge, int upgradeLevel, DungeonUpgrades dungeonUpgrades,
+ GearUpgrades gearUpgrades, List<String> gemstoneSlots, Map<String, Either<String, Gemstone>> gemstones, DrillInfo drillInfo, Object2IntMap<String> attributes,
+ AuctionBidInfo auctionBidInfo, MiscModifiers miscModifiers, AccessoryUpgrades accessoryUpgrades, Cosmetics cosmetics, PetInfo petInfo,
+ LimitedEditionInfo limitedEditionInfo, IntList cakeBagCakeYears) implements ItemMetadata {
+ private static final Codec<Object2IntMap<String>> OBJECT_2_INT_MAP_CODEC = CodecUtils.createObject2IntMapCodec(Codec.STRING);
+
+ static SkyblockItemMetadata of(NbtCompound customData, String itemId) {
+ return new SkyblockItemMetadata(
+ OBJECT_2_INT_MAP_CODEC.parse(NbtOps.INSTANCE, customData.getCompound("enchantments")).getOrThrow(),
+ customData.getInt("rarity_upgrades"),
+ customData.contains("modifier") ? Optional.of(customData.getString("modifier")) : Optional.empty(),
+ customData.getInt("upgrade_level"),
+ DungeonUpgrades.CODEC.parse(NbtOps.INSTANCE, customData).getOrThrow(),
+ GearUpgrades.CODEC.parse(NbtOps.INSTANCE, customData).getOrThrow(),
+ customData.getCompound("gems").getList("unlocked_slots", NbtElement.STRING_TYPE).stream().map(NbtElement::asString).toList(),
+ Util.make(() -> Gemstone.MAP_EITHER_CODEC.parse(NbtOps.INSTANCE, Util.make(customData.getCompound("gems").copy(), gemsCopy -> gemsCopy.remove("unlocked_slots"))).getOrThrow()),
+ DrillInfo.CODEC.parse(NbtOps.INSTANCE, customData).getOrThrow(),
+ OBJECT_2_INT_MAP_CODEC.parse(NbtOps.INSTANCE, customData.getCompound("attributes")).getOrThrow(),
+ AuctionBidInfo.CODEC.parse(NbtOps.INSTANCE, customData).getOrThrow(),
+ MiscModifiers.CODEC.parse(NbtOps.INSTANCE, customData).getOrThrow(),
+ AccessoryUpgrades.CODEC.parse(NbtOps.INSTANCE, customData).getOrThrow(),
+ Cosmetics.CODEC.parse(NbtOps.INSTANCE, customData).getOrThrow(),
+ customData.contains("petInfo") ? PetInfo.CODEC.parse(JsonOps.INSTANCE, JsonParser.parseString(customData.getString("petInfo"))).getOrThrow() : null,
+ LimitedEditionInfo.CODEC.parse(NbtOps.INSTANCE, customData).getOrThrow(),
+ itemId.equals("NEW_YEAR_CAKE_BAG") ? IntList.of() : IntList.of());
+ }
+}