Search in sources :

Example 6 with NetData

use of fr.neatmonster.nocheatplus.checks.net.NetData 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 7 with NetData

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

the class ProtocolLibComponent method onPlayerTeleport.

@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onPlayerTeleport(final PlayerTeleportEvent event) {
    if (!registeredPacketAdapters.isEmpty()) {
        // TODO: Might move to MovingListener.
        // TODO: Might still add cancelled UNKNOWN events. TEST IT
        final Location to = event.getTo();
        if (to == null) {
            return;
        }
        final Player player = event.getPlayer();
        final IPlayerData pData = DataManager.getPlayerData(player);
        final NetData data = pData.getGenericInstance(NetData.class);
        if (pData.isCheckActive(CheckType.NET_FLYINGFREQUENCY, player)) {
            // Register expected location for comparison with outgoing packets.
            data.teleportQueue.onTeleportEvent(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch());
        }
        data.clearFlyingQueue();
    }
}
Also used : Player(org.bukkit.entity.Player) NetData(fr.neatmonster.nocheatplus.checks.net.NetData) IPlayerData(fr.neatmonster.nocheatplus.players.IPlayerData) Location(org.bukkit.Location) EventHandler(org.bukkit.event.EventHandler)

Aggregations

NetData (fr.neatmonster.nocheatplus.checks.net.NetData)7 Player (org.bukkit.entity.Player)7 IPlayerData (fr.neatmonster.nocheatplus.players.IPlayerData)6 NetConfig (fr.neatmonster.nocheatplus.checks.net.NetConfig)4 PacketContainer (com.comphenix.protocol.events.PacketContainer)2 Location (org.bukkit.Location)2 EventHandler (org.bukkit.event.EventHandler)2 EntityUseAction (com.comphenix.protocol.wrappers.EnumWrappers.EntityUseAction)1 DataPacketFlying (fr.neatmonster.nocheatplus.checks.net.model.DataPacketFlying)1 AckReference (fr.neatmonster.nocheatplus.checks.net.model.TeleportQueue.AckReference)1 AlmostBoolean (fr.neatmonster.nocheatplus.compat.AlmostBoolean)1 IWorldData (fr.neatmonster.nocheatplus.worlds.IWorldData)1