diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockinteract/BlockInteractData.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockinteract/BlockInteractData.java index ddb32ab3..39d56469 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockinteract/BlockInteractData.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockinteract/BlockInteractData.java @@ -3,11 +3,15 @@ package fr.neatmonster.nocheatplus.checks.blockinteract; import java.util.HashMap; import java.util.Map; +import org.bukkit.Material; +import org.bukkit.block.Block; import org.bukkit.entity.Player; +import org.bukkit.event.block.Action; import fr.neatmonster.nocheatplus.checks.access.ACheckData; import fr.neatmonster.nocheatplus.checks.access.CheckDataFactory; import fr.neatmonster.nocheatplus.checks.access.ICheckData; +import fr.neatmonster.nocheatplus.utilities.TickTask; /* * M#"""""""'M dP dP M""M dP dP @@ -78,6 +82,15 @@ public class BlockInteractData extends ACheckData { public double reachVL = 0; public double speedVL = 0; public double visibleVL = 0; + + // General data + // Last block interacted with + public int lastX = Integer.MAX_VALUE; + public int lastY, lastZ; + /** null for air */ + public Material lastType = null; + public long lastTick; + public Action lastAction = null; // Data of the reach check. public double reachDistance; @@ -87,4 +100,27 @@ public class BlockInteractData extends ACheckData { /** Number of interactions since last reset-time. */ public int speedCount = 0; + /** + * Last interacted block. + * @param block + */ + public void setLastBlock(Block block, Action action) { + lastX = block.getX(); + lastY = block.getY(); + lastZ = block.getZ(); + lastType = block.getType(); + if (lastType == Material.AIR) { + lastType = null; + } + lastTick = TickTask.getTick(); + lastAction = action; + } + + public void resetLastBlock() { + lastTick = 0; + lastAction = null; + lastX = Integer.MAX_VALUE; + lastType = null; + } + } diff --git a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockinteract/BlockInteractListener.java b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockinteract/BlockInteractListener.java index 4dac86b8..49a2a84a 100644 --- a/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockinteract/BlockInteractListener.java +++ b/NCPCore/src/main/java/fr/neatmonster/nocheatplus/checks/blockinteract/BlockInteractListener.java @@ -83,7 +83,8 @@ public class BlockInteractListener extends CheckListener { return; } final Player player = event.getPlayer(); - + final BlockInteractData data = BlockInteractData.getData(player); + data.setLastBlock(block, action); switch(action){ case LEFT_CLICK_BLOCK: break; @@ -106,9 +107,7 @@ public class BlockInteractListener extends CheckListener { return; } - final BlockInteractData data = BlockInteractData.getData(player); final BlockInteractConfig cc = BlockInteractConfig.getConfig(player); - boolean cancelled = false; final BlockFace face = event.getBlockFace(); 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 be26bd03..7e329905 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 @@ -9,7 +9,11 @@ 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.checks.blockbreak.BlockBreakData; +import fr.neatmonster.nocheatplus.checks.blockinteract.BlockInteractData; import fr.neatmonster.nocheatplus.utilities.BlockProperties; +import fr.neatmonster.nocheatplus.utilities.TickTask; +import fr.neatmonster.nocheatplus.utilities.TrigUtil; /** * Check if the placing is legitimate in terms of surrounding materials. * @author mc_dev @@ -21,12 +25,24 @@ public class Against extends Check { super(CheckType.BLOCKPLACE_AGAINST); } - public boolean check(final Player player, final Block block, final Material mat, final Block blockAgainst, final BlockPlaceData data, final BlockPlaceConfig cc) { + public boolean check(final Player player, final Block block, final Material placedMat, final Block blockAgainst, final BlockPlaceData data, final BlockPlaceConfig cc) { boolean violation = false; // TODO: Make more precise (workarounds like WATER_LILY, general points). + // Workaround for signs on cactus and similar. final int againstId = blockAgainst.getTypeId(); + if (againstId == Material.AIR.getId()) { + // Attempt to workaround blocks like cactus. + final BlockInteractData bdata = BlockInteractData.getData(player); + if (bdata.lastType != null && bdata.lastX != Integer.MAX_VALUE && TickTask.getTick() == bdata.lastTick && TrigUtil.manhattan(bdata.lastX, bdata.lastY, bdata.lastZ, blockAgainst) == 0) { + // (Wide screen.) + // Block was placed against something (e.g. cactus), allow it. + // TODO: Later reset can conflict, though it makes sense to reset with placing blocks in general. + bdata.resetLastBlock(); + return false; + } + } if (BlockProperties.isLiquid(againstId)) { - if ((mat != Material.WATER_LILY || !BlockProperties.isLiquid(block.getRelative(BlockFace.DOWN).getTypeId()))) { + if ((placedMat != Material.WATER_LILY || !BlockProperties.isLiquid(block.getRelative(BlockFace.DOWN).getTypeId()))) { violation = true; } } @@ -37,7 +53,7 @@ public class Against extends Check { if (violation) { data.againstVL += 1.0; final ViolationData vd = new ViolationData(this, player, data.againstVL, 1, cc.againstActions); - vd.setParameter(ParameterName.BLOCK_ID, Integer.toString(mat.getId())); + vd.setParameter(ParameterName.BLOCK_ID, Integer.toString(placedMat.getId())); return executeActions(vd); } else { data.againstVL *= 100; // Assume one false positive every 100 blocks.