Handle recipe duplicates

This commit is contained in:
LLytho 2022-07-13 21:11:46 +02:00
parent 004b84290a
commit b9a4e8f26e
3 changed files with 141 additions and 23 deletions

View file

@ -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<RawRecipe> 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;
}
}

View file

@ -1,16 +1,20 @@
package com.almostreliable.unified.recipe; package com.almostreliable.unified.recipe;
import com.almostreliable.unified.AlmostUnified;
import com.almostreliable.unified.utils.JsonCompare;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects; import java.util.Objects;
public class RawRecipe { public class RawRecipe {
private final ResourceLocation id; private final ResourceLocation id;
private final ResourceLocation type; private final ResourceLocation type;
private final JsonObject originalRecipe; private final JsonObject originalRecipe;
private boolean isDuplicate = false; @Nullable private DuplicateLink duplicateLink;
@Nullable private JsonObject transformedRecipe; @Nullable private JsonObject transformedRecipe;
@ -37,17 +41,24 @@ public class RawRecipe {
return originalRecipe; return originalRecipe;
} }
public void markAsDuplicate() { void linkDuplicate(RawRecipe recipe) {
isDuplicate = true; 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() { @Nullable
return isDuplicate; public DuplicateLink getDuplicateLink() {
return duplicateLink;
} }
public void setTransformed(JsonObject transformedRecipe) { public void setTransformed(JsonObject transformedRecipe) {
Objects.requireNonNull(transformedRecipe); Objects.requireNonNull(transformedRecipe);
if(isTransformed()) { if (isTransformed()) {
throw new IllegalStateException("Recipe already transformed"); throw new IllegalStateException("Recipe already transformed");
} }
@ -62,4 +73,40 @@ public class RawRecipe {
public boolean isTransformed() { public boolean isTransformed() {
return transformedRecipe != null; return transformedRecipe != null;
} }
private List<String> getIgnoredFields() {
return List.of("conditions");
}
private LinkedHashMap<String, JsonCompare.Rule> getRules() {
LinkedHashMap<String, JsonCompare.Rule> 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;
}
} }

View file

@ -9,9 +9,9 @@ import com.google.gson.JsonPrimitive;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -50,26 +50,28 @@ public class RecipeTransformer {
recipeTransformationResult.track(curRecipe.getId(), curRecipe.getOriginal(), result); // TODO remove recipeTransformationResult.track(curRecipe.getId(), curRecipe.getOriginal(), result); // TODO remove
curRecipe.setTransformed(result); curRecipe.setTransformed(result);
handleDuplicate(curRecipe, rawRecipes);
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();
}
}
} }
} }
List<DuplicateLink> duplicateLinks = rawRecipes
.stream()
.map(RawRecipe::getDuplicateLink)
.filter(Objects::nonNull)
.distinct()
.toList();
String s = "";
}); });
Map<ResourceLocation, List<RawRecipe>> duplicates = new HashMap<>(); // Map<ResourceLocation, List<RawRecipe>> duplicates = new HashMap<>();
rawRecipesByType.forEach((type, rawRecipes) -> {
List<RawRecipe> duplicatesForType = rawRecipes.stream().filter(RawRecipe::isDuplicate).collect(Collectors.toList()); // rawRecipesByType.forEach((type, rawRecipes) -> {
if(!duplicatesForType.isEmpty()) { // List<RawRecipe> duplicatesForType = rawRecipes.stream().filter(RawRecipe::isDuplicate).collect(Collectors.toList());
duplicates.put(type, duplicatesForType); // if(!duplicatesForType.isEmpty()) {
} // duplicates.put(type, duplicatesForType);
}); // }
// });
recipeTransformationResult.end(); recipeTransformationResult.end();
@ -89,6 +91,43 @@ public class RecipeTransformer {
return recipeTransformationResult; return recipeTransformationResult;
} }
private void handleDuplicate(RawRecipe curRecipe, List<RawRecipe> 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 @Nullable
public JsonObject transformRecipe(ResourceLocation recipeId, JsonObject json) { public JsonObject transformRecipe(ResourceLocation recipeId, JsonObject json) {
try { try {
@ -107,4 +146,5 @@ public class RecipeTransformer {
} }
return null; return null;
} }
} }