diff --git a/eco-api/src/main/java/com/willfp/eco/core/recipe/Recipes.java b/eco-api/src/main/java/com/willfp/eco/core/recipe/Recipes.java index b23d0797..7f2134ad 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/recipe/Recipes.java +++ b/eco-api/src/main/java/com/willfp/eco/core/recipe/Recipes.java @@ -79,7 +79,27 @@ public final class Recipes { @NotNull final String key, @NotNull final ItemStack output, @NotNull final List recipeStrings) { - ShapedCraftingRecipe.Builder builder = ShapedCraftingRecipe.builder(plugin, key).setOutput(output); + return createAndRegisterRecipe(plugin, key, output, recipeStrings, null); + } + + /** + * Create and register recipe. + * + * @param plugin The plugin. + * @param key The key. + * @param output The output. + * @param recipeStrings The recipe. + * @param permission The permission. + * @return The recipe. + */ + public static CraftingRecipe createAndRegisterRecipe(@NotNull final EcoPlugin plugin, + @NotNull final String key, + @NotNull final ItemStack output, + @NotNull final List recipeStrings, + @Nullable final String permission) { + ShapedCraftingRecipe.Builder builder = ShapedCraftingRecipe.builder(plugin, key) + .setOutput(output) + .setPermission(permission); for (int i = 0; i < 9; i++) { builder.setRecipePart(i, Items.lookup(recipeStrings.get(i))); diff --git a/eco-api/src/main/java/com/willfp/eco/core/recipe/recipes/CraftingRecipe.java b/eco-api/src/main/java/com/willfp/eco/core/recipe/recipes/CraftingRecipe.java index e34d21eb..830fba3c 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/recipe/recipes/CraftingRecipe.java +++ b/eco-api/src/main/java/com/willfp/eco/core/recipe/recipes/CraftingRecipe.java @@ -4,6 +4,7 @@ import com.willfp.eco.core.items.TestableItem; import org.bukkit.NamespacedKey; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -31,6 +32,7 @@ public interface CraftingRecipe { * * @return The parts. */ + @NotNull List getParts(); /** @@ -38,6 +40,7 @@ public interface CraftingRecipe { * * @return The key. */ + @NotNull NamespacedKey getKey(); /** @@ -45,6 +48,7 @@ public interface CraftingRecipe { * * @return The key. */ + @NotNull NamespacedKey getDisplayedKey(); /** @@ -52,5 +56,16 @@ public interface CraftingRecipe { * * @return The output. */ + @NotNull ItemStack getOutput(); + + /** + * Get the recipe permission. + * + * @return The permission. + */ + @Nullable + default String getPermission() { + return null; + } } diff --git a/eco-api/src/main/java/com/willfp/eco/core/recipe/recipes/ShapedCraftingRecipe.java b/eco-api/src/main/java/com/willfp/eco/core/recipe/recipes/ShapedCraftingRecipe.java index 0f83b591..7dc1ed22 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/recipe/recipes/ShapedCraftingRecipe.java +++ b/eco-api/src/main/java/com/willfp/eco/core/recipe/recipes/ShapedCraftingRecipe.java @@ -15,6 +15,7 @@ import org.bukkit.inventory.RecipeChoice; import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.meta.ItemMeta; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Arrays; @@ -44,16 +45,23 @@ public final class ShapedCraftingRecipe extends PluginDependent imple */ private final ItemStack output; + /** + * The permission. + */ + private final String permission; + private ShapedCraftingRecipe(@NotNull final EcoPlugin plugin, @NotNull final String key, @NotNull final List parts, - @NotNull final ItemStack output) { + @NotNull final ItemStack output, + @Nullable final String permission) { super(plugin); this.parts = parts; this.key = plugin.getNamespacedKeyFactory().create(key); this.displayedKey = plugin.getNamespacedKeyFactory().create(key + "_displayed"); this.output = output; + this.permission = permission; } @Override @@ -140,6 +148,8 @@ public final class ShapedCraftingRecipe extends PluginDependent imple * * @return The parts. */ + @NotNull + @Override public List getParts() { return this.parts; } @@ -149,6 +159,8 @@ public final class ShapedCraftingRecipe extends PluginDependent imple * * @return The key. */ + @NotNull + @Override public NamespacedKey getKey() { return this.key; } @@ -158,6 +170,8 @@ public final class ShapedCraftingRecipe extends PluginDependent imple * * @return The displayed key. */ + @NotNull + @Override public NamespacedKey getDisplayedKey() { return this.displayedKey; } @@ -167,10 +181,23 @@ public final class ShapedCraftingRecipe extends PluginDependent imple * * @return The output. */ + @NotNull + @Override public ItemStack getOutput() { return this.output; } + /** + * Get the permission. + * + * @return The permission. + */ + @Nullable + @Override + public String getPermission() { + return permission; + } + /** * Builder for recipes. */ @@ -185,6 +212,11 @@ public final class ShapedCraftingRecipe extends PluginDependent imple */ private ItemStack output = null; + /** + * The permission for the recipe. + */ + private String permission = null; + /** * The key of the recipe. */ @@ -244,6 +276,16 @@ public final class ShapedCraftingRecipe extends PluginDependent imple return this; } + /** + * Set the permission required to craft the recipe. + * + * @param permission The permission. + */ + public Builder setPermission(@Nullable final String permission) { + this.permission = permission; + return this; + } + /** * Build the recipe. * @@ -256,7 +298,7 @@ public final class ShapedCraftingRecipe extends PluginDependent imple } } - return new ShapedCraftingRecipe(plugin, key.toLowerCase(), recipeParts, output); + return new ShapedCraftingRecipe(plugin, key.toLowerCase(), recipeParts, output, permission); } } } diff --git a/eco-core/core-plugin/src/main/java/com/willfp/eco/internal/spigot/recipes/ShapedRecipeListener.java b/eco-core/core-plugin/src/main/java/com/willfp/eco/internal/spigot/recipes/ShapedRecipeListener.java index 83f4464c..40a03767 100644 --- a/eco-core/core-plugin/src/main/java/com/willfp/eco/internal/spigot/recipes/ShapedRecipeListener.java +++ b/eco-core/core-plugin/src/main/java/com/willfp/eco/internal/spigot/recipes/ShapedRecipeListener.java @@ -12,6 +12,7 @@ import com.willfp.eco.core.recipe.recipes.CraftingRecipe; import com.willfp.eco.core.recipe.recipes.ShapedCraftingRecipe; import org.bukkit.Keyed; import org.bukkit.Material; +import org.bukkit.entity.Player; import org.bukkit.event.Event; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -28,6 +29,29 @@ public class ShapedRecipeListener extends PluginDependent implements super(plugin); } + private void allow(@NotNull final Event event, + @NotNull final CraftingRecipe recipe) { + if (event instanceof PrepareItemCraftEvent) { + ((PrepareItemCraftEvent) event).getInventory().setResult(recipe.getOutput()); + } + + if (event instanceof CraftItemEvent) { + ((CraftItemEvent) event).getInventory().setResult(recipe.getOutput()); + } + } + + private void deny(@NotNull final Event event) { + if (event instanceof PrepareItemCraftEvent) { + ((PrepareItemCraftEvent) event).getInventory().setResult(new ItemStack(Material.AIR)); + } + + if (event instanceof CraftItemEvent) { + ((CraftItemEvent) event).getInventory().setResult(new ItemStack(Material.AIR)); + ((CraftItemEvent) event).setResult(Event.Result.DENY); + ((CraftItemEvent) event).setCancelled(true); + } + } + @EventHandler public void complexRecipeListener(@NotNull final PrepareItemCraftEvent event) { if (!(event.getRecipe() instanceof ShapedRecipe recipe)) { @@ -38,18 +62,30 @@ public class ShapedRecipeListener extends PluginDependent implements return; } + if (!(event.getInventory().getViewers().get(0) instanceof Player player)) { + return; + } + ItemStack[] matrix = event.getInventory().getMatrix(); CraftingRecipe matched = Recipes.getMatch(matrix); if (matched == null) { - event.getInventory().setResult(new ItemStack(Material.AIR)); + deny(event); return; } if (matched.test(matrix)) { - event.getInventory().setResult(matched.getOutput()); + if (matched.getPermission() != null) { + if (player.hasPermission(matched.getPermission())) { + allow(event, matched); + } else { + deny(event); + } + } else { + allow(event, matched); + } } else { - event.getInventory().setResult(new ItemStack(Material.AIR)); + deny(event); } } @@ -63,25 +99,33 @@ public class ShapedRecipeListener extends PluginDependent implements return; } + if (!(event.getInventory().getViewers().get(0) instanceof Player player)) { + return; + } + ItemStack[] matrix = event.getInventory().getMatrix(); CraftingRecipe matched = Recipes.getMatch(matrix); if (matched == null) { - event.getInventory().setResult(new ItemStack(Material.AIR)); - event.setResult(Event.Result.DENY); - event.setCancelled(true); + deny(event); return; } if (matched.test(matrix)) { - event.getInventory().setResult(matched.getOutput()); + if (matched.getPermission() != null) { + if (player.hasPermission(matched.getPermission())) { + allow(event, matched); + } else { + deny(event); + } + } else { + allow(event, matched); + } } else { - event.getInventory().setResult(new ItemStack(Material.AIR)); - event.setResult(Event.Result.DENY); - event.setCancelled(true); + deny(event); } } - + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void stackedRecipeListener(@NotNull final CraftItemEvent event) { if (!(event.getRecipe() instanceof ShapedRecipe recipe)) { @@ -199,7 +243,7 @@ public class ShapedRecipeListener extends PluginDependent implements } } } - + @EventHandler public void preventUsingComplexPartInEcoRecipe(@NotNull final CraftItemEvent event) { if (!(event.getRecipe() instanceof ShapedRecipe recipe)) { @@ -243,7 +287,7 @@ public class ShapedRecipeListener extends PluginDependent implements } } } - + @EventHandler public void preventUsingComplexPartInVanillaRecipe(@NotNull final PrepareItemCraftEvent event) { if (!(event.getRecipe() instanceof Keyed recipe)) {