diff --git a/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedRuntimeImpl.java b/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedRuntimeImpl.java index 7ca8e3d..ccd64fe 100644 --- a/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedRuntimeImpl.java +++ b/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedRuntimeImpl.java @@ -7,9 +7,9 @@ import com.almostreliable.unified.config.UnifyConfig; import com.almostreliable.unified.recipe.RecipeDumper; import com.almostreliable.unified.recipe.RecipeTransformer; import com.almostreliable.unified.recipe.unifier.RecipeHandlerFactory; -import com.almostreliable.unified.utils.MissingRecipesDumper; import com.almostreliable.unified.utils.ReplacementMap; import com.almostreliable.unified.utils.TagMap; +import com.almostreliable.unified.utils.UncoveredRecipesDumper; import com.google.gson.JsonElement; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.Item; @@ -56,7 +56,10 @@ public final class AlmostUnifiedRuntimeImpl implements AlmostUnifiedRuntime { dumper.dump(debugConfig.dumpOverview, debugConfig.dumpUnification, debugConfig.dumpDuplicates); debugConfig.logRecipes(recipes, "recipes_after_unification.txt"); - MissingRecipesDumper.write(this, debugConfig.dumpPotentialMissingRecipes, recipes); + + if (debugConfig.dumpUncoveredRecipes) { + UncoveredRecipesDumper.write(recipes); + } } @Override diff --git a/Common/src/main/java/com/almostreliable/unified/compat/AlmostEMI.java b/Common/src/main/java/com/almostreliable/unified/compat/AlmostEMI.java index 879bed3..4761b2f 100644 --- a/Common/src/main/java/com/almostreliable/unified/compat/AlmostEMI.java +++ b/Common/src/main/java/com/almostreliable/unified/compat/AlmostEMI.java @@ -45,7 +45,7 @@ public class AlmostEMI implements EmiPlugin { .orElse(false); if (emiDisabled) return; - for (ItemStack item : HideHelper.createHidingList(AlmostUnified.getRuntime())) { + for (ItemStack item : HideHelper.getStacksToHide()) { registry.removeEmiStacks(EmiStack.of(item)); } } diff --git a/Common/src/main/java/com/almostreliable/unified/compat/AlmostJEI.java b/Common/src/main/java/com/almostreliable/unified/compat/AlmostJEI.java index 1d004f0..e415a6c 100644 --- a/Common/src/main/java/com/almostreliable/unified/compat/AlmostJEI.java +++ b/Common/src/main/java/com/almostreliable/unified/compat/AlmostJEI.java @@ -42,7 +42,7 @@ public class AlmostJEI implements IModPlugin { .orElse(false); if (jeiDisabled) return; - Collection items = HideHelper.createHidingList(AlmostUnified.getRuntime()); + Collection items = HideHelper.getStacksToHide(); if (!items.isEmpty()) { jei.getIngredientManager().removeIngredientsAtRuntime(VanillaTypes.ITEM_STACK, items); } diff --git a/Common/src/main/java/com/almostreliable/unified/compat/AlmostREI.java b/Common/src/main/java/com/almostreliable/unified/compat/AlmostREI.java index 1cd158e..e0b5132 100644 --- a/Common/src/main/java/com/almostreliable/unified/compat/AlmostREI.java +++ b/Common/src/main/java/com/almostreliable/unified/compat/AlmostREI.java @@ -55,7 +55,7 @@ public class AlmostREI implements REIClientPlugin { .orElse(false); if (reiDisabled) return List.of(); - return EntryIngredients.ofItemStacks(HideHelper.createHidingList(AlmostUnified.getRuntime())); + return EntryIngredients.ofItemStacks(HideHelper.getStacksToHide()); }); } diff --git a/Common/src/main/java/com/almostreliable/unified/compat/HideHelper.java b/Common/src/main/java/com/almostreliable/unified/compat/HideHelper.java index ba8318a..c36e7fd 100644 --- a/Common/src/main/java/com/almostreliable/unified/compat/HideHelper.java +++ b/Common/src/main/java/com/almostreliable/unified/compat/HideHelper.java @@ -4,122 +4,110 @@ import com.almostreliable.unified.AlmostUnified; import com.almostreliable.unified.AlmostUnifiedRuntime; import com.almostreliable.unified.utils.ReplacementMap; import com.almostreliable.unified.utils.TagOwnerships; +import com.almostreliable.unified.utils.UnifyTag; import com.almostreliable.unified.utils.Utils; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; +import java.util.List; import java.util.Set; -import java.util.stream.Collectors; public final class HideHelper { private HideHelper() {} - public static Collection createHidingList(AlmostUnifiedRuntime runtime) { + public static Multimap, ResourceLocation> createHidingMap() { + AlmostUnifiedRuntime runtime = AlmostUnified.getRuntime(); ReplacementMap repMap = runtime.getReplacementMap().orElse(null); var tagMap = runtime.getFilteredTagMap().orElse(null); - if (repMap == null || tagMap == null) return new ArrayList<>(); - - Set hidingList = new HashSet<>(); + Multimap, ResourceLocation> hidingMap = HashMultimap.create(); + if (repMap == null || tagMap == null) return hidingMap; + TagOwnerships ownerships = repMap.getTagOwnerships(); for (var unifyTag : tagMap.getTags()) { var itemsByTag = tagMap.getEntriesByTag(unifyTag); - - // avoid handling single entries and tags that only contain the same namespace for all items if (Utils.allSameNamespace(itemsByTag)) continue; - Set replacements = new HashSet<>(); - for (ResourceLocation item : itemsByTag) { - replacements.add(getReplacementForItem(repMap, item)); - } + ResourceLocation preferredItem = repMap.getPreferredItemForTag(unifyTag, $ -> true); + if (preferredItem == null) continue; - Set toHide = new HashSet<>(); - for (ResourceLocation item : itemsByTag) { - if (!replacements.contains(item)) { - toHide.add(item); - } - } + Set itemsToHide = getItemsToHide(unifyTag, itemsByTag, preferredItem); + if (itemsToHide == null) continue; + hidingMap.putAll(unifyTag, itemsToHide); - if (toHide.isEmpty()) continue; - - AlmostUnified.LOG.info( - "[AutoHiding] Hiding {}/{} items for tag '#{}' -> {}", - toHide.size(), - itemsByTag.size(), - unifyTag.location(), - toHide - ); - - hidingList.addAll(toHide); + Set refItemsToHide = getRefItemsToHide(unifyTag, ownerships, preferredItem); + hidingMap.putAll(unifyTag, refItemsToHide); } - hidingList.addAll(getRefItems(repMap)); - - return hidingList - .stream() - .flatMap(rl -> BuiltInRegistries.ITEM.getOptional(rl).stream()) - .map(ItemStack::new) - .collect(Collectors.toList()); + return hidingMap; } - /** - * Returns the replacement for the given item, or the item itself if no replacement is found. - *

- * Returning the item itself is important for stone strata detection. - * - * @param repMap The replacement map. - * @param item The item to get the replacement for. - * @return The replacement for the given item, or the item itself if no replacement is found. - */ - private static ResourceLocation getReplacementForItem(ReplacementMap repMap, ResourceLocation item) { - var replacement = repMap.getReplacementForItem(item); - if (replacement == null) return item; - return replacement; + @Nullable + private static Set getItemsToHide(UnifyTag unifyTag, Set itemsByTag, ResourceLocation preferredItem) { + Set itemsToHide = new HashSet<>(); + for (ResourceLocation item : itemsByTag) { + if (!item.equals(preferredItem)) { + itemsToHide.add(item); + } + } + + if (itemsToHide.isEmpty()) return null; + + AlmostUnified.LOG.info( + "[AutoHiding] Hiding {}/{} items for tag '#{}' -> {}", + itemsToHide.size(), + itemsByTag.size(), + unifyTag.location(), + itemsToHide + ); + return itemsToHide; } - /** - * Returns a set of all items that are contained in the reference tags. - * - * @return A set of all items that are contained in the reference tags. - */ - private static Set getRefItems(ReplacementMap repMap) { - Set hidingList = new HashSet<>(); - TagOwnerships ownerships = repMap.getTagOwnerships(); + private static Set getRefItemsToHide(UnifyTag unifyTag, TagOwnerships ownerships, ResourceLocation preferredItem) { + var refTags = ownerships.getRefsByOwner(unifyTag); + Set refItemsToHide = new HashSet<>(); - ownerships.getRefs().forEach(ref -> { - var owner = ownerships.getOwnerByTag(ref); - assert owner != null; + for (var refTag : refTags) { + var asTagKey = TagKey.create(Registries.ITEM, refTag.location()); - var dominantItem = repMap.getPreferredItemForTag(owner, $ -> true); - - TagKey asTagKey = TagKey.create(Registries.ITEM, ref.location()); - Set refItems = new HashSet<>(); BuiltInRegistries.ITEM.getTagOrEmpty(asTagKey).forEach(holder -> { ResourceLocation item = BuiltInRegistries.ITEM.getKey(holder.value()); - if (item.equals(dominantItem)) return; // don't hide if the item is a dominant one - refItems.add(item); + if (item.equals(preferredItem)) return; + refItemsToHide.add(item); }); - if (refItems.isEmpty()) return; + if (refItemsToHide.isEmpty()) continue; AlmostUnified.LOG.info( "[AutoHiding] Hiding reference tag '#{}' of owner tag '#{}' -> {}", - ref.location(), - owner.location(), - refItems + refTag.location(), + unifyTag.location(), + refItemsToHide ); + } - hidingList.addAll(refItems); - }); + return refItemsToHide; + } - return hidingList; + public static Collection getStacksToHide() { + var hidingMap = createHidingMap(); + if (hidingMap.isEmpty()) return List.of(); + + return hidingMap + .entries() + .stream() + .flatMap(rl -> BuiltInRegistries.ITEM.getOptional(rl.getValue()).stream()) + .map(ItemStack::new) + .toList(); } } diff --git a/Common/src/main/java/com/almostreliable/unified/config/DebugConfig.java b/Common/src/main/java/com/almostreliable/unified/config/DebugConfig.java index 82b275e..a1387ea 100644 --- a/Common/src/main/java/com/almostreliable/unified/config/DebugConfig.java +++ b/Common/src/main/java/com/almostreliable/unified/config/DebugConfig.java @@ -21,15 +21,15 @@ public class DebugConfig extends Config { public final boolean dumpUnification; public final boolean dumpOverview; public final boolean dumpRecipes; - public final boolean dumpPotentialMissingRecipes; + public final boolean dumpUncoveredRecipes; - public DebugConfig(boolean dumpTagMap, boolean dumpDuplicates, boolean dumpUnification, boolean dumpOverview, boolean dumpRecipes, boolean dumpPotentialMissingRecipes) { + public DebugConfig(boolean dumpTagMap, boolean dumpDuplicates, boolean dumpUnification, boolean dumpOverview, boolean dumpRecipes, boolean dumpUncoveredRecipes) { this.dumpTagMap = dumpTagMap; this.dumpDuplicates = dumpDuplicates; this.dumpUnification = dumpUnification; this.dumpOverview = dumpOverview; this.dumpRecipes = dumpRecipes; - this.dumpPotentialMissingRecipes = dumpPotentialMissingRecipes; + this.dumpUncoveredRecipes = dumpUncoveredRecipes; } public void logUnifyTagDump(TagMap tagMap) { @@ -73,7 +73,7 @@ public class DebugConfig extends Config { public static final String DUMP_UNIFICATION = "dumpUnification"; public static final String DUMP_OVERVIEW = "dumpOverview"; public static final String DUMP_RECIPES = "dumpRecipes"; - public static final String DUMP_POTENTIAL_MISSING_RECIPES = "dumpPotentialMissingRecipes"; + public static final String DUMP_UNCOVERED_RECIPES = "dumpUncoveredRecipes"; @Override public DebugConfig deserialize(JsonObject json) { @@ -83,7 +83,7 @@ public class DebugConfig extends Config { safeGet(() -> json.get(DUMP_UNIFICATION).getAsBoolean(), false), safeGet(() -> json.get(DUMP_OVERVIEW).getAsBoolean(), false), safeGet(() -> json.get(DUMP_RECIPES).getAsBoolean(), false), - safeGet(() -> json.get(DUMP_POTENTIAL_MISSING_RECIPES).getAsBoolean(), false) + safeGet(() -> json.get(DUMP_UNCOVERED_RECIPES).getAsBoolean(), false) ); } @@ -95,7 +95,7 @@ public class DebugConfig extends Config { json.addProperty(DUMP_UNIFICATION, src.dumpUnification); json.addProperty(DUMP_OVERVIEW, src.dumpOverview); json.addProperty(DUMP_RECIPES, src.dumpRecipes); - json.addProperty(DUMP_POTENTIAL_MISSING_RECIPES, src.dumpPotentialMissingRecipes); + json.addProperty(DUMP_UNCOVERED_RECIPES, src.dumpUncoveredRecipes); return json; } } diff --git a/Common/src/main/java/com/almostreliable/unified/utils/MissingRecipesDumper.java b/Common/src/main/java/com/almostreliable/unified/utils/MissingRecipesDumper.java deleted file mode 100644 index 1b19892..0000000 --- a/Common/src/main/java/com/almostreliable/unified/utils/MissingRecipesDumper.java +++ /dev/null @@ -1,95 +0,0 @@ -package com.almostreliable.unified.utils; - -import com.almostreliable.unified.AlmostUnifiedPlatform; -import com.almostreliable.unified.AlmostUnifiedRuntime; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.item.Item; - -import java.util.HashSet; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -public class MissingRecipesDumper { - - public static void write(AlmostUnifiedRuntime runtime, boolean dumpPotentialMissingRecipes, Map recipes) { - if (!dumpPotentialMissingRecipes) return; - - var itemsPerTag = getHidingIds(runtime); - FileUtils.write(AlmostUnifiedPlatform.INSTANCE.getLogPath(), "recipe_hiding_check.txt", sb -> { - recipes.forEach(((recipe, json) -> { - if (json instanceof JsonObject obj) { - write(recipe, obj, itemsPerTag, sb); - } - })); - }); - } - - private static void write(ResourceLocation recipe, JsonObject json, Multimap, ResourceLocation> itemsPerTag, StringBuilder sb) { - String jsonStr = json.toString(); - Multimap, ResourceLocation> found = HashMultimap.create(); - itemsPerTag.asMap().forEach((tag, items) -> { - for (ResourceLocation item : items) { - if (jsonStr.contains(item.toString())) { - found.put(tag, item); - } - } - }); - - if (found.isEmpty()) return; - - String type = Optional.ofNullable(json.get("type")).map(JsonElement::getAsString).orElse(""); - sb - .append("Recipe ") - .append(recipe) - .append(" (") - .append(type) - .append(") contains potentially hiding items:") - .append("\n") - .append("Json: ") - .append(jsonStr) - .append("\n") - .append("Items: ") - .append("\n"); - found.asMap().forEach((tag, items) -> { - for (ResourceLocation item : items) { - sb.append("\t").append(item).append(" (#").append(tag.location()).append(")").append("\n"); - } - }); - - sb.append("\n"); - } - - - public static Multimap, ResourceLocation> getHidingIds(AlmostUnifiedRuntime runtime) { - ReplacementMap repMap = runtime.getReplacementMap().orElse(null); - var tagMap = runtime.getFilteredTagMap().orElse(null); - - Multimap, ResourceLocation> hidings = HashMultimap.create(); - if (repMap == null || tagMap == null) return hidings; - - for (var unifyTag : tagMap.getTags()) { - var itemsByTag = tagMap.getEntriesByTag(unifyTag); - - if (Utils.allSameNamespace(itemsByTag)) continue; - - ResourceLocation kingItem = repMap.getPreferredItemForTag(unifyTag, $ -> true); - if (kingItem == null) continue; - - Set r = new HashSet<>(); - for (ResourceLocation item : itemsByTag) { - if (!item.equals(kingItem)) { - r.add(item); - } - } - - hidings.putAll(unifyTag, r); - } - - return hidings; - } -} diff --git a/Common/src/main/java/com/almostreliable/unified/utils/TagOwnerships.java b/Common/src/main/java/com/almostreliable/unified/utils/TagOwnerships.java index bc72299..26d1a4b 100644 --- a/Common/src/main/java/com/almostreliable/unified/utils/TagOwnerships.java +++ b/Common/src/main/java/com/almostreliable/unified/utils/TagOwnerships.java @@ -134,11 +134,12 @@ public class TagOwnerships { } /** - * Gets all reference tags for all owner tags. + * Gets all reference tags for the provided owner tag. * - * @return A set of all reference tags. + * @param tag The owner tag to get the references for. + * @return A collection of all reference tags. */ - public Set> getRefs() { - return refsToOwner.keySet(); + public Collection> getRefsByOwner(UnifyTag tag) { + return ownerToRefs.get(tag); } } diff --git a/Common/src/main/java/com/almostreliable/unified/utils/UncoveredRecipesDumper.java b/Common/src/main/java/com/almostreliable/unified/utils/UncoveredRecipesDumper.java new file mode 100644 index 0000000..8f6249b --- /dev/null +++ b/Common/src/main/java/com/almostreliable/unified/utils/UncoveredRecipesDumper.java @@ -0,0 +1,57 @@ +package com.almostreliable.unified.utils; + +import com.almostreliable.unified.AlmostUnifiedPlatform; +import com.almostreliable.unified.compat.HideHelper; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; + +import java.util.Map; +import java.util.Optional; + +public final class UncoveredRecipesDumper { + + private UncoveredRecipesDumper() {} + + public static void write(Map recipes) { + var hidingMap = HideHelper.createHidingMap(); + FileUtils.write(AlmostUnifiedPlatform.INSTANCE.getLogPath(), "uncovered_recipes.txt", sb -> { + recipes.forEach((recipeId, json) -> { + if (json instanceof JsonObject obj) { + write(recipeId, obj, hidingMap, sb); + } + }); + }); + } + + private static void write(ResourceLocation recipeId, JsonObject json, Multimap, ResourceLocation> hidingMap, StringBuilder sb) { + String jsonStr = json.toString(); + Multimap, ResourceLocation> foundEntries = HashMultimap.create(); + hidingMap.asMap().forEach((tag, items) -> { + for (ResourceLocation item : items) { + if (jsonStr.contains(item.toString())) { + foundEntries.put(tag, item); + } + } + }); + + if (foundEntries.isEmpty()) return; + + String type = Optional.ofNullable(json.get("type")).map(JsonElement::getAsString).orElse(""); + sb + .append("Id: ").append(recipeId).append("\n") + .append("Type: ").append(type).append("\n") + .append("Json: ").append(jsonStr).append("\n") + .append("Items: ").append("\n"); + foundEntries.asMap().forEach((tag, items) -> { + for (ResourceLocation item : items) { + sb.append("\t").append(item).append(" (#").append(tag.location()).append(")").append("\n"); + } + }); + + sb.append("\n"); + } +}