Search in sources :

Example 1 with CountableLocation

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

the class MovingUtil method processStoredSetBack.

/**
 * @param player
 * @param debugMessagePrefix
 * @return True, if the teleport has been successful.
 */
public static boolean processStoredSetBack(final Player player, final String debugMessagePrefix, final IPlayerData pData) {
    final MovingData data = pData.getGenericInstance(MovingData.class);
    final boolean debug = pData.isDebugActive(CheckType.MOVING);
    if (!data.hasTeleported()) {
        if (debug) {
            CheckUtils.debug(player, CheckType.MOVING, debugMessagePrefix + "No stored location available.");
        }
        return false;
    }
    // (teleported is set.).
    final Location loc = player.getLocation(useLoc);
    if (data.isTeleportedPosition(loc)) {
        // Skip redundant teleport.
        if (debug) {
            CheckUtils.debug(player, CheckType.MOVING, debugMessagePrefix + "Skip teleport, player is there, already.");
        }
        // Not necessary to keep.
        data.resetTeleported();
        useLoc.setWorld(null);
        return false;
    }
    useLoc.setWorld(null);
    // (player is somewhere else.)
    // Post-1.9 packet level workaround.
    final MovingConfig cc = pData.getGenericInstance(MovingConfig.class);
    // TODO: Consider to skip checking for packet level, if not available (plus optimize access).
    // TODO: Consider a config flag, so this can be turned off (set back method).
    final PlayerSetBackMethod method = cc.playerSetBackMethod;
    if (!method.shouldNoRisk() && (method.shouldCancel() || method.shouldSetTo()) && method.shouldUpdateFrom()) {
        /*
             * Another leniency option: Skip, if we have already received an ACK
             * for this position on packet level - typically the next move would
             * confirm the set-back, but a redundant teleport would freeze the
             * player for a slightly longer time. This could happen with the set
             * back being at the coordinates the player had just been at, but
             * between set back and on-tick there has been a micro move (not
             * firing a PlayerMoveEvent) - similarly observed on a local test
             * server once, HOWEVER there the micro move had been a look-only
             * packet, not explaining why the position of the player wasn't
             * reflecting the outgoing position. So here remains the uncertainty
             * concerning the question if a (silent) Minecraft entity teleport
             * always follows a cancelled PlayerMoveEvent (!), and a thinkable
             * potential for abuse.
             */
        // (CANCEL + UPDATE_FROM mean a certain teleport to the set back, still could be repeated tp.)
        // TODO: Better method, full sync reference?
        final CountableLocation cl = pData.getGenericInstance(NetData.class).teleportQueue.getLastAck();
        if (data.isTeleportedPosition(cl)) {
            if (debug) {
                CheckUtils.debug(player, CheckType.MOVING, debugMessagePrefix + "Skip teleport, having received an ACK for the teleport on packet level. Player is at: " + LocUtil.simpleFormat(loc));
            }
            // Keep teleported in data. Subject to debug logs and/or discussion.
            return false;
        }
    }
    // (No ACK received yet.)
    // Attempt to teleport.
    final Location teleported = data.getTeleported();
    // (Data resetting is done during PlayerTeleportEvent handling.)
    if (player.teleport(teleported, BridgeMisc.TELEPORT_CAUSE_CORRECTION_OF_POSITION)) {
        return true;
    } else {
        if (debug) {
            CheckUtils.debug(player, CheckType.MOVING, "Player set back on tick: Teleport failed.");
        }
        return false;
    }
}
Also used : MovingData(fr.neatmonster.nocheatplus.checks.moving.MovingData) CountableLocation(fr.neatmonster.nocheatplus.checks.net.model.CountableLocation) MovingConfig(fr.neatmonster.nocheatplus.checks.moving.MovingConfig) PlayerSetBackMethod(fr.neatmonster.nocheatplus.checks.moving.player.PlayerSetBackMethod) CountableLocation(fr.neatmonster.nocheatplus.checks.net.model.CountableLocation) PlayerLocation(fr.neatmonster.nocheatplus.utilities.location.PlayerLocation) RichBoundsLocation(fr.neatmonster.nocheatplus.utilities.location.RichBoundsLocation) Location(org.bukkit.Location)

Example 2 with CountableLocation

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

the class OutgoingPosition method interpretPacket.

private void interpretPacket(final Player player, final PacketContainer packet, final long time, final NetData data, final boolean debug) {
    final StructureModifier<Double> doubles = packet.getDoubles();
    final StructureModifier<Float> floats = packet.getFloat();
    if (doubles.size() != 3 || floats.size() != 2) {
        packetMismatch(packet);
        return;
    }
    // TODO: Detect/skip data with relative coordinates.
    // TODO: Concept: force KeepAlive vs. set expected coordinates in Bukkit events.
    final double x = doubles.read(indexX);
    final double y = doubles.read(indexY);
    final double z = doubles.read(indexZ);
    final float yaw = floats.read(indexYaw);
    final float pitch = floats.read(indexPitch);
    Integer teleportId = Integer.MIN_VALUE;
    if (hasTeleportId) {
        try {
            final StructureModifier<Integer> integers = packet.getIntegers();
            if (integers.size() == 1) {
                // Accept as id.
                teleportId = integers.read(0);
                if (teleportId == null) {
                    teleportId = Integer.MIN_VALUE;
                }
                if (teleportId != Integer.MIN_VALUE && debug) {
                    debug(player, "Outgoing confirm teleport id: " + teleportId);
                }
            } else {
                hasTeleportId = false;
                NCPAPIProvider.getNoCheatPlusAPI().getLogManager().info(Streams.STATUS, "PacketPlayOutPosition: Teleport confirm id not available, field mismatch: " + integers.size());
            }
        } catch (Throwable t) {
            hasTeleportId = false;
            NCPAPIProvider.getNoCheatPlusAPI().getLogManager().info(Streams.STATUS, "PacketPlayOutPosition: Teleport confirm id not available.");
        }
    }
    final CountableLocation packetData = data.teleportQueue.onOutgoingTeleport(x, y, z, yaw, pitch, teleportId);
    if (packetData == null) {
        // Add counter for untracked (by Bukkit API) outgoing teleport.
        // TODO: There may be other cases which are indicated by Bukkit API events.
        counters.add(ID_OUTGOING_POSITION_UNTRACKED, 1);
        if (debug) {
            debug(player, "Untracked outgoing position: " + x + ", " + y + ", " + z + " (yaw=" + yaw + ", pitch=" + pitch + ").");
        }
    } else {
        if (debug) {
            debug(player, "Expect ACK on outgoing position: " + packetData);
        }
    }
}
Also used : CountableLocation(fr.neatmonster.nocheatplus.checks.net.model.CountableLocation)

Aggregations

CountableLocation (fr.neatmonster.nocheatplus.checks.net.model.CountableLocation)2 MovingConfig (fr.neatmonster.nocheatplus.checks.moving.MovingConfig)1 MovingData (fr.neatmonster.nocheatplus.checks.moving.MovingData)1 PlayerSetBackMethod (fr.neatmonster.nocheatplus.checks.moving.player.PlayerSetBackMethod)1 PlayerLocation (fr.neatmonster.nocheatplus.utilities.location.PlayerLocation)1 RichBoundsLocation (fr.neatmonster.nocheatplus.utilities.location.RichBoundsLocation)1 Location (org.bukkit.Location)1