diff --git a/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/BlockCacheBukkitModern.java b/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/BlockCacheBukkitModern.java index 4832f5e6..cc4536a0 100644 --- a/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/BlockCacheBukkitModern.java +++ b/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/BlockCacheBukkitModern.java @@ -29,7 +29,15 @@ public class BlockCacheBukkitModern extends BlockCacheBukkit { @Override public int fetchData(int x, int y, int z) { - // TODO: Might fake here too. + Material mat = getType(x, y, z); + + final BukkitShapeModel shapeModel = shapeModels.get(mat); + if (shapeModel != null) { + final int data = shapeModel.getFakeData(this, world, x, y, z); + if (data != Integer.MAX_VALUE) { + return data; + } + } return super.fetchData(x, y, z); } diff --git a/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/MCAccessBukkitBase.java b/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/MCAccessBukkitBase.java index 9615eead..f20459d0 100644 --- a/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/MCAccessBukkitBase.java +++ b/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/MCAccessBukkitBase.java @@ -51,6 +51,19 @@ public class MCAccessBukkitBase implements MCAccess { */ protected final Set processedBlocks = new LinkedHashSet(); + /** + * Constructor to let it fail. + */ + public MCAccessBukkitBase() { + // TODO: Add more that might fail if not supported ? + testItchyBlock(); + // TODO: Deactivate checks that might not work. => MCAccess should have availability method, NCP deactivates check on base of that. + // TODO: Move getHeight and the like to EntityAccessXY. + bukkitHasGetHeightAndGetWidth = ReflectionUtil.getMethodNoArgs(Entity.class, "getHeight", double.class) != null + && ReflectionUtil.getMethodNoArgs(Entity.class, "getWidth", double.class) != null; + } + + @SuppressWarnings("deprecation") private boolean guessItchyBlockPre1_13(final Material mat) { return !mat.isOccluding() || !mat.isSolid() || mat.isTransparent(); } @@ -81,10 +94,12 @@ public class MCAccessBukkitBase implements MCAccess { return true; } } - long testFlags = (BlockProperties.F_SOLID | BlockProperties.F_XZ100 - | BlockProperties.F_HEIGHT100); - if (BlockFlags.hasAllFlags(flags, testFlags)) { - // Fully solid block. + long testFlags1 = (BlockProperties.F_SOLID | BlockProperties.F_XZ100); + long testFlags2 = (BlockProperties.F_HEIGHT100 + | BlockProperties.F_HEIGHT16_15); + if (BlockFlags.hasAllFlags(flags, testFlags1) + && BlockFlags.hasAnyFlag(flags, testFlags2)) { + // Solid blocks with explicitly set bounds. return false; } @@ -97,18 +112,6 @@ public class MCAccessBukkitBase implements MCAccess { guessItchyBlockPre1_13(Material.AIR); } - /** - * Constructor to let it fail. - */ - public MCAccessBukkitBase() { - // TODO: Add more that might fail if not supported ? - testItchyBlock(); - // TODO: Deactivate checks that might not work. => MCAccess should have availability method, NCP deactivates check on base of that. - // TODO: Move getHeight and the like to EntityAccessXY. - bukkitHasGetHeightAndGetWidth = ReflectionUtil.getMethodNoArgs(Entity.class, "getHeight", double.class) != null - && ReflectionUtil.getMethodNoArgs(Entity.class, "getWidth", double.class) != null; - } - @Override public String getMCVersion() { // Bukkit API. diff --git a/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/MCAccessBukkitModern.java b/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/MCAccessBukkitModern.java index df1f6219..241f083d 100644 --- a/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/MCAccessBukkitModern.java +++ b/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/MCAccessBukkitModern.java @@ -5,9 +5,11 @@ import java.util.Map; import org.bukkit.Material; +import fr.neatmonster.nocheatplus.compat.BridgeMaterial; import fr.neatmonster.nocheatplus.compat.blocks.init.BlockInit; import fr.neatmonster.nocheatplus.compat.bukkit.model.BukkitShapeModel; import fr.neatmonster.nocheatplus.compat.bukkit.model.BukkitSlab; +import fr.neatmonster.nocheatplus.compat.bukkit.model.BukkitStairs; import fr.neatmonster.nocheatplus.config.WorldConfigProvider; import fr.neatmonster.nocheatplus.utilities.map.BlockCache; import fr.neatmonster.nocheatplus.utilities.map.BlockFlags; @@ -19,11 +21,13 @@ public class MCAccessBukkitModern extends MCAccessBukkit { protected final Map shapeModels = new HashMap(); private static final BukkitShapeModel MODEL_SLAB = new BukkitSlab(); - + private static final BukkitShapeModel MODEL_STAIRS= new BukkitStairs(); + public MCAccessBukkitModern() { super(); + // TODO: Generic setup via Bukkit interface existence/relations, +- fetching methods. BlockInit.assertMaterialExists("OAK_LOG"); - BlockInit.assertMaterialExists("VOID_AIR"); + BlockInit.assertMaterialExists("CAVE_AIR"); } @Override @@ -39,6 +43,13 @@ public class MCAccessBukkitModern extends MCAccessBukkit { @Override public void setupBlockProperties(final WorldConfigProvider worldConfigProvider) { + // Directly keep blocks as is. + for (final Material mat : new Material[] { + BridgeMaterial.MOVING_PISTON + }) { + processedBlocks.add(mat); + } + // Pre-process for flags. // TODO: Also consider removing flags (passable_x4 etc). for (final Material mat : Material.values()) { @@ -52,10 +63,15 @@ public class MCAccessBukkitModern extends MCAccessBukkit { final long flags = BlockProperties.getBlockFlags(mat); // Step. if (BlockFlags.hasAnyFlag(flags, BlockProperties.F_MODEL_SLAB)) { + // TODO: Should scrap the flag and just register the shape model. processedBlocks.add(mat); shapeModels.put(mat, MODEL_SLAB); } // Stairs. + if (BlockFlags.hasAnyFlag(flags, BlockProperties.F_STAIRS)) { + processedBlocks.add(mat); + shapeModels.put(mat, MODEL_STAIRS); + } // Fences. // TODO: May need specialized models for edge cases? // Thin fences. // ... (heads, chests, static, shulker box ...) diff --git a/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/model/BukkitSlab.java b/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/model/BukkitSlab.java index 7577ed54..6e59aa94 100644 --- a/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/model/BukkitSlab.java +++ b/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/model/BukkitSlab.java @@ -28,10 +28,15 @@ public class BukkitSlab implements BukkitShapeModel { break; default: break; - } } return new double[] {0.0, 0.0, 0.0, 1.0, 1.0, 1.0}; } + @Override + public int getFakeData(final BlockCache blockCache, + final World world, final int x, final int y, final int z) { + return 0; + } + } diff --git a/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/model/BukkitStairs.java b/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/model/BukkitStairs.java new file mode 100644 index 00000000..269b6824 --- /dev/null +++ b/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/model/BukkitStairs.java @@ -0,0 +1,64 @@ +package fr.neatmonster.nocheatplus.compat.bukkit.model; + +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.data.Bisected.Half; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.type.Stairs; + +import fr.neatmonster.nocheatplus.utilities.map.BlockCache; + +public class BukkitStairs implements BukkitShapeModel { + + @Override + public double[] getShape(final BlockCache blockCache, + final World world, final int x, final int y, final int z) { + + // TODO: With fake data, this could simply return full bounds. + + // final Block block = world.getBlockAt(x, y, z); + // final BlockState state = block.getState(); + // final BlockData blockData = state.getBlockData(); + // + // if (blockData instanceof Stairs) { + // final Stairs stairs = (Stairs) blockData; + // final Half half = stairs.getHalf(); + // //final Shape shape = stairs.getShape(); + // // TODO: Refine later, with sub shapes. + // switch (half) { + // case BOTTOM: + // return new double[] {0.0, 0.0, 0.0, 1.0, 0.5, 1.0}; + // case TOP: + // return new double[] {0.0, 0.5, 0.0, 1.0, 1.0, 1.0}; + // default: + // break; + // + // } + // } + return new double[] {0.0, 0.0, 0.0, 1.0, 1.0, 1.0}; + } + + @Override + public int getFakeData(final BlockCache blockCache, + final World world, final int x, final int y, final int z) { + final Block block = world.getBlockAt(x, y, z); + final BlockState state = block.getState(); + final BlockData blockData = state.getBlockData(); + + if (blockData instanceof Stairs) { + final Stairs stairs = (Stairs) blockData; + final Half half = stairs.getHalf(); + //final Shape shape = stairs.getShape(); + // TODO: Refine later, with sub shapes. + switch (half) { + case TOP: + return 0x4; + default: + break; + } + } + return 0; + } + +} diff --git a/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/model/ShapeModel.java b/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/model/ShapeModel.java index 2373aefb..0793ffe2 100644 --- a/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/model/ShapeModel.java +++ b/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/model/ShapeModel.java @@ -4,7 +4,19 @@ import fr.neatmonster.nocheatplus.utilities.map.BlockCache; public interface ShapeModel { + // TODO: Rather fill in all into node directly (data as well), avoid redundant casting etc. + // TODO: Best route passable workaround through here too (base on a flag), + getGroundMinHeight?. + // TODO: Refine +- might have BukkitBlockCacheNode etc. public double[] getShape(BlockCache blockCache, W world, int x, int y, int z); + /** + * Allow faking data. + * + * @return Integer.MAX_VALUE, in case fake data is not supported, and the + * Bukkit method is used (as long as possible). 0 may be returned + * for performance. + */ + public int getFakeData(BlockCache blockCache, W world, int x, int y, int z); + } diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_13.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_13.java index 6315c5c2..c936268a 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_13.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_13.java @@ -94,12 +94,6 @@ public class BlocksMC1_13 implements BlockPropertiesSetup { // Blue ice. BlockInit.setAs("BLUE_ICE", Material.ICE); - // Grass path. - // TODO: HEIGHT16_15 instead. - BlockFlags.addFlags(Material.GRASS_PATH, BlockProperties.F_MIN_HEIGHT16_15 - | BlockProperties.F_HEIGHT100 - | BlockProperties.F_GROUND_HEIGHT); - // Wet sponge. BlockInit.setAs("WET_SPONGE", Material.SPONGE); @@ -176,6 +170,11 @@ public class BlocksMC1_13 implements BlockPropertiesSetup { BlockProperties.setBlockProps("TURTLE_EGG", new BlockProps( BlockProperties.noTool, 0.5f, BlockProperties.secToMs(0.7))); + // Grass path. + // TODO: HEIGHT16_15 instead. + BlockFlags.removeFlags(Material.GRASS_PATH, BlockProperties.F_HEIGHT100); + BlockFlags.addFlags(Material.GRASS_PATH, + BlockProperties.F_XZ100 | BlockProperties.F_HEIGHT16_15); StaticLog.logInfo("Added block-info for Minecraft 1.13 blocks."); } diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/BlockFlags.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/BlockFlags.java index 8a9b1318..8dafe70e 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/BlockFlags.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/BlockFlags.java @@ -106,6 +106,10 @@ public class BlockFlags { BlockProperties.setBlockFlags(id, BlockProperties.getBlockFlags(id) & ~flags); } + public static void removeFlags(Material mat, long flags) { + BlockProperties.setBlockFlags(mat, BlockProperties.getBlockFlags(mat) & ~flags); + } + /** * Test if any flags within testFlags are contained. * diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/BlockProperties.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/BlockProperties.java index bd77aeca..2feb9aa9 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/BlockProperties.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/BlockProperties.java @@ -860,6 +860,9 @@ public class BlockProperties { */ public static final long F_MODEL_SLAB = f_flag(); + /** Height 15/16 (0.9375 = 1 - 0.0625). */ + public static final long F_HEIGHT16_15 = f_flag(); + // TODO: Convenience constants combining all height / minheight flags. // TODO: When flags are out, switch to per-block classes :p. @@ -3904,6 +3907,10 @@ public class BlockProperties { bminY = 0; bmaxY = 1.0; } + else if ((flags & F_HEIGHT16_15) != 0) { + bminY = 0; + bmaxY = 0.9375; + } else if ((flags & F_HEIGHT_8SIM_DEC) != 0) { bminY = 0; final int data = node.getData(access, x, y, z);