From 67ec7cce2dfc6d367c94a1d103f77e56ccdbf976 Mon Sep 17 00:00:00 2001 From: mkram17 <1maxkramer@gmail.com> Date: Sun, 8 Mar 2026 15:08:10 -0400 Subject: [PATCH 01/15] refactor Bookmark to use MarketPrices --- .../bazaarutils/features/gui/buttons/bookmarks/Bookmark.java | 3 ++- .../features/gui/buttons/bookmarks/ToggleBookmarkButton.java | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/Bookmark.java b/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/Bookmark.java index 1a12f771..67832f09 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/Bookmark.java +++ b/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/Bookmark.java @@ -1,5 +1,6 @@ package com.github.mkram17.bazaarutils.features.gui.buttons.bookmarks; +import com.github.mkram17.bazaarutils.utils.bazaar.market.price.MarketPrices; import net.minecraft.item.ItemStack; -public record Bookmark(String name, ItemStack itemStack, String productID) {} \ No newline at end of file +public record Bookmark(String name, ItemStack itemStack, MarketPrices marketPrices) {} \ No newline at end of file diff --git a/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/ToggleBookmarkButton.java b/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/ToggleBookmarkButton.java index a01df5d6..7b3e2d5c 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/ToggleBookmarkButton.java +++ b/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/ToggleBookmarkButton.java @@ -8,6 +8,7 @@ import com.github.mkram17.bazaarutils.utils.bazaar.gui.BazaarScreenHandler; import com.github.mkram17.bazaarutils.utils.bazaar.gui.BazaarScreens; import com.github.mkram17.bazaarutils.utils.minecraft.item.ItemButton; +import com.github.mkram17.bazaarutils.utils.bazaar.market.price.MarketPrices; import com.github.mkram17.bazaarutils.utils.minecraft.ItemInfo; import com.github.mkram17.bazaarutils.utils.minecraft.components.CustomDataComponents; import com.github.mkram17.bazaarutils.utils.minecraft.gui.ScreenManager; @@ -97,7 +98,8 @@ private void toggleBookmark(String name) { .flatMap(BazaarScreenHandler::getDisplayProductId) .orElse(null); - Bookmark newBookmark = new Bookmark(name, itemStack, productId); + MarketPrices bookmarkMarketPrices = new MarketPrices(productId); + Bookmark newBookmark = new Bookmark(name, itemStack, bookmarkMarketPrices); list.add(newBookmark); BookmarkUtil.currentBookmarkOpt = Optional.of(newBookmark); From d733caf9feb67eacacd47d0e5618f4009e734ff3 Mon Sep 17 00:00:00 2001 From: mkram17 <1maxkramer@gmail.com> Date: Thu, 12 Mar 2026 20:27:12 -0400 Subject: [PATCH 02/15] separate methods and instance data from BazaarDataManager into new classes --- .../features/gui/overlays/PriceCharts.java | 4 +- .../utils/bazaar/data/BazaarDataManager.java | 265 ++++++------------ .../utils/bazaar/data/BazaarDataSettings.java | 9 + .../utils/bazaar/data/BazaarDataUtil.java | 111 ++++++++ .../utils/bazaar/gui/BazaarScreenHandler.java | 4 +- .../utils/bazaar/market/order/OrderInfo.java | 11 +- .../utils/minecraft/PlayerSlots.java | 4 +- 7 files changed, 210 insertions(+), 198 deletions(-) create mode 100644 src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataSettings.java create mode 100644 src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java diff --git a/src/main/java/com/github/mkram17/bazaarutils/features/gui/overlays/PriceCharts.java b/src/main/java/com/github/mkram17/bazaarutils/features/gui/overlays/PriceCharts.java index f9a34350..a6dc59d7 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/features/gui/overlays/PriceCharts.java +++ b/src/main/java/com/github/mkram17/bazaarutils/features/gui/overlays/PriceCharts.java @@ -2,9 +2,9 @@ import com.github.mkram17.bazaarutils.config.features.gui.OverlaysConfig; import com.github.mkram17.bazaarutils.utils.annotations.modules.Module; -import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataManager; import com.github.mkram17.bazaarutils.events.SlotClickEvent; import com.github.mkram17.bazaarutils.events.listener.BUListener; +import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataUtil; import com.github.mkram17.bazaarutils.utils.config.BUToggleableFeature; import com.github.mkram17.bazaarutils.utils.bazaar.gui.BazaarScreens; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.OrderInfo; @@ -78,7 +78,7 @@ private void onClick(SlotClickEvent e){ return; } - String productID = BazaarDataManager.findProductIdOptional(itemName).get(); // All cached items are safe + String productID = BazaarDataUtil.findProductIdOptional(itemName).get(); // All cached items are safe String link = "https://skyblock.finance/items/" + productID; MinecraftClient.getInstance().setScreen(new ConfirmLinkScreen(confirmed -> { diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java index 8a9cb156..77340935 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java @@ -4,19 +4,20 @@ import com.github.mkram17.bazaarutils.data.APIUtils; import com.github.mkram17.bazaarutils.events.BazaarDataUpdateEvent; import com.github.mkram17.bazaarutils.misc.NotificationType; -import com.github.mkram17.bazaarutils.utils.annotations.autoregistration.RunOnInit; -import com.github.mkram17.bazaarutils.mixin.AccessorSkyBlockBazaarReply; import com.github.mkram17.bazaarutils.utils.PlayerActionUtil; import com.github.mkram17.bazaarutils.utils.ResourceManager; import com.github.mkram17.bazaarutils.utils.Util; -import com.github.mkram17.bazaarutils.utils.bazaar.market.order.PriceType; -import com.github.mkram17.bazaarutils.utils.bazaar.market.order.TransactionType; +import com.github.mkram17.bazaarutils.utils.annotations.autoregistration.RunOnInit; +import com.github.mkram17.bazaarutils.mixin.AccessorSkyBlockBazaarReply; import lombok.Getter; import lombok.Setter; import net.hypixel.api.reply.skyblock.SkyBlockBazaarReply; -import java.time.Duration; -import java.util.*; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -25,12 +26,6 @@ public final class BazaarDataManager { - private static final long BASE_INTERVAL_MS = 20_000; - private static final long POST_OFFSET_MS = 500; - private static final long STALE_BACKOFF_MS = 750; - private static final long FAILURE_RETRY_MS = 500; - private static final int STALE_WARNING_THRESHOLD = 5; - @Getter private static volatile SkyBlockBazaarReply currentReply; @Getter @@ -38,12 +33,14 @@ public final class BazaarDataManager { private static volatile long lastFetchWallClock = -1; private static volatile ScheduledFuture scheduledTask; + // Serializes schedule/cancel so only one pending fetch task exists at a time. private static final Object SCHED_LOCK = new Object(); private static final AtomicInteger consecutiveIdenticalSnapshots = new AtomicInteger(0); private static final AtomicInteger consecutiveFailures = new AtomicInteger(0); - /* Cached conversions: lowercase name -> productID */ + /* Cached conversions: lowercase name -> productId */ + @Getter private static volatile Map nameToProductIdCache = Map.of(); @Setter private static volatile boolean conversionsLoaded = false; @@ -51,10 +48,9 @@ public final class BazaarDataManager { @RunOnInit public static void init() { scheduleFetch(0); - PlayerActionUtil.notifyAll("BazaarDataManager initialized (simple fixed-interval poller). Base=" + BASE_INTERVAL_MS + "ms", NotificationType.BAZAARDATA); + PlayerActionUtil.notifyAll("BazaarDataManager initialized (simple fixed-interval poller). Base=" + BazaarDataSettings.BASE_INTERVAL_MS + "ms", NotificationType.BAZAARDATA); } - private static void scheduleFetch(long delayMs) { synchronized (SCHED_LOCK) { if (scheduledTask != null && !scheduledTask.isDone()) { @@ -67,210 +63,127 @@ private static void scheduleFetch(long delayMs) { private static void fetchOnceSafely() { try { fetchOnce(); - } catch (Throwable t) { - Util.notifyError("Unexpected error in BazaarDataManager fetch loop", t); - scheduleFetch(FAILURE_RETRY_MS); + } catch (Throwable throwable) { + Util.notifyError("Unexpected error in BazaarDataManager fetch loop", throwable); + scheduleFailureRetry(); } } private static void fetchOnce() { - lastFetchWallClock = System.currentTimeMillis(); APIUtils.API.getSkyBlockBazaar().whenComplete((reply, throwable) -> { if (throwable != null) { - consecutiveFailures.incrementAndGet(); - PlayerActionUtil.notifyAll("Fetch failure (" + throwable.getClass().getSimpleName() + "). Retry in " + FAILURE_RETRY_MS + "ms (failures=" + consecutiveFailures.get() + ")", NotificationType.BAZAARDATA); - scheduleFetch(FAILURE_RETRY_MS); + handleFetchFailure( + "Fetch failure (" + throwable.getClass().getSimpleName() + "). Retry in " + BazaarDataSettings.FAILURE_RETRY_MS + "ms", + true + ); return; } + if (reply == null || !reply.isSuccess()) { - consecutiveFailures.incrementAndGet(); - PlayerActionUtil.notifyAll("Null/unsuccessful reply. Retry in " + FAILURE_RETRY_MS + "ms (failures=" + consecutiveFailures.get() + ")", NotificationType.BAZAARDATA); - scheduleFetch(FAILURE_RETRY_MS); + handleFetchFailure("Null/unsuccessful reply. Retry in " + BazaarDataSettings.FAILURE_RETRY_MS + "ms", true); return; } + consecutiveFailures.set(0); + updateFetchedProductIds(reply); long snapshotTs = extractLastUpdated(reply); if (snapshotTs <= 0) { - PlayerActionUtil.notifyAll("Invalid lastUpdated <= 0. Retry in " + FAILURE_RETRY_MS + "ms", NotificationType.BAZAARDATA); - scheduleFetch(FAILURE_RETRY_MS); + handleFetchFailure("Invalid lastUpdated <= 0. Retry in " + BazaarDataSettings.FAILURE_RETRY_MS + "ms", false); return; } - if (snapshotTs != lastSnapshotTs) { - long previous = lastSnapshotTs; - lastSnapshotTs = snapshotTs; - currentReply = reply; - consecutiveIdenticalSnapshots.set(0); - - EVENT_BUS.post(new BazaarDataUpdateEvent(reply)); - - if (previous != -1) { - PlayerActionUtil.notifyAll("New snapshot " + snapshotTs + " (Δ " + (snapshotTs - previous) + " ms). Scheduling next predicted fetch.", NotificationType.BAZAARDATA); - } else { - PlayerActionUtil.notifyAll("First snapshot " + snapshotTs + " received.", NotificationType.BAZAARDATA); - } - - scheduleNextFromSnapshot(snapshotTs); - } else { - int identical = consecutiveIdenticalSnapshots.incrementAndGet(); - PlayerActionUtil.notifyAll("Snapshot unchanged (" + snapshotTs + ") x" + identical, NotificationType.BAZAARDATA); - if (identical == STALE_WARNING_THRESHOLD) { - PlayerActionUtil.notifyAll("WARNING: " + identical + " identical snapshots in a row. Server might be lagging or BASE_INTERVAL_MS too short.", NotificationType.BAZAARDATA); - } - scheduleNextFromSnapshot(snapshotTs); - } + handleSnapshotResult(reply, snapshotTs); + scheduleNextFromSnapshot(snapshotTs); }); } - private static void scheduleNextFromSnapshot(long snapshotTs) { - long now = System.currentTimeMillis(); - long target = snapshotTs + BASE_INTERVAL_MS + POST_OFFSET_MS; - - long delay; - if (now >= target) { - // Past the ideal fetch time; server hasn’t advanced snapshot yet. Don’t spam: back off. - delay = STALE_BACKOFF_MS; - } else { - var typicalDelay = target - now; - delay = Math.max(typicalDelay, STALE_BACKOFF_MS); - } - scheduleFetch(delay); + private static void handleFetchFailure(String messagePrefix, boolean includeFailureCount) { + int failureCount = includeFailureCount ? consecutiveFailures.incrementAndGet() : consecutiveFailures.get(); + String message = includeFailureCount ? messagePrefix + " (failures=" + failureCount + ")" : messagePrefix; + PlayerActionUtil.notifyAll(message, NotificationType.BAZAARDATA); + scheduleFailureRetry(); } - private static long extractLastUpdated(SkyBlockBazaarReply reply) { - try { - return ((AccessorSkyBlockBazaarReply) reply).getLastUpdated(); - } catch (Exception e) { - Util.notifyError("Failed to access lastUpdated (mixin+reflection failed)", e); - return -1; - - } + private static void scheduleFailureRetry() { + scheduleFetch(BazaarDataSettings.FAILURE_RETRY_MS); } - - /** - * Get the number of orders at an exact price for a product & price type. - * @return OptionalInt empty if reply / product / priceType invalid or not found. - */ - public static OptionalInt getOrderCountOptional(String productId, TransactionType transactionType, double price) { - SkyBlockBazaarReply reply = currentReply; - - if (transactionType == null) { - return OptionalInt.empty(); - } - - PriceType priceType = transactionType.getPriceType(); - - if (reply == null || productId == null || priceType == null) { - return OptionalInt.empty(); + private static void handleSnapshotResult(SkyBlockBazaarReply reply, long snapshotTs) { + if (snapshotTs != lastSnapshotTs) { + handleNewSnapshot(reply, snapshotTs); + return; } - try { - SkyBlockBazaarReply.Product product = reply.getProduct(productId); + handleUnchangedSnapshot(snapshotTs); + } - if (product == null) { - return OptionalInt.empty(); - } + private static void handleNewSnapshot(SkyBlockBazaarReply reply, long snapshotTs) { + long previousSnapshotTs = lastSnapshotTs; + lastSnapshotTs = snapshotTs; + currentReply = reply; + consecutiveIdenticalSnapshots.set(0); - List list = switch (priceType) { - case INSTABUY -> product.getBuySummary(); - case INSTASELL -> product.getSellSummary(); - }; + EVENT_BUS.post(new BazaarDataUpdateEvent(reply)); - if (list == null) { - return OptionalInt.empty(); - } + if (previousSnapshotTs != -1) { + PlayerActionUtil.notifyAll( + "New snapshot " + snapshotTs + " (Δ " + (snapshotTs - previousSnapshotTs) + " ms). Scheduling next predicted fetch.", + NotificationType.BAZAARDATA + ); + return; + } - for (SkyBlockBazaarReply.Product.Summary s : list) { - if (Double.compare(s.getPricePerUnit(), price) == 0) { - return OptionalInt.of((int) s.getOrders()); - } - } + PlayerActionUtil.notifyAll("First snapshot " + snapshotTs + " received.", NotificationType.BAZAARDATA); + } - return OptionalInt.of(0); - } catch (Exception e) { - Util.notifyError("Error in getOrderCountOptional for productID=" + productId, e); + private static void handleUnchangedSnapshot(long snapshotTs) { + int identicalSnapshotCount = consecutiveIdenticalSnapshots.incrementAndGet(); + PlayerActionUtil.notifyAll("Snapshot unchanged (" + snapshotTs + ") x" + identicalSnapshotCount, NotificationType.BAZAARDATA); - return OptionalInt.empty(); + if (identicalSnapshotCount == BazaarDataSettings.STALE_WARNING_THRESHOLD) { + PlayerActionUtil.notifyAll( + "WARNING: " + identicalSnapshotCount + " identical snapshots in a row. Server might be lagging or BASE_INTERVAL_MS too short.", + NotificationType.BAZAARDATA + ); } } - /** - * Find the top bazaar price for a product based on the given {@link TransactionType}. - * The returned {@link OptionalDouble} is empty if the reply, product ID, or derived {@link PriceType} - * is {@code null}, if the product cannot be found, or if an exception occurs while resolving the price. - * If the selected summary list exists but is empty, this method returns {@code OptionalDouble.of(0.0)}. - * - * @param productId the bazaar product ID to look up - * @param transactionType the transaction type whose {@link PriceType} controls which summary is queried - * @return an {@link OptionalDouble} containing the resolved price per unit, or empty if unavailable - */ - public static OptionalDouble findItemPriceOptional(String productId, TransactionType transactionType) { - SkyBlockBazaarReply reply = currentReply; + private static void scheduleNextFromSnapshot(long snapshotTs) { + long nowMs = System.currentTimeMillis(); + long expectedNextFetchAtMs = snapshotTs + BazaarDataSettings.BASE_INTERVAL_MS + BazaarDataSettings.POST_OFFSET_MS; - if (transactionType == null) { - return OptionalDouble.empty(); + long nextDelayMs; + if (nowMs >= expectedNextFetchAtMs) { + // Past the ideal fetch time; server has not advanced snapshot yet, so back off. + nextDelayMs = BazaarDataSettings.STALE_BACKOFF_MS; + } else { + long idealDelayMs = expectedNextFetchAtMs - nowMs; + nextDelayMs = Math.max(idealDelayMs, BazaarDataSettings.STALE_BACKOFF_MS); } - PriceType priceType = transactionType.getPriceType(); - - if (reply == null || productId == null || priceType == null) { - return OptionalDouble.empty(); //TODO maybe throw error here instead. Needs testing to make sure it doesn't happen too frequently or at times where it is expected behavior - } + scheduleFetch(nextDelayMs); + } + private static long extractLastUpdated(SkyBlockBazaarReply reply) { try { - SkyBlockBazaarReply.Product product = reply.getProduct(productId); - - if (product == null) { - return OptionalDouble.empty(); - } - - return switch (priceType) { - case INSTABUY -> { - List buySummary = product.getBuySummary(); - - if (buySummary == null || buySummary.isEmpty()) { - yield OptionalDouble.of(0.0); - } - - yield OptionalDouble.of(buySummary.getFirst().getPricePerUnit()); - } - case INSTASELL -> { - List sellSummary = product.getSellSummary(); - - if (sellSummary == null || sellSummary.isEmpty()) { - yield OptionalDouble.of(0.0); - } - - yield OptionalDouble.of(sellSummary.getFirst().getPricePerUnit()); - } - }; + return ((AccessorSkyBlockBazaarReply) reply).getLastUpdated(); } catch (Exception e) { - Util.notifyError("Error in findItemPriceOptional for productID=" + productId, e); - - return OptionalDouble.empty(); + Util.notifyError("Failed to access lastUpdated (mixin+reflection failed)", e); + return -1; } } - public static Optional findProductIdOptional(String naturalName) { - if (naturalName == null || naturalName.isBlank()) { - return Optional.empty(); - } - - ensureConversionsLoaded(); - - return Optional.ofNullable(nameToProductIdCache.get(naturalName.toLowerCase(Locale.ROOT))); - } /** * Cached conversion load. Thread-safe (single pass). */ - private static void ensureConversionsLoaded() { + protected static void ensureConversionsLoaded() { if (conversionsLoaded) { return; } + // Double-checked guard avoids repeated JSON parsing on the hot path. synchronized (BazaarDataManager.class) { if (conversionsLoaded) { return; @@ -301,24 +214,4 @@ private static void ensureConversionsLoaded() { } } } - - public static Optional getCurrentSnapshotAge() { - long ts = lastSnapshotTs; - - if (ts <= 0) { - return Optional.empty(); - } - - return Optional.of(Duration.ofMillis(System.currentTimeMillis() - ts)); - } - - public static Optional getTimeSinceLastFetchAttempt() { - long f = lastFetchWallClock; - - if (f <= 0) { - return Optional.empty(); - } - - return Optional.of(Duration.ofMillis(System.currentTimeMillis() - f)); - } } \ No newline at end of file diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataSettings.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataSettings.java new file mode 100644 index 00000000..a58bad46 --- /dev/null +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataSettings.java @@ -0,0 +1,9 @@ +package com.github.mkram17.bazaarutils.utils.bazaar.data; + +public class BazaarDataSettings { + static final long BASE_INTERVAL_MS = 20_000; + static final long POST_OFFSET_MS = 500; + static final long STALE_BACKOFF_MS = 750; + static final long FAILURE_RETRY_MS = 500; + static final int STALE_WARNING_THRESHOLD = 5; +} diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java new file mode 100644 index 00000000..3192e47d --- /dev/null +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java @@ -0,0 +1,111 @@ +package com.github.mkram17.bazaarutils.utils.bazaar.data; + +import com.github.mkram17.bazaarutils.utils.Util; +import com.github.mkram17.bazaarutils.utils.bazaar.market.order.OrderType; +import com.github.mkram17.bazaarutils.utils.bazaar.market.order.PriceType; +import net.hypixel.api.reply.skyblock.SkyBlockBazaarReply; + +import java.util.*; + +public class BazaarDataUtil { + /** + * Get the number of orders at an exact price for a product & price type. + * @return OptionalInt empty if reply / product / priceType invalid or not found. + */ + public static OptionalInt getOrderCountOptional(String productId, OrderType orderType, double price) { + SkyBlockBazaarReply reply = BazaarDataManager.getCurrentReply(); + + PriceType priceType = orderType.asPriceType(); + + if (reply == null || productId == null || priceType == null) { + return OptionalInt.empty(); + } + + try { + SkyBlockBazaarReply.Product product = reply.getProduct(productId); + + if (product == null) { + return OptionalInt.empty(); + } + + List list = switch (priceType) { + case INSTABUY -> product.getBuySummary(); + case INSTASELL -> product.getSellSummary(); + }; + + if (list == null) { + return OptionalInt.empty(); + } + + for (SkyBlockBazaarReply.Product.Summary s : list) { + if (Double.compare(s.getPricePerUnit(), price) == 0) { + return OptionalInt.of((int) s.getOrders()); + } + } + + return OptionalInt.of(0); + } catch (Exception e) { + Util.notifyError("Error in getOrderCountOptional for productId=" + productId, e); + + return OptionalInt.empty(); + } + } + + /** + * Empty can mean: reply/product/priceType invalid or not found; exception while finding price + * BUY (top of buySummary aka people's sell orders). SELL (top of sellSummary, aka people's buy orders). + * @return OptionalDouble price found. + */ + public static OptionalDouble findItemPriceOptional(String productId, OrderType orderType) { + SkyBlockBazaarReply reply = BazaarDataManager.getCurrentReply(); + + PriceType priceType = orderType.asPriceType(); + + if (reply == null || productId == null || priceType == null) { + return OptionalDouble.empty(); //TODO maybe throw error here instead. Needs testing to make sure it doesn't happen too frequently or at times where it is expected behavior + } + + try { + SkyBlockBazaarReply.Product product = reply.getProduct(productId); + + if (product == null) { + return OptionalDouble.empty(); + } + + return switch (priceType) { + case INSTABUY -> { + List buySummary = product.getBuySummary(); + + if (buySummary == null || buySummary.isEmpty()) { + yield OptionalDouble.of(0.0); + } + + yield OptionalDouble.of(buySummary.getFirst().getPricePerUnit()); + } + case INSTASELL -> { + List sellSummary = product.getSellSummary(); + + if (sellSummary == null || sellSummary.isEmpty()) { + yield OptionalDouble.of(0.0); + } + + yield OptionalDouble.of(sellSummary.getFirst().getPricePerUnit()); + } + }; + } catch (Exception e) { + Util.notifyError("Error in findItemPriceOptional for productId=" + productId, e); + + return OptionalDouble.empty(); + } + } + + public static Optional findProductIdOptional(String naturalName) { + if (naturalName == null || naturalName.isBlank()) { + return Optional.empty(); + } + + BazaarDataManager.ensureConversionsLoaded(); + + return Optional.ofNullable(BazaarDataManager.getNameToProductIdCache().get(naturalName.toLowerCase(Locale.ROOT))); + } +} diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/gui/BazaarScreenHandler.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/gui/BazaarScreenHandler.java index bbd5c1ed..f90b16db 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/gui/BazaarScreenHandler.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/gui/BazaarScreenHandler.java @@ -1,6 +1,6 @@ package com.github.mkram17.bazaarutils.utils.bazaar.gui; -import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataManager; +import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataUtil; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.OrderInfo; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.TransactionType; import com.github.mkram17.bazaarutils.utils.minecraft.ItemInfo; @@ -70,7 +70,7 @@ public static Optional getDisplayItemName(@NotNull ScreenContext context public static Optional getDisplayProductId(@NotNull ScreenContext context) { return getDisplayItemName(context) - .flatMap(BazaarDataManager::findProductIdOptional); + .flatMap(BazaarDataUtil::findProductIdOptional); } public static Optional getDisplayOrderInfo(@NotNull ScreenContext context) { diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderInfo.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderInfo.java index 48895aaf..97a4d851 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderInfo.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderInfo.java @@ -1,12 +1,11 @@ package com.github.mkram17.bazaarutils.utils.bazaar.market.order; import com.github.mkram17.bazaarutils.data.UserOrdersStorage; -import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataManager; +import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataUtil; import com.github.mkram17.bazaarutils.utils.minecraft.ItemInfo; import com.github.mkram17.bazaarutils.utils.Util; import com.github.mkram17.bazaarutils.utils.bazaar.market.price.PriceInfo; import com.github.mkram17.bazaarutils.utils.bazaar.market.price.PricingPosition; -import com.teamresourceful.resourcefulconfig.api.annotations.ConfigEntry; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -49,7 +48,7 @@ public class OrderInfo extends PriceInfo { * Creates a container that tracks market data for a specific Bazaar product. * * @param name display name of the item - * @param side whether this is a buy or sell transaction + * @param side whether this is a buy or sell transaction * @param status status of the order * @param volume quantity of the order * @param pricePerItem current price per unit for the order @@ -64,7 +63,7 @@ public OrderInfo(@Nullable String name, @Nullable TransactionType.Side side, @Nu this.volume = volume; this.tolerance = calculateTolerance(); - BazaarDataManager.findProductIdOptional(name).ifPresent(productId -> this.productID = productId); + BazaarDataUtil.findProductIdOptional(name).ifPresent(productId -> this.productID = productId); validateProductId(productID); findPricingPosition().ifPresent(pricingPosition -> this.pricingPosition = pricingPosition); } @@ -98,7 +97,7 @@ private double calculateTolerance() { * @return {@code true} when a product ID exists for the name */ public static boolean isValidName(String itemName) { - return itemName != null && BazaarDataManager.findProductIdOptional(itemName).isPresent(); + return itemName != null && BazaarDataUtil.findProductIdOptional(itemName).isPresent(); } /** @@ -113,7 +112,7 @@ public Optional findPricingPosition() { double marketPrice = getMarketPrice(transactionType.getSide()); - var orderCountOpt = BazaarDataManager.getOrderCountOptional(productID, getTransactionType(), getPricePerItem()); + var orderCountOpt = BazaarDataUtil.getOrderCountOptional(productID, getTransactionType(), getPricePerItem()); if (orderCountOpt.isEmpty()) { return Optional.empty(); diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/minecraft/PlayerSlots.java b/src/main/java/com/github/mkram17/bazaarutils/utils/minecraft/PlayerSlots.java index 408d8638..59a69183 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/minecraft/PlayerSlots.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/minecraft/PlayerSlots.java @@ -1,6 +1,6 @@ package com.github.mkram17.bazaarutils.utils.minecraft; -import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataManager; +import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataUtil; import com.github.mkram17.bazaarutils.utils.minecraft.gui.ScreenManager; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.ingame.GenericContainerScreen; @@ -27,7 +27,7 @@ public static Optional findScreenSlotByProductId(String productId) { ItemStack stack = mainStacks.get(i); boolean matches = !stack.isEmpty() - && BazaarDataManager.findProductIdOptional(stack.getName().getString()) + && BazaarDataUtil.findProductIdOptional(stack.getName().getString()) .map(id -> id.equals(productId)) .orElse(false); From f04f89816be7cb4712ac4dbbf0f4d21b045ccff3 Mon Sep 17 00:00:00 2001 From: mkram17 <1maxkramer@gmail.com> Date: Thu, 12 Mar 2026 21:26:56 -0400 Subject: [PATCH 03/15] custom wrappers for api classes --- .../utils/bazaar/data/BazaarDataManager.java | 1 - .../utils/bazaar/data/CustomBazaarReply.java | 41 +++++++++ .../utils/bazaar/data/ProductData.java | 85 +++++++++++++++++++ .../utils/bazaar/data/ProductSummary.java | 36 ++++++++ .../utils/bazaar/data/UserProductSummary.java | 13 +++ 5 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/CustomBazaarReply.java create mode 100644 src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductData.java create mode 100644 src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductSummary.java create mode 100644 src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/UserProductSummary.java diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java index 77340935..8cff95be 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java @@ -85,7 +85,6 @@ private static void fetchOnce() { } consecutiveFailures.set(0); - updateFetchedProductIds(reply); long snapshotTs = extractLastUpdated(reply); if (snapshotTs <= 0) { diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/CustomBazaarReply.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/CustomBazaarReply.java new file mode 100644 index 00000000..5e2c44fa --- /dev/null +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/CustomBazaarReply.java @@ -0,0 +1,41 @@ +package com.github.mkram17.bazaarutils.utils.bazaar.data; + +import com.github.mkram17.bazaarutils.mixin.AccessorSkyBlockBazaarReply; +import lombok.Getter; +import net.hypixel.api.reply.AbstractReply; +import net.hypixel.api.reply.skyblock.SkyBlockBazaarReply; + +import java.util.Map; +import java.util.stream.Collectors; + +public class CustomBazaarReply extends AbstractReply { + @Getter + private final long lastUpdated; + @Getter + private final Map products; + + public CustomBazaarReply(long lastUpdated, Map products) { + this.lastUpdated = lastUpdated; + this.products = products; + } + + public static CustomBazaarReply fromSkyBlockReply(SkyBlockBazaarReply reply) { + AccessorSkyBlockBazaarReply accessor = (AccessorSkyBlockBazaarReply) reply; + + Map sourceProducts = reply.getProducts(); + + Map converted = (sourceProducts == null || sourceProducts.isEmpty()) + ? Map.of() + : sourceProducts.entrySet().stream() + .collect(Collectors.toUnmodifiableMap( + Map.Entry::getKey, + e -> ProductData.fromAPIProduct(e.getKey(), e.getValue()) + )); + + return new CustomBazaarReply(accessor.getLastUpdated(), converted); + } + + public ProductData getProduct(String productId) { + return products.get(productId); + } +} diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductData.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductData.java new file mode 100644 index 00000000..7db6c062 --- /dev/null +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductData.java @@ -0,0 +1,85 @@ +package com.github.mkram17.bazaarutils.utils.bazaar.data; + +import com.github.mkram17.bazaarutils.utils.bazaar.market.order.PriceType; +import lombok.Getter; +import net.hypixel.api.reply.skyblock.SkyBlockBazaarReply; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class ProductData { + @Getter + private final String productId; + private final List sellSummary; + private final List buySummary; + + public ProductData(String productId, List sellSummary, List buySummary) { + this.productId = productId; + this.sellSummary = new ArrayList<>(sellSummary); + this.buySummary = new ArrayList<>(buySummary); + } + + public static ProductData fromAPIProduct(String productId, SkyBlockBazaarReply.Product apiProduct) { + List sell = new ArrayList<>(); + List buy = new ArrayList<>(); + + if (apiProduct.getSellSummary() != null) { + for (SkyBlockBazaarReply.Product.Summary s : apiProduct.getSellSummary()) { + sell.add(ProductSummary.fromAPIProductSummary(s, PriceType.INSTASELL)); + } + } + + if (apiProduct.getBuySummary() != null) { + for (SkyBlockBazaarReply.Product.Summary s : apiProduct.getBuySummary()) { + buy.add(ProductSummary.fromAPIProductSummary(s, PriceType.INSTABUY)); + } + } + + return new ProductData(productId, sell, buy); + } + + public List getSellSummary() { + return Collections.unmodifiableList(sellSummary); + } + + public List getBuySummary() { + return Collections.unmodifiableList(buySummary); + } + + public void insertInstaSellSummary(ProductSummary productSummary) { + int index = 0; + for (ProductSummary existing : sellSummary) { + if (productSummary.getPricePerUnit() < existing.getPricePerUnit()) { + break; + } + index++; + } + sellSummary.add(index, productSummary); + } + + public void insertInstaBuySummary(ProductSummary productSummary) { + int index = 0; + for (ProductSummary existing : buySummary) { + if (productSummary.getPricePerUnit() > existing.getPricePerUnit()) { + break; + } + index++; + } + buySummary.add(index, productSummary); + } + + public List getUserInstaSellSummaries() { + return sellSummary.stream() + .filter(UserProductSummary.class::isInstance) + .map(UserProductSummary.class::cast) + .toList(); + } + + public List getUserInstaBuySummaries() { + return buySummary.stream() + .filter(UserProductSummary.class::isInstance) + .map(UserProductSummary.class::cast) + .toList(); + } +} diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductSummary.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductSummary.java new file mode 100644 index 00000000..77b3a5be --- /dev/null +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductSummary.java @@ -0,0 +1,36 @@ +package com.github.mkram17.bazaarutils.utils.bazaar.data; + +import com.github.mkram17.bazaarutils.utils.bazaar.market.order.PriceType; +import lombok.Getter; +import net.hypixel.api.reply.skyblock.SkyBlockBazaarReply; + +public class ProductSummary { + @Getter + private final PriceType priceType; + @Getter + private final double pricePerUnit; + @Getter + private final long amount; + @Getter + private final long orders; + + public ProductSummary(PriceType priceType, double pricePerUnit, long amount, long orders) { + this.priceType = priceType; + this.pricePerUnit = pricePerUnit; + this.amount = amount; + this.orders = orders; + } + + public static ProductSummary fromAPIProductSummary(SkyBlockBazaarReply.Product.Summary apiSummary, PriceType priceType) { + return new ProductSummary( + priceType, + apiSummary.getPricePerUnit(), + apiSummary.getAmount(), + apiSummary.getOrders() + ); + } + + public boolean hasOrders() { + return orders >0 && pricePerUnit >0; + } +} diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/UserProductSummary.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/UserProductSummary.java new file mode 100644 index 00000000..11987788 --- /dev/null +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/UserProductSummary.java @@ -0,0 +1,13 @@ +package com.github.mkram17.bazaarutils.utils.bazaar.data; + +import com.github.mkram17.bazaarutils.utils.bazaar.market.order.Order; +import com.github.mkram17.bazaarutils.utils.bazaar.market.order.PriceType; + +public class UserProductSummary extends ProductSummary{ + private Order userOrder; + + public UserProductSummary(Order userOrder, PriceType priceType, double pricePerUnit, long amount, long orders) { + super(priceType, pricePerUnit, amount, orders); + this.userOrder = userOrder; + } +} From 06ba0f17f35f3418a284184538b7885962ba0853 Mon Sep 17 00:00:00 2001 From: mkram17 <1maxkramer@gmail.com> Date: Thu, 12 Mar 2026 21:35:44 -0400 Subject: [PATCH 04/15] improve conversion --- .../utils/bazaar/data/CustomBazaarReply.java | 14 ++++++++----- .../utils/bazaar/data/ProductData.java | 20 +++++++++++++------ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/CustomBazaarReply.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/CustomBazaarReply.java index 5e2c44fa..2ac46809 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/CustomBazaarReply.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/CustomBazaarReply.java @@ -23,16 +23,20 @@ public static CustomBazaarReply fromSkyBlockReply(SkyBlockBazaarReply reply) { AccessorSkyBlockBazaarReply accessor = (AccessorSkyBlockBazaarReply) reply; Map sourceProducts = reply.getProducts(); + Map converted = convertAPIProducts(sourceProducts); - Map converted = (sourceProducts == null || sourceProducts.isEmpty()) - ? Map.of() - : sourceProducts.entrySet().stream() + return new CustomBazaarReply(accessor.getLastUpdated(), converted); + } + + public static Map convertAPIProducts(Map apiProducts) { + if (apiProducts == null || apiProducts.isEmpty()) { + return Map.of(); + } + return apiProducts.entrySet().stream() .collect(Collectors.toUnmodifiableMap( Map.Entry::getKey, e -> ProductData.fromAPIProduct(e.getKey(), e.getValue()) )); - - return new CustomBazaarReply(accessor.getLastUpdated(), converted); } public ProductData getProduct(String productId) { diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductData.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductData.java index 7db6c062..ff506816 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductData.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductData.java @@ -7,6 +7,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; public class ProductData { @Getter @@ -25,20 +26,27 @@ public static ProductData fromAPIProduct(String productId, SkyBlockBazaarReply.P List buy = new ArrayList<>(); if (apiProduct.getSellSummary() != null) { - for (SkyBlockBazaarReply.Product.Summary s : apiProduct.getSellSummary()) { - sell.add(ProductSummary.fromAPIProductSummary(s, PriceType.INSTASELL)); - } + var convertedSellSummaries = convertAPIProductSummaries(apiProduct.getSellSummary(), PriceType.INSTASELL); + sell.addAll(convertedSellSummaries); } if (apiProduct.getBuySummary() != null) { - for (SkyBlockBazaarReply.Product.Summary s : apiProduct.getBuySummary()) { - buy.add(ProductSummary.fromAPIProductSummary(s, PriceType.INSTABUY)); - } + var convertedBuySummaries = convertAPIProductSummaries(apiProduct.getSellSummary(), PriceType.INSTABUY); + buy.addAll(convertedBuySummaries); } return new ProductData(productId, sell, buy); } + public static List convertAPIProductSummaries(List apiSummaries, PriceType priceType) { + if (apiSummaries == null || apiSummaries.isEmpty()) { + return List.of(); + } + return apiSummaries.stream() + .map(s -> ProductSummary.fromAPIProductSummary(s, priceType)) + .toList(); + } + public List getSellSummary() { return Collections.unmodifiableList(sellSummary); } From e6221e5f7e543395ad8a6084174069a9e022d748 Mon Sep 17 00:00:00 2001 From: mkram17 <1maxkramer@gmail.com> Date: Thu, 12 Mar 2026 21:44:13 -0400 Subject: [PATCH 05/15] use CustomBazaarReply instead of SkyblockBazaarReply --- .../events/BazaarDataUpdateEvent.java | 30 ++++++------------- .../utils/bazaar/data/BazaarDataManager.java | 26 ++++++++-------- .../utils/bazaar/data/BazaarDataUtil.java | 27 +++++++++-------- .../utils/bazaar/data/ProductData.java | 3 +- 4 files changed, 38 insertions(+), 48 deletions(-) diff --git a/src/main/java/com/github/mkram17/bazaarutils/events/BazaarDataUpdateEvent.java b/src/main/java/com/github/mkram17/bazaarutils/events/BazaarDataUpdateEvent.java index f407a555..cb92cc6f 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/events/BazaarDataUpdateEvent.java +++ b/src/main/java/com/github/mkram17/bazaarutils/events/BazaarDataUpdateEvent.java @@ -1,40 +1,28 @@ package com.github.mkram17.bazaarutils.events; -import lombok.AllArgsConstructor; +import com.github.mkram17.bazaarutils.utils.bazaar.data.CustomBazaarReply; import lombok.Getter; import meteordevelopment.orbit.ICancellable; -import net.hypixel.api.reply.skyblock.SkyBlockBazaarReply; /** * Event fired when bazaar data is updated from the Hypixel API. *

* This event is triggered whenever fresh bazaar market data is retrieved from the Hypixel API. - * It provides access to the complete bazaar reply containing all current market prices, volumes, - * and other bazaar statistics. + * It provides access to the converted custom bazaar reply containing all current market prices, + * volumes, and other bazaar statistics. *

- * - *

Usage Example:

- *
- * {@code
- * @EventHandler
- * public void onBazaarDataUpdate(BazaarDataUpdateEvent event) {
- *     SkyBlockBazaarReply reply = event.getBazaarReply();
- *     // Update local cache with new market data
- *     updatePriceCache(reply);
- * }
- * }
- * 
- * - * @see SkyBlockBazaarReply */ -@AllArgsConstructor public class BazaarDataUpdateEvent implements ICancellable { /** - * The bazaar data reply from the Hypixel API containing current market information. + * The converted bazaar data reply containing current market information. */ @Getter - private SkyBlockBazaarReply bazaarReply; + private final CustomBazaarReply bazaarReply; + + public BazaarDataUpdateEvent(CustomBazaarReply bazaarReply) { + this.bazaarReply = bazaarReply; + } @Override public void setCancelled(boolean cancelled) { diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java index 8cff95be..9ecd7813 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java @@ -8,14 +8,12 @@ import com.github.mkram17.bazaarutils.utils.ResourceManager; import com.github.mkram17.bazaarutils.utils.Util; import com.github.mkram17.bazaarutils.utils.annotations.autoregistration.RunOnInit; -import com.github.mkram17.bazaarutils.mixin.AccessorSkyBlockBazaarReply; import lombok.Getter; import lombok.Setter; import net.hypixel.api.reply.skyblock.SkyBlockBazaarReply; import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Locale; import java.util.Map; import java.util.concurrent.ScheduledFuture; @@ -27,7 +25,7 @@ public final class BazaarDataManager { @Getter - private static volatile SkyBlockBazaarReply currentReply; + private static volatile CustomBazaarReply currentReply; @Getter private static volatile long lastSnapshotTs = -1; private static volatile long lastFetchWallClock = -1; @@ -70,6 +68,7 @@ private static void fetchOnceSafely() { } private static void fetchOnce() { + lastFetchWallClock = System.currentTimeMillis(); APIUtils.API.getSkyBlockBazaar().whenComplete((reply, throwable) -> { if (throwable != null) { handleFetchFailure( @@ -79,20 +78,21 @@ private static void fetchOnce() { return; } - if (reply == null || !reply.isSuccess()) { - handleFetchFailure("Null/unsuccessful reply. Retry in " + BazaarDataSettings.FAILURE_RETRY_MS + "ms", true); + CustomBazaarReply customReply = convertReply(reply); + if (customReply == null || !customReply.isSuccess()) { + handleFetchFailure("Reply conversion failed. Retry in " + BazaarDataSettings.FAILURE_RETRY_MS + "ms", true); return; } consecutiveFailures.set(0); - long snapshotTs = extractLastUpdated(reply); + long snapshotTs = customReply.getLastUpdated(); if (snapshotTs <= 0) { handleFetchFailure("Invalid lastUpdated <= 0. Retry in " + BazaarDataSettings.FAILURE_RETRY_MS + "ms", false); return; } - handleSnapshotResult(reply, snapshotTs); + handleSnapshotResult(customReply, snapshotTs); scheduleNextFromSnapshot(snapshotTs); }); } @@ -108,7 +108,7 @@ private static void scheduleFailureRetry() { scheduleFetch(BazaarDataSettings.FAILURE_RETRY_MS); } - private static void handleSnapshotResult(SkyBlockBazaarReply reply, long snapshotTs) { + private static void handleSnapshotResult(CustomBazaarReply reply, long snapshotTs) { if (snapshotTs != lastSnapshotTs) { handleNewSnapshot(reply, snapshotTs); return; @@ -117,7 +117,7 @@ private static void handleSnapshotResult(SkyBlockBazaarReply reply, long snapsho handleUnchangedSnapshot(snapshotTs); } - private static void handleNewSnapshot(SkyBlockBazaarReply reply, long snapshotTs) { + private static void handleNewSnapshot(CustomBazaarReply reply, long snapshotTs) { long previousSnapshotTs = lastSnapshotTs; lastSnapshotTs = snapshotTs; currentReply = reply; @@ -164,12 +164,12 @@ private static void scheduleNextFromSnapshot(long snapshotTs) { scheduleFetch(nextDelayMs); } - private static long extractLastUpdated(SkyBlockBazaarReply reply) { + private static CustomBazaarReply convertReply(SkyBlockBazaarReply reply) { try { - return ((AccessorSkyBlockBazaarReply) reply).getLastUpdated(); + return CustomBazaarReply.fromSkyBlockReply(reply); } catch (Exception e) { - Util.notifyError("Failed to access lastUpdated (mixin+reflection failed)", e); - return -1; + Util.notifyError("Failed to convert SkyBlockBazaarReply", e); + return null; } } diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java index 3192e47d..d7b8f6c7 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java @@ -3,9 +3,12 @@ import com.github.mkram17.bazaarutils.utils.Util; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.OrderType; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.PriceType; -import net.hypixel.api.reply.skyblock.SkyBlockBazaarReply; -import java.util.*; +import java.util.List; +import java.util.Locale; +import java.util.Optional; +import java.util.OptionalDouble; +import java.util.OptionalInt; public class BazaarDataUtil { /** @@ -13,7 +16,7 @@ public class BazaarDataUtil { * @return OptionalInt empty if reply / product / priceType invalid or not found. */ public static OptionalInt getOrderCountOptional(String productId, OrderType orderType, double price) { - SkyBlockBazaarReply reply = BazaarDataManager.getCurrentReply(); + CustomBazaarReply reply = BazaarDataManager.getCurrentReply(); PriceType priceType = orderType.asPriceType(); @@ -22,13 +25,13 @@ public static OptionalInt getOrderCountOptional(String productId, OrderType orde } try { - SkyBlockBazaarReply.Product product = reply.getProduct(productId); + ProductData product = reply.getProduct(productId); if (product == null) { return OptionalInt.empty(); } - List list = switch (priceType) { + List list = switch (priceType) { case INSTABUY -> product.getBuySummary(); case INSTASELL -> product.getSellSummary(); }; @@ -37,9 +40,9 @@ public static OptionalInt getOrderCountOptional(String productId, OrderType orde return OptionalInt.empty(); } - for (SkyBlockBazaarReply.Product.Summary s : list) { - if (Double.compare(s.getPricePerUnit(), price) == 0) { - return OptionalInt.of((int) s.getOrders()); + for (ProductSummary summary : list) { + if (Double.compare(summary.getPricePerUnit(), price) == 0) { + return OptionalInt.of((int) summary.getOrders()); } } @@ -57,7 +60,7 @@ public static OptionalInt getOrderCountOptional(String productId, OrderType orde * @return OptionalDouble price found. */ public static OptionalDouble findItemPriceOptional(String productId, OrderType orderType) { - SkyBlockBazaarReply reply = BazaarDataManager.getCurrentReply(); + CustomBazaarReply reply = BazaarDataManager.getCurrentReply(); PriceType priceType = orderType.asPriceType(); @@ -66,7 +69,7 @@ public static OptionalDouble findItemPriceOptional(String productId, OrderType o } try { - SkyBlockBazaarReply.Product product = reply.getProduct(productId); + ProductData product = reply.getProduct(productId); if (product == null) { return OptionalDouble.empty(); @@ -74,7 +77,7 @@ public static OptionalDouble findItemPriceOptional(String productId, OrderType o return switch (priceType) { case INSTABUY -> { - List buySummary = product.getBuySummary(); + List buySummary = product.getBuySummary(); if (buySummary == null || buySummary.isEmpty()) { yield OptionalDouble.of(0.0); @@ -83,7 +86,7 @@ public static OptionalDouble findItemPriceOptional(String productId, OrderType o yield OptionalDouble.of(buySummary.getFirst().getPricePerUnit()); } case INSTASELL -> { - List sellSummary = product.getSellSummary(); + List sellSummary = product.getSellSummary(); if (sellSummary == null || sellSummary.isEmpty()) { yield OptionalDouble.of(0.0); diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductData.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductData.java index ff506816..ffae818f 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductData.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductData.java @@ -7,7 +7,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.Map; public class ProductData { @Getter @@ -31,7 +30,7 @@ public static ProductData fromAPIProduct(String productId, SkyBlockBazaarReply.P } if (apiProduct.getBuySummary() != null) { - var convertedBuySummaries = convertAPIProductSummaries(apiProduct.getSellSummary(), PriceType.INSTABUY); + var convertedBuySummaries = convertAPIProductSummaries(apiProduct.getBuySummary(), PriceType.INSTABUY); buy.addAll(convertedBuySummaries); } From d569b3b69c9d76690a60fe8127112ff9f06c0b73 Mon Sep 17 00:00:00 2001 From: mkram17 <1maxkramer@gmail.com> Date: Thu, 12 Mar 2026 22:01:35 -0400 Subject: [PATCH 06/15] Add BazaarDataUtil.isValidProductId --- .../utils/bazaar/data/BazaarDataUtil.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java index d7b8f6c7..9c9d17b9 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java @@ -102,6 +102,24 @@ public static OptionalDouble findItemPriceOptional(String productId, OrderType o } } + /** + * Checks whether the provided string is a known bazaar product ID. + * Uses in-memory data only (current reply + conversion cache). + */ + public static boolean isValidProductId(String productId) { + if (productId == null || productId.isBlank()) { + return false; + } + + CustomBazaarReply reply = BazaarDataManager.getCurrentReply(); + if (reply != null && reply.getProduct(productId) != null) { + return true; + } + + BazaarDataManager.ensureConversionsLoaded(); + return BazaarDataManager.getNameToProductIdCache().containsValue(productId); + } + public static Optional findProductIdOptional(String naturalName) { if (naturalName == null || naturalName.isBlank()) { return Optional.empty(); From 5f3671ddc7d433b804eab0dfde146b27a0cc32fb Mon Sep 17 00:00:00 2001 From: mkram17 <1maxkramer@gmail.com> Date: Fri, 13 Mar 2026 17:14:33 -0400 Subject: [PATCH 07/15] move BazaarDataManager.ensureConversionsLoaded to ResourceManager --- .../bazaarutils/utils/ResourceManager.java | 53 +++++++++++++++++-- .../utils/bazaar/data/BazaarDataManager.java | 53 ------------------- .../utils/bazaar/data/BazaarDataUtil.java | 9 ++-- 3 files changed, 55 insertions(+), 60 deletions(-) diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/ResourceManager.java b/src/main/java/com/github/mkram17/bazaarutils/utils/ResourceManager.java index 0668ce70..2c79021c 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/ResourceManager.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/ResourceManager.java @@ -4,10 +4,13 @@ import com.github.mkram17.bazaarutils.config.BUConfig; import com.github.mkram17.bazaarutils.config.hidden.MetadataConfig; import com.github.mkram17.bazaarutils.config.util.ConfigUtil; +import com.github.mkram17.bazaarutils.misc.NotificationType; import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataManager; import com.github.mkram17.bazaarutils.utils.annotations.autoregistration.RunOnInit; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import lombok.Getter; +import lombok.Setter; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.MinecraftClient; @@ -22,8 +25,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; -import java.util.Optional; -import java.util.Scanner; +import java.util.*; import java.util.concurrent.CompletableFuture; //TODO move config to config/bazaarutils directory and rename to "config". See how REI does this. @@ -33,6 +35,11 @@ public class ResourceManager { private static final Path LOCAL_RESOURCES_PATH = MOD_CONFIG_DIR.resolve("bazaar-resources.json"); private static final Identifier BUNDLED_RESOURCES_ID = Identifier.of(BazaarUtils.MOD_ID, "bazaar-resources.json"); private static final String GITHUB_API_URL = "https://api.github.com/repos/mkram17/Skyblock-Bazaar-Conversions/contents/conversionupdating/bazaar-conversions.json?ref=main"; + /* Cached conversions: lowercase name -> productId */ + @Getter + private static volatile Map nameToProductIdCache = Map.of(); + @Setter + private static volatile boolean conversionsLoaded = false; public static void initialize() { @@ -118,7 +125,7 @@ private static void downloadLatestResources(String downloadUrl, String latestSha MetadataConfig.RESOURCES_SHA = latestSha; ConfigUtil.scheduleConfigSave(); - BazaarDataManager.setConversionsLoaded(false); + ResourceManager.setConversionsLoaded(false); PlayerActionUtil.notifyAll("Successfully updated Bazaar resources!"); } catch (Exception e) { Util.notifyError("Failed to download resources", e); @@ -158,4 +165,44 @@ public static void onClientStart(){ ResourceManager.initialize(); }); } + + /** + * Cached conversion load. Thread-safe (single pass). + */ + public static void ensureConversionsLoaded() { + if (conversionsLoaded) { + return; + } + + // Double-checked guard avoids repeated JSON parsing on the hot path. + synchronized (BazaarDataManager.class) { + if (conversionsLoaded) { + return; + } + + try { + Map mutable = new HashMap<>(); + + var resources = getResourceJson(); + var conversions = resources.getAsJsonObject(); + + for (String key : conversions.keySet()) { + String value = conversions.get(key).getAsString(); + if (value != null) { + mutable.put(value.toLowerCase(Locale.ROOT), key); + } + } + + nameToProductIdCache = Collections.unmodifiableMap(mutable); + conversionsLoaded = true; + + PlayerActionUtil.notifyAll("Loaded bazaarConversions cache: " + nameToProductIdCache.size() + " entries.", NotificationType.BAZAARDATA); + } catch (Exception e) { + Util.notifyError("Failed loading bazaarConversions cache", e); + + nameToProductIdCache = Map.of(); + conversionsLoaded = true; + } + } + } } \ No newline at end of file diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java index 9ecd7813..5efc452e 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java @@ -5,17 +5,11 @@ import com.github.mkram17.bazaarutils.events.BazaarDataUpdateEvent; import com.github.mkram17.bazaarutils.misc.NotificationType; import com.github.mkram17.bazaarutils.utils.PlayerActionUtil; -import com.github.mkram17.bazaarutils.utils.ResourceManager; import com.github.mkram17.bazaarutils.utils.Util; import com.github.mkram17.bazaarutils.utils.annotations.autoregistration.RunOnInit; import lombok.Getter; -import lombok.Setter; import net.hypixel.api.reply.skyblock.SkyBlockBazaarReply; -import java.util.Collections; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -37,12 +31,6 @@ public final class BazaarDataManager { private static final AtomicInteger consecutiveIdenticalSnapshots = new AtomicInteger(0); private static final AtomicInteger consecutiveFailures = new AtomicInteger(0); - /* Cached conversions: lowercase name -> productId */ - @Getter - private static volatile Map nameToProductIdCache = Map.of(); - @Setter - private static volatile boolean conversionsLoaded = false; - @RunOnInit public static void init() { scheduleFetch(0); @@ -172,45 +160,4 @@ private static CustomBazaarReply convertReply(SkyBlockBazaarReply reply) { return null; } } - - - /** - * Cached conversion load. Thread-safe (single pass). - */ - protected static void ensureConversionsLoaded() { - if (conversionsLoaded) { - return; - } - - // Double-checked guard avoids repeated JSON parsing on the hot path. - synchronized (BazaarDataManager.class) { - if (conversionsLoaded) { - return; - } - - try { - Map mutable = new HashMap<>(); - - var resources = ResourceManager.getResourceJson(); - var conversions = resources.getAsJsonObject(); - - for (String key : conversions.keySet()) { - String value = conversions.get(key).getAsString(); - if (value != null) { - mutable.put(value.toLowerCase(Locale.ROOT), key); - } - } - - nameToProductIdCache = Collections.unmodifiableMap(mutable); - conversionsLoaded = true; - - PlayerActionUtil.notifyAll("Loaded bazaarConversions cache: " + nameToProductIdCache.size() + " entries.", NotificationType.BAZAARDATA); - } catch (Exception e) { - Util.notifyError("Failed loading bazaarConversions cache", e); - - nameToProductIdCache = Map.of(); - conversionsLoaded = true; - } - } - } } \ No newline at end of file diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java index 9c9d17b9..1495f361 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java @@ -1,5 +1,6 @@ package com.github.mkram17.bazaarutils.utils.bazaar.data; +import com.github.mkram17.bazaarutils.utils.ResourceManager; import com.github.mkram17.bazaarutils.utils.Util; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.OrderType; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.PriceType; @@ -116,8 +117,8 @@ public static boolean isValidProductId(String productId) { return true; } - BazaarDataManager.ensureConversionsLoaded(); - return BazaarDataManager.getNameToProductIdCache().containsValue(productId); + ResourceManager.ensureConversionsLoaded(); + return ResourceManager.getNameToProductIdCache().containsValue(productId); } public static Optional findProductIdOptional(String naturalName) { @@ -125,8 +126,8 @@ public static Optional findProductIdOptional(String naturalName) { return Optional.empty(); } - BazaarDataManager.ensureConversionsLoaded(); + ResourceManager.ensureConversionsLoaded(); - return Optional.ofNullable(BazaarDataManager.getNameToProductIdCache().get(naturalName.toLowerCase(Locale.ROOT))); + return Optional.ofNullable(ResourceManager.getNameToProductIdCache().get(naturalName.toLowerCase(Locale.ROOT))); } } From 1e2e4187566ce863a2eba54f682ac1d2c6eb4787 Mon Sep 17 00:00:00 2001 From: mkram17 <1maxkramer@gmail.com> Date: Fri, 13 Mar 2026 18:06:57 -0400 Subject: [PATCH 08/15] bunch of refactors, and turned users orders in the reply into UserProductOrder with ref to Order --- .../events/BazaarDataUpdateEvent.java | 2 +- .../utils/bazaar/data/BazaarDataManager.java | 41 ++++----- .../utils/bazaar/data/BazaarDataSettings.java | 10 +- .../utils/bazaar/data/BazaarDataUtil.java | 15 +-- .../utils/bazaar/data/CustomBazaarReply.java | 45 --------- .../utils/bazaar/data/ProductData.java | 92 ------------------- .../utils/bazaar/data/ProductSummary.java | 36 -------- .../utils/bazaar/data/UserProductSummary.java | 13 --- .../data/wrappers/APIConversionUtil.java | 87 ++++++++++++++++++ .../data/wrappers/CustomBazaarReply.java | 35 +++++++ .../bazaar/data/wrappers/ProductData.java | 64 +++++++++++++ .../bazaar/data/wrappers/ProductOrder.java | 30 ++++++ .../data/wrappers/UserProductOrder.java | 17 ++++ 13 files changed, 266 insertions(+), 221 deletions(-) delete mode 100644 src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/CustomBazaarReply.java delete mode 100644 src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductData.java delete mode 100644 src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductSummary.java delete mode 100644 src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/UserProductSummary.java create mode 100644 src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/APIConversionUtil.java create mode 100644 src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/CustomBazaarReply.java create mode 100644 src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductData.java create mode 100644 src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductOrder.java create mode 100644 src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/UserProductOrder.java diff --git a/src/main/java/com/github/mkram17/bazaarutils/events/BazaarDataUpdateEvent.java b/src/main/java/com/github/mkram17/bazaarutils/events/BazaarDataUpdateEvent.java index cb92cc6f..483487c1 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/events/BazaarDataUpdateEvent.java +++ b/src/main/java/com/github/mkram17/bazaarutils/events/BazaarDataUpdateEvent.java @@ -1,6 +1,6 @@ package com.github.mkram17.bazaarutils.events; -import com.github.mkram17.bazaarutils.utils.bazaar.data.CustomBazaarReply; +import com.github.mkram17.bazaarutils.utils.bazaar.data.wrappers.CustomBazaarReply; import lombok.Getter; import meteordevelopment.orbit.ICancellable; diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java index 5efc452e..08c1838b 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java @@ -7,8 +7,9 @@ import com.github.mkram17.bazaarutils.utils.PlayerActionUtil; import com.github.mkram17.bazaarutils.utils.Util; import com.github.mkram17.bazaarutils.utils.annotations.autoregistration.RunOnInit; +import com.github.mkram17.bazaarutils.utils.bazaar.data.wrappers.APIConversionUtil; +import com.github.mkram17.bazaarutils.utils.bazaar.data.wrappers.CustomBazaarReply; import lombok.Getter; -import net.hypixel.api.reply.skyblock.SkyBlockBazaarReply; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; @@ -20,21 +21,24 @@ public final class BazaarDataManager { @Getter private static volatile CustomBazaarReply currentReply; + @Getter private static volatile long lastSnapshotTs = -1; - private static volatile long lastFetchWallClock = -1; + + private static final BazaarDataSettings BAZAAR_DATA_SETTINGS = new BazaarDataSettings(); private static volatile ScheduledFuture scheduledTask; // Serializes schedule/cancel so only one pending fetch task exists at a time. private static final Object SCHED_LOCK = new Object(); private static final AtomicInteger consecutiveIdenticalSnapshots = new AtomicInteger(0); + private static final AtomicInteger consecutiveFailures = new AtomicInteger(0); @RunOnInit public static void init() { scheduleFetch(0); - PlayerActionUtil.notifyAll("BazaarDataManager initialized (simple fixed-interval poller). Base=" + BazaarDataSettings.BASE_INTERVAL_MS + "ms", NotificationType.BAZAARDATA); + PlayerActionUtil.notifyAll("BazaarDataManager initialized (simple fixed-interval poller). Base=" + BAZAAR_DATA_SETTINGS.BASE_INTERVAL_MS + "ms", NotificationType.BAZAARDATA); } private static void scheduleFetch(long delayMs) { @@ -56,19 +60,18 @@ private static void fetchOnceSafely() { } private static void fetchOnce() { - lastFetchWallClock = System.currentTimeMillis(); APIUtils.API.getSkyBlockBazaar().whenComplete((reply, throwable) -> { if (throwable != null) { handleFetchFailure( - "Fetch failure (" + throwable.getClass().getSimpleName() + "). Retry in " + BazaarDataSettings.FAILURE_RETRY_MS + "ms", + "Fetch failure (" + throwable.getClass().getSimpleName() + "). Retry in " + BAZAAR_DATA_SETTINGS.FAILURE_RETRY_MS + "ms", true ); return; } - CustomBazaarReply customReply = convertReply(reply); - if (customReply == null || !customReply.isSuccess()) { - handleFetchFailure("Reply conversion failed. Retry in " + BazaarDataSettings.FAILURE_RETRY_MS + "ms", true); + CustomBazaarReply customReply = APIConversionUtil.fromSkyBlockReply(reply); + if (!customReply.isSuccess()) { + handleFetchFailure("Reply conversion failed. Retry in " + BAZAAR_DATA_SETTINGS.FAILURE_RETRY_MS + "ms", true); return; } @@ -76,10 +79,11 @@ private static void fetchOnce() { long snapshotTs = customReply.getLastUpdated(); if (snapshotTs <= 0) { - handleFetchFailure("Invalid lastUpdated <= 0. Retry in " + BazaarDataSettings.FAILURE_RETRY_MS + "ms", false); + handleFetchFailure("Invalid lastUpdated <= 0. Retry in " + BAZAAR_DATA_SETTINGS.FAILURE_RETRY_MS + "ms", false); return; } + customReply.replaceUserProductOrders(); handleSnapshotResult(customReply, snapshotTs); scheduleNextFromSnapshot(snapshotTs); }); @@ -93,7 +97,7 @@ private static void handleFetchFailure(String messagePrefix, boolean includeFail } private static void scheduleFailureRetry() { - scheduleFetch(BazaarDataSettings.FAILURE_RETRY_MS); + scheduleFetch(BAZAAR_DATA_SETTINGS.FAILURE_RETRY_MS); } private static void handleSnapshotResult(CustomBazaarReply reply, long snapshotTs) { @@ -128,7 +132,7 @@ private static void handleUnchangedSnapshot(long snapshotTs) { int identicalSnapshotCount = consecutiveIdenticalSnapshots.incrementAndGet(); PlayerActionUtil.notifyAll("Snapshot unchanged (" + snapshotTs + ") x" + identicalSnapshotCount, NotificationType.BAZAARDATA); - if (identicalSnapshotCount == BazaarDataSettings.STALE_WARNING_THRESHOLD) { + if (identicalSnapshotCount == BAZAAR_DATA_SETTINGS.STALE_WARNING_THRESHOLD) { PlayerActionUtil.notifyAll( "WARNING: " + identicalSnapshotCount + " identical snapshots in a row. Server might be lagging or BASE_INTERVAL_MS too short.", NotificationType.BAZAARDATA @@ -138,26 +142,17 @@ private static void handleUnchangedSnapshot(long snapshotTs) { private static void scheduleNextFromSnapshot(long snapshotTs) { long nowMs = System.currentTimeMillis(); - long expectedNextFetchAtMs = snapshotTs + BazaarDataSettings.BASE_INTERVAL_MS + BazaarDataSettings.POST_OFFSET_MS; + long expectedNextFetchAtMs = snapshotTs + BAZAAR_DATA_SETTINGS.BASE_INTERVAL_MS + BAZAAR_DATA_SETTINGS.POST_OFFSET_MS; long nextDelayMs; if (nowMs >= expectedNextFetchAtMs) { // Past the ideal fetch time; server has not advanced snapshot yet, so back off. - nextDelayMs = BazaarDataSettings.STALE_BACKOFF_MS; + nextDelayMs = BAZAAR_DATA_SETTINGS.STALE_BACKOFF_MS; } else { long idealDelayMs = expectedNextFetchAtMs - nowMs; - nextDelayMs = Math.max(idealDelayMs, BazaarDataSettings.STALE_BACKOFF_MS); + nextDelayMs = Math.max(idealDelayMs, BAZAAR_DATA_SETTINGS.STALE_BACKOFF_MS); } scheduleFetch(nextDelayMs); } - - private static CustomBazaarReply convertReply(SkyBlockBazaarReply reply) { - try { - return CustomBazaarReply.fromSkyBlockReply(reply); - } catch (Exception e) { - Util.notifyError("Failed to convert SkyBlockBazaarReply", e); - return null; - } - } } \ No newline at end of file diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataSettings.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataSettings.java index a58bad46..27984a30 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataSettings.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataSettings.java @@ -1,9 +1,9 @@ package com.github.mkram17.bazaarutils.utils.bazaar.data; public class BazaarDataSettings { - static final long BASE_INTERVAL_MS = 20_000; - static final long POST_OFFSET_MS = 500; - static final long STALE_BACKOFF_MS = 750; - static final long FAILURE_RETRY_MS = 500; - static final int STALE_WARNING_THRESHOLD = 5; + public final long BASE_INTERVAL_MS = 20_000; + public final long POST_OFFSET_MS = 500; + public final long STALE_BACKOFF_MS = 750; + public final long FAILURE_RETRY_MS = 500; + public final int STALE_WARNING_THRESHOLD = 5; } diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java index 1495f361..fc0a9fd6 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java @@ -2,6 +2,9 @@ import com.github.mkram17.bazaarutils.utils.ResourceManager; import com.github.mkram17.bazaarutils.utils.Util; +import com.github.mkram17.bazaarutils.utils.bazaar.data.wrappers.CustomBazaarReply; +import com.github.mkram17.bazaarutils.utils.bazaar.data.wrappers.ProductData; +import com.github.mkram17.bazaarutils.utils.bazaar.data.wrappers.ProductOrder; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.OrderType; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.PriceType; @@ -32,16 +35,16 @@ public static OptionalInt getOrderCountOptional(String productId, OrderType orde return OptionalInt.empty(); } - List list = switch (priceType) { - case INSTABUY -> product.getBuySummary(); - case INSTASELL -> product.getSellSummary(); + List list = switch (priceType) { + case INSTABUY -> product.getSellOrders(); + case INSTASELL -> product.getBuyOrders(); }; if (list == null) { return OptionalInt.empty(); } - for (ProductSummary summary : list) { + for (ProductOrder summary : list) { if (Double.compare(summary.getPricePerUnit(), price) == 0) { return OptionalInt.of((int) summary.getOrders()); } @@ -78,7 +81,7 @@ public static OptionalDouble findItemPriceOptional(String productId, OrderType o return switch (priceType) { case INSTABUY -> { - List buySummary = product.getBuySummary(); + List buySummary = product.getSellOrders(); if (buySummary == null || buySummary.isEmpty()) { yield OptionalDouble.of(0.0); @@ -87,7 +90,7 @@ public static OptionalDouble findItemPriceOptional(String productId, OrderType o yield OptionalDouble.of(buySummary.getFirst().getPricePerUnit()); } case INSTASELL -> { - List sellSummary = product.getSellSummary(); + List sellSummary = product.getBuyOrders(); if (sellSummary == null || sellSummary.isEmpty()) { yield OptionalDouble.of(0.0); diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/CustomBazaarReply.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/CustomBazaarReply.java deleted file mode 100644 index 2ac46809..00000000 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/CustomBazaarReply.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.github.mkram17.bazaarutils.utils.bazaar.data; - -import com.github.mkram17.bazaarutils.mixin.AccessorSkyBlockBazaarReply; -import lombok.Getter; -import net.hypixel.api.reply.AbstractReply; -import net.hypixel.api.reply.skyblock.SkyBlockBazaarReply; - -import java.util.Map; -import java.util.stream.Collectors; - -public class CustomBazaarReply extends AbstractReply { - @Getter - private final long lastUpdated; - @Getter - private final Map products; - - public CustomBazaarReply(long lastUpdated, Map products) { - this.lastUpdated = lastUpdated; - this.products = products; - } - - public static CustomBazaarReply fromSkyBlockReply(SkyBlockBazaarReply reply) { - AccessorSkyBlockBazaarReply accessor = (AccessorSkyBlockBazaarReply) reply; - - Map sourceProducts = reply.getProducts(); - Map converted = convertAPIProducts(sourceProducts); - - return new CustomBazaarReply(accessor.getLastUpdated(), converted); - } - - public static Map convertAPIProducts(Map apiProducts) { - if (apiProducts == null || apiProducts.isEmpty()) { - return Map.of(); - } - return apiProducts.entrySet().stream() - .collect(Collectors.toUnmodifiableMap( - Map.Entry::getKey, - e -> ProductData.fromAPIProduct(e.getKey(), e.getValue()) - )); - } - - public ProductData getProduct(String productId) { - return products.get(productId); - } -} diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductData.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductData.java deleted file mode 100644 index ffae818f..00000000 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductData.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.github.mkram17.bazaarutils.utils.bazaar.data; - -import com.github.mkram17.bazaarutils.utils.bazaar.market.order.PriceType; -import lombok.Getter; -import net.hypixel.api.reply.skyblock.SkyBlockBazaarReply; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class ProductData { - @Getter - private final String productId; - private final List sellSummary; - private final List buySummary; - - public ProductData(String productId, List sellSummary, List buySummary) { - this.productId = productId; - this.sellSummary = new ArrayList<>(sellSummary); - this.buySummary = new ArrayList<>(buySummary); - } - - public static ProductData fromAPIProduct(String productId, SkyBlockBazaarReply.Product apiProduct) { - List sell = new ArrayList<>(); - List buy = new ArrayList<>(); - - if (apiProduct.getSellSummary() != null) { - var convertedSellSummaries = convertAPIProductSummaries(apiProduct.getSellSummary(), PriceType.INSTASELL); - sell.addAll(convertedSellSummaries); - } - - if (apiProduct.getBuySummary() != null) { - var convertedBuySummaries = convertAPIProductSummaries(apiProduct.getBuySummary(), PriceType.INSTABUY); - buy.addAll(convertedBuySummaries); - } - - return new ProductData(productId, sell, buy); - } - - public static List convertAPIProductSummaries(List apiSummaries, PriceType priceType) { - if (apiSummaries == null || apiSummaries.isEmpty()) { - return List.of(); - } - return apiSummaries.stream() - .map(s -> ProductSummary.fromAPIProductSummary(s, priceType)) - .toList(); - } - - public List getSellSummary() { - return Collections.unmodifiableList(sellSummary); - } - - public List getBuySummary() { - return Collections.unmodifiableList(buySummary); - } - - public void insertInstaSellSummary(ProductSummary productSummary) { - int index = 0; - for (ProductSummary existing : sellSummary) { - if (productSummary.getPricePerUnit() < existing.getPricePerUnit()) { - break; - } - index++; - } - sellSummary.add(index, productSummary); - } - - public void insertInstaBuySummary(ProductSummary productSummary) { - int index = 0; - for (ProductSummary existing : buySummary) { - if (productSummary.getPricePerUnit() > existing.getPricePerUnit()) { - break; - } - index++; - } - buySummary.add(index, productSummary); - } - - public List getUserInstaSellSummaries() { - return sellSummary.stream() - .filter(UserProductSummary.class::isInstance) - .map(UserProductSummary.class::cast) - .toList(); - } - - public List getUserInstaBuySummaries() { - return buySummary.stream() - .filter(UserProductSummary.class::isInstance) - .map(UserProductSummary.class::cast) - .toList(); - } -} diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductSummary.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductSummary.java deleted file mode 100644 index 77b3a5be..00000000 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/ProductSummary.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.github.mkram17.bazaarutils.utils.bazaar.data; - -import com.github.mkram17.bazaarutils.utils.bazaar.market.order.PriceType; -import lombok.Getter; -import net.hypixel.api.reply.skyblock.SkyBlockBazaarReply; - -public class ProductSummary { - @Getter - private final PriceType priceType; - @Getter - private final double pricePerUnit; - @Getter - private final long amount; - @Getter - private final long orders; - - public ProductSummary(PriceType priceType, double pricePerUnit, long amount, long orders) { - this.priceType = priceType; - this.pricePerUnit = pricePerUnit; - this.amount = amount; - this.orders = orders; - } - - public static ProductSummary fromAPIProductSummary(SkyBlockBazaarReply.Product.Summary apiSummary, PriceType priceType) { - return new ProductSummary( - priceType, - apiSummary.getPricePerUnit(), - apiSummary.getAmount(), - apiSummary.getOrders() - ); - } - - public boolean hasOrders() { - return orders >0 && pricePerUnit >0; - } -} diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/UserProductSummary.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/UserProductSummary.java deleted file mode 100644 index 11987788..00000000 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/UserProductSummary.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.github.mkram17.bazaarutils.utils.bazaar.data; - -import com.github.mkram17.bazaarutils.utils.bazaar.market.order.Order; -import com.github.mkram17.bazaarutils.utils.bazaar.market.order.PriceType; - -public class UserProductSummary extends ProductSummary{ - private Order userOrder; - - public UserProductSummary(Order userOrder, PriceType priceType, double pricePerUnit, long amount, long orders) { - super(priceType, pricePerUnit, amount, orders); - this.userOrder = userOrder; - } -} diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/APIConversionUtil.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/APIConversionUtil.java new file mode 100644 index 00000000..e9db43db --- /dev/null +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/APIConversionUtil.java @@ -0,0 +1,87 @@ +package com.github.mkram17.bazaarutils.utils.bazaar.data.wrappers; + +import com.github.mkram17.bazaarutils.data.UserOrdersStorage; +import com.github.mkram17.bazaarutils.mixin.AccessorSkyBlockBazaarReply; +import com.github.mkram17.bazaarutils.utils.bazaar.market.order.Order; +import com.github.mkram17.bazaarutils.utils.bazaar.market.order.PriceType; +import net.hypixel.api.reply.skyblock.SkyBlockBazaarReply; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public final class APIConversionUtil { + + public static List replaceUserOrdersInList(Order order, List orders) { + List replaced = new ArrayList<>(); + + for (int i = 0; i < orders.size(); i++) { + ProductOrder productOrder = orders.get(i); + if (!productOrder.equalsOrder(order)) { + continue; + } + + UserProductOrder replacement = new UserProductOrder(order, productOrder); + orders.set(i, replacement); + replaced.add(replacement); + } + + return replaced; + } + + public static CustomBazaarReply fromSkyBlockReply(SkyBlockBazaarReply reply) { + AccessorSkyBlockBazaarReply accessor = (AccessorSkyBlockBazaarReply) reply; + + Map sourceProducts = reply.getProducts(); + Map converted = convertAPIProducts(sourceProducts); + + return new CustomBazaarReply(accessor.getLastUpdated(), converted); + } + + public static Map convertAPIProducts(Map apiProducts) { + if (apiProducts == null || apiProducts.isEmpty()) { + return Map.of(); + } + return apiProducts.entrySet().stream() + .collect(Collectors.toUnmodifiableMap( + Map.Entry::getKey, + e -> fromAPIProduct(e.getKey(), e.getValue()) + )); + } + + public static ProductData fromAPIProduct(String productId, SkyBlockBazaarReply.Product apiProduct) { + List sell = new ArrayList<>(); + List buy = new ArrayList<>(); + + if (apiProduct.getSellSummary() != null) { + var convertedSellSummaries = convertAPIProductSummaries(apiProduct.getSellSummary(), PriceType.INSTASELL); + sell.addAll(convertedSellSummaries); + } + + if (apiProduct.getBuySummary() != null) { + var convertedBuySummaries = convertAPIProductSummaries(apiProduct.getBuySummary(), PriceType.INSTABUY); + buy.addAll(convertedBuySummaries); + } + + return new ProductData(productId, sell, buy); + } + + public static List convertAPIProductSummaries(List apiSummaries, PriceType priceType) { + if (apiSummaries == null || apiSummaries.isEmpty()) { + return List.of(); + } + return apiSummaries.stream() + .map(s -> fromAPIProductSummary(s, priceType)) + .toList(); + } + + public static ProductOrder fromAPIProductSummary(SkyBlockBazaarReply.Product.Summary apiSummary, PriceType priceType) { + return new ProductOrder( + priceType, + apiSummary.getPricePerUnit(), + apiSummary.getAmount(), + apiSummary.getOrders() + ); + } +} diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/CustomBazaarReply.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/CustomBazaarReply.java new file mode 100644 index 00000000..b2ebb666 --- /dev/null +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/CustomBazaarReply.java @@ -0,0 +1,35 @@ +package com.github.mkram17.bazaarutils.utils.bazaar.data.wrappers; + +import com.github.mkram17.bazaarutils.data.UserOrdersStorage; +import com.github.mkram17.bazaarutils.utils.bazaar.market.order.Order; +import lombok.Getter; +import net.hypixel.api.reply.AbstractReply; + +import java.util.List; +import java.util.Map; + +public class CustomBazaarReply extends AbstractReply { + @Getter + private final long lastUpdated; + @Getter + private final Map products; + + public CustomBazaarReply(long lastUpdated, Map products) { + this.lastUpdated = lastUpdated; + this.products = products; + } + + public ProductData getProduct(String productId) { + return products.get(productId); + } + + public void replaceUserProductOrders() { + List userOrders = UserOrdersStorage.INSTANCE.get(); + + for (Order order : userOrders) { + ProductData product = getProduct(order.getProductID()); + APIConversionUtil.replaceUserOrdersInList(order, product.getSellOrders()); + APIConversionUtil.replaceUserOrdersInList(order, product.getBuyOrders()); + } + } +} diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductData.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductData.java new file mode 100644 index 00000000..b21cf7e6 --- /dev/null +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductData.java @@ -0,0 +1,64 @@ +package com.github.mkram17.bazaarutils.utils.bazaar.data.wrappers; + +import lombok.Getter; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class ProductData { + @Getter + private final String productId; + private final List productBuyOrders; + private final List productSellOrders; + + public ProductData(String productId, List productBuyOrders, List productSellOrders) { + this.productId = productId; + this.productBuyOrders = new ArrayList<>(productBuyOrders); + this.productSellOrders = new ArrayList<>(productSellOrders); + } + + public List getBuyOrders() { + return productBuyOrders; + } + + public List getSellOrders() { + return productSellOrders; + } + + public void insertInstaSellSummary(ProductOrder productOrder) { + int index = 0; + for (ProductOrder existing : productBuyOrders) { + if (productOrder.getPricePerUnit() < existing.getPricePerUnit()) { + break; + } + index++; + } + productBuyOrders.add(index, productOrder); + } + + public void insertInstaBuySummary(ProductOrder productOrder) { + int index = 0; + for (ProductOrder existing : productSellOrders) { + if (productOrder.getPricePerUnit() > existing.getPricePerUnit()) { + break; + } + index++; + } + productSellOrders.add(index, productOrder); + } + + public List getUserInstaSellSummaries() { + return productBuyOrders.stream() + .filter(UserProductOrder.class::isInstance) + .map(UserProductOrder.class::cast) + .toList(); + } + + public List getUserInstaBuySummaries() { + return productSellOrders.stream() + .filter(UserProductOrder.class::isInstance) + .map(UserProductOrder.class::cast) + .toList(); + } +} diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductOrder.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductOrder.java new file mode 100644 index 00000000..6936e14a --- /dev/null +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductOrder.java @@ -0,0 +1,30 @@ +package com.github.mkram17.bazaarutils.utils.bazaar.data.wrappers; + +import com.github.mkram17.bazaarutils.utils.bazaar.market.order.*; +import lombok.Getter; + +public class ProductOrder { + @Getter + private final PriceType priceType; + @Getter + private final double pricePerUnit; + @Getter + private final long amount; + @Getter + private final long orders; + + public ProductOrder(PriceType priceType, double pricePerUnit, long amount, long orders) { + this.priceType = priceType; + this.pricePerUnit = pricePerUnit; + this.amount = amount; + this.orders = orders; + } + + public boolean hasOrders() { + return orders >0 && pricePerUnit >0; + } + + public boolean equalsOrder(Order order) { + return order.getOrderType().asPriceType() == priceType && order.getPricePerItem() == pricePerUnit && order.getVolume() == amount; + } +} diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/UserProductOrder.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/UserProductOrder.java new file mode 100644 index 00000000..9cd9ae01 --- /dev/null +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/UserProductOrder.java @@ -0,0 +1,17 @@ +package com.github.mkram17.bazaarutils.utils.bazaar.data.wrappers; + +import com.github.mkram17.bazaarutils.utils.bazaar.market.order.Order; +import com.github.mkram17.bazaarutils.utils.bazaar.market.order.PriceType; + +public class UserProductOrder extends ProductOrder { + private Order userOrder; + + public UserProductOrder(Order userOrder, PriceType priceType, double pricePerUnit, long amount, long orders) { + super(priceType, pricePerUnit, amount, orders); + this.userOrder = userOrder; + } + public UserProductOrder(Order userOrder, ProductOrder productOrder) { + super(productOrder.getPriceType(), productOrder.getPricePerUnit(), productOrder.getAmount(), productOrder.getOrders()); + this.userOrder = userOrder; + } +} From 93ac9b2734b099f6b4ab94554e900627a23683d1 Mon Sep 17 00:00:00 2001 From: mkram17 <1maxkramer@gmail.com> Date: Fri, 13 Mar 2026 18:39:43 -0400 Subject: [PATCH 09/15] fix reply success handling and refactor var names in ProductOrder --- .../utils/bazaar/data/BazaarDataManager.java | 12 +++---- .../utils/bazaar/data/BazaarDataUtil.java | 2 +- .../bazaar/data/wrappers/ProductData.java | 36 ------------------- .../bazaar/data/wrappers/ProductOrder.java | 14 ++++---- .../data/wrappers/UserProductOrder.java | 2 +- 5 files changed, 13 insertions(+), 53 deletions(-) diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java index 08c1838b..063276ce 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java @@ -61,7 +61,7 @@ private static void fetchOnceSafely() { private static void fetchOnce() { APIUtils.API.getSkyBlockBazaar().whenComplete((reply, throwable) -> { - if (throwable != null) { + if (throwable != null || !reply.isSuccess()) { handleFetchFailure( "Fetch failure (" + throwable.getClass().getSimpleName() + "). Retry in " + BAZAAR_DATA_SETTINGS.FAILURE_RETRY_MS + "ms", true @@ -70,12 +70,6 @@ private static void fetchOnce() { } CustomBazaarReply customReply = APIConversionUtil.fromSkyBlockReply(reply); - if (!customReply.isSuccess()) { - handleFetchFailure("Reply conversion failed. Retry in " + BAZAAR_DATA_SETTINGS.FAILURE_RETRY_MS + "ms", true); - return; - } - - consecutiveFailures.set(0); long snapshotTs = customReply.getLastUpdated(); if (snapshotTs <= 0) { @@ -83,6 +77,8 @@ private static void fetchOnce() { return; } + consecutiveFailures.set(0); + customReply.replaceUserProductOrders(); handleSnapshotResult(customReply, snapshotTs); scheduleNextFromSnapshot(snapshotTs); @@ -92,7 +88,7 @@ private static void fetchOnce() { private static void handleFetchFailure(String messagePrefix, boolean includeFailureCount) { int failureCount = includeFailureCount ? consecutiveFailures.incrementAndGet() : consecutiveFailures.get(); String message = includeFailureCount ? messagePrefix + " (failures=" + failureCount + ")" : messagePrefix; - PlayerActionUtil.notifyAll(message, NotificationType.BAZAARDATA); + Util.notifyError(message, new Throwable()); scheduleFailureRetry(); } diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java index fc0a9fd6..9256e1a6 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java @@ -46,7 +46,7 @@ public static OptionalInt getOrderCountOptional(String productId, OrderType orde for (ProductOrder summary : list) { if (Double.compare(summary.getPricePerUnit(), price) == 0) { - return OptionalInt.of((int) summary.getOrders()); + return OptionalInt.of((int) summary.getNumOrders()); } } diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductData.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductData.java index b21cf7e6..08951a1a 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductData.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductData.java @@ -25,40 +25,4 @@ public List getBuyOrders() { public List getSellOrders() { return productSellOrders; } - - public void insertInstaSellSummary(ProductOrder productOrder) { - int index = 0; - for (ProductOrder existing : productBuyOrders) { - if (productOrder.getPricePerUnit() < existing.getPricePerUnit()) { - break; - } - index++; - } - productBuyOrders.add(index, productOrder); - } - - public void insertInstaBuySummary(ProductOrder productOrder) { - int index = 0; - for (ProductOrder existing : productSellOrders) { - if (productOrder.getPricePerUnit() > existing.getPricePerUnit()) { - break; - } - index++; - } - productSellOrders.add(index, productOrder); - } - - public List getUserInstaSellSummaries() { - return productBuyOrders.stream() - .filter(UserProductOrder.class::isInstance) - .map(UserProductOrder.class::cast) - .toList(); - } - - public List getUserInstaBuySummaries() { - return productSellOrders.stream() - .filter(UserProductOrder.class::isInstance) - .map(UserProductOrder.class::cast) - .toList(); - } } diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductOrder.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductOrder.java index 6936e14a..e19cfc55 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductOrder.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductOrder.java @@ -9,22 +9,22 @@ public class ProductOrder { @Getter private final double pricePerUnit; @Getter - private final long amount; + private final long volume; @Getter - private final long orders; + private final long numOrders; - public ProductOrder(PriceType priceType, double pricePerUnit, long amount, long orders) { + public ProductOrder(PriceType priceType, double pricePerUnit, long volume, long numOrders) { this.priceType = priceType; this.pricePerUnit = pricePerUnit; - this.amount = amount; - this.orders = orders; + this.volume = volume; + this.numOrders = numOrders; } public boolean hasOrders() { - return orders >0 && pricePerUnit >0; + return numOrders >0 && pricePerUnit >0; } public boolean equalsOrder(Order order) { - return order.getOrderType().asPriceType() == priceType && order.getPricePerItem() == pricePerUnit && order.getVolume() == amount; + return order.getOrderType().asPriceType() == priceType && order.getPricePerItem() == pricePerUnit && order.getVolume() == volume; } } diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/UserProductOrder.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/UserProductOrder.java index 9cd9ae01..ab2f276e 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/UserProductOrder.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/UserProductOrder.java @@ -11,7 +11,7 @@ public UserProductOrder(Order userOrder, PriceType priceType, double pricePerUni this.userOrder = userOrder; } public UserProductOrder(Order userOrder, ProductOrder productOrder) { - super(productOrder.getPriceType(), productOrder.getPricePerUnit(), productOrder.getAmount(), productOrder.getOrders()); + super(productOrder.getPriceType(), productOrder.getPricePerUnit(), productOrder.getVolume(), productOrder.getNumOrders()); this.userOrder = userOrder; } } From 86a10b467d086e04cdc9aa99453b705d9f3a45fd Mon Sep 17 00:00:00 2001 From: mkram17 <1maxkramer@gmail.com> Date: Tue, 24 Mar 2026 21:03:35 -0400 Subject: [PATCH 10/15] rebase artifacts --- .../commands/DeveloperCommands.java | 3 +- .../gui/buttons/bookmarks/Bookmark.java | 3 +- .../bookmarks/ToggleBookmarkButton.java | 4 +- .../utils/bazaar/SignInputHelper.java | 7 +-- .../utils/bazaar/data/BazaarDataUtil.java | 48 ++++++++++++------- .../bazaar/data/wrappers/ProductOrder.java | 2 +- .../utils/bazaar/market/order/OrderUtil.java | 6 +-- 7 files changed, 43 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/github/mkram17/bazaarutils/commands/DeveloperCommands.java b/src/main/java/com/github/mkram17/bazaarutils/commands/DeveloperCommands.java index 39270757..13be12b9 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/commands/DeveloperCommands.java +++ b/src/main/java/com/github/mkram17/bazaarutils/commands/DeveloperCommands.java @@ -8,6 +8,7 @@ import com.github.mkram17.bazaarutils.utils.PlayerActionUtil; import com.github.mkram17.bazaarutils.utils.annotations.modules.Module; import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataManager; +import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataUtil; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.Order; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.TransactionType; import com.mojang.brigadier.arguments.IntegerArgumentType; @@ -152,7 +153,7 @@ private int convertNameToId(CommandContext context) { if (!isEnabled()) return 0; String name = StringArgumentType.getString(context, "item name").replaceAll("_", " "); - BazaarDataManager.findProductIdOptional(name).ifPresentOrElse( + BazaarDataUtil.findProductIdOptional(name).ifPresentOrElse( id -> PlayerActionUtil.notifyAll(name + ": " + id), () -> PlayerActionUtil.notifyAll("Could not find product ID for " + name) ); diff --git a/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/Bookmark.java b/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/Bookmark.java index 67832f09..1a12f771 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/Bookmark.java +++ b/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/Bookmark.java @@ -1,6 +1,5 @@ package com.github.mkram17.bazaarutils.features.gui.buttons.bookmarks; -import com.github.mkram17.bazaarutils.utils.bazaar.market.price.MarketPrices; import net.minecraft.item.ItemStack; -public record Bookmark(String name, ItemStack itemStack, MarketPrices marketPrices) {} \ No newline at end of file +public record Bookmark(String name, ItemStack itemStack, String productID) {} \ No newline at end of file diff --git a/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/ToggleBookmarkButton.java b/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/ToggleBookmarkButton.java index 7b3e2d5c..a01df5d6 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/ToggleBookmarkButton.java +++ b/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/ToggleBookmarkButton.java @@ -8,7 +8,6 @@ import com.github.mkram17.bazaarutils.utils.bazaar.gui.BazaarScreenHandler; import com.github.mkram17.bazaarutils.utils.bazaar.gui.BazaarScreens; import com.github.mkram17.bazaarutils.utils.minecraft.item.ItemButton; -import com.github.mkram17.bazaarutils.utils.bazaar.market.price.MarketPrices; import com.github.mkram17.bazaarutils.utils.minecraft.ItemInfo; import com.github.mkram17.bazaarutils.utils.minecraft.components.CustomDataComponents; import com.github.mkram17.bazaarutils.utils.minecraft.gui.ScreenManager; @@ -98,8 +97,7 @@ private void toggleBookmark(String name) { .flatMap(BazaarScreenHandler::getDisplayProductId) .orElse(null); - MarketPrices bookmarkMarketPrices = new MarketPrices(productId); - Bookmark newBookmark = new Bookmark(name, itemStack, bookmarkMarketPrices); + Bookmark newBookmark = new Bookmark(name, itemStack, productId); list.add(newBookmark); BookmarkUtil.currentBookmarkOpt = Optional.of(newBookmark); diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/SignInputHelper.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/SignInputHelper.java index 337c0cf2..75a9a7f4 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/SignInputHelper.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/SignInputHelper.java @@ -4,6 +4,7 @@ import com.github.mkram17.bazaarutils.events.ChestLoadedEvent; import com.github.mkram17.bazaarutils.utils.Util; import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataManager; +import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataUtil; import com.github.mkram17.bazaarutils.utils.bazaar.gui.BazaarScreenHandler; import com.github.mkram17.bazaarutils.utils.bazaar.gui.BazaarScreens; import com.github.mkram17.bazaarutils.utils.bazaar.gui.BazaarSlots; @@ -226,7 +227,7 @@ protected String getButtonItemStackSize(TransactionState state) { @Override protected ResolvedInput resolveInput(TransactionState state) { - OptionalDouble price = BazaarDataManager.findItemPriceOptional(state.productId(), getTransactionType()); + OptionalDouble price = BazaarDataUtil.findItemPriceOptional(state.productId(), getTransactionType()); if (price.isEmpty()) { Util.logMessage("Could not retrieve relevant item pricing for " + name + "'s resolved value."); @@ -278,7 +279,7 @@ protected int computeMaxValue(TransactionState state) { .filter(stack -> !stack.isEmpty()) .filter(stack -> Optional.ofNullable(stack.getCustomName()) .map(Text::getString) - .flatMap(BazaarDataManager::findProductIdOptional) + .flatMap(BazaarDataUtil::findProductIdOptional) .map(productId -> productId.equals(state.productId())) .orElse(false)) .mapToInt(ItemStack::getCount) @@ -348,7 +349,7 @@ protected String getButtonItemStackSize(TransactionState state) { @Override protected ResolvedInput resolveInput(TransactionState state) { - OptionalDouble price = BazaarDataManager.findItemPriceOptional(state.productId(), getTransactionType()); + OptionalDouble price = BazaarDataUtil.findItemPriceOptional(state.productId(), getTransactionType()); if (price.isEmpty()) { Util.logMessage("Could not retrieve relevant item pricing for " + name + "'s resolved value."); diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java index 9256e1a6..68ce3864 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java @@ -5,8 +5,9 @@ import com.github.mkram17.bazaarutils.utils.bazaar.data.wrappers.CustomBazaarReply; import com.github.mkram17.bazaarutils.utils.bazaar.data.wrappers.ProductData; import com.github.mkram17.bazaarutils.utils.bazaar.data.wrappers.ProductOrder; -import com.github.mkram17.bazaarutils.utils.bazaar.market.order.OrderType; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.PriceType; +import com.github.mkram17.bazaarutils.utils.bazaar.market.order.TransactionType; +import net.hypixel.api.reply.skyblock.SkyBlockBazaarReply; import java.util.List; import java.util.Locale; @@ -19,10 +20,14 @@ public class BazaarDataUtil { * Get the number of orders at an exact price for a product & price type. * @return OptionalInt empty if reply / product / priceType invalid or not found. */ - public static OptionalInt getOrderCountOptional(String productId, OrderType orderType, double price) { + public static OptionalInt getOrderCountOptional(String productId, TransactionType transactionType, double price) { CustomBazaarReply reply = BazaarDataManager.getCurrentReply(); - PriceType priceType = orderType.asPriceType(); + if (transactionType == null) { + return OptionalInt.empty(); + } + + PriceType priceType = transactionType.getPriceType(); if (reply == null || productId == null || priceType == null) { return OptionalInt.empty(); @@ -36,37 +41,45 @@ public static OptionalInt getOrderCountOptional(String productId, OrderType orde } List list = switch (priceType) { - case INSTABUY -> product.getSellOrders(); - case INSTASELL -> product.getBuyOrders(); + case INSTABUY -> product.getBuyOrders(); + case INSTASELL -> product.getSellOrders(); }; if (list == null) { return OptionalInt.empty(); } - for (ProductOrder summary : list) { - if (Double.compare(summary.getPricePerUnit(), price) == 0) { - return OptionalInt.of((int) summary.getNumOrders()); + for (ProductOrder s : list) { + if (Double.compare(s.getPricePerUnit(), price) == 0) { + return OptionalInt.of((int) s.getVolume()); } } return OptionalInt.of(0); } catch (Exception e) { - Util.notifyError("Error in getOrderCountOptional for productId=" + productId, e); + Util.notifyError("Error in getOrderCountOptional for productID=" + productId, e); return OptionalInt.empty(); } } /** - * Empty can mean: reply/product/priceType invalid or not found; exception while finding price - * BUY (top of buySummary aka people's sell orders). SELL (top of sellSummary, aka people's buy orders). - * @return OptionalDouble price found. + * Find the top bazaar price for a product based on the given {@link TransactionType}. + * The returned {@link OptionalDouble} is empty if the reply, product ID, or derived {@link PriceType} + * is {@code null}, if the product cannot be found, or if an exception occurs while resolving the price. + * If the selected summary list exists but is empty, this method returns {@code OptionalDouble.of(0.0)}. + * + * @param productId the bazaar product ID to look up + * @param transactionType the transaction type whose {@link PriceType} controls which summary is queried + * @return an {@link OptionalDouble} containing the resolved price per unit, or empty if unavailable */ - public static OptionalDouble findItemPriceOptional(String productId, OrderType orderType) { + public static OptionalDouble findItemPriceOptional(String productId, TransactionType transactionType) { CustomBazaarReply reply = BazaarDataManager.getCurrentReply(); + if (transactionType == null) { + return OptionalDouble.empty(); + } - PriceType priceType = orderType.asPriceType(); + PriceType priceType = transactionType.getPriceType(); if (reply == null || productId == null || priceType == null) { return OptionalDouble.empty(); //TODO maybe throw error here instead. Needs testing to make sure it doesn't happen too frequently or at times where it is expected behavior @@ -81,7 +94,7 @@ public static OptionalDouble findItemPriceOptional(String productId, OrderType o return switch (priceType) { case INSTABUY -> { - List buySummary = product.getSellOrders(); + List buySummary = product.getBuyOrders(); if (buySummary == null || buySummary.isEmpty()) { yield OptionalDouble.of(0.0); @@ -90,7 +103,7 @@ public static OptionalDouble findItemPriceOptional(String productId, OrderType o yield OptionalDouble.of(buySummary.getFirst().getPricePerUnit()); } case INSTASELL -> { - List sellSummary = product.getBuyOrders(); + List sellSummary = product.getSellOrders(); if (sellSummary == null || sellSummary.isEmpty()) { yield OptionalDouble.of(0.0); @@ -100,12 +113,13 @@ public static OptionalDouble findItemPriceOptional(String productId, OrderType o } }; } catch (Exception e) { - Util.notifyError("Error in findItemPriceOptional for productId=" + productId, e); + Util.notifyError("Error in findItemPriceOptional for productID=" + productId, e); return OptionalDouble.empty(); } } + /** * Checks whether the provided string is a known bazaar product ID. * Uses in-memory data only (current reply + conversion cache). diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductOrder.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductOrder.java index e19cfc55..614bb584 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductOrder.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductOrder.java @@ -25,6 +25,6 @@ public boolean hasOrders() { } public boolean equalsOrder(Order order) { - return order.getOrderType().asPriceType() == priceType && order.getPricePerItem() == pricePerUnit && order.getVolume() == volume; + return order.getTransactionType().getPriceType() == priceType && order.getPricePerItem() == pricePerUnit && order.getVolume() == volume; } } diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderUtil.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderUtil.java index 657c3fa1..b3a9efff 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderUtil.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderUtil.java @@ -5,7 +5,7 @@ import com.github.mkram17.bazaarutils.misc.NotificationType; import com.github.mkram17.bazaarutils.utils.PlayerActionUtil; import com.github.mkram17.bazaarutils.utils.Util; -import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataManager; +import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataUtil; import com.github.mkram17.bazaarutils.utils.bazaar.gui.BazaarScreens; import com.github.mkram17.bazaarutils.utils.bazaar.market.price.PricingPosition; import com.github.mkram17.bazaarutils.utils.minecraft.gui.ScreenManager; @@ -74,8 +74,8 @@ public static double getPriceForPosition(String productID, PricingPosition prici return -1; } - OptionalDouble marketSellPriceOpt = BazaarDataManager.findItemPriceOptional(productID, TransactionType.of(TransactionType.Side.SELL, TransactionType.Method.ORDER)); - OptionalDouble marketBuyPriceOpt = BazaarDataManager.findItemPriceOptional(productID, TransactionType.of(TransactionType.Side.BUY, TransactionType.Method.ORDER)); + OptionalDouble marketSellPriceOpt = BazaarDataUtil.findItemPriceOptional(productID, TransactionType.of(TransactionType.Side.SELL, TransactionType.Method.ORDER)); + OptionalDouble marketBuyPriceOpt = BazaarDataUtil.findItemPriceOptional(productID, TransactionType.of(TransactionType.Side.BUY, TransactionType.Method.ORDER)); if(marketBuyPriceOpt.isEmpty() || marketSellPriceOpt.isEmpty()) { Util.notifyError("Could not resolve market prices for " + productID + " when calculating price for position. Buy price present: " + marketBuyPriceOpt.isPresent() + " Sell price present: " + marketSellPriceOpt.isPresent(), new Exception("Price resolution error")); From 3f66b13bc17a5e6985686a0c05e159ae8601f900 Mon Sep 17 00:00:00 2001 From: mkram17 <1maxkramer@gmail.com> Date: Tue, 24 Mar 2026 21:05:53 -0400 Subject: [PATCH 11/15] refactor classes in data directory into utils --- .../mkram17/bazaarutils/commands/DeveloperCommands.java | 3 +-- .../bazaarutils/events/handler/BazaarChatEventHandler.java | 2 +- .../mkram17/bazaarutils/events/handler/ChatHandler.java | 2 +- .../features/gui/buttons/bookmarks/BookmarkUtil.java | 2 +- .../features/gui/overlays/BazaarLimitsVisualizer.java | 2 +- .../bazaarutils/features/notification/OutbidOrderHandler.java | 2 +- .../bazaarutils/{data/APIUtils.java => utils/APIUtil.java} | 4 ++-- .../mkram17/bazaarutils/utils/bazaar/SignInputHelper.java | 3 +-- .../bazaarutils/utils/bazaar/data/BazaarDataManager.java | 4 ++-- .../utils/bazaar/data/wrappers/APIConversionUtil.java | 1 - .../utils/bazaar/data/wrappers/CustomBazaarReply.java | 2 +- .../mkram17/bazaarutils/utils/bazaar/market/order/Order.java | 2 +- .../bazaarutils/utils/bazaar/market/order/OrderInfo.java | 2 +- .../bazaarutils/utils/bazaar/market/order/OrderUpdater.java | 2 +- .../bazaarutils/utils/bazaar/market/order/OrderUtil.java | 2 +- .../{data => utils/storage}/BazaarLimitsStorage.java | 3 +-- .../bazaarutils/{data => utils/storage}/BookmarksStorage.java | 3 +-- .../{data => utils/storage}/UserOrdersStorage.java | 3 +-- 18 files changed, 19 insertions(+), 25 deletions(-) rename src/main/java/com/github/mkram17/bazaarutils/{data/APIUtils.java => utils/APIUtil.java} (91%) rename src/main/java/com/github/mkram17/bazaarutils/{data => utils/storage}/BazaarLimitsStorage.java (83%) rename src/main/java/com/github/mkram17/bazaarutils/{data => utils/storage}/BookmarksStorage.java (81%) rename src/main/java/com/github/mkram17/bazaarutils/{data => utils/storage}/UserOrdersStorage.java (81%) diff --git a/src/main/java/com/github/mkram17/bazaarutils/commands/DeveloperCommands.java b/src/main/java/com/github/mkram17/bazaarutils/commands/DeveloperCommands.java index 13be12b9..c446c2b7 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/commands/DeveloperCommands.java +++ b/src/main/java/com/github/mkram17/bazaarutils/commands/DeveloperCommands.java @@ -2,12 +2,11 @@ import com.github.mkram17.bazaarutils.config.features.DeveloperConfig; import com.github.mkram17.bazaarutils.config.util.ConfigUtil; -import com.github.mkram17.bazaarutils.data.UserOrdersStorage; +import com.github.mkram17.bazaarutils.utils.storage.UserOrdersStorage; import com.github.mkram17.bazaarutils.features.notification.OutbidOrderHandler; import com.github.mkram17.bazaarutils.misc.NotificationType; import com.github.mkram17.bazaarutils.utils.PlayerActionUtil; import com.github.mkram17.bazaarutils.utils.annotations.modules.Module; -import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataManager; import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataUtil; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.Order; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.TransactionType; diff --git a/src/main/java/com/github/mkram17/bazaarutils/events/handler/BazaarChatEventHandler.java b/src/main/java/com/github/mkram17/bazaarutils/events/handler/BazaarChatEventHandler.java index da22f135..57b9e580 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/events/handler/BazaarChatEventHandler.java +++ b/src/main/java/com/github/mkram17/bazaarutils/events/handler/BazaarChatEventHandler.java @@ -2,7 +2,7 @@ import com.github.mkram17.bazaarutils.config.BUConfig; import com.github.mkram17.bazaarutils.config.features.notification.NotificationsConfig; -import com.github.mkram17.bazaarutils.data.UserOrdersStorage; +import com.github.mkram17.bazaarutils.utils.storage.UserOrdersStorage; import com.github.mkram17.bazaarutils.events.BazaarChatEvent; import com.github.mkram17.bazaarutils.features.gui.overlays.BazaarLimitsVisualizer; import com.github.mkram17.bazaarutils.misc.NotificationType; diff --git a/src/main/java/com/github/mkram17/bazaarutils/events/handler/ChatHandler.java b/src/main/java/com/github/mkram17/bazaarutils/events/handler/ChatHandler.java index 46885892..407d2e0f 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/events/handler/ChatHandler.java +++ b/src/main/java/com/github/mkram17/bazaarutils/events/handler/ChatHandler.java @@ -1,7 +1,7 @@ package com.github.mkram17.bazaarutils.events.handler; import com.github.mkram17.bazaarutils.config.BUConfig; -import com.github.mkram17.bazaarutils.data.UserOrdersStorage; +import com.github.mkram17.bazaarutils.utils.storage.UserOrdersStorage; import com.github.mkram17.bazaarutils.events.BazaarChatEvent; import com.github.mkram17.bazaarutils.misc.NotificationType; import com.github.mkram17.bazaarutils.utils.annotations.autoregistration.RunOnInit; diff --git a/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/BookmarkUtil.java b/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/BookmarkUtil.java index 96dc34a4..26150718 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/BookmarkUtil.java +++ b/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/bookmarks/BookmarkUtil.java @@ -1,7 +1,7 @@ package com.github.mkram17.bazaarutils.features.gui.buttons.bookmarks; import com.github.mkram17.bazaarutils.BazaarUtils; -import com.github.mkram17.bazaarutils.data.BookmarksStorage; +import com.github.mkram17.bazaarutils.utils.storage.BookmarksStorage; import lombok.Getter; import net.minecraft.client.gui.screen.ButtonTextures; import net.minecraft.util.Identifier; diff --git a/src/main/java/com/github/mkram17/bazaarutils/features/gui/overlays/BazaarLimitsVisualizer.java b/src/main/java/com/github/mkram17/bazaarutils/features/gui/overlays/BazaarLimitsVisualizer.java index 45c9c1ec..b8349456 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/features/gui/overlays/BazaarLimitsVisualizer.java +++ b/src/main/java/com/github/mkram17/bazaarutils/features/gui/overlays/BazaarLimitsVisualizer.java @@ -6,7 +6,7 @@ import java.util.List; import com.github.mkram17.bazaarutils.config.features.gui.OverlaysConfig; -import com.github.mkram17.bazaarutils.data.BazaarLimitsStorage; +import com.github.mkram17.bazaarutils.utils.storage.BazaarLimitsStorage; import com.github.mkram17.bazaarutils.events.listener.BUListener; import com.github.mkram17.bazaarutils.generated.BazaarUtilsModules; import com.github.mkram17.bazaarutils.misc.BUCompatibilityHelper; diff --git a/src/main/java/com/github/mkram17/bazaarutils/features/notification/OutbidOrderHandler.java b/src/main/java/com/github/mkram17/bazaarutils/features/notification/OutbidOrderHandler.java index 2cb95773..857adeb7 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/features/notification/OutbidOrderHandler.java +++ b/src/main/java/com/github/mkram17/bazaarutils/features/notification/OutbidOrderHandler.java @@ -1,7 +1,7 @@ package com.github.mkram17.bazaarutils.features.notification; import com.github.mkram17.bazaarutils.config.features.notification.NotificationsConfig; -import com.github.mkram17.bazaarutils.data.UserOrdersStorage; +import com.github.mkram17.bazaarutils.utils.storage.UserOrdersStorage; import com.github.mkram17.bazaarutils.utils.annotations.modules.Module; import com.github.mkram17.bazaarutils.utils.config.BUToggleableFeature; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.Order; diff --git a/src/main/java/com/github/mkram17/bazaarutils/data/APIUtils.java b/src/main/java/com/github/mkram17/bazaarutils/utils/APIUtil.java similarity index 91% rename from src/main/java/com/github/mkram17/bazaarutils/data/APIUtils.java rename to src/main/java/com/github/mkram17/bazaarutils/utils/APIUtil.java index dda16ddd..0b8a02f4 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/data/APIUtils.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/APIUtil.java @@ -1,11 +1,11 @@ -package com.github.mkram17.bazaarutils.data; +package com.github.mkram17.bazaarutils.utils; import net.hypixel.api.HypixelAPI; import net.hypixel.api.apache.ApacheHttpClient; import java.util.UUID; -public class APIUtils { +public class APIUtil { public static String getApiKey() { String apiKey = System.getenv("HYPIXEL_API_KEY"); diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/SignInputHelper.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/SignInputHelper.java index 75a9a7f4..4eaedb11 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/SignInputHelper.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/SignInputHelper.java @@ -1,9 +1,8 @@ package com.github.mkram17.bazaarutils.utils.bazaar; -import com.github.mkram17.bazaarutils.data.UserOrdersStorage; +import com.github.mkram17.bazaarutils.utils.storage.UserOrdersStorage; import com.github.mkram17.bazaarutils.events.ChestLoadedEvent; import com.github.mkram17.bazaarutils.utils.Util; -import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataManager; import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataUtil; import com.github.mkram17.bazaarutils.utils.bazaar.gui.BazaarScreenHandler; import com.github.mkram17.bazaarutils.utils.bazaar.gui.BazaarScreens; diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java index 063276ce..42b7d7ec 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java @@ -1,7 +1,7 @@ package com.github.mkram17.bazaarutils.utils.bazaar.data; import com.github.mkram17.bazaarutils.BazaarUtils; -import com.github.mkram17.bazaarutils.data.APIUtils; +import com.github.mkram17.bazaarutils.utils.APIUtil; import com.github.mkram17.bazaarutils.events.BazaarDataUpdateEvent; import com.github.mkram17.bazaarutils.misc.NotificationType; import com.github.mkram17.bazaarutils.utils.PlayerActionUtil; @@ -60,7 +60,7 @@ private static void fetchOnceSafely() { } private static void fetchOnce() { - APIUtils.API.getSkyBlockBazaar().whenComplete((reply, throwable) -> { + APIUtil.API.getSkyBlockBazaar().whenComplete((reply, throwable) -> { if (throwable != null || !reply.isSuccess()) { handleFetchFailure( "Fetch failure (" + throwable.getClass().getSimpleName() + "). Retry in " + BAZAAR_DATA_SETTINGS.FAILURE_RETRY_MS + "ms", diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/APIConversionUtil.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/APIConversionUtil.java index e9db43db..c8fba4fc 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/APIConversionUtil.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/APIConversionUtil.java @@ -1,6 +1,5 @@ package com.github.mkram17.bazaarutils.utils.bazaar.data.wrappers; -import com.github.mkram17.bazaarutils.data.UserOrdersStorage; import com.github.mkram17.bazaarutils.mixin.AccessorSkyBlockBazaarReply; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.Order; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.PriceType; diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/CustomBazaarReply.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/CustomBazaarReply.java index b2ebb666..bad37a31 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/CustomBazaarReply.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/CustomBazaarReply.java @@ -1,6 +1,6 @@ package com.github.mkram17.bazaarutils.utils.bazaar.data.wrappers; -import com.github.mkram17.bazaarutils.data.UserOrdersStorage; +import com.github.mkram17.bazaarutils.utils.storage.UserOrdersStorage; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.Order; import lombok.Getter; import net.hypixel.api.reply.AbstractReply; diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/Order.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/Order.java index e306dd1b..20264be9 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/Order.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/Order.java @@ -2,7 +2,7 @@ import com.github.mkram17.bazaarutils.config.features.notification.NotificationsConfig; import com.github.mkram17.bazaarutils.config.features.DeveloperConfig; -import com.github.mkram17.bazaarutils.data.UserOrdersStorage; +import com.github.mkram17.bazaarutils.utils.storage.UserOrdersStorage; import com.github.mkram17.bazaarutils.events.BazaarDataUpdateEvent; import com.github.mkram17.bazaarutils.events.UserOrdersChangeEvent; import com.github.mkram17.bazaarutils.events.listener.AbstractListener; diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderInfo.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderInfo.java index 97a4d851..70bfe75d 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderInfo.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderInfo.java @@ -1,6 +1,6 @@ package com.github.mkram17.bazaarutils.utils.bazaar.market.order; -import com.github.mkram17.bazaarutils.data.UserOrdersStorage; +import com.github.mkram17.bazaarutils.utils.storage.UserOrdersStorage; import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataUtil; import com.github.mkram17.bazaarutils.utils.minecraft.ItemInfo; import com.github.mkram17.bazaarutils.utils.Util; diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderUpdater.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderUpdater.java index 7b3d2855..fb34a3b9 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderUpdater.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderUpdater.java @@ -1,6 +1,6 @@ package com.github.mkram17.bazaarutils.utils.bazaar.market.order; -import com.github.mkram17.bazaarutils.data.UserOrdersStorage; +import com.github.mkram17.bazaarutils.utils.storage.UserOrdersStorage; import com.github.mkram17.bazaarutils.events.ChestLoadedEvent; import com.github.mkram17.bazaarutils.utils.Util; import com.github.mkram17.bazaarutils.utils.bazaar.gui.BazaarScreens; diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderUtil.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderUtil.java index b3a9efff..b167df41 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderUtil.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderUtil.java @@ -1,6 +1,6 @@ package com.github.mkram17.bazaarutils.utils.bazaar.market.order; -import com.github.mkram17.bazaarutils.data.UserOrdersStorage; +import com.github.mkram17.bazaarutils.utils.storage.UserOrdersStorage; import com.github.mkram17.bazaarutils.events.UserOrdersChangeEvent; import com.github.mkram17.bazaarutils.misc.NotificationType; import com.github.mkram17.bazaarutils.utils.PlayerActionUtil; diff --git a/src/main/java/com/github/mkram17/bazaarutils/data/BazaarLimitsStorage.java b/src/main/java/com/github/mkram17/bazaarutils/utils/storage/BazaarLimitsStorage.java similarity index 83% rename from src/main/java/com/github/mkram17/bazaarutils/data/BazaarLimitsStorage.java rename to src/main/java/com/github/mkram17/bazaarutils/utils/storage/BazaarLimitsStorage.java index a7596c06..166c4b06 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/data/BazaarLimitsStorage.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/storage/BazaarLimitsStorage.java @@ -1,7 +1,6 @@ -package com.github.mkram17.bazaarutils.data; +package com.github.mkram17.bazaarutils.utils.storage; import com.github.mkram17.bazaarutils.features.gui.overlays.BazaarLimitsVisualizer; -import com.github.mkram17.bazaarutils.utils.storage.DataStorage; import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type; import java.util.ArrayList; diff --git a/src/main/java/com/github/mkram17/bazaarutils/data/BookmarksStorage.java b/src/main/java/com/github/mkram17/bazaarutils/utils/storage/BookmarksStorage.java similarity index 81% rename from src/main/java/com/github/mkram17/bazaarutils/data/BookmarksStorage.java rename to src/main/java/com/github/mkram17/bazaarutils/utils/storage/BookmarksStorage.java index 504c436f..14b3b70f 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/data/BookmarksStorage.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/storage/BookmarksStorage.java @@ -1,7 +1,6 @@ -package com.github.mkram17.bazaarutils.data; +package com.github.mkram17.bazaarutils.utils.storage; import com.github.mkram17.bazaarutils.features.gui.buttons.bookmarks.Bookmark; -import com.github.mkram17.bazaarutils.utils.storage.DataStorage; import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type; import java.util.ArrayList; diff --git a/src/main/java/com/github/mkram17/bazaarutils/data/UserOrdersStorage.java b/src/main/java/com/github/mkram17/bazaarutils/utils/storage/UserOrdersStorage.java similarity index 81% rename from src/main/java/com/github/mkram17/bazaarutils/data/UserOrdersStorage.java rename to src/main/java/com/github/mkram17/bazaarutils/utils/storage/UserOrdersStorage.java index 018b605c..13b5c18d 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/data/UserOrdersStorage.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/storage/UserOrdersStorage.java @@ -1,7 +1,6 @@ -package com.github.mkram17.bazaarutils.data; +package com.github.mkram17.bazaarutils.utils.storage; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.Order; -import com.github.mkram17.bazaarutils.utils.storage.DataStorage; import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type; import java.util.ArrayList; From 860c316d2f6fc67d5f2304b9d92ac28aea0ba6f8 Mon Sep 17 00:00:00 2001 From: mkram17 <1maxkramer@gmail.com> Date: Tue, 24 Mar 2026 21:10:07 -0400 Subject: [PATCH 12/15] remove UserProductOrder.java in preparation for switch to PriceLevelPool impl --- .../utils/bazaar/data/BazaarDataManager.java | 1 - .../bazaar/data/wrappers/APIConversionUtil.java | 17 ----------------- .../bazaar/data/wrappers/CustomBazaarReply.java | 10 ---------- .../bazaar/data/wrappers/UserProductOrder.java | 17 ----------------- 4 files changed, 45 deletions(-) delete mode 100644 src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/UserProductOrder.java diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java index 42b7d7ec..d47f492f 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataManager.java @@ -79,7 +79,6 @@ private static void fetchOnce() { consecutiveFailures.set(0); - customReply.replaceUserProductOrders(); handleSnapshotResult(customReply, snapshotTs); scheduleNextFromSnapshot(snapshotTs); }); diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/APIConversionUtil.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/APIConversionUtil.java index c8fba4fc..897e88b5 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/APIConversionUtil.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/APIConversionUtil.java @@ -11,23 +11,6 @@ import java.util.stream.Collectors; public final class APIConversionUtil { - - public static List replaceUserOrdersInList(Order order, List orders) { - List replaced = new ArrayList<>(); - - for (int i = 0; i < orders.size(); i++) { - ProductOrder productOrder = orders.get(i); - if (!productOrder.equalsOrder(order)) { - continue; - } - - UserProductOrder replacement = new UserProductOrder(order, productOrder); - orders.set(i, replacement); - replaced.add(replacement); - } - - return replaced; - } public static CustomBazaarReply fromSkyBlockReply(SkyBlockBazaarReply reply) { AccessorSkyBlockBazaarReply accessor = (AccessorSkyBlockBazaarReply) reply; diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/CustomBazaarReply.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/CustomBazaarReply.java index bad37a31..3fdba9a6 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/CustomBazaarReply.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/CustomBazaarReply.java @@ -22,14 +22,4 @@ public CustomBazaarReply(long lastUpdated, Map products) { public ProductData getProduct(String productId) { return products.get(productId); } - - public void replaceUserProductOrders() { - List userOrders = UserOrdersStorage.INSTANCE.get(); - - for (Order order : userOrders) { - ProductData product = getProduct(order.getProductID()); - APIConversionUtil.replaceUserOrdersInList(order, product.getSellOrders()); - APIConversionUtil.replaceUserOrdersInList(order, product.getBuyOrders()); - } - } } diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/UserProductOrder.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/UserProductOrder.java deleted file mode 100644 index ab2f276e..00000000 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/UserProductOrder.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.github.mkram17.bazaarutils.utils.bazaar.data.wrappers; - -import com.github.mkram17.bazaarutils.utils.bazaar.market.order.Order; -import com.github.mkram17.bazaarutils.utils.bazaar.market.order.PriceType; - -public class UserProductOrder extends ProductOrder { - private Order userOrder; - - public UserProductOrder(Order userOrder, PriceType priceType, double pricePerUnit, long amount, long orders) { - super(priceType, pricePerUnit, amount, orders); - this.userOrder = userOrder; - } - public UserProductOrder(Order userOrder, ProductOrder productOrder) { - super(productOrder.getPriceType(), productOrder.getPricePerUnit(), productOrder.getVolume(), productOrder.getNumOrders()); - this.userOrder = userOrder; - } -} From e62e2a116fd1fcf6f82a05eb751d34ce8217861c Mon Sep 17 00:00:00 2001 From: mkram17 <1maxkramer@gmail.com> Date: Tue, 24 Mar 2026 21:13:04 -0400 Subject: [PATCH 13/15] product id validation --- .../utils/bazaar/market/order/OrderInfo.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderInfo.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderInfo.java index 70bfe75d..7180086f 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderInfo.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/order/OrderInfo.java @@ -63,15 +63,14 @@ public OrderInfo(@Nullable String name, @Nullable TransactionType.Side side, @Nu this.volume = volume; this.tolerance = calculateTolerance(); - BazaarDataUtil.findProductIdOptional(name).ifPresent(productId -> this.productID = productId); - validateProductId(productID); + BazaarDataUtil.findProductIdOptional(name).ifPresent(id -> this.productID = id); + validateProductId(); findPricingPosition().ifPresent(pricingPosition -> this.pricingPosition = pricingPosition); } - //TODO validate name/product id with method specifically for that. Maybe can switch findProdIdOpt for non optional version and then rely on validation method. - private void validateProductId(String productId) { - if(productId == null || productId.isBlank()) { - Util.notifyError("Error setting product id for " + this, new Throwable("Product ID cannot be null or blank")); + private void validateProductId() { + if(!BazaarDataUtil.isValidProductId(productID)){ + Util.notifyError("Error setting product id for " + this, new Throwable("Product ID is invalid")); } } From bf2efce4c86d2f827d75aaa1674a93194f95504f Mon Sep 17 00:00:00 2001 From: Max <53064237+mkram17@users.noreply.github.com> Date: Wed, 25 Mar 2026 20:39:24 -0400 Subject: [PATCH 14/15] make api data immutable Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../bazaarutils/utils/bazaar/data/wrappers/ProductData.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductData.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductData.java index 08951a1a..23ff7782 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductData.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/wrappers/ProductData.java @@ -19,10 +19,10 @@ public ProductData(String productId, List productBuyOrders, List

getBuyOrders() { - return productBuyOrders; + return Collections.unmodifiableList(productBuyOrders); } public List getSellOrders() { - return productSellOrders; + return Collections.unmodifiableList(productSellOrders); } } From db027ec02b03bf15d6bbc50990520e161e58ae92 Mon Sep 17 00:00:00 2001 From: Max <53064237+mkram17@users.noreply.github.com> Date: Wed, 25 Mar 2026 20:39:52 -0400 Subject: [PATCH 15/15] fix getOrderCountOptional Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java index 68ce3864..bfc75d80 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/data/BazaarDataUtil.java @@ -51,7 +51,7 @@ public static OptionalInt getOrderCountOptional(String productId, TransactionTyp for (ProductOrder s : list) { if (Double.compare(s.getPricePerUnit(), price) == 0) { - return OptionalInt.of((int) s.getVolume()); + return OptionalInt.of(s.getNumOrders()); } }