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 53e86d17867e5c2eae2db6a10bfbed788019a1ad..89b797c3468f401a208ef2351ba9f91b234455fd 100644
--- a/src/main/java/org/bukkit/Bukkit.java
+++ b/src/main/java/org/bukkit/Bukkit.java
@@ -990,6 +990,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.
      *
@@ -1050,6 +1070,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.
@@ -1241,6 +1275,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 e9773ebcc76fb637ed19dce203ae0dfe226b0066..f834dd696d3a40af72ab03f4bd03a784ff5ef23e 100644
--- a/src/main/java/org/bukkit/Server.java
+++ b/src/main/java/org/bukkit/Server.java
@@ -839,6 +839,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.
      *
@@ -880,15 +896,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.
@@ -1057,6 +1092,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.
      *
