Reduce false positives with elytra: lift off and boost.

Missing (false positives):
* Bounding box, eye height.

Missing (cheating):
* Better abort conditions (e.g. inside water / lava).
* Friction inside water / lava.
This commit is contained in:
asofold 2017-05-06 20:37:44 +02:00
parent 8c6ebbaad8
commit bff58b83db
5 changed files with 57 additions and 8 deletions

View File

@ -306,7 +306,11 @@ public class BlockInteractListener extends CheckListener {
* HIGHEST to account for other plugins.
*/
// Elytra boost.
if (event.getAction() == Action.RIGHT_CLICK_AIR
final Block block = event.getClickedBlock();
if ((event.getAction() == Action.RIGHT_CLICK_AIR
|| event.getAction() == Action.RIGHT_CLICK_BLOCK
&& block != null && BlockProperties.isLiquid(block.getType())
)
&& event.isCancelled() && event.useItemInHand() != Result.DENY) {
final ItemStack stack = Bridge1_9.getUsedItem(player, event);
if (stack != null && BridgeMisc.maybeElytraBoost(player, stack.getType())) {

View File

@ -107,6 +107,12 @@ public class MovingConfig extends ACheckConfig {
return ccNew;
}
// Model flying ids.
public static final String ID_JETPACK_ELYTRA = "jetpack.elytra";
public static final String ID_POTION_LEVITATION = "potion.levitation";
// INSTANCE
public final boolean ignoreCreative;
public final boolean ignoreAllowFlight;
@ -256,9 +262,9 @@ public class MovingConfig extends ACheckConfig {
for (final GameMode gameMode : GameMode.values()) {
flyingModelGameMode.put(gameMode, new ModelFlying("gamemode." + gameMode.name().toLowerCase(), config, ConfPaths.MOVING_CREATIVEFLY_MODEL + (gameMode.name().toLowerCase()) + ".", defaultModel));
}
flyingModelLevitation = new ModelFlying("potion.levitation", config, ConfPaths.MOVING_CREATIVEFLY_MODEL + "levitation.", defaultModel);
flyingModelLevitation = new ModelFlying(ID_POTION_LEVITATION, config, ConfPaths.MOVING_CREATIVEFLY_MODEL + "levitation.", defaultModel);
flyingModelLevitation.setScaleLevitationEffect(true); // Pirate.
flyingModelElytra = new ModelFlying("jetpack.elytra", config, ConfPaths.MOVING_CREATIVEFLY_MODEL + "elytra.", defaultModel);
flyingModelElytra = new ModelFlying(ID_JETPACK_ELYTRA, config, ConfPaths.MOVING_CREATIVEFLY_MODEL + "elytra.", defaultModel);
creativeFlyActions = config.getOptimizedActionList(ConfPaths.MOVING_CREATIVEFLY_ACTIONS, Permissions.MOVING_CREATIVEFLY);
morePacketsCheck = config.getBoolean(ConfPaths.MOVING_MOREPACKETS_CHECK);

View File

@ -250,6 +250,8 @@ public class MovingData extends ACheckData implements IRemoveSubCheckData {
public int combinedMediumHCount = 0;
/** Sum of actual speed / base speed for horizontal moving within air + certain medium. */
public double combinedMediumHValue = 0.0;
/** Count combined medium successive moves, permanent. */
public int combinedMediumPermanentCount = 0; // TODO: Not 100% convinced of usefulness.
// Locations shared between all checks.
private Location setBack = null;

View File

@ -295,6 +295,7 @@ public class SurvivalFly extends Check {
// Handle ice.
// TODO: Re-model ice stuff and other (e.g. general thing: ground-modifier + reset conditions).
if (thisMove.from.onIce || thisMove.to.onIce) {
// TODO: 1. Test if this can simply be removed. 2. Ensure data.sfOnIce resets with a violation.
data.sfOnIce = 20;
}
else if (data.sfOnIce > 0) {
@ -303,6 +304,11 @@ public class SurvivalFly extends Check {
data.sfOnIce--;
}
/*
* TODO: if (Bridge1_9.isGlidingWithElytra(player)) { // Force stop
* gliding?
*/
// TODO: Remove these local variables ?
double hAllowedDistance = 0.0, hDistanceAboveLimit = 0.0, hFreedom = 0.0;
if (hasHdist) {
@ -565,10 +571,12 @@ public class SurvivalFly extends Check {
// TODO: Is above stairs ?
}
// Count how long one is moving inside of a medium.
data.combinedMediumPermanentCount ++;
if (oldLiftOffEnvelope != data.liftOffEnvelope) {
data.insideMediumCount = 0;
data.combinedMediumHCount = 0;
data.combinedMediumHValue = 0.0;
data.combinedMediumPermanentCount = 0;
}
else if (!resetFrom || !resetTo) {
data.insideMediumCount = 0;

View File

@ -30,6 +30,7 @@ import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.checks.moving.MovingConfig;
import fr.neatmonster.nocheatplus.checks.moving.MovingData;
import fr.neatmonster.nocheatplus.checks.moving.magic.Magic;
import fr.neatmonster.nocheatplus.checks.moving.model.LiftOffEnvelope;
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
import fr.neatmonster.nocheatplus.checks.moving.model.PlayerMoveData;
import fr.neatmonster.nocheatplus.checks.moving.player.PlayerSetBackMethod;
@ -96,8 +97,8 @@ public class MovingUtil {
}
/**
* Prerequisite is Bridge1_9.isGlidingWithElytra(player) having returned
* true.
* Consistency / cheat check. Prerequisite is
* Bridge1_9.isGlidingWithElytra(player) having returned true.
*
* @param player
* @param fromLocation
@ -107,9 +108,37 @@ public class MovingUtil {
*/
public static boolean isGlidingWithElytraValid(final Player player, final PlayerLocation fromLocation,
final MovingData data, final MovingConfig cc) {
// TODO: Extend by thisMove / past moves checking (partly a cheat detection).
// TODO: Short touch of water/vines (/ground?) is possible - use past moves or in-medium-count.
return !fromLocation.isOnGroundOrResetCond();
// Prevent forms of noclip - could be too coarse / false positives.
if (!fromLocation.isPassable()) {
return false;
}
// TODO: Confine/relax more, if needed (in-medium count, past moves).
// TODO: TEST LAVA (ordinary and boost, lift off and other).
// Check start glide conditions.
final PlayerMoveData firstPastMove = data.playerMoves.getFirstPastMove();
if (!firstPastMove.toIsValid || firstPastMove.modelFlying == null
|| !MovingConfig.ID_JETPACK_ELYTRA.equals(firstPastMove.modelFlying.id)) {
// Treat as a lift off.
return canLiftOffWithElytra(fromLocation, data);
}
// TODO: Past map states might allow lift off (...).
// TODO: Other abort conditions.
// Only the web can stop a player who isn't propelled by a rocket.
return data.fireworksBoostDuration > 0 || !fromLocation.isInWeb();
}
private static boolean canLiftOffWithElytra(final PlayerLocation fromLocation, final MovingData data) {
return !fromLocation.isInLiquid() && !fromLocation.isInWeb()
&& (data.liftOffEnvelope == LiftOffEnvelope.LIMIT_NEAR_GROUND
|| data.liftOffEnvelope == LiftOffEnvelope.NORMAL);
// && !fromLocation.isOnGround() // TODO: Nice to have: been in air slightly before.
//|| data.combinedMediumPermanentCount > data.insideMediumCount
//&& data.combinedMediumPermanentCount > 15;
}
/**