From ad2a0d43eaceb1a6fafb901c9511e576b1e8099f Mon Sep 17 00:00:00 2001 From: Pim van der Loos Date: Sun, 12 Jul 2026 12:07:47 +0200 Subject: [PATCH 1/2] Fix stick dupe Closes #74 --- NEXT_RELEASE_CHANGELOG.md | 1 + .../java/nl/pim16aap2/bigDoors/BigDoors.java | 2 + .../bigDoors/handlers/EventHandlers.java | 11 +- .../bigDoors/handlers/GrindstoneListener.java | 115 ++++++++++++++++++ 4 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 core/src/main/java/nl/pim16aap2/bigDoors/handlers/GrindstoneListener.java diff --git a/NEXT_RELEASE_CHANGELOG.md b/NEXT_RELEASE_CHANGELOG.md index 961302d5c..897194fa4 100644 --- a/NEXT_RELEASE_CHANGELOG.md +++ b/NEXT_RELEASE_CHANGELOG.md @@ -1 +1,2 @@ - Fix support for version before MC 1.16.5. +- Fixed a way to dupe the BigDoors stick. Thanks, 1Pootis1, for the bug report! diff --git a/core/src/main/java/nl/pim16aap2/bigDoors/BigDoors.java b/core/src/main/java/nl/pim16aap2/bigDoors/BigDoors.java index 839c99fd1..e24e0bbab 100644 --- a/core/src/main/java/nl/pim16aap2/bigDoors/BigDoors.java +++ b/core/src/main/java/nl/pim16aap2/bigDoors/BigDoors.java @@ -42,6 +42,7 @@ import nl.pim16aap2.bigDoors.handlers.EventHandlers; import nl.pim16aap2.bigDoors.handlers.FailureCommandHandler; import nl.pim16aap2.bigDoors.handlers.GUIHandler; +import nl.pim16aap2.bigDoors.handlers.GrindstoneListener; import nl.pim16aap2.bigDoors.handlers.LoginMessageHandler; import nl.pim16aap2.bigDoors.handlers.LoginResourcePackHandler; import nl.pim16aap2.bigDoors.handlers.RedstoneHandler; @@ -273,6 +274,7 @@ else if (config.unsafeModeNotification()) Bukkit.getPluginManager().registerEvents(new EventHandlers(this), this); Bukkit.getPluginManager().registerEvents(new GUIHandler(this), this); Bukkit.getPluginManager().registerEvents(new ChunkUnloadHandler(this), this); + GrindstoneListener.tryRegister(this); // No need to put these in init, as they should not be reloaded. pbCache = new TimedCache<>(config.cacheTimeout()); diff --git a/core/src/main/java/nl/pim16aap2/bigDoors/handlers/EventHandlers.java b/core/src/main/java/nl/pim16aap2/bigDoors/handlers/EventHandlers.java index 9bbf198e4..b5c0d19e0 100644 --- a/core/src/main/java/nl/pim16aap2/bigDoors/handlers/EventHandlers.java +++ b/core/src/main/java/nl/pim16aap2/bigDoors/handlers/EventHandlers.java @@ -1,7 +1,9 @@ package nl.pim16aap2.bigDoors.handlers; -import java.text.MessageFormat; - +import nl.pim16aap2.bigDoors.BigDoors; +import nl.pim16aap2.bigDoors.Door; +import nl.pim16aap2.bigDoors.events.DoorEventToggleStart; +import nl.pim16aap2.bigDoors.toolUsers.ToolUser; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -20,10 +22,7 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.PlayerInventory; -import nl.pim16aap2.bigDoors.BigDoors; -import nl.pim16aap2.bigDoors.Door; -import nl.pim16aap2.bigDoors.events.DoorEventToggleStart; -import nl.pim16aap2.bigDoors.toolUsers.ToolUser; +import java.text.MessageFormat; public class EventHandlers implements Listener { diff --git a/core/src/main/java/nl/pim16aap2/bigDoors/handlers/GrindstoneListener.java b/core/src/main/java/nl/pim16aap2/bigDoors/handlers/GrindstoneListener.java new file mode 100644 index 000000000..eda3e3e4c --- /dev/null +++ b/core/src/main/java/nl/pim16aap2/bigDoors/handlers/GrindstoneListener.java @@ -0,0 +1,115 @@ +package nl.pim16aap2.bigDoors.handlers; + +import nl.pim16aap2.bigDoors.BigDoors; +import org.bukkit.Bukkit; +import org.bukkit.event.Event; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryEvent; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.lang.reflect.Method; + +public class GrindstoneListener implements Listener +{ + private static final String EVENT_CLASS_NAME = "org.bukkit.event.inventory.PrepareGrindstoneEvent"; + + private final BigDoors bigDoors; + + private final Class clzPrepareGrindstoneEvent; + private final Method methodSetResult; + private final InventoryType grindStoneInventoryType; + + GrindstoneListener( + BigDoors bigDoors, + Class clzPrepareGrindstoneEvent, + Method methodSetResult, + InventoryType grindStoneInventoryType + ) + { + this.bigDoors = bigDoors; + this.clzPrepareGrindstoneEvent = clzPrepareGrindstoneEvent; + this.methodSetResult = methodSetResult; + this.grindStoneInventoryType = grindStoneInventoryType; + } + + public static void tryRegister(BigDoors bigDoors) + { + final Class clzPrepareGrindstoneEvent; + final Method methodSetResult; + final InventoryType grindStoneInventoryType; + try + { + clzPrepareGrindstoneEvent = Class.forName(EVENT_CLASS_NAME).asSubclass(Event.class); + methodSetResult = clzPrepareGrindstoneEvent.getMethod("setResult", ItemStack.class); + grindStoneInventoryType = InventoryType.valueOf("GRINDSTONE"); + } + catch (ReflectiveOperationException e) + { + return; + } + + final GrindstoneListener listener = new GrindstoneListener( + bigDoors, + clzPrepareGrindstoneEvent, + methodSetResult, + grindStoneInventoryType + ); + + Bukkit.getPluginManager().registerEvent( + clzPrepareGrindstoneEvent, + listener, + EventPriority.HIGHEST, + (ignored, event) -> listener.onPrepareGrindstone(event), + bigDoors, + true + ); + + Bukkit.getPluginManager().registerEvent( + InventoryClickEvent.class, + listener, + EventPriority.HIGHEST, + (ignored, event) -> listener.onInventoryClick(event), + bigDoors, + true + ); + } + + void onInventoryClick(Event event) + { + if (!(event instanceof InventoryClickEvent)) + return; + + final InventoryClickEvent ice = (InventoryClickEvent) event; + if (ice.getClickedInventory() == null) + return; + + if (ice.getClickedInventory().getType() != grindStoneInventoryType) + return; + + if (bigDoors.getTF().isTool(ice.getCurrentItem()) || bigDoors.getTF().isTool(ice.getCursor())) + ice.setCancelled(true); + } + + void onPrepareGrindstone(Event event) + { + if (!clzPrepareGrindstoneEvent.isInstance(event)) + return; + + final Inventory inventory = ((InventoryEvent) event).getInventory(); + if (!bigDoors.getTF().isTool(inventory.getItem(0)) && !bigDoors.getTF().isTool(inventory.getItem(1))) + return; + + try + { + methodSetResult.invoke(event, (Object) null); + } + catch (ReflectiveOperationException exception) + { + bigDoors.getMyLogger().log(exception); + } + } +} From 612d8c28e674dba66bab7f4157b984868d26f4cb Mon Sep 17 00:00:00 2001 From: Pim van der Loos Date: Sun, 12 Jul 2026 13:14:12 +0200 Subject: [PATCH 2/2] Support grindstone filtering on versions between grindstone introduction and PrepareGrindstoneEvent introduction --- .../bigDoors/handlers/GrindstoneListener.java | 91 +++++++++++-------- 1 file changed, 52 insertions(+), 39 deletions(-) diff --git a/core/src/main/java/nl/pim16aap2/bigDoors/handlers/GrindstoneListener.java b/core/src/main/java/nl/pim16aap2/bigDoors/handlers/GrindstoneListener.java index eda3e3e4c..ba3a66a88 100644 --- a/core/src/main/java/nl/pim16aap2/bigDoors/handlers/GrindstoneListener.java +++ b/core/src/main/java/nl/pim16aap2/bigDoors/handlers/GrindstoneListener.java @@ -1,6 +1,7 @@ package nl.pim16aap2.bigDoors.handlers; import nl.pim16aap2.bigDoors.BigDoors; +import nl.pim16aap2.bigDoors.reflection.ReflectionBuilder; import org.bukkit.Bukkit; import org.bukkit.event.Event; import org.bukkit.event.EventPriority; @@ -11,6 +12,7 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; +import javax.annotation.Nullable; import java.lang.reflect.Method; public class GrindstoneListener implements Listener @@ -19,66 +21,77 @@ public class GrindstoneListener implements Listener private final BigDoors bigDoors; - private final Class clzPrepareGrindstoneEvent; - private final Method methodSetResult; - private final InventoryType grindStoneInventoryType; - - GrindstoneListener( - BigDoors bigDoors, - Class clzPrepareGrindstoneEvent, - Method methodSetResult, - InventoryType grindStoneInventoryType - ) + GrindstoneListener(BigDoors bigDoors) { this.bigDoors = bigDoors; - this.clzPrepareGrindstoneEvent = clzPrepareGrindstoneEvent; - this.methodSetResult = methodSetResult; - this.grindStoneInventoryType = grindStoneInventoryType; } - public static void tryRegister(BigDoors bigDoors) + private boolean tryRegisterOnGrindstoneInventoryClick(GrindstoneListener listener) { - final Class clzPrepareGrindstoneEvent; - final Method methodSetResult; - final InventoryType grindStoneInventoryType; - try - { - clzPrepareGrindstoneEvent = Class.forName(EVENT_CLASS_NAME).asSubclass(Event.class); - methodSetResult = clzPrepareGrindstoneEvent.getMethod("setResult", ItemStack.class); - grindStoneInventoryType = InventoryType.valueOf("GRINDSTONE"); - } - catch (ReflectiveOperationException e) - { - return; - } + final @Nullable InventoryType grindStoneInventoryType = (InventoryType) ReflectionBuilder.findEnumValues() + .inClass(InventoryType.class) + .withName("GRINDSTONE") + .setNullable() + .get(); - final GrindstoneListener listener = new GrindstoneListener( - bigDoors, - clzPrepareGrindstoneEvent, - methodSetResult, - grindStoneInventoryType - ); + // Grindstone inventory type was introduced in 1.14; clzPrepareGrindstoneEvent in 1.16. + if (grindStoneInventoryType == null) + return false; Bukkit.getPluginManager().registerEvent( - clzPrepareGrindstoneEvent, + InventoryClickEvent.class, listener, EventPriority.HIGHEST, - (ignored, event) -> listener.onPrepareGrindstone(event), + (ignored, event) -> listener.onGrindstoneInventoryClick(event, grindStoneInventoryType), bigDoors, true ); + return true; + } + + @SuppressWarnings("unchecked") + private void tryRegisterOnPrepareGrindstone(GrindstoneListener listener) + { + final @Nullable Class clzPrepareGrindstoneEvent = (Class) ReflectionBuilder + .findClass() + .withNames(EVENT_CLASS_NAME) + .setNullable() + .get(); + if (clzPrepareGrindstoneEvent == null) + return; + + final @Nullable Method methodSetResult = ReflectionBuilder.findMethod() + .inClass(clzPrepareGrindstoneEvent) + .withName("setResult") + .withParameters(ItemStack.class) + .setNullable() + .get(); + if (methodSetResult == null) + return; + + Bukkit.getPluginManager().registerEvent( - InventoryClickEvent.class, + clzPrepareGrindstoneEvent, listener, EventPriority.HIGHEST, - (ignored, event) -> listener.onInventoryClick(event), + (ignored, event) -> listener.onPrepareGrindstone(event, clzPrepareGrindstoneEvent, methodSetResult), bigDoors, true ); } - void onInventoryClick(Event event) + public static void tryRegister(BigDoors bigDoors) + { + final GrindstoneListener listener = new GrindstoneListener(bigDoors); + + if (!listener.tryRegisterOnGrindstoneInventoryClick(listener)) + return; + + listener.tryRegisterOnPrepareGrindstone(listener); + } + + void onGrindstoneInventoryClick(Event event, InventoryType grindStoneInventoryType) { if (!(event instanceof InventoryClickEvent)) return; @@ -94,7 +107,7 @@ void onInventoryClick(Event event) ice.setCancelled(true); } - void onPrepareGrindstone(Event event) + void onPrepareGrindstone(Event event, Class clzPrepareGrindstoneEvent, Method methodSetResult) { if (!clzPrepareGrindstoneEvent.isInstance(event)) return;