diff --git a/pom.xml b/pom.xml
index ccd35a1ba..3faadd738 100644
--- a/pom.xml
+++ b/pom.xml
@@ -75,7 +75,7 @@
-LOCAL
- 3.9.0
+ 3.9.1
bentobox-world
https://sonarcloud.io
${project.basedir}/lib
diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListener.java
index 0b01ce79a..56b723191 100644
--- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListener.java
+++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/BlockInteractionListener.java
@@ -22,6 +22,7 @@
import world.bentobox.bentobox.api.flags.FlagListener;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.lists.Flags;
+import world.bentobox.bentobox.util.Util;
/**
* Handle interaction with blocks
@@ -246,18 +247,20 @@ private boolean checkSpecialCases(Event e, Player player, Block block) {
this.checkIsland(e, player, loc, Flags.FLOWER_POT);
return true;
}
- // Prevent animation of copper golems. Use break blocks for now. This could potentiall have it's own flag in the future.
- if (Tag.COPPER_GOLEM_STATUES.isTagged(type)) {
- this.checkIsland(e, player, loc, Flags.BREAK_BLOCKS);
- return true;
+ if (Util.isVersionAtLeast("1.21.10")) {
+ // Prevent animation of copper golems. Use break blocks for now. This could potentiall have it's own flag in the future.
+ if (Tag.COPPER_GOLEM_STATUES.isTagged(type)) {
+ this.checkIsland(e, player, loc, Flags.BREAK_BLOCKS);
+ return true;
+ }
+
+ // There are various types of copper chests
+ if (Tag.COPPER_CHESTS.isTagged(type)) {
+ this.checkIsland(e, player, loc, Flags.CHEST);
+ return true;
+ }
}
- // There are various types of copper chests
- if (Tag.COPPER_CHESTS.isTagged(type)) {
- this.checkIsland(e, player, loc, Flags.CHEST);
- return true;
- }
-
if (block.getState() instanceof BrushableBlock && BlockInteractionListener.holds(player, Material.BRUSH)) {
// Protect this using break blocks flag for now. Maybe in the future it can have its own flag.
this.checkIsland(e, player, loc, Flags.BREAK_BLOCKS);
diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/PlaceBlocksListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/PlaceBlocksListener.java
index 5bd393f80..8fd00650b 100644
--- a/src/main/java/world/bentobox/bentobox/listeners/flags/protection/PlaceBlocksListener.java
+++ b/src/main/java/world/bentobox/bentobox/listeners/flags/protection/PlaceBlocksListener.java
@@ -16,6 +16,8 @@
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
+import com.google.common.base.Enums;
+
import world.bentobox.bentobox.api.flags.FlagListener;
import world.bentobox.bentobox.lists.Flags;
@@ -131,7 +133,7 @@ public void onPlayerInteract(final PlayerInteractEvent e)
e.getMaterial() == Material.ITEM_FRAME ||
e.getMaterial() == Material.GLOW_ITEM_FRAME ||
e.getMaterial() == Material.CHEST ||
- e.getMaterial() == Material.COPPER_CHEST ||
+ e.getMaterial() == Enums.getIfPresent(Material.class, "COPPER_CHEST").or(Material.CHEST) ||
e.getMaterial() == Material.TRAPPED_CHEST)
{
this.checkIsland(e, e.getPlayer(), e.getPlayer().getLocation(), Flags.PLACE_BLOCKS);
diff --git a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/ChestDamageListener.java b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/ChestDamageListener.java
index 1615695bb..59b67421c 100644
--- a/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/ChestDamageListener.java
+++ b/src/main/java/world/bentobox/bentobox/listeners/flags/worldsettings/ChestDamageListener.java
@@ -8,6 +8,7 @@
import world.bentobox.bentobox.api.flags.FlagListener;
import world.bentobox.bentobox.lists.Flags;
+import world.bentobox.bentobox.util.Util;
/**
* @author tastybento
@@ -24,10 +25,17 @@ public void onExplosion(final EntityExplodeEvent e)
if (getIWM().inWorld(e.getLocation()) && !Flags.CHEST_DAMAGE.isSetForWorld(e.getLocation().getWorld()))
{
e.blockList().removeIf(b -> b.getType().equals(Material.CHEST) ||
- Tag.COPPER_CHESTS.isTagged(b.getType()) ||
- b.getType().equals(Material.TRAPPED_CHEST) ||
- Tag.SHULKER_BOXES.isTagged(b.getType()));
-
+ isCopperChest(b.getType()) ||
+ b.getType().equals(Material.TRAPPED_CHEST) ||
+ Tag.SHULKER_BOXES.isTagged(b.getType()));
+
+ }
+ }
+
+ private boolean isCopperChest(Material m) {
+ if (Util.isVersionAtLeast("1.21.10")) {
+ return Tag.COPPER_CHESTS.isTagged(m);
}
+ return false;
}
}
diff --git a/src/main/java/world/bentobox/bentobox/util/Util.java b/src/main/java/world/bentobox/bentobox/util/Util.java
index d55c813f8..9a3e45c16 100644
--- a/src/main/java/world/bentobox/bentobox/util/Util.java
+++ b/src/main/java/world/bentobox/bentobox/util/Util.java
@@ -73,6 +73,8 @@ public class Util {
private static final String NETHER = "_nether";
private static final String THE_END = "_the_end";
+
+ private static final String SERVER_VERSION = Bukkit.getMinecraftVersion();
private static String serverVersion = null;
private static BentoBox plugin = BentoBox.getInstance();
private static PasteHandler pasteHandler = null;
@@ -363,10 +365,15 @@ public static boolean isPassiveEntity(Entity entity) {
// Fishes, Dolphin and Squid extends WaterMob | Excludes PufferFish
// Bat extends Mob
// Most of passive mobs extends Animals
-
+ boolean copperGolem = false;
+ try {
+ copperGolem = entity instanceof CopperGolem;
+ } catch (Exception ex) {
+ copperGolem = false;
+ }
return entity instanceof Animals || entity instanceof IronGolem || entity instanceof Snowman ||
entity instanceof WaterMob && !(entity instanceof PufferFish) || entity instanceof Bat ||
- entity instanceof Allay || entity instanceof CopperGolem;
+ entity instanceof Allay || copperGolem;
}
public static boolean isTamableEntity(Entity entity) {
@@ -744,7 +751,7 @@ public static void resetHealth(Player player) {
public static void setRegenerator(WorldRegenerator regenerator) {
Util.regenerator = regenerator;
}
-
+
private static Pair getPrefix() {
// Bukkit method that was added in 2011
// Example value: 1.20.4-R0.1-SNAPSHOT
@@ -752,7 +759,7 @@ private static Pair getPrefix() {
final String pluginPackageName = plugin.getClass().getPackage().getName();
return new Pair(pluginPackageName + ".nms." + bukkitVersion, bukkitVersion);
}
-
+
/**
* Generic method to get NMS handlers with fallback options
* @param The type of handler to get
@@ -771,7 +778,7 @@ private static T getNMSHandler(Class handlerClass,
if (existingHandler != null) {
return existingHandler;
}
-
+
T handler;
try {
Class> clazz = Class.forName(getPrefix().x() + "." + implName);
@@ -786,7 +793,7 @@ private static T getNMSHandler(Class handlerClass,
}
return handler;
}
-
+
/**
* Get metadata decoder
* @return an accelerated metadata class for this server
@@ -909,5 +916,30 @@ public static boolean inTest() {
public static String stripColor(String input) {
return input.replaceAll("(?i)ยง[0-9A-FK-ORX]", ""); // Use regex because it's fast and reliable
}
-
+
+ /**
+ * Simple utility method to check if the server version is at least the target version.
+ */
+ public static boolean isVersionAtLeast(String targetVersion) {
+ // Simple string comparison may be sufficient for minor versions,
+ // but a proper numeric check is safer for major releases.
+ try {
+ // Get major, minor, patch versions
+ String[] currentParts = SERVER_VERSION.split("\\.");
+ String[] targetParts = targetVersion.split("\\.");
+
+ for (int i = 0; i < targetParts.length; i++) {
+ int current = (i < currentParts.length) ? Integer.parseInt(currentParts[i]) : 0;
+ int target = Integer.parseInt(targetParts[i]);
+
+ if (current > target) return true;
+ if (current < target) return false;
+ }
+ // All parts checked are equal (e.g., 1.21.9 vs 1.21.9)
+ return true;
+ } catch (NumberFormatException e) {
+ // Fallback for non-standard version strings
+ return SERVER_VERSION.startsWith(targetVersion);
+ }
+ }
}
diff --git a/src/test/java/world/bentobox/bentobox/AbstractCommonSetup.java b/src/test/java/world/bentobox/bentobox/AbstractCommonSetup.java
index 1e970d6ee..13f36e5f8 100644
--- a/src/test/java/world/bentobox/bentobox/AbstractCommonSetup.java
+++ b/src/test/java/world/bentobox/bentobox/AbstractCommonSetup.java
@@ -116,6 +116,8 @@ public void setUp() throws Exception {
server = ServerMocks.newServer();
// Bukkit
PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
+ // Version
+ when(Bukkit.getMinecraftVersion()).thenReturn("1.21.10");
// Set up plugin
Whitebox.setInternalState(BentoBox.class, "instance", plugin);
diff --git a/src/test/java/world/bentobox/bentobox/listeners/PanelListenerManagerTest.java b/src/test/java/world/bentobox/bentobox/listeners/PanelListenerManagerTest.java
index 6da0b43d9..6d9036664 100644
--- a/src/test/java/world/bentobox/bentobox/listeners/PanelListenerManagerTest.java
+++ b/src/test/java/world/bentobox/bentobox/listeners/PanelListenerManagerTest.java
@@ -37,6 +37,7 @@
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
+import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
@@ -85,6 +86,8 @@ public class PanelListenerManagerTest {
@SuppressWarnings("deprecation")
@Before
public void setUp() throws Exception {
+ PowerMockito.mockStatic(Bukkit.class, Mockito.RETURNS_MOCKS);
+ when(Bukkit.getMinecraftVersion()).thenReturn("1.21.10");
// Set up plugin
BentoBox plugin = mock(BentoBox.class);
Whitebox.setInternalState(BentoBox.class, "instance", plugin);