From 9467a08b3689efb82524db6338fc3c45d85ee209 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 31 Oct 2024 20:36:41 -0700
Subject: [PATCH] Improve performance of RecipeMap#removeRecipe

---
 .../item/crafting/RecipeManager.java.patch    |  2 +-
 .../world/item/crafting/RecipeMap.java.patch  | 47 +++++++++++++------
 .../craftbukkit/inventory/RecipeIterator.java |  4 ++
 3 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/paper-server/patches/sources/net/minecraft/world/item/crafting/RecipeManager.java.patch b/paper-server/patches/sources/net/minecraft/world/item/crafting/RecipeManager.java.patch
index 805865ea9e..83a2caa10c 100644
--- a/paper-server/patches/sources/net/minecraft/world/item/crafting/RecipeManager.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/item/crafting/RecipeManager.java.patch
@@ -92,7 +92,7 @@
  
 +    // CraftBukkit start
 +    public boolean removeRecipe(ResourceKey<Recipe<?>> mcKey) {
-+        boolean removed = this.recipes.removeRecipe(mcKey);
++        boolean removed = this.recipes.removeRecipe((ResourceKey<Recipe<RecipeInput>>) (ResourceKey) mcKey); // Paper - generic fix
 +        if (removed) {
 +            this.finalizeRecipeLoading();
 +        }
diff --git a/paper-server/patches/sources/net/minecraft/world/item/crafting/RecipeMap.java.patch b/paper-server/patches/sources/net/minecraft/world/item/crafting/RecipeMap.java.patch
index bd0b6a1be6..171f3d8e88 100644
--- a/paper-server/patches/sources/net/minecraft/world/item/crafting/RecipeMap.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/item/crafting/RecipeMap.java.patch
@@ -11,7 +11,7 @@
  
  public class RecipeMap {
  
-@@ -35,11 +39,39 @@
+@@ -35,11 +39,56 @@
              com_google_common_collect_immutablemap_builder.put(recipeholder.id(), recipeholder);
          }
  
@@ -31,21 +31,38 @@
 +        }
 +    }
 +
-+    public boolean removeRecipe(ResourceKey<Recipe<?>> mcKey) {
-+        boolean removed = false;
-+        Iterator<RecipeHolder<?>> iter = this.byType.values().iterator();
-+        while (iter.hasNext()) {
-+            RecipeHolder<?> recipe = iter.next();
-+            if (recipe.id().equals(mcKey)) {
-+                iter.remove();
-+                removed = true;
-+            }
-+        }
-+        removed |= this.byKey.remove(mcKey) != null;
-+
-+        return removed;
-+    }
++    // public boolean removeRecipe(ResourceKey<Recipe<?>> mcKey) {
++    //     boolean removed = false;
++    //     Iterator<RecipeHolder<?>> iter = this.byType.values().iterator();
++    //     while (iter.hasNext()) {
++    //         RecipeHolder<?> recipe = iter.next();
++    //         if (recipe.id().equals(mcKey)) {
++    //             iter.remove();
++    //             removed = true;
++    //         }
++    //     }
++    //     removed |= this.byKey.remove(mcKey) != null;
++    //
++    //     return removed;
++    // }
 +    // CraftBukkit end
++
++
++    // Paper start - replace removeRecipe implementation
++    public <T extends RecipeInput> boolean removeRecipe(ResourceKey<Recipe<T>> mcKey) {
++        //noinspection unchecked
++        final RecipeHolder<Recipe<T>> remove = (RecipeHolder<Recipe<T>>) this.byKey.remove(mcKey);
++        if (remove == null) {
++            return false;
++        }
++        final Collection<? extends RecipeHolder<? extends Recipe<T>>> recipes = this.byType(remove.value().getType());
++        if (recipes.remove(remove)) {
++            return true;
++        }
++        return false;
++        // Paper end - why are you using a loop???
++    }
++    // Paper end - replace removeRecipe implementation
 +
      public <I extends RecipeInput, T extends Recipe<I>> Collection<RecipeHolder<T>> byType(RecipeType<T> type) {
 -        return this.byType.get(type);
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java
index c0433e054e..a20b471389 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java
@@ -32,5 +32,9 @@ public class RecipeIterator implements Iterator<Recipe> {
     public void remove() {
         MinecraftServer.getServer().getRecipeManager().recipes.byKey.remove(this.currentRecipe.id()); // Paper - fix removing recipes from RecipeIterator
         this.recipes.remove();
+        // Paper start - correctly reload recipes
+        MinecraftServer.getServer().getRecipeManager().finalizeRecipeLoading();
+        MinecraftServer.getServer().getPlayerList().reloadRecipes();
+        // Paper end - correctly reload recipes
     }
 }