papermc/patches/server/0976-Fix-issues-with-Recipe-API.patch
Nassim Jahnke 4bc15f13aa
Updated Upstream (Bukkit/CraftBukkit)
Upstream has released updates that appear to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

Bukkit Changes:
e2160a18 Make MapCursor#type not depends on deprecated values

CraftBukkit Changes:
6ce172642 SPIGOT-7761: Ender pearl does not damage or spawn endermites
f5a63f734 SPIGOT-7759: Chunk not there when requested in ChunkUnloadEvent
28287259c Remove unused import
eb9a7dde0 SPIGOT-7757: Cannot set item in Stonecutter Inventory
f8be9d752 Move deserialized removed unhandled tags to dedicated removedTags
a7e576186 Fix potential mutability issue with CraftMetaItem copy constructor
995885452 SPIGOT-7741: Vanilla ItemComponent in commands can't remove components
9ef69aa0b PR-1284: Move ItemType <-> ItemMeta linking to a centralized place
3e82eafbe PR-1420: Fix DirectEntity and CausingEntity Damager for Creepers ignited by Player
c23daa71f SPIGOT-7751: Fix crash caused by arrows from trial spawners
Make MapCursor#type not depends on deprecated values
SPIGOT-7761: Ender pearl does not damage or spawn endermites
2024-06-15 18:31:58 +02:00

116 lines
7.4 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
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 53b49a7ee1ae185e0def7c90cf11223f55a57e65..7862d578f53e48bc467cc4f475d32d9d6ea71e04 100644
--- a/src/test/java/org/bukkit/support/DummyServer.java
+++ b/src/test/java/org/bukkit/support/DummyServer.java
@@ -105,6 +105,14 @@ public final class DummyServer {
when(instance.getTag(anyString(), any(org.bukkit.NamespacedKey.class), any())).thenAnswer(ignored -> new io.papermc.paper.util.EmptyTag());
// 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);