use of fr.neatmonster.nocheatplus.checks.moving.model.PlayerMoveInfo 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.checks.moving.model.PlayerMoveInfo 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.checks.moving.model.PlayerMoveInfo in project NoCheatPlus by NoCheatPlus.
the class MovingListener method onPlayerBedLeave.
/**
* We listen to this event to prevent player from flying by sending bed leaving packets.
*
* @param event
* the event
*/
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerBedLeave(final PlayerBedLeaveEvent event) {
final Player player = event.getPlayer();
final IPlayerData pData = DataManager.getPlayerData(player);
if (pData.isCheckActive(bedLeave.getType(), player) && bedLeave.checkBed(player, pData)) {
final MovingConfig cc = pData.getGenericInstance(MovingConfig.class);
// Check if the player has to be reset.
// To "cancel" the event, we teleport the player.
final Location loc = player.getLocation(useLoc);
final MovingData data = pData.getGenericInstance(MovingData.class);
Location target = null;
final PlayerMoveInfo moveInfo = aux.usePlayerMoveInfo();
moveInfo.set(player, loc, null, cc.yOnGround);
final boolean sfCheck = MovingUtil.shouldCheckSurvivalFly(player, moveInfo.from, data, cc, pData);
aux.returnPlayerMoveInfo(moveInfo);
if (sfCheck) {
target = MovingUtil.getApplicableSetBackLocation(player, loc.getYaw(), loc.getPitch(), moveInfo.from, data, cc);
}
if (target == null) {
// TODO: Add something to guess the best set back location (possibly data.guessSetBack(Location)).
target = LocUtil.clone(loc);
}
if (sfCheck && cc.sfSetBackPolicyFallDamage && noFall.isEnabled(player, pData)) {
// Check if to deal damage.
double y = loc.getY();
if (data.hasSetBack()) {
y = Math.min(y, data.getSetBackY());
}
noFall.checkDamage(player, y, data, pData);
}
// Cleanup
useLoc.setWorld(null);
// Teleport.
// Should be enough. | new Location(target.getWorld(), target.getX(), target.getY(), target.getZ(), target.getYaw(), target.getPitch());
data.prepareSetBack(target);
// TODO: schedule / other measures ?
player.teleport(target, BridgeMisc.TELEPORT_CAUSE_CORRECTION_OF_POSITION);
} else {
// Reset bed ...
pData.getGenericInstance(CombinedData.class).wasInBed = false;
}
}
use of fr.neatmonster.nocheatplus.checks.moving.model.PlayerMoveInfo in project NoCheatPlus by NoCheatPlus.
the class MovingListener method confirmSetBack.
/**
* A set back has been performed, or applying it got through to
* EventPriority.MONITOR.
*
* @param player
* @param fakeNews
* True, iff it's not really been applied yet (, but should get
* applied, due to reaching EventPriority.MONITOR).
* @param data
* @param cc
*/
private void confirmSetBack(final Player player, final boolean fakeNews, final MovingData data, final MovingConfig cc, final IPlayerData pData) {
final Location teleported = data.getTeleported();
final PlayerMoveInfo moveInfo = aux.usePlayerMoveInfo();
moveInfo.set(player, teleported, null, cc.yOnGround);
if (cc.loadChunksOnTeleport) {
MovingUtil.ensureChunksLoaded(player, teleported, "teleport", data, cc, pData);
}
data.onSetBack(moveInfo.from);
aux.returnPlayerMoveInfo(moveInfo);
// Reset stuff.
Combined.resetYawRate(player, teleported.getYaw(), System.currentTimeMillis(), true, // TODO: Not sure.
pData);
data.resetTeleported();
}
use of fr.neatmonster.nocheatplus.checks.moving.model.PlayerMoveInfo in project NoCheatPlus by NoCheatPlus.
the class MovingListener method checkHover.
/**
* The heavier checking including on.ground etc., check if enabled/valid to check before this.
* @param player
* @param data
* @param cc
* @param info
* @return
*/
private boolean checkHover(final Player player, final MovingData data, final MovingConfig cc, final IPlayerData pData, final PlayerMoveInfo info) {
// Check if player is on ground.
// useLoc.setWorld(null) is done in onTick.
final Location loc = player.getLocation(useLoc);
info.set(player, loc, null, cc.yOnGround);
// (Could use useLoc of MoveInfo here. Note orderm though.)
final boolean res;
// TODO: Collect flags, more margin ?
final int loaded = info.from.ensureChunksLoaded();
if (loaded > 0 && pData.isDebugActive(checkType)) {
// DEBUG
StaticLog.logInfo("Hover check: Needed to load " + loaded + " chunk" + (loaded == 1 ? "" : "s") + " for the world " + loc.getWorld().getName() + " around " + loc.getBlockX() + "," + loc.getBlockZ() + " in order to check player: " + player.getName());
}
if (info.from.isOnGroundOrResetCond() || info.from.isAboveLadder() || info.from.isAboveStairs()) {
res = true;
data.sfHoverTicks = 0;
} else {
if (data.sfHoverTicks > cc.sfHoverTicks) {
// Re-Check if survivalfly can apply at all.
final PlayerMoveInfo moveInfo = aux.usePlayerMoveInfo();
moveInfo.set(player, loc, null, cc.yOnGround);
if (MovingUtil.shouldCheckSurvivalFly(player, moveInfo.from, data, cc, pData)) {
handleHoverViolation(player, moveInfo.from, cc, data, pData);
// Assume the player might still be hovering.
res = false;
data.sfHoverTicks = 0;
} else {
// Reset hover ticks and check next period.
res = false;
data.sfHoverTicks = 0;
}
aux.returnPlayerMoveInfo(moveInfo);
} else {
res = false;
}
}
info.cleanup();
return res;
}
Aggregations