aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorKevin <92656833+kevinthegreat1@users.noreply.github.com>2025-07-09 14:12:37 +0800
committerGitHub <noreply@github.com>2025-07-09 02:12:37 -0400
commitcb5f8faf39fee4077543c2599120e951be79c5c4 (patch)
tree22358532225d9530dcc41f648502de2906ae20aa /src/main/java
parent325538abeb2b85bd531b0deae94885838b9ea800 (diff)
downloadSkyblocker-cb5f8faf39fee4077543c2599120e951be79c5c4.tar.gz
Skyblocker-cb5f8faf39fee4077543c2599120e951be79c5c4.tar.bz2
Skyblocker-cb5f8faf39fee4077543c2599120e951be79c5c4.zip
Refactor NEURepoManager (#1480)
* Refactor NEURepoManager * Clear ItemRepository caches * Fix import
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/ItemPickupWidget.java7
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/SackItemAutocomplete.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/chat/SackMessagePrice.java34
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/garden/visitor/VisitorHelper.java5
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/CraftPriceTooltip.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemRepository.java228
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemStackBuilder.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/itemlist/StackOverlays.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/profileviewer/inventory/Pet.java13
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/searchoverlay/SearchOverManager.java6
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java326
12 files changed, 354 insertions, 281 deletions
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/ItemPickupWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/ItemPickupWidget.java
index b6f5265b..9ca0d1b3 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/ItemPickupWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/ItemPickupWidget.java
@@ -59,13 +59,12 @@ public class ItemPickupWidget extends ComponentBasedWidget {
*/
private static ItemStack getItem(String itemName) {
if (NEURepoManager.isLoading() || !ItemRepository.filesImported()) return new ItemStack(Items.BARRIER);
- return NEURepoManager.NEU_REPO.getItems().getItems()
- .values().stream()
- .filter(item -> Formatting.strip(item.getDisplayName()).equals(itemName))
+ return NEURepoManager.getItemByName(itemName)
+ .stream()
.findFirst()
.map(NEUItem::getSkyblockItemId)
.map(ItemRepository::getItemStack)
- .orElse(new ItemStack(Items.BARRIER));
+ .orElseGet(() -> new ItemStack(Items.BARRIER));
}
/**
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/SackItemAutocomplete.java b/src/main/java/de/hysky/skyblocker/skyblock/SackItemAutocomplete.java
index 8646300c..7168b24d 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/SackItemAutocomplete.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/SackItemAutocomplete.java
@@ -44,7 +44,7 @@ public class SackItemAutocomplete {
}
private static void loadSackItems() {
- try (InputStream stream = NEURepoManager.NEU_REPO.file("constants/sacks.json").stream()) {
+ try (InputStream stream = NEURepoManager.file("constants/sacks.json").stream()) {
JsonObject sacks = JsonParser.parseString(new String(stream.readAllBytes())).getAsJsonObject().getAsJsonObject("sacks");
Set<String> sackItemIds = sacks.entrySet().stream()
@@ -56,7 +56,7 @@ public class SackItemAutocomplete {
.collect(Collectors.toUnmodifiableSet());
Set<String> sackItems = sackItemIds.stream()
.map(neuId -> {
- NEUItem stack = NEURepoManager.NEU_REPO.getItems().getItemBySkyblockId(neuId);
+ NEUItem stack = NEURepoManager.getItemByNeuId(neuId);
return stack != null ? Formatting.strip(stack.getDisplayName()) : neuId;
})
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/chat/SackMessagePrice.java b/src/main/java/de/hysky/skyblocker/skyblock/chat/SackMessagePrice.java
index 57205e6f..565d3346 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/chat/SackMessagePrice.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/chat/SackMessagePrice.java
@@ -9,7 +9,6 @@ import de.hysky.skyblocker.utils.NEURepoManager;
import de.hysky.skyblocker.utils.RegexUtils;
import io.github.moulberry.repo.data.NEUItem;
import it.unimi.dsi.fastutil.objects.*;
-import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientWorldEvents;
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.HoverEvent.ShowText;
@@ -36,21 +35,9 @@ import java.util.regex.Pattern;
public class SackMessagePrice {
private static final Pattern ITEM_COUNT_PATTERN = Pattern.compile("([-+][\\d,]+)");
private static final Logger LOGGER = LoggerFactory.getLogger(SackMessagePrice.class);
- /**
- * <p>
- * Cache that holds item name to NEU ID mappings.
- * This helps over time when farming similar items in the same world, as it avoids repeated lookups in a very large item list.
- * The Sack message is only sent like every 30s in a normal farming case, so there's not much performance impact anyway, but it still helps.
- * </p>
- * <p>
- * Additionally, there are 2 identical hover events per message, and they are processed separately, so this cache will be hit at least once per message, cutting the lookup time in half or more.
- * </p>
- */
- private static final Object2ObjectOpenHashMap<String, String> NAME_2_ID_CACHE = new Object2ObjectOpenHashMap<>();
@Init
public static void init() {
- ClientWorldEvents.AFTER_CLIENT_WORLD_CHANGE.register(((client, world) -> NAME_2_ID_CACHE.clear()));
ClientReceiveMessageEvents.MODIFY_GAME.register(SackMessagePrice::onMessage);
}
@@ -156,19 +143,14 @@ public class SackMessagePrice {
@Nullable
private static String getNeuId(@NotNull String itemName) {
- return NAME_2_ID_CACHE.computeIfAbsent(itemName, ignored ->
- NEURepoManager.NEU_REPO.getItems()
- .getItems()
- .values()
- .stream()
- .filter(item -> Formatting.strip(item.getDisplayName()).equals(itemName))
- .findFirst()
- .map(NEUItem::getSkyblockItemId)
- .orElseGet(() -> {
- LOGGER.warn("Failed to find item ID for item: {}", itemName);
- return null; // This won't be entered into the cache, nor will it be used to calculate the price
- })
- );
+ return NEURepoManager.getItemByName(itemName)
+ .stream()
+ .findFirst()
+ .map(NEUItem::getSkyblockItemId)
+ .orElseGet(() -> {
+ LOGGER.warn("Failed to find the NEU item ID for item: {}", itemName);
+ return null; // This won't be used to calculate the price
+ });
}
@NotNull
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/garden/visitor/VisitorHelper.java b/src/main/java/de/hysky/skyblocker/skyblock/garden/visitor/VisitorHelper.java
index 49085eb1..b26c44ee 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/garden/visitor/VisitorHelper.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/garden/visitor/VisitorHelper.java
@@ -141,9 +141,8 @@ public class VisitorHelper {
return cachedItems.computeIfAbsent(cleanName, name -> {
if (NEURepoManager.isLoading() || !ItemRepository.filesImported()) return null;
- return NEURepoManager.NEU_REPO.getItems().getItems()
- .values().stream()
- .filter(item -> Formatting.strip(item.getDisplayName()).equals(name))
+ return NEURepoManager.getItemByName(itemName)
+ .stream()
.findFirst()
.map(NEUItem::getSkyblockItemId)
.map(ItemRepository::getItemStack)
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/CraftPriceTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/CraftPriceTooltip.java
index 35171251..2dbd65a5 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/CraftPriceTooltip.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/adders/CraftPriceTooltip.java
@@ -41,7 +41,7 @@ public class CraftPriceTooltip extends SimpleTooltipAdder {
return;
}
- NEUItem neuItem = NEURepoManager.NEU_REPO.getItems().getItemBySkyblockId(stack.getNeuName());
+ NEUItem neuItem = NEURepoManager.getItemByNeuId(stack.getNeuName());
if (neuItem == null) return;
List<NEURecipe> neuRecipes = neuItem.getRecipes();
@@ -87,7 +87,7 @@ public class CraftPriceTooltip extends SimpleTooltipAdder {
cachedCraftCosts.put(inputItemName, itemCost);
}
- NEUItem neuItem = NEURepoManager.NEU_REPO.getItems().getItemBySkyblockId(inputItemName);
+ NEUItem neuItem = NEURepoManager.getItemByNeuId(inputItemName);
if (neuItem != null) {
List<NEURecipe> neuRecipes = neuItem.getRecipes();
if (!neuRecipes.isEmpty()) {
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemRepository.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemRepository.java
index ac58cdcf..f304d03f 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemRepository.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemRepository.java
@@ -7,10 +7,10 @@ import de.hysky.skyblocker.skyblock.itemlist.recipes.SkyblockRecipe;
import de.hysky.skyblocker.utils.ItemUtils;
import de.hysky.skyblocker.utils.NEURepoManager;
import io.github.moulberry.repo.data.NEUCraftingRecipe;
+import io.github.moulberry.repo.data.NEUForgeRecipe;
import io.github.moulberry.repo.data.NEUItem;
import io.github.moulberry.repo.data.NEURecipe;
import io.github.moulberry.repo.util.NEUId;
-import io.github.moulberry.repo.data.*;
import net.minecraft.item.ItemStack;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
@@ -20,127 +20,137 @@ import java.util.*;
import java.util.stream.Stream;
public class ItemRepository {
- protected static final Logger LOGGER = LoggerFactory.getLogger(ItemRepository.class);
+ protected static final Logger LOGGER = LoggerFactory.getLogger(ItemRepository.class);
- private static final List<ItemStack> items = new ArrayList<>();
- private static final Map<String, ItemStack> itemsMap = new HashMap<>();
- private static final List<SkyblockRecipe> recipes = new ArrayList<>();
+ private static final List<ItemStack> items = new ArrayList<>();
+ private static final Map<String, ItemStack> itemsMap = new HashMap<>();
+ private static final List<SkyblockRecipe> recipes = new ArrayList<>();
private static final HashMap<String, @NEUId String> bazaarStocks = new HashMap<>();
- private static boolean filesImported = false;
-
- @Init
- public static void init() {
- NEURepoManager.runAsyncAfterLoad(ItemStackBuilder::loadPetNums);
- NEURepoManager.runAsyncAfterLoad(ItemRepository::importItemFiles);
+ /**
+ * Consumers must check this field when accessing `items` and `itemsMap`, or else thread safety is not guaranteed.
+ */
+ private static boolean itemsImported = false;
+ /**
+ * Consumers must check this field when accessing `recipes`, or else thread safety is not guaranteed.
+ */
+ private static boolean filesImported = false;
+
+ @Init
+ public static void init() {
+ NEURepoManager.runAsyncAfterLoad(ItemStackBuilder::loadPetNums);
+ NEURepoManager.runAsyncAfterLoad(ItemRepository::importItemFiles);
NEURepoManager.runAsyncAfterLoad(ItemRepository::loadBazaarStocks);
- }
-
- private static void importItemFiles() {
- NEURepoManager.NEU_REPO.getItems().getItems().values().forEach(ItemRepository::loadItem);
- NEURepoManager.NEU_REPO.getItems().getItems().values().forEach(ItemRepository::loadRecipes);
-
- items.sort((lhs, rhs) -> {
- String lhsInternalName = ItemUtils.getItemId(lhs);
- String lhsFamilyName = lhsInternalName.replaceAll(".\\d+$", "");
- String rhsInternalName = ItemUtils.getItemId(rhs);
- String rhsFamilyName = rhsInternalName.replaceAll(".\\d+$", "");
- if (lhsFamilyName.equals(rhsFamilyName)) {
- if (lhsInternalName.length() != rhsInternalName.length())
- return lhsInternalName.length() - rhsInternalName.length();
- else return lhsInternalName.compareTo(rhsInternalName);
- }
- return lhsFamilyName.compareTo(rhsFamilyName);
- });
- filesImported = true;
- }
-
- private static void loadItem(NEUItem item) {
- try {
- ItemStack stack = ItemStackBuilder.fromNEUItem(item);
- StackOverlays.applyOverlay(item, stack);
-
- items.add(stack);
- itemsMap.put(item.getSkyblockItemId(), stack);
- } catch (Exception e) {
- LOGGER.error("[Skyblocker Item Repo Loader] Failed to load item, please report this! Skyblock Id: {}", item.getSkyblockItemId(), e);
- }
- }
-
- private static void loadRecipes(NEUItem item) {
- item.getRecipes().stream().map(ItemRepository::toSkyblockRecipe).filter(Objects::nonNull).forEach(recipes::add);
- }
+ }
+
+ private static void importItemFiles() {
+ itemsImported = false;
+ filesImported = false;
+
+ items.clear();
+ itemsMap.clear();
+ recipes.clear();
+
+ NEURepoManager.forEachItem(ItemRepository::loadItem);
+ items.sort(Comparator.<ItemStack, String>comparing(stack -> ItemUtils.getItemId(stack).replaceAll(".\\d+$", ""))
+ .thenComparingInt(stack -> ItemUtils.getItemId(stack).length())
+ .thenComparing(ItemUtils::getItemId)
+ );
+ itemsImported = true;
+
+ NEURepoManager.forEachItem(ItemRepository::loadRecipes);
+ filesImported = true;
+ }
+
+ private static void loadItem(NEUItem item) {
+ try {
+ ItemStack stack = ItemStackBuilder.fromNEUItem(item);
+ StackOverlays.applyOverlay(item, stack);
+
+ items.add(stack);
+ itemsMap.put(item.getSkyblockItemId(), stack);
+ } catch (Exception e) {
+ LOGGER.error("[Skyblocker Item Repo Loader] Failed to load item, please report this! Skyblock Id: {}", item.getSkyblockItemId(), e);
+ }
+ }
+
+ private static void loadRecipes(NEUItem item) {
+ item.getRecipes().stream().map(ItemRepository::toSkyblockRecipe).filter(Objects::nonNull).forEach(recipes::add);
+ }
private static void loadBazaarStocks() {
bazaarStocks.clear();
- NEURepoManager.NEU_REPO.getConstants().getBazaarStocks().getStocks().forEach((String neuId, String skyblockId) -> bazaarStocks.put(skyblockId, neuId));
- }
-
- public static String getWikiLink(String neuId, boolean useOfficial) {
- NEUItem item = NEURepoManager.NEU_REPO.getItems().getItemBySkyblockId(neuId);
- if (item == null || item.getInfo() == null || item.getInfo().isEmpty()) {
- return null;
- }
-
- List<String> info = item.getInfo();
- String wikiLink0 = info.getFirst();
- String wikiLink1 = info.size() > 1 ? info.get(1) : "";
- String wikiDomain = useOfficial ? "https://wiki.hypixel.net" : "https://hypixel-skyblock.fandom.com";
- if (wikiLink0.startsWith(wikiDomain)) {
- return wikiLink0;
- } else if (wikiLink1.startsWith(wikiDomain)) {
- return wikiLink1;
- }
- return null;
- }
-
- public static List<SkyblockRecipe> getRecipesAndUsages(ItemStack stack) {
- return Stream.concat(getRecipes(stack), getUsages(stack)).toList();
- }
-
- public static boolean filesImported() {
- return filesImported;
- }
-
- public static void setFilesImported(boolean filesImported) {
- ItemRepository.filesImported = filesImported;
- }
-
- public static List<ItemStack> getItems() {
- return items;
- }
-
- public static Stream<ItemStack> getItemsStream() {
- if (!filesImported) return Stream.empty();
- return items.stream();
- }
+ NEURepoManager.getConstants().getBazaarStocks().getStocks().forEach((String neuId, String skyblockId) -> bazaarStocks.put(skyblockId, neuId));
+ }
+
+ public static String getWikiLink(String neuId, boolean useOfficial) {
+ NEUItem item = NEURepoManager.getItemByNeuId(neuId);
+ if (item == null || item.getInfo() == null || item.getInfo().isEmpty()) {
+ return null;
+ }
+
+ List<String> info = item.getInfo();
+ String wikiLink0 = info.getFirst();
+ String wikiLink1 = info.size() > 1 ? info.get(1) : "";
+ String wikiDomain = useOfficial ? "https://wiki.hypixel.net" : "https://hypixel-skyblock.fandom.com";
+ if (wikiLink0.startsWith(wikiDomain)) {
+ return wikiLink0;
+ } else if (wikiLink1.startsWith(wikiDomain)) {
+ return wikiLink1;
+ }
+ return null;
+ }
+
+ public static List<SkyblockRecipe> getRecipesAndUsages(ItemStack stack) {
+ return Stream.concat(getRecipes(stack), getUsages(stack)).toList();
+ }
+
+ public static boolean filesImported() {
+ return filesImported;
+ }
+
+ public static void setFilesImported() {
+ itemsImported = false;
+ filesImported = false;
+ }
+
+ public static List<ItemStack> getItems() {
+ return itemsImported ? items : List.of();
+ }
+
+ public static Stream<ItemStack> getItemsStream() {
+ return itemsImported ? items.stream() : Stream.empty();
+ }
public static Map<String, @NEUId String> getBazaarStocks() {
+ // This is not protected by `filesImported` because it is loaded asynchronously separately from `items`, `itemsMap`, and `recipes`.
return bazaarStocks;
}
- /**
- * @param neuId the NEU item id gotten through {@link NEUItem#getSkyblockItemId()}, {@link ItemStack#getNeuName()}, or {@link ItemUtils#getNeuId(ItemStack) ItemTooltip#getNeuName(String, String)}
- */
- @Nullable
- public static ItemStack getItemStack(String neuId) {
- return itemsMap.get(neuId);
- }
+ /**
+ * @param neuId the NEU item id gotten through {@link NEUItem#getSkyblockItemId()}, {@link ItemStack#getNeuName()}, or {@link ItemUtils#getNeuId(ItemStack) ItemTooltip#getNeuName(String, String)}
+ */
+ @Nullable
+ public static ItemStack getItemStack(String neuId) {
+ return itemsImported ? itemsMap.get(neuId) : null;
+ }
- public static Stream<SkyblockRecipe> getRecipesStream() {return recipes.stream(); }
+ public static Stream<SkyblockRecipe> getRecipesStream() {
+ return filesImported ? recipes.stream() : Stream.empty();
+ }
- public static Stream<SkyblockRecipe> getRecipes(ItemStack stack) {
- return NEURepoManager.RECIPE_CACHE.getRecipes().getOrDefault(stack.getNeuName(), Set.of()).stream().map(ItemRepository::toSkyblockRecipe).filter(Objects::nonNull);
- }
+ public static Stream<SkyblockRecipe> getRecipes(ItemStack stack) {
+ return NEURepoManager.getRecipes().getOrDefault(stack.getNeuName(), Set.of()).stream().map(ItemRepository::toSkyblockRecipe).filter(Objects::nonNull);
+ }
- public static Stream<SkyblockRecipe> getUsages(ItemStack stack) {
- return NEURepoManager.RECIPE_CACHE.getUsages().getOrDefault(stack.getNeuName(), Set.of()).stream().map(ItemRepository::toSkyblockRecipe).filter(Objects::nonNull);
- }
+ public static Stream<SkyblockRecipe> getUsages(ItemStack stack) {
+ return NEURepoManager.getUsages().getOrDefault(stack.getNeuName(), Set.of()).stream().map(ItemRepository::toSkyblockRecipe).filter(Objects::nonNull);
+ }
- private static SkyblockRecipe toSkyblockRecipe(NEURecipe neuRecipe) {
- return switch (neuRecipe) {
- case NEUCraftingRecipe craftingRecipe -> new SkyblockCraftingRecipe(craftingRecipe);
- case NEUForgeRecipe forgeRecipe -> new SkyblockForgeRecipe(forgeRecipe);
- case null, default -> null;
- };
- }
+ private static SkyblockRecipe toSkyblockRecipe(NEURecipe neuRecipe) {
+ return switch (neuRecipe) {
+ case NEUCraftingRecipe craftingRecipe -> new SkyblockCraftingRecipe(craftingRecipe);
+ case NEUForgeRecipe forgeRecipe -> new SkyblockForgeRecipe(forgeRecipe);
+ case null, default -> null;
+ };
+ }
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemStackBuilder.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemStackBuilder.java
index 636523ca..fe06352e 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemStackBuilder.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/ItemStackBuilder.java
@@ -27,7 +27,7 @@ public class ItemStackBuilder {
protected static void loadPetNums() {
try {
- petNums = NEURepoManager.NEU_REPO.getConstants().getPetNumbers();
+ petNums = NEURepoManager.getConstants().getPetNumbers();
} catch (Exception e) {
ItemRepository.LOGGER.error("Failed to load petnums.json");
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/StackOverlays.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/StackOverlays.java
index 314ec244..aeaf4f09 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/StackOverlays.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/StackOverlays.java
@@ -32,7 +32,7 @@ public class StackOverlays {
*/
protected static void applyOverlay(NEUItem neuItem, ItemStack stack) {
try {
- NEURepoFile file = NEURepoManager.NEU_REPO.file(OVERLAY_DIRECTORY + "/" + neuItem.getSkyblockItemId() + ".snbt");
+ NEURepoFile file = NEURepoManager.file(OVERLAY_DIRECTORY + "/" + neuItem.getSkyblockItemId() + ".snbt");
//The returned file is null if it does not exist
if (file != null) {
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/inventory/Pet.java b/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/inventory/Pet.java
index 503155e6..89b49aa2 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/inventory/Pet.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/profileviewer/inventory/Pet.java
@@ -96,18 +96,16 @@ public class Pet {
private ItemStack createIcon() {
if (NEURepoManager.isLoading() || !ItemRepository.filesImported()) return Ico.BARRIER;
- Map<String, NEUItem> items = NEURepoManager.NEU_REPO.getItems().getItems();
- if (items == null) return Ico.BARRIER;
String targetItemId = this.getName() + ";" + (this.getTier() + (heldItem.isPresent() && heldItem.get().equals("PET_ITEM_TIER_BOOST") ? 1 : 0));
- NEUItem item = NEURepoManager.NEU_REPO.getItems().getItems().get(targetItemId);
+ NEUItem item = NEURepoManager.getItemByNeuId(targetItemId);
// For cases life RIFT_FERRET Where it can be tier boosted into a pet that otherwise can't exist
if (item == null && heldItem.isPresent() && heldItem.get().equals("PET_ITEM_TIER_BOOST")) {
- item = NEURepoManager.NEU_REPO.getItems().getItems().get(getName() + ";" + getTier());
+ item = NEURepoManager.getItemByNeuId(getName() + ";" + getTier());
}
- return fromNEUItem(item, this.heldItem.map(ItemRepository::getItemStack).orElse(null));
+ return item == null ? Ico.BARRIER : fromNEUItem(item, this.heldItem.map(ItemRepository::getItemStack).orElse(null));
}
/**
@@ -148,7 +146,8 @@ public class Pet {
// Skin Head Texture
if (skinTexture.isPresent() && skin.isPresent()) {
- formattedLore.set(0, Text.of(formattedLore.getFirst().getString() + ", " + Formatting.strip(NEURepoManager.NEU_REPO.getItems().getItems().get("PET_SKIN_" + skin.get()).getDisplayName())));
+ NEUItem skinItem = NEURepoManager.getItemByNeuId("PET_SKIN_" + skin.get());
+ if (skinItem != null) formattedLore.set(0, Text.of(formattedLore.getFirst().getString() + ", " + Formatting.strip(skinItem.getDisplayName())));
petStack.set(DataComponentTypes.PROFILE, skinTexture.get());
}
@@ -169,7 +168,7 @@ public class Pet {
* @return Formatted lore with injected stats inserted into the tooltip
*/
private List<Text> processLore(List<String> lore, ItemStack heldItem) {
- Map<String, Map<Rarity, PetNumbers>> petNums = NEURepoManager.NEU_REPO.getConstants().getPetNumbers();
+ Map<String, Map<Rarity, PetNumbers>> petNums = NEURepoManager.getConstants().getPetNumbers();
Rarity rarity = Rarity.values()[getTier()];
PetNumbers data = petNums.get(getName()).get(rarity);
List<Text> formattedLore = new ArrayList<>();
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/searchoverlay/SearchOverManager.java b/src/main/java/de/hysky/skyblocker/skyblock/searchoverlay/SearchOverManager.java
index 721db667..c06e2609 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/searchoverlay/SearchOverManager.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/searchoverlay/SearchOverManager.java
@@ -145,7 +145,7 @@ public class SearchOverManager {
}
//look up id for name
- NEUItem neuItem = NEURepoManager.NEU_REPO.getItems().getItemBySkyblockId(id);
+ NEUItem neuItem = NEURepoManager.getItemByNeuId(id);
if (neuItem != null) {
name = Formatting.strip(neuItem.getDisplayName());
bazaarItems.add(name);
@@ -158,7 +158,7 @@ public class SearchOverManager {
//get auction items
try {
- Set<@NEUId String> essenceCosts = NEURepoManager.NEU_REPO.getConstants().getEssenceCost().getCosts().keySet();
+ Set<@NEUId String> essenceCosts = NEURepoManager.getConstants().getEssenceCost().getCosts().keySet();
if (TooltipInfoType.THREE_DAY_AVERAGE.getData() == null) {
TooltipInfoType.THREE_DAY_AVERAGE.run();
}
@@ -166,7 +166,7 @@ public class SearchOverManager {
String id = entry.getKey();
//look up in NEU repo.
id = id.split("[+-]")[0];
- NEUItem neuItem = NEURepoManager.NEU_REPO.getItems().getItemBySkyblockId(id);
+ NEUItem neuItem = NEURepoManager.getItemByNeuId(id);
if (neuItem != null) {
String name = Formatting.strip(neuItem.getDisplayName());
//add names that are pets to the list of pets to work with the lvl 100 button
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java
index d695bc19..2c4ec4b8 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java
@@ -71,8 +71,8 @@ public class FairySouls {
private static void loadFairySouls() {
fairySoulsLoaded = NEURepoManager.runAsyncAfterLoad(() -> {
- maxSouls = NEURepoManager.NEU_REPO.getConstants().getFairySouls().getMaxSouls();
- NEURepoManager.NEU_REPO.getConstants().getFairySouls().getSoulLocations().forEach((location, fairiesForLocation) -> fairySouls.put(location, fairiesForLocation.stream().map(coordinate -> new BlockPos(coordinate.getX(), coordinate.getY(), coordinate.getZ())).collect(Collectors.toUnmodifiableMap(pos -> pos, pos -> new FairySoul(pos, TYPE_SUPPLIER, ColorUtils.getFloatComponents(DyeColor.GREEN), ColorUtils.getFloatComponents(DyeColor.RED))))));
+ maxSouls = NEURepoManager.getConstants().getFairySouls().getMaxSouls();
+ NEURepoManager.getConstants().getFairySouls().getSoulLocations().forEach((location, fairiesForLocation) -> fairySouls.put(location, fairiesForLocation.stream().map(coordinate -> new BlockPos(coordinate.getX(), coordinate.getY(), coordinate.getZ())).collect(Collectors.toUnmodifiableMap(pos -> pos, pos -> new FairySoul(pos, TYPE_SUPPLIER, ColorUtils.getFloatComponents(DyeColor.GREEN), ColorUtils.getFloatComponents(DyeColor.RED))))));
LOGGER.debug("[Skyblocker] Loaded {} fairy souls across {} locations", fairySouls.values().stream().mapToInt(Map::size).sum(), fairySouls.size());
try (BufferedReader reader = Files.newBufferedReader(SkyblockerMod.CONFIG_DIR.resolve("found_fairy_souls.json"))) {
diff --git a/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java b/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java
index 465a263f..46ff8318 100644
--- a/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java
+++ b/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java
@@ -1,13 +1,20 @@
package de.hysky.skyblocker.utils;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Multimaps;
import com.mojang.brigadier.Command;
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.annotations.Init;
import de.hysky.skyblocker.events.SkyblockEvents;
-import de.hysky.skyblocker.skyblock.itemlist.ItemRepository;
import de.hysky.skyblocker.utils.scheduler.Scheduler;
+import io.github.moulberry.repo.NEUConstants;
import io.github.moulberry.repo.NEURecipeCache;
+import io.github.moulberry.repo.NEURepoFile;
import io.github.moulberry.repo.NEURepository;
+import io.github.moulberry.repo.data.NEUItem;
+import io.github.moulberry.repo.data.NEURecipe;
+import io.github.moulberry.repo.util.NEUId;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.minecraft.client.MinecraftClient;
@@ -15,139 +22,216 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.packet.s2c.play.SynchronizeRecipesS2CPacket;
import net.minecraft.recipe.display.CuttingRecipeDisplay;
import net.minecraft.text.Text;
+import net.minecraft.util.Formatting;
import org.apache.commons.lang3.function.Consumers;
+import org.checkerframework.checker.nullness.qual.Nullable;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.TransportException;
import org.eclipse.jgit.errors.RepositoryNotFoundException;
+import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.concurrent.CompletableFuture;
+import java.util.function.Consumer;
+import java.util.function.Function;
/**
* Initializes the NEU repo, which contains item metadata and fairy souls location data. Clones the repo if it does not exist and checks for updates. Use {@link #runAsyncAfterLoad(Runnable)} to run code after the repo is initialized.
*/
public class NEURepoManager {
- private static final Logger LOGGER = LoggerFactory.getLogger(NEURepoManager.class);
- public static final String REMOTE_REPO_URL = "https://github.com/NotEnoughUpdates/NotEnoughUpdates-REPO.git";
- /**
- * Use {@link #NEU_REPO}.
- */
- private static final Path LOCAL_REPO_DIR = SkyblockerMod.CONFIG_DIR.resolve("item-repo"); // TODO rename to NotEnoughUpdates-REPO
- private static CompletableFuture<Void> REPO_LOADING = loadRepository().thenAccept(Consumers.nop());
- public static final NEURepository NEU_REPO = NEURepository.of(LOCAL_REPO_DIR);
- public static final NEURecipeCache RECIPE_CACHE = NEURecipeCache.forRepo(NEU_REPO);
-
- /**
- * Adds command to update repository manually from ingame.
- * <p></p>
- * TODO A button could be added to the settings menu that will trigger this command.
- */
- @Init
- public static void init() {
- ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) ->
- dispatcher.register(ClientCommandManager.literal(SkyblockerMod.NAMESPACE)
- .then(ClientCommandManager.literal("updateRepository").executes(context -> {
- deleteAndDownloadRepository(context.getSource().getPlayer());
- return Command.SINGLE_SUCCESS;
- }))
- )
- );
- SkyblockEvents.JOIN.register(NEURepoManager::handleRecipeSynchronization);
- }
-
- /**
- * load the recipe manually because Hypixel doesn't send any vanilla recipes to the client
- */
- private static void handleRecipeSynchronization() {
- MinecraftClient client = MinecraftClient.getInstance();
- if (client.world != null && client.getNetworkHandler() != null) {
- //FIXME not sure if we even need this - depends on how REI, EMI, and JEI adapt to the changes
- SynchronizeRecipesS2CPacket packet = new SynchronizeRecipesS2CPacket(Map.of(), CuttingRecipeDisplay.Grouping.empty());
-
- try {
- client.getNetworkHandler().onSynchronizeRecipes(packet);
- } catch (Exception e) {
- LOGGER.info("[Skyblocker NEU Repo] recipe sync error", e);
- }
- }
- }
-
- public static boolean isLoading() {
- return REPO_LOADING != null && !REPO_LOADING.isDone();
- }
-
- private static CompletableFuture<Boolean> loadRepository() {
- return CompletableFuture.supplyAsync(() -> {
- boolean success = true;
- try {
- if (Files.isDirectory(NEURepoManager.LOCAL_REPO_DIR)) {
- try (Git localRepo = Git.open(NEURepoManager.LOCAL_REPO_DIR.toFile())) {
- localRepo.pull().setRebase(true).call();
- LOGGER.info("[Skyblocker NEU Repo] NEU Repository Updated");
- }
- } else {
- Git.cloneRepository().setURI(REMOTE_REPO_URL).setDirectory(NEURepoManager.LOCAL_REPO_DIR.toFile()).setBranchesToClone(List.of("refs/heads/master")).setBranch("refs/heads/master").call().close();
- LOGGER.info("[Skyblocker NEU Repo] NEU Repository Downloaded");
- }
- } catch (TransportException e) {
- LOGGER.error("[Skyblocker NEU Repo] Transport operation failed. Most likely unable to connect to the remote NEU repo on github", e);
- success = false;
- } catch (RepositoryNotFoundException e) {
- LOGGER.warn("[Skyblocker NEU Repo] Local NEU Repository not found or corrupted, downloading new one", e);
- Scheduler.INSTANCE.schedule(() -> deleteAndDownloadRepository(MinecraftClient.getInstance().player), 1);
- success = false;
- } catch (Exception e) {
- LOGGER.error("[Skyblocker NEU Repo] Encountered unknown exception while downloading NEU Repository", e);
- success = false;
- }
-
- try {
- NEU_REPO.reload();
- } catch (Exception e) {
- LOGGER.error("[Skyblocker NEU Repo] Encountered unknown exception while loading NEU Repository", e);
- success = false;
- }
- return success;
-