The last block is now private.

* Add methods for checking/testing vs. last block.
* TrigUtil.isSameBlock for a block.
* Reset last block on cancel.
This commit is contained in:
asofold 2017-04-29 14:25:06 +02:00
parent adf8c2b949
commit 9f3c10951d
5 changed files with 116 additions and 9 deletions

View File

@ -120,7 +120,8 @@ public class BlockBreakListener extends CheckListener {
final GameMode gameMode = player.getGameMode();
// Has the player broken a block that was not damaged before?
if (wrongBlock.isEnabled(player) && wrongBlock.check(player, block, cc, data, isInstaBreak)) {
final boolean wrongBlockEnabled = wrongBlock.isEnabled(player);
if (wrongBlockEnabled && wrongBlock.check(player, block, cc, data, isInstaBreak)) {
cancelled = true;
}
@ -145,6 +146,7 @@ public class BlockBreakListener extends CheckListener {
}
// Did the player look at the block at all?
// TODO: Skip if checks were run on this block (all sorts of hashes/conditions).
if (!cancelled && direction.isEnabled(player) && direction.check(player, block, data)) {
cancelled = true;
}

View File

@ -27,6 +27,7 @@ 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;
import fr.neatmonster.nocheatplus.utilities.location.TrigUtil;
/**
* Player specific data for the block interact checks.
@ -88,8 +89,9 @@ public class BlockInteractData extends ACheckData {
// General data
// Last block interacted with
public int lastX = Integer.MAX_VALUE;
public int lastY, lastZ;
/** Set to Integer.MAX_VALUE for reset. */
private int lastX = Integer.MAX_VALUE;
private int lastY, lastZ;
/** null for air */
public Material lastType = null;
public int lastTick;
@ -120,7 +122,7 @@ public class BlockInteractData extends ACheckData {
* Last interacted block.
* @param block
*/
public void setLastBlock(Block block, Action action) {
public void setLastBlock(final Block block, final Action action) {
lastX = block.getX();
lastY = block.getY();
lastZ = block.getZ();
@ -132,6 +134,77 @@ public class BlockInteractData extends ACheckData {
lastAction = action;
}
/**
* Full state comparison.
* @param material
* @param action
* @param tick
* @param block
* @return
*/
public boolean matchesLastBlock(final Material material, final Action action, final int tick, final Block block) {
return lastX != Integer.MAX_VALUE && material == lastType && matchesLastBlock(action, tick, block);
}
/**
* Compare action, tick and block.
*
* @param action
* @param tick
* @param block
* @return
*/
public boolean matchesLastBlock(final Action action, final int tick, final Block block) {
return lastX != Integer.MAX_VALUE && tick == lastTick && matchesLastBlock(action, block);
}
/**
* Compare only action and coordinates.
*
* @param action
* @param block
* @return
*/
public boolean matchesLastBlock(final Action action, final Block block) {
return lastX != Integer.MAX_VALUE && action == lastAction && matchesLastBlock(block);
}
/**
* Compare only tick and coordinates.
*
* @param action
* @param block
* @return
*/
public boolean matchesLastBlock(final int tick, final Block block) {
return lastX != Integer.MAX_VALUE && tick == lastTick && matchesLastBlock(block);
}
/**
* Compare the block coordinates.
*
* @param block
* @return
*/
public boolean matchesLastBlock(final Block block) {
// Skip the MAX_VALUE check.
return lastX == block.getX() && lastY == block.getY() && lastZ == block.getZ();
}
/**
* The Manhattan distance to the set last block, Integer.MAX_VALUE is
* returned if none is set.
*
* @param block
* @return The Manhattan distance if appropriate - if no block is set,
* Integer.MAX_VALUE is returned.
*/
public int manhattanLastBlock(final Block block) {
return lastX == Integer.MAX_VALUE ? Integer.MAX_VALUE : TrigUtil.manhattan(lastX, lastY, lastZ,
block.getX(), block.getY(), block.getZ());
}
public void resetLastBlock() {
lastTick = 0;
lastAction = null;
@ -139,4 +212,19 @@ public class BlockInteractData extends ACheckData {
lastType = null;
}
/**
* Reset passed checks (concern the last block interacted with).
*/
public void resetPassedChecks() {
// TODO
}
/**
* Adjustments, disregarding who/what cancelled the event.
*/
public void onCancelledBlockInteractEvent() {
resetLastBlock();
resetPassedChecks();
}
}

View File

@ -81,6 +81,8 @@ public class BlockInteractListener extends CheckListener {
@EventHandler(ignoreCancelled = false, priority = EventPriority.LOWEST)
protected void onPlayerInteract(final PlayerInteractEvent event) {
final Player player = event.getPlayer();
final BlockInteractData data = BlockInteractData.getData(player);
data.resetPassedChecks();
// Early cancel for interact events with dead players and other.
final int cancelId;
if (player.isDead() && BridgeHealth.getHealth(player) <= 0.0) { // TODO: Should be dead !?.
@ -102,6 +104,7 @@ public class BlockInteractListener extends CheckListener {
event.setUseInteractedBlock(Result.DENY);
event.setUseItemInHand(Result.DENY);
event.setCancelled(true);
data.onCancelledBlockInteractEvent();
if (cancelId >= 0) {
counters.addPrimaryThread(cancelId, 1);
}
@ -111,7 +114,6 @@ public class BlockInteractListener extends CheckListener {
// TODO: Re-arrange for interact spamming. (With ProtocolLib something else is in place as well.)
final Action action = event.getAction();
final Block block = event.getClickedBlock();
final BlockInteractData data = BlockInteractData.getData(player);
final int previousLastTick = data.lastTick;
// TODO: Last block setting: better on monitor !?.
if (block == null) {
@ -143,6 +145,7 @@ public class BlockInteractListener extends CheckListener {
boolean cancelled = false;
if (event.isCancelled() && event.useInteractedBlock() != Result.ALLOW) {
data.subsequentCancel ++;
data.onCancelledBlockInteractEvent();
return;
}
@ -216,7 +219,8 @@ public class BlockInteractListener extends CheckListener {
if (data.debug) {
genericDebug(player, block, face, event, "already cancelled: deny use block", previousLastTick, data, cc);
}
} else {
}
else {
final Result previousUseItem = event.useItemInHand();
event.setCancelled(true);
event.setUseInteractedBlock(Result.DENY);
@ -239,6 +243,7 @@ public class BlockInteractListener extends CheckListener {
}
}
}
data.onCancelledBlockInteractEvent();
data.subsequentCancel ++;
}

View File

@ -26,7 +26,6 @@ import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.checks.blockinteract.BlockInteractData;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.utilities.TickTask;
import fr.neatmonster.nocheatplus.utilities.location.TrigUtil;
import fr.neatmonster.nocheatplus.utilities.map.BlockProperties;
/**
* Check if the placing is legitimate in terms of surrounding materials.
@ -47,10 +46,10 @@ public class Against extends Check {
if (BlockProperties.isAir(againstType)) {
// 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.)
if (bdata.matchesLastBlock(TickTask.getTick(), blockAgainst)) {
// 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.
// TODO: Reset on leaving the listener rather - why could it conflict?
bdata.resetLastBlock();
return false;
}

View File

@ -760,4 +760,17 @@ public class TrigUtil {
return x1 == Location.locToBlock(x2) && z1 == Location.locToBlock(z2) && y1 == Location.locToBlock(y2);
}
/**
* Check if the block has the same coordinates.
*
* @param x
* @param y
* @param z
* @param block
* @return
*/
public static boolean isSameBlock(int x, int y, int z, Block block) {
return x == block.getX() && y == block.getY() && z == block.getZ();
}
}