From f6c45adc5f031accead3a41f51056279eab1f47b Mon Sep 17 00:00:00 2001 From: BrainStone Date: Sun, 18 Jul 2021 03:19:56 +0200 Subject: [PATCH 1/2] Added a fallback for the case when numerical IDs have been removed from Bukkit This fixes webbukkit/dynmap#3418. The idea is to catch the case when numeric IDs have been removed from the code base and to then just use a fallback. Also doing it this way ensures maxium longevity, as `Material#getID` will be among the last ones removed, while other methods to get the numerical ID will get likely get removed earlier --- .../java/org/dynmap/bukkit/DynmapPlugin.java | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java b/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java index 843da305..30e080a1 100644 --- a/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java +++ b/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java @@ -15,6 +15,7 @@ import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicBoolean; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; @@ -172,6 +173,27 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { } } + // Nonblocking thread safety + private static final AtomicBoolean tryNativeId = new AtomicBoolean(true); + @SuppressWarnings("deprecation") + private static final int getBlockIdFromMaterial(Material material) { + if (tryNativeId.get()) { + try { + return material.getId(); + } catch (NoSuchMethodError e) { + // We failed once, no need to retry + tryNativeId.set(false); + } + } + + // We're living in a world where numerical IDs have been phased out completely. + // Let's return *some* number, because we need one + return material.ordinal(); + } + private static final int getBlockIdFromBlock(Block block) { + return getBlockIdFromMaterial(block.getType()); + } + private class BukkitEnableCoreCallback extends DynmapCore.EnableCoreCallbacks { @Override public void configurationLoaded() { @@ -213,7 +235,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { public int getBlockIDAt(String wname, int x, int y, int z) { World w = getServer().getWorld(wname); if((w != null) && w.isChunkLoaded(x >> 4, z >> 4)) { - return w.getBlockTypeIdAt(x, y, z); + return getBlockIdFromBlock(w.getBlockAt(x, y, z)); } return -1; } @@ -1186,7 +1208,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { World w = loc.getWorld(); if(!w.isChunkLoaded(loc.getBlockX()>>4, loc.getBlockZ()>>4)) continue; - int bt = w.getBlockTypeIdAt(loc); + int bt = getBlockIdFromBlock(w.getBlockAt(loc)); /* Avoid stationary and moving water churn */ if(bt == 9) bt = 8; if(btt.typeid == 9) btt.typeid = 8; @@ -1213,7 +1235,7 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { private void checkBlock(Block b, String trigger) { BlockToCheck btt = new BlockToCheck(); btt.loc = b.getLocation(); - btt.typeid = b.getTypeId(); + btt.typeid = getBlockIdFromBlock(b); btt.data = b.getData(); btt.trigger = trigger; blocks_to_check_accum.add(btt); /* Add to accumulator */ From b7c88f9911b552fccfa6a96cd20ccb1561e12cbf Mon Sep 17 00:00:00 2001 From: BrainStone Date: Sun, 18 Jul 2021 03:27:59 +0200 Subject: [PATCH 2/2] New materials don't even have an ID anymore Handle that case as well. Honestly the best solution would be to just get rid of getBlockIDAt as it's only used in two places where it could be trivially replaced --- spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java b/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java index 30e080a1..7399094a 100644 --- a/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java +++ b/spigot/src/main/java/org/dynmap/bukkit/DynmapPlugin.java @@ -183,12 +183,17 @@ public class DynmapPlugin extends JavaPlugin implements DynmapAPI { } catch (NoSuchMethodError e) { // We failed once, no need to retry tryNativeId.set(false); + } catch (java.lang.IllegalArgumentException e) { + // Ignore this entirely, as modern materials throw + // java.lang.IllegalArgumentException: Cannot get ID of Modern Material } } // We're living in a world where numerical IDs have been phased out completely. - // Let's return *some* number, because we need one - return material.ordinal(); + // Let's return *some* number, because we need one. + // Also in that case we are adding a constant to ensure we're not conflicting with the + // actual IDs + return material.ordinal() + (1 << 20); } private static final int getBlockIdFromBlock(Block block) { return getBlockIdFromMaterial(block.getType());