[BLEEDING][BREAKING] Player move set back: cancel event + schedule TP.

Because Spigot changed to fire the teleport following an altered move
end point with TeleportCause.PLUGIN, we have to alter set back handling,
so we can ensure to keep TeleportCause.UNKNOWN for setting back players.

Instead of altering the move end point, the event is just cancelled, and
a teleport is scheduled (with a dedicated TickTask method). Uncancelled
moving events mean removing scheduled teleports.

[BLEEDING]
* Comparably simple change - more places and special cases may still be
uncovered.

[BREAKING]
* Plugins that may rely on the exact sequence of things within NCP, as
it used to be.

Random
* Change "set-back" to "set back" everywhere for simplicity, and to
obfuscate the actual code changes.
* Set backs are now going through MovingListener.onCancelledMove instead
of MovingListener.onMoveMonitorNotCancelled.
* Illegal move handling would still use event.setTo.
This commit is contained in:
asofold 2017-04-02 15:01:23 +02:00
parent 8b3dcff7c4
commit c5e1f6ba2b
23 changed files with 305 additions and 160 deletions

View File

@ -30,7 +30,7 @@ public class BedLeave extends Check {
*
* @param player
* the player
* @return If to prevent action (would be set back location of survivalfly).
* @return If to prevent action (use the set back location of survivalfly).
*/
public boolean checkBed(final Player player) {
final CombinedData data = CombinedData.getData(player);

View File

@ -177,16 +177,16 @@ public class MovingData extends ACheckData {
public float walkSpeed = 0.0f;
public float flySpeed = 0.0f;
/** Count set-back (re-) setting. */
/** Count set back (re-) setting. */
private int setBackResetCount = 0;
/**
* setBackResetCount (incremented) at the time of (re-) setting the ordinary
* set-back.
* set back.
*/
private int setBackResetTime = 0;
/**
* setBackResetCount (incremented) at the time of (re-) setting the
* morepackets set-back.
* morepackets set back.
*/
private int morePacketsSetBackResetTime = 0;
@ -320,7 +320,7 @@ public class MovingData extends ACheckData {
// HOT FIX / WORKAROUND
/**
* Set to true after login/respawn, only if the set-back is reset there.
* Set to true after login/respawn, only if the set back is reset there.
* Reset in MovingListener after handling PlayerMoveEvent
*/
public boolean joinOrRespawn = false;
@ -330,8 +330,8 @@ public class MovingData extends ACheckData {
*/
public int timeSinceSetBack = 0;
/**
* Location hash value of the last (player/vehicle) set-back, for checking
* independently of which set-back location had been used.
* Location hash value of the last (player/vehicle) set back, for checking
* independently of which set back location had been used.
*/
public int lastSetBackHash = 0;
@ -351,7 +351,7 @@ public class MovingData extends ACheckData {
// Data of the more packets vehicle check.
public int vehicleMorePacketsBuffer = vehicleMorePacketsBufferDefault;
public long vehicleMorePacketsLastTime;
/** Task id of the vehicle set-back task. */
/** Task id of the vehicle set back task. */
public int vehicleSetBackTaskId = -1;
public MovingData(final MovingConfig config) {
@ -443,8 +443,8 @@ public class MovingData extends ACheckData {
// Reset to setBack.
resetPlayerPositions(setBack);
adjustMediumProperties(setBack);
setSetBack(setBack); // Problematic with multiple set-back locations stored (currently the safe-medium one is preferred, but later...)
// vehicleSetBacks.resetAllLazily(setBack); // Not good: Overrides older set-back locations.
setSetBack(setBack); // Problematic with multiple set back locations stored (currently the safe-medium one is preferred, but later...)
// vehicleSetBacks.resetAllLazily(setBack); // Not good: Overrides older set back locations.
}
/**
@ -614,7 +614,7 @@ public class MovingData extends ACheckData {
}
/**
* Set the set-back location, this will also adjust the y-coordinate for some block types (at least air).
* Set the set back location, this will also adjust the y-coordinate for some block types (at least air).
* @param loc
*/
public void setSetBack(final PlayerLocation loc) {
@ -624,7 +624,7 @@ public class MovingData extends ACheckData {
else{
LocUtil.set(setBack, loc);
}
// TODO: Consider adjusting the set-back-y here. Problem: Need to take into account for bounding box (collect max-ground-height needed).
// TODO: Consider adjusting the set back-y here. Problem: Need to take into account for bounding box (collect max-ground-height needed).
setBackResetTime = ++setBackResetCount;
}
@ -643,7 +643,7 @@ public class MovingData extends ACheckData {
}
/**
* Get the set-back location with yaw and pitch set form ref.
* Get the set back location with yaw and pitch set form ref.
* @param ref
* @return
*/
@ -652,7 +652,7 @@ public class MovingData extends ACheckData {
}
/**
* Get the set-back location with yaw and pitch set from ref.
* Get the set back location with yaw and pitch set from ref.
* @param ref
* @return
*/
@ -692,7 +692,7 @@ public class MovingData extends ACheckData {
}
/**
* Test, if the 'teleported' location is set, e.g. on a scheduled set-back.
* Test, if the 'teleported' location is set, e.g. on a scheduled set back.
*
* @return
*/
@ -721,7 +721,7 @@ public class MovingData extends ACheckData {
}
/**
* Set teleport-to location to recognize NCP set-backs. This copies the coordinates and world.
* Set teleport-to location to recognize NCP set backs. This copies the coordinates and world.
* @param loc
*/
public final void setTeleported(final Location loc) {
@ -733,7 +733,7 @@ public class MovingData extends ACheckData {
}
/**
* Test if the morepackets set-back is older than the ordinary set-back.
* Test if the morepackets set back is older than the ordinary set back.
* Does not check for existence of either.
*
* @return
@ -771,7 +771,7 @@ public class MovingData extends ACheckData {
}
/**
* Set set-back location to null.
* Set set back location to null.
*/
public final void resetSetBack() {
setBack = null;

View File

@ -374,7 +374,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
final MovingData data = MovingData.getData(event.getPlayer());
data.clearFlyData();
data.clearPlayerMorePacketsData();
// TODO: Set new set-back if any fly check is activated.
// TODO: Set new set back if any fly check is activated.
// (Keep vehicle data as is.)
}
}
@ -393,8 +393,14 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
// Store the event for monitor level checks.
processingEvents.put(player.getName(), event);
final MovingConfig cc = MovingConfig.getConfig(player);
final MovingData data = MovingData.getData(player);
/*
* 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;
@ -431,6 +437,9 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
// Ignore changing worlds.
earlyReturn = true;
}
else if (data.hasTeleported()) {
earlyReturn = handleTeleportedOnMove(player, event, data);
}
else {
earlyReturn = false;
}
@ -452,10 +461,11 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
}
// Set.
// TODO: Reset positions? enforceLocation?
event.setTo(newTo);
//event.setTo(newTo); // LEGACY: pre-2017-03-24
if (data.debug) {
debug(player, "Early return on PlayerMoveEvent, set back to: " + newTo);
}
onSetBack(player, event, newTo, data, cc);
}
data.joinOrRespawn = false;
return;
@ -463,7 +473,6 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
// newTo should be null here.
// Fire one or two moves here.
final MovingConfig cc = MovingConfig.getConfig(player);
final PlayerMoveInfo moveInfo = aux.usePlayerMoveInfo();
final Location loc = player.getLocation(moveInfo.useLoc);
final PlayerMoveData lastMove = data.playerMoves.getFirstPastMove();
@ -510,6 +519,34 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
aux.returnPlayerMoveInfo(moveInfo);
}
/**
* During early player move handling: data.hasTeleported() returned true.
*
* @param player
* @param event
* @param data
*
* @return
*/
private boolean handleTeleportedOnMove(Player player, PlayerMoveEvent event, MovingData data) {
if (TickTask.isPlayerGoingToBeSetBack(player.getUniqueId())) {
event.setCancelled(true);
if (data.debug) {
debug(player, "Cancel move, due to a scheduled teleport (set back).");
}
return true;
}
else {
// Left-over.
if (data.debug) {
debug(player, "Invalidate left-over teleported (set back) location: " + data.getTeleported());
}
data.resetTeleported();
// TODO: More to do?
return false;
}
}
/**
*
* @param player
@ -665,7 +702,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
final boolean useBlockChangeTracker;
if (checkSf || checkCf) {
// Ensure we have a set-back set.
// Ensure we have a set back set.
MovingUtil.checkSetBack(player, pFrom, data, this);
// Check for special cross world teleportation issues with the end.
@ -747,13 +784,13 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
useBlockChangeTracker = false;
}
// Check passable first to prevent set-back override.
// TODO: Redesign to set set-backs later (queue + invalidate).
// Check passable first to prevent set back override.
// TODO: Redesign to set set backs later (queue + invalidate).
boolean mightSkipNoFall = false; // If to skip nofall check (mainly on violation of other checks).
if (newTo == null && cc.passableCheck && player.getGameMode() != BridgeMisc.GAME_MODE_SPECTATOR
&& !NCPExemptionManager.isExempted(player, CheckType.MOVING_PASSABLE)
&& !player.hasPermission(Permissions.MOVING_PASSABLE)) {
// Passable is checked first to get the original set-back locations from the other checks, if needed.
// Passable is checked first to get the original set back locations from the other checks, if needed.
newTo = passable.check(player, pFrom, pTo, data, cc, tick, useBlockChangeTracker);
if (newTo != null) {
// Check if to skip the nofall check.
@ -841,9 +878,9 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
to avoid packet speeding using micro-violations.) */
final Location mpNewTo = morePackets.check(player, pFrom, pTo, newTo == null, data, cc);
if (mpNewTo != null) {
// Only override set-back, if the morepackets set-back location is older/-est.
// Only override set back, if the morepackets set back location is older/-est.
if (newTo != null && data.debug) {
debug(player, "Override set-back by the older morepackets set-back.");
debug(player, "Override set back by the older morepackets set back.");
}
newTo = mpNewTo;
}
@ -886,7 +923,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
// Teleport during violation processing, just invalidate thisMove.
thisMove.invalidate();
}
// Increase time since set-back.
// Increase time since set back.
data.timeSinceSetBack ++;
return false;
}
@ -899,7 +936,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
debug(player, "Bounce effect not used: " + data.verticalBounce);
}
}
// Set-back handling.
// Set back handling.
onSetBack(player, event, newTo, data, cc);
return true;
}
@ -1164,7 +1201,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
}
}
if (violation > 0.0) {
// Ensure a set-back location is present.
// Ensure a set back location is present.
if (!data.hasSetBack()) {
data.setSetBack(from);
}
@ -1195,7 +1232,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
}
// Some resetting is done in MovingListener.
if (check.executeActions(vd).willCancel()) {
// Set-back + view direction of to (more smooth).
// Set back + view direction of to (more smooth).
return data.getSetBack(to);
}
}
@ -1290,10 +1327,14 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
}
/**
* Called during PlayerMoveEvent for adjusting to a to-be-scheduled set
* back.
*
* @param player
* @param event
* @param newTo Must be a cloned or new Location instance, free for whatever other plugins do with it.
* @param newTo
* Must be a cloned or new Location instance, free for whatever
* other plugins do with it.
* @param data
* @param cc
*/
@ -1311,7 +1352,9 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
aux.resetPositionsAndMediumProperties(player, newTo, data, cc); // TODO: Might move into prepareSetBack, experimental here.
// Set new to-location.
event.setTo(newTo);
// event.setTo(newTo); // LEGACY: pre-2017-03-24
event.setCancelled(true);
// NOTE: A teleport is scheduled on MONITOR priority, if still relevant.
// Debug.
if (data.debug) {
@ -1344,7 +1387,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
// Feed combined check.
final CombinedData data = CombinedData.getData(player);
data.lastMoveTime = now; // TODO: Move to MovingData ?
final Location from = event.getFrom();
@ -1375,12 +1418,32 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
* @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) {
// TODO: Revise handling of cancelled events.
data.lastMoveTime = now; // TODO: Move to MovingData?
// TODO: teleported + other resetting ?
Combined.feedYawRate(player, from.getYaw(), now, from.getWorld().getName(), data);
aux.resetPositionsAndMediumProperties(player, from, mData, mCc);
mData.resetTrace(player, from, tick, mcAccess.getHandle(), mCc); // TODO: Should probably leave this to the teleport event!
// Detect our own set back, choice of reference location.
if (mData.hasSetBack()) {
final Location ref = mData.getTeleported();
final UUID playerId = player.getUniqueId();
if (!TickTask.isPlayerGoingToBeSetBack(playerId)) {
TickTask.requestPlayerSetBack(playerId);
if (mData.debug) {
debug(player, "Schedule teleport (set back) to: " + ref);
}
}
else if (data.debug) {
debug(player, "Teleport (set back) already scheduled to: " + ref);
}
// TODO: Does this still play well with onSetBack etc (not having the teleport follow directly)?
// (Position adaption will happen with the teleport on tick.)
}
// Assume the implicit teleport to the from-location (no Bukkit event fires).
Combined.resetYawRate(player, from.getYaw(), now, false); // Not reset frequency, but do set yaw.
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 (((NetConfig) CheckType.NET_FLYINGFREQUENCY.getConfigFactory().getConfig(player)).flyingFrequencyActive) {
((NetData) CheckType.NET_FLYINGFREQUENCY.getDataFactory().getData(player)).teleportQueue.onTeleportEvent(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch());
}
@ -1397,7 +1460,6 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
* @param mData
*/
private void onMoveMonitorNotCancelled(final Player player, final Location from, final Location to, final long now, final long tick, final CombinedData data, final MovingData mData, final MovingConfig mCc) {
data.lastMoveTime = now; // TODO: Move to MovingData ?
final String toWorldName = to.getWorld().getName();
Combined.feedYawRate(player, to.getYaw(), now, toWorldName, data);
// TODO: maybe even not count vehicles at all ?
@ -1417,13 +1479,27 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
// TODO: Detect differing location (a teleport event would follow).
final PlayerMoveData lastMove = mData.playerMoves.getFirstPastMove();
if (!lastMove.toIsValid || !TrigUtil.isSamePos(to, lastMove.to.getX(), lastMove.to.getY(), lastMove.to.getZ())) {
// Something odd happened.
// Something odd happened, e.g. a set back.
aux.resetPositionsAndMediumProperties(player, to, mData, mCc);
}
else {
// Normal move, nothing to do.
}
mData.updateTrace(player, to, tick, mcAccess.getHandle());
if (mData.hasTeleported()) {
if (TickTask.isPlayerGoingToBeSetBack(player.getUniqueId())) {
// Skip.
if (mData.debug) {
debug(player, "Event not cancelled, despite a set back has been scheduled. Ignore set back.");
}
}
else {
if (mData.debug) {
debug(player, "Inconsistent state (move MONITOR): teleported has been set, but no set back is scheduled. Ignore set back.");
}
}
mData.resetTeleported(); // (TickTask will notice it's not set.)
}
}
}
@ -1546,7 +1622,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
}
/**
* HIGHEST: Revert cancel on set-back.
* HIGHEST: Revert cancel on set back.
*
* @param event
*/
@ -1559,7 +1635,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
final Player player = event.getPlayer();
final MovingData data = MovingData.getData(player);
Location to = event.getTo();
// Revert cancel on set-back.
// Revert cancel on set back.
if (data.isTeleported(to)) {
// Teleport by NCP.
final Location teleported = data.getTeleported();
@ -1569,7 +1645,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
event.setTo(teleported); // ?
event.setFrom(teleported);
if (data.debug) {
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().warning(Streams.TRACE_FILE, player.getName() + " TP " + event.getCause() + " (revert cancel on set-back): " + to);
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().warning(Streams.TRACE_FILE, player.getName() + " TP " + event.getCause() + " (revert cancel on set back): " + to);
}
return;
}
@ -1594,9 +1670,9 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
final Location to = event.getTo();
if (event.isCancelled()) {
if (data.isTeleported(to)) {
// TODO: Schedule a teleport to set-back with PlayerData (+ failure count)?
// TODO: Schedule a teleport to set back with PlayerData (+ failure count)?
// TODO: Log once per player always?
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().warning(Streams.TRACE_FILE, CheckUtils.getLogMessagePrefix(player, CheckType.MOVING) + " TP " + event.getCause() + " (set-back was prevented): " + to);
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().warning(Streams.TRACE_FILE, CheckUtils.getLogMessagePrefix(player, CheckType.MOVING) + " TP " + event.getCause() + " (set back was prevented): " + to);
}
else {
if (data.debug) {
@ -1617,10 +1693,10 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
return;
}
final MovingConfig cc = MovingConfig.getConfig(player);
// Detect our own player set-backs.
// Detect our own player set backs.
if (data.hasTeleported()) {
if (data.isTeleported(to)) {
// Set-back.
// Set back.
final Location teleported = data.getTeleported();
final PlayerMoveInfo moveInfo = aux.usePlayerMoveInfo();
moveInfo.set(player, teleported, null, cc.yOnGround);
@ -1641,13 +1717,13 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
return;
}
else {
// Another plugin overrides the set-back location.
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().warning(Streams.TRACE_FILE, CheckUtils.getLogMessagePrefix(player, CheckType.MOVING) + " TP " + event.getCause() + " (set-back was overridden): " + to);
// Another plugin overrides the set back location.
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().warning(Streams.TRACE_FILE, CheckUtils.getLogMessagePrefix(player, CheckType.MOVING) + " TP " + event.getCause() + " (set back was overridden): " + to);
}
}
boolean skipExtras = false; // Skip extra data adjustments during special teleport, e.g. vehicle set back.
// Detect our own vehicle set-backs (...).
// Detect our own vehicle set backs (...).
if (data.isVehicleSetBack) {
// Uncertain if this is vehicle leave or vehicle enter.
if (event.getCause() != PlayerTeleportEvent.TeleportCause.UNKNOWN) {
@ -1925,7 +2001,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
}
}
// Correct set-back on join.
// Correct set back on join.
if (!data.hasSetBack() || data.hasSetBackWorldChanged(loc)) {
data.clearFlyData();
data.setSetBack(loc);
@ -1936,14 +2012,14 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
// TODO: Check consistency/distance.
//final Location setBack = data.getSetBack(loc);
//final double d = loc.distanceSquared(setBack);
// TODO: If to reset positions: relate to previous ones and set-back.
// TODO: If to reset positions: relate to previous ones and set back.
// (resetPositions is called below)
}
// (Note: resetPositions resets lastFlyCheck and other.)
data.clearVehicleData(); // TODO: Uncertain here, what to check.
data.clearAllMorePacketsData();
data.removeAllVelocity();
data.resetTrace(player, loc, tick, mcAccess.getHandle(), cc); // Might reset to loc instead of set-back ?
data.resetTrace(player, loc, tick, mcAccess.getHandle(), cc); // Might reset to loc instead of set back ?
// More resetting.
data.vDistAcc.clear();
@ -2020,7 +2096,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
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);
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));
@ -2197,8 +2273,8 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
// TODO: Add history / alert?
//player.sendMessage(ChatColor.RED + "NCP: enforce location !"); // TODO: DEBUG - REMOVE.
if (data.hasSetBack()) {
// Might have to re-check all context with playerJoins and keeping old set-backs...
// Could use a flexible set-back policy (switch to in-air on login).
// Might have to re-check all context with playerJoins and keeping old set backs...
// Could use a flexible set back policy (switch to in-air on login).
return data.getSetBack(loc);
}
else {

View File

@ -21,7 +21,7 @@ import fr.neatmonster.nocheatplus.time.monotonic.Monotonic;
/**
* A default extension of SetBackStorage, featuring convenience methods for
* set-back locations with standard naming, including a default set-back.
* set back locations with standard naming, including a default set back.
* <ul>
* <li>0: Default. Typically after teleport/join.</li>
* <li>1: Mid-term. Typically used by more packets checks.</li>
@ -62,7 +62,7 @@ public class DefaultSetBackStorage extends SetBackStorage {
}
/**
* Get the 'mid-term' set-back entry, disregarding validity.
* Get the 'mid-term' set back entry, disregarding validity.
*
* @return
*/
@ -71,7 +71,7 @@ public class DefaultSetBackStorage extends SetBackStorage {
}
/**
* Get the 'safe-medium' set-back entry, disregarding validity.
* Get the 'safe-medium' set back entry, disregarding validity.
*
* @return
*/
@ -80,7 +80,7 @@ public class DefaultSetBackStorage extends SetBackStorage {
}
/**
* Get the 'last-move' set-back entry, disregarding validity of the entry
* Get the 'last-move' set back entry, disregarding validity of the entry
* itself.
*
* @return

View File

@ -20,5 +20,5 @@ package fr.neatmonster.nocheatplus.checks.moving.location.setback;
*
*/
public class MagicSetBack {
// TODO: Consider flags for type of set-back locations, for fast inclusion+exclusion.
// TODO: Consider flags for type of set back locations, for fast inclusion+exclusion.
}

View File

@ -169,7 +169,7 @@ public class SetBackEntry implements IGetLocationWithLook, ISetLocationWithLook
* @return A new Location object, containing the given world, ready to be
* used.
* @throws IllegalStateException
* In case the set-back entry is not valid.
* In case the set back entry is not valid.
* @throws IllegalArgumentException
* In case the name of the given world does not match the stored
* one.

View File

@ -22,8 +22,8 @@ import fr.neatmonster.nocheatplus.time.monotonic.Monotonic;
import fr.neatmonster.nocheatplus.utilities.location.TrigUtil;
/**
* Represent a set-back location storage, allowing for more or less efficient
* keeping track of multiple set-backs for use within one overall checking
* Represent a set back location storage, allowing for more or less efficient
* keeping track of multiple set backs for use within one overall checking
* context (e.g. player moving, or vehicle moving). For timing values, a counter
* is used as time and a monotonic clock for msTime (static primary thread
* clock: Monotonic.millis()).
@ -34,11 +34,11 @@ import fr.neatmonster.nocheatplus.utilities.location.TrigUtil;
public class SetBackStorage {
// TODO: Support a hash for locations (LocUtil.hashCode).
// TODO: Support for last-used set-back (on retrieving a Location instance)?
// TODO: Support for last-used set back (on retrieving a Location instance)?
final SetBackEntry[] entries;
final int defaultIndex;
/** Count times setting a set-back. */
/** Count times setting a set back. */
int time; // TODO: Switch to a counter/clock implementation, in order to allow the same provider for player + vehicle?
/**
@ -210,7 +210,7 @@ public class SetBackStorage {
}
/**
* Test if any of the stored set-back location is valid.
* Test if any of the stored set back location is valid.
*
* @return
*/
@ -238,7 +238,7 @@ public class SetBackStorage {
}
/**
* Get the default set-back entry, disregarding validity.
* Get the default set back entry, disregarding validity.
*
* @return In case no default is set, null is returned. Otherwise the
* default entry is returned disregarding validity.
@ -279,6 +279,6 @@ public class SetBackStorage {
return entry.isValid() ? entry.getLocation(world) : null;
}
// TODO: Method to reset only newer entries to a certain location [a) pass a set-back entry b) find it first, then compare age].
// TODO: Method to reset only newer entries to a certain location [a) pass a set back entry b) find it first, then compare age].
}

View File

@ -410,7 +410,7 @@ public class LostGround {
* Apply lost-ground workaround.
* @param player
* @param refLoc
* @param setBackSafe If to use the given location as set-back.
* @param setBackSafe If to use the given location as set back.
* @param data
* @param tag Added to "lostground_" as tag.
* @return Always true.
@ -420,7 +420,7 @@ public class LostGround {
data.setSetBack(refLoc);
}
else {
// Keep Set-back.
// Keep Set back.
}
return applyLostGround(player, thisMove, data, tag, tags, mcAccess);
}
@ -429,7 +429,7 @@ public class LostGround {
* Apply lost-ground workaround.
* @param player
* @param refLoc
* @param setBackSafe If to use the given location as set-back.
* @param setBackSafe If to use the given location as set back.
* @param data
* @param tag Added to "lostground_" as tag.
* @return Always true.
@ -440,7 +440,7 @@ public class LostGround {
data.setSetBack(refLoc);
}
else {
// Keep Set-back.
// Keep Set back.
}
return applyLostGround(player, thisMove, data, tag, tags, refLoc.getMCAccess());
}
@ -449,7 +449,7 @@ public class LostGround {
* Apply lost-ground workaround (data adjustments and tag).
* @param player
* @param refLoc
* @param setBackSafe If to use the given location as set-back.
* @param setBackSafe If to use the given location as set back.
* @param data
* @param tag Added to "lostground_" as tag.
* @return Always true.

View File

@ -267,7 +267,7 @@ public class Magic {
}
/**
* First move after set-back / teleport. Originally has been found with
* First move after set back / teleport. Originally has been found with
* PaperSpigot for MC 1.7.10, however it also does occur on Spigot for MC
* 1.7.10.
*

View File

@ -22,7 +22,7 @@ import fr.neatmonster.nocheatplus.utilities.location.TrigUtil;
* Carry data of a move, involving from- and to- locations. This is for
* temporary storage and often resetting, also to encapsulate some data during
* checking. The I/Location instead of I/Position is used in order to be
* compatible with passing these to set-back handling and similar.
* compatible with passing these to set back handling and similar.
*
* @author asofold
*
@ -120,7 +120,7 @@ public class MoveData {
}
/**
* Set with join / teleport / set-back.
* Set with join / teleport / set back.
* @param x
* @param y
* @param z
@ -162,7 +162,7 @@ public class MoveData {
}
/**
* Set with join / teleport / set-back. Does not set extra properties for
* Set with join / teleport / set back. Does not set extra properties for
* locations.
*
* @param loc
@ -173,7 +173,7 @@ public class MoveData {
}
/**
* Set with join / teleport / set-back, also set extra properties.
* Set with join / teleport / set back, also set extra properties.
*
* @param loc
*/

View File

@ -237,19 +237,19 @@ public class CreativeFly extends Check {
// Return setBack, if set.
if (setBack != null) {
// Check for max height of the set-back.
// Check for max height of the set back.
if (setBack.getY() > maximumHeight) {
// Correct the y position.
setBack.setY(getCorrectedHeight(maximumHeight, setBack.getWorld()));
if (data.debug) {
debug(player, "Maximum height exceeded by set-back, correct to: " + setBack.getY());
debug(player, "Maximum height exceeded by set back, correct to: " + setBack.getY());
}
}
data.sfJumpPhase = 0;
return setBack;
}
else {
// Adjust the set-back and other last distances.
// Adjust the set back and other last distances.
data.setSetBack(to);
// Adjust jump phase.
if (!thisMove.from.onGroundOrResetCond && !thisMove.to.onGroundOrResetCond) {
@ -438,7 +438,7 @@ public class CreativeFly extends Check {
private double hackLytra(final double yDistance, final double limitV, final PlayerMoveData thisMove, final PlayerMoveData lastMove, final MovingData data) {
// TODO: Hack, move / config / something.
// TODO: Confine more. hdist change relates to ydist change
// TODO: Further: jumpphase vs. y-distance to set-back. Problem: velocity
// TODO: Further: jumpphase vs. y-distance to set back. Problem: velocity
// TODO: Further: record max h and descend speeds and relate to those.
// TODO: Demand total speed to decrease.
if (yDistance > Magic.GLIDE_DESCEND_PHASE_MIN && yDistance < 17.0 * Magic.GRAVITY_MAX

View File

@ -56,7 +56,7 @@ public class MorePackets extends Check {
* @param from
* @param to
* @param allowSetSetBack
* If to allow setting the set-back location.
* If to allow setting the set back location.
* @param data
* @param cc
* @return
@ -72,9 +72,9 @@ public class MorePackets extends Check {
// return null;
// }
// Ensure we have a set-back location.
// Ensure we have a set back location.
if (allowSetSetBack && !data.hasMorePacketsSetBack()){
// TODO: Check if other set-back is appropriate or if to set/reset on other events.
// TODO: Check if other set back is appropriate or if to set/reset on other events.
if (data.hasSetBack()) {
data.setMorePacketsSetBack(data.getSetBack(to));
}
@ -104,12 +104,12 @@ public class MorePackets extends Check {
}
}
else if (allowSetSetBack) {
// Update the set-back location. (CHANGED to only update, if not a violation.)
// Update the set back location. (CHANGED to only update, if not a violation.)
// (Might update whenever newTo == null)
data.setMorePacketsSetBack(from);
}
// No set-back.
// No set back.
return null;
}

View File

@ -170,11 +170,11 @@ public class Passable extends Check {
final String tags, final MovingData data, final MovingConfig cc) {
Location setBackLoc = null; // Alternative to from.getLocation().
// Prefer the set-back location from the data.
// Prefer the set back location from the data.
if (data.hasSetBack()) {
setBackLoc = data.getSetBack(to);
if (data.debug) {
debug(player, "Using set-back location for passable.");
debug(player, "Using set back location for passable.");
}
}
@ -340,13 +340,13 @@ public class Passable extends Check {
return null;
}
}
// From should be the set-back.
// From should be the set back.
tags += "into";
}
// } else if (BlockProperties.isPassableExact(from.getBlockCache(), loc.getX(), loc.getY(), loc.getZ(), from.getTypeId(lbX, lbY, lbZ))) {
// (Mind that this can be the case on the same block theoretically.)
// Keep loc as set-back.
// Keep loc as set back.
// }
else if (manhattan == 1 && to.isBlockAbove(from)
&& BlockProperties.isPassable(from.getBlockCache(), from.getX(), from.getY() + from.getBoxMarginVertical(), from.getZ(), from.getBlockCache().getOrCreateBlockCacheNode(from.getBlockX(), Location.locToBlock(from.getY() + from.getBoxMarginVertical()), from.getBlockZ(), false), null)) {
@ -355,7 +355,7 @@ public class Passable extends Check {
return null;
}
else if (manhattan > 0) {
// Otherwise keep from as set-back.
// Otherwise keep from as set back.
tags += "cross";
}
else {

View File

@ -409,7 +409,7 @@ public class SurvivalFly extends Check {
vAllowedDistance = res[0];
vDistanceAboveLimit = res[1];
if (res[0] == Double.MIN_VALUE && res[1] == Double.MIN_VALUE) {
// Silent set-back.
// Silent set back.
if (data.debug) {
tags.add("silentsbcobweb");
outputDebug(player, to, data, cc, hDistance, hAllowedDistance, hFreedom,
@ -992,7 +992,7 @@ public class SurvivalFly extends Check {
// TODO: lostground_pyramid(yDist < 0.0) -> step up (yDist 0.5). Needs better last-move modeling.
// TODO: lostground_edgedesc(yDist <0.0) -> Bunny (yDist > .72, e_jump). Needs better last-move modeling.
// TODO: air->ground...small-range-tp...air-air+vDist==0.0 (might work around with fromWasReset?).
// TODO: bunny after vDist<0.0... vdistsb. Might need set-back detection. [solved with setFrictionJumpPhase?]
// TODO: bunny after vDist<0.0... vdistsb. Might need set back detection. [solved with setFrictionJumpPhase?]
// TODO: Other edge cases?
// TODO: Cleanup pending.
final boolean strictVdistRel;
@ -1075,7 +1075,7 @@ public class SurvivalFly extends Check {
if (yDistance < 0.0 && lastMove.yDistance < 0.0 && yDistChange > -Magic.GRAVITY_MAX
&& (from.isOnGround(Math.abs(yDistance) + 0.001) || BlockProperties.isLiquid(to.getTypeId(to.getBlockX(), Location.locToBlock(to.getY() - 0.5), to.getBlockZ())))) {
// Pretty coarse workaround, should instead do a proper modeling for from.getDistanceToGround.
// (OR loc... needs different model, distanceToGround, proper set-back, moveHitGround)
// (OR loc... needs different model, distanceToGround, proper set back, moveHitGround)
// TODO: Slightly too short move onto the same level as snow (0.75), but into air (yDistance > -0.5).
// TODO: Better on-ground model (adapt to actual client code).
}
@ -1960,7 +1960,7 @@ public class SurvivalFly extends Check {
}
// Some resetting is done in MovingListener.
if (executeActions(vd).willCancel()) {
// Set-back + view direction of to (more smooth).
// Set back + view direction of to (more smooth).
return data.getSetBack(to);
}
else {
@ -1981,7 +1981,7 @@ public class SurvivalFly extends Check {
public final void handleHoverViolation(final Player player, final Location loc, final MovingConfig cc, final MovingData data) {
data.survivalFlyVL += cc.sfHoverViolation;
// TODO: Extra options for set-back / kick, like vl?
// TODO: Extra options for set back / kick, like vl?
data.sfVLTime = System.currentTimeMillis();
final ViolationData vd = new ViolationData(this, player, data.survivalFlyVL, cc.sfHoverViolation, cc.survivalFlyActions);
if (vd.needsParameters()) {
@ -1991,7 +1991,7 @@ public class SurvivalFly extends Check {
vd.setParameter(ParameterName.TAGS, "hover");
}
if (executeActions(vd).willCancel()) {
// Set-back or kick.
// Set back or kick.
if (data.hasSetBack()) {
final Location newTo = data.getSetBack(loc);
data.prepareSetBack(newTo);

View File

@ -80,11 +80,16 @@ public class MovingUtil {
/**
* Handle an illegal move by a player, attempt to restore a valid location.
* <br>
* NOTE: event.setTo is used to not leave a gap.
*
* @param event
* @param player
* @param data
* @param cc
*/
public static void handleIllegalMove(final PlayerMoveEvent event, final Player player, final MovingData data, final MovingConfig cc)
public static void handleIllegalMove(final PlayerMoveEvent event, final Player player,
final MovingData data, final MovingConfig cc)
{
// This might get extended to a check-like thing.
boolean restored = false;
@ -125,7 +130,7 @@ public class MovingUtil {
}
/**
* Used for a workaround that resets the set-back for the case of jumping on just placed blocks.
* Used for a workaround that resets the set back for the case of jumping on just placed blocks.
* @param id
* @return
*/
@ -235,7 +240,7 @@ public class MovingUtil {
}
/**
* Ensure we have a set-back location set, plus allow moving from upwards
* Ensure we have a set back location set, plus allow moving from upwards
* with respawn/login. Intended for MovingListener (pre-checks).
*
* @param player
@ -253,7 +258,7 @@ public class MovingUtil {
// TODO: Is a margin needed for from.isOnGround()? [bukkitapionly]
if (data.debug) {
// TODO: Should this be info?
idp.debug(player, "Adjust set-back after join/respawn: " + from.getLocation());
idp.debug(player, "Adjust set back after join/respawn: " + from.getLocation());
}
data.setSetBack(from);
data.resetPlayerPositions(from);

View File

@ -346,7 +346,7 @@ public class VehicleChecks extends CheckListener {
// Ensure firstPastMove is valid.
if (!firstPastMove.valid) {
// Determine the best location to use as past move.
// TODO: Could also check the set-backs for plausible entries, however that would lead to a violation by default. Could use an indicator.
// TODO: Could also check the set backs for plausible entries, however that would lead to a violation by default. Could use an indicator.
final Location refLoc = from == null ? vehicleLocation : from;
MovingUtil.ensureChunksLoaded(player, refLoc, "vehicle move (no past move)", data, cc);
aux.resetVehiclePositions(vehicle, refLoc, data, cc);
@ -421,7 +421,7 @@ public class VehicleChecks extends CheckListener {
else {
// Better than nothing.
data.vehicleSetBacks.setDefaultEntry(vehicleLocation);
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().warning(Streams.STATUS, CheckUtils.getLogMessagePrefix(player, checkType) + "Using the current vehicle location for set-back, due to not having a past location to rely on. This could be a bug.");
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().warning(Streams.STATUS, CheckUtils.getLogMessagePrefix(player, checkType) + "Using the current vehicle location for set back, due to not having a past location to rely on. This could be a bug.");
}
}
else {
@ -498,21 +498,21 @@ public class VehicleChecks extends CheckListener {
// TODO: Check activation of any check?
// Ensure a common set-back for now.
// Ensure a common set back for now.
if (!data.vehicleSetBacks.isDefaultEntryValid()) {
ensureSetBack(player, thisMove, data);
}
// Moving envelope check(s).
// TODO: Use set-back storage for testing if this is appropriate (use SetBackEntry instead, remove Location retrieval then?).
// TODO: Use set back storage for testing if this is appropriate (use SetBackEntry instead, remove Location retrieval then?).
if ((newTo == null || data.vehicleSetBacks.getSafeMediumEntry().isValidAndOlderThan(newTo))
&& vehicleEnvelope.isEnabled(player, data, cc)) {
// Skip if this is the first move after set-back, with to=set-back.
// Skip if this is the first move after set back, with to=set back.
if (data.timeSinceSetBack == 0 || thisMove.to.hashCode() == data.lastSetBackHash) {
// TODO: This is a hot fix, to prevent a set-back loop. Depends on having only the morepackets set-back for vehicles.
// TODO: This is a hot fix, to prevent a set back loop. Depends on having only the morepackets set back for vehicles.
// TODO: Perhaps might want to add || !data.equalsAnyVehicleSetBack(to)
if (data.debug) {
debug(player, "Skip envelope check on first move after set back acknowledging the set-back with an odd starting point (from).");
debug(player, "Skip envelope check on first move after set back acknowledging the set back with an odd starting point (from).");
}
}
else {
@ -526,7 +526,7 @@ public class VehicleChecks extends CheckListener {
}
}
// More packets: Sort this in last, to avoid setting the set-back early. Always check to adjust set-back, for now.
// More packets: Sort this in last, to avoid setting the set back early. Always check to adjust set back, for now.
// TODO: Still always update the frequency part?
if ((newTo == null || data.vehicleSetBacks.getMidTermEntry().isValidAndOlderThan(newTo))) {
if (vehicleMorePackets.isEnabled(player, data, cc)) {
@ -537,14 +537,14 @@ public class VehicleChecks extends CheckListener {
}
else {
// Otherwise we need to clear their data.
// TODO: Make mid-term set-back resetting independent of more packets.
// TODO: Make mid-term set back resetting independent of more packets.
data.clearVehicleMorePacketsData();
}
}
// Schedule a set-back?
// Schedule a set back?
if (newTo == null) {
// Increase time since set-back.
// Increase time since set back.
data.timeSinceSetBack ++;
// Finally finish processing the current move and move it to past ones.
data.vehicleMoves.finishCurrentMove();
@ -556,7 +556,7 @@ public class VehicleChecks extends CheckListener {
}
/**
* Called if the default set-back entry isn't valid.
* Called if the default set back entry isn't valid.
*
* @param player
* @param thisMove
@ -572,20 +572,20 @@ public class VehicleChecks extends CheckListener {
}
data.vehicleSetBacks.setDefaultEntry(ensureLoc);
if (data.debug) {
debug(player, "Ensure vehicle set-back: " + ensureLoc);
debug(player, "Ensure vehicle set back: " + ensureLoc);
}
// if (data.vehicleSetBackTaskId != -1) {
// // TODO: This is likely the wrong thing to do!
// Bukkit.getScheduler().cancelTask(data.vehicleSetBackTaskId);
// data.vehicleSetBackTaskId = -1;
// if (data.debug) {
// debug(player, "Cancel set-back task on ensureSetBack.");
// debug(player, "Cancel set back task on ensureSetBack.");
// }
// }
}
private void setBack(final Player player, final Entity vehicle, final SetBackEntry newTo, final MovingData data, final MovingConfig cc) {
// TODO: Generic set-back manager, preventing all sorts of stuff that might be attempted or just happen before the task is running?
// TODO: Generic set back manager, preventing all sorts of stuff that might be attempted or just happen before the task is running?
if (data.vehicleSetBackTaskId == -1) {
// Schedule a delayed task to teleport back the vehicle with the player.
// (Only schedule if not already scheduled.)
@ -604,7 +604,7 @@ public class VehicleChecks extends CheckListener {
data.vehicleSetBackTaskId = Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new VehicleSetBackTask(vehicle, player, newTo.getLocation(vehicle.getWorld()), data.debug));
if (data.vehicleSetBackTaskId == -1) {
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().warning(Streams.STATUS, "Failed to schedule vehicle set back task. Player: " + player.getName() + " , set-back: " + newTo);
NCPAPIProvider.getNoCheatPlusAPI().getLogManager().warning(Streams.STATUS, "Failed to schedule vehicle set back task. Player: " + player.getName() + " , set back: " + newTo);
scheduleSetBack = false; // Force direct teleport as a fall-back measure.
}
else if (data.debug) {
@ -617,7 +617,7 @@ public class VehicleChecks extends CheckListener {
* NOTE: This causes nested vehicle exit+enter and player
* teleport events, while the current event is still being
* processed (one of player move, vehicle update/move). Position
* resetting and updating the set-back (if needed) is done there
* resetting and updating the set back (if needed) is done there
* (hack, subject to current review).
*/
if (data.debug) {
@ -644,7 +644,7 @@ public class VehicleChecks extends CheckListener {
/**
* Assume entering a vehicle, event or join with being inside a vehicle.
* Set-back and past move overriding are done here, performing the necessary
* 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.
@ -753,7 +753,7 @@ public class VehicleChecks extends CheckListener {
if (!(entity instanceof Player)) {
return;
}
// TODO: Queued set-backs? Usually means they still get teleported, individually though.
// TODO: Queued set backs? Usually means they still get teleported, individually though.
onPlayerVehicleLeave((Player) entity, event.getVehicle());
}
@ -794,20 +794,20 @@ public class VehicleChecks extends CheckListener {
data.wasInVehicle = false;
data.joinOrRespawn = false;
// if (data.vehicleSetBackTaskId != -1) {
// // Await set-back.
// // TODO: might still set ordinary set-backs ?
// // Await set back.
// // TODO: might still set ordinary set backs ?
// return;
// }
final MovingConfig cc = MovingConfig.getConfig(player);
// TODO: Loc can be inconsistent, determine which to use !
final Location pLoc = player.getLocation(useLoc1);
Location loc = pLoc; // The location to use as set-back.
Location loc = pLoc; // The location to use as set back.
// TODO: Which vehicle to use ?
// final Entity vehicle = player.getVehicle();
if (vehicle != null) {
final Location vLoc = vehicle.getLocation(useLoc2);
// (Don't override vehicle set-back and last position here.)
// (Don't override vehicle set back and last position here.)
// Workaround for some entities/animals that don't fire VehicleMoveEventS.
if (!normalVehicles.contains(vehicle.getType()) || cc.noFallVehicleReset) {
data.noFallSkipAirCheck = true; // Might allow one time cheat.

View File

@ -67,9 +67,9 @@ public class VehicleEnvelope extends Check {
public boolean checkAscendMuch;
public boolean checkDescendMuch;
/** From could be a new set-back location. */
/** From could be a new set back location. */
public boolean fromIsSafeMedium;
/** To could be a new set-back location. */
/** To could be a new set back location. */
public boolean toIsSafeMedium;
/** Interpreted differently depending on check. */
@ -127,7 +127,7 @@ public class VehicleEnvelope extends Check {
}
else {
data.vehicleEnvelopeVL *= 0.99; // Random cool down for now.
// Do not set a set-back here.
// Do not set a set back here.
}
return null;
}
@ -279,7 +279,7 @@ public class VehicleEnvelope extends Check {
data.sfJumpPhase ++;
}
else {
// Adjust set-back.
// Adjust set back.
if (checkDetails.toIsSafeMedium) {
data.vehicleSetBacks.setSafeMediumEntry(thisMove.to);
data.sfJumpPhase = 0;
@ -380,7 +380,7 @@ public class VehicleEnvelope extends Check {
}
if (checkDetails.canJump) {
// TODO: Max. y-distance to set-back.
// TODO: Max. y-distance to set back.
// TODO: Friction.
}
else {

View File

@ -52,7 +52,7 @@ public class VehicleMorePackets extends Check {
* @param player
* the player
* @param thisMove
* @param setBack Already decided set-back, if not null.
* @param setBack Already decided set back, if not null.
* @param cc
* @param data
* @return the location
@ -111,11 +111,11 @@ public class VehicleMorePackets extends Check {
// Set the new "last" time.
data.vehicleMorePacketsLastTime = time;
// Set the new set-back location.
// Set the new set back location.
if (allowSetSetBack && newTo == null) {
data.vehicleSetBacks.setMidTermEntry(thisMove.from);
if (data.debug) {
debug(player, "Update vehicle morepackets set-back: " + thisMove.from);
debug(player, "Update vehicle morepackets set back: " + thisMove.from);
}
}
} else if (data.vehicleMorePacketsLastTime > time) {

View File

@ -34,7 +34,7 @@ public class AccountEntry {
/**
* "Some sum" for general purpose. <li>For vertical entries this is used to
* alter the allowed y-distance to the set-back point.</li>
* alter the allowed y-distance to the set back point.</li>
*/
public double sum = 0.0;

View File

@ -25,7 +25,7 @@ import fr.neatmonster.nocheatplus.components.data.IData;
* On the medium run this is intended to carry all data for the player...
* <li>Checks data objects.</li>
* <li>Time stamps for logged out players</li>
* <li>Data to be persisted, like set-backs, xray.</li>
* <li>Data to be persisted, like set backs, xray.</li>
* <br>Might contain...
* <li>References of configs.</li>
* <li>Exemption entries.</li>

View File

@ -51,7 +51,8 @@ public class TeleportUtil {
* @param debug
* the debug
*/
public static void teleport(final Entity vehicle, final Player player, final Location location, final boolean debug) {
public static void teleport(final Entity vehicle, final Player player, final Location location,
final boolean debug) {
// TODO: Rubber band issue needs synchronizing with packet level and ignore certain incoming ones?
// TODO: This handling could conflict with WorldGuard region flags.
// TODO: Account for nested passengers and inconsistencies.
@ -92,29 +93,31 @@ public class TeleportUtil {
BridgeMisc.TELEPORT_CAUSE_CORRECTION_OF_POSITION);
}
if (!playerTeleported && player.isOnline() && !player.isDead()) {
// Mask player teleport as a set-back.
// Mask player teleport as a set back.
data.prepareSetBack(location);
playerTeleported = player.teleport(LocUtil.clone(location));
data.resetTeleported(); // Just in case.
// Workarounds.
data.ws.resetConditions(WRPT.G_RESET_NOTINAIR); // Allow re-use of certain workarounds. Hack/shouldbedoneelsewhere?
// TODO: Magic 1.0, plus is this valid with horse, dragon...
if (playerIsPassenger && playerTeleported && vehicleTeleported && player.getLocation().distance(vehicle.getLocation(useLoc)) < 1.5) {
if (playerIsPassenger && playerTeleported && vehicleTeleported
&& player.getLocation().distance(vehicle.getLocation(useLoc)) < 1.5) {
// Somewhat check against tp showing something wrong (< 1.0).
vehicle.setPassenger(player); // NOTE: VehicleEnter fires, unknown TP fires.
// TODO: What on failure of setPassenger?
// Ensure a set-back.
// TODO: Set-backs get invalidated somewhere, likely on an extra unknown TP. Use data.isVehicleSetBack in MovingListener/teleport.
// Ensure a set back.
// TODO: Set backs get invalidated somewhere, likely on an extra unknown TP. Use data.isVehicleSetBack in MovingListener/teleport.
if (data.vehicleSetBacks.getFirstValidEntry(location) == null) {
// At least ensure one of the entries has to match the location we teleported the vehicle to.
if (data.debug) {
CheckUtils.debug(player, CheckType.MOVING_VEHICLE, "No set-back is matching the vehicle location that it has just been set back to. Reset all lazily to: " + location);
CheckUtils.debug(player, CheckType.MOVING_VEHICLE, "No set back is matching the vehicle location that it has just been set back to. Reset all lazily to: " + location);
}
data.vehicleSetBacks.resetAllLazily(location);
}
// Set this location as past move.
final VehicleMoveData firstPastMove = data.vehicleMoves.getFirstPastMove();
if (!firstPastMove.valid || firstPastMove.toIsValid || !TrigUtil.isSamePos(firstPastMove.from, location)) {
if (!firstPastMove.valid || firstPastMove.toIsValid
|| !TrigUtil.isSamePos(firstPastMove.from, location)) {
final MovingConfig cc = MovingConfig.getConfig(player);
NCPAPIProvider.getNoCheatPlusAPI().getGenericInstance(AuxMoving.class).resetVehiclePositions(vehicle, location, data, cc);
}

View File

@ -33,6 +33,8 @@ import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.ViolationData;
import fr.neatmonster.nocheatplus.checks.access.ICheckData;
import fr.neatmonster.nocheatplus.checks.combined.Improbable;
import fr.neatmonster.nocheatplus.checks.moving.MovingData;
import fr.neatmonster.nocheatplus.compat.BridgeMisc;
import fr.neatmonster.nocheatplus.components.registry.feature.TickListener;
import fr.neatmonster.nocheatplus.logging.StaticLog;
import fr.neatmonster.nocheatplus.players.DataManager;
@ -53,16 +55,16 @@ public class TickTask implements Runnable {
* The Class PermissionUpdateEntry.
*/
protected static final class PermissionUpdateEntry{
/** The check type. */
public final CheckType checkType;
/** The player name. */
public final String playerName;
/** The hash code. */
private final int hashCode;
/**
* Instantiates a new permission update entry.
*
@ -76,7 +78,7 @@ public class TickTask implements Runnable {
this.checkType = checkType;
hashCode = playerName.hashCode() ^ checkType.hashCode();
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@ -88,7 +90,7 @@ public class TickTask implements Runnable {
final PermissionUpdateEntry other = (PermissionUpdateEntry) obj;
return playerName.equals(other.playerName) && checkType.equals(other.checkType);
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@ -102,10 +104,10 @@ public class TickTask implements Runnable {
* The Class ImprobableUpdateEntry.
*/
protected static final class ImprobableUpdateEntry {
/** The add level. */
public float addLevel;
/**
* Instantiates a new improbable update entry.
*
@ -126,7 +128,10 @@ public class TickTask implements Runnable {
private static Set<PermissionUpdateEntry> permissionUpdates = new LinkedHashSet<PermissionUpdateEntry>(50);
/** Improbable entries to update. */
private static Map<UUID, ImprobableUpdateEntry> improbableUpdates = new LinkedHashMap<UUID, TickTask.ImprobableUpdateEntry>(50);
/** UUIDs of players who are to be set back. Primary thread only, so far. */
private static final Set<UUID> playerSetBackIds = new LinkedHashSet<UUID>(); // Could use a list, though.
/** The Constant improbableLock. */
private static final ReentrantLock improbableLock = new ReentrantLock();
@ -266,6 +271,29 @@ public class TickTask implements Runnable {
}
}
/**
* Using the getTeleported() Location instance in MovingData, in order to
* set back the player on tick. This is for PlayerMoveEvent-like handling,
* not for vehicles. Primary thread only, so far.
*
* @param playerId
*/
public static void requestPlayerSetBack(final UUID playerId) {
if (!locked) {
playerSetBackIds.add(playerId);
}
}
/**
* Test if a player set back is scheduled (MovingData).
*
* @param playerId
* @return
*/
public static boolean isPlayerGoingToBeSetBack(final UUID playerId) {
return playerSetBackIds.contains(playerId);
}
/**
* Request actions execution.<br>
* NOTE: Thread safe.
@ -599,6 +627,9 @@ public class TickTask implements Runnable {
synchronized (tickListeners) {
tickListeners.clear();
}
if (Bukkit.isPrimaryThread()) {
playerSetBackIds.clear();
}
}
/**
@ -647,17 +678,47 @@ public class TickTask implements Runnable {
}
}
private void processPlayerSetBackIds() {
// TODO: Might design as a permanent tick listener (access API elsewhere) to minimize TickListener.
for (final UUID id : playerSetBackIds) {
final Player player = DataManager.getPlayer(id);
if (player == null) {
// (Should be intercepted elsewhere, e.g. on quit/kick.)
continue;
}
final MovingData data = MovingData.getData(player);
if (!data.hasTeleported()) {
if (data.debug) {
CheckUtils.debug(player, CheckType.MOVING, "Player set back on tick: No stored location available.");
}
continue;
}
if (!player.teleport(data.getTeleported(), BridgeMisc.TELEPORT_CAUSE_CORRECTION_OF_POSITION)) {
if (data .debug) {
CheckUtils.debug(player, CheckType.MOVING, "Player set back on tick: Teleport failed.");
}
}
// (Data resetting is done during PlayerTeleportEvent handling.)
}
// (There could be ids kept on errors !?)
playerSetBackIds.clear();
}
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
// Actions.
executeActions();
// Permissions.
updatePermissions();
public void run() {
// Improbable.
updateImprobable();
// Actions.
executeActions();
// Set back (after actions, for now, because actions may contain a set back action later on).
if (!playerSetBackIds.isEmpty()) {
processPlayerSetBackIds();
}
// Permissions.
updatePermissions();
// Listeners.
notifyListeners();

View File

@ -26,7 +26,7 @@ import fr.neatmonster.nocheatplus.components.location.ISetPositionWithLook;
/**
* Auxiliary methods for Location handling, mainly intended for use with
* set-back locations.
* set back locations.
*
* @author asofold
*