mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2025-01-12 18:50:50 +01:00
Avoid sign duplication due to a bug in CraftBukkit.
The cancelled BlockPlaceEvent will lead to an extra sign being dropped, while the item in hand stays. Odd enough, the cactus is removed before the BlockPlaceEvent - need to check if a ticket exists for CraftBukkit already...
This commit is contained in:
parent
3361280cc7
commit
9528b15f55
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user