Search in sources :

Example 1 with FlyingQueueHandle

use of fr.neatmonster.nocheatplus.checks.net.FlyingQueueHandle 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);
}
Also used : Player(org.bukkit.entity.Player) BlockInteractData(fr.neatmonster.nocheatplus.checks.blockinteract.BlockInteractData) FlyingQueueHandle(fr.neatmonster.nocheatplus.checks.net.FlyingQueueHandle) Material(org.bukkit.Material) Block(org.bukkit.block.Block) IPlayerData(fr.neatmonster.nocheatplus.players.IPlayerData) ItemStack(org.bukkit.inventory.ItemStack) Location(org.bukkit.Location) EventHandler(org.bukkit.event.EventHandler)

Example 2 with FlyingQueueHandle

use of fr.neatmonster.nocheatplus.checks.net.FlyingQueueHandle in project NoCheatPlus by NoCheatPlus.

the class BlockInteractListener method onPlayerInteract.

/**
 * We listen to PlayerInteractEvent events for obvious reasons.
 *
 * @param event
 *            the event
 */
@EventHandler(ignoreCancelled = false, priority = EventPriority.LOWEST)
public void onPlayerInteract(final PlayerInteractEvent event) {
    final Player player = event.getPlayer();
    final IPlayerData pData = DataManager.getPlayerData(player);
    final BlockInteractData data = pData.getGenericInstance(BlockInteractData.class);
    data.resetLastBlock();
    // 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 !?.
        // Auto-soup after death.
        /*
             * TODO: Allow physical interact after death? Risks could be command
             * blocks used etc.
             */
        cancelId = idCancelDead;
    } else if (!player.isOnline()) {
        cancelId = idCancelOffline;
    } else if (MovingUtil.hasScheduledPlayerSetBack(player)) {
        // Might log.
        // No counters yet, but do prevent.
        cancelId = -1;
    } else {
        cancelId = Integer.MIN_VALUE;
    }
    if (cancelId != Integer.MIN_VALUE) {
        event.setUseInteractedBlock(Result.DENY);
        event.setUseItemInHand(Result.DENY);
        event.setCancelled(true);
        data.setPlayerInteractEventResolution(event);
        if (cancelId >= 0) {
            counters.addPrimaryThread(cancelId, 1);
        }
        return;
    }
    // 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 int previousLastTick = data.getLastTick();
    // TODO: Last block setting: better on monitor !?.
    boolean blockChecks = true;
    if (block == null) {
        data.resetLastBlock();
        blockChecks = false;
    } else {
        data.setLastBlock(block, action);
    }
    final BlockFace face = event.getBlockFace();
    final ItemStack stack;
    switch(action) {
        case RIGHT_CLICK_AIR:
        // TODO: What else to adapt?
        case LEFT_CLICK_AIR:
        // TODO: What else to adapt?
        case LEFT_CLICK_BLOCK:
            stack = null;
            break;
        case RIGHT_CLICK_BLOCK:
            stack = Bridge1_9.getUsedItem(player, event);
            if (stack != null && stack.getType() == Material.ENDER_PEARL) {
                checkEnderPearlRightClickBlock(player, block, face, event, previousLastTick, data, pData);
            }
            break;
        default:
            data.setPlayerInteractEventResolution(event);
            return;
    }
    boolean cancelled = false;
    if (event.isCancelled() && event.useInteractedBlock() != Result.ALLOW) {
        if (event.useItemInHand() == Result.ALLOW) {
            blockChecks = false;
        // TODO: Some potential for plugin features...
        } else {
            // Can't do more than prevent all (could: set to prevent on highest, if desired).
            data.setPlayerInteractEventResolution(event);
            return;
        }
    }
    final BlockInteractConfig cc = pData.getGenericInstance(BlockInteractConfig.class);
    boolean preventUseItem = false;
    final Location loc = player.getLocation(useLoc);
    final FlyingQueueHandle flyingHandle = new FlyingQueueHandle(pData);
    // Interaction speed.
    if (!cancelled && speed.isEnabled(player, pData) && speed.check(player, data, cc)) {
        cancelled = true;
        preventUseItem = true;
    }
    if (blockChecks) {
        final double eyeHeight = MovingUtil.getEyeHeight(player);
        // First the reach check.
        if (!cancelled && reach.isEnabled(player, pData) && reach.check(player, loc, eyeHeight, block, data, cc)) {
            cancelled = true;
        }
        // Second the direction check
        if (!cancelled && direction.isEnabled(player, pData) && direction.check(player, loc, eyeHeight, block, flyingHandle, data, cc, pData)) {
            cancelled = true;
        }
        // Ray tracing for freecam use etc.
        if (!cancelled && visible.isEnabled(player, pData) && visible.check(player, loc, eyeHeight, block, face, action, flyingHandle, data, cc, pData)) {
            cancelled = true;
        }
    }
    // If one of the checks requested to cancel the event, do so.
    if (cancelled) {
        onCancelInteract(player, block, face, event, previousLastTick, preventUseItem, data, cc, pData);
    } 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) {
                cId = idInteractLookFlyingFirst;
            } else {
                cId = idInteractLookFlyingOther;
            }
            counters.add(cId, 1);
            if (pData.isDebugActive(CheckType.BLOCKINTERACT)) {
                // Log which entry was used.
                logUsedFlyingPacket(player, flyingHandle, flyingIndex);
            }
        } else {
            counters.addPrimaryThread(idInteractLookCurrent, 1);
        }
    }
    // Set resolution here already:
    data.setPlayerInteractEventResolution(event);
    useLoc.setWorld(null);
}
Also used : Player(org.bukkit.entity.Player) Action(org.bukkit.event.block.Action) BlockFace(org.bukkit.block.BlockFace) FlyingQueueHandle(fr.neatmonster.nocheatplus.checks.net.FlyingQueueHandle) IPlayerData(fr.neatmonster.nocheatplus.players.IPlayerData) Block(org.bukkit.block.Block) ItemStack(org.bukkit.inventory.ItemStack) Location(org.bukkit.Location) EventHandler(org.bukkit.event.EventHandler)

Example 3 with FlyingQueueHandle

use of fr.neatmonster.nocheatplus.checks.net.FlyingQueueHandle 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;
}
Also used : Player(org.bukkit.entity.Player) BlockInteractData(fr.neatmonster.nocheatplus.checks.blockinteract.BlockInteractData) FlyingQueueHandle(fr.neatmonster.nocheatplus.checks.net.FlyingQueueHandle) GameMode(org.bukkit.GameMode) IPlayerData(fr.neatmonster.nocheatplus.players.IPlayerData) Block(org.bukkit.block.Block) Location(org.bukkit.Location) EventHandler(org.bukkit.event.EventHandler)

Aggregations

FlyingQueueHandle (fr.neatmonster.nocheatplus.checks.net.FlyingQueueHandle)3 IPlayerData (fr.neatmonster.nocheatplus.players.IPlayerData)3 Location (org.bukkit.Location)3 Block (org.bukkit.block.Block)3 Player (org.bukkit.entity.Player)3 EventHandler (org.bukkit.event.EventHandler)3 BlockInteractData (fr.neatmonster.nocheatplus.checks.blockinteract.BlockInteractData)2 ItemStack (org.bukkit.inventory.ItemStack)2 GameMode (org.bukkit.GameMode)1 Material (org.bukkit.Material)1 BlockFace (org.bukkit.block.BlockFace)1 Action (org.bukkit.event.block.Action)1