Interface RecipeService


public interface RecipeService
Service for managing custom Zentrix recipes.

This service allows addon developers to create, register, and manage custom crafting recipes that integrate with the Zentrix game system.

Features

  • Register shaped and shapeless recipes
  • Set craft limits (GLOBAL per world/game, not per player!)
  • Query existing recipes
  • Remove recipes programmatically
  • Check global craft availability
  • Batch operations for multiple recipes

IMPORTANT: Craft Limits are GLOBAL per World!

Craft limits restrict how many TOTAL times a recipe can be crafted in a world/game, not per player:

  • One-time (oneTime()): Only 1 player total can craft it per world
  • Craft limit (craftLimit(9)): Only 9 total crafts per world (any players)
  • Unlimited: Any number of players can craft unlimited times

Creating and Registering a Recipe


 RecipeService recipeService = api.getRecipeService();

 // Create a shaped recipe
 RecipeBuilder builder = new RecipeBuilder()
     .id("super-pickaxe")
     .shaped()
     .result(new ItemStack(Material.DIAMOND_PICKAXE))
     .pattern("DDD", " S ", " S ")
     .ingredient('D', new ItemStack(Material.DIAMOND))
     .ingredient('S', new ItemStack(Material.STICK))
     .craftLimit(1);

 // Register it
 boolean success = recipeService.registerRecipe(builder);
 

Querying Recipes


 // Get all recipes
 Collection<ZentrixRecipe> recipes = recipeService.getAllRecipes();

 // Find a specific recipe
 Optional<ZentrixRecipe> recipe = recipeService.getRecipe("super-pickaxe");

 // Check if recipe exists
 boolean exists = recipeService.recipeExists("super-pickaxe");
 
Since:
1.0.1
See Also:
  • Method Details

    • registerRecipe

      boolean registerRecipe(@NotNull @NotNull RecipeBuilder builder)
      Registers a new recipe from a builder.

      The builder must have all required fields set (ID, result, and ingredients). If a recipe with the same ID already exists, registration will fail.

      Parameters:
      builder - The recipe builder with configuration
      Returns:
      true if registered successfully, false if failed (e.g., duplicate ID)
      Throws:
      IllegalArgumentException - if the builder is invalid
    • registerRecipeAsync

      @NotNull @NotNull CompletableFuture<Boolean> registerRecipeAsync(@NotNull @NotNull RecipeBuilder builder)
      Registers a new recipe and saves it to file asynchronously.

      This method performs the same registration as registerRecipe(RecipeBuilder) but also persists the recipe to disk so it survives server restarts.

      The returned CompletableFuture completes only after both registration AND file saving have completed (or failed).

      Parameters:
      builder - The recipe builder with configuration
      Returns:
      CompletableFuture that completes with true if successful
      Throws:
      IllegalArgumentException - if the builder is invalid
    • registerRecipes

      int registerRecipes(@NotNull @NotNull Collection<RecipeBuilder> builders)
      Registers multiple recipes at once.

      This is more efficient than calling registerRecipe(RecipeBuilder) multiple times, especially for addons with many recipes.

      Parameters:
      builders - The recipe builders to register
      Returns:
      Number of recipes successfully registered
      Throws:
      IllegalArgumentException - if any builder is invalid
    • registerRecipesAsync

      @NotNull @NotNull CompletableFuture<Integer> registerRecipesAsync(@NotNull @NotNull Collection<RecipeBuilder> builders)
      Registers multiple recipes and saves them to file asynchronously.
      Parameters:
      builders - The recipe builders to register
      Returns:
      CompletableFuture that completes with the number of successful registrations
    • unregisterRecipe

      boolean unregisterRecipe(@NotNull @NotNull String recipeId)
      Unregisters a recipe by its ID.

      This removes the recipe from the server but does NOT delete the file. Use unregisterRecipeAndDelete(String) to also remove from disk.

      Parameters:
      recipeId - The recipe ID to unregister
      Returns:
      true if the recipe was found and unregistered
    • unregisterRecipeAndDelete

      @NotNull @NotNull CompletableFuture<Boolean> unregisterRecipeAndDelete(@NotNull @NotNull String recipeId)
      Unregisters a recipe and deletes it from disk.

      This completely removes the recipe, including the saved file. The returned CompletableFuture completes only after both unregistration AND file deletion have completed (or failed).

      Parameters:
      recipeId - The recipe ID to unregister and delete
      Returns:
      CompletableFuture that completes with true if successful
    • unregisterRecipes

      int unregisterRecipes(@NotNull @NotNull Collection<String> recipeIds)
      Unregisters multiple recipes by their IDs.
      Parameters:
      recipeIds - The recipe IDs to unregister
      Returns:
      Number of recipes successfully unregistered
    • unregisterRecipesAndDelete

      @NotNull @NotNull CompletableFuture<Integer> unregisterRecipesAndDelete(@NotNull @NotNull Collection<String> recipeIds)
      Unregisters multiple recipes and deletes them from disk.
      Parameters:
      recipeIds - The recipe IDs to unregister and delete
      Returns:
      CompletableFuture that completes with the number of successful deletions
    • updateRecipe

      boolean updateRecipe(@NotNull @NotNull RecipeBuilder builder)
      Updates an existing recipe with new settings.

      This replaces the existing recipe while preserving craft tracking data. The builder's ID must match an existing recipe.

      Parameters:
      builder - The recipe builder with updated configuration
      Returns:
      true if the recipe was updated successfully
      Throws:
      IllegalArgumentException - if the builder is invalid or recipe doesn't exist
    • updateRecipeAsync

      @NotNull @NotNull CompletableFuture<Boolean> updateRecipeAsync(@NotNull @NotNull RecipeBuilder builder)
      Updates an existing recipe and saves changes to file asynchronously.
      Parameters:
      builder - The recipe builder with updated configuration
      Returns:
      CompletableFuture that completes with true if successful
      Throws:
      IllegalArgumentException - if the builder is invalid
    • getRecipe

      @NotNull @NotNull Optional<ZentrixRecipe> getRecipe(@NotNull @NotNull String recipeId)
      Gets a recipe by its ID.
      Parameters:
      recipeId - The recipe ID
      Returns:
      Optional containing the recipe, or empty if not found
    • getAllRecipes

      @NotNull @NotNull Collection<ZentrixRecipe> getAllRecipes()
      Gets all registered recipes.

      The returned collection is a snapshot and modifications won't affect the actual recipe registry.

      Returns:
      Collection of all registered recipes
    • recipeExists

      boolean recipeExists(@NotNull @NotNull String recipeId)
      Checks if a recipe with the given ID exists.
      Parameters:
      recipeId - The recipe ID to check
      Returns:
      true if a recipe with this ID exists
    • getRecipeCount

      int getRecipeCount()
      Gets the total number of registered recipes.
      Returns:
      The recipe count
    • findRecipesByResult

      @NotNull @NotNull Collection<ZentrixRecipe> findRecipesByResult(@NotNull @NotNull org.bukkit.inventory.ItemStack result)
      Finds recipes by their result item type.

      Returns all recipes that produce an item of the specified type.

      Parameters:
      result - The result item to search for (type is compared)
      Returns:
      Collection of matching recipes
    • findRecipesByCreator

      @NotNull @NotNull Collection<ZentrixRecipe> findRecipesByCreator(@NotNull @NotNull String creatorName)
      Finds recipes created by a specific player.
      Parameters:
      creatorName - The creator's name
      Returns:
      Collection of recipes created by this player
    • getOneTimeRecipes

      @NotNull @NotNull Collection<ZentrixRecipe> getOneTimeRecipes()
      Gets all one-time recipes.
      Returns:
      Collection of one-time recipes
    • getLimitedRecipes

      @NotNull @NotNull Collection<ZentrixRecipe> getLimitedRecipes()
      Gets all recipes with craft limits.
      Returns:
      Collection of recipes that have craft limits
    • canPlayerCraft

      boolean canPlayerCraft(@NotNull @NotNull org.bukkit.entity.Player player, @NotNull @NotNull String recipeId)
      Checks if a recipe can still be crafted in the player's current world.

      IMPORTANT: Craft limits are GLOBAL per world, not per player!

      • One-time recipes: Only 1 player total can craft per world
      • Limited recipes: Only N total crafts allowed per world

      Parameters:
      player - The player (used to determine world)
      recipeId - The recipe ID
      Returns:
      true if the GLOBAL limit hasn't been reached
    • canPlayerCraft

      boolean canPlayerCraft(@NotNull @NotNull UUID playerId, @NotNull @NotNull String recipeId)
      Checks if a recipe can still be crafted in the player's current world.

      IMPORTANT: Craft limits are GLOBAL per world, not per player!

      Note: If the player is offline (not found by UUID), this method returns false because the world cannot be determined. This does NOT mean the recipe cannot be crafted - use canCraftInWorld(String, String) if you know the world name.

      Parameters:
      playerId - The player's UUID (used to determine world)
      recipeId - The recipe ID
      Returns:
      true if the GLOBAL limit hasn't been reached, false if limit reached OR player offline
    • canCraftInWorld

      boolean canCraftInWorld(@NotNull @NotNull String worldName, @NotNull @NotNull String recipeId)
      Checks if a recipe can still be crafted in a specific world.

      IMPORTANT: Craft limits are GLOBAL per world, not per player!

      Parameters:
      worldName - The world name to check
      recipeId - The recipe ID
      Returns:
      true if the GLOBAL limit hasn't been reached
    • getPlayerCraftCount

      int getPlayerCraftCount(@NotNull @NotNull org.bukkit.entity.Player player, @NotNull @NotNull String recipeId)
      Gets how many times a specific player has crafted a recipe in the current game.

      Note: This is for statistics only! Craft limits are checked globally, not per player. Use getRemainingCrafts(Player, String) to check if the recipe can still be crafted.

      Parameters:
      player - The player
      recipeId - The recipe ID
      Returns:
      The number of times THIS player crafted it (for stats)
    • getPlayerCraftCount

      int getPlayerCraftCount(@NotNull @NotNull UUID playerId, @NotNull @NotNull String recipeId)
      Gets how many times a specific player has crafted a recipe in the current game.

      Note: This is for statistics only! Craft limits are checked globally. Returns 0 if the player is offline.

      Parameters:
      playerId - The player's UUID
      recipeId - The recipe ID
      Returns:
      The number of times THIS player crafted it (for stats), 0 if player offline
    • getGlobalCraftCount

      int getGlobalCraftCount(@NotNull @NotNull String worldName, @NotNull @NotNull String recipeId)
      Gets the GLOBAL craft count for a recipe in a specific world.

      This returns the TOTAL number of times ANY player has crafted this recipe in the specified world.

      Parameters:
      worldName - The world name
      recipeId - The recipe ID
      Returns:
      Total crafts in this world by all players
    • getRemainingCrafts

      int getRemainingCrafts(@NotNull @NotNull org.bukkit.entity.Player player, @NotNull @NotNull String recipeId)
      Gets the remaining GLOBAL crafts for a recipe in the player's world.

      IMPORTANT: This returns the GLOBAL remaining count, not per-player!

      • One-time: Returns 1 if not crafted, 0 if someone crafted it
      • Limited (e.g., 9): Returns 9 minus total crafts by ALL players
      • Unlimited: Returns -1

      Parameters:
      player - The player (used to determine world)
      recipeId - The recipe ID
      Returns:
      GLOBAL remaining crafts, -1 if unlimited, 0 if limit reached
    • getRemainingCrafts

      int getRemainingCrafts(@NotNull @NotNull UUID playerId, @NotNull @NotNull String recipeId)
      Gets the remaining GLOBAL crafts for a recipe in the player's world.

      IMPORTANT: This returns the GLOBAL remaining count, not per-player!

      Note: If the player is offline, returns -1 (treated as unlimited/unknown). Use getRemainingCraftsInWorld(String, String) if you know the world name.

      Parameters:
      playerId - The player's UUID (used to determine world)
      recipeId - The recipe ID
      Returns:
      GLOBAL remaining crafts, -1 if unlimited or player offline
    • getRemainingCraftsInWorld

      int getRemainingCraftsInWorld(@NotNull @NotNull String worldName, @NotNull @NotNull String recipeId)
      Gets the remaining GLOBAL crafts for a recipe in a specific world.
      Parameters:
      worldName - The world name
      recipeId - The recipe ID
      Returns:
      GLOBAL remaining crafts, -1 if unlimited
    • hasPlayerEverCrafted

      boolean hasPlayerEverCrafted(@NotNull @NotNull UUID playerId, @NotNull @NotNull String recipeId)
      Checks if a player has ever crafted a specific recipe (for first-time bonus).

      Note: This is for the first-time crafting bonus tracking, not for one-time recipe limits. One-time limits are checked globally.

      Parameters:
      playerId - The player's UUID
      recipeId - The recipe ID
      Returns:
      true if this player has crafted this recipe at least once
    • hasPlayerCraftedOneTime

      @Deprecated(since="1.0.2", forRemoval=true) default boolean hasPlayerCraftedOneTime(@NotNull @NotNull UUID playerId, @NotNull @NotNull String recipeId)
      Deprecated, for removal: This API element is subject to removal in a future version.
      Use hasPlayerEverCrafted(UUID, String) instead. The old name was misleading as it suggested relation to one-time recipes.
    • getRecipeIds

      @NotNull @NotNull Collection<String> getRecipeIds()
      Gets the IDs of all registered recipes.
      Returns:
      Collection of recipe IDs
    • getRecipesByAddon

      @NotNull @NotNull Collection<ZentrixRecipe> getRecipesByAddon(@NotNull @NotNull String addonId)
      Gets recipes added by a specific addon.

      Recipes track their source addon via a custom field.

      Parameters:
      addonId - The addon ID
      Returns:
      Collection of recipes from this addon
    • isRecipePersisted

      boolean isRecipePersisted(@NotNull @NotNull String recipeId)
      Checks if a recipe is persisted to disk.
      Parameters:
      recipeId - The recipe ID
      Returns:
      true if the recipe file exists on disk
    • saveRecipe

      @NotNull @NotNull CompletableFuture<Boolean> saveRecipe(@NotNull @NotNull String recipeId)
      Saves an existing recipe to disk.

      Use this to persist a recipe that was registered without saving, or to update the saved version after modifications.

      Parameters:
      recipeId - The recipe ID to save
      Returns:
      CompletableFuture that completes with true if saved successfully
    • reloadRecipes

      void reloadRecipes()
      Reloads all recipes from disk.

      This clears the recipe registry and reloads from files.

    • isAvailable

      boolean isAvailable()
      Checks if the recipe system is available and ready.
      Returns:
      true if recipes can be registered and queried
    • createBuilder

      @NotNull default @NotNull RecipeBuilder createBuilder()
      Creates a new RecipeBuilder instance.

      Convenience method for creating builders.

      Returns:
      A new RecipeBuilder
    • createBuilder

      @NotNull default @NotNull RecipeBuilder createBuilder(@NotNull @NotNull String id)
      Creates a new RecipeBuilder with the specified ID.
      Parameters:
      id - The recipe ID
      Returns:
      A new RecipeBuilder with the ID set
    • cleanupWorld

      void cleanupWorld(@NotNull @NotNull String worldName)
      Cleans up craft tracking data for a specific world.

      This should be called when a game world is deleted to prevent memory leaks.

      Parameters:
      worldName - The world name to cleanup
    • cleanupPlayer

      void cleanupPlayer(@NotNull @NotNull UUID playerId)
      Cleans up craft tracking data for a specific player.

      This can be called when a player leaves the server permanently to free memory.

      Parameters:
      playerId - The player's UUID to cleanup