use of fr.neatmonster.nocheatplus.checks.blockinteract.BlockInteractData in project NoCheatPlus by NoCheatPlus.
the class Against method check.
public boolean check(final Player player, final Block block, final Material placedMat, final Block blockAgainst, final boolean isInteractBlock, final BlockPlaceData data, final BlockPlaceConfig cc, final IPlayerData pData) {
boolean violation = false;
// TODO: Make more precise (workarounds like WATER_LILY, general points, such as action?).
// Workaround for signs on cactus and similar.
// TODO: pass as argument.
final BlockInteractData bdata = pData.getGenericInstance(BlockInteractData.class);
final Material againstType = blockAgainst.getType();
if (bdata.isConsumedCheck(this.type) && !bdata.isPassedCheck(this.type)) {
// TODO: Awareness of repeated violation probably is to be implemented below somewhere.
violation = true;
if (pData.isDebugActive(type)) {
debug(player, "Cancel due to block having been consumed by this check.");
}
} 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.
} else if (!pData.hasPermission(Permissions.BLOCKPLACE_AGAINST_AIR, player)) {
violation = true;
}
} else if (BlockProperties.isLiquid(againstType)) {
// TODO: F_PLACE_AGAINST_WATER|LIQUID...
if ((placedMat != Material.WATER_LILY || !BlockProperties.isLiquid(block.getRelative(BlockFace.DOWN).getType())) && !pData.hasPermission(Permissions.BLOCKPLACE_AGAINST_LIQUIDS, player)) {
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());
return executeActions(vd).willCancel();
} else {
// Assume one false positive every 100 blocks.
data.againstVL *= 0.99;
bdata.addPassedCheck(this.type);
return false;
}
}
use of fr.neatmonster.nocheatplus.checks.blockinteract.BlockInteractData in project NoCheatPlus by NoCheatPlus.
the class BlockPlaceListener method onBlockPlace.
/**
* We listen to BlockPlace events for obvious reasons.
*
* @param event
* the event
*/
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onBlockPlace(final BlockPlaceEvent event) {
final Block block = event.getBlockPlaced();
final Block blockAgainst = event.getBlockAgainst();
// Skip any null blocks.
if (block == null || blockAgainst == null) {
return;
}
// TODO: What if same block?
// TODO: Revise material use (not block.get... ?)
// final Material mat = block.getType();
final Player player = event.getPlayer();
final Material placedMat;
if (hasGetReplacedState) {
placedMat = event.getBlockPlaced().getType();
} else if (Bridge1_9.hasGetItemInOffHand()) {
final ItemStack stack = event.getItemInHand();
placedMat = BlockProperties.isAir(stack) ? Material.AIR : stack.getType();
} else {
// Safety first.
placedMat = Bridge1_9.getItemInMainHand(player).getType();
}
boolean cancelled = false;
// TODO: Use for data + config getting etc.
final IPlayerData pData = DataManager.getPlayerData(player);
final BlockPlaceData data = pData.getGenericInstance(BlockPlaceData.class);
final BlockPlaceConfig cc = pData.getGenericInstance(BlockPlaceConfig.class);
final BlockInteractData bdata = pData.getGenericInstance(BlockInteractData.class);
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 debug = pData.isDebugActive(CheckType.BLOCKPLACE);
final boolean shouldSkipSome;
if (blockMultiPlaceEvent != null && event.getClass() == blockMultiPlaceEvent) {
if (placedMat == Material.BEDROCK || Bridge1_9.hasEndCrystalItem() && placedMat == Bridge1_9.END_CRYSTAL_ITEM) {
shouldSkipSome = true;
} else {
if (debug) {
debug(player, "Block place " + event.getClass().getName() + " " + placedMat);
}
shouldSkipSome = false;
}
} else {
shouldSkipSome = false;
}
if (placedMat == Material.SIGN) {
// Might move to MONITOR priority.
data.autoSignPlacedTime = System.currentTimeMillis();
// Always hash as sign post for improved compatibility with Lockette etc.
data.autoSignPlacedHash = getBlockPlaceHash(block, Material.SIGN);
}
// Don't run checks, if a set back is scheduled.
if (!cancelled && pData.isPlayerSetBackScheduled()) {
cancelled = true;
}
// Fast place check.
if (!cancelled && fastPlace.isEnabled(player, pData)) {
if (fastPlace.check(player, block, tick, data, cc, pData)) {
cancelled = true;
} else {
// Feed the improbable.
Improbable.feed(player, 0.5f, System.currentTimeMillis(), pData);
}
}
// No swing check (player doesn't swing their arm when placing a lily pad).
if (!cancelled && !cc.noSwingExceptions.contains(placedMat) && noSwing.isEnabled(player, pData) && noSwing.check(player, data, cc)) {
// Consider skipping all insta placables or using simplified version (true or true within time frame).
cancelled = true;
}
final FlyingQueueHandle flyingHandle;
final boolean reachCheck = pData.isCheckActive(CheckType.BLOCKPLACE_REACH, player);
final boolean directionCheck = pData.isCheckActive(CheckType.BLOCKPLACE_DIRECTION, player);
if (reachCheck || directionCheck) {
flyingHandle = new FlyingQueueHandle(pData);
final Location loc = player.getLocation(useLoc);
final double eyeHeight = MovingUtil.getEyeHeight(player);
// Reach check (distance).
if (!cancelled && !shouldSkipSome) {
if (isInteractBlock && bdata.isPassedCheck(CheckType.BLOCKINTERACT_REACH)) {
skippedRedundantChecks++;
} else if (reachCheck && reach.check(player, eyeHeight, block, data, cc)) {
cancelled = true;
}
}
// Direction check.
if (!cancelled && !shouldSkipSome) {
if (isInteractBlock && bdata.isPassedCheck(CheckType.BLOCKINTERACT_DIRECTION)) {
skippedRedundantChecks++;
} else if (directionCheck && direction.check(player, loc, eyeHeight, block, flyingHandle, data, cc, pData)) {
cancelled = true;
}
}
useLoc.setWorld(null);
} else {
flyingHandle = null;
}
// Surrounding material.
if (!cancelled && against.isEnabled(player, pData) && against.check(player, block, placedMat, blockAgainst, isInteractBlock, data, cc, pData)) {
cancelled = true;
}
// If one of the checks requested to cancel the event, do so.
if (cancelled) {
event.setCancelled(cancelled);
} else {
// Debug log (only if not cancelled, to avoid spam).
if (debug) {
debugBlockPlace(player, placedMat, block, blockAgainst, skippedRedundantChecks, flyingHandle, pData);
}
}
// Cleanup
// Reminder(currently unused): useLoc.setWorld(null);
}
use of fr.neatmonster.nocheatplus.checks.blockinteract.BlockInteractData in project NoCheatPlus by NoCheatPlus.
the class BlockBreakListener method onBlockBreak.
/**
* We listen to BlockBreak events for obvious reasons.
*
* @param event
* the event
*/
@EventHandler(ignoreCancelled = false, priority = EventPriority.LOWEST)
public void onBlockBreak(final BlockBreakEvent event) {
final long now = System.currentTimeMillis();
final Player player = event.getPlayer();
final IPlayerData pData = DataManager.getPlayerData(player);
// TODO: Legacy / encapsulate fully there.
if (Items.checkIllegalEnchantmentsAllHands(player, pData)) {
event.setCancelled(true);
counters.addPrimaryThread(idCancelDIllegalItem, 1);
} else if (MovingUtil.hasScheduledPlayerSetBack(player)) {
event.setCancelled(true);
}
// Cancelled events only leads to resetting insta break.
if (event.isCancelled()) {
isInstaBreak = AlmostBoolean.NO;
return;
}
// TODO: maybe invalidate instaBreak on some occasions.
final Block block = event.getBlock();
boolean cancelled = false;
// Do the actual checks, if still needed. It's a good idea to make computationally cheap checks first, because
// it may save us from doing the computationally expensive checks.
final BlockBreakConfig cc = pData.getGenericInstance(BlockBreakConfig.class);
final BlockBreakData data = pData.getGenericInstance(BlockBreakData.class);
final BlockInteractData bdata = pData.getGenericInstance(BlockInteractData.class);
/*
* Re-check if this is a block interacted with before. With instantly
* broken blocks, this may be off by one orthogonally.
*/
final int tick = TickTask.getTick();
final boolean isInteractBlock = !bdata.getLastIsCancelled() && bdata.matchesLastBlock(tick, block);
int skippedRedundantChecks = 0;
final GameMode gameMode = player.getGameMode();
// Has the player broken a block that was not damaged before?
final boolean wrongBlockEnabled = wrongBlock.isEnabled(player, pData);
if (wrongBlockEnabled && wrongBlock.check(player, block, cc, data, pData, isInstaBreak)) {
cancelled = true;
}
// Has the player broken more blocks per second than allowed?
if (!cancelled && frequency.isEnabled(player, pData) && frequency.check(player, tick, cc, data, pData)) {
cancelled = true;
}
// Has the player broken blocks faster than possible?
if (!cancelled && gameMode != GameMode.CREATIVE && fastBreak.isEnabled(player, pData) && fastBreak.check(player, block, isInstaBreak, cc, data, pData)) {
cancelled = true;
}
// Did the arm of the player move before breaking this block?
if (!cancelled && noSwing.isEnabled(player, pData) && noSwing.check(player, data, pData)) {
cancelled = true;
}
final FlyingQueueHandle flyingHandle;
final boolean reachEnabled = reach.isEnabled(player, pData);
final boolean directionEnabled = direction.isEnabled(player, pData);
if (reachEnabled || directionEnabled) {
flyingHandle = new FlyingQueueHandle(pData);
final Location loc = player.getLocation(useLoc);
final double eyeHeight = MovingUtil.getEyeHeight(player);
// Is the block really in reach distance?
if (!cancelled) {
if (isInteractBlock && bdata.isPassedCheck(CheckType.BLOCKINTERACT_REACH)) {
skippedRedundantChecks++;
} else if (reachEnabled && reach.check(player, eyeHeight, block, data, cc)) {
cancelled = true;
}
}
// TODO: Skip if checks were run on this block (all sorts of hashes/conditions).
if (!cancelled) {
if (isInteractBlock && (bdata.isPassedCheck(CheckType.BLOCKINTERACT_DIRECTION) || bdata.isPassedCheck(CheckType.BLOCKINTERACT_VISIBLE))) {
skippedRedundantChecks++;
} else if (directionEnabled && direction.check(player, loc, eyeHeight, block, flyingHandle, data, cc, pData)) {
cancelled = true;
}
}
useLoc.setWorld(null);
} else {
flyingHandle = null;
}
// Destroying liquid blocks.
if (!cancelled && BlockProperties.isLiquid(block.getType()) && !pData.hasPermission(Permissions.BLOCKBREAK_BREAK_LIQUID, player) && !NCPExemptionManager.isExempted(player, CheckType.BLOCKBREAK_BREAK)) {
cancelled = true;
}
// On cancel...
if (cancelled) {
event.setCancelled(cancelled);
// Reset damage position:
// TODO: Review this (!), check if set at all !?
data.clickedX = block.getX();
data.clickedY = block.getY();
data.clickedZ = block.getZ();
} else {
// Debug log (only if not cancelled, to avoid spam).
if (pData.isDebugActive(CheckType.BLOCKBREAK)) {
debugBlockBreakResult(player, block, skippedRedundantChecks, flyingHandle, pData);
}
}
if (isInstaBreak.decideOptimistically()) {
data.wasInstaBreak = now;
} else {
data.wasInstaBreak = 0;
}
// Adjust data.
data.fastBreakBreakTime = now;
// data.fastBreakfirstDamage = now;
isInstaBreak = AlmostBoolean.NO;
}
Aggregations