Make set back method configurable.

We do need to fix behavior to move on, so the intention rather is to
react more flexibly towards debugging results, rather than having people
use random configurations early on. Still this does allow for fall-back
configuration, e.g. for live servers.

NOTES:
* Later we will make the configuration set at 'default' adjust to server
mod and version.
* Overriding checks.moving.setback.method with SET_TO can lead to
PlayerTeleportEvents with TeleportCause.PLUGIN on newer versions of
Spigot, which may conflict with other plugins assuming feature-based
teleportation (possibly resulting in /back locations getting overridden
wrongly). For legacy setups this will be similar to restoring the state
of build 1066 for most.

There could still be places where distinction of the used method is
necessary, which would mean bugs.
This commit is contained in:
asofold 2017-04-07 15:27:18 +02:00
parent c1b12c3fb8
commit ae80e20457
5 changed files with 63 additions and 31 deletions

View File

@ -29,6 +29,7 @@ import fr.neatmonster.nocheatplus.checks.access.CheckConfigFactory;
import fr.neatmonster.nocheatplus.checks.access.ICheckConfig;
import fr.neatmonster.nocheatplus.checks.moving.magic.Magic;
import fr.neatmonster.nocheatplus.checks.moving.model.ModelFlying;
import fr.neatmonster.nocheatplus.checks.moving.player.PlayerSetBackMethod;
import fr.neatmonster.nocheatplus.command.CommandUtil;
import fr.neatmonster.nocheatplus.compat.AlmostBoolean;
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
@ -197,6 +198,7 @@ public class MovingConfig extends ACheckConfig {
public final int speedGrace;
public final boolean enforceLocation;
public final boolean trackBlockMove;
public final PlayerSetBackMethod playerSetBackMethod;
// Vehicles
public final boolean vehicleEnforceLocation;
@ -336,6 +338,9 @@ public class MovingConfig extends ACheckConfig {
&& (config.getBoolean(ConfPaths.COMPATIBILITY_BLOCKS_CHANGETRACKER_PISTONS
// TODO: || other activation flags.
));
final PlayerSetBackMethod playerSetBackMethod = PlayerSetBackMethod.fromString(
"extern.fromconfig", config.getString(ConfPaths.MOVING_SETBACK_METHOD));
this.playerSetBackMethod = playerSetBackMethod.doesThisMakeSense() ? playerSetBackMethod : PlayerSetBackMethod.CAUTIOUS;
traceMaxAge = config.getInt(ConfPaths.MOVING_TRACE_MAXAGE, 200);
traceMaxSize = config.getInt(ConfPaths.MOVING_TRACE_MAXSIZE, 200);

View File

@ -69,6 +69,7 @@ import fr.neatmonster.nocheatplus.checks.moving.player.CreativeFly;
import fr.neatmonster.nocheatplus.checks.moving.player.MorePackets;
import fr.neatmonster.nocheatplus.checks.moving.player.NoFall;
import fr.neatmonster.nocheatplus.checks.moving.player.Passable;
import fr.neatmonster.nocheatplus.checks.moving.player.PlayerSetBackMethod;
import fr.neatmonster.nocheatplus.checks.moving.player.SurvivalFly;
import fr.neatmonster.nocheatplus.checks.moving.util.AuxMoving;
import fr.neatmonster.nocheatplus.checks.moving.util.MovingUtil;
@ -92,7 +93,6 @@ import fr.neatmonster.nocheatplus.components.modifier.IAttributeAccess;
import fr.neatmonster.nocheatplus.components.registry.event.IGenericInstanceHandle;
import fr.neatmonster.nocheatplus.components.registry.feature.IHaveCheckType;
import fr.neatmonster.nocheatplus.components.registry.feature.INeedConfig;
import fr.neatmonster.nocheatplus.components.registry.feature.INotifyReload;
import fr.neatmonster.nocheatplus.components.registry.feature.IRemoveData;
import fr.neatmonster.nocheatplus.components.registry.feature.JoinLeaveListener;
import fr.neatmonster.nocheatplus.components.registry.feature.TickListener;
@ -121,7 +121,7 @@ import fr.neatmonster.nocheatplus.utilities.map.MapUtil;
*
* @see MovingEvent
*/
public class MovingListener extends CheckListener implements TickListener, IRemoveData, IHaveCheckType, INotifyReload, INeedConfig, JoinLeaveListener{
public class MovingListener extends CheckListener implements TickListener, IRemoveData, IHaveCheckType, INeedConfig, JoinLeaveListener{
/**
* Bounce preparation state.
@ -460,12 +460,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
newTo.setPitch(LocUtil.correctPitch(newTo.getPitch()));
}
// Set.
// TODO: Reset positions? enforceLocation?
//event.setTo(newTo); // LEGACY: pre-2017-03-24
if (data.debug) {
debug(player, "Early return on PlayerMoveEvent, set back to: " + newTo);
}
prepareSetBack(player, event, newTo, data, cc);
prepareSetBack(player, event, newTo, data, cc); // Logs set back details.
}
data.joinOrRespawn = false;
return;
@ -1367,15 +1362,21 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
data.prepareSetBack(newTo);
aux.resetPositionsAndMediumProperties(player, newTo, data, cc); // TODO: Might move into prepareSetBack, experimental here.
// Set new to-location.
// TODO: Perhaps need to distinguish by version+settings?
// event.setTo(newTo); // LEGACY: pre-2017-03-24
event.setCancelled(true);
// NOTE: A teleport is scheduled on MONITOR priority, if still relevant.
// Set new to-location, distinguish method by settings.
final PlayerSetBackMethod method = cc.playerSetBackMethod;
if (method.shouldSetTo()) {
event.setTo(newTo); // LEGACY: pre-2017-03-24
}
if (method.shouldCancel()) {
event.setCancelled(true);
}
// NOTE: A teleport is scheduled on MONITOR priority, if set so.
// TODO: enforcelocation?
// Debug.
if (data.debug) {
debug(player, "Set back to: " + newTo.getWorld() + StringUtil.fdec3.format(newTo.getX()) + ", " + StringUtil.fdec3.format(newTo.getY()) + ", " + StringUtil.fdec3.format(newTo.getZ()));
debug(player, "Prepare set back to: " + newTo.getWorld().getName() + "/"
+ LocUtil.simpleFormatPosition(newTo) + " (" + method.getId() + ")");
}
}
@ -1439,18 +1440,24 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
// Detect our own set back, choice of reference location.
if (mData.hasSetBack()) {
final Location ref = mData.getTeleported();
// TODO: Initiate further action depending on version/capabilities (update getFrom()).
LocUtil.set(from, ref); // Attempt to do without a PlayerTeleportEvent as follow up.
// Schedule the teleport, because it might be faster than the next incoming packet.
final UUID playerId = player.getUniqueId();
if (!TickTask.isPlayerGoingToBeSetBack(playerId)) {
TickTask.requestPlayerSetBack(playerId);
if (mData.debug) {
debug(player, "Schedule teleport (set back) to: " + ref);
}
// Initiate further action depending on settings.
final PlayerSetBackMethod method = mCc.playerSetBackMethod;
if (method.shouldUpdateFrom()) {
// Attempt to do without a PlayerTeleportEvent as follow up.
LocUtil.set(from, ref);
}
else if (mData.debug) {
debug(player, "Teleport (set back) already scheduled to: " + ref);
if (method.shouldSchedule()) {
// Schedule the teleport, because it might be faster than the next incoming packet.
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 (mData.debug) {
debug(player, "Teleport (set back) already scheduled to: " + ref);
}
}
// (Position adaption will happen with the teleport on tick, or with the next move.)
}

View File

@ -26,11 +26,14 @@ public class PlayerSetBackMethod {
// DEFAULTS
public static final PlayerSetBackMethod LEGACY = new PlayerSetBackMethod(SET_TO);
public static final PlayerSetBackMethod CAUTIOUS = new PlayerSetBackMethod(CANCEL | UPDATE_FROM | SCHEDULE);
public static final PlayerSetBackMethod MODERN = new PlayerSetBackMethod(CANCEL | UPDATE_FROM);
public static final PlayerSetBackMethod LEGACY = new PlayerSetBackMethod("default.legacy",
SET_TO);
public static final PlayerSetBackMethod CAUTIOUS = new PlayerSetBackMethod("default.cautious",
CANCEL | UPDATE_FROM | SCHEDULE);
public static final PlayerSetBackMethod MODERN = new PlayerSetBackMethod("default.modern",
CANCEL | UPDATE_FROM);
public static final PlayerSetBackMethod fromString(String input) {
public static final PlayerSetBackMethod fromString(String name, String input) {
// TODO: Perhaps complain for incomplete/wrong content, much later.
input = input.toLowerCase().replaceAll("_", "");
int flags = 0;
@ -46,18 +49,32 @@ public class PlayerSetBackMethod {
if (input.contains("schedule")) {
flags |= SCHEDULE;
}
return new PlayerSetBackMethod(flags);
return new PlayerSetBackMethod(name, flags);
}
// INSTANCE
private final String id;
private final int flags;
public PlayerSetBackMethod(int flags) {
public PlayerSetBackMethod(String id, int flags) {
this.id = id;
this.flags = flags;
}
public String getId() {
return id;
}
/**
* ?
* @return
*/
public boolean doesThisMakeSense() {
return (flags & (SET_TO | CANCEL | SCHEDULE)) != 0;
}
public boolean shouldSetTo() {
return (flags & SET_TO) != 0;
}

View File

@ -662,6 +662,8 @@ public abstract class ConfPaths {
public static final String MOVING_ASSUMESPRINT = MOVING + "assumesprint";
public static final String MOVING_SPEEDGRACE = MOVING + "speedgrace";
public static final String MOVING_ENFORCELOCATION = MOVING + "enforcelocation";
private static final String MOVING_SETBACK = MOVING + "setback.";
public static final String MOVING_SETBACK_METHOD = MOVING_SETBACK + "method";
private static final String MOVING_TRACE = MOVING + "trace.";
public static final String MOVING_TRACE_MAXAGE = MOVING_TRACE + "maxage";

View File

@ -472,6 +472,7 @@ public class DefaultConfig extends ConfigFile {
set(ConfPaths.MOVING_ASSUMESPRINT, true);
set(ConfPaths.MOVING_SPEEDGRACE, 4.0);
set(ConfPaths.MOVING_ENFORCELOCATION, "default");
set(ConfPaths.MOVING_SETBACK_METHOD, "default");
// Vehicles.
set(ConfPaths.MOVING_VEHICLE_PREVENTDESTROYOWN, true);