From aa01ca2d990187cd2051c00a0ab1cfd4bdde4c0a Mon Sep 17 00:00:00 2001 From: Golfing8 Date: Sat, 7 Mar 2026 16:11:02 -0500 Subject: [PATCH 1/6] Prevent dupe bug with recipe command --- .../earth2me/essentials/commands/Commandrecipe.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java index e63222ab9bb..b31e4c24acc 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java @@ -13,8 +13,10 @@ import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.Server; +import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.FurnaceRecipe; import org.bukkit.inventory.InventoryView; +import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Recipe; import org.bukkit.inventory.RecipeChoice; @@ -159,6 +161,14 @@ public void shapedRecipe(final CommandSource sender, final ShapedRecipe recipe, user.getBase().closeInventory(); user.setRecipeSee(true); final InventoryView view = user.getBase().openWorkbench(null, true); + // If InventoryOpenEvent is canceled, the items can end up in the player's own crafting grid + // which allows players to extract counterfeit items. + InventoryViewProvider provider = ess.provider(InventoryViewProvider.class); + Inventory topInventory = provider.getTopInventory(view); + if (topInventory.getType() != InventoryType.WORKBENCH) { + return; + } + final String[] recipeShape = recipe.getShape(); final Map ingredientMap = recipe.getIngredientMap(); for (int j = 0; j < recipeShape.length; j++) { @@ -170,7 +180,7 @@ public void shapedRecipe(final CommandSource sender, final ShapedRecipe recipe, if (VersionUtil.PRE_FLATTENING && item.getDurability() == Short.MAX_VALUE) { item.setDurability((short) 0); } - ess.provider(InventoryViewProvider.class).getTopInventory(view).setItem(j * 3 + k + 1, item); + topInventory.setItem(j * 3 + k + 1, item); } } } else { From 4fd19a826e10f3bbd6baa3cb7075cb4ae60c98dc Mon Sep 17 00:00:00 2001 From: Josh Roy <10731363+JRoy@users.noreply.github.com> Date: Sun, 8 Mar 2026 14:56:48 -0700 Subject: [PATCH 2/6] Update Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java Co-authored-by: Benedikt Johannes --- .../java/com/earth2me/essentials/commands/Commandrecipe.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java index b31e4c24acc..c12e1d4e346 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java @@ -164,7 +164,7 @@ public void shapedRecipe(final CommandSource sender, final ShapedRecipe recipe, // If InventoryOpenEvent is canceled, the items can end up in the player's own crafting grid // which allows players to extract counterfeit items. InventoryViewProvider provider = ess.provider(InventoryViewProvider.class); - Inventory topInventory = provider.getTopInventory(view); + final Inventory topInventory = provider.getTopInventory(view); if (topInventory.getType() != InventoryType.WORKBENCH) { return; } From 8f4ab6ce259aa1ca3b92540d2c63df34152abc6c Mon Sep 17 00:00:00 2001 From: Golfing7 Date: Sun, 8 Mar 2026 18:32:12 -0400 Subject: [PATCH 3/6] Fix checkstyle --- .../java/com/earth2me/essentials/commands/Commandrecipe.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java index c12e1d4e346..b44cf67fc0b 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java @@ -163,9 +163,10 @@ public void shapedRecipe(final CommandSource sender, final ShapedRecipe recipe, final InventoryView view = user.getBase().openWorkbench(null, true); // If InventoryOpenEvent is canceled, the items can end up in the player's own crafting grid // which allows players to extract counterfeit items. - InventoryViewProvider provider = ess.provider(InventoryViewProvider.class); + final InventoryViewProvider provider = ess.provider(InventoryViewProvider.class); final Inventory topInventory = provider.getTopInventory(view); if (topInventory.getType() != InventoryType.WORKBENCH) { + user.setRecipeSee(false); return; } From 709ca752a63220db2bb3be22a6e32a9ff99a7342 Mon Sep 17 00:00:00 2001 From: Golfing7 Date: Sun, 8 Mar 2026 22:49:31 -0400 Subject: [PATCH 4/6] Fix shapeless recipe problem --- .../essentials/commands/Commandrecipe.java | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java index b44cf67fc0b..e878a327643 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java @@ -36,6 +36,7 @@ public class Commandrecipe extends EssentialsCommand { private static final Material FIREWORK_STAR = EnumUtil.getMaterial("FIREWORK_STAR", "FIREWORK_CHARGE"); private static final Material GUNPOWDER = EnumUtil.getMaterial("GUNPOWDER", "SULPHUR"); private final boolean unsupported; + private final InventoryViewProvider inventoryViewProvider; public Commandrecipe() { super("recipe"); @@ -49,6 +50,7 @@ public Commandrecipe() { } } this.unsupported = unsupported; + this.inventoryViewProvider = ess.provider(InventoryViewProvider.class); } @Override @@ -160,15 +162,12 @@ public void shapedRecipe(final CommandSource sender, final ShapedRecipe recipe, final User user = ess.getUser(sender.getPlayer()); user.getBase().closeInventory(); user.setRecipeSee(true); - final InventoryView view = user.getBase().openWorkbench(null, true); - // If InventoryOpenEvent is canceled, the items can end up in the player's own crafting grid - // which allows players to extract counterfeit items. - final InventoryViewProvider provider = ess.provider(InventoryViewProvider.class); - final Inventory topInventory = provider.getTopInventory(view); - if (topInventory.getType() != InventoryType.WORKBENCH) { + final InventoryView view = openWorkbench(user); + if (view == null) { user.setRecipeSee(false); return; } + final Inventory topInventory = inventoryViewProvider.getTopInventory(view); final String[] recipeShape = recipe.getShape(); final Map ingredientMap = recipe.getIngredientMap(); @@ -228,13 +227,17 @@ public void shapelessRecipe(final CommandSource sender, final ShapelessRecipe re final User user = ess.getUser(sender.getPlayer()); user.getBase().closeInventory(); user.setRecipeSee(true); - final InventoryView view = user.getBase().openWorkbench(null, true); + final InventoryView view = openWorkbench(user); + if (view == null) { + user.setRecipeSee(false); + return; + } for (int i = 0; i < ingredients.size(); i++) { final ItemStack item = ingredients.get(i); if (VersionUtil.PRE_FLATTENING && item.getDurability() == Short.MAX_VALUE) { item.setDurability((short) 0); } - ess.provider(InventoryViewProvider.class).setItem(view, i + 1, item); + inventoryViewProvider.setItem(view, i + 1, item); } } else { @@ -250,6 +253,17 @@ public void shapelessRecipe(final CommandSource sender, final ShapelessRecipe re } } + private InventoryView openWorkbench(final User user) { + final InventoryView view = user.getBase().openWorkbench(null, true); + // If InventoryOpenEvent is canceled, the items can end up in the player's own crafting grid + // which allows players to extract counterfeit items. + if (view == null) + return null; + + final Inventory inventory = inventoryViewProvider.getTopInventory(view); + return inventory.getType() == InventoryType.CRAFTING ? view : null; + } + public String getMaterialName(final CommandSource sender, final ItemStack stack) { if (stack == null) { return sender.tl("recipeNothing"); From 2776b84fd55c888b6d77efb09c4d25b014c9a0b8 Mon Sep 17 00:00:00 2001 From: Golfing7 Date: Mon, 9 Mar 2026 12:12:23 -0400 Subject: [PATCH 5/6] Fix incorrect inventorytype --- .../java/com/earth2me/essentials/commands/Commandrecipe.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java index e878a327643..d964b2b9850 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java @@ -261,7 +261,7 @@ private InventoryView openWorkbench(final User user) { return null; final Inventory inventory = inventoryViewProvider.getTopInventory(view); - return inventory.getType() == InventoryType.CRAFTING ? view : null; + return inventory.getType() == InventoryType.WORKBENCH ? view : null; } public String getMaterialName(final CommandSource sender, final ItemStack stack) { From 4fb464f741e6023563f774b148d00c14408bc20d Mon Sep 17 00:00:00 2001 From: Golfing7 Date: Mon, 9 Mar 2026 12:14:28 -0400 Subject: [PATCH 6/6] Fix provider error --- .../com/earth2me/essentials/commands/Commandrecipe.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java index d964b2b9850..9a0a0f0ca87 100644 --- a/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java +++ b/Essentials/src/main/java/com/earth2me/essentials/commands/Commandrecipe.java @@ -36,7 +36,6 @@ public class Commandrecipe extends EssentialsCommand { private static final Material FIREWORK_STAR = EnumUtil.getMaterial("FIREWORK_STAR", "FIREWORK_CHARGE"); private static final Material GUNPOWDER = EnumUtil.getMaterial("GUNPOWDER", "SULPHUR"); private final boolean unsupported; - private final InventoryViewProvider inventoryViewProvider; public Commandrecipe() { super("recipe"); @@ -50,7 +49,6 @@ public Commandrecipe() { } } this.unsupported = unsupported; - this.inventoryViewProvider = ess.provider(InventoryViewProvider.class); } @Override @@ -167,7 +165,7 @@ public void shapedRecipe(final CommandSource sender, final ShapedRecipe recipe, user.setRecipeSee(false); return; } - final Inventory topInventory = inventoryViewProvider.getTopInventory(view); + final Inventory topInventory = ess.provider(InventoryViewProvider.class).getTopInventory(view); final String[] recipeShape = recipe.getShape(); final Map ingredientMap = recipe.getIngredientMap(); @@ -237,7 +235,7 @@ public void shapelessRecipe(final CommandSource sender, final ShapelessRecipe re if (VersionUtil.PRE_FLATTENING && item.getDurability() == Short.MAX_VALUE) { item.setDurability((short) 0); } - inventoryViewProvider.setItem(view, i + 1, item); + ess.provider(InventoryViewProvider.class).setItem(view, i + 1, item); } } else { @@ -260,7 +258,7 @@ private InventoryView openWorkbench(final User user) { if (view == null) return null; - final Inventory inventory = inventoryViewProvider.getTopInventory(view); + final Inventory inventory = ess.provider(InventoryViewProvider.class).getTopInventory(view); return inventory.getType() == InventoryType.WORKBENCH ? view : null; }