aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0973-Fix-issues-with-Recipe-API.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/server/0973-Fix-issues-with-Recipe-API.patch')
-rw-r--r--patches/server/0973-Fix-issues-with-Recipe-API.patch116
1 files changed, 116 insertions, 0 deletions
diff --git a/patches/server/0973-Fix-issues-with-Recipe-API.patch b/patches/server/0973-Fix-issues-with-Recipe-API.patch
new file mode 100644
index 0000000000..bb85dca687
--- /dev/null
+++ b/patches/server/0973-Fix-issues-with-Recipe-API.patch
@@ -0,0 +1,116 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jake Potrebic <[email protected]>
+Date: Sun, 12 May 2024 15:49:36 -0700
+Subject: [PATCH] Fix issues with Recipe API
+
+
+diff --git a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
+index 63cf2b66f51df68aa3f6d98c69368ce454869d64..1bf54b0142fe41b29b21c8b97d3f52bb24a36a92 100644
+--- a/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
++++ b/src/main/java/net/minecraft/world/item/crafting/ShapedRecipe.java
+@@ -90,7 +90,7 @@ public class ShapedRecipe extends io.papermc.paper.inventory.recipe.RecipeBookEx
+ char c = 'a';
+ for (Ingredient list : this.pattern.ingredients()) {
+ RecipeChoice choice = CraftRecipe.toBukkit(list);
+- if (choice != null) {
++ if (choice != RecipeChoice.empty()) { // Paper
+ recipe.setIngredient(c, choice);
+ }
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
+index 6ba29875d78ede4aa7978ff689e588f7fed11528..c76c78bb7757d407102271463e14716a1b012deb 100644
+--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
+@@ -29,6 +29,10 @@ public interface CraftRecipe extends Recipe {
+ } else if (bukkit instanceof RecipeChoice.ExactChoice) {
+ stack = new Ingredient(((RecipeChoice.ExactChoice) bukkit).getChoices().stream().map((mat) -> new net.minecraft.world.item.crafting.Ingredient.ItemValue(CraftItemStack.asNMSCopy(mat))));
+ stack.exact = true;
++ // Paper start - support "empty" choices
++ } else if (bukkit == RecipeChoice.empty()) {
++ stack = Ingredient.EMPTY;
++ // Paper end
+ } else {
+ throw new IllegalArgumentException("Unknown recipe stack instance " + bukkit);
+ }
+@@ -45,7 +49,7 @@ public interface CraftRecipe extends Recipe {
+ list.getItems();
+
+ if (list.itemStacks.length == 0) {
+- return null;
++ return RecipeChoice.empty(); // Paper - null breaks API contracts
+ }
+
+ if (list.exact) {
+diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
+index 38690b28b6f67624d68877c1e89ebe30b402b233..3aec771478a6b17353d57e82baac53dd24779e7b 100644
+--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTransformRecipe.java
+@@ -30,6 +30,6 @@ public class CraftSmithingTransformRecipe extends SmithingTransformRecipe implem
+ public void addToCraftingManager() {
+ ItemStack result = this.getResult();
+
+- MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMS(this.getTemplate(), true), this.toNMS(this.getBase(), true), this.toNMS(this.getAddition(), true), CraftItemStack.asNMSCopy(result), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy
++ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTransformRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), CraftItemStack.asNMSCopy(result), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy & support empty RecipeChoice
+ }
+ }
+diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
+index 5d7782b168138383c606a2c52fbdebe1732364ac..61af2fe3534ff67f10310c6c7dec39cff0f93ee3 100644
+--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingTrimRecipe.java
+@@ -28,6 +28,6 @@ public class CraftSmithingTrimRecipe extends SmithingTrimRecipe implements Craft
+
+ @Override
+ public void addToCraftingManager() {
+- MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMS(this.getTemplate(), true), this.toNMS(this.getBase(), true), this.toNMS(this.getAddition(), true), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy
++ MinecraftServer.getServer().getRecipeManager().addRecipe(new RecipeHolder<>(CraftNamespacedKey.toMinecraft(this.getKey()), new net.minecraft.world.item.crafting.SmithingTrimRecipe(this.toNMS(this.getTemplate(), false), this.toNMS(this.getBase(), false), this.toNMS(this.getAddition(), false), this.willCopyDataComponents()))); // Paper - Option to prevent data components copy & support empty RecipeChoice
+ }
+ }
+diff --git a/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java b/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..b6816485a2360b936c049b398183658ee18813ec
+--- /dev/null
++++ b/src/test/java/io/papermc/paper/inventory/recipe/TestRecipeChoice.java
+@@ -0,0 +1,24 @@
++package io.papermc.paper.inventory.recipe;
++
++import java.util.Iterator;
++import org.bukkit.Bukkit;
++import org.bukkit.inventory.Recipe;
++import org.bukkit.support.AbstractTestingBase;
++import org.junit.jupiter.api.Test;
++
++import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
++import static org.junit.jupiter.api.Assertions.assertTrue;
++
++class TestRecipeChoice extends AbstractTestingBase {
++
++ @Test
++ void testRecipeChoices() {
++ final Iterator<Recipe> iter = Bukkit.recipeIterator();
++ boolean foundRecipes = false;
++ while (iter.hasNext()) {
++ foundRecipes = true;
++ assertDoesNotThrow(iter::next, "Failed to convert a recipe to Bukkit recipe!");
++ }
++ assertTrue(foundRecipes, "No recipes found!");
++ }
++}
+diff --git a/src/test/java/org/bukkit/support/DummyServer.java b/src/test/java/org/bukkit/support/DummyServer.java
+index 6e9ee1b56b4151c31c373e58172055e02fd7875a..11ba7a3db4c56ec00d9ad1ed8e46b242c033fe74 100644
+--- a/src/test/java/org/bukkit/support/DummyServer.java
++++ b/src/test/java/org/bukkit/support/DummyServer.java
+@@ -104,6 +104,14 @@ public final class DummyServer {
+ when(instance.getPluginManager()).thenReturn(pluginManager);
+ // paper end - testing additions
+
++ // Paper start - add test for recipe conversion
++ when(instance.recipeIterator()).thenAnswer(ignored -> {
++ return com.google.common.collect.Iterators.transform(
++ AbstractTestingBase.DATA_PACK.getRecipeManager().byType.entries().iterator(),
++ input -> input.getValue().toBukkitRecipe());
++ });
++ // Paper end - add test for recipe conversion
++
+ Bukkit.setServer(instance);
+ } catch (Throwable t) {
+ throw new Error(t);