diff --git a/CHANGELOG.md b/CHANGELOG.md index 8666136..4bb254d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,12 +2,23 @@ All notable changes to this project will be documented in this file. -The format is based on [Keep a Changelog], -and this project adheres to [Semantic Versioning]. - ## Unreleased - / +## [1.2.2] - 2024-10-23 + +- fixed crash on empty recipe JSONs + +## [1.2.1] - 2024-10-22 + +- added logging for cases where items are assigned to multiple unification tags +- added logging for cases where the recipe type can't be found +- added skipping logic for recipes with invalid recipe types +- added Turkish translation ([#102](https://github.com/AlmostReliable/almostunified/pull/102)) +- fixed crash when runtime isn't loaded ([#101](https://github.com/AlmostReliable/almostunified/issues/101)) +- fixed newly created custom tags not being considered for unification +- fixed runtime not being available when items are assigned to multiple unification tags + ## [1.2.0] - 2024-10-06 - added support for custom ingredient types @@ -32,11 +43,9 @@ and this project adheres to [Semantic Versioning]. Initial 1.21.1 port. - -[keep a changelog]: https://keepachangelog.com/en/1.0.0/ -[semantic versioning]: https://semver.org/spec/v2.0.0.html - +[1.2.2]: https://github.com/AlmostReliable/almostunified/releases/tag/v1.21.1-1.2.2 +[1.2.1]: https://github.com/AlmostReliable/almostunified/releases/tag/v1.21.1-1.2.1 [1.2.0]: https://github.com/AlmostReliable/almostunified/releases/tag/v1.21.1-1.2.0 [1.1.0]: https://github.com/AlmostReliable/almostunified/releases/tag/v1.21.1-1.1.0 [1.0.0]: https://github.com/AlmostReliable/almostunified/releases/tag/v1.21.1-1.0.0 diff --git a/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedCommon.java b/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedCommon.java index d944220..78a5c98 100644 --- a/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedCommon.java +++ b/Common/src/main/java/com/almostreliable/unified/AlmostUnifiedCommon.java @@ -46,12 +46,12 @@ public final class AlmostUnifiedCommon { } public static void onRecipeManagerError(ResourceLocation recipe) { - assert RUNTIME != null; + if (RUNTIME == null) return; RUNTIME.getDebugHandler().collectRecipeError(recipe); } public static void onRecipeManagerEnd() { - assert RUNTIME != null; + if (RUNTIME == null) return; RUNTIME.getDebugHandler().finish(); } } diff --git a/Common/src/main/java/com/almostreliable/unified/core/AlmostUnifiedRuntimeImpl.java b/Common/src/main/java/com/almostreliable/unified/core/AlmostUnifiedRuntimeImpl.java index 16bb2a5..d9c73eb 100644 --- a/Common/src/main/java/com/almostreliable/unified/core/AlmostUnifiedRuntimeImpl.java +++ b/Common/src/main/java/com/almostreliable/unified/core/AlmostUnifiedRuntimeImpl.java @@ -76,12 +76,7 @@ public final class AlmostUnifiedRuntimeImpl implements AlmostUnifiedRuntime { var tagConfig = Config.load(TagConfig.NAME, TagConfig.SERIALIZER); var unificationConfigs = UnificationConfig.safeLoadConfigs(); - var unificationTags = bakeAndValidateTags( - unificationConfigs, - itemTags, - placeholderConfig, - debugConfig.shouldLogInvalidTags() - ); + TagReloadHandler.applyCustomTags(tagConfig.getCustomTags(), itemTags); CustomIngredientUnifierRegistry ingredientUnifierRegistry = new CustomIngredientUnifierRegistryImpl(); PluginManager.instance().registerCustomIngredientUnifiers(ingredientUnifierRegistry); @@ -89,7 +84,13 @@ public final class AlmostUnifiedRuntimeImpl implements AlmostUnifiedRuntime { PluginManager.instance().registerRecipeUnifiers(recipeUnifierRegistry); // TODO: add plugin support for registering config defaults - TagReloadHandler.applyCustomTags(tagConfig.getCustomTags(), itemTags); + var unificationTags = bakeAndValidateTags( + unificationConfigs, + itemTags, + placeholderConfig, + debugConfig.shouldLogInvalidTags() + ); + TagSubstitutionsImpl tagSubstitutions = TagSubstitutionsImpl.create( itemTags::has, unificationTags::contains, diff --git a/Common/src/main/java/com/almostreliable/unified/unification/UnificationLookupImpl.java b/Common/src/main/java/com/almostreliable/unified/unification/UnificationLookupImpl.java index e7041cd..991489a 100644 --- a/Common/src/main/java/com/almostreliable/unified/unification/UnificationLookupImpl.java +++ b/Common/src/main/java/com/almostreliable/unified/unification/UnificationLookupImpl.java @@ -7,6 +7,7 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.crafting.Ingredient; +import com.almostreliable.unified.AlmostUnifiedCommon; import com.almostreliable.unified.api.unification.ModPriorities; import com.almostreliable.unified.api.unification.StoneVariants; import com.almostreliable.unified.api.unification.TagSubstitutions; @@ -117,15 +118,22 @@ public final class UnificationLookupImpl implements UnificationLookup { public static class Builder { - private final Set> createdEntries = new HashSet<>(); + private final Map, TagKey> entriesToTags = new HashMap<>(); private final Map, Set>> tagsToEntries = new HashMap<>(); private void put(TagKey tag, UnificationEntry entry) { - if (createdEntries.contains(entry)) { - throw new IllegalStateException("entry " + entry + " already created"); + if (entriesToTags.containsKey(entry)) { + var boundTag = entriesToTags.get(entry); + AlmostUnifiedCommon.LOGGER.error( + "Unification entry for item '{}' with tag '#{}' is already part of tag '#{}'.", + entry.id(), + tag.location(), + boundTag.location() + ); + return; } - createdEntries.add(entry); + entriesToTags.put(entry, tag); tagsToEntries.computeIfAbsent(tag, $ -> new HashSet<>()).add(entry); } diff --git a/Common/src/main/java/com/almostreliable/unified/unification/recipe/RecipeJsonImpl.java b/Common/src/main/java/com/almostreliable/unified/unification/recipe/RecipeJsonImpl.java index 5a40cae..6246fe0 100644 --- a/Common/src/main/java/com/almostreliable/unified/unification/recipe/RecipeJsonImpl.java +++ b/Common/src/main/java/com/almostreliable/unified/unification/recipe/RecipeJsonImpl.java @@ -28,7 +28,7 @@ public class RecipeJsonImpl implements RecipeJson { try { return ResourceLocation.parse(json.get("type").getAsString()); } catch (Exception e) { - throw new IllegalArgumentException("could not detect recipe type"); + throw new IllegalArgumentException("could not detect recipe type for recipe " + id); } } diff --git a/Common/src/main/java/com/almostreliable/unified/unification/recipe/RecipeLink.java b/Common/src/main/java/com/almostreliable/unified/unification/recipe/RecipeLink.java index 3300248..bd49962 100644 --- a/Common/src/main/java/com/almostreliable/unified/unification/recipe/RecipeLink.java +++ b/Common/src/main/java/com/almostreliable/unified/unification/recipe/RecipeLink.java @@ -2,6 +2,7 @@ package com.almostreliable.unified.unification.recipe; import net.minecraft.resources.ResourceLocation; +import com.almostreliable.unified.AlmostUnifiedCommon; import com.almostreliable.unified.api.unification.recipe.RecipeData; import com.almostreliable.unified.utils.JsonCompare; @@ -17,7 +18,7 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -public class RecipeLink implements RecipeData { +public final class RecipeLink implements RecipeData { /** * This cache is an optimization to avoid creating many ResourceLocations for just a few different types. * Having fewer ResourceLocation instances can greatly speed up equality checking when these are used as map keys. @@ -30,15 +31,30 @@ public class RecipeLink implements RecipeData { @Nullable private DuplicateLink duplicateLink; @Nullable private JsonObject unifiedRecipe; - public RecipeLink(ResourceLocation id, JsonObject originalRecipe) { + private RecipeLink(ResourceLocation id, JsonObject originalRecipe, ResourceLocation type) { this.id = id; this.originalRecipe = originalRecipe; + this.type = type; + } + @Nullable + public static RecipeLink of(ResourceLocation id, JsonObject originalRecipe) { + try { + ResourceLocation type = ResourceLocation.parse(originalRecipe.get("type").getAsString()); + return new RecipeLink(id, originalRecipe, type); + } catch (Exception e) { + AlmostUnifiedCommon.LOGGER.warn("Could not detect recipe type for recipe '{}', skipping.", id); + return null; + } + } + + public static RecipeLink ofOrThrow(ResourceLocation id, JsonObject originalRecipe) { try { String typeString = originalRecipe.get("type").getAsString(); - this.type = PARSED_TYPE_CACHE.computeIfAbsent(typeString, ResourceLocation::parse); + ResourceLocation type = PARSED_TYPE_CACHE.computeIfAbsent(typeString, ResourceLocation::parse); + return new RecipeLink(id, originalRecipe, type); } catch (Exception e) { - throw new IllegalArgumentException("could not detect recipe type"); + throw new IllegalArgumentException("could not detect recipe type for recipe " + id); } } diff --git a/Common/src/main/java/com/almostreliable/unified/unification/recipe/RecipeTransformer.java b/Common/src/main/java/com/almostreliable/unified/unification/recipe/RecipeTransformer.java index 3579082..b53b93c 100644 --- a/Common/src/main/java/com/almostreliable/unified/unification/recipe/RecipeTransformer.java +++ b/Common/src/main/java/com/almostreliable/unified/unification/recipe/RecipeTransformer.java @@ -31,6 +31,7 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.function.Consumer; import java.util.stream.Collectors; @@ -111,7 +112,9 @@ public class RecipeTransformer { return recipes .entrySet() .stream() - .map(entry -> new RecipeLink(entry.getKey(), entry.getValue().getAsJsonObject())) + .filter(entry -> entry.getValue() instanceof JsonObject jsonObject && !jsonObject.isEmpty()) + .map(entry -> RecipeLink.of(entry.getKey(), entry.getValue().getAsJsonObject())) + .filter(Objects::nonNull) .sorted(Comparator.comparing(entry -> entry.getId().toString())) .collect(Collectors.groupingByConcurrent(RecipeLink::getType)); } diff --git a/Common/src/main/resources/assets/almostunified/lang/tr_tr.json b/Common/src/main/resources/assets/almostunified/lang/tr_tr.json new file mode 100644 index 0000000..a0bb5b3 --- /dev/null +++ b/Common/src/main/resources/assets/almostunified/lang/tr_tr.json @@ -0,0 +1,8 @@ +{ + "almostunified.description": "Almost Unified tarafından değiştirildi!", + "almostunified.warning": "Tarif sorunlarını orijinal sahibine bildirmeyin.", + "almostunified.unified": "Birleştirilmiş", + "almostunified.duplicate": "Kopyaları Vardı", + "almostunified.yes": "Evet", + "almostunified.no": "Hayır" +} diff --git a/Common/src/test/java/testmod/TestUtils.java b/Common/src/test/java/testmod/TestUtils.java index e5b5728..c68f7fc 100644 --- a/Common/src/test/java/testmod/TestUtils.java +++ b/Common/src/test/java/testmod/TestUtils.java @@ -83,11 +83,11 @@ public class TestUtils { public static RecipeLink recipe(String jsonStr) { var json = json(jsonStr); - return new RecipeLink(ResourceLocation.parse("test"), json); + return RecipeLink.ofOrThrow(ResourceLocation.parse("test"), json); } public static RecipeLink recipe(JsonObject json) { - return new RecipeLink(ResourceLocation.parse("test"), json); + return RecipeLink.ofOrThrow(ResourceLocation.parse("test"), json); } public static JsonObject json(String json) { diff --git a/gradle.properties b/gradle.properties index 36e2d42..fcb305f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ enableAccessWidener = false minecraftVersion = 1.21.1 # Mod -modVersion = 1.2.0 +modVersion = 1.2.2 modPackage = com.almostreliable.unified modId = almostunified modName = AlmostUnified