use of fr.neatmonster.nocheatplus.players.IPlayerData in project NoCheatPlus by NoCheatPlus.
the class MovingListener method onPlayerToggleFlight.
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = false)
public void onPlayerToggleFlight(final PlayerToggleFlightEvent event) {
// (ignoreCancelled = false: we track the bit of vertical extra momentum/thing).
final Player player = event.getPlayer();
if (player.isFlying() || event.isFlying() && !event.isCancelled()) {
return;
}
final IPlayerData pData = DataManager.getPlayerData(player);
final MovingData data = pData.getGenericInstance(MovingData.class);
final MovingConfig cc = pData.getGenericInstance(MovingConfig.class);
final PlayerMoveInfo moveInfo = aux.usePlayerMoveInfo();
final Location loc = player.getLocation(useLoc);
moveInfo.set(player, loc, null, cc.yOnGround);
// TODO: data.isVelocityJumpPhase() might be too harsh, but prevents too easy abuse.
if (!MovingUtil.shouldCheckSurvivalFly(player, moveInfo.from, data, cc, pData) || data.isVelocityJumpPhase() || BlockProperties.isOnGroundOrResetCond(player, loc, cc.yOnGround)) {
useLoc.setWorld(null);
aux.returnPlayerMoveInfo(moveInfo);
return;
}
aux.returnPlayerMoveInfo(moveInfo);
useLoc.setWorld(null);
// TODO: Configurable.
// TODO: Confine to minimum activation ticks.
data.addVelocity(player, cc, 0.0, 0.3, 0.0);
}
use of fr.neatmonster.nocheatplus.players.IPlayerData in project NoCheatPlus by NoCheatPlus.
the class MovingListener method onPlayerTeleportLowest.
/**
* LOWEST: Checks, indicate cancel processing player move.
*
* @param event
*/
@EventHandler(ignoreCancelled = false, priority = EventPriority.LOWEST)
public void onPlayerTeleportLowest(final PlayerTeleportEvent event) {
final Player player = event.getPlayer();
// Prevent further moving processing for nested events.
processingEvents.remove(player.getName());
// Various early return conditions.
if (event.isCancelled()) {
return;
}
final TeleportCause cause = event.getCause();
switch(cause) {
case COMMAND:
case ENDER_PEARL:
break;
default:
return;
}
final IPlayerData pData = DataManager.getPlayerData(player);
final boolean debug = pData.isDebugActive(checkType);
final MovingData data = pData.getGenericInstance(MovingData.class);
final Location to = event.getTo();
if (to == null) {
// Better cancel this one.
if (!event.isCancelled()) {
if (debug) {
debugTeleportMessage(player, event, "Cancel event, that has no target location (to) set.");
}
event.setCancelled(true);
}
return;
}
if (data.hasTeleported()) {
// More lenient: accept the position.
if (data.isTeleportedPosition(to)) {
return;
} else {
// TODO: Configurable ?
if (debug) {
debugTeleportMessage(player, event, "Prevent teleport, due to a scheduled set back: ", to);
}
event.setCancelled(true);
return;
}
}
// Run checks.
final MovingConfig cc = pData.getGenericInstance(MovingConfig.class);
boolean cancel = false;
// Ender pearl into blocks.
if (cause == TeleportCause.ENDER_PEARL) {
if (pData.getGenericInstance(CombinedConfig.class).enderPearlCheck && !BlockProperties.isPassable(to)) {
// || !BlockProperties.isOnGroundOrResetCond(player, to, 1.0)) {
// Not check on-ground: Check the second throw.
// TODO: Bounding box check or onGround as replacement?
cancel = true;
}
} else // Teleport to untracked locations.
if (cause == TeleportCause.COMMAND) {
// Attempt to prevent teleporting to players inside of blocks at untracked coordinates.
if (cc.passableUntrackedTeleportCheck) {
if (cc.loadChunksOnTeleport) {
MovingUtil.ensureChunksLoaded(player, to, "teleport", data, cc, pData);
}
if (cc.passableUntrackedTeleportCheck && MovingUtil.shouldCheckUntrackedLocation(player, to, pData)) {
final Location newTo = MovingUtil.checkUntrackedLocation(to);
if (newTo != null) {
// Adjust the teleport to go to the last tracked to-location of the other player.
event.setTo(newTo);
// TODO: Consider console, consider debug.
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().warning(Streams.TRACE_FILE, player.getName() + " correct untracked teleport destination (" + to + " corrected to " + newTo + ").");
}
}
}
}
// Handle cancel.
if (cancel) {
// NCP actively prevents this teleport.
event.setCancelled(true);
// Log.
if (debug) {
debug(player, "TP " + cause + " (cancel): " + to);
}
}
}
use of fr.neatmonster.nocheatplus.players.IPlayerData in project NoCheatPlus by NoCheatPlus.
the class MovingListener method onPlayerMove.
/**
* When a player moves, they will be checked for various suspicious behaviors.<br>
* (lowest priority)
*
* @param event
* the event
*/
@EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST)
public void onPlayerMove(final PlayerMoveEvent event) {
counters.add(idMoveEvent, 1);
final Player player = event.getPlayer();
// Store the event for monitor level checks.
processingEvents.put(player.getName(), event);
final IPlayerData pData = DataManager.getPlayerData(player);
final MovingConfig cc = pData.getGenericInstance(MovingConfig.class);
final MovingData data = pData.getGenericInstance(MovingData.class);
data.increasePlayerMoveCount();
/*
* TODO: Check if teleportation is set, verify if scheduled (tick task).
* Early return / adapt, if necessary.
*/
final Location from = event.getFrom();
final Location to = event.getTo();
Location newTo = null;
// // Check problematic yaw/pitch values.
// if (LocUtil.needsDirectionCorrection(from.getYaw(), from.getPitch())
// || LocUtil.needsDirectionCorrection(to.getYaw(), to.getPitch())) {
// DataManager.getPlayerData(player).task.correctDirection();
// }
// TODO: Check illegal moves here anyway (!).
// TODO: Check if vehicle move logs correctly (fake).
// Early return checks (no full processing).
final boolean earlyReturn;
final String token;
if (player.isInsideVehicle()) {
// No full processing for players in vehicles.
newTo = vehicleChecks.onPlayerMoveVehicle(player, from, to, data, pData);
earlyReturn = true;
token = "vehicle";
} else if (player.isDead()) {
// Ignore dead players.
data.sfHoverTicks = -1;
earlyReturn = true;
token = "dead";
} else if (player.isSleeping()) {
// Ignore sleeping playerrs.
// TODO: sleeping: (which cb!) debug(player, "isSleepingIgnored=" + player.isSleepingIgnored());
data.sfHoverTicks = -1;
earlyReturn = true;
token = "sleeping";
} else if (!from.getWorld().equals(to.getWorld())) {
// Keep hover ticks.
// Ignore changing worlds.
earlyReturn = true;
token = "worldchange";
} else if (data.hasTeleported()) {
earlyReturn = handleTeleportedOnMove(player, event, data, cc, pData);
token = "awaitsetback";
} else {
earlyReturn = false;
token = null;
}
final boolean debug = pData.isDebugActive(checkType);
// TODO: Might log base parts here (+extras).
if (earlyReturn) {
// TODO: Log "early return: " + tags.
if (debug) {
debug(player, "Early return" + (token == null ? "" : (" (" + token + ")")) + " on PlayerMoveEvent: from: " + from + " , to: " + to);
}
if (newTo != null) {
// 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()));
}
// Set.
// Logs set back details.
prepareSetBack(player, event, newTo, data, cc, pData);
}
data.joinOrRespawn = false;
return;
}
// newTo should be null here.
// Fire one or two moves here.
final PlayerMoveInfo moveInfo = aux.usePlayerMoveInfo();
final Location loc = player.getLocation(moveInfo.useLoc);
final PlayerMoveData lastMove = data.playerMoves.getFirstPastMove();
if (cc.loadChunksOnMove) {
MovingUtil.ensureChunksLoaded(player, from, to, lastMove, "move", cc, pData);
}
// TODO: On pistons pulling the player back: -1.15 yDistance for split move 1 (untracked position > 0.5 yDistance!).
if (// Handling split moves has been disabled.
!cc.splitMoves || // The usual case: no micro move happened.
TrigUtil.isSamePos(from, loc) || // Special case / bug? TODO: Which/why, which version of MC/spigot?
lastMove.valid && TrigUtil.isSamePos(loc, lastMove.from.getX(), lastMove.from.getY(), lastMove.from.getZ())) // Could also be other envelopes (0.9 velocity upwards), too tedious to research.
// && data.lastYDist < -SurvivalFly.GRAVITY_MIN && data.lastYDist > -SurvivalFly.GRAVITY_MAX - SurvivalFly.GRAVITY_MIN
{
// Fire move from -> to
// (Special case: Location has not been updated last moving event.)
moveInfo.set(player, from, to, cc.yOnGround);
checkPlayerMove(player, from, to, 0, moveInfo, debug, data, cc, pData, event);
} else {
// 1. Process from -> loc.
if (debug) {
debug(player, "Split move 1 (from -> loc):");
}
moveInfo.set(player, from, loc, cc.yOnGround);
if (!checkPlayerMove(player, from, loc, 1, moveInfo, debug, data, cc, pData, event) && processingEvents.containsKey(player.getName())) {
// Between -> set data accordingly (compare: onPlayerMoveMonitor).
onMoveMonitorNotCancelled(player, from, loc, System.currentTimeMillis(), TickTask.getTick(), pData.getGenericInstance(CombinedData.class), data, cc, pData);
data.joinOrRespawn = false;
// 2. Process loc -> to.
if (debug) {
debug(player, "Split move 2 (loc -> to):");
}
moveInfo.set(player, loc, to, cc.yOnGround);
checkPlayerMove(player, loc, to, 2, moveInfo, debug, data, cc, pData, event);
}
}
// Cleanup.
data.joinOrRespawn = false;
aux.returnPlayerMoveInfo(moveInfo);
}
use of fr.neatmonster.nocheatplus.players.IPlayerData in project NoCheatPlus by NoCheatPlus.
the class MovingListener method onPlayerPortal.
/**
* When a player uses a portal, all information related to the moving checks becomes invalid.
*
* @param event
* the event
*/
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public void onPlayerPortal(final PlayerPortalEvent event) {
final Location to = event.getTo();
final IPlayerData pData = DataManager.getPlayerData(event.getPlayer());
final MovingData data = pData.getGenericInstance(MovingData.class);
if (pData.isDebugActive(checkType)) {
debug(event.getPlayer(), "[PORTAL] to=" + to);
}
if (to != null) {
// TODO: This should be redundant, might remove anyway.
// TODO: Rather add something like setLatencyImmunity(...ms / conditions).
data.clearMostMovingCheckData();
}
}
use of fr.neatmonster.nocheatplus.players.IPlayerData in project NoCheatPlus by NoCheatPlus.
the class MovingListener method playerLeaves.
@Override
public void playerLeaves(final Player player) {
final IPlayerData pData = DataManager.getPlayerData(player);
final MovingData data = pData.getGenericInstance(MovingData.class);
final Location loc = player.getLocation(useLoc);
// Debug logout.
if (pData.isDebugActive(checkType)) {
StaticLog.logInfo("Player " + player.getName() + " leaves at location: " + loc.toString());
}
if (!player.isSleeping() && !player.isDead()) {
// TODO: Consider to catch all, at least (debug-) logging-wise.
if (!BlockProperties.isPassable(loc)) {
final PlayerMoveData lastMove = data.playerMoves.getFirstPastMove();
if (lastMove.toIsValid) {
final Location refLoc = new Location(loc.getWorld(), lastMove.to.getX(), lastMove.to.getY(), lastMove.to.getZ());
final double d = refLoc.distanceSquared(loc);
if (d > 0.0) {
// TODO: Consider to always set back here. Might skip on big distances.
if (TrigUtil.manhattan(loc, refLoc) > 0 || BlockProperties.isPassable(refLoc)) {
if (passable.isEnabled(player, pData)) {
StaticLog.logWarning("Potential exploit: Player " + player.getName() + " leaves, having moved into a block (not tracked by moving checks): " + player.getWorld().getName() + " / " + DebugUtil.formatMove(refLoc, loc));
// TODO: Actually trigger a passable violation (+tag).
if (d > 1.25) {
StaticLog.logWarning("SKIP set back for " + player.getName() + ", because distance is too high (risk of false positives): " + d);
} else {
StaticLog.logInfo("Set back player " + player.getName() + ": " + LocUtil.simpleFormat(refLoc));
data.prepareSetBack(refLoc);
if (!player.teleport(refLoc, BridgeMisc.TELEPORT_CAUSE_CORRECTION_OF_POSITION)) {
StaticLog.logWarning("FAILED to set back player " + player.getName());
}
}
}
}
}
}
}
}
useLoc.setWorld(null);
// Adjust data.
survivalFly.setReallySneaking(player, false);
noFall.onLeave(player, data, pData);
// TODO: Add a method for ordinary presence-change resetting (use in join + leave).
data.onPlayerLeave();
if (data.vehicleSetBackTaskId != -1) {
// Reset the id, assume the task will still teleport the vehicle.
// TODO: Should rather force teleport (needs storing the task + data).
data.vehicleSetBackTaskId = -1;
}
}
Aggregations