Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

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;
import com.mojang.brigadier.arguments.IntegerArgumentType;
Expand Down Expand Up @@ -152,7 +152,7 @@ private int convertNameToId(CommandContext<FabricClientCommandSource> 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)
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,40 +1,28 @@
package com.github.mkram17.bazaarutils.events;

import lombok.AllArgsConstructor;
import com.github.mkram17.bazaarutils.utils.bazaar.data.wrappers.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.
* <p>
* 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.
* </p>
*
* <p><strong>Usage Example:</strong></p>
* <pre>
* {@code
* @EventHandler
* public void onBazaarDataUpdate(BazaarDataUpdateEvent event) {
* SkyBlockBazaarReply reply = event.getBazaarReply();
* // Update local cache with new market data
* updatePriceCache(reply);
* }
* }
* </pre>
*
* @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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.
Expand All @@ -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<String, String> nameToProductIdCache = Map.of();
@Setter
private static volatile boolean conversionsLoaded = false;


public static void initialize() {
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Comment on lines +177 to +180
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ensureConversionsLoaded() synchronizes on BazaarDataManager.class, which couples ResourceManager’s cache locking to an unrelated class and risks unexpected contention/deadlocks if BazaarDataManager ever also synchronizes while calling into ResourceManager. Use ResourceManager.class or a dedicated private lock object for this cache instead.

Copilot uses AI. Check for mistakes.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot edit this pull request to fix the issues you noted in comments here.

}

try {
Map<String, String> 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;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
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;
import com.github.mkram17.bazaarutils.utils.bazaar.gui.BazaarSlots;
Expand Down Expand Up @@ -226,7 +226,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.");
Expand Down Expand Up @@ -278,7 +278,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)
Expand Down Expand Up @@ -348,7 +348,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.");
Expand Down
Loading
Loading