Search in sources :

Example 1 with MovingData

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

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

the class VehicleChecks method onPlayerVehicleEnter.

/**
 * Assume entering a vehicle, event or join with being inside a vehicle. Set
 * back and past move overriding are done here, performing the necessary
 * consistency checking. Because teleporting players with their vehicle
 * means exit + teleport + re-enter, vehicle data should not be reset on
 * player teleportation.
 *
 * @param player
 * @param vehicle
 * @return True, if an event is to be cancelled.
 */
public boolean onPlayerVehicleEnter(final Player player, final Entity vehicle) {
    final IPlayerData pData = DataManager.getPlayerData(player);
    final boolean debug = pData.isDebugActive(checkType);
    final MovingData data = pData.getGenericInstance(MovingData.class);
    if (!data.isVehicleSetBack && MovingUtil.hasScheduledPlayerSetBack(player.getUniqueId(), data)) {
        if (debug) {
            debug(player, "Vehicle enter: prevent, due to a scheduled set back.");
        }
        return true;
    }
    if (debug) {
        debug(player, "Vehicle enter: first vehicle: " + vehicle.getClass().getName());
    }
    // Check for nested vehicles.
    final Entity lastVehicle = passengerUtil.getLastNonPlayerVehicle(vehicle, true);
    if (lastVehicle == null) {
        data.clearVehicleData();
        if (debug) {
            debugNestedVehicleEnter(player);
        }
        return false;
    } else if (!lastVehicle.equals(vehicle)) {
        // TODO: Should in general skip checking these? Set backs don't yet work with these anyway (either... or ...).
        if (debug) {
            debug(player, "Vehicle enter: last of nested vehicles: " + lastVehicle.getClass().getName());
        }
        dataOnVehicleEnter(player, lastVehicle, data, pData);
    } else {
        // Proceed normally.
        dataOnVehicleEnter(player, vehicle, data, pData);
    }
    return false;
}
Also used : Entity(org.bukkit.entity.Entity) MovingData(fr.neatmonster.nocheatplus.checks.moving.MovingData) IPlayerData(fr.neatmonster.nocheatplus.players.IPlayerData)

Example 3 with MovingData

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

the class VehicleChecks method onPlayerVehicleLeave.

/**
 * Call on leaving or just having left a vehicle.
 * @param player
 * @param vehicle May be null in case of "not possible to determine".
 */
private void onPlayerVehicleLeave(final Player player, final Entity vehicle) {
    final IPlayerData pData = DataManager.getPlayerData(player);
    final MovingData data = pData.getGenericInstance(MovingData.class);
    final boolean debug = pData.isDebugActive(checkType);
    data.wasInVehicle = false;
    data.joinOrRespawn = false;
    // if (data.vehicleSetBackTaskId != -1) {
    // // Await set back.
    // // TODO: might still set ordinary set backs ?
    // return;
    // }
    final MovingConfig cc = pData.getGenericInstance(MovingConfig.class);
    // TODO: Loc can be inconsistent, determine which to use !
    final Location pLoc = player.getLocation(useLoc1);
    // The location to use as set back.
    Location loc = pLoc;
    // final Entity vehicle = player.getVehicle();
    if (vehicle != null) {
        final Location vLoc = vehicle.getLocation(useLoc2);
        // Workaround for some entities/animals that don't fire VehicleMoveEventS.
        if (!normalVehicles.contains(vehicle.getType()) || cc.noFallVehicleReset) {
            // Might allow one time cheat.
            data.noFallSkipAirCheck = true;
            data.clearNoFallData();
        }
        // Check consistency with vehicle location.
        if (MoveConsistency.getConsistency(vLoc, null, pLoc) == MoveConsistency.INCONSISTENT) {
            // TODO: Consider teleporting the player (...)
            // TODO: What with the case of vehicle moved to another world !?
            // 
            loc = vLoc;
            if (data.vehicleConsistency != MoveConsistency.INCONSISTENT) {
                // TODO: This may need re-setting on player move -> vehicle move.
                final PlayerMoveData lastMove = data.playerMoves.getFirstPastMove();
                if (lastMove.toIsValid) {
                    final Location oldLoc = new Location(pLoc.getWorld(), lastMove.to.getX(), lastMove.to.getY(), lastMove.to.getZ());
                    if (MoveConsistency.getConsistency(oldLoc, null, pLoc) != MoveConsistency.INCONSISTENT) {
                        loc = oldLoc;
                    }
                }
            }
        }
        if (debug) {
            debug(player, "Vehicle leave: " + vehicle.getType() + "@" + pLoc.distance(vLoc));
        }
    }
    // Adjust loc if in liquid (meant for boats !?).
    if (BlockProperties.isLiquid(loc.getBlock().getType())) {
        loc.setY(Location.locToBlock(loc.getY()) + 1.25);
    }
    if (debug) {
        debug(player, "Vehicle leave: " + pLoc.toString() + (pLoc.equals(loc) ? "" : " / player at: " + pLoc.toString()));
    }
    aux.resetPositionsAndMediumProperties(player, loc, data, cc);
    data.setSetBack(loc);
    // Give some freedom to allow the "exiting move".
    data.removeAllVelocity();
    // TODO: Use-once entries usually are intended to allow one offset, but not jumping/flying on.
    data.addHorizontalVelocity(new AccountEntry(0.9, 1, 1));
    // TODO: Typical margin?
    data.addVerticalVelocity(new SimpleEntry(0.6, 1));
    useLoc1.setWorld(null);
    useLoc2.setWorld(null);
}
Also used : MovingData(fr.neatmonster.nocheatplus.checks.moving.MovingData) PlayerMoveData(fr.neatmonster.nocheatplus.checks.moving.model.PlayerMoveData) SimpleEntry(fr.neatmonster.nocheatplus.checks.moving.velocity.SimpleEntry) IPlayerData(fr.neatmonster.nocheatplus.players.IPlayerData) MovingConfig(fr.neatmonster.nocheatplus.checks.moving.MovingConfig) AccountEntry(fr.neatmonster.nocheatplus.checks.moving.velocity.AccountEntry) Location(org.bukkit.Location) RichBoundsLocation(fr.neatmonster.nocheatplus.utilities.location.RichBoundsLocation)

Example 4 with MovingData

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

the class VehicleChecks method onVehicleMove.

/**
 * When a vehicle moves, its player will be checked for various suspicious behaviors.
 *
 * @param event
 *            the event
 */
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onVehicleMove(final VehicleMoveEvent event) {
    // Check data.
    final Vehicle vehicle = event.getVehicle();
    if (vehicle == null) {
        return;
    }
    // Mind that players could be riding horses inside of minecarts etc.
    if (vehicle.getVehicle() != null) {
        // Do ignore events for vehicles inside of other vehicles.
        return;
    }
    final Player player = passengerUtil.getFirstPlayerPassenger(vehicle);
    if (player == null) {
        return;
    }
    if (vehicle.isDead() || !vehicle.isValid()) {
        // TODO: Actually force dismount?
        onPlayerVehicleLeave(player, vehicle);
        return;
    }
    final EntityType vehicleType = vehicle.getType();
    final IPlayerData pData = DataManager.getPlayerData(player);
    final MovingData data = pData.getGenericInstance(MovingData.class);
    final Location from = event.getFrom();
    final Location to = event.getTo();
    if (pData.isDebugActive(checkType)) {
        outputDebugVehicleMoveEvent(player, from, to);
    }
    if (from == null) {
        // TODO: (In case update doesn't, could fake it here.)
        return;
    } else if (from.equals(to)) {
    // Not possible by obc code.
    } else {
        if (!from.getWorld().equals(to.getWorld())) {
            // TODO: Data adjustments will be necessary with the envelope check.
            return;
        }
    // TODO: Check consistency with assumed/tracked past position, both for from and to. Do something based on result.
    }
    if (normalVehicles.contains(vehicleType)) {
        // Assume handled.
        return;
    } else {
    // Should not be possible, unless plugins somehow force this.
    // TODO: Log warning once / what?
    // TODO: Ignore or continue?
    }
    // Process as move.
    final boolean debug = pData.isDebugActive(checkType);
    if (debug) {
        debug(player, "VehicleMoveEvent: legacy handling, potential issue.");
    }
    // TODO: Actually here consistency with past position tracking should be tested.
    // TODO: Abstraction creation before calling checkVehicleMove, compare/align with onVehicleUpdate.
    checkVehicleMove(vehicle, vehicleType, from, to, player, false, data, pData, debug);
}
Also used : Vehicle(org.bukkit.entity.Vehicle) EntityType(org.bukkit.entity.EntityType) Player(org.bukkit.entity.Player) MovingData(fr.neatmonster.nocheatplus.checks.moving.MovingData) IPlayerData(fr.neatmonster.nocheatplus.players.IPlayerData) Location(org.bukkit.Location) RichBoundsLocation(fr.neatmonster.nocheatplus.utilities.location.RichBoundsLocation) EventHandler(org.bukkit.event.EventHandler)

Example 5 with MovingData

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

the class BlockInteractListener method onPlayerInteractMonitor.

@EventHandler(ignoreCancelled = false, priority = EventPriority.MONITOR)
public void onPlayerInteractMonitor(final PlayerInteractEvent event) {
    // Set event resolution.
    final Player player = event.getPlayer();
    final IPlayerData pData = DataManager.getPlayerData(player);
    final BlockInteractData data = pData.getGenericInstance(BlockInteractData.class);
    data.setPlayerInteractEventResolution(event);
    // }
    if ((event.getAction() == Action.RIGHT_CLICK_AIR) && event.isCancelled() && event.useItemInHand() != Result.DENY) {
        final ItemStack stack = Bridge1_9.getUsedItem(player, event);
        if (stack != null && BridgeMisc.maybeElytraBoost(player, stack.getType())) {
            final int power = BridgeMisc.getFireworksPower(stack);
            final MovingData mData = pData.getGenericInstance(MovingData.class);
            final int ticks = Math.max((1 + power) * 20, 30);
            mData.fireworksBoostDuration = ticks;
            // Expiration tick: not general latency, rather a minimum margin for sudden congestion.
            mData.fireworksBoostTickExpire = TickTask.getTick() + ticks;
            // TODO: Implement using it in CreativeFly.
            if (pData.isDebugActive(CheckType.MOVING)) {
                debug(player, "Elytra boost (power " + power + "): " + stack);
            }
        }
    }
}
Also used : Player(org.bukkit.entity.Player) MovingData(fr.neatmonster.nocheatplus.checks.moving.MovingData) IPlayerData(fr.neatmonster.nocheatplus.players.IPlayerData) ItemStack(org.bukkit.inventory.ItemStack) EventHandler(org.bukkit.event.EventHandler)

Aggregations

MovingData (fr.neatmonster.nocheatplus.checks.moving.MovingData)13 IPlayerData (fr.neatmonster.nocheatplus.players.IPlayerData)7 Player (org.bukkit.entity.Player)7 Location (org.bukkit.Location)6 MovingConfig (fr.neatmonster.nocheatplus.checks.moving.MovingConfig)5 RichBoundsLocation (fr.neatmonster.nocheatplus.utilities.location.RichBoundsLocation)5 Entity (org.bukkit.entity.Entity)4 PlayerMoveData (fr.neatmonster.nocheatplus.checks.moving.model.PlayerMoveData)3 EventHandler (org.bukkit.event.EventHandler)3 PlayerMoveInfo (fr.neatmonster.nocheatplus.checks.moving.model.PlayerMoveInfo)2 CountableLocation (fr.neatmonster.nocheatplus.checks.net.model.CountableLocation)2 PlayerLocation (fr.neatmonster.nocheatplus.utilities.location.PlayerLocation)2 EntityType (org.bukkit.entity.EntityType)2 Vehicle (org.bukkit.entity.Vehicle)2 ViolationData (fr.neatmonster.nocheatplus.checks.ViolationData)1 LocationTrace (fr.neatmonster.nocheatplus.checks.moving.location.tracking.LocationTrace)1 PlayerSetBackMethod (fr.neatmonster.nocheatplus.checks.moving.player.PlayerSetBackMethod)1 AccountEntry (fr.neatmonster.nocheatplus.checks.moving.velocity.AccountEntry)1 SimpleEntry (fr.neatmonster.nocheatplus.checks.moving.velocity.SimpleEntry)1 IDebugPlayer (fr.neatmonster.nocheatplus.components.debug.IDebugPlayer)1