From 84e047c6694be5523701e579a789d5792049616a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 15 Mar 2026 17:23:24 +0000 Subject: [PATCH 1/3] Initial plan From 789fdda1e34b0f861bf8faf54141838e2ed1905a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 15 Mar 2026 17:32:39 +0000 Subject: [PATCH 2/3] Fix MarketPrices listener leak in SignInputHelper by using static price lookup Co-authored-by: mkram17 <53064237+mkram17@users.noreply.github.com> --- .../amount/BuyOrderAmountHelper.java | 3 +- .../amount/InstantBuyAmountHelper.java | 3 +- .../amount/SellOfferAmountHelper.java | 3 +- .../utils/bazaar/SignInputHelper.java | 16 ++++------ .../bazaar/market/price/MarketPrices.java | 30 +++++++++++++++++++ 5 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/inputhelper/amount/BuyOrderAmountHelper.java b/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/inputhelper/amount/BuyOrderAmountHelper.java index 3a8e76df..5f16c13f 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/inputhelper/amount/BuyOrderAmountHelper.java +++ b/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/inputhelper/amount/BuyOrderAmountHelper.java @@ -5,7 +5,6 @@ import com.github.mkram17.bazaarutils.utils.bazaar.gui.BazaarSlots; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.MarketType; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.OrderType; -import com.github.mkram17.bazaarutils.utils.bazaar.market.price.MarketPrices; import com.github.mkram17.bazaarutils.utils.minecraft.gui.ScreenManager; import com.teamresourceful.resourcefulconfig.api.annotations.Comment; import com.teamresourceful.resourcefulconfig.api.annotations.ConfigEntry; @@ -92,7 +91,7 @@ public BuyOrderAmountHelper(boolean enabled, int slotNumber) { } @Override - protected int computeFixedValue(TransactionState state, MarketPrices price) { + protected int computeFixedValue(TransactionState state) { return getFixedAmount(); } diff --git a/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/inputhelper/amount/InstantBuyAmountHelper.java b/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/inputhelper/amount/InstantBuyAmountHelper.java index fa7e092f..078fdbba 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/inputhelper/amount/InstantBuyAmountHelper.java +++ b/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/inputhelper/amount/InstantBuyAmountHelper.java @@ -5,7 +5,6 @@ import com.github.mkram17.bazaarutils.utils.bazaar.gui.BazaarSlots; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.MarketType; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.OrderType; -import com.github.mkram17.bazaarutils.utils.bazaar.market.price.MarketPrices; import com.github.mkram17.bazaarutils.utils.minecraft.gui.ScreenManager; import com.teamresourceful.resourcefulconfig.api.annotations.Comment; import com.teamresourceful.resourcefulconfig.api.annotations.ConfigEntry; @@ -92,7 +91,7 @@ public InstantBuyAmountHelper(boolean enabled, int slotNumber) { } @Override - protected int computeFixedValue(TransactionState state, MarketPrices price) { + protected int computeFixedValue(TransactionState state) { return getFixedAmount(); } diff --git a/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/inputhelper/amount/SellOfferAmountHelper.java b/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/inputhelper/amount/SellOfferAmountHelper.java index 84584822..4c3b0dc3 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/inputhelper/amount/SellOfferAmountHelper.java +++ b/src/main/java/com/github/mkram17/bazaarutils/features/gui/buttons/inputhelper/amount/SellOfferAmountHelper.java @@ -5,7 +5,6 @@ import com.github.mkram17.bazaarutils.utils.bazaar.gui.BazaarSlots; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.MarketType; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.OrderType; -import com.github.mkram17.bazaarutils.utils.bazaar.market.price.MarketPrices; import com.github.mkram17.bazaarutils.utils.minecraft.gui.ScreenManager; import com.teamresourceful.resourcefulconfig.api.annotations.Comment; import com.teamresourceful.resourcefulconfig.api.annotations.ConfigEntry; @@ -92,7 +91,7 @@ public SellOfferAmountHelper(boolean enabled, int slotNumber) { } @Override - protected int computeFixedValue(TransactionState state, MarketPrices price) { + protected int computeFixedValue(TransactionState state) { return getFixedAmount(); } 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 d1047723..af2f5600 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 @@ -235,19 +235,17 @@ protected ResolvedInput resolveInput(TransactionState state) { return new ResolvedInput.Value(0); } - MarketPrices marketPrices = new MarketPrices(state.productId); - int amount = switch (getAmountStrategy()) { - case MAX -> computeMaxValue(state, marketPrices); - case FIXED -> computeFixedValue(state, marketPrices); + case MAX -> computeMaxValue(state); + case FIXED -> computeFixedValue(state); }; return new ResolvedInput.Value(amount); } - protected abstract int computeFixedValue(TransactionState state, MarketPrices price); + protected abstract int computeFixedValue(TransactionState state); - protected int computeMaxValue(TransactionState state, MarketPrices prices) { + protected int computeMaxValue(TransactionState state) { return switch (getMarketType()) { case INSTANT -> switch (getOrderType()) { case BUY -> Optional.of(state.containerScreen()) @@ -268,7 +266,7 @@ protected int computeMaxValue(TransactionState state, MarketPrices prices) { }; case ORDER -> switch (getOrderType()) { case BUY -> { - int amountCanAfford = (int) (state.purse() / prices.getPriceForPosition(PricingPosition.COMPETITIVE, getMarketType().withIntention(getOrderType()))); + int amountCanAfford = (int) (state.purse() / MarketPrices.getPriceForPosition(state.productId(), PricingPosition.COMPETITIVE, getMarketType().withIntention(getOrderType()))); yield BazaarScreens.findBuyOrderAmountLimit(state.inputSign().itemStack()) .map(limit -> Math.min(amountCanAfford, limit)) @@ -357,9 +355,7 @@ protected ResolvedInput resolveInput(TransactionState state) { return new ResolvedInput.Value(0); } - MarketPrices marketPrices = new MarketPrices(state.productId); - - return new ResolvedInput.Value(marketPrices.getPriceForPosition(getPricingPosition(), getOrderType())); + return new ResolvedInput.Value(MarketPrices.getPriceForPosition(state.productId(), getPricingPosition(), getOrderType())); } } diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/price/MarketPrices.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/price/MarketPrices.java index d855e413..fbcb0187 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/price/MarketPrices.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/price/MarketPrices.java @@ -8,6 +8,8 @@ import lombok.Getter; import meteordevelopment.orbit.EventHandler; +import java.util.OptionalDouble; + public class MarketPrices extends BUListener { private final PriceInfo buyPriceInfo = new PriceInfo(null, OrderType.BUY); @@ -58,4 +60,32 @@ public Double getPriceForPosition(PricingPosition pricingPosition, OrderType ord }; }; } + + /** + * Computes the adjusted price for a product at the given pricing position and order type + * without creating a {@link MarketPrices} instance. Use this instead of instantiating + * {@link MarketPrices} transiently to avoid listener leaks. + * + * @param productId the Hypixel product ID to look up + * @param pricingPosition the positioning strategy (competitive, matched, outbid) + * @param orderType the order side (BUY or SELL) + * @return the market price adjusted for the given pricing position, or {@code 0.0} if no data is available + */ + public static double getPriceForPosition(String productId, PricingPosition pricingPosition, OrderType orderType) { + OptionalDouble priceOpt = BazaarDataManager.findItemPriceOptional(productId, orderType); + double price = Util.truncateNum(priceOpt.orElse(0.0)); + + return switch (orderType) { + case SELL -> switch (pricingPosition) { + case COMPETITIVE -> price - 0.1; + case MATCHED -> price; + case OUTBID -> price + 0.1; + }; + case BUY -> switch (pricingPosition) { + case COMPETITIVE -> price + 0.1; + case MATCHED -> price; + case OUTBID -> price - 0.1; + }; + }; + } } From df5bc6071abd602889a3d879b6a3ef94c05a2828 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Mar 2026 19:30:34 +0000 Subject: [PATCH 3/3] Have instance getPriceForPosition delegate to static overload; remove BUListener inheritance Co-authored-by: mkram17 <53064237+mkram17@users.noreply.github.com> --- .../bazaar/market/price/MarketPrices.java | 46 +++---------------- 1 file changed, 6 insertions(+), 40 deletions(-) diff --git a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/price/MarketPrices.java b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/price/MarketPrices.java index fbcb0187..1d2c358b 100644 --- a/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/price/MarketPrices.java +++ b/src/main/java/com/github/mkram17/bazaarutils/utils/bazaar/market/price/MarketPrices.java @@ -1,64 +1,30 @@ package com.github.mkram17.bazaarutils.utils.bazaar.market.price; -import com.github.mkram17.bazaarutils.events.BazaarDataUpdateEvent; -import com.github.mkram17.bazaarutils.events.listener.BUListener; import com.github.mkram17.bazaarutils.utils.Util; import com.github.mkram17.bazaarutils.utils.bazaar.data.BazaarDataManager; import com.github.mkram17.bazaarutils.utils.bazaar.market.order.OrderType; import lombok.Getter; -import meteordevelopment.orbit.EventHandler; import java.util.OptionalDouble; -public class MarketPrices extends BUListener { +public class MarketPrices { - private final PriceInfo buyPriceInfo = new PriceInfo(null, OrderType.BUY); - private final PriceInfo sellPriceInfo = new PriceInfo(null, OrderType.SELL); @Getter private final String productID; public MarketPrices(String productID) { this.productID = productID; - subscribe(); - updateMarketPrices(productID); - } - - @EventHandler - private void onDataUpdate(BazaarDataUpdateEvent event) { - updateMarketPrices(); } /** - * Refreshes cached market price data for this product. + * No-op: prices are now read fresh from {@link BazaarDataManager} on every call to + * {@link #getPriceForPosition}. Kept for API compatibility. */ public void updateMarketPrices() { - updateMarketPrices(productID); - } - - private void updateMarketPrices(String productId) { - var buyPriceOpt = BazaarDataManager.findItemPriceOptional(productId, OrderType.BUY); - var sellPriceOpt = BazaarDataManager.findItemPriceOptional(productId, OrderType.SELL); - - buyPriceOpt.ifPresent(price -> buyPriceInfo.setPricePerItem(Util.truncateNum(price))); - sellPriceOpt.ifPresent(price -> sellPriceInfo.setPricePerItem(Util.truncateNum(price))); } public Double getPriceForPosition(PricingPosition pricingPosition, OrderType orderType) { - double marketSellPrice = sellPriceInfo.getPricePerItem(); - double marketBuyPrice = buyPriceInfo.getPricePerItem(); - - return switch (orderType) { - case SELL -> switch (pricingPosition) { - case COMPETITIVE -> marketSellPrice - 0.1; - case MATCHED -> marketSellPrice; - case OUTBID -> marketSellPrice + 0.1; - }; - case BUY -> switch (pricingPosition) { - case COMPETITIVE -> marketBuyPrice + 0.1; - case MATCHED -> marketBuyPrice; - case OUTBID -> marketBuyPrice - 0.1; - }; - }; + return getPriceForPosition(productID, pricingPosition, orderType); } /** @@ -66,9 +32,9 @@ public Double getPriceForPosition(PricingPosition pricingPosition, OrderType ord * without creating a {@link MarketPrices} instance. Use this instead of instantiating * {@link MarketPrices} transiently to avoid listener leaks. * - * @param productId the Hypixel product ID to look up + * @param productId the Hypixel product ID to look up * @param pricingPosition the positioning strategy (competitive, matched, outbid) - * @param orderType the order side (BUY or SELL) + * @param orderType the order side (BUY or SELL) * @return the market price adjusted for the given pricing position, or {@code 0.0} if no data is available */ public static double getPriceForPosition(String productId, PricingPosition pricingPosition, OrderType orderType) {