Search in sources :

Example 1 with DataPacketFlying

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

the class FlyingQueueLookBlockChecker method checkFlyingQueue.

/**
 * Run check with the given start position (e.g. eye coordinates), but use
 * yaw and pitch from the flying queue. Non matching entries are nulled,
 * unless setUnusableToNull is set to false.
 *
 * @param x
 * @param y
 * @param z
 * @param oldYaw
 * @param oldPitch
 * @param blockX
 * @param blockY
 * @param blockZ
 * @param flyingHandle
 * @return True, if check returned true (the first time is returned). False
 *         if the queue is empty or check has not returned true for any
 *         contained element. Special return values have to be set
 *         elsewhere. An empty queue also yields false as return value.
 */
public boolean checkFlyingQueue(final double x, final double y, final double z, final float oldYaw, final float oldPitch, final int blockX, final int blockY, final int blockZ, final FlyingQueueHandle flyingHandle) {
    if (checkOldLook && flyingHandle.isCurrentLocationValid()) {
        if (check(x, y, z, oldYaw, oldPitch, blockX, blockY, blockZ)) {
            return true;
        } else {
            // Invalidate.
            flyingHandle.setCurrentLocationValid(false);
        }
    }
    final DataPacketFlying[] queue = flyingHandle.getHandle();
    if (queue.length == 0) {
        return false;
    }
    for (int i = 0; i < queue.length; i++) {
        final DataPacketFlying packetData = queue[i];
        if (packetData == null) {
            continue;
        }
        if (!packetData.hasLook) {
            if (invalidateFailed) {
                queue[i] = null;
            }
            continue;
        }
        final float yaw = packetData.getYaw();
        final float pitch = packetData.getPitch();
        // TODO: Other heuristic / what's typical?
        if (yaw == oldYaw && pitch == oldPitch) {
            if (invalidateFailed) {
                queue[i] = null;
            }
            continue;
        }
        // TODO: Consider support some other type of metric (possibly checking positions too?);
        if (check(x, y, z, yaw, pitch, blockX, blockY, blockZ)) {
            // TODO: Consider to remember index and entry as well?
            return true;
        } else {
            if (invalidateFailed) {
                queue[i] = null;
            }
        }
    }
    return false;
}
Also used : DataPacketFlying(fr.neatmonster.nocheatplus.checks.net.model.DataPacketFlying)

Example 2 with DataPacketFlying

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

the class BlockBreakListener method debugBlockBreakResult.

private void debugBlockBreakResult(final Player player, final Block block, final int skippedRedundantChecks, final FlyingQueueHandle flyingHandle, final IPlayerData pData) {
    debug(player, "Block break(" + block.getType() + "): " + block.getX() + ", " + block.getY() + ", " + block.getZ());
    BlockInteractListener.debugBlockVSBlockInteract(player, checkType, block, "onBlockBreak", Action.LEFT_CLICK_BLOCK, pData);
    if (skippedRedundantChecks > 0) {
        debug(player, "Skipped redundant checks: " + skippedRedundantChecks);
    }
    if (flyingHandle != null && flyingHandle.isFlyingQueueFetched()) {
        final int flyingIndex = flyingHandle.getFirstIndexWithContentIfFetched();
        final DataPacketFlying packet = flyingHandle.getIfFetched(flyingIndex);
        if (packet != null) {
            debug(player, "Flying packet queue used at index " + flyingIndex + ": pitch=" + packet.getPitch() + ",yaw=" + packet.getYaw());
            return;
        }
    }
}
Also used : DataPacketFlying(fr.neatmonster.nocheatplus.checks.net.model.DataPacketFlying)

Example 3 with DataPacketFlying

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

the class NetData method peekFlyingQueue.

/**
 * Fetch the latest packet (under lock).
 *
 * @return
 */
public DataPacketFlying peekFlyingQueue() {
    lock.lock();
    final DataPacketFlying latest = flyingQueue.isEmpty() ? null : flyingQueue.getFirst();
    lock.unlock();
    return latest;
}
Also used : DataPacketFlying(fr.neatmonster.nocheatplus.checks.net.model.DataPacketFlying)

Example 4 with DataPacketFlying

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

the class MovingFlying method onFlyingPacket.

private void onFlyingPacket(final PacketEvent event) {
    // TODO: Code review protocol plugin :p.
    final boolean primaryThread = Bukkit.isPrimaryThread();
    counters.add(idFlying, 1, primaryThread);
    if (event.isAsync() == primaryThread) {
        counters.add(ProtocolLibComponent.idInconsistentIsAsync, 1, primaryThread);
    }
    if (!primaryThread) {
        // Count all asynchronous events extra.
        counters.addSynchronized(idAsyncFlying, 1);
    // TODO: Detect game phase for the player?
    }
    final long time = System.currentTimeMillis();
    final Player player = event.getPlayer();
    if (player == null) {
        // TODO: Need config?
        counters.add(ProtocolLibComponent.idNullPlayer, 1, primaryThread);
        event.setCancelled(true);
        return;
    }
    final IPlayerData pData = DataManager.getPlayerData(player);
    // Always update last received time.
    final NetData data = pData.getGenericInstance(NetData.class);
    // Update without much of a contract.
    data.lastKeepAliveTime = time;
    // TODO: Leniency options too (packet order inversion). -> current: flyingQueue is fetched.
    final IWorldData worldData = pData.getCurrentWorldDataSafe();
    if (!worldData.isCheckActive(CheckType.NET_FLYINGFREQUENCY)) {
        return;
    }
    final NetConfig cc = pData.getGenericInstance(NetConfig.class);
    boolean cancel = false;
    // Interpret the packet content.
    final DataPacketFlying packetData = interpretPacket(event, time);
    // Early return tests, if the packet can be interpreted.
    boolean skipFlyingFrequency = false;
    if (packetData != null) {
        // Prevent processing packets with obviously malicious content.
        if (isInvalidContent(packetData)) {
            // TODO: extra actions: log and kick (cancel state is not evaluated)
            event.setCancelled(true);
            if (pData.isDebugActive(this.checkType)) {
                debug(player, "Incoming packet, cancel due to malicious content: " + packetData.toString());
            }
            return;
        }
        switch(data.teleportQueue.processAck(packetData)) {
            case WAITING:
                {
                    if (pData.isDebugActive(this.checkType)) {
                        debug(player, "Incoming packet, still waiting for ACK on outgoing position.");
                    }
                    if (confirmTeleportType != null && cc.supersededFlyingCancelWaiting) {
                        // Don't add to the flying queue for now (assumed invalid).
                        final AckReference ackReference = data.teleportQueue.getLastAckReference();
                        if (ackReference.lastOutgoingId != Integer.MIN_VALUE && ackReference.lastOutgoingId != ackReference.maxConfirmedId) {
                            // Still waiting for a 'confirm teleport' packet. More or less safe to cancel this out.
                            /*
                             * TODO: The actual issue with this, apart from
                             * potential freezing, also concerns gameplay experience
                             * in case of minor set backs, which also could be
                             * caused by the server, e.g. with 'moved wrongly' or
                             * setting players outside of blocks. In this case the
                             * moves sent before teleport ack would still be valid
                             * after the teleport, because distances are small. The
                             * actual solution should still be to a) not have false
                             * positives b) somehow get rid all the
                             * position-correction teleporting the server does, for
                             * the cases a plugin can handle.
                             */
                            // TODO: Timeout -> either skip cancel or schedule a set back (to last valid pos or other).
                            // TODO: Config?
                            cancel = true;
                        }
                    }
                    break;
                }
            case ACK:
                {
                    // Skip processing ACK packets, no cancel.
                    skipFlyingFrequency = true;
                    if (pData.isDebugActive(this.checkType)) {
                        debug(player, "Incoming packet, interpret as ACK for outgoing position.");
                    }
                }
            default:
                {
                    // Continue.
                    // TODO: Not the optimal position, perhaps.
                    data.addFlyingQueue(packetData);
                }
        }
        // Add as valid packet (exclude invalid coordinates etc. for now).
        validContent.add(packetData.getSimplifiedContentType());
    }
    // TODO: Consider using the NetStatic check.
    if (!cancel && !skipFlyingFrequency && !pData.hasBypass(CheckType.NET_FLYINGFREQUENCY, player) && flyingFrequency.check(player, packetData, time, data, cc, pData)) {
        cancel = true;
    }
    // Process cancel and debug log.
    if (cancel) {
        event.setCancelled(true);
    }
    if (pData.isDebugActive(this.checkType)) {
        debug(player, (packetData == null ? "(Incompatible data)" : packetData.toString()) + (event.isCancelled() ? " CANCEL" : ""));
    }
}
Also used : Player(org.bukkit.entity.Player) NetData(fr.neatmonster.nocheatplus.checks.net.NetData) NetConfig(fr.neatmonster.nocheatplus.checks.net.NetConfig) IPlayerData(fr.neatmonster.nocheatplus.players.IPlayerData) AckReference(fr.neatmonster.nocheatplus.checks.net.model.TeleportQueue.AckReference) IWorldData(fr.neatmonster.nocheatplus.worlds.IWorldData) DataPacketFlying(fr.neatmonster.nocheatplus.checks.net.model.DataPacketFlying)

Example 5 with DataPacketFlying

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

the class MovingFlying method interpretPacket.

/**
 * Interpret the packet content and do with it whatever is suitable.
 * @param player
 * @param event
 * @param allScore
 * @param time
 * @param data
 * @param cc
 * @return Packet data if successful, or null on packet mismatch.
 */
private DataPacketFlying interpretPacket(final PacketEvent event, final long time) {
    final PacketContainer packet = event.getPacket();
    final List<Boolean> booleans = packet.getBooleans().getValues();
    if (booleans.size() != 3) {
        packetMismatch(event);
        return null;
    }
    final boolean onGround = booleans.get(MovingFlying.indexOnGround).booleanValue();
    final boolean hasPos = booleans.get(MovingFlying.indexhasPos).booleanValue();
    final boolean hasLook = booleans.get(MovingFlying.indexhasLook).booleanValue();
    if (!hasPos && !hasLook) {
        return new DataPacketFlying(onGround, time);
    }
    final List<Double> doubles;
    final List<Float> floats;
    if (hasPos) {
        doubles = packet.getDoubles().getValues();
        if (doubles.size() != 3 && doubles.size() != 4) {
            // 3: 1.8, 4: 1.7.10 and before (stance).
            packetMismatch(event);
            return null;
        }
    // TODO: before 1.8: stance (should make possible to reject in isInvalidContent).
    } else {
        doubles = null;
    }
    if (hasLook) {
        floats = packet.getFloat().getValues();
        if (floats.size() != 2) {
            packetMismatch(event);
            return null;
        }
    } else {
        floats = null;
    }
    if (hasPos && hasLook) {
        return new DataPacketFlying(onGround, doubles.get(indexX), doubles.get(indexY), doubles.get(indexZ), floats.get(indexYaw), floats.get(indexPitch), time);
    } else if (hasLook) {
        return new DataPacketFlying(onGround, floats.get(indexYaw), floats.get(indexPitch), time);
    } else if (hasPos) {
        return new DataPacketFlying(onGround, doubles.get(indexX), doubles.get(indexY), doubles.get(indexZ), time);
    } else {
        throw new IllegalStateException("Can't be, it can't be!");
    }
}
Also used : PacketContainer(com.comphenix.protocol.events.PacketContainer) DataPacketFlying(fr.neatmonster.nocheatplus.checks.net.model.DataPacketFlying) AlmostBoolean(fr.neatmonster.nocheatplus.compat.AlmostBoolean)

Aggregations

DataPacketFlying (fr.neatmonster.nocheatplus.checks.net.model.DataPacketFlying)6 PacketContainer (com.comphenix.protocol.events.PacketContainer)1 NetConfig (fr.neatmonster.nocheatplus.checks.net.NetConfig)1 NetData (fr.neatmonster.nocheatplus.checks.net.NetData)1 AckReference (fr.neatmonster.nocheatplus.checks.net.model.TeleportQueue.AckReference)1 AlmostBoolean (fr.neatmonster.nocheatplus.compat.AlmostBoolean)1 IPlayerData (fr.neatmonster.nocheatplus.players.IPlayerData)1 IWorldData (fr.neatmonster.nocheatplus.worlds.IWorldData)1 Player (org.bukkit.entity.Player)1