Search in sources :

Example 1 with PlayerSetBackMethod

use of fr.neatmonster.nocheatplus.checks.moving.player.PlayerSetBackMethod 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 PlayerSetBackMethod

use of fr.neatmonster.nocheatplus.checks.moving.player.PlayerSetBackMethod in project NoCheatPlus by NoCheatPlus.

the class MovingListener method onCancelledMove.

/**
 * Adjust data for a cancelled move. No teleport event will fire, but an
 * outgoing position is sent. Note that event.getFrom() may be overridden by
 * a plugin, which the server will ignore, but can lead to confusion.
 *
 * @param player
 * @param from
 * @param tick
 * @param now
 * @param mData
 * @param data
 */
private void onCancelledMove(final Player player, final Location from, final int tick, final long now, final MovingData mData, final MovingConfig mCc, final CombinedData data, final IPlayerData pData) {
    final boolean debug = pData.isDebugActive(checkType);
    // Detect our own set back, choice of reference location.
    if (mData.hasTeleported()) {
        final Location ref = mData.getTeleported();
        // Initiate further action depending on settings.
        final PlayerSetBackMethod method = mCc.playerSetBackMethod;
        if (method.shouldUpdateFrom()) {
            // Attempt to do without a PlayerTeleportEvent as follow up.
            // TODO: Doing this on MONITOR priority is problematic, despite optimal.
            LocUtil.set(from, ref);
        }
        if (method.shouldSchedule()) {
            // Schedule the teleport, because it might be faster than the next incoming packet.
            final IPlayerData pd = DataManager.getPlayerData(player);
            if (pd.isPlayerSetBackScheduled()) {
                debug(player, "Teleport (set back) already scheduled to: " + ref);
            } else if (debug) {
                pd.requestPlayerSetBack();
                if (debug) {
                    debug(player, "Schedule teleport (set back) to: " + ref);
                }
            }
        }
    // (Position adaption will happen with the teleport on tick, or with the next move.)
    }
    // Assume the implicit teleport to the from-location (no Bukkit event fires).
    // Not reset frequency, but do set yaw.
    Combined.resetYawRate(player, from.getYaw(), now, false, pData);
    aux.resetPositionsAndMediumProperties(player, from, mData, mCc);
    // TODO: Should probably leave this to the teleport event!
    mData.resetTrace(player, from, tick, mcAccess.getHandle(), mCc);
    // Expect a teleport to the from location (packet balance, no Bukkit event will fire).
    if (pData.isCheckActive(CheckType.NET_FLYINGFREQUENCY, player)) {
        // TODO: A summary method.
        pData.getGenericInstance(NetData.class).teleportQueue.onTeleportEvent(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch());
    }
}
Also used : IPlayerData(fr.neatmonster.nocheatplus.players.IPlayerData) PlayerSetBackMethod(fr.neatmonster.nocheatplus.checks.moving.player.PlayerSetBackMethod) PlayerLocation(fr.neatmonster.nocheatplus.utilities.location.PlayerLocation) Location(org.bukkit.Location)

Example 3 with PlayerSetBackMethod

use of fr.neatmonster.nocheatplus.checks.moving.player.PlayerSetBackMethod in project NoCheatPlus by NoCheatPlus.

the class MovingListener method prepareSetBack.

/**
 * Called during PlayerMoveEvent for adjusting to a to-be-done/scheduled set
 * back. <br>
 * NOTE: Meaning differs from data.onSetBack (to be cleaned up).
 *
 * @param player
 * @param event
 * @param newTo
 *            Must be a cloned or new Location instance, free for whatever
 *            other plugins do with it.
 * @param data
 * @param cc
 */
private void prepareSetBack(final Player player, final PlayerMoveEvent event, final Location newTo, final MovingData data, final MovingConfig cc, final IPlayerData pData) {
    // Illegal Yaw/Pitch.
    if (LocUtil.needsYawCorrection(newTo.getYaw())) {
        newTo.setYaw(LocUtil.correctYaw(newTo.getYaw()));
    }
    if (LocUtil.needsPitchCorrection(newTo.getPitch())) {
        newTo.setPitch(LocUtil.correctPitch(newTo.getPitch()));
    }
    // Reset some data.
    data.prepareSetBack(newTo);
    // TODO: Might move into prepareSetBack, experimental here.
    aux.resetPositionsAndMediumProperties(player, newTo, data, cc);
    // Set new to-location, distinguish method by settings.
    final PlayerSetBackMethod method = cc.playerSetBackMethod;
    if (method.shouldSetTo()) {
        // LEGACY: pre-2017-03-24
        event.setTo(newTo);
    }
    if (method.shouldCancel()) {
        event.setCancelled(true);
    }
    // Debug.
    if (pData.isDebugActive(checkType)) {
        debug(player, "Prepare set back to: " + newTo.getWorld().getName() + "/" + LocUtil.simpleFormatPosition(newTo) + " (" + method.getId() + ")");
    }
}
Also used : PlayerSetBackMethod(fr.neatmonster.nocheatplus.checks.moving.player.PlayerSetBackMethod)

Aggregations

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