From 62df128efdb475a8c8adc9ab3ab96386fb426387 Mon Sep 17 00:00:00 2001 From: asofold Date: Sat, 18 Aug 2018 22:23:21 +0200 Subject: [PATCH] [BLEEDING][BREAKING] MC 1.13 Material changes, first batch. First batch: * Initialize blocks somehow, so no errors nor missing blocks happen during startup. Possibly Missing: * There might be references of removed/renamed material (blocks/items) throughout the code. * Some blocks may behave different now/then. Missing: * Block#getData may not reflect (all?) properties anymore. * Block shape getting is missing. Block shapes are now (potentially) more complex to process. Concept might be to keep a double array for the rough bounds, and add an (optional +- null) array of arrays for sub shapes, if present (IBlockCacheNode). So a first rough update is more simple/compatible. --- .../nocheatplus/utilities/StringUtil.java | 4 + .../test/TestSimpleCharPrefixTree.java | 111 +++- .../HotFixFallingBlockPortalEnter.java | 6 +- .../compat/bukkit/MCAccessBukkit.java | 22 +- .../compat/bukkit/MCAccessBukkitBase.java | 18 +- .../checks/blockbreak/BlockBreakData.java | 2 +- .../checks/blockplace/Against.java | 8 +- .../checks/blockplace/AutoSign.java | 5 +- .../checks/blockplace/BlockPlaceListener.java | 6 +- .../checks/inventory/InventoryListener.java | 3 +- .../checks/moving/MovingListener.java | 15 +- .../checks/moving/player/NoFall.java | 2 +- .../nocheatplus/compat/BridgeMaterial.java | 420 ++++++++++++++ .../nocheatplus/compat/BridgeMisc.java | 7 +- .../changetracker/BlockChangeListener.java | 3 +- .../compat/blocks/init/BlockInit.java | 41 +- .../blocks/init/vanilla/BlocksMC1_10.java | 11 +- .../blocks/init/vanilla/BlocksMC1_11.java | 30 +- .../blocks/init/vanilla/BlocksMC1_12.java | 70 +-- .../blocks/init/vanilla/BlocksMC1_13.java | 183 ++++++ .../blocks/init/vanilla/BlocksMC1_5.java | 36 +- .../blocks/init/vanilla/BlocksMC1_6_1.java | 15 +- .../blocks/init/vanilla/BlocksMC1_7_2.java | 27 +- .../blocks/init/vanilla/BlocksMC1_8.java | 121 ++-- .../blocks/init/vanilla/BlocksMC1_9.java | 27 +- .../init/vanilla/VanillaBlocksFactory.java | 1 + .../MultiClientProtocolBlockShapePatch.java | 15 +- .../nocheatplus/config/DefaultConfig.java | 10 +- .../nocheatplus/penalties/ActionPenalty.java | 14 + .../nocheatplus/utilities/InventoryUtil.java | 14 - .../nocheatplus/utilities/map/BlockCache.java | 2 +- .../nocheatplus/utilities/map/BlockFlags.java | 10 + .../utilities/map/BlockProperties.java | 545 +++++++++++++----- .../utilities/map/FakeBlockCache.java | 2 +- .../utilities/map/MaterialUtil.java | 401 +++++++++++++ NCPPlugin/src/main/resources/plugin.yml | 1 + .../nocheatplus/test/TestConfig.java | 9 +- .../test/TestInteractRayTracing.java | 6 +- 38 files changed, 1771 insertions(+), 452 deletions(-) create mode 100644 NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/BridgeMaterial.java create mode 100644 NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_13.java create mode 100644 NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/MaterialUtil.java diff --git a/NCPCommons/src/main/java/fr/neatmonster/nocheatplus/utilities/StringUtil.java b/NCPCommons/src/main/java/fr/neatmonster/nocheatplus/utilities/StringUtil.java index ec44c076..416e424e 100644 --- a/NCPCommons/src/main/java/fr/neatmonster/nocheatplus/utilities/StringUtil.java +++ b/NCPCommons/src/main/java/fr/neatmonster/nocheatplus/utilities/StringUtil.java @@ -430,4 +430,8 @@ public class StringUtil { return false; } + public static String reverse(final String input) { + return new StringBuilder(input).reverse().toString(); + } + } diff --git a/NCPCommons/src/test/java/fr/neatmonster/nocheatplus/test/TestSimpleCharPrefixTree.java b/NCPCommons/src/test/java/fr/neatmonster/nocheatplus/test/TestSimpleCharPrefixTree.java index b4f09015..d9f3edc1 100644 --- a/NCPCommons/src/test/java/fr/neatmonster/nocheatplus/test/TestSimpleCharPrefixTree.java +++ b/NCPCommons/src/test/java/fr/neatmonster/nocheatplus/test/TestSimpleCharPrefixTree.java @@ -20,34 +20,93 @@ import java.util.List; import org.junit.Test; +import fr.neatmonster.nocheatplus.utilities.StringUtil; import fr.neatmonster.nocheatplus.utilities.ds.prefixtree.SimpleCharPrefixTree; public class TestSimpleCharPrefixTree { - private List feed = Arrays.asList( - "op", "op dummy", "ncp info" - ); - - private List mustFind = Arrays.asList( - "op", "op dummy", "ncp info", "ncp info test" - ); - - private List mustNotFind = Arrays.asList( - "opp", "opp dummy", "op dummy2", "ncp", "ncp dummy" - ); + private List feed = Arrays.asList( + "op", "op dummy", "ncp info" + ); + + private List mustFind = Arrays.asList( + "op", "op dummy", "ncp info", "ncp info test" + ); + + private List mustNotFindWords = Arrays.asList( + "opp", "opp dummy", "op dummy2", "ncp", "ncp dummy" + ); + + private List mustNotFindPrefix = Arrays.asList( + "ok", "ncp", "ncp dummy", "ncp inf" + ); + + /** Numbers are neither prefix nor suffix of each other. */ + private List uniqueNumbers = Arrays.asList( + "123456", "2345678", "34567", "456789" + ); + + @Test + public void testPrefixWords(){ + SimpleCharPrefixTree tree = new SimpleCharPrefixTree(); + tree.feedAll(feed, false, true); + for (String input : mustFind){ + if (!tree.hasPrefixWords(input)){ + fail("Expect to be matched: '" + input + "'"); + } + } + for (String input : mustNotFindWords){ + if (tree.hasPrefixWords(input)){ + fail("Expect not to be matched: '" + input + "'"); + } + } + } + + @Test + public void testHasPrefix() { + SimpleCharPrefixTree tree = new SimpleCharPrefixTree(); + tree.feedAll(feed, false, true); + // Same tests as with prefix words. + for (String input : mustFind){ + if (!tree.hasPrefix(input)){ + fail("Expect to be matched: '" + input + "'"); + } + } + for (String input : mustNotFindPrefix){ + if (tree.hasPrefix(input)){ + fail("Expect not to be matched: '" + input + "'"); + } + } + // Extra + if (!tree.hasPrefix("ncp infocrabs")) { + fail("'ncp info' should be a prefix of 'ncp infocrabs'."); + } + } + + @Test + public void testSuffixTree() { + SimpleCharPrefixTree prefixTree = new SimpleCharPrefixTree(); + prefixTree.feedAll(uniqueNumbers, false, true); + SimpleCharPrefixTree suffixTree = new SimpleCharPrefixTree(); + for (String key : uniqueNumbers) { + suffixTree.feed(StringUtil.reverse(key)); + } + for (String input : uniqueNumbers) { + if (!prefixTree.hasPrefix(input)) { + fail("Fed data not matching prefix tree: " + input); + } + if (suffixTree.hasPrefix(input)) { + fail("Non-reversed data is matching suffix tree: " + input); + } + } + for (String input : uniqueNumbers) { + input = StringUtil.reverse(input); + if (prefixTree.hasPrefix(input)) { + fail("Reversed fed data is matching prefix tree: " + input); + } + if (!suffixTree.hasPrefix(input)) { + fail("Reversed fed data not matching suffix tree: " + input); + } + } + } - @Test - public void testPrefixWords(){ - SimpleCharPrefixTree tree = new SimpleCharPrefixTree(); - tree.feedAll(feed, false, true); - for (String input : mustFind){ - if (!tree.hasPrefixWords(input)){ - fail("Expect to be matched: '" + input + "'"); - } - } - for (String input : mustNotFind){ - if (tree.hasPrefixWords(input)){ - fail("Expect not to be matched: '" + input + "'"); - } - } - } } diff --git a/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/checks/inventory/HotFixFallingBlockPortalEnter.java b/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/checks/inventory/HotFixFallingBlockPortalEnter.java index 2c24ceaf..6efd1159 100644 --- a/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/checks/inventory/HotFixFallingBlockPortalEnter.java +++ b/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/checks/inventory/HotFixFallingBlockPortalEnter.java @@ -26,6 +26,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityPortalEnterEvent; import fr.neatmonster.nocheatplus.NCPAPIProvider; +import fr.neatmonster.nocheatplus.compat.BridgeMaterial; import fr.neatmonster.nocheatplus.compat.versions.ServerVersion; import fr.neatmonster.nocheatplus.logging.Streams; import fr.neatmonster.nocheatplus.utilities.ReflectionUtil; @@ -92,7 +93,10 @@ public class HotFixFallingBlockPortalEnter implements Listener { if (worldData.getGenericInstance(InventoryConfig.class).hotFixFallingBlockEndPortalActive) { final BlockCache blockCache = wrapBlockCache.getBlockCache(); blockCache.setAccess(world); - final boolean nearbyPortal = BlockProperties.collidesId(blockCache, loc.getX() - 2.0, loc.getY() - 2.0, loc.getZ() - 2.0, loc.getX() + 3.0, loc.getY() + 3.0, loc.getZ() + 3.0, Material.ENDER_PORTAL); + final boolean nearbyPortal = BlockProperties.collidesId(blockCache, + loc.getX() - 2.0, loc.getY() - 2.0, loc.getZ() - 2.0, + loc.getX() + 3.0, loc.getY() + 3.0, loc.getZ() + 3.0, + BridgeMaterial.END_PORTAL); blockCache.cleanup(); if (nearbyPortal) { // Likely spigot currently removes entities entering portals anyway (cross-world teleport issues). diff --git a/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/MCAccessBukkit.java b/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/MCAccessBukkit.java index 7cf73218..08b85e3b 100644 --- a/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/MCAccessBukkit.java +++ b/NCPCompatBukkit/src/main/java/fr/neatmonster/nocheatplus/compat/bukkit/MCAccessBukkit.java @@ -15,14 +15,18 @@ package fr.neatmonster.nocheatplus.compat.bukkit; +import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.Set; import org.bukkit.Material; +import fr.neatmonster.nocheatplus.compat.BridgeMaterial; import fr.neatmonster.nocheatplus.compat.blocks.BlockPropertiesSetup; import fr.neatmonster.nocheatplus.config.WorldConfigProvider; import fr.neatmonster.nocheatplus.utilities.map.BlockProperties; +import fr.neatmonster.nocheatplus.utilities.map.MaterialUtil; public class MCAccessBukkit extends MCAccessBukkitBase implements BlockPropertiesSetup{ @@ -37,12 +41,24 @@ public class MCAccessBukkit extends MCAccessBukkitBase implements BlockPropertie final Set fullBlocks = new HashSet(); for (final Material mat : new Material[]{ // TODO: Ice !? / Packed ice !? - Material.GLASS, Material.GLOWSTONE, Material.ICE, Material.LEAVES, - Material.COMMAND, Material.BEACON, - Material.PISTON_BASE, + Material.GLASS, Material.GLOWSTONE, Material.ICE, + BridgeMaterial.COMMAND_BLOCK, Material.BEACON, + BridgeMaterial.PISTON, }) { fullBlocks.add(mat); } + @SuppressWarnings("unchecked") + final List> fullBlockSets = Arrays.asList( + // TODO: GLASS_TYPES, ICE_TYPES, + MaterialUtil.LEAVES, + BridgeMaterial.getAll( + "repeating_command_block", "chain_command_block" + )); + for (final Set set : fullBlockSets) { + for (final Material mat : set) { + fullBlocks.add(mat); + } + } for (final Material mat : Material.values()) { if (!mat.isBlock()) { continue; 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 ae0096de..b916929a 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 @@ -34,6 +34,7 @@ import fr.neatmonster.nocheatplus.compat.MCAccess; import fr.neatmonster.nocheatplus.utilities.PotionUtil; import fr.neatmonster.nocheatplus.utilities.ReflectionUtil; import fr.neatmonster.nocheatplus.utilities.map.BlockCache; +import fr.neatmonster.nocheatplus.utilities.map.MaterialUtil; public class MCAccessBukkitBase implements MCAccess { @@ -239,15 +240,14 @@ public class MCAccessBukkitBase implements MCAccess { @Override public AlmostBoolean isBlockLiquid(final Material mat) { - if (mat == null) return AlmostBoolean.MAYBE; - switch (mat) { - case STATIONARY_LAVA: - case STATIONARY_WATER: - case WATER: - case LAVA: - return AlmostBoolean.YES; - default: - return AlmostBoolean.NO; + if (mat == null) { + return AlmostBoolean.MAYBE; + } + else if (MaterialUtil.WATER.contains(mat) || MaterialUtil.LAVA.contains(mat)) { + return AlmostBoolean.YES; + } + else { + return AlmostBoolean.NO; } } diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockbreak/BlockBreakData.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockbreak/BlockBreakData.java index 105662eb..676d9a0c 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockbreak/BlockBreakData.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockbreak/BlockBreakData.java @@ -95,7 +95,7 @@ public class BlockBreakData extends ACheckData implements IDataOnReload { clickedY = block.getY(); clickedZ = block.getZ(); clickedTick = tick; - clickedTool = tool == Material.AIR ? null : tool; + clickedTool = BlockProperties.isAir(tool) ? null : tool; } /** diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockplace/Against.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockplace/Against.java index beecb32d..bd1c0bef 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockplace/Against.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockplace/Against.java @@ -24,6 +24,7 @@ import fr.neatmonster.nocheatplus.checks.Check; import fr.neatmonster.nocheatplus.checks.CheckType; import fr.neatmonster.nocheatplus.checks.ViolationData; import fr.neatmonster.nocheatplus.checks.blockinteract.BlockInteractData; +import fr.neatmonster.nocheatplus.compat.BridgeMaterial; import fr.neatmonster.nocheatplus.permissions.Permissions; import fr.neatmonster.nocheatplus.players.IPlayerData; import fr.neatmonster.nocheatplus.utilities.map.BlockProperties; @@ -42,7 +43,10 @@ public class Against extends Check { final Block blockAgainst, final boolean isInteractBlock, final BlockPlaceData data, final BlockPlaceConfig cc, final IPlayerData pData) { boolean violation = false; - // TODO: Make more precise (workarounds like WATER_LILY, general points, such as action?). + /* + * TODO: Make more precise (workarounds like BridgeMisc.LILY_PAD, + * general points, such as action?). + */ // Workaround for signs on cactus and similar. final BlockInteractData bdata = pData.getGenericInstance(BlockInteractData.class); // TODO: pass as argument. final Material againstType = blockAgainst.getType(); @@ -65,7 +69,7 @@ public class Against extends Check { } else if (BlockProperties.isLiquid(againstType)) { // TODO: F_PLACE_AGAINST_WATER|LIQUID... - if ((placedMat != Material.WATER_LILY + if ((placedMat != BridgeMaterial.LILY_PAD || !BlockProperties.isLiquid(block.getRelative(BlockFace.DOWN).getType())) && !pData.hasPermission(Permissions.BLOCKPLACE_AGAINST_LIQUIDS, player)) { violation = true; diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockplace/AutoSign.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockplace/AutoSign.java index 4c6f70a2..eb16486a 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockplace/AutoSign.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockplace/AutoSign.java @@ -27,6 +27,7 @@ import fr.neatmonster.nocheatplus.actions.ParameterName; import fr.neatmonster.nocheatplus.checks.Check; import fr.neatmonster.nocheatplus.checks.CheckType; import fr.neatmonster.nocheatplus.checks.ViolationData; +import fr.neatmonster.nocheatplus.compat.BridgeMaterial; import fr.neatmonster.nocheatplus.players.IPlayerData; import fr.neatmonster.nocheatplus.utilities.StringUtil; import fr.neatmonster.nocheatplus.utilities.TickTask; @@ -59,8 +60,8 @@ public class AutoSign extends Check { final BlockPlaceData data = pData.getGenericInstance(BlockPlaceData.class); final BlockPlaceConfig cc = pData.getGenericInstance(BlockPlaceConfig.class); Material mat = block.getType(); - if (mat == Material.SIGN_POST || mat == Material.WALL_SIGN) { - mat = Material.SIGN; + if (mat == BridgeMaterial.SIGN || mat == Material.WALL_SIGN) { + mat = Material.SIGN; // ITEM } if (data.autoSignPlacedHash != BlockPlaceListener.getBlockPlaceHash(block, mat)){ tags.add("block_mismatch"); diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockplace/BlockPlaceListener.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockplace/BlockPlaceListener.java index 225bb6e3..762d40f1 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockplace/BlockPlaceListener.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockplace/BlockPlaceListener.java @@ -56,10 +56,10 @@ import fr.neatmonster.nocheatplus.players.DataManager; import fr.neatmonster.nocheatplus.players.IPlayerData; import fr.neatmonster.nocheatplus.players.PlayerFactoryArgument; import fr.neatmonster.nocheatplus.stats.Counters; -import fr.neatmonster.nocheatplus.utilities.InventoryUtil; import fr.neatmonster.nocheatplus.utilities.ReflectionUtil; import fr.neatmonster.nocheatplus.utilities.TickTask; import fr.neatmonster.nocheatplus.utilities.map.BlockProperties; +import fr.neatmonster.nocheatplus.utilities.map.MaterialUtil; import fr.neatmonster.nocheatplus.worlds.WorldFactoryArgument; /** @@ -375,14 +375,14 @@ public class BlockPlaceListener extends CheckListener { final IPlayerData pData = DataManager.getPlayerData(player); final BlockPlaceConfig cc = pData.getGenericInstance(BlockPlaceConfig.class); final Material type = stack.getType(); - if (InventoryUtil.isBoat(type)) { + if (MaterialUtil.isBoat(type)) { if (cc.preventBoatsAnywhere) { // TODO: Alter config (activation, allow on top of ground). // TODO: Version/plugin specific alteration for 'default'. checkBoatsAnywhere(player, event, cc, pData); } } - else if (type == Material.MONSTER_EGG) { + else if (MaterialUtil.isSpawnEgg(type)) { // Check blockplace.speed. if (speed.isEnabled(player, pData) && speed.check(player, cc, pData)) { // If the check was positive, cancel the event. diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/inventory/InventoryListener.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/inventory/InventoryListener.java index 112fa1b2..80ff5c97 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/inventory/InventoryListener.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/inventory/InventoryListener.java @@ -65,6 +65,7 @@ import fr.neatmonster.nocheatplus.players.PlayerFactoryArgument; import fr.neatmonster.nocheatplus.stats.Counters; import fr.neatmonster.nocheatplus.utilities.InventoryUtil; import fr.neatmonster.nocheatplus.utilities.ReflectionUtil; +import fr.neatmonster.nocheatplus.utilities.map.MaterialUtil; import fr.neatmonster.nocheatplus.worlds.WorldFactoryArgument; /** @@ -455,7 +456,7 @@ public class InventoryListener extends CheckListener implements JoinLeaveListen // TODO: Activate mob-egg check only for specific server versions. final ItemStack stack = Bridge1_9.getUsedItem(player, event); Entity entity = event.getRightClicked(); - if (stack != null && stack.getType() == Material.MONSTER_EGG + if (stack != null && MaterialUtil.isSpawnEgg(stack.getType()) && (entity == null || entity instanceof LivingEntity || entity instanceof ComplexEntityPart) && items.isEnabled(player, DataManager.getPlayerData(player))) { event.setCancelled(true); diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java index f94b8914..bc0d4484 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/MovingListener.java @@ -1925,6 +1925,13 @@ public class MovingListener extends CheckListener implements TickListener, IRemo // Always keep fall damage. player.setFallDistance((float) fallDistance); data.noFallFallDistance = (float) fallDistance; + + // TEST: Detect jumping on a just placed fence. + // 1. Detect the low correction teleport. + // 2. Detect the fence. + // 3. Verify the past move. + // (4. Check for a block change entry or last placed block.) + // TODO: REMOVE TEST } else if (fallDistance > 1.0 && fallDistance - player.getFallDistance() > 0.0) { // Reset fall distance if set so in the config. @@ -2817,10 +2824,10 @@ public class MovingListener extends CheckListener implements TickListener, IRemo if (from.getBlockFlags() != 0) { builder.append("\nfrom flags: " + StringUtil.join(BlockProperties.getFlagNames(from.getBlockFlags()), "+")); } - if (from.getTypeId() != Material.AIR) { + if (!BlockProperties.isAir(from.getTypeId())) { DebugUtil.addBlockInfo(builder, from, "\nfrom"); } - if (from.getTypeIdBelow() != Material.AIR) { + if (!BlockProperties.isAir(from.getTypeIdBelow())) { DebugUtil.addBlockBelowInfo(builder, from, "\nfrom"); } if (!from.isOnGround() && from.isOnGround(0.5)) { @@ -2830,10 +2837,10 @@ public class MovingListener extends CheckListener implements TickListener, IRemo if (to.getBlockFlags() != 0) { builder.append("\nto flags: " + StringUtil.join(BlockProperties.getFlagNames(to.getBlockFlags()), "+")); } - if (to.getTypeId() != Material.AIR) { + if (!BlockProperties.isAir(to.getTypeId())) { DebugUtil.addBlockInfo(builder, to, "\nto"); } - if (to.getTypeIdBelow() != Material.AIR) { + if (!BlockProperties.isAir(to.getTypeIdBelow())) { DebugUtil.addBlockBelowInfo(builder, to, "\nto"); } if (!to.isOnGround() && to.isOnGround(0.5)) { diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/player/NoFall.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/player/NoFall.java index 94d785ae..b253278e 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/player/NoFall.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/moving/player/NoFall.java @@ -38,7 +38,7 @@ import fr.neatmonster.nocheatplus.utilities.location.PlayerLocation; public class NoFall extends Check { /* - * TODO: Due to soil not converting back to dirt with the current + * TODO: Due to farmland/soil not converting back to dirt with the current * implementation: Implement packet sync with moving events. Then alter * packet on-ground and mc fall distance for a new default concept. As a * fall back either the old method, or an adaption with scheduled/later fall diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/BridgeMaterial.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/BridgeMaterial.java new file mode 100644 index 00000000..0300181f --- /dev/null +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/BridgeMaterial.java @@ -0,0 +1,420 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package fr.neatmonster.nocheatplus.compat; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.bukkit.Material; + +import fr.neatmonster.nocheatplus.utilities.StringUtil; +import fr.neatmonster.nocheatplus.utilities.ds.prefixtree.SimpleCharPrefixTree; + +public class BridgeMaterial { + + // TODO: Should be non static, ideally. + + /** Legacy Material by lower case name without preceding 'legacy_' part. */ + private static final Map legacy = new HashMap(); + + /** Actual lower case name to Material map for all existing materials. */ + private static final Map all = new HashMap(); + + static { + for (Material mat : Material.values()) { + String name = mat.name().toLowerCase(); + all.put(name, mat); + if (name.startsWith("legacy_")) { + legacy.put(name.substring(7), mat); + } + } + } + + public static Material legacy(String name) { + return legacy.get(name.toLowerCase()); + } + + /** + * Get current Material by case-insensitive name. + * + * @param name + * @return + */ + public static Material get(String name) { + return all.get(name.toLowerCase()); + } + + /** + * Like {@link BridgeMaterial#get(String)}, but return null for non-blocks. + * + * @param name + * @return + */ + public static Material getBlock(String name) { + Material mat = get(name); + if (mat == null || !mat.isBlock()) { + return null; + } + else { + return mat; + } + } + + /** + * Get current Material by case-insensitive name. + * + * @param name + * @return + * @throws NullPointerException If the material is not present. + */ + public static Material getNotNull(String name) { + final Material mat = get(name); + if (mat == null) { + throw new NullPointerException("Material not present: " + name); + } + else { + return mat; + } + } + + /** + * Get current Material by case-insensitive names, return the first Material + * instance that exists for a given name. + * + * @param name + * @return + */ + public static Material getFirst(String... names) { + for (String name : names) { + final Material mat = get(name); + if (mat != null) { + return mat; + } + } + return null; + } + + /** + * Get current Material by case-insensitive names, return the first Material + * instance that exists for a given name. + * + * @param name + * @return + * @throws NullPointerException + * If no material is present. + */ + public static Material getFirstNotNull(String... names) { + final Material mat = getFirst(names); + if (mat == null) { + throw new NullPointerException("Material not present: " + StringUtil.join(names, ", ")); + } + else { + return mat; + } + } + + public static Set getAll(String... names) { + final LinkedHashSet res = new LinkedHashSet(); + for (final String name : names) { + final Material mat = get(name); + if (mat != null) { + res.add(mat); + } + } + return res; + } + + public static boolean has(String name) { + return all.containsKey(name.toLowerCase()); + } + + ///////////////////////////////////////////////////////// + // Specific unique material instances for items (only). + ///////////////////////////////////////////////////////// + + public static final Material DIAMOND_SHOVEL = getFirstNotNull("diamond_shovel", "diamond_spade"); + + public static final Material GOLDEN_AXE = getFirstNotNull("golden_axe", "gold_axe"); + public static final Material GOLDEN_HOE = getFirstNotNull("golden_hoe", "gold_hoe"); + public static final Material GOLDEN_PICKAXE = getFirstNotNull("golden_pickaxe", "gold_pickaxe"); + public static final Material GOLDEN_SHOVEL = getFirstNotNull("golden_shovel", "gold_spade"); + public static final Material GOLDEN_SWORD = getFirstNotNull("golden_sword", "gold_sword"); + + public static final Material IRON_SHOVEL = getFirstNotNull("iron_shovel", "iron_spade"); + + public static final Material STONE_SHOVEL = getFirstNotNull("stone_shovel", "stone_spade"); + + public static final Material WOODEN_AXE = getFirstNotNull("wooden_axe", "wood_axe"); + public static final Material WOODEN_HOE = getFirstNotNull("wooden_hoe", "wood_hoe"); + public static final Material WOODEN_PICKAXE = getFirstNotNull("wooden_pickaxe", "wood_pickaxe"); + public static final Material WOODEN_SHOVEL = getFirstNotNull("wooden_shovel", "wood_spade"); + public static final Material WOODEN_SWORD = getFirstNotNull("wooden_sword", "wood_sword"); + + + /////////////////////////////////////////////////// + // Specific unique material instances for blocks. + /////////////////////////////////////////////////// + + public static final Material BEETROOTS = getFirst("beetroots", "beetroot_block"); + + public static final Material BRICKS = getFirst("bricks", "brick"); + public static final Material BRICK_SLAB = getFirst("brick_slab"); + + public static final Material CAKE = getFirstNotNull("cake_block", "cake"); + + public static final Material CARROTS = getFirst("carrots", "carrot"); + + public static final Material CAVE_AIR = getFirst("cave_air"); + + public static final Material CHAIN_COMMAND_BLOCK = getFirst( + "chain_command_block", "command_chain"); + + public static final Material COBBLESTONE_WALL = getFirstNotNull("cobblestone_wall", "cobble_wall"); + + public static final Material COBWEB = getFirstNotNull("cobweb", "web"); + + public static final Material COMMAND_BLOCK = getFirstNotNull("command_block", "command"); + + public static final Material CRAFTING_TABLE = getFirstNotNull("crafting_table", "workbench"); + + public static final Material DANDELION = getFirstNotNull("dandelion", "yellow_flower"); + + public static final Material ENCHANTING_TABLE = getFirstNotNull("enchanting_table", "enchantment_table"); + + public static final Material END_PORTAL = getFirstNotNull("end_portal", "ender_portal"); + public static final Material END_PORTAL_FRAME = getFirstNotNull("end_portal_frame", "ender_portal_frame"); + public static final Material END_STONE = getFirstNotNull("end_stone", "ender_stone"); + public static final Material END_STONE_BRICKS = getFirst("end_stone_bricks", "end_bricks"); + + public static final Material FARMLAND = getFirstNotNull("farmland", "soil"); + + /** Could be null for very old Minecraft. */ + public static final Material FIREWORK_ROCKET = getFirst("firework_rocket", "firework"); + + /** Passable (long) grass block. */ + public static final Material GRASS = getFirstNotNull("long_grass", "grass"); + + /** Classic dirt-like grass block. */ + public static final Material GRASS_BLOCK = getFirstNotNull("grass_block", "grass"); + + public static final Material HEAVY_WEIGHTED_PRESSURE_PLATE = getFirstNotNull( + "heavy_weighted_pressure_plate", "iron_plate"); + + public static final Material IRON_BARS = getFirstNotNull("iron_bars", "iron_fence"); + /** (Block.) */ + public static final Material IRON_DOOR = getFirstNotNull("iron_door_block", "iron_door"); + + public static final Material LIGHT_WEIGHTED_PRESSURE_PLATE = getFirstNotNull( + "light_weighted_pressure_plate", "gold_plate"); + + public static final Material LILY_PAD = getFirstNotNull("lily_pad", "water_lily"); + + public static final Material MAGMA_BLOCK = getFirst("magma_block", "magma"); + + /** (Block.) /*/ + public static final Material MELON = getFirstNotNull("melon_block", "melon"); + + public static final Material MOVING_PISTON = getFirstNotNull("moving_piston", "piston_moving_piece"); + + public static final Material MYCELIUM = getFirstNotNull("mycelium", "mycel"); + + public static final Material NETHER_BRICKS = getFirstNotNull("nether_bricks", "nether_brick"); + public static final Material NETHER_BRICK_FENCE = getFirstNotNull("nether_brick_fence", "nether_fence"); + public static final Material NETHER_PORTAL = getFirstNotNull("nether_portal", "portal"); + public static final Material NETHER_QUARTZ_ORE = getFirstNotNull("nether_quartz_ore", "quartz_ore"); + public static final Material NETHER_WARTS = getFirstNotNull("nether_warts", "nether_wart"); + + /** For reference: ordinary log. */ + public static final Material OAK_LOG = getFirstNotNull("oak_log", "log"); + /** For reference: ordinary wood. */ + public static final Material OAK_WOOD = getFirstNotNull("oak_wood", "wood"); + /** For reference: the ordinary wooden trap door. */ + public static final Material OAK_TRAPDOOR = getFirstNotNull("oak_trapdoor", "trap_door"); + + /** (Block.) */ + public static final Material PISTON = getFirstNotNull("piston_base", "piston"); + public static final Material PISTON_HEAD = getFirstNotNull("piston_head", "piston_extension"); + + public static final Material POTATOES = getFirst("potatoes", "potato"); + + public static final Material RED_NETHER_BRICKS = getFirst("red_nether_bricks", "red_nether_brick"); + + /** For reference to have the breaking/shape. */ + public static final Material REPEATER = getFirstNotNull("repeater", "diode_block_off"); + + public static final Material REPEATING_COMMAND_BLOCK = getFirst( + "repeating_command_block", "command_repeating"); + + /** Sign block. */ + public static final Material SIGN = getFirstNotNull("sign_post", "sign"); + + /** Some skull for reference. */ + public static final Material SKELETON_SKULL = getFirst("skeleton_skull", "skull"); + + public static final Material SPAWNER = getFirstNotNull("spawner", "mob_spawner"); + + /** (Block.) */ + public static final Material STICKY_PISTON = getFirstNotNull("piston_sticky_base", "sticky_piston"); + + public static final Material STONE_BRICKS = getFirstNotNull("stone_bricks", "smooth_brick"); + public static final Material STONE_BRICK_STAIRS = getFirstNotNull( + "stone_brick_stairs", "smooth_stairs"); + public static final Material STONE_PRESSURE_PLATE = getFirstNotNull( + "stone_pressure_plate", "stone_plate"); + public static final Material STONE_SLAB = getFirstNotNull("stone_slab", "step"); + + public static final Material SUGAR_CANE = getFirstNotNull("sugar_cane_block", "sugar_cane"); // Reversed + + // TODO: Which is the old long grass... + public static final Material TALL_GRASS = getFirstNotNull("tall_grass", "long_grass"); + + public static final Material TERRACOTTA = getFirstNotNull("terracotta", "hard_clay"); + + public static final Material VOID_AIR = get("void_air"); // May be null on legacy spigot. + + public static final Material WHEAT_CROPS = getFirstNotNull("crops", "wheat"); // Reversed + + private static void getBySuffix(final String suffix, final AlmostBoolean isBlock, + final SimpleCharPrefixTree excludePrefixTree, final Set res) { + for (final Entry entry : all.entrySet()) { + final String key = entry.getKey(); + if (key.endsWith(suffix)) { + if (excludePrefixTree.hasPrefix(key)) { + continue; + } + final Material value = entry.getValue(); + if (isBlock == AlmostBoolean.MAYBE || !(isBlock.decide() ^ value.isBlock())) { + res.add(value); + } + } + } + } + + /** + * + * @param suffix + * @param isBlock + * @param excludePrefixes + * @return + */ + public static Set getBySuffix(final String suffix, + final AlmostBoolean isBlock, final String... excludePrefixes) { + final Set res = new LinkedHashSet(); + final SimpleCharPrefixTree prefixTree = new SimpleCharPrefixTree(); + prefixTree.feedAll(Arrays.asList(excludePrefixes), false, true); + getBySuffix(suffix.toLowerCase(), isBlock, prefixTree, res); + return res; + } + + /** + * Collect materials for all suffices as + * {@link #getBySuffix(String, AlmostBoolean, String...)} does for one.
+ * + * @param suffices + * @param isBlock + * @param excludePrefixes + * @return + */ + public static Set getBySuffix(final Collection suffices, + final AlmostBoolean isBlock, final String... excludePrefixes) { + final Set res = new LinkedHashSet(); + final SimpleCharPrefixTree prefixTree = new SimpleCharPrefixTree(); + prefixTree.feedAll(Arrays.asList(excludePrefixes), false, true); + for (final String suffix : suffices) { + getBySuffix(suffix.toLowerCase(), isBlock, prefixTree, res); + } + return res; + } + + public static Set getByPrefix(final String prefix, final AlmostBoolean isBlock) { + final Set res = new LinkedHashSet(); + for (final Entry entry : all.entrySet()) { + final String key = entry.getKey(); + if (key.startsWith(prefix)) { + final Material value = entry.getValue(); + if (isBlock == AlmostBoolean.MAYBE || !(isBlock.decide() ^ value.isBlock())) { + res.add(value); + } + } + } + return res; + } + + /** + * Return materials for which all prefixes and suffices match but none of + * excludeContains is contained, respecting the isBlock filter. + * + * @param prefixes + * If prefixes is null, all prefixes will match. + * @param suffices + * @param isBlock + * @param excludeContains + * @return + */ + public static Set getByPrefixAndSuffix(final Collection prefixes, + final Collection suffices, final AlmostBoolean isBlock, + final String... excludeContains) { + final Set res = new LinkedHashSet(); + final List useExcludeContains = new LinkedList(); + for (final String exclude : excludeContains) { + useExcludeContains.add(exclude.toLowerCase()); + } + final SimpleCharPrefixTree prefixTree; + if (prefixes == null) { + prefixTree = null; + } + else { + prefixTree = new SimpleCharPrefixTree(); + prefixTree.feedAll(prefixes, false, true); + } + final SimpleCharPrefixTree suffixTree = new SimpleCharPrefixTree(); // reversed inputs (!). + for (final String suffix : suffices) { + suffixTree.feed(StringUtil.reverse(suffix.toLowerCase())); + } + final boolean isBlockDecided = isBlock.decide(); + for (final Entry entry : all.entrySet()) { + final String key = entry.getKey(); + if ((prefixTree == null || prefixTree.hasPrefix(key)) + && suffixTree.hasPrefix(StringUtil.reverse(key))) { + final Material value = entry.getValue(); + if (isBlock == AlmostBoolean.MAYBE || !(isBlockDecided ^ value.isBlock())) { + boolean match = true; + for (final String exclude : useExcludeContains) { + if (key.contains(exclude)) { + match = false; + break; + } + } + if (match) { + res.add(entry.getValue()); + } + } + } + } + return res; + } + + // public static Set getKeySet() { + // return all.keySet(); + // } + +} diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/BridgeMisc.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/BridgeMisc.java index 6f4937da..5603fa14 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/BridgeMisc.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/BridgeMisc.java @@ -50,8 +50,6 @@ public class BridgeMisc { private static final Method Bukkit_getOnlinePlayers = ReflectionUtil.getMethodNoArgs(Bukkit.class, "getOnlinePlayers"); - public static final Material FIREWORK = Material.getMaterial("FIREWORK"); - /** * Correction of position: Used for ordinary setting back.
* NOTE: Currently it's not distinguished, if we do it as a proactive @@ -130,7 +128,8 @@ public class BridgeMisc { public static boolean maybeElytraBoost(final Player player, final Material materialInHand) { // TODO: Account for MC version (needs configuration override or auto adapt to protocol support). // TODO: Non-static due to version checks (...). - return FIREWORK != null && materialInHand == FIREWORK && Bridge1_9.isGlidingWithElytra(player); + return BridgeMaterial.FIREWORK_ROCKET != null + && materialInHand == BridgeMaterial.FIREWORK_ROCKET && Bridge1_9.isGlidingWithElytra(player); } /** @@ -142,7 +141,7 @@ public class BridgeMisc { * the item is null or can't be judged, -1 is returned. */ public static int getFireworksPower(final ItemStack item) { - if (item == null || item.getType() != FIREWORK) { + if (item == null || item.getType() != BridgeMaterial.FIREWORK_ROCKET) { return 0; } final ItemMeta meta = item.getItemMeta(); diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/changetracker/BlockChangeListener.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/changetracker/BlockChangeListener.java index 2602ba1e..4424410e 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/changetracker/BlockChangeListener.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/changetracker/BlockChangeListener.java @@ -36,6 +36,7 @@ import org.bukkit.material.Door; import org.bukkit.material.MaterialData; import fr.neatmonster.nocheatplus.NCPAPIProvider; +import fr.neatmonster.nocheatplus.compat.BridgeMaterial; import fr.neatmonster.nocheatplus.components.NoCheatPlusAPI; import fr.neatmonster.nocheatplus.components.registry.order.RegistrationOrder.RegisterMethodWithOrder; import fr.neatmonster.nocheatplus.event.mini.MiniListener; @@ -280,7 +281,7 @@ public class BlockChangeListener implements Listener { if (block != null) { final Material type = block.getType(); // TODO: Consider a flag. - if (type == Material.SOIL) { + if (type == BridgeMaterial.FARMLAND) { tracker.addBlocks(block); } } diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/BlockInit.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/BlockInit.java index 41cb5315..b74f90d2 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/BlockInit.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/BlockInit.java @@ -16,12 +16,13 @@ package fr.neatmonster.nocheatplus.compat.blocks.init; import org.bukkit.Material; +import fr.neatmonster.nocheatplus.compat.BridgeMaterial; import fr.neatmonster.nocheatplus.utilities.map.BlockFlags; import fr.neatmonster.nocheatplus.utilities.map.BlockProperties; /** * Auxiliary methods for block initialization. - * @author mc_dev + * @author asofold * */ public class BlockInit { @@ -47,6 +48,17 @@ public class BlockInit { } } + /** + * Set the block breaking properties of newMat to the same as are present + * for mat. + * + * @param newMat + * @param mat + */ + public static void setPropsAs(Material newMat, Material mat) { + BlockProperties.setBlockProps(newMat, BlockProperties.getBlockProps(mat)); + } + /** * Set block breaking properties same as the block of the given material. * @param newId @@ -65,6 +77,11 @@ public class BlockInit { BlockProperties.setBlockProps(newId, BlockProperties.getBlockProps(otherId)); } + public static void setAs(Material newMat, Material mat) { + BlockFlags.setFlagsAs(newMat, mat); + setPropsAs(newMat, mat); + } + /** * Set block breaking and shape properties same as the block of the given material. * @param newId @@ -94,4 +111,26 @@ public class BlockInit { BlockProperties.setBlockProps(newId, BlockProperties.instantType); } + /** + * Set like air, plus instantly breakable. + * @param newId + */ + public static void setInstantAir(Material newId) { + BlockFlags.setFlagsAs(newId, Material.AIR); + BlockProperties.setBlockProps(newId, BlockProperties.instantType); + } + + public static void setAsIfExists(String newName, Material mat) { + if (BridgeMaterial.has(newName)) { + setAs(newName, mat); + } + } + + public static void setAsIfExists(String newName, String otherName) { + if (BridgeMaterial.has(newName)) { + setAs(newName, otherName); + } + } + + } diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_10.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_10.java index 1f6356aa..334a293e 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_10.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_10.java @@ -16,6 +16,7 @@ package fr.neatmonster.nocheatplus.compat.blocks.init.vanilla; import org.bukkit.Material; +import fr.neatmonster.nocheatplus.compat.BridgeMaterial; import fr.neatmonster.nocheatplus.compat.blocks.BlockPropertiesSetup; import fr.neatmonster.nocheatplus.compat.blocks.init.BlockInit; import fr.neatmonster.nocheatplus.config.WorldConfigProvider; @@ -30,7 +31,9 @@ import fr.neatmonster.nocheatplus.logging.StaticLog; public class BlocksMC1_10 implements BlockPropertiesSetup { public BlocksMC1_10() { - BlockInit.assertMaterialExists("MAGMA"); + if (BridgeMaterial.MAGMA_BLOCK == null) { + throw new RuntimeException("Not suitable."); + } BlockInit.assertMaterialExists("BONE_BLOCK"); BlockInit.assertMaterialExists("STRUCTURE_VOID"); } @@ -38,11 +41,11 @@ public class BlocksMC1_10 implements BlockPropertiesSetup { @Override public void setupBlockProperties(WorldConfigProvider worldConfigProvider) { // 213 MAGMA - BlockInit.setAs("MAGMA", Material.STONE_PLATE); + BlockInit.setAs(BridgeMaterial.MAGMA_BLOCK, BridgeMaterial.STONE_PRESSURE_PLATE); // 214 NETHER_WART_BLOCK - BlockInit.setAs("NETHER_WART_BLOCK", Material.SKULL); + BlockInit.setAs("NETHER_WART_BLOCK", BridgeMaterial.SKELETON_SKULL); // 215 RED_NETHER_BRICK - BlockInit.setAs("RED_NETHER_BRICK", Material.NETHER_BRICK); + BlockInit.setAs(BridgeMaterial.RED_NETHER_BRICKS, BridgeMaterial.NETHER_BRICKS); // 216 BONE_BLOCK BlockInit.setAs("BONE_BLOCK", Material.COBBLESTONE); // 217 STRUCTURE_VOID diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_11.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_11.java index 4b027967..7c34de7f 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_11.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_11.java @@ -24,30 +24,9 @@ import fr.neatmonster.nocheatplus.utilities.map.BlockProperties.BlockProps; @SuppressWarnings("deprecation") public class BlocksMC1_11 implements BlockPropertiesSetup { - private static final String[] shulker_boxes = new String[]{ - "WHITE_SHULKER_BOX", - "ORANGE_SHULKER_BOX", - "MAGENTA_SHULKER_BOX", - "LIGHT_BLUE_SHULKER_BOX", - "YELLOW_SHULKER_BOX", - "LIME_SHULKER_BOX", - "PINK_SHULKER_BOX", - "GRAY_SHULKER_BOX", - "SILVER_SHULKER_BOX", - "CYAN_SHULKER_BOX", - "PURPLE_SHULKER_BOX", - "BLUE_SHULKER_BOX", - "BROWN_SHULKER_BOX", - "GREEN_SHULKER_BOX", - "RED_SHULKER_BOX", - "BLACK_SHULKER_BOX" - }; - public BlocksMC1_11() { BlockInit.assertMaterialExists("OBSERVER"); - for (String box : shulker_boxes) { - BlockInit.assertMaterialExists(box); - } + BlockInit.assertMaterialExists("BLACK_SHULKER_BOX"); } @Override @@ -59,12 +38,7 @@ public class BlocksMC1_11 implements BlockPropertiesSetup { BlockProperties.secToMs(15.0, 2.2, 1.1, 0.7, 0.55, 0.45))); BlockProperties.setBlockFlags("OBSERVER", solidFlags); // ALL SORTS OF SHULKER BOXES - for (String box : shulker_boxes) { - // Wiki (16-11-25): 9, 4.5, 2.25, 1.5, 1.15, 0.75 - BlockProperties.setBlockProps(box, new BlockProps(BlockProperties.woodPickaxe, 6, - BlockProperties.secToMs(10.0, 1.45, 0.7, 0.5, 0.35, 0.2))); - BlockProperties.setBlockFlags(box, solidFlags); - } + StaticLog.logInfo("Added block-info for Minecraft 1.11 blocks."); } diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_12.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_12.java index 45d157da..cb11c80d 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_12.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_12.java @@ -14,87 +14,21 @@ */ package fr.neatmonster.nocheatplus.compat.blocks.init.vanilla; -import org.bukkit.Material; - import fr.neatmonster.nocheatplus.compat.blocks.BlockPropertiesSetup; import fr.neatmonster.nocheatplus.compat.blocks.init.BlockInit; import fr.neatmonster.nocheatplus.config.WorldConfigProvider; import fr.neatmonster.nocheatplus.logging.StaticLog; -import fr.neatmonster.nocheatplus.utilities.map.BlockFlags; -import fr.neatmonster.nocheatplus.utilities.map.BlockProperties; -import fr.neatmonster.nocheatplus.utilities.map.BlockProperties.BlockProps; -@SuppressWarnings("deprecation") public class BlocksMC1_12 implements BlockPropertiesSetup { - private static final String[] terracotta = new String[]{ - "WHITE_GLAZED_TERRACOTTA", - "ORANGE_GLAZED_TERRACOTTA", - "MAGENTA_GLAZED_TERRACOTTA", - "LIGHT_BLUE_GLAZED_TERRACOTTA", - "YELLOW_GLAZED_TERRACOTTA", - "LIME_GLAZED_TERRACOTTA", - "PINK_GLAZED_TERRACOTTA", - "GRAY_GLAZED_TERRACOTTA", - "SILVER_GLAZED_TERRACOTTA", - "CYAN_GLAZED_TERRACOTTA", - "PURPLE_GLAZED_TERRACOTTA", - "BLUE_GLAZED_TERRACOTTA", - "BROWN_GLAZED_TERRACOTTA", - "GREEN_GLAZED_TERRACOTTA", - "RED_GLAZED_TERRACOTTA", - "BLACK_GLAZED_TERRACOTTA" - }; - public BlocksMC1_12() { - BlockInit.assertMaterialExists("CONCRETE"); - for (String glazed : terracotta) { - BlockInit.assertMaterialExists(glazed); - } + BlockInit.assertMaterialExists("BLACK_GLAZED_TERRACOTTA"); } @Override public void setupBlockProperties(WorldConfigProvider worldConfigProvider) { - // * MISSING 235(WHITE_GLAZED_TERRACOTTA / SOLID+GROUND) - // * MISSING 236(ORANGE_GLAZED_TERRACOTTA / SOLID+GROUND) - // * MISSING 237(MAGENTA_GLAZED_TERRACOTTA / SOLID+GROUND) - // * MISSING 238(LIGHT_BLUE_GLAZED_TERRACOTTA / SOLID+GROUND) - // * MISSING 239(YELLOW_GLAZED_TERRACOTTA / SOLID+GROUND) - // * MISSING 240(LIME_GLAZED_TERRACOTTA / SOLID+GROUND) - // * MISSING 241(PINK_GLAZED_TERRACOTTA / SOLID+GROUND) - // * MISSING 242(GRAY_GLAZED_TERRACOTTA / SOLID+GROUND) - // * MISSING 243(SILVER_GLAZED_TERRACOTTA / SOLID+GROUND) - // * MISSING 244(CYAN_GLAZED_TERRACOTTA / SOLID+GROUND) - // * MISSING 245(PURPLE_GLAZED_TERRACOTTA / SOLID+GROUND) - // * MISSING 246(BLUE_GLAZED_TERRACOTTA / SOLID+GROUND) - // * MISSING 247(BROWN_GLAZED_TERRACOTTA / SOLID+GROUND) - // * MISSING 248(GREEN_GLAZED_TERRACOTTA / SOLID+GROUND) - // * MISSING 249(RED_GLAZED_TERRACOTTA / SOLID+GROUND) - // * MISSING 250(BLACK_GLAZED_TERRACOTTA / SOLID+GROUND) - // * MISSING 251(CONCRETE / SOLID+GROUND) - // * MISSING 252(CONCRETE_POWDER / SOLID+GROUND) - - BlockProps props = new BlockProps(BlockProperties.woodPickaxe, 1.4f, - BlockProperties.secToMs(7.0, 1.05, 0.55, 0.35, 0.3, 0.2)); - for (String glazed : terracotta) { - // Set flags as with "hardened clay". - BlockFlags.setFlagsAs(glazed, "HARD_CLAY"); - // Breaking times. - BlockProperties.setBlockProps(glazed, props); - } - - // Concrete - BlockFlags.setFlagsAs("CONCRETE", Material.COBBLESTONE); - BlockProperties.setBlockProps("CONCRETE", - new BlockProps(BlockProperties.woodPickaxe, 1.8f, - // TODO: 2.7 with bare hands seems unlikely. - BlockProperties.secToMs(2.7, 1.35, 0.7, 0.45, 0.35, 0.25) - ) - ); - - // Concrete powder - BlockInit.setAs("CONCRETE_POWDER", Material.DIRT); + // (All are done via generic setup.) StaticLog.logInfo("Added block-info for Minecraft 1.12 blocks."); } 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 new file mode 100644 index 00000000..0e360586 --- /dev/null +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_13.java @@ -0,0 +1,183 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package fr.neatmonster.nocheatplus.compat.blocks.init.vanilla; + +import org.bukkit.Material; + +import fr.neatmonster.nocheatplus.compat.BridgeMaterial; +import fr.neatmonster.nocheatplus.compat.blocks.BlockPropertiesSetup; +import fr.neatmonster.nocheatplus.compat.blocks.init.BlockInit; +import fr.neatmonster.nocheatplus.config.WorldConfigProvider; +import fr.neatmonster.nocheatplus.logging.StaticLog; +import fr.neatmonster.nocheatplus.utilities.map.BlockFlags; +import fr.neatmonster.nocheatplus.utilities.map.BlockProperties; +import fr.neatmonster.nocheatplus.utilities.map.BlockProperties.BlockProps; +import fr.neatmonster.nocheatplus.utilities.map.MaterialUtil; + +@SuppressWarnings("deprecation") +public class BlocksMC1_13 implements BlockPropertiesSetup { + + public BlocksMC1_13() { + BlockInit.assertMaterialExists("LILY_PAD"); + BlockInit.assertMaterialExists("CAVE_AIR"); + } + + @Override + public void setupBlockProperties(WorldConfigProvider worldConfigProvider) { + + // Void air. + BlockInit.setAs("VOID_AIR", Material.AIR); + // Cave air. + BlockInit.setAs("CAVE_AIR", Material.AIR); + + // Dirt like. + BlockInit.setAs("PODZOL", Material.DIRT); + BlockInit.setAs("COARSE_DIRT", Material.DIRT); + + // Coral blocks (dead or alive). + for (Material mat : MaterialUtil.CORAL_BLOCKS) { + BlockInit.setAs(mat, Material.STONE); + } + + // Passable (alive) coral parts. + for (Material mat : MaterialUtil.PASSABLE_CORAL_PARTS) { + BlockInit.setInstantAir(mat); + } + + // Dead coral parts (solid + ground already set). + for (Material mat : MaterialUtil.DEAD_CORAL_PARTS) { + // (Flags should be set correctly by default.) + BlockInit.setPropsAs(mat, Material.STONE); + } + + // Kelp. + BlockInit.setInstantAir("KELP"); + + // Fern. + BlockInit.setInstantAir("FERN"); + + // Bubble column. + // TODO: Drag down effect: probably not using velocity. + BlockInit.setAs("BUBBLE_COLUMN", Material.WATER); + + // Further melon/pumpkin stems. + BlockInit.setInstantAir("ATTACHED_MELON_STEM"); + BlockInit.setInstantAir("ATTACHED_PUMPKIN_STEM"); + + // Wall torch + BlockInit.setInstantAir("WALL_TORCH"); + + // Stone types. + for (Material mat : BridgeMaterial.getAll("andesite", "diorite", "granite", + "polished_andesite", "polished_diorite", "polished_granite", + "smooth_stone")) { + BlockInit.setAs(mat, Material.STONE); + } + + // Wall heads. + for (Material mat : MaterialUtil.HEADS_WALL) { + BlockInit.setAs(mat, BridgeMaterial.SKELETON_SKULL); // TODO: Test... + } + + // 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); + + // Red sand. + BlockInit.setAs("RED_SAND", Material.SAND); + + // Sandstone slabs. + BlockInit.setPropsAs("SANDSTONE_SLAB", Material.SANDSTONE); + BlockInit.setPropsAs("RED_SANDSTONE_SLAB", Material.SANDSTONE); + + // More sandstone. + BlockInit.setAs("SMOOTH_SANDSTONE", Material.SANDSTONE); + BlockInit.setAs("SMOOTH_RED_SANDSTONE", Material.SANDSTONE); + BlockInit.setAs("CUT_SANDSTONE", Material.SANDSTONE); + BlockInit.setAs("CUT_RED_SANDSTONE", Material.SANDSTONE); + BlockInit.setAs("CHISELED_SANDSTONE", Material.SANDSTONE); + BlockInit.setAs("CHISELED_RED_SANDSTONE", Material.SANDSTONE); + + // More brick slabs. + BlockInit.setAs("COBBLESTONE_SLAB", BridgeMaterial.BRICK_SLAB); + BlockInit.setAs("STONE_BRICK_SLAB", BridgeMaterial.BRICK_SLAB); + BlockInit.setAs("NETHER_BRICK_SLAB", BridgeMaterial.BRICK_SLAB); + BlockInit.setAs("PRISMARINE_BRICK_SLAB", BridgeMaterial.BRICK_SLAB); + + // More slabs. + BlockInit.setAs("PRISMARINE_SLAB", BridgeMaterial.STONE_SLAB); + BlockInit.setAs("DARK_PRISMARINE_SLAB", BridgeMaterial.STONE_SLAB); + BlockInit.setAs("QUARTZ_SLAB", BridgeMaterial.STONE_SLAB); // TODO: Test. + BlockInit.setAs("PETRIFIED_OAK_SLAB", BridgeMaterial.STONE_SLAB); // TODO: Test. + + // More bricks. + BlockInit.setAs("PRISMARINE_BRICKS", BridgeMaterial.BRICKS); + BlockInit.setAs("MOSSY_STONE_BRICKS", BridgeMaterial.BRICKS); + BlockInit.setAs("CHISELED_STONE_BRICKS", BridgeMaterial.BRICKS); + BlockInit.setAs("CRACKED_STONE_BRICKS", BridgeMaterial.BRICKS); + + // More brick stairs. + BlockInit.setAs("PRISMARINE_BRICK_STAIRS", BridgeMaterial.STONE_BRICK_STAIRS); + + // More stairs. + BlockInit.setAs("PRISMARINE_STAIRS", Material.COBBLESTONE_STAIRS); + BlockInit.setAs("DARK_PRISMARINE_STAIRS", Material.COBBLESTONE_STAIRS); + + // More cobblestone walls. + BlockInit.setAs("MOSSY_COBBLESTONE_WALL", BridgeMaterial.COBBLESTONE_WALL); + + // Dark prismarine. + BlockInit.setAs("DARK_PRISMARINE", "PRISMARINE"); + + // More anvil. + BlockInit.setAs("DAMAGED_ANVIL", "ANVIL"); + BlockInit.setAs("CHIPPED_ANVIL", "ANVIL"); + + // Carved pumpkin. + BlockInit.setAs("CARVED_PUMPKIN", Material.PUMPKIN); + + // Mushroom stem: via MaterialUtil collection. + + // More quartz blocks. + BlockInit.setAs("SMOOTH_QUARTZ", "QUARTZ_BLOCK"); + BlockInit.setAs("CHISELED_QUARTZ_BLOCK", "QUARTZ_BLOCK"); + + // Quartz pillar. + BlockInit.setPropsAs("QUARTZ_PILLAR", "QUARTZ_BLOCK"); + + // Dried kelp block. + BlockProperties.setBlockProps("DRIED_KELP_BLOCK", new BlockProps( + BlockProperties.noTool, 0.5f, BlockProperties.secToMs(0.75))); + + // Conduit. + BlockProperties.setBlockProps("CONDUIT", BlockProperties.woodDoorType); + + // Turtle egg. + BlockProperties.setBlockProps("TURTLE_EGG", new BlockProps( + BlockProperties.noTool, 0.5f, BlockProperties.secToMs(0.7))); + + + StaticLog.logInfo("Added block-info for Minecraft 1.13 blocks."); + } + +} diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_5.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_5.java index 40846e4d..dbbff383 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_5.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_5.java @@ -16,6 +16,7 @@ package fr.neatmonster.nocheatplus.compat.blocks.init.vanilla; import org.bukkit.Material; +import fr.neatmonster.nocheatplus.compat.BridgeMaterial; import fr.neatmonster.nocheatplus.compat.blocks.BlockPropertiesSetup; import fr.neatmonster.nocheatplus.compat.blocks.init.BlockInit; import fr.neatmonster.nocheatplus.config.WorldConfigProvider; @@ -47,29 +48,42 @@ public class BlocksMC1_5 implements BlockPropertiesSetup { // 147 Weighted Pressure Plate (Light) // BlockFlags.addFlags(147, BlockProperties.F_IGN_PASSABLE | BlockProperties.F_GROUND | BlockProperties.F_GROUND_HEIGHT); - BlockInit.setAs("GOLD_PLATE", Material.STONE_PLATE); + BlockInit.setAs(BridgeMaterial.LIGHT_WEIGHTED_PRESSURE_PLATE, + BridgeMaterial.STONE_PRESSURE_PLATE); // 148 Weighted Pressure Plate (Heavy) // BlockFlags.addFlags(148, BlockProperties.F_IGN_PASSABLE | BlockProperties.F_GROUND | BlockProperties.F_GROUND_HEIGHT); - BlockInit.setAs("IRON_PLATE", Material.STONE_PLATE); + BlockInit.setAs(BridgeMaterial.HEAVY_WEIGHTED_PRESSURE_PLATE, + BridgeMaterial.STONE_PRESSURE_PLATE); - // 149 Redstone Comparator (inactive) - // BlockFlags.addFlags(149, BlockProperties.F_IGN_PASSABLE | BlockProperties.F_GROUND | BlockProperties.F_GROUND_HEIGHT); - BlockInit.setAs("REDSTONE_COMPARATOR_OFF", Material.DIODE_BLOCK_OFF); + // HACK 1.13 + Material comparator = BridgeMaterial.get("comparator"); + if (comparator == null) { + // LEGACY - // 150 Redstone Comparator (active) - // BlockFlags.addFlags(150, BlockProperties.F_IGN_PASSABLE | BlockProperties.F_GROUND | BlockProperties.F_GROUND_HEIGHT); - BlockInit.setAs("REDSTONE_COMPARATOR_ON", Material.DIODE_BLOCK_ON); + // 149 Redstone Comparator (inactive) + // BlockFlags.addFlags(149, BlockProperties.F_IGN_PASSABLE | BlockProperties.F_GROUND | BlockProperties.F_GROUND_HEIGHT); + BlockInit.setAs("REDSTONE_COMPARATOR_OFF", Material.DIODE_BLOCK_OFF); + + // 150 Redstone Comparator (active) + // BlockFlags.addFlags(150, BlockProperties.F_IGN_PASSABLE | BlockProperties.F_GROUND | BlockProperties.F_GROUND_HEIGHT); + BlockInit.setAs("REDSTONE_COMPARATOR_ON", Material.DIODE_BLOCK_ON); + } + else { + // 1.13 + + BlockInit.setAs("COMPARATOR", BridgeMaterial.REPEATER); + } // 151 Daylight Sensor // BlockFlags.addFlags(151, BlockProperties.F_IGN_PASSABLE | BlockProperties.F_GROUND | BlockProperties.F_GROUND_HEIGHT); - BlockInit.setAs("DAYLIGHT_DETECTOR", Material.HUGE_MUSHROOM_1); + BlockInit.setAs("DAYLIGHT_DETECTOR", Material.VINE); // 152 Block of Redstone - BlockInit.setAs("REDSTONE_BLOCK", Material.ENCHANTMENT_TABLE); + BlockInit.setAs("REDSTONE_BLOCK", BridgeMaterial.ENCHANTING_TABLE); // 153 Nether Quartz Ore - BlockInit.setAs("QUARTZ_ORE", Material.COAL_ORE); + BlockInit.setAs(BridgeMaterial.NETHER_QUARTZ_ORE, Material.COAL_ORE); // 154 Hopper BlockInit.setAs("HOPPER", Material.COAL_ORE); diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_6_1.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_6_1.java index b03c9eee..45cbfc44 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_6_1.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_6_1.java @@ -21,10 +21,8 @@ import fr.neatmonster.nocheatplus.compat.blocks.init.BlockInit; import fr.neatmonster.nocheatplus.config.WorldConfigProvider; import fr.neatmonster.nocheatplus.logging.StaticLog; import fr.neatmonster.nocheatplus.utilities.map.BlockFlags; -import fr.neatmonster.nocheatplus.utilities.map.BlockProperties; -import fr.neatmonster.nocheatplus.utilities.map.BlockProperties.BlockProps; -@SuppressWarnings("deprecation") + public class BlocksMC1_6_1 implements BlockPropertiesSetup{ public BlocksMC1_6_1(){ @@ -37,20 +35,13 @@ public class BlocksMC1_6_1 implements BlockPropertiesSetup{ // Block of Coal: like block of redstone. BlockInit.setAs("COAL_BLOCK", "REDSTONE_BLOCK"); - // Hardened Clay - BlockProperties.setBlockProps("HARD_CLAY", new BlockProps(BlockProperties.woodPickaxe, 1.25f, BlockProperties.secToMs(6.25, 0.95, 0.5, 0.35, 0.25, 0.2))); - BlockFlags.setFlagsAs("HARD_CLAY", Material.STONE); // TODO: Assumption (!). - - // Stained Clay: Set as hardened clay. - BlockInit.setAs("STAINED_CLAY", "HARD_CLAY"); + // (hard_clay and stained clay via generic setup.) // Hay Bale BlockInit.setPropsAs("HAY_BLOCK", Material.STONE_BUTTON); BlockFlags.setFlagsAs("HAY_BLOCK", Material.STONE); // TODO: Assumption (!). - // Carpet - BlockProperties.setBlockProps("CARPET", new BlockProps(BlockProperties.noTool, 0.1f, BlockProperties.secToMs(0.15))); - BlockProperties.setBlockFlags("CARPET", BlockProperties.F_GROUND|BlockProperties.F_IGN_PASSABLE|BlockProperties.F_GROUND_HEIGHT|BlockProperties.F_CARPET); + // (Carpet via generic setup.) StaticLog.logInfo("Added block-info for Minecraft 1.6.1 blocks."); } diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_7_2.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_7_2.java index d7b21c08..0321f9c5 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_7_2.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_7_2.java @@ -16,6 +16,7 @@ package fr.neatmonster.nocheatplus.compat.blocks.init.vanilla; import org.bukkit.Material; +import fr.neatmonster.nocheatplus.compat.BridgeMaterial; import fr.neatmonster.nocheatplus.compat.blocks.BlockPropertiesSetup; import fr.neatmonster.nocheatplus.compat.blocks.init.BlockInit; import fr.neatmonster.nocheatplus.config.WorldConfigProvider; @@ -28,7 +29,7 @@ import fr.neatmonster.nocheatplus.utilities.map.BlockProperties.BlockProps; public class BlocksMC1_7_2 implements BlockPropertiesSetup{ public BlocksMC1_7_2() { - BlockInit.assertMaterialExists("STAINED_GLASS"); + BlockInit.assertMaterialExists("DARK_OAK_STAIRS"); BlockInit.assertMaterialExists("PACKED_ICE"); } @@ -37,21 +38,21 @@ public class BlocksMC1_7_2 implements BlockPropertiesSetup{ // Block shapes. // Stained glass - BlockInit.setAs("STAINED_GLASS", Material.GLASS); + BlockInit.setAsIfExists("STAINED_GLASS", Material.GLASS); // Stained glass pane - BlockInit.setAs("STAINED_GLASS_PANE", "THIN_GLASS"); + // Collected otherwise: BlockInit.setAsIfExists("STAINED_GLASS_PANE", "THIN_GLASS"); // Leaves 2 - BlockInit.setAs("LEAVES_2", Material.LEAVES); + BlockInit.setAsIfExists("LEAVES_2", "LEAVES"); // Log 2 - BlockInit.setAs("LOG_2", Material.LOG); + BlockInit.setAsIfExists("LOG_2", "LOG"); // Acacia wood stairs - BlockInit.setAs("ACACIA_STAIRS", Material.WOOD_STAIRS); - // Oak wood stairs - BlockInit.setAs("DARK_OAK_STAIRS", Material.WOOD_STAIRS); + // BlockInit.setAsIfExists("ACACIA_STAIRS", "WOOD_STAIRS"); + // // Oak wood stairs + // BlockInit.setAsIfExists("DARK_OAK_STAIRS", "WOOD_STAIRS"); // Packed ice - BlockInit.setAs("PACKED_ICE", Material.ICE); + BlockInit.setAsIfExists("PACKED_ICE", Material.ICE); // Large flowers - BlockInit.setAs("DOUBLE_PLANT", Material.YELLOW_FLOWER); + BlockInit.setAsIfExists("DOUBLE_PLANT", BridgeMaterial.DANDELION); // Block breaking. final long[] ironTimes = BlockProperties.secToMs(15, 7.5, 1.15, 0.75, 0.56, 1.25); @@ -64,10 +65,12 @@ public class BlocksMC1_7_2 implements BlockPropertiesSetup{ final long[] diamondTimes = BlockProperties.secToMs(15, 7.5, 3.75, 0.75, 0.56, 1.25); final BlockProps diamondType = new BlockProps(BlockProperties.woodPickaxe, 3, diamondTimes); for (Material mat : new Material[]{ - Material.REDSTONE_ORE, Material.GLOWING_REDSTONE_ORE, + Material.REDSTONE_ORE, BridgeMaterial.get("glowing_redstone_ore"), Material.EMERALD_ORE, Material.GOLD_ORE, Material.DIAMOND_ORE, }) { - BlockProperties.setBlockProps(mat, diamondType); + if (mat != null) { + BlockProperties.setBlockProps(mat, diamondType); + } } StaticLog.logInfo("Added block-info for Minecraft 1.7.2 blocks."); diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_8.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_8.java index 610d59ca..cc59f55a 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_8.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_8.java @@ -16,6 +16,7 @@ package fr.neatmonster.nocheatplus.compat.blocks.init.vanilla; import org.bukkit.Material; +import fr.neatmonster.nocheatplus.compat.BridgeMaterial; import fr.neatmonster.nocheatplus.compat.blocks.BlockPropertiesSetup; import fr.neatmonster.nocheatplus.compat.blocks.init.BlockInit; import fr.neatmonster.nocheatplus.config.WorldConfigProvider; @@ -28,35 +29,35 @@ import fr.neatmonster.nocheatplus.utilities.map.BlockProperties.BlockProps; public class BlocksMC1_8 implements BlockPropertiesSetup { public BlocksMC1_8() { - BlockInit.assertMaterialExists("BARRIER"); + //BlockInit.assertMaterialExists("BARRIER"); BlockInit.assertMaterialExists("SLIME_BLOCK"); BlockInit.assertMaterialExists("ACACIA_FENCE_GATE"); - BlockInit.assertMaterialExists("STANDING_BANNER"); + //BlockInit.assertMaterialExists("STANDING_BANNER"); BlockInit.assertMaterialExists("SEA_LANTERN"); } @Override public void setupBlockProperties(WorldConfigProvider worldConfigProvider) { - + // ---- Changed block break timings ---- // Melon/pumpkin/like. BlockProps props = new BlockProps(BlockProperties.woodAxe, 1f, BlockProperties.secToMs(1.45, 0.70, 0.325, 0.2, 0.13, 0.075), 3f); for (Material mat : new Material[] { - Material.MELON_BLOCK, + BridgeMaterial.MELON, Material.PUMPKIN, Material.JACK_O_LANTERN, // Same core breaking times, but behave different on efficiency + other tool (?): Material.WALL_SIGN, - Material.SIGN_POST, + BridgeMaterial.SIGN, }) { BlockProperties.setBlockProps(mat, props); } - + // Ladder. props = new BlockProps(BlockProperties.woodAxe, 0.4f, BlockProperties.secToMs(0.6, 0.3, 0.15, 0.1, 0.075, 0.05)); BlockProperties.setBlockProps(Material.LADDER, props); - + // ---- New blocks ---- // 165(SLIME_BLOCK @@ -68,25 +69,21 @@ public class BlocksMC1_8 implements BlockPropertiesSetup { BlockInit.setAs("BARRIER", Material.BEDROCK); // Full block, unbreakable. // 167(IRON_TRAP_DOOR - BlockFlags.setFlagsAs("IRON_TRAPDOOR", Material.TRAP_DOOR); - BlockInit.setPropsAs("IRON_TRAPDOOR", Material.IRON_DOOR_BLOCK); + BlockFlags.setFlagsAs("IRON_TRAPDOOR", BridgeMaterial.OAK_TRAPDOOR); + BlockInit.setPropsAs("IRON_TRAPDOOR", BridgeMaterial.IRON_DOOR); // 168(PRISMARINE BlockInit.setAs("PRISMARINE", Material.STONE); // 169(SEA_LANTERN - BlockInit.setAs("SEA_LANTERN", Material.REDSTONE_LAMP_OFF); + BlockInit.setAs("SEA_LANTERN", + BridgeMaterial.getFirstNotNull("redstone_lamp", "redstone_lamp_off")); // 176(STANDING_BANNER - BlockProperties.setBlockFlags("STANDING_BANNER", 0L); - props = new BlockProps(BlockProperties.woodAxe, 0.4f, BlockProperties.secToMs(1.5, 0.75, 0.4, 0.25, 0.2, 0.15)); - BlockProperties.setBlockProps("STANDING_BANNER", props); - // 177(WALL_BANNER - BlockInit.setInstantAir("WALL_BANNER"); // 178(DAYLIGHT_DETECTOR_INVERTED - BlockInit.setAs("DAYLIGHT_DETECTOR_INVERTED", Material.DAYLIGHT_DETECTOR); + BlockInit.setAsIfExists("DAYLIGHT_DETECTOR_INVERTED", Material.DAYLIGHT_DETECTOR); // 179(RED_SANDSTONE BlockInit.setAs("RED_SANDSTONE", Material.SANDSTONE); @@ -95,55 +92,55 @@ public class BlocksMC1_8 implements BlockPropertiesSetup { BlockInit.setAs("RED_SANDSTONE_STAIRS", Material.SANDSTONE_STAIRS); // 181(DOUBLE_STEP_2 - BlockInit.setAs("DOUBLE_STONE_SLAB2", Material.DOUBLE_STEP); // TODO: red sandstone / prismarine ? + BlockInit.setAsIfExists("DOUBLE_STONE_SLAB2", BridgeMaterial.get("double_step")); // TODO: red sandstone / prismarine ? // 182(STEP_2 - BlockInit.setAs("STONE_SLAB2", Material.STEP); // TODO: red sandstone / prismarine ? + BlockInit.setAsIfExists("STONE_SLAB2", BridgeMaterial.STONE_SLAB); // TODO: red sandstone / prismarine ? - // 183(SPRUCE_FENCE_GATE - BlockInit.setAs("SPRUCE_FENCE_GATE", Material.FENCE_GATE); - - // 184(BIRCH_FENCE_GATE - BlockInit.setAs("BIRCH_FENCE_GATE", Material.FENCE_GATE); - - // 185(JUNGLE_FENCE_GATE - BlockInit.setAs("JUNGLE_FENCE_GATE", Material.FENCE_GATE); - - // 186(DARK_OAK_FENCE_GATE - BlockInit.setAs("DARK_OAK_FENCE_GATE", Material.FENCE_GATE); - - // 187(ACACIA_FENCE_GATE - BlockInit.setAs("ACACIA_FENCE_GATE", Material.FENCE_GATE); - - // 188(SPRUCE_FENCE - BlockInit.setAs("SPRUCE_FENCE", Material.FENCE); - - // 189(BIRCH_FENCE - BlockInit.setAs("BIRCH_FENCE", Material.FENCE); - - // 190(JUNGLE_FENCE - BlockInit.setAs("JUNGLE_FENCE", Material.FENCE); - - // 191(DARK_OAK_FENCE - BlockInit.setAs("DARK_OAK_FENCE", Material.FENCE); - - // 192(ACACIA_FENCE - BlockInit.setAs("ACACIA_FENCE", Material.FENCE); - - // 193(SPRUCE_DOOR - BlockInit.setAs("SPRUCE_DOOR", Material.WOODEN_DOOR); - - // 194(BIRCH_DOOR - BlockInit.setAs("BIRCH_DOOR", Material.WOODEN_DOOR); - - // 195(JUNGLE_DOOR - BlockInit.setAs("JUNGLE_DOOR", Material.WOODEN_DOOR); - - // 196(ACACIA_DOOR - BlockInit.setAs("ACACIA_DOOR", Material.WOODEN_DOOR); - - // 197(DARK_OAK_DOOR - BlockInit.setAs("DARK_OAK_DOOR", Material.WOODEN_DOOR); + // // 183(SPRUCE_FENCE_GATE + // BlockInit.setAs("SPRUCE_FENCE_GATE", Material.FENCE_GATE); + // + // // 184(BIRCH_FENCE_GATE + // BlockInit.setAs("BIRCH_FENCE_GATE", Material.FENCE_GATE); + // + // // 185(JUNGLE_FENCE_GATE + // BlockInit.setAs("JUNGLE_FENCE_GATE", Material.FENCE_GATE); + // + // // 186(DARK_OAK_FENCE_GATE + // BlockInit.setAs("DARK_OAK_FENCE_GATE", Material.FENCE_GATE); + // + // // 187(ACACIA_FENCE_GATE + // BlockInit.setAs("ACACIA_FENCE_GATE", Material.FENCE_GATE); + // + // // 188(SPRUCE_FENCE + // BlockInit.setAs("SPRUCE_FENCE", Material.FENCE); + // + // // 189(BIRCH_FENCE + // BlockInit.setAs("BIRCH_FENCE", Material.FENCE); + // + // // 190(JUNGLE_FENCE + // BlockInit.setAs("JUNGLE_FENCE", Material.FENCE); + // + // // 191(DARK_OAK_FENCE + // BlockInit.setAs("DARK_OAK_FENCE", Material.FENCE); + // + // // 192(ACACIA_FENCE + // BlockInit.setAs("ACACIA_FENCE", Material.FENCE); + // + // // 193(SPRUCE_DOOR + // BlockInit.setAs("SPRUCE_DOOR", Material.WOODEN_DOOR); + // + // // 194(BIRCH_DOOR + // BlockInit.setAs("BIRCH_DOOR", Material.WOODEN_DOOR); + // + // // 195(JUNGLE_DOOR + // BlockInit.setAs("JUNGLE_DOOR", Material.WOODEN_DOOR); + // + // // 196(ACACIA_DOOR + // BlockInit.setAs("ACACIA_DOOR", Material.WOODEN_DOOR); + // + // // 197(DARK_OAK_DOOR + // BlockInit.setAs("DARK_OAK_DOOR", Material.WOODEN_DOOR); StaticLog.logInfo("Added block-info for Minecraft 1.8 blocks."); } diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_9.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_9.java index 2507d82e..4ff1cd92 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_9.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/BlocksMC1_9.java @@ -16,6 +16,7 @@ package fr.neatmonster.nocheatplus.compat.blocks.init.vanilla; import org.bukkit.Material; +import fr.neatmonster.nocheatplus.compat.BridgeMaterial; import fr.neatmonster.nocheatplus.compat.blocks.BlockPropertiesSetup; import fr.neatmonster.nocheatplus.compat.blocks.init.BlockInit; import fr.neatmonster.nocheatplus.config.WorldConfigProvider; @@ -52,39 +53,43 @@ public class BlocksMC1_9 implements BlockPropertiesSetup { BlockProperties.setBlockProps("CHORUS_FLOWER", instant); // 201(PURPUR_BLOCK / SOLID+GROUND) - BlockInit.setAs("PURPUR_BLOCK", Material.SMOOTH_BRICK); + BlockInit.setAs("PURPUR_BLOCK", BridgeMaterial.STONE_BRICKS); // 202(PURPUR_PILLAR / SOLID+GROUND) - BlockInit.setAs("PURPUR_PILLAR", Material.SMOOTH_BRICK); // Rough. + BlockInit.setAs("PURPUR_PILLAR", BridgeMaterial.STONE_BRICKS); // Rough. // 203(PURPUR_STAIRS / SOLID+GROUND) - BlockInit.setAs("PURPUR_STAIRS", Material.SMOOTH_STAIRS); // Rough. + BlockInit.setAs("PURPUR_STAIRS", BridgeMaterial.STONE_BRICK_STAIRS); // Rough. // 204(PURPUR_DOUBLE_SLAB / SOLID+GROUND) - BlockInit.setAs("PURPUR_DOUBLE_SLAB", Material.DOUBLE_STEP); + if (BridgeMaterial.has("PURPUR_DOUBLE_SLAB")) { + if (BridgeMaterial.has("PURPUR_DOUBLE_SLAB")) { + BlockInit.setAs("PURPUR_DOUBLE_SLAB", Material.DOUBLE_STEP); + } + } // 205(PURPUR_SLAB / SOLID+GROUND) - BlockInit.setAs("PURPUR_SLAB", Material.STEP); + BlockInit.setAs("PURPUR_SLAB", BridgeMaterial.STONE_SLAB); // 206(END_BRICKS / SOLID+GROUND) - BlockInit.setAs("END_BRICKS", Material.SANDSTONE); + BlockInit.setAs(BridgeMaterial.END_STONE_BRICKS, Material.SANDSTONE); // 207(BEETROOT_BLOCK) - BlockFlags.addFlags("BEETROOT_BLOCK", ground); - BlockProperties.setBlockProps("BEETROOT_BLOCK", instant); + BlockFlags.addFlags(BridgeMaterial.BEETROOTS, ground); + BlockProperties.setBlockProps(BridgeMaterial.BEETROOTS, instant); // 208(GRASS_PATH / SOLID+GROUND) - BlockInit.setAs("GRASS_PATH", Material.GRASS); + BlockInit.setAs("GRASS_PATH", BridgeMaterial.GRASS_BLOCK); // Later it'll be lower! // 209(END_GATEWAY) // -> Leave flags as is (like air). BlockProperties.setBlockProps("END_GATEWAY", BlockProperties.indestructibleType); // 210(COMMAND_REPEATING / SOLID+GROUND) - BlockInit.setAs("COMMAND_REPEATING", "COMMAND"); // Like command block. + BlockInit.setAs(BridgeMaterial.REPEATING_COMMAND_BLOCK, BridgeMaterial.COMMAND_BLOCK); // 211(COMMAND_CHAIN / SOLID+GROUND) - BlockInit.setAs("COMMAND_CHAIN", "COMMAND"); // Like command block. + BlockInit.setAs(BridgeMaterial.CHAIN_COMMAND_BLOCK, BridgeMaterial.COMMAND_BLOCK); // 212(FROSTED_ICE / SOLID+GROUND) BlockInit.setAs("FROSTED_ICE", Material.ICE); diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/VanillaBlocksFactory.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/VanillaBlocksFactory.java index 58a861ce..a9d8152b 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/VanillaBlocksFactory.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/VanillaBlocksFactory.java @@ -39,6 +39,7 @@ public class VanillaBlocksFactory { setups.add(new BlocksMC1_10()); setups.add(new BlocksMC1_11()); setups.add(new BlocksMC1_12()); + setups.add(new BlocksMC1_13()); } catch(Throwable t){} for (final BlockPropertiesSetup setup : setups){ diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/special/MultiClientProtocolBlockShapePatch.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/special/MultiClientProtocolBlockShapePatch.java index 11e8a69d..405b4e9f 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/special/MultiClientProtocolBlockShapePatch.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/compat/blocks/init/vanilla/special/MultiClientProtocolBlockShapePatch.java @@ -19,6 +19,7 @@ import java.util.List; import org.bukkit.Material; +import fr.neatmonster.nocheatplus.compat.BridgeMaterial; import fr.neatmonster.nocheatplus.compat.activation.ActivationUtil; import fr.neatmonster.nocheatplus.compat.blocks.AbstractBlockPropertiesPatch; import fr.neatmonster.nocheatplus.config.WorldConfigProvider; @@ -28,7 +29,7 @@ import fr.neatmonster.nocheatplus.utilities.map.BlockFlags; import fr.neatmonster.nocheatplus.utilities.map.BlockProperties; /** - * WATER_LILY for multi client protocol support between 1.7.x - 1.11.x. + * Multi client protocol support between 1.7.x - 1.13.x. * * @author asofold * @@ -38,7 +39,7 @@ public class MultiClientProtocolBlockShapePatch extends AbstractBlockPropertiesP public MultiClientProtocolBlockShapePatch() { activation - .neutralDescription("Block shape patch for multi client protocol support around 1.7.x - 1.12.x.") + .neutralDescription("Block shape patch for multi client protocol support around 1.7.x - 1.13.x.") .advertise(true) .setConditionsAND() .notUnitTest() @@ -52,24 +53,24 @@ public class MultiClientProtocolBlockShapePatch extends AbstractBlockPropertiesP final List done = new LinkedList(); - BlockFlags.addFlags(Material.WATER_LILY, + BlockFlags.addFlags(BridgeMaterial.LILY_PAD, BlockProperties.F_GROUND | BlockProperties.F_HEIGHT8_1 | BlockProperties.F_GROUND_HEIGHT); - done.add("WATER_LILY"); + done.add("water_lily"); - BlockFlags.addFlags(Material.SOIL, + BlockFlags.addFlags(BridgeMaterial.FARMLAND, BlockProperties.F_MIN_HEIGHT16_15 | BlockProperties.F_HEIGHT100 | BlockProperties.F_GROUND_HEIGHT); - done.add("SOIL"); + done.add("soil"); try { BlockFlags.addFlags(Material.GRASS_PATH, BlockProperties.F_MIN_HEIGHT16_15 | BlockProperties.F_HEIGHT100 | BlockProperties.F_GROUND_HEIGHT); - done.add("GRASS_PATH"); + done.add("grass_path"); } catch (Throwable t) { // TODO: What throws for enum not there. diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/config/DefaultConfig.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/config/DefaultConfig.java index bff4d7aa..270c13e2 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/config/DefaultConfig.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/config/DefaultConfig.java @@ -188,7 +188,7 @@ public class DefaultConfig extends ConfigFile { set(ConfPaths.BLOCKPLACE_REACH_ACTIONS, unifiedBlockReachActions, 785); set(ConfPaths.BLOCKPLACE_NOSWING_CHECK, "default", 785); - set(ConfPaths.BLOCKPLACE_NOSWING_EXCEPTIONS, Arrays.asList(Material.WATER_LILY.toString(), Material.FLINT_AND_STEEL.toString()), 785); + set(ConfPaths.BLOCKPLACE_NOSWING_EXCEPTIONS, Arrays.asList("WATER_LILY", "LILY_PAD", Material.FLINT_AND_STEEL.toString()), 785); set(ConfPaths.BLOCKPLACE_NOSWING_ACTIONS, "cancel vl>10 log:noswing:0:5:if cancel", 785); set(ConfPaths.BLOCKPLACE_SPEED_CHECK, "default", 785); @@ -675,10 +675,12 @@ public class DefaultConfig extends ConfigFile { set(ConfPaths.COMPATIBILITY_BLOCKS + ConfPaths.SUB_ALLOWINSTANTBREAK, new LinkedList(), 785); set(ConfPaths.COMPATIBILITY_BLOCKS + ConfPaths.SUB_OVERRIDEFLAGS + "." + Material.SNOW.name().toLowerCase(), "default", 785); // Make blocks ign_passable+ground_height. - for (final Material mat : Arrays.asList( - Material.PISTON_MOVING_PIECE + for (final String name : Arrays.asList( + // TODO: + "piston_moving_piece", + "moving_piston" )) { - set(ConfPaths.COMPATIBILITY_BLOCKS + ConfPaths.SUB_OVERRIDEFLAGS + "." + mat.name().toLowerCase(), "default+ign_passable+ground_height", 785); + set(ConfPaths.COMPATIBILITY_BLOCKS + ConfPaths.SUB_OVERRIDEFLAGS + "." + name, "default+ign_passable+ground_height", 785); } set(ConfPaths.COMPATIBILITY_BLOCKS_CHANGETRACKER_ACTIVE, true, 1036); // With lastChangedBuildNumber. set(ConfPaths.COMPATIBILITY_BLOCKS_CHANGETRACKER_PISTONS, true, 785); diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/penalties/ActionPenalty.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/penalties/ActionPenalty.java index 0638e1ec..75eaf79e 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/penalties/ActionPenalty.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/penalties/ActionPenalty.java @@ -1,3 +1,17 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ package fr.neatmonster.nocheatplus.penalties; import fr.neatmonster.nocheatplus.actions.Action; diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/InventoryUtil.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/InventoryUtil.java index 504f9414..a4cf8ccb 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/InventoryUtil.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/InventoryUtil.java @@ -14,10 +14,8 @@ */ package fr.neatmonster.nocheatplus.utilities; -import java.util.HashSet; import java.util.LinkedList; import java.util.List; -import java.util.Set; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -37,14 +35,6 @@ import fr.neatmonster.nocheatplus.utilities.map.BlockProperties; */ public class InventoryUtil { - // TODO: Better location for the boat/item stuff than InventoryUtil. - private static final Set boats = new HashSet(); - - static { - boats.add(Material.BOAT); - boats.addAll(collectItemsByPrefix("BOAT_")); // Oops: prefix. - } - /** * Collect non-block items by suffix of their Material name (case insensitive). * @param suffix @@ -77,10 +67,6 @@ public class InventoryUtil { return res; } - public static boolean isBoat(final Material mat) { - return boats.contains(mat); - } - /** * Does not account for special slots like armor. * diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/BlockCache.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/BlockCache.java index 52a24063..83bd980d 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/BlockCache.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/BlockCache.java @@ -311,7 +311,7 @@ public abstract class BlockCache { } final Material id = (y < 0 || y > maxBlockY) ? Material.AIR : fetchTypeId(x, y, z); // (Later: Static id-node map from config.) - if (id == Material.AIR) { + if (BlockProperties.isAir(id)) { return airNode; } else { 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 9ebf207d..661acedf 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 @@ -51,6 +51,16 @@ public class BlockFlags { BlockProperties.setBlockFlags(id, BlockProperties.getBlockFlags(otherId)); } + /** + * Set the same flags for newMat as are present for mat. + * + * @param newMat + * @param mat + */ + public static void setFlagsAs(Material newMat, Material mat) { + BlockProperties.setBlockFlags(newMat, BlockProperties.getBlockFlags(mat)); + } + /** * Add flags to existent flags. (Uses BlockProperties.) * 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 734e83e4..81c89efd 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 @@ -43,6 +43,7 @@ import fr.neatmonster.nocheatplus.NCPAPIProvider; import fr.neatmonster.nocheatplus.checks.moving.util.MovingUtil; import fr.neatmonster.nocheatplus.compat.AlmostBoolean; import fr.neatmonster.nocheatplus.compat.Bridge1_9; +import fr.neatmonster.nocheatplus.compat.BridgeMaterial; import fr.neatmonster.nocheatplus.compat.MCAccess; import fr.neatmonster.nocheatplus.compat.blocks.BlockPropertiesSetup; import fr.neatmonster.nocheatplus.compat.blocks.init.BlockInit; @@ -611,32 +612,53 @@ public class BlockProperties { /** The Constant instantMat. */ protected static final Material[] instantMat = new Material[]{ // Named in wiki. - Material.CROPS, + BridgeMaterial.WHEAT_CROPS, Material.TRIPWIRE_HOOK, Material.TRIPWIRE, Material.TORCH, Material.TNT, - Material.SUGAR_CANE_BLOCK, - Material.SAPLING, - Material.RED_ROSE, Material.YELLOW_FLOWER, + BridgeMaterial.SUGAR_CANE, + BridgeMaterial.get("red_rose"), BridgeMaterial.DANDELION, + BridgeMaterial.get("blue_orchid"), Material.REDSTONE_WIRE, - Material.REDSTONE_TORCH_ON, Material.REDSTONE_TORCH_OFF, - Material.DIODE_BLOCK_ON, Material.DIODE_BLOCK_OFF, + BridgeMaterial.get("REDSTONE_TORCH_ON"), + BridgeMaterial.get("REDSTONE_TORCH_OFF"), + BridgeMaterial.get("DIODE_BLOCK_ON"), BridgeMaterial.get("DIODE_BLOCK_OFF"), + BridgeMaterial.get("repeater"), Material.PUMPKIN_STEM, - Material.NETHER_WARTS, + BridgeMaterial.getBlock("NETHER_WART"), + BridgeMaterial.getBlock("NETHER_WARTS"), // TODO: Bug or very old? Material.BROWN_MUSHROOM, Material.RED_MUSHROOM, Material.MELON_STEM, - Material.WATER_LILY, - Material.LONG_GRASS, + BridgeMaterial.LILY_PAD, + BridgeMaterial.TALL_GRASS, + BridgeMaterial.GRASS, Material.FIRE, - Material.DEAD_BUSH, // - Material.CROPS, + BridgeMaterial.WHEAT_CROPS, // 1.4 - Material.COMMAND, - Material.FLOWER_POT, - Material.CARROT, - Material.POTATO, + BridgeMaterial.COMMAND_BLOCK, + BridgeMaterial.CARROTS, + BridgeMaterial.POTATOES, + + // 1.13 /... + BridgeMaterial.get("allium"), + BridgeMaterial.get("azure_bluet"), + BridgeMaterial.get("dandelion"), + BridgeMaterial.getBlock("dandelion_yellow"), + BridgeMaterial.get("kelp_plant"), + BridgeMaterial.get("large_fern"), + BridgeMaterial.get("lilac"), + BridgeMaterial.get("oxeye_daisy"), + BridgeMaterial.get("peony"), + BridgeMaterial.get("poppy"), + BridgeMaterial.get("redstone_torch"), + BridgeMaterial.get("redstone_wall_torch"), + BridgeMaterial.getBlock("rose_red"), + BridgeMaterial.get("seagrass"), + BridgeMaterial.get("sea_pickle"), + BridgeMaterial.get("sunflower"), + BridgeMaterial.get("tall_seagrass"), }; /** The rt ray. */ @@ -808,7 +830,7 @@ public class BlockProperties { * Block change tracking: block redstone events can change the shape. */ public static final long F_VARIABLE_REDSTONE = 0x800000000L; - + /** * Indicator to start recoding towards multiple flag types (shape, moving, * interaction, block-type/special, ...). @@ -917,43 +939,55 @@ public class BlockProperties { */ private static void initTools(final IHandle mcAccess, final WorldConfigProvider worldConfigProvider) { tools.clear(); - tools.put(Material.WOOD_SWORD, new ToolProps(ToolType.SWORD, MaterialBase.WOOD)); - tools.put(Material.WOOD_SPADE, new ToolProps(ToolType.SPADE, MaterialBase.WOOD)); - tools.put(Material.WOOD_PICKAXE, new ToolProps(ToolType.PICKAXE, MaterialBase.WOOD)); - tools.put(Material.WOOD_AXE, new ToolProps(ToolType.AXE, MaterialBase.WOOD)); + tools.put(BridgeMaterial.WOODEN_SWORD, new ToolProps(ToolType.SWORD, MaterialBase.WOOD)); + tools.put(BridgeMaterial.WOODEN_SHOVEL, new ToolProps(ToolType.SPADE, MaterialBase.WOOD)); + tools.put(BridgeMaterial.WOODEN_PICKAXE, new ToolProps(ToolType.PICKAXE, MaterialBase.WOOD)); + tools.put(BridgeMaterial.WOODEN_AXE, new ToolProps(ToolType.AXE, MaterialBase.WOOD)); tools.put(Material.STONE_SWORD, new ToolProps(ToolType.SWORD, MaterialBase.STONE)); - tools.put(Material.STONE_SPADE, new ToolProps(ToolType.SPADE, MaterialBase.STONE)); + tools.put(BridgeMaterial.STONE_SHOVEL, new ToolProps(ToolType.SPADE, MaterialBase.STONE)); tools.put(Material.STONE_PICKAXE, new ToolProps(ToolType.PICKAXE, MaterialBase.STONE)); tools.put(Material.STONE_AXE, new ToolProps(ToolType.AXE, MaterialBase.STONE)); tools.put(Material.IRON_SWORD, new ToolProps(ToolType.SWORD, MaterialBase.IRON)); - tools.put(Material.IRON_SPADE, new ToolProps(ToolType.SPADE, MaterialBase.IRON)); + tools.put(BridgeMaterial.IRON_SHOVEL, new ToolProps(ToolType.SPADE, MaterialBase.IRON)); tools.put(Material.IRON_PICKAXE, new ToolProps(ToolType.PICKAXE, MaterialBase.IRON)); tools.put(Material.IRON_AXE, new ToolProps(ToolType.AXE, MaterialBase.IRON)); tools.put(Material.DIAMOND_SWORD, new ToolProps(ToolType.SWORD, MaterialBase.DIAMOND)); - tools.put(Material.DIAMOND_SPADE, new ToolProps(ToolType.SPADE, MaterialBase.DIAMOND)); + tools.put(BridgeMaterial.DIAMOND_SHOVEL, new ToolProps(ToolType.SPADE, MaterialBase.DIAMOND)); tools.put(Material.DIAMOND_PICKAXE, new ToolProps(ToolType.PICKAXE, MaterialBase.DIAMOND)); tools.put(Material.DIAMOND_AXE, new ToolProps(ToolType.AXE, MaterialBase.DIAMOND)); - tools.put(Material.GOLD_SWORD, new ToolProps(ToolType.SWORD, MaterialBase.GOLD)); - tools.put(Material.GOLD_SPADE, new ToolProps(ToolType.SPADE, MaterialBase.GOLD)); - tools.put(Material.GOLD_PICKAXE, new ToolProps(ToolType.PICKAXE, MaterialBase.GOLD)); - tools.put(Material.GOLD_AXE, new ToolProps(ToolType.AXE, MaterialBase.GOLD)); + tools.put(BridgeMaterial.GOLDEN_SWORD, new ToolProps(ToolType.SWORD, MaterialBase.GOLD)); + tools.put(BridgeMaterial.GOLDEN_SHOVEL, new ToolProps(ToolType.SPADE, MaterialBase.GOLD)); + tools.put(BridgeMaterial.GOLDEN_PICKAXE, new ToolProps(ToolType.PICKAXE, MaterialBase.GOLD)); + tools.put(BridgeMaterial.GOLDEN_AXE, new ToolProps(ToolType.AXE, MaterialBase.GOLD)); tools.put(Material.SHEARS, new ToolProps(ToolType.SHEARS, MaterialBase.NONE)); } private static void setFlag(Material material, long addFlag) { + if (!material.isBlock()) { + // Let's not fail hard here. + StaticLog.logWarning("Attempt to set flag for a non-block: " + material); + } blockFlags.put(material, blockFlags.get(material) | addFlag); } private static void maskFlag(Material material, long addFlag) { + if (!material.isBlock()) { + // Let's not fail hard here. + StaticLog.logWarning("Attempt to mask flag for a non-block: " + material); + } blockFlags.put(material, blockFlags.get(material) & addFlag); } private static void setBlock(Material material, BlockProps props) { + if (!material.isBlock()) { + // Let's not fail hard here. + StaticLog.logWarning("Attempt to set block breaking properties for a non-block: " + material); + } blocks.put(material, props); } @@ -985,38 +1019,44 @@ public class BlockProperties { } + BlockProps props; + // Stairs. - for (final Material mat : new Material[] { Material.NETHER_BRICK_STAIRS, Material.COBBLESTONE_STAIRS, - Material.SMOOTH_STAIRS, Material.BRICK_STAIRS, Material.SANDSTONE_STAIRS, Material.WOOD_STAIRS, - Material.SPRUCE_WOOD_STAIRS, Material.BIRCH_WOOD_STAIRS, Material.JUNGLE_WOOD_STAIRS }) { - setFlag(mat, F_STAIRS | F_HEIGHT100 | F_XZ100 | F_GROUND | F_GROUND_HEIGHT); // Set ground too, to be sure. + final long stairFlags = F_STAIRS | F_HEIGHT100 | F_XZ100 | F_GROUND | F_GROUND_HEIGHT; + for (final Material mat : new Material[] { + Material.NETHER_BRICK_STAIRS, Material.COBBLESTONE_STAIRS, + BridgeMaterial.STONE_BRICK_STAIRS, + Material.BRICK_STAIRS, Material.SANDSTONE_STAIRS, + }) { + setFlag(mat, stairFlags); + } + for (final Material mat : MaterialUtil.WOODEN_STAIRS) { + setFlag(mat, stairFlags); } // Step (ground + full width). + final long stepFlags = F_GROUND | F_XZ100; for (final Material mat : new Material[]{ - Material.STEP, Material.WOOD_STEP, + BridgeMaterial.STONE_SLAB, }) { - setFlag(mat, F_GROUND | F_XZ100); + setFlag(mat, stepFlags); + } + for (final Material mat : MaterialUtil.WOODEN_SLABS) { + setFlag(mat, stepFlags); } // Rails - for (final Material mat : new Material[] { - Material.RAILS, Material.DETECTOR_RAIL, Material.POWERED_RAIL, - }) { + for (final Material mat : MaterialUtil.RAILS) { setFlag(mat, F_RAILS); } // WATER. - for (final Material mat : new Material[]{ - Material.STATIONARY_WATER, Material.WATER, - }) { + for (final Material mat : MaterialUtil.WATER) { setFlag(mat, F_LIQUID | F_HEIGHT_8SIM_DEC | F_WATER | F_FALLDIST_ZERO); } // LAVA. - for (final Material mat : new Material[]{ - Material.LAVA, Material.STATIONARY_LAVA, - }) { + for (final Material mat : MaterialUtil.LAVA) { setFlag(mat, F_LIQUID | F_HEIGHT_8SIM_DEC | F_LAVA | F_FALLDIST_HALF); } @@ -1033,29 +1073,32 @@ public class BlockProperties { // Workarounds. // Ground (can stand on). for (final Material mat : new Material[]{ - Material.WATER_LILY, Material.LADDER, - Material.DIODE_BLOCK_OFF, Material.DIODE_BLOCK_ON, + BridgeMaterial.LILY_PAD, Material.LADDER, + BridgeMaterial.get("DIODE_BLOCK_OFF"), + BridgeMaterial.get("DIODE_BLOCK_ON"), Material.COCOA, Material.SNOW, Material.BREWING_STAND, - Material.PISTON_MOVING_PIECE, Material.PISTON_EXTENSION, - Material.STEP, Material.WOOD_STEP, + BridgeMaterial.MOVING_PISTON, BridgeMaterial.PISTON_HEAD, + BridgeMaterial.STONE_SLAB, }) { - setFlag(mat, F_GROUND); + if (mat != null) { + setFlag(mat, F_GROUND); + } } // Full block height. for (final Material mat : new Material[]{ - // Material.ENDER_PORTAL_FRAME, + // BridgeMaterial.END_PORTAL_FRAME, Material.BREWING_STAND, - Material.PISTON_EXTENSION, - Material.SOIL, // Server reports the visible shape 0.9375, client moves on full block height. + BridgeMaterial.PISTON_HEAD, + BridgeMaterial.FARMLAND, // Server reports the visible shape 0.9375, client moves on full block height. }) { setFlag(mat, F_HEIGHT100); } // Full width/xz-bounds. for (final Material mat : new Material[]{ - Material.PISTON_EXTENSION, - Material.ENDER_PORTAL_FRAME + BridgeMaterial.PISTON_HEAD, + BridgeMaterial.END_PORTAL_FRAME }) { setFlag(mat, F_XZ100); } @@ -1065,7 +1108,7 @@ public class BlockProperties { // Not ground (!). for (final Material mat : new Material[]{ - Material.WALL_SIGN, Material.SIGN_POST, + Material.WALL_SIGN, BridgeMaterial.SIGN, }) { // TODO: Might keep solid since it is meant to be related to block shapes rather ("original mc value"). maskFlag(mat, ~(F_GROUND | F_SOLID)); @@ -1074,40 +1117,53 @@ public class BlockProperties { // Ignore for passable. for (final Material mat : new Material[]{ // More strictly needed. - Material.WOOD_PLATE, Material.STONE_PLATE, - Material.WALL_SIGN, Material.SIGN_POST, - Material.DIODE_BLOCK_ON, Material.DIODE_BLOCK_OFF, + BridgeMaterial.STONE_PRESSURE_PLATE, + Material.WALL_SIGN, BridgeMaterial.SIGN, + BridgeMaterial.get("DIODE_BLOCK_ON"), + BridgeMaterial.get("DIODE_BLOCK_OFF"), Material.BREWING_STAND, // Compatibility. Material.LADDER, // Somewhat needed (xz-bounds vary, not critical to pass through). - Material.CAKE_BLOCK, + BridgeMaterial.CAKE, // Workarounds. // Material.COCOA, }) { + if (mat != null) { + setFlag(mat, F_IGN_PASSABLE); + } + } + for (final Material mat : MaterialUtil.WOODEN_PRESSURE_PLATES) { setFlag(mat, F_IGN_PASSABLE); } // ? Extra flag for COCOA, ANVIL: depends on data value (other issue) // Fences, 1.5 block high. + final long flags150 = F_HEIGHT150 | F_VARIABLE | F_THICK_FENCE; for (final Material mat : new Material[]{ - Material.FENCE, Material.FENCE_GATE, - Material.NETHER_FENCE, Material.COBBLE_WALL, + BridgeMaterial.NETHER_BRICK_FENCE, + BridgeMaterial.COBBLESTONE_WALL, }) { - setFlag(mat, F_HEIGHT150 | F_VARIABLE | F_THICK_FENCE); + setFlag(mat, flags150); + } + for (final Material mat : MaterialUtil.WOODEN_FENCES) { + setFlag(mat, flags150); + }for (final Material mat : MaterialUtil.WOODEN_FENCE_GATES) { + setFlag(mat, flags150); } // F_PASSABLE_X4 - for (final Material mat : new Material[] { - Material.FENCE_GATE, - Material.TRAP_DOOR, // TODO: Players can stand on - still passable past 1.9? - }) { - // TODO: PASSABLE_X4 is abused for other checks, need another one? + // TODO: PASSABLE_X4 is abused for other checks, need another one? + for (final Material mat : MaterialUtil.WOODEN_FENCE_GATES) { + setFlag(mat, F_PASSABLE_X4); + } + for (final Material mat : MaterialUtil.WOODEN_TRAP_DOORS) { setFlag(mat, F_PASSABLE_X4); } // F_VARIABLE_REDSTONE, F_VARIABLE_USE + // TODO: Use collections. for (Material material : Material.values()) { if (material.isBlock()) { final String name = material.name().toLowerCase(); @@ -1130,141 +1186,198 @@ public class BlockProperties { } // F_FACING_LOW2_SNEW - for (final Material mat : new Material[]{ - Material.TRAP_DOOR, - }) { + for (final Material mat : MaterialUtil.WOODEN_TRAP_DOORS) { setFlag(mat, F_ATTACHED_LOW2_SNEW); } // Thin fences (iron fence, glass panes). + final long paneFlags = F_THIN_FENCE | F_VARIABLE; for (final Material mat : new Material[]{ - Material.IRON_FENCE, Material.THIN_GLASS, + BridgeMaterial.IRON_BARS, }) { - setFlag(mat, F_THIN_FENCE | F_VARIABLE); + setFlag(mat, paneFlags); + } + for (final Material mat : MaterialUtil.GLASS_PANES) { + setFlag(mat, paneFlags); } // Flexible ground (height): for (final Material mat : new Material[]{ // Strictly needed (multiple boxes otherwise). - Material.PISTON_EXTENSION, + BridgeMaterial.PISTON_HEAD, Material.BREWING_STAND, - Material.ENDER_PORTAL_FRAME, + BridgeMaterial.END_PORTAL_FRAME, // XZ-bounds issues. - Material.CAKE_BLOCK, + BridgeMaterial.CAKE, // Already worked around with isPassableWorkaround (kept for dev-reference). // Material.ANVIL, // Material.SKULL, Material.FLOWER_POT, // Material.DRAGON_EGG, // Material.COCOA, - // Issues standing on with F_PASSABLE_X4. - Material.TRAP_DOOR, // 1.10.2 +- client uses the reported height. - Material.SOIL, + BridgeMaterial.FARMLAND, }) { setFlag(mat, F_GROUND_HEIGHT); } + // Issues standing on with F_PASSABLE_X4. Note getGroundMinHeight. + for (Material mat : MaterialUtil.WOODEN_TRAP_DOORS) { + setFlag(mat, F_GROUND_HEIGHT); + } // Set block break properties. // Instantly breakable. for (final Material mat : instantMat) { - setBlock(mat, instantType); + if (mat != null) { + setBlock(mat, instantType); + } } - // TODO: Bed is special. + @SuppressWarnings("unchecked") + List> instantSets = Arrays.asList( + MaterialUtil.BUSHES, MaterialUtil.TULIPS, + MaterialUtil.SAPLINGS, MaterialUtil.FLOWER_POTS + ); + for (final Set set : instantSets) { + for (final Material mat : set) { + setBlock(mat, instantType); + } + } + // Leaf type - for (Material mat : new Material[]{ - Material.LEAVES, Material.BED_BLOCK}) { + for (final Material mat : MaterialUtil.LEAVES) { + setBlock(mat, leafType); + setFlag(mat, F_LEAVES); + } + for (Material mat : MaterialUtil.BEDS) { // TODO: Beds are special. setBlock(mat, leafType); } - setFlag(Material.LEAVES, F_LEAVES); + // Cobweb - setFlag(Material.WEB, F_COBWEB); + setFlag(BridgeMaterial.COBWEB, F_COBWEB); // Huge mushroom type (...) for (Material mat : new Material[]{ - Material.HUGE_MUSHROOM_1, Material.HUGE_MUSHROOM_2, Material.VINE, Material.COCOA}) { setBlock(mat, hugeMushroomType); } + for (Material mat : MaterialUtil.MUSHROOM_BLOCKS) { + setBlock(mat, hugeMushroomType); + } - setBlock(Material.SNOW, new BlockProps(getToolProps(Material.WOOD_SPADE), 0.1f, secToMs(0.5, 0.1, 0.05, 0.05, 0.05, 0.05))); - setBlock(Material.SNOW_BLOCK, new BlockProps(getToolProps(Material.WOOD_SPADE), 0.1f, secToMs(1, 0.15, 0.1, 0.05, 0.05, 0.05))); + setBlock(Material.SNOW, new BlockProps(getToolProps(BridgeMaterial.WOODEN_SHOVEL), 0.1f, secToMs(0.5, 0.1, 0.05, 0.05, 0.05, 0.05))); + setBlock(Material.SNOW_BLOCK, new BlockProps(getToolProps(BridgeMaterial.WOODEN_SHOVEL), 0.1f, secToMs(1, 0.15, 0.1, 0.05, 0.05, 0.05))); for (Material mat : new Material[]{ - Material.REDSTONE_LAMP_ON, Material.REDSTONE_LAMP_OFF, - Material.GLOWSTONE, Material.GLASS, + BridgeMaterial.get("REDSTONE_LAMP_ON"), + BridgeMaterial.get("REDSTONE_LAMP_OFF"), + BridgeMaterial.get("REDSTONE_LAMP"), + Material.GLOWSTONE, }) { + if (mat != null) { + setBlock(mat, glassType); + } + } + for (final Material mat : MaterialUtil.GLASS_BLOCKS) { + setBlock(mat, glassType); + } + for (final Material mat : MaterialUtil.GLASS_PANES) { setBlock(mat, glassType); } - setBlock(Material.THIN_GLASS, glassType); setBlock(Material.NETHERRACK, new BlockProps(woodPickaxe, 0.4f, secToMs(2, 0.3, 0.15, 0.1, 0.1, 0.05))); setBlock(Material.LADDER, new BlockProps(noTool, 0.4f, secToMs(0.6), 2.5f)); setBlock(Material.CACTUS, new BlockProps(noTool, 0.4f, secToMs(0.6))); - setBlock(Material.WOOD_PLATE, new BlockProps(woodAxe, 0.5f, secToMs(0.75, 0.4, 0.2, 0.15, 0.1, 0.1))); - setBlock(Material.STONE_PLATE, new BlockProps(woodPickaxe, 0.5f, secToMs(2.5, 0.4, 0.2, 0.15, 0.1, 0.07))); + for (Material mat : MaterialUtil.WOODEN_PRESSURE_PLATES) { + setBlock(mat, new BlockProps(woodAxe, 0.5f, secToMs(0.75, 0.4, 0.2, 0.15, 0.1, 0.1))); + } + setBlock(BridgeMaterial.STONE_PRESSURE_PLATE, new BlockProps(woodPickaxe, 0.5f, secToMs(2.5, 0.4, 0.2, 0.15, 0.1, 0.07))); setBlock(Material.SAND, sandType); setBlock(Material.SOUL_SAND, sandType); - for (Material mat: new Material[]{Material.LEVER, Material.PISTON_BASE, - Material.PISTON_EXTENSION, Material.PISTON_STICKY_BASE, - Material.STONE_BUTTON, Material.PISTON_MOVING_PIECE}) { + for (Material mat: new Material[]{Material.LEVER, BridgeMaterial.PISTON, + BridgeMaterial.PISTON_HEAD, BridgeMaterial.STICKY_PISTON, + Material.STONE_BUTTON, BridgeMaterial.MOVING_PISTON}) { setBlock(mat, leverType); } // setBlock(Material.ICE, new BlockProps(woodPickaxe, 0.5f, secToMs(2.5, 0.4, 0.2, 0.15, 0.1, 0.1))); setBlock(Material.ICE, new BlockProps(woodPickaxe, 0.5f, secToMs(0.7, 0.35, 0.18, 0.12, 0.09, 0.06 ))); setBlock(Material.DIRT, sandType); - setBlock(Material.CAKE_BLOCK, leverType); + setBlock(BridgeMaterial.CAKE, leverType); setBlock(Material.BREWING_STAND, new BlockProps(woodPickaxe, 0.5f, secToMs(2.5, 0.4, 0.2, 0.15, 0.1, 0.1))); setBlock(Material.SPONGE, new BlockProps(noTool, 0.6f, secToMs(0.9))); for (Material mat : new Material[]{ - Material.MYCEL, Material.GRAVEL, Material.GRASS, Material.SOIL, + BridgeMaterial.MYCELIUM, BridgeMaterial.FARMLAND, + Material.GRAVEL, BridgeMaterial.GRASS_BLOCK, Material.CLAY, }) { setBlock(mat, gravelType); } - for (Material mat : new Material[]{ - Material.RAILS, Material.POWERED_RAIL, Material.DETECTOR_RAIL, - }) { + for (Material mat : MaterialUtil.RAILS) { setBlock(mat, new BlockProps(woodPickaxe, 0.7f, railsTimes)); } - setBlock(Material.MONSTER_EGGS, new BlockProps(noTool, 0.75f, secToMs(1.15))); - setBlock(Material.WOOL, new BlockProps(noTool, 0.8f, secToMs(1.2), 3f)); + for (Material mat : MaterialUtil.INFESTED_BLOCKS) { + setBlock(mat, new BlockProps(noTool, 0.75f, secToMs(1.15))); + } + for (Material mat : MaterialUtil.WOOD_BLOCKS) { + setBlock(mat, new BlockProps(noTool, 0.8f, secToMs(1.2), 3f)); + } setBlock(Material.SANDSTONE, sandStoneType); setBlock(Material.SANDSTONE_STAIRS, sandStoneType); for (Material mat : new Material[]{ - Material.STONE, Material.SMOOTH_BRICK, Material.SMOOTH_STAIRS, + Material.STONE, BridgeMaterial.STONE_BRICKS, + BridgeMaterial.STONE_BRICK_STAIRS, }) { setBlock(mat, stoneType); } setBlock(Material.NOTE_BLOCK, new BlockProps(woodAxe, 0.8f, secToMs(1.2, 0.6, 0.3, 0.2, 0.15, 0.1))); final BlockProps pumpkinType = new BlockProps(woodAxe, 1, secToMs(1.5, 0.75, 0.4, 0.25, 0.2, 0.15)); setBlock(Material.WALL_SIGN, pumpkinType); - setBlock(Material.SIGN_POST, pumpkinType); + setBlock(BridgeMaterial.SIGN, pumpkinType); setBlock(Material.PUMPKIN, pumpkinType); setBlock(Material.JACK_O_LANTERN, pumpkinType); - setBlock(Material.MELON_BLOCK, new BlockProps(noTool, 1, secToMs(1.45), 3)); + setBlock(BridgeMaterial.MELON, new BlockProps(noTool, 1, secToMs(1.45), 3)); setBlock(Material.BOOKSHELF, new BlockProps(woodAxe, 1.5f, secToMs(2.25, 1.15, 0.6, 0.4, 0.3, 0.2))); for (Material mat : new Material[]{ - Material.WOOD_STAIRS, Material.WOOD, Material.WOOD_STEP, Material.LOG, - Material.FENCE, Material.FENCE_GATE, Material.JUKEBOX, - Material.JUNGLE_WOOD_STAIRS, Material.SPRUCE_WOOD_STAIRS, - Material.BIRCH_WOOD_STAIRS, - Material.WOOD_DOUBLE_STEP, // ? + Material.JUKEBOX, + BridgeMaterial.get("wood_double_step"), // double slabs ? }) { - setBlock(mat, woodType); + if (mat != null) { + setBlock(mat, woodType); + } } - for (Material mat : new Material[]{ + @SuppressWarnings("unchecked") + final List> woodTypes = Arrays.asList( + MaterialUtil.WOODEN_FENCE_GATES, MaterialUtil.WOODEN_FENCES, + MaterialUtil.WOODEN_STAIRS, MaterialUtil.WOODEN_SLABS, + MaterialUtil.LOGS, MaterialUtil.WOOD_BLOCKS, + MaterialUtil.PLANKS + ); + for (final Set set : woodTypes) { + for (final Material mat : set) { + setBlock(mat, woodType); + } + } + for (Material mat : new Material[] { + Material.CAULDRON, Material.COBBLESTONE_STAIRS, Material.COBBLESTONE, - Material.NETHER_BRICK, Material.NETHER_BRICK_STAIRS, Material.NETHER_FENCE, - Material.CAULDRON, Material.BRICK, Material.BRICK_STAIRS, - Material.MOSSY_COBBLESTONE, Material.BRICK, Material.BRICK_STAIRS, - Material.STEP, Material.DOUBLE_STEP, // ? + BridgeMaterial.NETHER_BRICKS, Material.NETHER_BRICK_STAIRS, + BridgeMaterial.NETHER_BRICK_FENCE, + Material.MOSSY_COBBLESTONE, + BridgeMaterial.BRICKS, Material.BRICK_STAIRS, + Material.BRICK_STAIRS, BridgeMaterial.BRICK_SLAB, + BridgeMaterial.STONE_SLAB, + BridgeMaterial.get("double_step"), // ? }) { - setBlock(mat, brickType); + if (mat != null) { + setBlock(mat, brickType); + } } - setBlock(Material.WORKBENCH, chestType); + setBlock(BridgeMaterial.CRAFTING_TABLE, chestType); setBlock(Material.CHEST, chestType); - setBlock(Material.WOODEN_DOOR, woodDoorType); - setBlock(Material.TRAP_DOOR, woodDoorType); + for (Material mat : MaterialUtil.WOODEN_DOORS) { + setBlock(mat, woodDoorType); + } + for (Material mat : MaterialUtil.WOODEN_TRAP_DOORS) { + setBlock(mat, woodDoorType); + } for (Material mat : new Material[]{ - Material.ENDER_STONE, Material.COAL_ORE, + BridgeMaterial.END_STONE, Material.COAL_ORE, }) { setBlock(mat, coalType); @@ -1280,20 +1393,24 @@ public class BlockProperties { final long[] diamondTimes = secToMs(15, 15, 15, 0.75, 0.6, 15); final BlockProps diamondType = new BlockProps(ironPickaxe, 3, diamondTimes); for (Material mat : new Material[]{ - Material.REDSTONE_ORE, Material.GLOWING_REDSTONE_ORE, + Material.REDSTONE_ORE, BridgeMaterial.get("glowing_redstone_ore"), Material.EMERALD_ORE, Material.GOLD_ORE, Material.DIAMOND_ORE, }) { - setBlock(mat, diamondType); + if (mat != null) { + setBlock(mat, diamondType); + } } setBlock(Material.GOLD_BLOCK, goldBlockType); setBlock(Material.FURNACE, dispenserType); - setBlock(Material.BURNING_FURNACE, dispenserType); + if (BridgeMaterial.has("burning_furnace")) { + setBlock(BridgeMaterial.get("burning_furnace"), dispenserType); + } setBlock(Material.DISPENSER, dispenserType); - setBlock(Material.WEB, new BlockProps(woodSword, 4, secToMs(20, 0.4, 0.4, 0.4, 0.4, 0.4))); + setBlock(BridgeMaterial.COBWEB, new BlockProps(woodSword, 4, secToMs(20, 0.4, 0.4, 0.4, 0.4, 0.4))); for (Material mat : new Material[]{ - Material.MOB_SPAWNER, Material.IRON_DOOR_BLOCK, - Material.IRON_FENCE, Material.ENCHANTMENT_TABLE, + BridgeMaterial.SPAWNER, BridgeMaterial.IRON_DOOR, + BridgeMaterial.IRON_BARS, BridgeMaterial.ENCHANTING_TABLE, Material.EMERALD_BLOCK, }) { setBlock(mat, ironDoorType); @@ -1309,30 +1426,130 @@ public class BlockProperties { // More 1.4 (not insta). // TODO: Either move all to an extra setup class, or integrate above. setBlock(Material.BEACON, new BlockProps(noTool, 25f, secToMs(4.45))); // TODO - setBlock(Material.COBBLE_WALL, brickType); - setFlag(Material.COBBLE_WALL, F_HEIGHT150); - setBlock(Material.WOOD_BUTTON, leverType); - setBlock(Material.SKULL, new BlockProps(noTool, 8.5f, secToMs(1.45))); // TODO - setFlag(Material.SKULL, F_GROUND); + setBlock(BridgeMaterial.COBBLESTONE_WALL, brickType); + setFlag(BridgeMaterial.COBBLESTONE_WALL, F_HEIGHT150); + for (Material mat : MaterialUtil.WOODEN_BUTTONS) { + setBlock(mat, leverType); + } + props = new BlockProps(noTool, 8.5f, secToMs(1.45)); + for (Material mat : MaterialUtil.HEADS_GROUND) { + setBlock(mat, props); + setFlag(mat, F_GROUND); + } + for (Material mat : MaterialUtil.HEADS_GROUND) { + setBlock(mat, props); + setFlag(mat, F_GROUND); // TODO: Test ! + } setBlock(Material.ANVIL, new BlockProps(woodPickaxe, 5f)); // TODO setFlag(Material.FLOWER_POT, F_GROUND); // Indestructible. for (Material mat : new Material[]{ - Material.AIR, Material.ENDER_PORTAL, Material.ENDER_PORTAL_FRAME, - Material.PORTAL, Material.LAVA, Material.WATER, Material.BEDROCK, - Material.STATIONARY_LAVA, Material.STATIONARY_WATER, + Material.AIR, BridgeMaterial.END_PORTAL, BridgeMaterial.END_PORTAL_FRAME, + BridgeMaterial.NETHER_PORTAL, Material.BEDROCK, + BridgeMaterial.get("void_air") }) { - setBlock(mat, indestructibleType); + if (mat != null) { + setBlock(mat, indestructibleType); + } + } + @SuppressWarnings("unchecked") + final List> indestructible = new LinkedList>(Arrays.asList( + MaterialUtil.LAVA, + MaterialUtil.WATER + )); + for (Set set : indestructible) { + for (Material mat : set) { + setBlock(mat, indestructibleType); + } } // 95 Locked chest // blocks[95] = indestructibleType; // Locked chest (prevent crash with 1.7). - Material mat = BlockInit.getMaterial("LOCKED_CHEST"); - if (mat != null) { - BlockFlags.setFlagsAs(mat.name(), Material.CHEST); + if (BridgeMaterial.has("locked_chest")) { + BlockFlags.setFlagsAs("locked_chest", Material.CHEST); // Breaks like chest later on. - setBlockProps(mat.name(), BlockProperties.instantType); + setBlockProps("locked_chest", BlockProperties.instantType); } + + // Terracotta (hard_clay). + props = new BlockProps(BlockProperties.woodPickaxe, 1.25f, + BlockProperties.secToMs(6.25, 0.95, 0.5, 0.35, 0.25, 0.2)); + for (final Material mat : MaterialUtil.TERRACOTTA_BLOCKS) { + BlockProperties.setBlockProps(mat, props); + BlockFlags.setFlagsAs(mat, Material.STONE); + } + + // Glazed Terracotta + props = new BlockProps(BlockProperties.woodPickaxe, 1.4f, + BlockProperties.secToMs(7.0, 1.05, 0.55, 0.35, 0.3, 0.2)); + for (final Material mat : MaterialUtil.GLAZED_TERRACOTTA_BLOCKS) { + BlockProperties.setBlockProps(mat, props); + BlockFlags.setFlagsAs(mat, BridgeMaterial.TERRACOTTA); + } + + // Carpets. + final BlockProps carpetProps = new BlockProps(BlockProperties.noTool, 0.1f, + BlockProperties.secToMs(0.15)); + final long carpetFlags = BlockProperties.F_GROUND | BlockProperties.F_IGN_PASSABLE + | BlockProperties.F_GROUND_HEIGHT | BlockProperties.F_CARPET; + for (final Material mat : MaterialUtil.CARPETS) { + BlockProperties.setBlockProps(mat, carpetProps); + setBlockFlags(mat, carpetFlags); + } + + // Banners. + props = new BlockProps(BlockProperties.woodAxe, 0.4f, BlockProperties.secToMs(1.5, 0.75, 0.4, 0.25, 0.2, 0.15)); + for (Material mat : MaterialUtil.BANNERS) { + BlockProperties.setBlockFlags(mat, 0L); + setBlockProps(mat, props); + } + + // Wall banners. + for (Material mat : MaterialUtil.WALL_BANNERS) { + BlockInit.setInstantAir(mat); + } + + // Shulker boxes + for (Material mat : MaterialUtil.SHULKER_BOXES) { + // Wiki (16-11-25): 9, 4.5, 2.25, 1.5, 1.15, 0.75 + BlockProperties.setBlockProps(mat, new BlockProps(BlockProperties.woodPickaxe, 6, + BlockProperties.secToMs(10.0, 1.45, 0.7, 0.5, 0.35, 0.2))); + BlockProperties.setBlockFlags(mat, BlockProperties.F_SOLID | BlockProperties.F_GROUND); + } + + // Concrete + props = new BlockProps(BlockProperties.woodPickaxe, 1.8f, + // TODO: 2.7 with bare hands seems unlikely. + BlockProperties.secToMs(2.7, 1.35, 0.7, 0.45, 0.35, 0.25)); + for (Material mat : MaterialUtil.CONCRETE_BLOCKS) { + setBlockProps(mat, props); + BlockFlags.setFlagsAs(mat, Material.COBBLESTONE); + } + + // Concrete powder + for (Material mat : MaterialUtil.CONCRETE_POWDER_BLOCKS) { + BlockInit.setAs(mat, Material.DIRT); + } + + // Stripped logs. + for (Material mat : MaterialUtil.STRIPPED_LOGS) { + BlockInit.setAs(mat, BridgeMaterial.OAK_LOG); + } + + // Stripped wood blocks. + for (Material mat : MaterialUtil.STRIPPED_WOOD_BLOCKS) { + BlockInit.setAs(mat, BridgeMaterial.OAK_WOOD); + } + + // Wool blocks. + props = new BlockProps(tools.get(Material.SHEARS), 0.8f, + secToMs(1.25, 1.25, 1.25, 1.25, 1.25, 1.25)); + for (Material mat : MaterialUtil.WOOL_BLOCKS) { + BlockFlags.setFlagsAs(mat, Material.STONE); + setBlockProps(mat, props); + // TODO: Model shears directly somehow (per-block list). + } + } /** @@ -1357,6 +1574,16 @@ public class BlockProperties { * the all */ public static void dumpBlocks(boolean all) { + // Dump name-based setup. + //StaticLog.logDebug("All non-legacy Material found: " + StringUtil.join(BridgeMaterial.getKeySet(), ", ")); + //StaticLog.logDebug("Dump Material collections:"); + //MaterialUtil.dumpStaticSets(MaterialUtil.class, Level.FINE); + + // Check for initialized block breaking data. + /* + * TODO: Possibly switch to a class per block, to see what/if-anything + * is initialized, including flags. + */ final LogManager logManager = NCPAPIProvider.getNoCheatPlusAPI().getLogManager(); List missing = new LinkedList(); List allBlocks = new LinkedList(); @@ -1852,11 +2079,11 @@ public class BlockProperties { if (toolProps.toolType == ToolType.SHEARS) { // (Note: shears are not in the block props, anywhere) // Treat these extra (partly experimental): - if (blockId == Material.WEB) { + if (blockId == BridgeMaterial.COBWEB) { duration = 400; isValidTool = true; } - else if (blockId == Material.WOOL) { + else if (MaterialUtil.WOOL_BLOCKS.contains(blockId)) { duration = 240; isValidTool = true; } @@ -1889,7 +2116,8 @@ public class BlockProperties { // Efficiency level. if (efficiency > 0) { // Workarounds ... - if (blockId == Material.WOODEN_DOOR && toolProps.toolType != ToolType.AXE) { + if (toolProps.toolType != ToolType.AXE + && MaterialUtil.WOODEN_DOORS.contains(blockId)) { // Heck [Cleanup pending]... switch (efficiency) { case 1: @@ -1945,7 +2173,7 @@ public class BlockProperties { } // Post/legacy workarounds for efficiency tools ("improper"). if (efficiency > 0 && !isValidTool) { - if (!isValidTool && blockId == Material.MELON_BLOCK) { + if (!isValidTool && blockId == BridgeMaterial.MELON) { // Fall back to pre-1.8 behavior. // 450, 200 , 100 , 50 , 0 duration = Math.min(duration, 450 / (long) Math.pow(2, efficiency - 1)); @@ -1990,10 +2218,10 @@ public class BlockProperties { if (blockId == Material.SNOW) { return toolProps.toolType == ToolType.SPADE; } - if (blockId == Material.WOOL) { + if (MaterialUtil.WOOL_BLOCKS.contains(blockId)) { return true; } - if (blockId == Material.WOODEN_DOOR) { + if (MaterialUtil.WOODEN_DOORS.contains(blockId)) { return true; } if (blockProps.hardness <= 2 @@ -2003,7 +2231,7 @@ public class BlockProperties { && (blockId != Material.NETHERRACK && blockId != Material.SNOW && blockId != Material.SNOW_BLOCK - && blockId != Material.STONE_PLATE)))) { + && blockId != BridgeMaterial.STONE_PRESSURE_PLATE)))) { // Also roughly. return true; } @@ -2058,7 +2286,7 @@ public class BlockProperties { } blockProps.validate(); - blocks.put(blockId, blockProps); + setBlock(blockId, blockProps); } /** @@ -2264,6 +2492,10 @@ public class BlockProperties { * the flags */ public static final void setBlockFlags(final Material blockType, final long flags) { + if (!blockType.isBlock()) { + // Let's not fail hard here. + StaticLog.logWarning("Attempt to set flags for a non-block: " + blockType); + } blockFlags.put(blockType, flags); } @@ -2448,7 +2680,12 @@ public class BlockProperties { * @return true, if is air */ public static final boolean isAir(Material type) { - return type == null || type == Material.AIR; + // TODO: Flags rather? + return type == null || type == Material.AIR + // Assume the compiler throws away further null values. + || type == BridgeMaterial.VOID_AIR + || type == BridgeMaterial.CAVE_AIR + ; } /** @@ -2812,7 +3049,7 @@ public class BlockProperties { return true; } } - else if (id == Material.CAKE_BLOCK) { + else if (id == BridgeMaterial.CAKE) { if (Math.min(fy, fy + dY * dT) >= 0.4375) { return true; // 0.0625 = 0.125 / 2 } @@ -2830,7 +3067,7 @@ public class BlockProperties { } return !collidesCenter(fx, fz, dX, dZ, dT, 0.0625); } - else if (id == Material.PISTON_EXTENSION) { + else if (id == BridgeMaterial.PISTON_HEAD) { if (Math.min(fy, fy + dY * dT) >= 0.625) { return true; } @@ -3019,7 +3256,7 @@ public class BlockProperties { else if (id == Material.SOUL_SAND) { return 0.875; } - // else if (id == Material.CAKE_BLOCK.getId()) { + // else if (id == BridgeMaterial.CAKE.getId()) { // return 0.4375; // } else if (id == Material.CAULDRON) { @@ -3029,10 +3266,10 @@ public class BlockProperties { else if (id == Material.CACTUS) { return 0.9375; } - else if (id == Material.PISTON_EXTENSION) { + else if (id == BridgeMaterial.PISTON_HEAD) { return 0.625; } - else if (id == Material.ENDER_PORTAL_FRAME) { + else if (id == BridgeMaterial.END_PORTAL_FRAME) { // Allow moving as if no eye was inserted. return 0.8125; } @@ -3050,7 +3287,7 @@ public class BlockProperties { return 0.9375; } // Default height is used. - if (id == Material.SOIL) { + if (id == BridgeMaterial.FARMLAND) { return bounds[4]; } // Assume open gates/trapdoors/things to only allow standing on to, if at all. @@ -3653,7 +3890,7 @@ public class BlockProperties { bminY = 0.0; bmaxY = 0.125; } - else if (node.getType() == Material.ENDER_PORTAL_FRAME) { + else if (node.getType() == BridgeMaterial.END_PORTAL_FRAME) { // TODO: Test // TODO: Other concepts ... bminY = 0; diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/FakeBlockCache.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/FakeBlockCache.java index 6e902fa0..d13c0bc0 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/FakeBlockCache.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/FakeBlockCache.java @@ -386,7 +386,7 @@ public class FakeBlockCache extends BlockCache { final int y = entry.getY(); final int z = entry.getZ(); final Material id = entry.getValue(); - if (id == Material.AIR) { + if (BlockProperties.isAir(id)) { builder.append(fbcName + ".set(" + x + ", " + y + ", " + z + ", " + id + ");"); } else { diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/MaterialUtil.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/MaterialUtil.java new file mode 100644 index 00000000..d9e4a309 --- /dev/null +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/utilities/map/MaterialUtil.java @@ -0,0 +1,401 @@ +/* + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package fr.neatmonster.nocheatplus.utilities.map; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; + +import org.bukkit.Material; + +import fr.neatmonster.nocheatplus.compat.AlmostBoolean; +import fr.neatmonster.nocheatplus.compat.BridgeMaterial; +import fr.neatmonster.nocheatplus.logging.StaticLog; +import fr.neatmonster.nocheatplus.utilities.InventoryUtil; +import fr.neatmonster.nocheatplus.utilities.StringUtil; + +/** + * Auxiliary collections and functionality for Material. + * + * @author asofold + * + */ +public class MaterialUtil { + + // TODO: Naming conventions for collections (_BLOCKS suffix?). + + + /////////////////////// + // Internal + /////////////////////// + + private static final List woodTypes = Arrays.asList( + "acacia", "birch", "dark_oak", "jungle", "oak", "spruce", + "wood" // Legacy + ); + + /** + * Get a new set containing the given set, as well as all non-null results + * from names. + * + * @param set + * @param names + * @return + */ + private static Set add(Set set, String... names) { + final LinkedHashSet res = new LinkedHashSet(set); + res.addAll(BridgeMaterial.getAll(names)); + return res; + } + + /** + * Dump public static fields of type Set to StaticLog, using + * StringUtil.join (not recursive). + */ + public static void dumpStaticSets(final Class clazz, final Level level) { + final StringBuilder builder = new StringBuilder(6000); + for (Field field : clazz.getDeclaredFields()) { + if (Modifier.isStatic(field.getModifiers()) + && Modifier.isPublic(field.getModifiers())) { + try { + Object obj = field.get(clazz); + if (obj instanceof Set) { + Set set = (Set) obj; + builder.append(clazz.getName()); + builder.append('.'); + builder.append(field.getName()); + builder.append(": "); + StringUtil.join(set, ", ", builder); + builder.append('\n'); + } + } catch (IllegalArgumentException e) { + } catch (IllegalAccessException e) { + } + } + } + StaticLog.log(level, builder.toString()); + } + + ///////////////////////////////////////////////// + // Material collections with common properties + // (May not always have all aspects in common.) + ///////////////////////////////////////////////// + + public static final Set BANNERS = Collections.unmodifiableSet(add( + BridgeMaterial.getByPrefixAndSuffix( + null, + Arrays.asList("_banner"), + AlmostBoolean.YES, + "legacy", "_wall" + ), "standing_banner")); + + public static final Set BEDS = Collections.unmodifiableSet(add( + BridgeMaterial.getBySuffix("_bed", AlmostBoolean.YES, + "legacy"), "bed_block")); + + public static final Set BOATS; + static { + HashSet temp = new HashSet(); + if (BridgeMaterial.get("boat") != null) { + temp.add(BridgeMaterial.get("boat")); + } + temp.addAll(InventoryUtil.collectItemsByPrefix("BOAT_")); + temp.addAll(InventoryUtil.collectItemsBySuffix("_BOAT")); + BOATS = Collections.unmodifiableSet(temp); + } + + /** Bushes (block). */ + public static final Set BUSHES = Collections.unmodifiableSet( + BridgeMaterial.getBySuffix("bush", AlmostBoolean.YES, "legacy", "potted")); + + public static final Set CARPETS = Collections.unmodifiableSet(add( + BridgeMaterial.getBySuffix("_carpet", AlmostBoolean.YES, "legacy"), + "carpet")); + + public static final Set CONCRETE_BLOCKS = Collections.unmodifiableSet(add( + BridgeMaterial.getBySuffix("_concrete", AlmostBoolean.YES, "legacy"), + "concrete")); + + public static final Set CONCRETE_POWDER_BLOCKS = Collections.unmodifiableSet(add( + BridgeMaterial.getBySuffix("_concrete_powder", AlmostBoolean.YES, "legacy"), + "concrete_powder")); + + /** Dead or alive. */ + public static final Set CORAL_BLOCKS = Collections.unmodifiableSet( + BridgeMaterial.getBySuffix("coral_block", AlmostBoolean.YES, "legacy") + ); + + /** + * Dead coral parts, that have been passable alive, but which are like stone + * when dead. + */ + public static final Set DEAD_CORAL_PARTS = Collections.unmodifiableSet( + BridgeMaterial.getByPrefixAndSuffix( + Arrays.asList("dead_"), + Arrays.asList("coral_fan", "coral_wall_fan", "coral"), + AlmostBoolean.YES, + "block", "legacy" + )); + + /** Flower pot and potted plants / things. */ + public static final Set FLOWER_POTS = Collections.unmodifiableSet(add( + BridgeMaterial.getByPrefix( + "potted_", AlmostBoolean.YES), "flower_pot")); + + /** Stained and other. */ + public static final Set GLASS_BLOCKS = Collections.unmodifiableSet(add( + BridgeMaterial.getBySuffix("_glass", AlmostBoolean.YES, "legacy"), + "glass")); + + public static final Set GLASS_PANES = Collections.unmodifiableSet(add( + BridgeMaterial.getBySuffix("_glass_pane", AlmostBoolean.YES, "legacy"), + "glass_pane", "thin_glass")); + + public static final Set GLAZED_TERRACOTTA_BLOCKS = Collections.unmodifiableSet( + BridgeMaterial.getBySuffix("glazed_terracotta", AlmostBoolean.YES, "legacy") + ); + + /** Heads placed on the ground. Includes skulls. */ + public static final Set HEADS_GROUND = Collections.unmodifiableSet(add( + BridgeMaterial.getByPrefixAndSuffix( + null, + Arrays.asList("_skull", "_head"), + AlmostBoolean.YES, + "legacy", "_wall_" + ), "skull")); + + /** Heads placed on the wall. Includes skulls. */ + public static final Set HEADS_WALL = Collections.unmodifiableSet( + BridgeMaterial.getByPrefixAndSuffix( + null, + Arrays.asList("_wall_skull", "_wall_head"), + AlmostBoolean.YES, + "legacy" + )); + + /** Blocks that are infested with silverfish. */ + public static final Set INFESTED_BLOCKS = Collections.unmodifiableSet(add( + BridgeMaterial.getByPrefix("infested_", AlmostBoolean.YES), "monster_eggs")); + + /** All lava blocks. */ + public static final Set LAVA = Collections.unmodifiableSet( + BridgeMaterial.getAll("lava", "stationary_lava")); + + public static final Set LEAVES = Collections.unmodifiableSet(add( + BridgeMaterial.getByPrefixAndSuffix( + woodTypes, + Arrays.asList("_leaves"), // Strictly _pressure_plate for 1.13. + AlmostBoolean.YES + // , ... + ), "leaves", "leaves_2")); + + /** LOGS. */ + public static final Set LOGS = Collections.unmodifiableSet(add( + BridgeMaterial.getByPrefixAndSuffix( + woodTypes, + Arrays.asList("_log"), + AlmostBoolean.YES, + "legacy" + ), "log", "log_2")); + + /** Mushroom blocks (huge ones). */ + public static final Set MUSHROOM_BLOCKS = Collections.unmodifiableSet(add( + BridgeMaterial.getBySuffix( + "_mushroom_block", + AlmostBoolean.YES, + "legacy" + ), "mushroom_stem" , "huge_mushroom_1", "huge_mushroom_2")); + + /** Coral parts that are passable when alive, but become solid when dead. */ + public static final Set PASSABLE_CORAL_PARTS = Collections.unmodifiableSet( + BridgeMaterial.getByPrefixAndSuffix( + null, + Arrays.asList("coral_fan", "coral_wall_fan", "coral"), + AlmostBoolean.YES, + "dead", "legacy" + )); + + public static final Set PLANKS = Collections.unmodifiableSet(add( + BridgeMaterial.getBySuffix("_planks", AlmostBoolean.YES, "legacy"), + "wood")); + + /** All rail types. */ + public static final Set RAILS = Collections.unmodifiableSet( + BridgeMaterial.getBySuffix(Arrays.asList("rail", "rails"), AlmostBoolean.YES, "legacy")); + + /** Places saplings (block). */ + public static final Set SAPLINGS = Collections.unmodifiableSet( + BridgeMaterial.getBySuffix("sapling", AlmostBoolean.YES, "legacy", "potted")); + + public static final Set SHULKER_BOXES = Collections.unmodifiableSet( + BridgeMaterial.getBySuffix("shulker_box", AlmostBoolean.YES, "legacy")); + + public static final Set SPAWN_EGGS = Collections.unmodifiableSet(add( + BridgeMaterial.getBySuffix("_spawn_egg", AlmostBoolean.YES, "legacy"), + "monster_egg" + )); + + public static final Set STRIPPED_LOGS = Collections.unmodifiableSet( + BridgeMaterial.getByPrefixAndSuffix( + Arrays.asList("stripped_"), + Arrays.asList("_log"), AlmostBoolean.YES) + ); + + public static final Set STRIPPED_WOOD_BLOCKS = Collections.unmodifiableSet( + BridgeMaterial.getByPrefixAndSuffix( + Arrays.asList("stripped_"), + Arrays.asList("_wood"), AlmostBoolean.YES) + ); + + /** All ordinary terracotta (hard clay) blocks. */ + public static final Set TERRACOTTA_BLOCKS = Collections.unmodifiableSet(add( + // TODO: exclude GLAZED or not? + BridgeMaterial.getByPrefixAndSuffix( + null, Arrays.asList("_terracotta"), + AlmostBoolean.YES, + "legacy", "glazed"), + "terracotta", "hard_clay", "stained_clay" + )); + + /** Tulips (block). */ + public static final Set TULIPS = Collections.unmodifiableSet( + BridgeMaterial.getBySuffix("tulip", AlmostBoolean.YES, "legacy", "potted")); + + public static final Set WALL_BANNERS = Collections.unmodifiableSet(add( + BridgeMaterial.getByPrefixAndSuffix( + null, + Arrays.asList("_wall_banner"), + AlmostBoolean.YES, + "legacy" + ), "wall_banner")); + + /** All water blocks. */ + public static final Set WATER = Collections.unmodifiableSet( + BridgeMaterial.getAll("water", "stationary_water")); + + /** Wood types (1.13 rather). */ + public static final Set WOOD_BLOCKS = Collections.unmodifiableSet(add( + BridgeMaterial.getByPrefixAndSuffix( + woodTypes, + Arrays.asList("_wood"), + AlmostBoolean.YES + // , ... + ), "wood")); + + public static final Set WOODEN_BUTTONS = Collections.unmodifiableSet( + BridgeMaterial.getByPrefixAndSuffix( + woodTypes, + Arrays.asList("_button"), + AlmostBoolean.YES + )); + + public static final Set WOODEN_DOORS = Collections.unmodifiableSet( + BridgeMaterial.getByPrefixAndSuffix( + woodTypes, + Arrays.asList("_door"), + AlmostBoolean.YES, + "trap" + )); + + public static final Set WOODEN_FENCES = Collections.unmodifiableSet(add( + BridgeMaterial.getByPrefixAndSuffix( + woodTypes, + Arrays.asList("_fence"), + AlmostBoolean.YES + // , ... + ), "fence")); + + public static final Set WOODEN_FENCE_GATES = Collections.unmodifiableSet(add( + BridgeMaterial.getByPrefixAndSuffix( + woodTypes, + Arrays.asList("_fence_gate"), + AlmostBoolean.YES + // , ... + ), "fence_gate")); + + /** Wooden pressure plates. */ + public static final Set WOODEN_PRESSURE_PLATES = Collections.unmodifiableSet( + BridgeMaterial.getByPrefixAndSuffix( + woodTypes, + Arrays.asList("_plate"), // Strictly _pressure_plate for 1.13. + AlmostBoolean.YES + // , ... + )); + + /** Wooden slabs. */ + public static final Set WOODEN_SLABS = Collections.unmodifiableSet( + BridgeMaterial.getByPrefixAndSuffix( + woodTypes, + Arrays.asList("_slab", "_step"), + AlmostBoolean.YES, + "double" // Legacy + )); + + /** Wooden stairs. */ + public static final Set WOODEN_STAIRS = Collections.unmodifiableSet( + BridgeMaterial.getByPrefixAndSuffix( + woodTypes, + Arrays.asList("_stairs"), + AlmostBoolean.YES + // , ... + )); + + public static final Set WOODEN_TRAP_DOORS = Collections.unmodifiableSet(add( + BridgeMaterial.getByPrefixAndSuffix( + woodTypes, + Arrays.asList("_trap_door", "_trapdoor"), + AlmostBoolean.YES + // , ... + ), "trap_door")); + + public static final Set WOOL_BLOCKS = Collections.unmodifiableSet(add( + BridgeMaterial.getBySuffix( + "_wool", + AlmostBoolean.YES, + "legacy" + ), "wool")); + + + //////////////////// + // Access methods. + //////////////////// + + /** + * Test if the material is a boat. + * + * @param mat + * @return + */ + public static boolean isBoat(final Material mat) { + return BOATS.contains(mat); + } + + /** + * Test if the material is a spawn egg. + * + * @param mat + * @return + */ + public static boolean isSpawnEgg(final Material mat) { + return SPAWN_EGGS.contains(mat); + } + +} diff --git a/NCPPlugin/src/main/resources/plugin.yml b/NCPPlugin/src/main/resources/plugin.yml index fbc93a6b..20bfff9a 100644 --- a/NCPPlugin/src/main/resources/plugin.yml +++ b/NCPPlugin/src/main/resources/plugin.yml @@ -8,6 +8,7 @@ website: ${project.url} dev-url: ${project.url} main: ${project.groupId}.${project.artifactId}.${project.name} +api-version: 1.13 softdepend: - ProtocolLib diff --git a/NCPPlugin/src/test/java/fr/neatmonster/nocheatplus/test/TestConfig.java b/NCPPlugin/src/test/java/fr/neatmonster/nocheatplus/test/TestConfig.java index b623757a..e89d33c5 100644 --- a/NCPPlugin/src/test/java/fr/neatmonster/nocheatplus/test/TestConfig.java +++ b/NCPPlugin/src/test/java/fr/neatmonster/nocheatplus/test/TestConfig.java @@ -19,6 +19,7 @@ import static org.junit.Assert.fail; import org.bukkit.Material; import org.junit.Test; +import fr.neatmonster.nocheatplus.compat.BridgeMaterial; import fr.neatmonster.nocheatplus.config.ConfPaths; import fr.neatmonster.nocheatplus.config.ConfigFile; import fr.neatmonster.nocheatplus.config.DefaultConfig; @@ -39,9 +40,11 @@ public class TestConfig { @Test public void testReadMaterial() { // Some really needed parts first. - testReadMaterial("water lily", Material.WATER_LILY); - testReadMaterial("water-lily", Material.WATER_LILY); - testReadMaterial("watEr_lily", Material.WATER_LILY); + Material lily = BridgeMaterial.LILY_PAD; + String lilys = lily.name(); + testReadMaterial(lilys.replaceAll("_", " "), lily); + testReadMaterial(lilys.replaceAll("_", "-"), lily); + testReadMaterial(lilys.replaceAll("e", "E"), lily); testReadMaterial("flint and steel", Material.FLINT_AND_STEEL); testReadMaterial("259", Material.FLINT_AND_STEEL); diff --git a/NCPPlugin/src/test/java/fr/neatmonster/nocheatplus/test/TestInteractRayTracing.java b/NCPPlugin/src/test/java/fr/neatmonster/nocheatplus/test/TestInteractRayTracing.java index 691d5519..dcc7218f 100644 --- a/NCPPlugin/src/test/java/fr/neatmonster/nocheatplus/test/TestInteractRayTracing.java +++ b/NCPPlugin/src/test/java/fr/neatmonster/nocheatplus/test/TestInteractRayTracing.java @@ -17,6 +17,7 @@ package fr.neatmonster.nocheatplus.test; import org.bukkit.Material; import org.junit.Test; +import fr.neatmonster.nocheatplus.compat.BridgeMaterial; import fr.neatmonster.nocheatplus.logging.StaticLog; import fr.neatmonster.nocheatplus.utilities.build.BuildParameters; import fr.neatmonster.nocheatplus.utilities.collision.InteractRayTracing; @@ -163,7 +164,10 @@ public class TestInteractRayTracing { public void testIngame() { // Circle around the corners of 4 blocks with left button pressed down (random sample). // Bad end coords (should fail): - {FakeBlockCache fbc = new FakeBlockCache(); double[] _fb = new double[]{0.0, 0.0, 0.0, 1.0, 1.0, 1.0};fbc.set(142, 67, 221, Material.DIRT, 0, _fb);fbc.set(142, 67, 217, Material.GRASS, 0, _fb);fbc.set(142, 69, 219, Material.AIR);fbc.set(142, 68, 218, Material.GRASS, 0, _fb);fbc.set(142, 70, 220, Material.AIR);fbc.set(142, 71, 217, Material.AIR);fbc.set(142, 71, 221, Material.AIR);fbc.set(143, 67, 218, Material.DIRT, 0, _fb);fbc.set(143, 68, 217, Material.GRASS, 0, _fb);fbc.set(143, 68, 221, Material.GRASS, 0, _fb);fbc.set(143, 69, 220, Material.AIR);fbc.set(143, 70, 219, Material.AIR);fbc.set(143, 71, 218, Material.AIR);fbc.set(144, 67, 219, Material.DIRT, 0, _fb);fbc.set(144, 68, 220, Material.GRASS, 0, _fb);fbc.set(144, 69, 217, Material.AIR);fbc.set(144, 69, 221, Material.LONG_GRASS, 1, new double[]{0.09999999403953552, 0.0, 0.09999999403953552, 0.8999999761581421, 0.800000011920929, 0.8999999761581421});fbc.set(144, 70, 218, Material.AIR);fbc.set(144, 71, 219, Material.AIR);fbc.set(145, 67, 220, Material.DIRT, 0, _fb);fbc.set(145, 68, 219, Material.GRASS, 0, _fb);fbc.set(145, 69, 218, Material.AIR);fbc.set(145, 70, 217, Material.AIR);fbc.set(145, 70, 221, Material.AIR);fbc.set(145, 71, 220, Material.AIR);fbc.set(142, 68, 217, Material.GRASS, 0, _fb);fbc.set(142, 68, 221, Material.GRASS, 0, _fb);fbc.set(142, 67, 218, Material.DIRT, 0, _fb);fbc.set(142, 69, 220, Material.AIR);fbc.set(142, 70, 219, Material.AIR);fbc.set(142, 71, 218, Material.AIR);fbc.set(143, 67, 217, Material.DIRT, 0, _fb);fbc.set(143, 67, 221, Material.DIRT, 0, _fb);fbc.set(143, 68, 218, Material.OBSIDIAN, 0, _fb);fbc.set(143, 69, 219, Material.AIR);fbc.set(143, 70, 220, Material.AIR);fbc.set(143, 71, 217, Material.AIR);fbc.set(143, 71, 221, Material.AIR);fbc.set(144, 67, 220, Material.DIRT, 0, _fb);fbc.set(144, 68, 219, Material.OBSIDIAN, 0, _fb);fbc.set(144, 69, 218, Material.AIR);fbc.set(144, 70, 217, Material.AIR);fbc.set(144, 70, 221, Material.AIR);fbc.set(144, 71, 220, Material.AIR);fbc.set(145, 67, 219, Material.DIRT, 0, _fb);fbc.set(145, 68, 220, Material.GRASS, 0, _fb);fbc.set(145, 69, 217, Material.AIR);fbc.set(145, 69, 221, Material.TORCH, 5, new double[]{0.4000000059604645, 0.0, 0.4000000059604645, 0.6000000238418579, 0.6000000238418579, 0.6000000238418579});fbc.set(145, 70, 218, Material.AIR);fbc.set(145, 71, 219, Material.AIR);fbc.set(142, 67, 219, Material.DIRT, 0, _fb);fbc.set(142, 70, 218, Material.AIR);fbc.set(142, 69, 221, Material.LONG_GRASS, 1, new double[]{0.09999999403953552, 0.0, 0.09999999403953552, 0.8999999761581421, 0.800000011920929, 0.8999999761581421});fbc.set(142, 69, 217, Material.AIR);fbc.set(142, 68, 220, Material.GRASS, 0, _fb);fbc.set(142, 71, 219, Material.AIR);fbc.set(143, 67, 220, Material.DIRT, 0, _fb);fbc.set(143, 68, 219, Material.OBSIDIAN, 0, _fb);fbc.set(143, 69, 218, Material.AIR);fbc.set(143, 70, 217, Material.AIR);fbc.set(143, 70, 221, Material.AIR);fbc.set(143, 71, 220, Material.AIR);fbc.set(144, 67, 217, Material.DIRT, 0, _fb);fbc.set(144, 67, 221, Material.DIRT, 0, _fb);fbc.set(144, 68, 218, Material.OBSIDIAN, 0, _fb);fbc.set(144, 69, 219, Material.AIR);fbc.set(144, 70, 220, Material.AIR);fbc.set(144, 71, 217, Material.AIR);fbc.set(144, 71, 221, Material.AIR);fbc.set(145, 67, 218, Material.DIRT, 0, _fb);fbc.set(145, 68, 217, Material.GRASS, 0, _fb);fbc.set(145, 68, 221, Material.GRASS, 0, _fb);fbc.set(145, 69, 220, Material.AIR);fbc.set(145, 70, 219, Material.AIR);fbc.set(145, 71, 218, Material.AIR);fbc.set(142, 68, 219, Material.GRASS, 0, _fb);fbc.set(142, 70, 217, Material.AIR);fbc.set(142, 67, 220, Material.DIRT, 0, _fb);fbc.set(142, 69, 218, Material.LONG_GRASS, 1, new double[]{0.09999999403953552, 0.0, 0.09999999403953552, 0.8999999761581421, 0.800000011920929, 0.8999999761581421});fbc.set(142, 70, 221, Material.AIR);fbc.set(142, 71, 220, Material.AIR);fbc.set(143, 67, 219, Material.DIRT, 0, _fb);fbc.set(143, 68, 220, Material.GRASS, 0, _fb);fbc.set(143, 69, 217, Material.AIR);fbc.set(143, 69, 221, Material.AIR);fbc.set(143, 70, 218, Material.AIR);fbc.set(143, 71, 219, Material.AIR);fbc.set(144, 67, 218, Material.DIRT, 0, _fb);fbc.set(144, 68, 217, Material.GRASS, 0, _fb);fbc.set(144, 68, 221, Material.GRASS, 0, _fb);fbc.set(144, 69, 220, Material.AIR);fbc.set(144, 70, 219, Material.AIR);fbc.set(144, 71, 218, Material.AIR);fbc.set(145, 67, 217, Material.DIRT, 0, _fb);fbc.set(145, 67, 221, Material.DIRT, 0, _fb);fbc.set(145, 68, 218, Material.GRASS, 0, _fb);fbc.set(145, 69, 219, Material.AIR);fbc.set(145, 70, 220, Material.AIR);fbc.set(145, 71, 217, Material.AIR);fbc.set(145, 71, 221, Material.AIR);InteractRayTracing rt = new CenteredInteractRayTracing(false, 144, 68, 218);rt.setBlockCache(fbc);TestRayTracing.runCoordinates(rt, new double[]{144.01901074886095, 70.62, 220.1221052415879, 144.07776715103876, 68.99423513239826, 219.0}, true, false, 0.0, false, "ingame");rt.cleanup(); fbc.cleanup();} + {FakeBlockCache fbc = new FakeBlockCache(); + double[] _fb = new double[]{0.0, 0.0, 0.0, 1.0, 1.0, 1.0}; + fbc.set(142, 67, 221, Material.DIRT, 0, _fb);fbc.set(142, 67, 217, Material.GRASS, 0, _fb);fbc.set(142, 69, 219, Material.AIR);fbc.set(142, 68, 218, Material.GRASS, 0, _fb);fbc.set(142, 70, 220, Material.AIR);fbc.set(142, 71, 217, Material.AIR);fbc.set(142, 71, 221, Material.AIR);fbc.set(143, 67, 218, Material.DIRT, 0, _fb);fbc.set(143, 68, 217, Material.GRASS, 0, _fb);fbc.set(143, 68, 221, Material.GRASS, 0, _fb);fbc.set(143, 69, 220, Material.AIR);fbc.set(143, 70, 219, Material.AIR);fbc.set(143, 71, 218, Material.AIR);fbc.set(144, 67, 219, Material.DIRT, 0, _fb);fbc.set(144, 68, 220, Material.GRASS, 0, _fb);fbc.set(144, 69, 217, Material.AIR); + fbc.set(144, 69, 221, BridgeMaterial.TALL_GRASS, 1, new double[]{0.09999999403953552, 0.0, 0.09999999403953552, 0.8999999761581421, 0.800000011920929, 0.8999999761581421});fbc.set(144, 70, 218, Material.AIR);fbc.set(144, 71, 219, Material.AIR);fbc.set(145, 67, 220, Material.DIRT, 0, _fb);fbc.set(145, 68, 219, Material.GRASS, 0, _fb);fbc.set(145, 69, 218, Material.AIR);fbc.set(145, 70, 217, Material.AIR);fbc.set(145, 70, 221, Material.AIR);fbc.set(145, 71, 220, Material.AIR);fbc.set(142, 68, 217, Material.GRASS, 0, _fb);fbc.set(142, 68, 221, Material.GRASS, 0, _fb);fbc.set(142, 67, 218, Material.DIRT, 0, _fb);fbc.set(142, 69, 220, Material.AIR);fbc.set(142, 70, 219, Material.AIR);fbc.set(142, 71, 218, Material.AIR);fbc.set(143, 67, 217, Material.DIRT, 0, _fb);fbc.set(143, 67, 221, Material.DIRT, 0, _fb);fbc.set(143, 68, 218, Material.OBSIDIAN, 0, _fb);fbc.set(143, 69, 219, Material.AIR);fbc.set(143, 70, 220, Material.AIR);fbc.set(143, 71, 217, Material.AIR);fbc.set(143, 71, 221, Material.AIR);fbc.set(144, 67, 220, Material.DIRT, 0, _fb);fbc.set(144, 68, 219, Material.OBSIDIAN, 0, _fb);fbc.set(144, 69, 218, Material.AIR);fbc.set(144, 70, 217, Material.AIR);fbc.set(144, 70, 221, Material.AIR);fbc.set(144, 71, 220, Material.AIR);fbc.set(145, 67, 219, Material.DIRT, 0, _fb);fbc.set(145, 68, 220, Material.GRASS, 0, _fb);fbc.set(145, 69, 217, Material.AIR);fbc.set(145, 69, 221, Material.TORCH, 5, new double[]{0.4000000059604645, 0.0, 0.4000000059604645, 0.6000000238418579, 0.6000000238418579, 0.6000000238418579});fbc.set(145, 70, 218, Material.AIR);fbc.set(145, 71, 219, Material.AIR);fbc.set(142, 67, 219, Material.DIRT, 0, _fb);fbc.set(142, 70, 218, Material.AIR);fbc.set(142, 69, 221, Material.LONG_GRASS, 1, new double[]{0.09999999403953552, 0.0, 0.09999999403953552, 0.8999999761581421, 0.800000011920929, 0.8999999761581421});fbc.set(142, 69, 217, Material.AIR);fbc.set(142, 68, 220, Material.GRASS, 0, _fb);fbc.set(142, 71, 219, Material.AIR);fbc.set(143, 67, 220, Material.DIRT, 0, _fb);fbc.set(143, 68, 219, Material.OBSIDIAN, 0, _fb);fbc.set(143, 69, 218, Material.AIR);fbc.set(143, 70, 217, Material.AIR);fbc.set(143, 70, 221, Material.AIR);fbc.set(143, 71, 220, Material.AIR);fbc.set(144, 67, 217, Material.DIRT, 0, _fb);fbc.set(144, 67, 221, Material.DIRT, 0, _fb);fbc.set(144, 68, 218, Material.OBSIDIAN, 0, _fb);fbc.set(144, 69, 219, Material.AIR);fbc.set(144, 70, 220, Material.AIR);fbc.set(144, 71, 217, Material.AIR);fbc.set(144, 71, 221, Material.AIR);fbc.set(145, 67, 218, Material.DIRT, 0, _fb);fbc.set(145, 68, 217, Material.GRASS, 0, _fb);fbc.set(145, 68, 221, Material.GRASS, 0, _fb);fbc.set(145, 69, 220, Material.AIR);fbc.set(145, 70, 219, Material.AIR);fbc.set(145, 71, 218, Material.AIR);fbc.set(142, 68, 219, Material.GRASS, 0, _fb);fbc.set(142, 70, 217, Material.AIR);fbc.set(142, 67, 220, Material.DIRT, 0, _fb);fbc.set(142, 69, 218, Material.LONG_GRASS, 1, new double[]{0.09999999403953552, 0.0, 0.09999999403953552, 0.8999999761581421, 0.800000011920929, 0.8999999761581421});fbc.set(142, 70, 221, Material.AIR);fbc.set(142, 71, 220, Material.AIR);fbc.set(143, 67, 219, Material.DIRT, 0, _fb);fbc.set(143, 68, 220, Material.GRASS, 0, _fb);fbc.set(143, 69, 217, Material.AIR);fbc.set(143, 69, 221, Material.AIR);fbc.set(143, 70, 218, Material.AIR);fbc.set(143, 71, 219, Material.AIR);fbc.set(144, 67, 218, Material.DIRT, 0, _fb);fbc.set(144, 68, 217, Material.GRASS, 0, _fb);fbc.set(144, 68, 221, Material.GRASS, 0, _fb);fbc.set(144, 69, 220, Material.AIR);fbc.set(144, 70, 219, Material.AIR);fbc.set(144, 71, 218, Material.AIR);fbc.set(145, 67, 217, Material.DIRT, 0, _fb);fbc.set(145, 67, 221, Material.DIRT, 0, _fb);fbc.set(145, 68, 218, Material.GRASS, 0, _fb);fbc.set(145, 69, 219, Material.AIR);fbc.set(145, 70, 220, Material.AIR);fbc.set(145, 71, 217, Material.AIR);fbc.set(145, 71, 221, Material.AIR);InteractRayTracing rt = new CenteredInteractRayTracing(false, 144, 68, 218);rt.setBlockCache(fbc);TestRayTracing.runCoordinates(rt, new double[]{144.01901074886095, 70.62, 220.1221052415879, 144.07776715103876, 68.99423513239826, 219.0}, true, false, 0.0, false, "ingame");rt.cleanup(); fbc.cleanup();} } }