From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sat, 21 Aug 2021 17:25:54 -0700
Subject: [PATCH] API for updating recipes on clients


diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
index 5170f7ba71d8a09f2b4ae0d945c758fd4ae4130f..886c1aab96bd34739665c22793217f3f41ba92d0 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -1004,6 +1004,26 @@ public final class Bukkit {
         server.reloadData();
     }
 
+    // Paper start - update reloadable data
+    /**
+     * Updates all advancement, tag, and recipe data for all connected clients.
+     * Useful for updating clients to new advancements/recipes/tags.
+     * @see #updateRecipes()
+     */
+    public static void updateResources() {
+        server.updateResources();
+    }
+
+    /**
+     * Updates recipe data and the recipe book for all connected clients. Useful for
+     * updating clients to new recipes.
+     * @see #updateResources()
+     */
+    public static void updateRecipes() {
+        server.updateRecipes();
+    }
+    // Paper end - update reloadable data
+
     /**
      * Returns the primary logger associated with this server instance.
      *
@@ -1064,6 +1084,20 @@ public final class Bukkit {
         return server.addRecipe(recipe);
     }
 
+    // Paper start - method to send recipes immediately
+    /**
+     * Adds a recipe to the crafting manager.
+     *
+     * @param recipe the recipe to add
+     * @param resendRecipes true to update the client with the full set of recipes
+     * @return true if the recipe was added, false if it wasn't for some reason
+     */
+    @Contract("null, _ -> false")
+    public static boolean addRecipe(@Nullable Recipe recipe, boolean resendRecipes) {
+        return server.addRecipe(recipe, resendRecipes);
+    }
+    // Paper end - method to send recipes immediately
+
     /**
      * Get a list of all recipes for a given item. The stack size is ignored
      * in comparisons. If the durability is -1, it will match any data value.
@@ -1255,6 +1289,24 @@ public final class Bukkit {
         return server.removeRecipe(key);
     }
 
+    // Paper start - method to resend recipes
+    /**
+     * Remove a recipe from the server.
+     * <p>
+     * <b>Note that removing a recipe may cause permanent loss of data
+     * associated with that recipe (eg whether it has been discovered by
+     * players).</b>
+     *
+     * @param key NamespacedKey of recipe to remove.
+     * @param resendRecipes true to update all clients on the new recipe list.
+     *                      Will only update if a recipe was actually removed
+     * @return True if recipe was removed
+     */
+    public static boolean removeRecipe(@NotNull NamespacedKey key, boolean resendRecipes) {
+        return server.removeRecipe(key, resendRecipes);
+    }
+    // Paper end - method to resend recipes
+
     /**
      * Gets a list of command aliases defined in the server properties.
      *
diff --git a/src/main/java/org/bukkit/Server.java b/src/main/java/org/bukkit/Server.java
index d05ea34d8f58b475628157a7bd2ba0143e9a6c36..897d659e45d1a32c1bdaf8e0941f00597261a0b9 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -853,6 +853,22 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
      */
     public void reloadData();
 
+    // Paper start - update reloadable data
+    /**
+     * Updates all advancement, tag, and recipe data to all connected clients.
+     * Useful for updating clients to new advancements/recipes/tags.
+     * @see #updateRecipes()
+     */
+    void updateResources();
+
+    /**
+     * Updates recipe data and the recipe book to each player. Useful for
+     * updating clients to new recipes.
+     * @see #updateResources()
+     */
+    void updateRecipes();
+    // Paper end - update reloadable data
+
     /**
      * Returns the primary logger associated with this server instance.
      *
@@ -894,15 +910,34 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
     public boolean dispatchCommand(@NotNull CommandSender sender, @NotNull String commandLine) throws CommandException;
 
     /**
-     * Adds a recipe to the crafting manager.
+     * Adds a recipe to the crafting manager. Recipes added with
+     * this method won't be sent to the client automatically. Use
+     * {@link #updateRecipes()} or {@link #updateResources()} to
+     * update clients to new recipes added.
+     * <p>
+     * Player's still have to discover recipes via {@link Player#discoverRecipe(NamespacedKey)}
+     * before seeing them in their recipe book.
      *
      * @param recipe the recipe to add
      * @return true if the recipe was added, false if it wasn't for some
      *     reason
+     * @see #addRecipe(Recipe, boolean)
      */
     @Contract("null -> false")
     public boolean addRecipe(@Nullable Recipe recipe);
 
+    // Paper start - method to send recipes immediately
+    /**
+     * Adds a recipe to the crafting manager.
+     *
+     * @param recipe the recipe to add
+     * @param resendRecipes true to update the client with the full set of recipes
+     * @return true if the recipe was added, false if it wasn't for some reason
+     */
+    @Contract("null, _ -> false")
+    boolean addRecipe(@Nullable Recipe recipe, boolean resendRecipes);
+    // Paper end - method to send recipes immediately
+
     /**
      * Get a list of all recipes for a given item. The stack size is ignored
      * in comparisons. If the durability is -1, it will match any data value.
@@ -1071,6 +1106,22 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
      */
     public boolean removeRecipe(@NotNull NamespacedKey key);
 
+    // Paper start - method to resend recipes
+    /**
+     * Remove a recipe from the server.
+     * <p>
+     * <b>Note that removing a recipe may cause permanent loss of data
+     * associated with that recipe (eg whether it has been discovered by
+     * players).</b>
+     *
+     * @param key NamespacedKey of recipe to remove.
+     * @param resendRecipes true to update all clients on the new recipe list.
+     *                      Will only update if a recipe was actually removed
+     * @return True if recipe was removed
+     */
+    boolean removeRecipe(@NotNull NamespacedKey key, boolean resendRecipes);
+    // Paper end - method to resend recipes
+
     /**
      * Gets a list of command aliases defined in the server properties.
      *