Fix blockplace.against. Confine isInteractBlock by tick as well.

(+ Pass tick fetched in listener to other checks as well.)
This commit is contained in:
asofold 2017-05-03 13:46:05 +02:00
parent e852fb03d2
commit b9a73ae801
7 changed files with 55 additions and 32 deletions

View File

@ -127,7 +127,8 @@ public class BlockBreakListener extends CheckListener {
* Re-check if this is a block interacted with before. With instantly
* broken blocks, this may be off by one orthogonally.
*/
final boolean isInteractBlock = !bdata.getLastIsCancelled() && bdata.matchesLastBlock(block);
final int tick = TickTask.getTick();
final boolean isInteractBlock = !bdata.getLastIsCancelled() && bdata.matchesLastBlock(tick, block);
int skippedRedundantChecks = 0;
@ -140,7 +141,7 @@ public class BlockBreakListener extends CheckListener {
}
// Has the player broken more blocks per second than allowed?
if (!cancelled && frequency.isEnabled(player) && frequency.check(player, cc, data)) {
if (!cancelled && frequency.isEnabled(player) && frequency.check(player, tick, cc, data)) {
cancelled = true;
}

View File

@ -32,7 +32,8 @@ public class Frequency extends Check {
super(CheckType.BLOCKBREAK_FREQUENCY);
}
public boolean check(final Player player, final BlockBreakConfig cc, final BlockBreakData data){
public boolean check(final Player player, final int tick,
final BlockBreakConfig cc, final BlockBreakData data){
final float interval = (float) ((player.getGameMode() == GameMode.CREATIVE)?(cc.frequencyIntervalCreative):(cc.frequencyIntervalSurvival));
data.frequencyBuckets.add(System.currentTimeMillis(), interval);
@ -42,7 +43,6 @@ public class Frequency extends Check {
final long fullTime = cc.frequencyBucketDur * cc.frequencyBuckets;
// Short term arrivals.
final int tick = TickTask.getTick();
if (tick < data.frequencyShortTermTick){
// Tick task got reset.
data.frequencyShortTermTick = tick;

View File

@ -231,7 +231,7 @@ public class BlockInteractData extends ACheckData {
/**
* Compare only tick and coordinates.
*
* @param action
* @param tick
* @param block
* @return
*/
@ -275,6 +275,16 @@ public class BlockInteractData extends ACheckData {
return lastIsCancelled;
}
/**
* Return the type of the block last interacted with. This does not check
* for invalidation.
*
* @return
*/
public Material getLastType() {
return lastType;
}
/**
* Get the tick of the last interaction with a block.
*

View File

@ -226,6 +226,7 @@ public class BlockInteractListener extends CheckListener {
}
else {
if (flyingHandle.isFlyingQueueFetched()) {
// TODO: Update flying queue removing failed entries? At least store index for subsequent checks.
final int flyingIndex = flyingHandle.getFirstIndexWithContentIfFetched();
final Integer cId;
if (flyingIndex == 0) {

View File

@ -25,7 +25,6 @@ import fr.neatmonster.nocheatplus.checks.CheckType;
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.map.BlockProperties;
/**
* Check if the placing is legitimate in terms of surrounding materials.
@ -38,7 +37,8 @@ public class Against extends Check {
super(CheckType.BLOCKPLACE_AGAINST);
}
public boolean check(final Player player, final Block block, final Material placedMat, 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 boolean isInteractBlock, final BlockPlaceData data, final BlockPlaceConfig cc) {
boolean violation = false;
// TODO: Make more precise (workarounds like WATER_LILY, general points, such as action?).
// Workaround for signs on cactus and similar.
@ -47,36 +47,40 @@ public class Against extends Check {
if (bdata.isConsumedCheck(this.type) && !bdata.isPassedCheck(this.type)) {
// TODO: Awareness of repeated violation probably is to be implemented below somewhere.
violation = true;
if (data.debug) {
debug(player, "Cancel due to block having been consumed by this check.");
}
}
bdata.addConsumedCheck(this.type);
if (!violation) {
if (BlockProperties.isAir(againstType)) {
// Attempt to workaround blocks like cactus.
if (!bdata.getLastIsCancelled() && 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?
return false;
}
else if (BlockProperties.isAir(againstType)) {
// Attempt to workaround blocks like cactus.
final Material matAgainst = bdata.getLastType();
if (isInteractBlock && !BlockProperties.isAir(matAgainst) && ! BlockProperties.isLiquid(matAgainst)) {
// Block was placed against something (e.g. cactus), allow it.
}
if (BlockProperties.isLiquid(againstType)) {
if ((placedMat != Material.WATER_LILY || !BlockProperties.isLiquid(block.getRelative(BlockFace.DOWN).getType())) && !player.hasPermission(Permissions.BLOCKPLACE_AGAINST_LIQUIDS)) {
violation = true;
}
else if (!player.hasPermission(Permissions.BLOCKPLACE_AGAINST_AIR)) {
violation = true;
}
else if (BlockProperties.isAir(againstType) && !player.hasPermission(Permissions.BLOCKPLACE_AGAINST_AIR)) {
}
else if (BlockProperties.isLiquid(againstType)) {
// TODO: F_PLACE_AGAINST_WATER|LIQUID...
if ((placedMat != Material.WATER_LILY
|| !BlockProperties.isLiquid(block.getRelative(BlockFace.DOWN).getType()))
&& !player.hasPermission(Permissions.BLOCKPLACE_AGAINST_LIQUIDS)) {
violation = true;
}
}
// Handle violation and return.
bdata.addConsumedCheck(this.type);
if (violation) {
data.againstVL += 1.0;
final ViolationData vd = new ViolationData(this, player, data.againstVL, 1, cc.againstActions);
vd.setParameter(ParameterName.BLOCK_TYPE, placedMat.toString());
vd.setParameter(ParameterName.BLOCK_ID, Integer.toString(BlockProperties.getId(placedMat)));
return executeActions(vd).willCancel();
} else {
}
else {
data.againstVL *= 0.99; // Assume one false positive every 100 blocks.
bdata.addPassedCheck(this.type);
return false;
}
}

View File

@ -49,6 +49,7 @@ import fr.neatmonster.nocheatplus.compat.BridgeMisc;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.stats.Counters;
import fr.neatmonster.nocheatplus.utilities.ReflectionUtil;
import fr.neatmonster.nocheatplus.utilities.TickTask;
import fr.neatmonster.nocheatplus.utilities.map.BlockProperties;
/**
@ -151,12 +152,15 @@ public class BlockPlaceListener extends CheckListener {
final BlockPlaceData data = BlockPlaceData.getData(player);
final BlockPlaceConfig cc = BlockPlaceConfig.getConfig(player);
final BlockInteractData bdata = BlockInteractData.getData(player);
final boolean isInteractBlock = !bdata.getLastIsCancelled() && bdata.matchesLastBlock(blockAgainst);
final int tick = TickTask.getTick();
// isInteractBlock - the block placed against is the block last interacted with.
final boolean isInteractBlock = !bdata.getLastIsCancelled() && bdata.matchesLastBlock(tick, blockAgainst);
int skippedRedundantChecks = 0;
final boolean shouldSkipSome;
if (blockMultiPlaceEvent != null && event.getClass() == blockMultiPlaceEvent) {
if (placedMat == Material.BEDROCK || Bridge1_9.hasEndCrystalItem() && placedMat == Bridge1_9.END_CRYSTAL_ITEM) {
if (placedMat == Material.BEDROCK
|| Bridge1_9.hasEndCrystalItem() && placedMat == Bridge1_9.END_CRYSTAL_ITEM) {
shouldSkipSome = true;
}
else {
@ -184,7 +188,7 @@ public class BlockPlaceListener extends CheckListener {
// Fast place check.
if (!cancelled && fastPlace.isEnabled(player)) {
if (fastPlace.check(player, block, data, cc)) {
if (fastPlace.check(player, block, tick, data, cc)) {
cancelled = true;
}
else {
@ -194,7 +198,8 @@ public class BlockPlaceListener extends CheckListener {
}
// No swing check (player doesn't swing their arm when placing a lily pad).
if (!cancelled && !cc.noSwingExceptions.contains(placedMat) && noSwing.isEnabled(player) && noSwing.check(player, data, cc)) {
if (!cancelled && !cc.noSwingExceptions.contains(placedMat)
&& noSwing.isEnabled(player) && noSwing.check(player, data, cc)) {
// Consider skipping all insta placables or using simplified version (true or true within time frame).
cancelled = true;
}
@ -218,7 +223,8 @@ public class BlockPlaceListener extends CheckListener {
if (isInteractBlock && bdata.isPassedCheck(CheckType.BLOCKINTERACT_DIRECTION)) {
skippedRedundantChecks ++;
}
else if (direction.isEnabled(player) && direction.check(player, loc, block, flyingHandle, data, cc)) {
else if (direction.isEnabled(player) && direction.check(player, loc, block, flyingHandle,
data, cc)) {
cancelled = true;
}
}
@ -229,7 +235,8 @@ public class BlockPlaceListener extends CheckListener {
}
// Surrounding material.
if (!cancelled && against.isEnabled(player) && against.check(player, block, placedMat, blockAgainst, data, cc)) {
if (!cancelled && against.isEnabled(player) && against.check(player, block, placedMat, blockAgainst,
isInteractBlock, data, cc)) {
cancelled = true;
}
@ -251,7 +258,7 @@ public class BlockPlaceListener extends CheckListener {
final Block block, final Block blockAgainst,
final int skippedRedundantChecks, final FlyingQueueHandle flyingHandle) {
debug(player, "Block place(" + placedMat + "): " + block.getX() + ", " + block.getY() + ", " + block.getZ());
BlockInteractListener.debugBlockVSBlockInteract(player, checkType, blockAgainst, "onBlockInteract(blockAgainst)",
BlockInteractListener.debugBlockVSBlockInteract(player, checkType, blockAgainst, "onBlockPlace(blockAgainst)",
Action.RIGHT_CLICK_BLOCK);
if (skippedRedundantChecks > 0) {
debug(player, "Skipped redundant checks: " + skippedRedundantChecks);

View File

@ -43,7 +43,8 @@ public class FastPlace extends Check {
* @param cc
* @return true, if successful
*/
public boolean check(final Player player, final Block block, final BlockPlaceData data, final BlockPlaceConfig cc) {
public boolean check(final Player player, final Block block, final int tick,
final BlockPlaceData data, final BlockPlaceConfig cc) {
data.fastPlaceBuckets.add(System.currentTimeMillis(), 1f);
@ -51,7 +52,6 @@ public class FastPlace extends Check {
final float fullScore = data.fastPlaceBuckets.score(1f);
// Short term arrivals.
final int tick = TickTask.getTick();
if (tick < data.fastPlaceShortTermTick ) {
// TickTask got reset.
data.fastPlaceShortTermTick = tick;