use of fr.neatmonster.nocheatplus.checks.moving.player.PlayerSetBackMethod 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.player.PlayerSetBackMethod in project NoCheatPlus by NoCheatPlus.
the class MovingListener method onCancelledMove.
/**
* Adjust data for a cancelled move. No teleport event will fire, but an
* outgoing position is sent. Note that event.getFrom() may be overridden by
* a plugin, which the server will ignore, but can lead to confusion.
*
* @param player
* @param from
* @param tick
* @param now
* @param mData
* @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, final IPlayerData pData) {
final boolean debug = pData.isDebugActive(checkType);
// Detect our own set back, choice of reference location.
if (mData.hasTeleported()) {
final Location ref = mData.getTeleported();
// Initiate further action depending on settings.
final PlayerSetBackMethod method = mCc.playerSetBackMethod;
if (method.shouldUpdateFrom()) {
// Attempt to do without a PlayerTeleportEvent as follow up.
// TODO: Doing this on MONITOR priority is problematic, despite optimal.
LocUtil.set(from, ref);
}
if (method.shouldSchedule()) {
// Schedule the teleport, because it might be faster than the next incoming packet.
final IPlayerData pd = DataManager.getPlayerData(player);
if (pd.isPlayerSetBackScheduled()) {
debug(player, "Teleport (set back) already scheduled to: " + ref);
} else if (debug) {
pd.requestPlayerSetBack();
if (debug) {
debug(player, "Schedule teleport (set back) to: " + ref);
}
}
}
// (Position adaption will happen with the teleport on tick, or with the next move.)
}
// Assume the implicit teleport to the from-location (no Bukkit event fires).
// Not reset frequency, but do set yaw.
Combined.resetYawRate(player, from.getYaw(), now, false, pData);
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 (pData.isCheckActive(CheckType.NET_FLYINGFREQUENCY, player)) {
// TODO: A summary method.
pData.getGenericInstance(NetData.class).teleportQueue.onTeleportEvent(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch());
}
}
use of fr.neatmonster.nocheatplus.checks.moving.player.PlayerSetBackMethod in project NoCheatPlus by NoCheatPlus.
the class MovingListener method prepareSetBack.
/**
* Called during PlayerMoveEvent for adjusting to a to-be-done/scheduled set
* back. <br>
* NOTE: Meaning differs from data.onSetBack (to be cleaned up).
*
* @param player
* @param event
* @param newTo
* Must be a cloned or new Location instance, free for whatever
* other plugins do with it.
* @param data
* @param cc
*/
private void prepareSetBack(final Player player, final PlayerMoveEvent event, final Location newTo, final MovingData data, final MovingConfig cc, final IPlayerData pData) {
// 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()));
}
// Reset some data.
data.prepareSetBack(newTo);
// TODO: Might move into prepareSetBack, experimental here.
aux.resetPositionsAndMediumProperties(player, newTo, data, cc);
// Set new to-location, distinguish method by settings.
final PlayerSetBackMethod method = cc.playerSetBackMethod;
if (method.shouldSetTo()) {
// LEGACY: pre-2017-03-24
event.setTo(newTo);
}
if (method.shouldCancel()) {
event.setCancelled(true);
}
// Debug.
if (pData.isDebugActive(checkType)) {
debug(player, "Prepare set back to: " + newTo.getWorld().getName() + "/" + LocUtil.simpleFormatPosition(newTo) + " (" + method.getId() + ")");
}
}
Aggregations