aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJake Potrebic <[email protected]>2024-12-17 11:45:39 +0100
committerNassim Jahnke <[email protected]>2024-12-17 11:45:39 +0100
commitac69f75d23618d914c0d705b578ac47dbac2bff0 (patch)
tree72d17a6b0bf990c81c13bdeef0668fc33f2b01f9
parent05c0d4a6e2acfc1558f6af6384625c4938fd8554 (diff)
downloadPaper-ac69f75d23618d914c0d705b578ac47dbac2bff0.tar.gz
Paper-ac69f75d23618d914c0d705b578ac47dbac2bff0.zip
Apply Improve-performance-of-mass-crafts directly
-rw-r--r--feature-patches/1065-Improve-performance-of-mass-crafts.patch92
-rw-r--r--paper-server/patches/sources/net/minecraft/world/inventory/CraftingContainer.java.patch4
-rw-r--r--paper-server/patches/sources/net/minecraft/world/inventory/CraftingMenu.java.patch27
-rw-r--r--paper-server/patches/sources/net/minecraft/world/inventory/ResultSlot.java.patch11
-rw-r--r--paper-server/patches/sources/net/minecraft/world/inventory/TransientCraftingContainer.java.patch6
5 files changed, 42 insertions, 98 deletions
diff --git a/feature-patches/1065-Improve-performance-of-mass-crafts.patch b/feature-patches/1065-Improve-performance-of-mass-crafts.patch
deleted file mode 100644
index c09f2cf750..0000000000
--- a/feature-patches/1065-Improve-performance-of-mass-crafts.patch
+++ /dev/null
@@ -1,92 +0,0 @@
-From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
-From: Jake Potrebic <[email protected]>
-Date: Sun, 13 Aug 2023 15:41:52 -0700
-Subject: [PATCH] Improve performance of mass crafts
-
-When the server crafts all available items in CraftingMenu or InventoryMenu the game
-checks either 4 or 9 times for each individual craft for a matching recipe for that container.
-This check can be expensive if 64 total crafts are being performed with the recipe matching logic
-being run 64 * 9 + 64 times. A breakdown of those times is below. This patch caches the last matching
-recipe so that it is checked first and only if it doesn't match does the rest of the matching logic run.
-
-Shift-click crafts are processed one at a time, so shift clicking on an item in the result of a iron block craft
-where all the 9 inputs are full stacks of iron will run 64 iron block crafts. For each of those crafts, the
-'remaining' blocks are calculated. This is due to recipes that have leftover items like buckets. This is done
-for each craft, and done once to get the full 9 leftover items which are usually air. Then 1 item is removed
-from each of the 9 inputs and each time that happens, logic is triggered to update the result itemstack. So
-for each craft, that logic is run 9 times (hence the 64 * 9). The + 64 is from the 64 checks for remaining items.
-
-After this patch, the full iteration over all recipes checking for a match should run once for a full craft to find the
-initial recipe match. Then that recipe will be checked first for all future recipe match checks.
-
-diff --git a/src/main/java/net/minecraft/world/inventory/CraftingContainer.java b/src/main/java/net/minecraft/world/inventory/CraftingContainer.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/inventory/CraftingContainer.java
-+++ b/src/main/java/net/minecraft/world/inventory/CraftingContainer.java
-@@ -0,0 +0,0 @@ public interface CraftingContainer extends Container, StackedContentsCompatible
- List<ItemStack> getItems();
-
- // CraftBukkit start
-- default RecipeHolder<?> getCurrentRecipe() {
-+ default RecipeHolder<net.minecraft.world.item.crafting.CraftingRecipe> getCurrentRecipe() { // Paper - use correct generic
- return null;
- }
-
-- default void setCurrentRecipe(RecipeHolder<?> recipe) {
-+ default void setCurrentRecipe(RecipeHolder<net.minecraft.world.item.crafting.CraftingRecipe> recipe) { // Paper - use correct generic
- }
- // CraftBukkit end
-
-diff --git a/src/main/java/net/minecraft/world/inventory/CraftingMenu.java b/src/main/java/net/minecraft/world/inventory/CraftingMenu.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/inventory/CraftingMenu.java
-+++ b/src/main/java/net/minecraft/world/inventory/CraftingMenu.java
-@@ -0,0 +0,0 @@ public class CraftingMenu extends AbstractCraftingMenu {
- CraftingInput craftinginput = craftingInventory.asCraftInput();
- ServerPlayer entityplayer = (ServerPlayer) player;
- ItemStack itemstack = ItemStack.EMPTY;
-+ if (recipe == null) recipe = craftingInventory.getCurrentRecipe(); // Paper - Perf: Improve mass crafting; check last recipe used first
- Optional<RecipeHolder<CraftingRecipe>> optional = world.getServer().getRecipeManager().getRecipeFor(RecipeType.CRAFTING, craftinginput, world, recipe);
- craftingInventory.setCurrentRecipe(optional.orElse(null)); // CraftBukkit
-
-diff --git a/src/main/java/net/minecraft/world/inventory/ResultSlot.java b/src/main/java/net/minecraft/world/inventory/ResultSlot.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/inventory/ResultSlot.java
-+++ b/src/main/java/net/minecraft/world/inventory/ResultSlot.java
-@@ -0,0 +0,0 @@ public class ResultSlot extends Slot {
- private NonNullList<ItemStack> getRemainingItems(CraftingInput input, Level world) {
- return world instanceof ServerLevel serverLevel
- ? serverLevel.recipeAccess()
-- .getRecipeFor(RecipeType.CRAFTING, input, serverLevel)
-+ .getRecipeFor(RecipeType.CRAFTING, input, serverLevel, this.craftSlots.getCurrentRecipe()) // Paper - Perf: Improve mass crafting; check last recipe used first
- .map(recipe -> recipe.value().getRemainingItems(input))
- .orElseGet(() -> copyAllInputItems(input))
- : CraftingRecipe.defaultCraftingReminder(input);
-diff --git a/src/main/java/net/minecraft/world/inventory/TransientCraftingContainer.java b/src/main/java/net/minecraft/world/inventory/TransientCraftingContainer.java
-index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
---- a/src/main/java/net/minecraft/world/inventory/TransientCraftingContainer.java
-+++ b/src/main/java/net/minecraft/world/inventory/TransientCraftingContainer.java
-@@ -0,0 +0,0 @@ public class TransientCraftingContainer implements CraftingContainer {
-
- // CraftBukkit start - add fields
- public List<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>();
-- private RecipeHolder<?> currentRecipe;
-+ private RecipeHolder<net.minecraft.world.item.crafting.CraftingRecipe> currentRecipe; // Paper - use correct generic
- public Container resultInventory;
- private Player owner;
- private int maxStack = MAX_STACK;
-@@ -0,0 +0,0 @@ public class TransientCraftingContainer implements CraftingContainer {
- }
-
- @Override
-- public RecipeHolder<?> getCurrentRecipe() {
-+ public RecipeHolder<net.minecraft.world.item.crafting.CraftingRecipe> getCurrentRecipe() { // Paper - use correct generic
- return this.currentRecipe;
- }
-
- @Override
-- public void setCurrentRecipe(RecipeHolder<?> currentRecipe) {
-+ public void setCurrentRecipe(RecipeHolder<net.minecraft.world.item.crafting.CraftingRecipe> currentRecipe) { // Paper - use correct generic
- this.currentRecipe = currentRecipe;
- }
-
diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/CraftingContainer.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/CraftingContainer.java.patch
index 2225d1d404..2aef7bff97 100644
--- a/paper-server/patches/sources/net/minecraft/world/inventory/CraftingContainer.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/inventory/CraftingContainer.java.patch
@@ -5,11 +5,11 @@
List<ItemStack> getItems();
+ // CraftBukkit start
-+ default net.minecraft.world.item.crafting.RecipeHolder<?> getCurrentRecipe() {
++ default net.minecraft.world.item.crafting.RecipeHolder<net.minecraft.world.item.crafting.CraftingRecipe> getCurrentRecipe() {
+ return null;
+ }
+
-+ default void setCurrentRecipe(net.minecraft.world.item.crafting.RecipeHolder<?> recipe) {
++ default void setCurrentRecipe(net.minecraft.world.item.crafting.RecipeHolder<net.minecraft.world.item.crafting.CraftingRecipe> recipe) {
+ }
+ // CraftBukkit end
+
diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/CraftingMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/CraftingMenu.java.patch
index f490a6a0d3..d04a6f281e 100644
--- a/paper-server/patches/sources/net/minecraft/world/inventory/CraftingMenu.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/inventory/CraftingMenu.java.patch
@@ -18,9 +18,34 @@
this.access = access;
this.player = playerInventory.player;
this.addResultSlot(this.player, 124, 35);
-@@ -56,6 +_,7 @@
+@@ -55,7 +_,32 @@
+ CraftingInput craftInput = craftSlots.asCraftInput();
ServerPlayer serverPlayer = (ServerPlayer)player;
ItemStack itemStack = ItemStack.EMPTY;
++ // Paper start - Perf: Improve mass crafting; check last recipe used first
++ /*
++ When the server crafts all available items in CraftingMenu or InventoryMenu the game
++ checks either 4 or 9 times for each individual craft for a matching recipe for that container.
++ This check can be expensive if 64 total crafts are being performed with the recipe matching logic
++ being run 64 * 9 + 64 times. A breakdown of those times is below. This caches the last matching
++ recipe so that it is checked first and only if it doesn't match does the rest of the matching logic run.
++
++ Shift-click crafts are processed one at a time, so shift clicking on an item in the result of a iron block craft
++ where all the 9 inputs are full stacks of iron will run 64 iron block crafts. For each of those crafts, the
++ 'remaining' blocks are calculated. This is due to recipes that have leftover items like buckets. This is done
++ for each craft, and done once to get the full 9 leftover items which are usually air. Then 1 item is removed
++ from each of the 9 inputs and each time that happens, logic is triggered to update the result itemstack. So
++ for each craft, that logic is run 9 times (hence the 64 * 9). The + 64 is from the 64 checks for remaining items.
++
++ After this change, the full iteration over all recipes checking for a match should run once for a full craft to find the
++ initial recipe match. Then that recipe will be checked first for all future recipe match checks.
++
++ See also: ResultSlot class
++ */
++ if (recipe == null) {
++ recipe = craftSlots.getCurrentRecipe();
++ }
++ // Paper end - Perf: Improve mass crafting; check last recipe used first
Optional<RecipeHolder<CraftingRecipe>> recipeFor = level.getServer().getRecipeManager().getRecipeFor(RecipeType.CRAFTING, craftInput, level, recipe);
+ craftSlots.setCurrentRecipe(recipeFor.orElse(null)); // CraftBukkit
if (recipeFor.isPresent()) {
diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/ResultSlot.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/ResultSlot.java.patch
new file mode 100644
index 0000000000..c8c1e2c156
--- /dev/null
+++ b/paper-server/patches/sources/net/minecraft/world/inventory/ResultSlot.java.patch
@@ -0,0 +1,11 @@
+--- a/net/minecraft/world/inventory/ResultSlot.java
++++ b/net/minecraft/world/inventory/ResultSlot.java
+@@ -72,7 +_,7 @@
+ private NonNullList<ItemStack> getRemainingItems(CraftingInput input, Level level) {
+ return level instanceof ServerLevel serverLevel
+ ? serverLevel.recipeAccess()
+- .getRecipeFor(RecipeType.CRAFTING, input, serverLevel)
++ .getRecipeFor(RecipeType.CRAFTING, input, serverLevel, this.craftSlots.getCurrentRecipe()) // Paper - Perf: Improve mass crafting; check last recipe used first
+ .map(recipe -> recipe.value().getRemainingItems(input))
+ .orElseGet(() -> copyAllInputItems(input))
+ : CraftingRecipe.defaultCraftingReminder(input);
diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/TransientCraftingContainer.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/TransientCraftingContainer.java.patch
index 898f5850c4..85f7ca8636 100644
--- a/paper-server/patches/sources/net/minecraft/world/inventory/TransientCraftingContainer.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/inventory/TransientCraftingContainer.java.patch
@@ -6,7 +6,7 @@
+ // CraftBukkit start - add fields
+ public List<org.bukkit.entity.HumanEntity> transaction = new java.util.ArrayList<>();
-+ private net.minecraft.world.item.crafting.RecipeHolder<?> currentRecipe;
++ private net.minecraft.world.item.crafting.RecipeHolder<net.minecraft.world.item.crafting.CraftingRecipe> currentRecipe;
+ public net.minecraft.world.Container resultInventory;
+ private Player owner;
+ private int maxStack = MAX_STACK;
@@ -51,12 +51,12 @@
+ }
+
+ @Override
-+ public net.minecraft.world.item.crafting.RecipeHolder<?> getCurrentRecipe() {
++ public net.minecraft.world.item.crafting.RecipeHolder<net.minecraft.world.item.crafting.CraftingRecipe> getCurrentRecipe() {
+ return this.currentRecipe;
+ }
+
+ @Override
-+ public void setCurrentRecipe(net.minecraft.world.item.crafting.RecipeHolder<?> currentRecipe) {
++ public void setCurrentRecipe(net.minecraft.world.item.crafting.RecipeHolder<net.minecraft.world.item.crafting.CraftingRecipe> currentRecipe) {
+ this.currentRecipe = currentRecipe;
+ }
+