From 0bcda4f71d048b6387ba87ade848978239c5e3be Mon Sep 17 00:00:00 2001 From: RobertWesner Date: Sat, 21 Mar 2026 09:17:35 +0100 Subject: [PATCH 1/6] BOSEConomy -> BOSEconomy --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f8f23e8..a8c52d9 100644 --- a/pom.xml +++ b/pom.xml @@ -35,7 +35,7 @@ BOSEconomy 1.0 system - ${project.basedir}/lib/BOSEConomy.jar + ${project.basedir}/lib/BOSEconomy.jar com.earth2me.essentials @@ -157,4 +157,4 @@ - \ No newline at end of file + From afc7d801eb0f3a87acdd82130bfd73b7329ac97d Mon Sep 17 00:00:00 2001 From: RobertWesner Date: Sat, 21 Mar 2026 10:58:24 +0100 Subject: [PATCH 2/6] Prevent dangling protection though sand falling. --- pom.xml | 2 +- .../listeners/LWCBlockListener.java | 76 +++++++++++++++++-- .../java/com/griefcraft/lwc/LWCPlugin.java | 1 + 3 files changed, 72 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index a8c52d9..5e2548c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ LWC LWC jar - 3.53 + 3.54 UTF-8 diff --git a/src/main/java/com/griefcraft/listeners/LWCBlockListener.java b/src/main/java/com/griefcraft/listeners/LWCBlockListener.java index 932c98d..b802e32 100644 --- a/src/main/java/com/griefcraft/listeners/LWCBlockListener.java +++ b/src/main/java/com/griefcraft/listeners/LWCBlockListener.java @@ -15,21 +15,48 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.entity.Player; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockListener; -import org.bukkit.event.block.BlockPistonExtendEvent; -import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.block.BlockRedstoneEvent; -import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.event.block.*; +import org.bukkit.material.Attachable; import org.bukkit.material.MaterialData; import org.bukkit.material.PistonBaseMaterial; +import java.util.*; + public class LWCBlockListener extends BlockListener { /** * The plugin instance */ private LWCPlugin plugin; + private Set attachmentsTopToCheck = new HashSet<>( + Arrays.asList( + Material.SAPLING, + Material.POWERED_RAIL, + Material.DETECTOR_RAIL, + Material.LONG_GRASS, + Material.DEAD_BUSH, + Material.YELLOW_FLOWER, + Material.RED_ROSE, + Material.BROWN_MUSHROOM, + Material.RED_MUSHROOM, + Material.TORCH, + Material.FIRE, + Material.REDSTONE_WIRE, + Material.SIGN_POST, + Material.WOODEN_DOOR, + Material.RAILS, + Material.LEVER, + Material.STONE_PLATE, + Material.IRON_DOOR_BLOCK, + Material.WOOD_PLATE, + Material.REDSTONE_TORCH_OFF, + Material.REDSTONE_TORCH_ON, + Material.SNOW, + Material.CACTUS, + Material.SUGAR_CANE_BLOCK, + Material.CAKE_BLOCK + ) + ); public LWCBlockListener(LWCPlugin plugin) { this.plugin = plugin; @@ -135,6 +162,43 @@ public void onBlockBreak(BlockBreakEvent event) { } } + @Override + public void onBlockPhysics(BlockPhysicsEvent event) { + if (event.isCancelled()) { + return; + } + + if (event.getBlock().getType() != Material.SAND && event.getBlock().getType() != Material.GRAVEL) { + return; + } + + LWC lwc = plugin.getLWC(); + Block upNeighbor = event.getBlock().getRelative(BlockFace.UP); + if (attachmentsTopToCheck.contains(upNeighbor.getType()) && lwc.findProtection(upNeighbor) != null) { + event.setCancelled(true); + + return; + } + + List horizontals = Arrays.asList( + BlockFace.NORTH, + BlockFace.EAST, + BlockFace.SOUTH, + BlockFace.WEST + ); + for (BlockFace face: horizontals) { + Block neighbor = event.getBlock().getRelative(face); + if (neighbor.getState() != null && (neighbor.getState().getData() instanceof Attachable)) { + Attachable data = (Attachable) neighbor.getState().getData(); + if (data.getAttachedFace() == face.getOppositeFace() && lwc.findProtection(neighbor) != null) { + event.setCancelled(true); + + return; + } + } + } + } + @Override public void onBlockPistonExtend(BlockPistonExtendEvent event) { if (!LWC.ENABLED) { diff --git a/src/main/java/com/griefcraft/lwc/LWCPlugin.java b/src/main/java/com/griefcraft/lwc/LWCPlugin.java index 126066d..84fc85c 100644 --- a/src/main/java/com/griefcraft/lwc/LWCPlugin.java +++ b/src/main/java/com/griefcraft/lwc/LWCPlugin.java @@ -399,6 +399,7 @@ private void registerEvents() { registerEvent(blockListener, Type.REDSTONE_CHANGE); registerEvent(blockListener, Type.SIGN_CHANGE); registerEvent(blockListener, Type.BLOCK_PISTON_EXTEND); + registerEvent(blockListener, Type.BLOCK_PHYSICS); /* Server events */ registerEvent(serverListener, Type.PLUGIN_DISABLE); From 6f14a0a22eab1facb61fbecd28fba9339ac14265 Mon Sep 17 00:00:00 2001 From: RobertWesner Date: Sat, 21 Mar 2026 22:14:46 +0100 Subject: [PATCH 3/6] Remove private air when interacting. --- .../listeners/LWCBlockListener.java | 4 +++ .../listeners/LWCPlayerListener.java | 34 +++++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/griefcraft/listeners/LWCBlockListener.java b/src/main/java/com/griefcraft/listeners/LWCBlockListener.java index b802e32..570d500 100644 --- a/src/main/java/com/griefcraft/listeners/LWCBlockListener.java +++ b/src/main/java/com/griefcraft/listeners/LWCBlockListener.java @@ -168,6 +168,10 @@ public void onBlockPhysics(BlockPhysicsEvent event) { return; } + if (!LWC.ENABLED) { + return; + } + if (event.getBlock().getType() != Material.SAND && event.getBlock().getType() != Material.GRAVEL) { return; } diff --git a/src/main/java/com/griefcraft/listeners/LWCPlayerListener.java b/src/main/java/com/griefcraft/listeners/LWCPlayerListener.java index 18f3e79..0dd5b84 100644 --- a/src/main/java/com/griefcraft/listeners/LWCPlayerListener.java +++ b/src/main/java/com/griefcraft/listeners/LWCPlayerListener.java @@ -12,6 +12,7 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; import org.bukkit.block.ContainerBlock; import org.bukkit.craftbukkit.CraftChunk; import org.bukkit.craftbukkit.CraftWorld; @@ -26,9 +27,21 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.ItemStack; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class LWCPlayerListener extends PlayerListener { + private final Set invalidPrivates = new HashSet<>(Arrays.asList( + Material.AIR, + Material.WATER, + Material.STATIONARY_WATER, + Material.LAVA, + Material.STATIONARY_LAVA, + Material.SNOW, + Material.FIRE + )); /** * The plugin instance @@ -76,15 +89,32 @@ public void onPlayerChat(PlayerChatEvent event) { @Override public void onPlayerInteract(PlayerInteractEvent event) { - if (event.getAction() != Action.LEFT_CLICK_BLOCK && event.getAction() != Action.RIGHT_CLICK_BLOCK) { + if (event.isCancelled()) { return; } + LWC lwc = plugin.getLWC(); + if (!LWC.ENABLED) { return; } - LWC lwc = plugin.getLWC(); + BlockFace face = event.getBlockFace(); + Block target = event.getClickedBlock(); + if (face != null) { + target = event.getClickedBlock().getRelative(face); + } + if (invalidPrivates.contains(target.getType())) { + Protection protection = lwc.findProtection(target); + if (protection != null) { + protection.remove(); + } + } + + if (event.getAction() != Action.LEFT_CLICK_BLOCK && event.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; + } + Player player = event.getPlayer(); Block clickedBlock = event.getClickedBlock(); Location location = clickedBlock.getLocation(); From b3a8885c619432cdb3c27364b12b1e9e12441090 Mon Sep 17 00:00:00 2001 From: Robert Wesner Date: Tue, 24 Mar 2026 15:25:52 +0100 Subject: [PATCH 4/6] Hotfix: Sand physics (#1) * BOSEConomy -> BOSEconomy * Prevent dangling protection though sand falling. * Remove private air when interacting. --- pom.xml | 6 +- .../listeners/LWCBlockListener.java | 80 +++++++++++++++++-- .../listeners/LWCPlayerListener.java | 34 +++++++- .../java/com/griefcraft/lwc/LWCPlugin.java | 1 + 4 files changed, 110 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index f8f23e8..5e2548c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ LWC LWC jar - 3.53 + 3.54 UTF-8 @@ -35,7 +35,7 @@ BOSEconomy 1.0 system - ${project.basedir}/lib/BOSEConomy.jar + ${project.basedir}/lib/BOSEconomy.jar com.earth2me.essentials @@ -157,4 +157,4 @@ - \ No newline at end of file + diff --git a/src/main/java/com/griefcraft/listeners/LWCBlockListener.java b/src/main/java/com/griefcraft/listeners/LWCBlockListener.java index 932c98d..570d500 100644 --- a/src/main/java/com/griefcraft/listeners/LWCBlockListener.java +++ b/src/main/java/com/griefcraft/listeners/LWCBlockListener.java @@ -15,21 +15,48 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.entity.Player; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockListener; -import org.bukkit.event.block.BlockPistonExtendEvent; -import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.block.BlockRedstoneEvent; -import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.event.block.*; +import org.bukkit.material.Attachable; import org.bukkit.material.MaterialData; import org.bukkit.material.PistonBaseMaterial; +import java.util.*; + public class LWCBlockListener extends BlockListener { /** * The plugin instance */ private LWCPlugin plugin; + private Set attachmentsTopToCheck = new HashSet<>( + Arrays.asList( + Material.SAPLING, + Material.POWERED_RAIL, + Material.DETECTOR_RAIL, + Material.LONG_GRASS, + Material.DEAD_BUSH, + Material.YELLOW_FLOWER, + Material.RED_ROSE, + Material.BROWN_MUSHROOM, + Material.RED_MUSHROOM, + Material.TORCH, + Material.FIRE, + Material.REDSTONE_WIRE, + Material.SIGN_POST, + Material.WOODEN_DOOR, + Material.RAILS, + Material.LEVER, + Material.STONE_PLATE, + Material.IRON_DOOR_BLOCK, + Material.WOOD_PLATE, + Material.REDSTONE_TORCH_OFF, + Material.REDSTONE_TORCH_ON, + Material.SNOW, + Material.CACTUS, + Material.SUGAR_CANE_BLOCK, + Material.CAKE_BLOCK + ) + ); public LWCBlockListener(LWCPlugin plugin) { this.plugin = plugin; @@ -135,6 +162,47 @@ public void onBlockBreak(BlockBreakEvent event) { } } + @Override + public void onBlockPhysics(BlockPhysicsEvent event) { + if (event.isCancelled()) { + return; + } + + if (!LWC.ENABLED) { + return; + } + + if (event.getBlock().getType() != Material.SAND && event.getBlock().getType() != Material.GRAVEL) { + return; + } + + LWC lwc = plugin.getLWC(); + Block upNeighbor = event.getBlock().getRelative(BlockFace.UP); + if (attachmentsTopToCheck.contains(upNeighbor.getType()) && lwc.findProtection(upNeighbor) != null) { + event.setCancelled(true); + + return; + } + + List horizontals = Arrays.asList( + BlockFace.NORTH, + BlockFace.EAST, + BlockFace.SOUTH, + BlockFace.WEST + ); + for (BlockFace face: horizontals) { + Block neighbor = event.getBlock().getRelative(face); + if (neighbor.getState() != null && (neighbor.getState().getData() instanceof Attachable)) { + Attachable data = (Attachable) neighbor.getState().getData(); + if (data.getAttachedFace() == face.getOppositeFace() && lwc.findProtection(neighbor) != null) { + event.setCancelled(true); + + return; + } + } + } + } + @Override public void onBlockPistonExtend(BlockPistonExtendEvent event) { if (!LWC.ENABLED) { diff --git a/src/main/java/com/griefcraft/listeners/LWCPlayerListener.java b/src/main/java/com/griefcraft/listeners/LWCPlayerListener.java index 18f3e79..0dd5b84 100644 --- a/src/main/java/com/griefcraft/listeners/LWCPlayerListener.java +++ b/src/main/java/com/griefcraft/listeners/LWCPlayerListener.java @@ -12,6 +12,7 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; import org.bukkit.block.ContainerBlock; import org.bukkit.craftbukkit.CraftChunk; import org.bukkit.craftbukkit.CraftWorld; @@ -26,9 +27,21 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.inventory.ItemStack; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; public class LWCPlayerListener extends PlayerListener { + private final Set invalidPrivates = new HashSet<>(Arrays.asList( + Material.AIR, + Material.WATER, + Material.STATIONARY_WATER, + Material.LAVA, + Material.STATIONARY_LAVA, + Material.SNOW, + Material.FIRE + )); /** * The plugin instance @@ -76,15 +89,32 @@ public void onPlayerChat(PlayerChatEvent event) { @Override public void onPlayerInteract(PlayerInteractEvent event) { - if (event.getAction() != Action.LEFT_CLICK_BLOCK && event.getAction() != Action.RIGHT_CLICK_BLOCK) { + if (event.isCancelled()) { return; } + LWC lwc = plugin.getLWC(); + if (!LWC.ENABLED) { return; } - LWC lwc = plugin.getLWC(); + BlockFace face = event.getBlockFace(); + Block target = event.getClickedBlock(); + if (face != null) { + target = event.getClickedBlock().getRelative(face); + } + if (invalidPrivates.contains(target.getType())) { + Protection protection = lwc.findProtection(target); + if (protection != null) { + protection.remove(); + } + } + + if (event.getAction() != Action.LEFT_CLICK_BLOCK && event.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; + } + Player player = event.getPlayer(); Block clickedBlock = event.getClickedBlock(); Location location = clickedBlock.getLocation(); diff --git a/src/main/java/com/griefcraft/lwc/LWCPlugin.java b/src/main/java/com/griefcraft/lwc/LWCPlugin.java index 126066d..84fc85c 100644 --- a/src/main/java/com/griefcraft/lwc/LWCPlugin.java +++ b/src/main/java/com/griefcraft/lwc/LWCPlugin.java @@ -399,6 +399,7 @@ private void registerEvents() { registerEvent(blockListener, Type.REDSTONE_CHANGE); registerEvent(blockListener, Type.SIGN_CHANGE); registerEvent(blockListener, Type.BLOCK_PISTON_EXTEND); + registerEvent(blockListener, Type.BLOCK_PHYSICS); /* Server events */ registerEvent(serverListener, Type.PLUGIN_DISABLE); From 457af03398f7da0ee77277de3f4960127f55f023 Mon Sep 17 00:00:00 2001 From: RobertWesner Date: Fri, 3 Apr 2026 08:26:34 +0200 Subject: [PATCH 5/6] Implement recursion detection. --- src/main/java/cb1060/RDEB.java | 63 ++++++++++++++++++ .../listeners/LWCBlockListener.java | 66 +++++++++++-------- 2 files changed, 102 insertions(+), 27 deletions(-) create mode 100644 src/main/java/cb1060/RDEB.java diff --git a/src/main/java/cb1060/RDEB.java b/src/main/java/cb1060/RDEB.java new file mode 100644 index 0000000..fc72d4b --- /dev/null +++ b/src/main/java/cb1060/RDEB.java @@ -0,0 +1,63 @@ +package cb1060; + + +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.bukkit.Bukkit; + +import java.util.HashMap; +import java.util.Map; + +/** + * Recursion-Detection-Early-Break + * Because betajankā„¢ + */ +public class RDEB { + private static final int THRESHOLD = 10; + + private static final Map tracker = new HashMap<>(); + + public static void up() { + String k = key(getCaller()); + Integer v = tracker.get(k); + + if (v == null) { + v = 0; + } + + tracker.put(k, v + 1); + } + + public static void down() { + String k = key(getCaller()); + Integer v = tracker.get(k); + + if (v == null) { + v = 0; + } + + tracker.put(k, Math.max(0, v - 1)); + } + + public static boolean shouldBreak() { + String k = key(getCaller()); + Integer v = tracker.get(k); + + if (v == null || v < THRESHOLD) { + return false; + } + + tracker.remove(k); + + Bukkit.getLogger().severe("[RDEB_REPORT] Detected invalid recursion, please investigate!\n" + ExceptionUtils.getStackTrace(new Throwable())); + + return true; + } + + private static StackTraceElement getCaller() { + return Thread.currentThread().getStackTrace()[3]; + } + + private static String key(StackTraceElement element) { + return element.getClassName() + "::" + element.getMethodName() + "()"; + } +} diff --git a/src/main/java/com/griefcraft/listeners/LWCBlockListener.java b/src/main/java/com/griefcraft/listeners/LWCBlockListener.java index 570d500..f1b6219 100644 --- a/src/main/java/com/griefcraft/listeners/LWCBlockListener.java +++ b/src/main/java/com/griefcraft/listeners/LWCBlockListener.java @@ -1,5 +1,6 @@ package com.griefcraft.listeners; +import cb1060.RDEB; import com.griefcraft.lwc.LWC; import com.griefcraft.lwc.LWCPlugin; import com.griefcraft.model.Protection; @@ -164,42 +165,53 @@ public void onBlockBreak(BlockBreakEvent event) { @Override public void onBlockPhysics(BlockPhysicsEvent event) { - if (event.isCancelled()) { - return; - } + RDEB.up(); + if (RDEB.shouldBreak()) { + event.setCancelled(true); - if (!LWC.ENABLED) { return; } - if (event.getBlock().getType() != Material.SAND && event.getBlock().getType() != Material.GRAVEL) { - return; - } + try { + if (event.isCancelled()) { + return; + } - LWC lwc = plugin.getLWC(); - Block upNeighbor = event.getBlock().getRelative(BlockFace.UP); - if (attachmentsTopToCheck.contains(upNeighbor.getType()) && lwc.findProtection(upNeighbor) != null) { - event.setCancelled(true); + if (!LWC.ENABLED) { + return; + } - return; - } + if (event.getBlock().getType() != Material.SAND && event.getBlock().getType() != Material.GRAVEL) { + return; + } + + LWC lwc = plugin.getLWC(); + Block upNeighbor = event.getBlock().getRelative(BlockFace.UP); + if (attachmentsTopToCheck.contains(upNeighbor.getType()) && lwc.findProtection(upNeighbor) != null) { + event.setCancelled(true); - List horizontals = Arrays.asList( - BlockFace.NORTH, - BlockFace.EAST, - BlockFace.SOUTH, - BlockFace.WEST - ); - for (BlockFace face: horizontals) { - Block neighbor = event.getBlock().getRelative(face); - if (neighbor.getState() != null && (neighbor.getState().getData() instanceof Attachable)) { - Attachable data = (Attachable) neighbor.getState().getData(); - if (data.getAttachedFace() == face.getOppositeFace() && lwc.findProtection(neighbor) != null) { - event.setCancelled(true); - - return; + return; + } + + List horizontals = Arrays.asList( + BlockFace.NORTH, + BlockFace.EAST, + BlockFace.SOUTH, + BlockFace.WEST + ); + for (BlockFace face: horizontals) { + Block neighbor = event.getBlock().getRelative(face); + if (neighbor.getState() != null && (neighbor.getState().getData() instanceof Attachable)) { + Attachable data = (Attachable) neighbor.getState().getData(); + if (data.getAttachedFace() == face.getOppositeFace() && lwc.findProtection(neighbor) != null) { + event.setCancelled(true); + + return; + } } } + } finally { + RDEB.down(); } } From af8f931d88f123771d1e4c37902200ce47c112f2 Mon Sep 17 00:00:00 2001 From: RobertWesner Date: Fri, 3 Apr 2026 08:30:33 +0200 Subject: [PATCH 6/6] Update version. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5e2548c..955ed47 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ LWC LWC jar - 3.54 + 3.55 UTF-8