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;
}
}
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;
}
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);
}
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);
}
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);
}
}
}
}
Aggregations