From b9a4e8f26e90a58a9f635f0f2274cc091784cd83 Mon Sep 17 00:00:00 2001 From: LLytho <29131229+LLytho@users.noreply.github.com> Date: Wed, 13 Jul 2022 21:11:46 +0200 Subject: [PATCH] Handle recipe duplicates --- .../unified/recipe/DuplicateLink.java | 31 ++++++++ .../unified/recipe/RawRecipe.java | 59 +++++++++++++-- .../unified/recipe/RecipeTransformer.java | 74 ++++++++++++++----- 3 files changed, 141 insertions(+), 23 deletions(-) create mode 100644 Common/src/main/java/com/almostreliable/unified/recipe/DuplicateLink.java diff --git a/Common/src/main/java/com/almostreliable/unified/recipe/DuplicateLink.java b/Common/src/main/java/com/almostreliable/unified/recipe/DuplicateLink.java new file mode 100644 index 0000000..b472a55 --- /dev/null +++ b/Common/src/main/java/com/almostreliable/unified/recipe/DuplicateLink.java @@ -0,0 +1,31 @@ +package com.almostreliable.unified.recipe; + +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +public class DuplicateLink { + private RawRecipe currentMaster; + private final Set recipes = new HashSet<>(); + + public DuplicateLink(RawRecipe master) { + updateMaster(master); + } + + void updateMaster(RawRecipe master) { + 4 = {DuplicateLink@28142} Objects.requireNonNull(master); + addDuplicate(master); + this.currentMaster = master; + } + + void addDuplicate(RawRecipe recipe) { + if(recipe == null) { + String s = ""; + } + recipes.add(recipe); + } + + public RawRecipe getMaster() { + return currentMaster; + } +} diff --git a/Common/src/main/java/com/almostreliable/unified/recipe/RawRecipe.java b/Common/src/main/java/com/almostreliable/unified/recipe/RawRecipe.java index 3c1b859..4c9728d 100644 --- a/Common/src/main/java/com/almostreliable/unified/recipe/RawRecipe.java +++ b/Common/src/main/java/com/almostreliable/unified/recipe/RawRecipe.java @@ -1,16 +1,20 @@ package com.almostreliable.unified.recipe; +import com.almostreliable.unified.AlmostUnified; +import com.almostreliable.unified.utils.JsonCompare; import com.google.gson.JsonObject; import net.minecraft.resources.ResourceLocation; import javax.annotation.Nullable; +import java.util.LinkedHashMap; +import java.util.List; import java.util.Objects; public class RawRecipe { private final ResourceLocation id; private final ResourceLocation type; private final JsonObject originalRecipe; - private boolean isDuplicate = false; + @Nullable private DuplicateLink duplicateLink; @Nullable private JsonObject transformedRecipe; @@ -37,17 +41,24 @@ public class RawRecipe { return originalRecipe; } - public void markAsDuplicate() { - isDuplicate = true; + void linkDuplicate(RawRecipe recipe) { + Objects.requireNonNull(recipe); + if(recipe.getDuplicateLink() != null) { + AlmostUnified.LOG.error("Recipe {} already linked", recipe.getId()); + } + + this.duplicateLink = new DuplicateLink(this); + this.duplicateLink.addDuplicate(recipe); } - public boolean isDuplicate() { - return isDuplicate; + @Nullable + public DuplicateLink getDuplicateLink() { + return duplicateLink; } public void setTransformed(JsonObject transformedRecipe) { Objects.requireNonNull(transformedRecipe); - if(isTransformed()) { + if (isTransformed()) { throw new IllegalStateException("Recipe already transformed"); } @@ -62,4 +73,40 @@ public class RawRecipe { public boolean isTransformed() { return transformedRecipe != null; } + + + private List getIgnoredFields() { + return List.of("conditions"); + } + + private LinkedHashMap getRules() { + LinkedHashMap rules = new LinkedHashMap<>(); + rules.put("experience", new JsonCompare.HigherRule()); + rules.put("cookingtime", new JsonCompare.LowerRule()); + return rules; + } + + @Nullable + public RawRecipe compare(RawRecipe toCompare) { + JsonObject selfActual = getTransformed() != null ? getTransformed() : originalRecipe; + JsonObject toCompareActual = toCompare.getTransformed() != null ? toCompare.getTransformed() + : toCompare.getOriginal(); + + if (JsonCompare.matches(selfActual, toCompareActual, getIgnoredFields())) { + JsonObject compare = JsonCompare.compare(getRules(), selfActual, toCompareActual); + if (compare == null) { + return null; + } + + if (compare == selfActual) { + return this; + } + + if (compare == toCompareActual) { + return toCompare; + } + } + + return null; + } } diff --git a/Common/src/main/java/com/almostreliable/unified/recipe/RecipeTransformer.java b/Common/src/main/java/com/almostreliable/unified/recipe/RecipeTransformer.java index e0e1bb7..6452024 100644 --- a/Common/src/main/java/com/almostreliable/unified/recipe/RecipeTransformer.java +++ b/Common/src/main/java/com/almostreliable/unified/recipe/RecipeTransformer.java @@ -9,9 +9,9 @@ import com.google.gson.JsonPrimitive; import net.minecraft.resources.ResourceLocation; import javax.annotation.Nullable; -import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentMap; import java.util.stream.Collectors; @@ -50,26 +50,28 @@ public class RecipeTransformer { recipeTransformationResult.track(curRecipe.getId(), curRecipe.getOriginal(), result); // TODO remove curRecipe.setTransformed(result); - - for (int compareIndex = 0; compareIndex < curIndex; compareIndex++) { // TODO extract - RawRecipe toCompare = rawRecipes.get(compareIndex); - if(toCompare.isDuplicate()) continue; - JsonObject json = toCompare.isTransformed() ? toCompare.getTransformed() : toCompare.getOriginal(); - if(result.equals(json)) { // TODO replace with cool equal which has additional compare rules - toCompare.markAsDuplicate(); - } - } + handleDuplicate(curRecipe, rawRecipes); } } + + List duplicateLinks = rawRecipes + .stream() + .map(RawRecipe::getDuplicateLink) + .filter(Objects::nonNull) + .distinct() + .toList(); + + String s = ""; }); - Map> duplicates = new HashMap<>(); - rawRecipesByType.forEach((type, rawRecipes) -> { - List duplicatesForType = rawRecipes.stream().filter(RawRecipe::isDuplicate).collect(Collectors.toList()); - if(!duplicatesForType.isEmpty()) { - duplicates.put(type, duplicatesForType); - } - }); +// Map> duplicates = new HashMap<>(); + +// rawRecipesByType.forEach((type, rawRecipes) -> { +// List duplicatesForType = rawRecipes.stream().filter(RawRecipe::isDuplicate).collect(Collectors.toList()); +// if(!duplicatesForType.isEmpty()) { +// duplicates.put(type, duplicatesForType); +// } +// }); recipeTransformationResult.end(); @@ -89,6 +91,43 @@ public class RecipeTransformer { return recipeTransformationResult; } + private void handleDuplicate(RawRecipe curRecipe, List rawRecipes) { + if(curRecipe.getDuplicateLink() != null) { + AlmostUnified.LOG.error("Duplication already handled for recipe {}", curRecipe.getId()); + return; + } + + for (RawRecipe rawRecipe : rawRecipes) { + if (rawRecipe == curRecipe) { + return; + } + + if (handleDuplicate(curRecipe, rawRecipe)) { + return; + } + } + } + + private boolean handleDuplicate(RawRecipe curRecipe, RawRecipe rawRecipe) { + DuplicateLink link = rawRecipe.getDuplicateLink(); + if(link != null) { + RawRecipe master = link.getMaster(); + RawRecipe compare = curRecipe.compare(master); + if(compare != null) { + link.updateMaster(compare); + return true; + } + } else { + RawRecipe compare = curRecipe.compare(rawRecipe); + if(compare != null) { + rawRecipe.linkDuplicate(compare); + return true; + } + } + return false; + } + + @Nullable public JsonObject transformRecipe(ResourceLocation recipeId, JsonObject json) { try { @@ -107,4 +146,5 @@ public class RecipeTransformer { } return null; } + }