Skip to content

Commit

Permalink
Fix crash from tag info recipes having UID that matches another recip…
Browse files Browse the repository at this point in the history
…e type
  • Loading branch information
mezz committed Aug 26, 2024
1 parent 7698d58 commit fd4d163
Show file tree
Hide file tree
Showing 14 changed files with 90 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ private static <C extends AbstractContainerMenu, R> Optional<IRecipeTransferErro
} catch (RuntimeException e) {
LOGGER.error(
"Recipe transfer handler '{}' for container '{}' and recipe type '{}' threw an error: ",
transferHandler.getClass(), transferHandler.getContainerClass(), recipeCategory.getRecipeType().getUid(), e
transferHandler.getClass(), transferHandler.getContainerClass(), recipeCategory.getRecipeType(), e
);
return Optional.of(RecipeTransferErrorInternal.INSTANCE);
}
Expand Down
13 changes: 13 additions & 0 deletions CommonApi/src/main/java/mezz/jei/api/helpers/IJeiHelpers.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ public interface IJeiHelpers {
*/
IPlatformFluidHelper<?> getPlatformFluidHelper();

/**
* Get the registered recipe type for the given unique id.
* <p>
* This is useful for integrating with other mods that do not share their
* recipe types directly from their API.
*
* @see RecipeType#getUid()
* @since 15.13.0
*/
<T> Optional<RecipeType<T>> getRecipeType(ResourceLocation uid, Class<? extends T> recipeClass);

/**
* Get the registered recipe type for the given unique id.
* <p>
Expand All @@ -59,7 +70,9 @@ public interface IJeiHelpers {
*
* @see RecipeType#getUid()
* @since 11.4.0
* @deprecated use {@link #getRecipeType(ResourceLocation, Class)}
*/
@Deprecated(since = "15.13.0", forRemoval = true)
Optional<RecipeType<?>> getRecipeType(ResourceLocation uid);

/**
Expand Down
15 changes: 14 additions & 1 deletion CommonApi/src/main/java/mezz/jei/api/recipe/IRecipeManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,17 @@ IRecipeSlotDrawable createRecipeSlotDrawable(
int ingredientCycleOffset
);

/**
* Get the registered recipe type for the given unique id.
* <p>
* This is useful for integrating with other mods that do not share their
* recipe types directly from their API.
*
* @see RecipeType#getUid()
* @since 15.3.0
*/
<T> Optional<RecipeType<T>> getRecipeType(ResourceLocation recipeUid, Class<? extends T> recipeClass);

/**
* Get the registered recipe type for the given unique id.
* <p>
Expand All @@ -180,6 +191,8 @@ IRecipeSlotDrawable createRecipeSlotDrawable(
*
* @see RecipeType#getUid()
* @since 11.2.3
* @deprecated use {@link #getRecipeType(ResourceLocation, Class)}
*/
Optional<RecipeType<?>> getRecipeType(ResourceLocation uid);
@Deprecated(since = "15.3.0", forRemoval = true)
Optional<RecipeType<?>> getRecipeType(ResourceLocation recipeUid);
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,7 @@ public void draw(boolean selected, GuiGraphics guiGraphics, int mouseX, int mous

@Override
public boolean isSelected(IRecipeCategory<?> selectedCategory) {
ResourceLocation categoryUid = category.getRecipeType().getUid();
ResourceLocation selectedCategoryUid = selectedCategory.getRecipeType().getUid();
return categoryUid.equals(selectedCategoryUid);
return category.getRecipeType().equals(selectedCategory.getRecipeType());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public static <T> Optional<IRecipeLayoutDrawable<T>> create(
);
return Optional.of(recipeLayout);
} catch (RuntimeException | LinkageError e) {
LOGGER.error("Error caught from Recipe Category: {}", recipeCategory.getRecipeType().getUid(), e);
LOGGER.error("Error caught from Recipe Category: {}", recipeCategory.getRecipeType(), e);
}
return Optional.empty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ public RecipeManager createRecipeManager(

RecipeCatalystRegistration recipeCatalystRegistration = new RecipeCatalystRegistration(ingredientManager, jeiHelpers);
PluginCaller.callOnPlugins("Registering recipe catalysts", plugins, p -> p.registerRecipeCatalysts(recipeCatalystRegistration));
ImmutableListMultimap<ResourceLocation, ITypedIngredient<?>> recipeCatalysts = recipeCatalystRegistration.getRecipeCatalysts();
ImmutableListMultimap<RecipeType<?>, ITypedIngredient<?>> recipeCatalysts = recipeCatalystRegistration.getRecipeCatalysts();

IJeiFeatures jeiFeatures = Internal.getJeiFeatures();
AdvancedRegistration advancedRegistration = new AdvancedRegistration(jeiHelpers, jeiFeatures);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@
import mezz.jei.common.util.ErrorUtil;
import mezz.jei.core.collect.ListMultiMap;
import mezz.jei.library.ingredients.TypedIngredient;
import net.minecraft.resources.ResourceLocation;

public class RecipeCatalystRegistration implements IRecipeCatalystRegistration {
private final ListMultiMap<ResourceLocation, ITypedIngredient<?>> recipeCatalysts = new ListMultiMap<>();
private final ListMultiMap<RecipeType<?>, ITypedIngredient<?>> recipeCatalysts = new ListMultiMap<>();
private final IIngredientManager ingredientManager;
private final IJeiHelpers jeiHelpers;

Expand Down Expand Up @@ -42,11 +41,11 @@ public <T> void addRecipeCatalyst(IIngredientType<T> ingredientType, T ingredien
ErrorUtil.checkNotNull(recipeType, "recipeType");
ITypedIngredient<T> typedIngredient = TypedIngredient.createAndFilterInvalid(this.ingredientManager, ingredientType, ingredient, true)
.orElseThrow(() -> new IllegalArgumentException("Recipe catalyst must be valid"));
this.recipeCatalysts.put(recipeType.getUid(), typedIngredient);
this.recipeCatalysts.put(recipeType, typedIngredient);
}
}

public ImmutableListMultimap<ResourceLocation, ITypedIngredient<?>> getRecipeCatalysts() {
public ImmutableListMultimap<RecipeType<?>, ITypedIngredient<?>> getRecipeCatalysts() {
return recipeCatalysts.toImmutable();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public void addRecipeCategories(IRecipeCategory<?>... recipeCategories) {
RecipeType<?> recipeType = recipeCategory.getRecipeType();
Preconditions.checkNotNull(recipeType, "Recipe type cannot be null %s", recipeCategory);
if (recipeTypes.contains(recipeType)) {
throw new IllegalArgumentException("A RecipeCategory with type \"" + recipeType.getUid() + "\" has already been registered.");
throw new IllegalArgumentException("A RecipeCategory with type \"" + recipeType + "\" has already been registered.");
} else {
recipeTypes.add(recipeType);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ private static <B> void createAndRegisterTagCategory(
}

private static RecipeType<ITagInfoRecipe> createTagInfoRecipeType(ResourceLocation registryLocation) {
return RecipeType.create(registryLocation.getNamespace(), registryLocation.getPath(), ITagInfoRecipe.class);
return RecipeType.create(registryLocation.getNamespace(), "tag_recipes/" + registryLocation.getPath(), ITagInfoRecipe.class);
}

private static <B, I> boolean createAndRegisterTagCategory(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ public void unhideRecipeCategory(RecipeType<?> recipeType) {
internal.unhideRecipeCategory(recipeType);
}

@Override
public <T> Optional<RecipeType<T>> getRecipeType(ResourceLocation recipeUid, Class<? extends T> recipeClass) {
return internal.getRecipeType(recipeUid, recipeClass);
}

@Override
public Optional<RecipeType<?>> getRecipeType(ResourceLocation recipeUid) {
return internal.getRecipeType(recipeUid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public class RecipeManagerInternal {

public RecipeManagerInternal(
List<IRecipeCategory<?>> recipeCategories,
ImmutableListMultimap<ResourceLocation, ITypedIngredient<?>> recipeCatalysts,
ImmutableListMultimap<RecipeType<?>, ITypedIngredient<?>> recipeCatalysts,
ImmutableListMultimap<RecipeType<?>, IRecipeCategoryDecorator<?>> recipeCategoryDecorators,
IIngredientManager ingredientManager,
List<IRecipeManagerPlugin> plugins,
Expand Down Expand Up @@ -86,9 +86,9 @@ public RecipeManagerInternal(

RecipeCatalystBuilder recipeCatalystBuilder = new RecipeCatalystBuilder(this.recipeMaps.get(RecipeIngredientRole.CATALYST));
for (IRecipeCategory<?> recipeCategory : recipeCategories) {
ResourceLocation recipeCategoryUid = recipeCategory.getRecipeType().getUid();
if (recipeCatalysts.containsKey(recipeCategoryUid)) {
List<ITypedIngredient<?>> catalysts = recipeCatalysts.get(recipeCategoryUid);
RecipeType<?> recipeType = recipeCategory.getRecipeType();
if (recipeCatalysts.containsKey(recipeType)) {
List<ITypedIngredient<?>> catalysts = recipeCatalysts.get(recipeType);
recipeCatalystBuilder.addCategoryCatalysts(recipeCategory, catalysts);
}
}
Expand All @@ -104,7 +104,7 @@ public RecipeManagerInternal(
}

public <T> void addRecipes(RecipeType<T> recipeType, List<T> recipes) {
LOGGER.debug("Adding recipes: {}", recipeType.getUid());
LOGGER.debug("Adding recipes: {}", recipeType);
RecipeTypeData<T> recipeTypeData = recipeTypeDataMap.get(recipeType);
IRecipeCategory<T> recipeCategory = recipeTypeData.getRecipeCategory();
Set<T> hiddenRecipes = recipeTypeData.getHiddenRecipes();
Expand Down Expand Up @@ -270,6 +270,10 @@ public void unhideRecipeCategory(RecipeType<?> recipeType) {
recipeCategoriesVisibleCache = null;
}

public <T> Optional<RecipeType<T>> getRecipeType(ResourceLocation recipeUid, Class<? extends T> recipeClass) {
return recipeTypeDataMap.getType(recipeUid, recipeClass);
}

public Optional<RecipeType<?>> getRecipeType(ResourceLocation recipeUid) {
return recipeTypeDataMap.getType(recipeUid);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

public class RecipeTypeDataMap {
@Unmodifiable
private final Map<ResourceLocation, RecipeTypeData<?>> uidMap;
private final Map<RecipeType<?>, RecipeTypeData<?>> uidMap;

public RecipeTypeDataMap(
List<IRecipeCategory<?>> recipeCategories,
Expand All @@ -23,7 +23,7 @@ public RecipeTypeDataMap(
this.uidMap = recipeCategories.stream()
.collect(
Collectors.toUnmodifiableMap(
recipeCategory -> recipeCategory.getRecipeType().getUid(),
IRecipeCategory::getRecipeType,
recipeCategory -> {
List<ITypedIngredient<?>> catalysts = recipeCategoryCatalystsMap.get(recipeCategory);
return new RecipeTypeData<>(recipeCategory, catalysts);
Expand All @@ -33,10 +33,10 @@ public RecipeTypeDataMap(
}

public <T> RecipeTypeData<T> get(RecipeType<T> recipeType) {
RecipeTypeData<?> data = this.uidMap.get(recipeType.getUid());
RecipeTypeData<?> data = this.uidMap.get(recipeType);
if (data == null) {
throw new IllegalStateException(
"There is no recipe category registered for: " + recipeType.getUid() +
"There is no recipe category registered for: " + recipeType +
"\nA recipe category must be registered in order to use this recipe type."
);
}
Expand All @@ -56,7 +56,7 @@ private static <T> RecipeTypeData<T> validate(Iterable<? extends T> recipes, Rec
Class<?> recipeClass = recipeType.getRecipeClass();
for (T recipe : recipes) {
if (!recipeClass.isInstance(recipe)) {
throw new IllegalArgumentException(recipeType.getUid() + " recipes must be an instance of " + recipeClass + ". Instead got: " + recipe.getClass());
throw new IllegalArgumentException(recipeType + " recipes must be an instance of " + recipeClass + ". Instead got: " + recipe.getClass());
}
}
@SuppressWarnings("unchecked")
Expand All @@ -65,15 +65,27 @@ private static <T> RecipeTypeData<T> validate(Iterable<? extends T> recipes, Rec
}

public void validate(RecipeType<?> recipeType) {
if (!uidMap.containsKey(recipeType.getUid())) {
throw new IllegalStateException("There is no recipe type registered for: " + recipeType.getUid());
if (!uidMap.containsKey(recipeType)) {
throw new IllegalStateException("There is no recipe type registered for: " + recipeType);
}
}

public Optional<RecipeType<?>> getType(ResourceLocation recipeTypeUid) {
RecipeTypeData<?> data = uidMap.get(recipeTypeUid);
return Optional.ofNullable(data)
.map(RecipeTypeData::getRecipeCategory)
.map(IRecipeCategory::getRecipeType);
return uidMap.keySet()
.stream()
.filter(recipeType -> recipeType.getUid().equals(recipeTypeUid))
.findFirst();
}

public <T> Optional<RecipeType<T>> getType(ResourceLocation recipeTypeUid, Class<? extends T> recipeClass) {
return uidMap.keySet()
.stream()
.filter(recipeType -> recipeType.getUid().equals(recipeTypeUid) && recipeType.getRecipeClass().equals(recipeClass))
.map(recipeType -> {
@SuppressWarnings("unchecked")
RecipeType<T> castRecipeType = (RecipeType<T>) recipeType;
return castRecipeType;
})
.findFirst();
}
}
16 changes: 16 additions & 0 deletions Library/src/main/java/mezz/jei/library/runtime/JeiHelpers.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,22 @@ public IPlatformFluidHelper<?> getPlatformFluidHelper() {
return platformFluidHelper;
}

@Override
public <T> Optional<RecipeType<T>> getRecipeType(ResourceLocation uid, Class<? extends T> recipeClass) {
return Optional.ofNullable(this.recipeCategories)
.flatMap(r -> r.stream()
.map(IRecipeCategory::getRecipeType)
.filter(t -> t.getUid().equals(uid) && t.getRecipeClass().equals(recipeClass))
.map(t -> {
@SuppressWarnings("unchecked")
RecipeType<T> cast = (RecipeType<T>) t;
return cast;
})
.findFirst()
);
}

@SuppressWarnings("removal")
@Override
public Optional<RecipeType<?>> getRecipeType(ResourceLocation uid) {
return Optional.ofNullable(this.recipeCategories)
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ curseHomepageUrl=https://www.curseforge.com/minecraft/mc-mods/jei
jUnitVersion=5.8.2

# Version
specificationVersion=15.12.3
specificationVersion=15.13.0

0 comments on commit fd4d163

Please sign in to comment.