Skip to content

Commit

Permalink
Fix blockplace.against. Confine isInteractBlock by tick as well.
Browse files Browse the repository at this point in the history
(+ Pass tick fetched in listener to other checks as well.)
  • Loading branch information
asofold committed May 3, 2017
1 parent e852fb0 commit b9a73ae
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 32 deletions.
Expand Up @@ -127,7 +127,8 @@ else if (MovingUtil.hasScheduledPlayerSetBack(player)) {
* 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;


Expand All @@ -140,7 +141,7 @@ else if (MovingUtil.hasScheduledPlayerSetBack(player)) {
}

// 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;
}

Expand Down
Expand Up @@ -32,7 +32,8 @@ public Frequency() {
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);
Expand All @@ -42,7 +43,6 @@ public boolean check(final Player player, final BlockBreakConfig cc, final Block
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;
Expand Down
Expand Up @@ -231,7 +231,7 @@ public boolean matchesLastBlock(final Action action, final Block block) {
/**
* Compare only tick and coordinates.
*
* @param action
* @param tick
* @param block
* @return
*/
Expand Down Expand Up @@ -275,6 +275,16 @@ public boolean getLastIsCancelled() {
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.
*
Expand Down
Expand Up @@ -226,6 +226,7 @@ else if (MovingUtil.hasScheduledPlayerSetBack(player)) {
}
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) {
Expand Down
Expand Up @@ -25,7 +25,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.map.BlockProperties;
/**
* Check if the placing is legitimate in terms of surrounding materials.
Expand All @@ -38,7 +37,8 @@ public Against() {
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.
Expand All @@ -47,36 +47,40 @@ public boolean check(final Player player, final Block block, final Material plac
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;
}
}
Expand Down
Expand Up @@ -49,6 +49,7 @@
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;

/**
Expand Down Expand Up @@ -151,12 +152,15 @@ else if (Bridge1_9.hasGetItemInOffHand()) {
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 {
Expand Down Expand Up @@ -184,7 +188,7 @@ else if (Bridge1_9.hasGetItemInOffHand()) {

// 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 {
Expand All @@ -194,7 +198,8 @@ else if (Bridge1_9.hasGetItemInOffHand()) {
}

// 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;
}
Expand All @@ -218,7 +223,8 @@ else if (reach.isEnabled(player) && reach.check(player, block, data, cc)) {
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;
}
}
Expand All @@ -229,7 +235,8 @@ else if (direction.isEnabled(player) && direction.check(player, loc, block, flyi
}

// 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;
}

Expand All @@ -251,7 +258,7 @@ private void debugBlockPlace(final Player player, final Material placedMat,
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);
Expand Down
Expand Up @@ -43,15 +43,15 @@ public FastPlace() {
* @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);

// Full period frequency.
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;
Expand Down

0 comments on commit b9a73ae

Please sign in to comment.