mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-09-28 22:47:32 +02:00
Add a workaround case for skipping a vehicle move event. Adjust ids.
* Add a late in-air phase skip once workaround. * Adjust oddSlope workaround ids to be lower-case and not contain wrpt. * Add workaround counter for back to surface.
This commit is contained in:
parent
f9d0a1a6ca
commit
ab5ca5c9dc
@ -1,5 +1,10 @@
|
||||
package fr.neatmonster.nocheatplus.checks.moving.magic;
|
||||
|
||||
import fr.neatmonster.nocheatplus.checks.moving.MovingData;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.model.VehicleMoveData;
|
||||
import fr.neatmonster.nocheatplus.checks.workaround.WRPT;
|
||||
import fr.neatmonster.nocheatplus.utilities.RichEntityLocation;
|
||||
|
||||
/**
|
||||
* Magic for vehicles.
|
||||
*
|
||||
@ -40,6 +45,78 @@ public class MagicVehicle {
|
||||
public static final double boatGravityMax = Magic.GRAVITY_MAX + Magic.GRAVITY_SPAN;
|
||||
/** The speed up to which gravity mechanics roughly work. */
|
||||
public static final double boatVerticalFallTarget = 3.7;
|
||||
public static final double boatMaxBackToSurfaceAscend = 1.5;
|
||||
public static final double boatMaxBackToSurfaceAscend = 3.25;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param thisMove
|
||||
* @param minDescend Case-sensitive.
|
||||
* @param maxDescend Case-sensitive.
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public static boolean oddInAir(final VehicleMoveData thisMove, final double minDescend, final double maxDescend, final MovingData data) {
|
||||
// TODO: Guard by past move tracking, instead of minDescend and maxDescend.
|
||||
// (Try individual if this time, let JIT do the rest.)
|
||||
if (thisMove.vDistance < 0 && oddInAirDescend(thisMove, minDescend, maxDescend, data)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param thisMove
|
||||
* @param minDescend Case-sensitive.
|
||||
* @param maxDescend Case-sensitive.
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
private static boolean oddInAirDescend(final VehicleMoveData thisMove, final double minDescend, final double maxDescend, final MovingData data) {
|
||||
// TODO: Guard by past move tracking, instead of minDescend and maxDescend.
|
||||
// (Try individual if this time, let JIT do the rest.)
|
||||
if (thisMove.vDistance < 2.0 * minDescend && thisMove.vDistance > 2.0 * maxDescend
|
||||
// TODO: Past move tracking.
|
||||
// TODO: Fall distances?
|
||||
&& data.ws.use(WRPT.W_M_V_ENV_INAIR_SKIP)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* In-water (water-water) cases.
|
||||
* @param thisMove
|
||||
* @return
|
||||
*/
|
||||
public static boolean oddInWater(final RichEntityLocation from, final RichEntityLocation to,
|
||||
final VehicleMoveData thisMove, final MovingData data) {
|
||||
if (thisMove.vDistance > 0.0) {
|
||||
if (oddInWaterAscend(from, to, thisMove, data)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ascending in-water (water-water).
|
||||
* @param thisMove
|
||||
* @return
|
||||
*/
|
||||
private static boolean oddInWaterAscend(final RichEntityLocation from, final RichEntityLocation to,
|
||||
final VehicleMoveData thisMove, final MovingData data) {
|
||||
// (Try individual if this time, let JIT do the rest.)
|
||||
if (thisMove.vDistance > MagicVehicle.maxAscend && thisMove.vDistance < MagicVehicle.boatMaxBackToSurfaceAscend
|
||||
&& data.ws.use(WRPT.W_M_V_ENV_INWATER_BTS)) {
|
||||
// (Assume players can't control sinking boats for now.)
|
||||
// TODO: Limit by more side conditions (e.g. to is on the surface and in-medium count is about 1, past moves).
|
||||
// TODO: Checking for surface can be complicated. Might check blocks at location and above and accept if any is not liquid.
|
||||
// (Always smaller than previous descending move, roughly to below 0.5 above water.)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ import fr.neatmonster.nocheatplus.checks.moving.MovingData;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.location.setback.SetBackEntry;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.magic.MagicVehicle;
|
||||
import fr.neatmonster.nocheatplus.checks.moving.model.VehicleMoveData;
|
||||
import fr.neatmonster.nocheatplus.checks.workaround.WRPT;
|
||||
import fr.neatmonster.nocheatplus.logging.Streams;
|
||||
import fr.neatmonster.nocheatplus.utilities.BlockCache;
|
||||
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
|
||||
@ -63,6 +64,7 @@ public class VehicleEnvelope extends Check {
|
||||
tags.add("entity." + vehicle.getType());
|
||||
if (data.debug) {
|
||||
debugDetails.clear();
|
||||
data.ws.setJustUsedIds(debugDetails); // Add just used workaround ids to this list directly, for now.
|
||||
}
|
||||
final boolean violation;
|
||||
if (vehicle instanceof LivingEntity) {
|
||||
@ -74,6 +76,7 @@ public class VehicleEnvelope extends Check {
|
||||
}
|
||||
if (data.debug && !debugDetails.isEmpty()) {
|
||||
debugDetails(player);
|
||||
debugDetails.clear();
|
||||
}
|
||||
if (violation) {
|
||||
// Add up one for now.
|
||||
@ -198,18 +201,16 @@ public class VehicleEnvelope extends Check {
|
||||
if (maxDistHorizontal(thisMove, MagicVehicle.boatMaxDistanceHorizontal)) {
|
||||
return true;
|
||||
}
|
||||
// Maximum descend speed.
|
||||
if (thisMove.vDistance < -MagicVehicle.maxDescend) {
|
||||
// TODO: At times it looks like one move is skipped, resulting in double distance ~ -5 and at the same time 'vehicle moved too quickly'.
|
||||
// TODO: Test with log this to console to see the order of things.
|
||||
tags.add("descend_much");
|
||||
return true;
|
||||
}
|
||||
// TODO: Could limit descend by 2*maxDescend, ascend by much less.
|
||||
// Medium dependent checking.
|
||||
boolean violation = false;
|
||||
boolean checkAscendMuch = true;
|
||||
boolean checkDescendMuch = true;
|
||||
// (Assume boats can't climb.)
|
||||
final boolean fromIsSafeMedium = from.isInWater() || from.isOnGround() || from.isInWeb();
|
||||
final boolean toIsSafeMedium = to.isInWater() || to.isOnGround() || to.isInWeb();
|
||||
final boolean inAir = !fromIsSafeMedium && !toIsSafeMedium;
|
||||
// TODO: Split code to methods.
|
||||
if (from.isInWeb()) {
|
||||
// TODO: Check anything?
|
||||
if (data.debug) {
|
||||
@ -228,12 +229,13 @@ public class VehicleEnvelope extends Check {
|
||||
// TODO: Should still cover extreme moves here.
|
||||
|
||||
// Special case moving up after falling.
|
||||
// TODO: Move to MagicVehicle.oddInWater
|
||||
// TODO: Check past moves for falling (not yet available).
|
||||
// TODO: Check if the target location somehow is the surface.
|
||||
if (thisMove.vDistance > MagicVehicle.maxAscend && thisMove.vDistance < MagicVehicle.boatMaxBackToSurfaceAscend) {
|
||||
if (MagicVehicle.oddInWater(from, to, thisMove, data)) {
|
||||
// (Assume players can't control sinking boats for now.)
|
||||
checkAscendMuch = false;
|
||||
tags.add("back_to_surface");
|
||||
checkDescendMuch = checkAscendMuch = false;
|
||||
violation = false;
|
||||
}
|
||||
}
|
||||
else if (from.isOnGround() && to.isOnGround()) {
|
||||
@ -253,7 +255,7 @@ public class VehicleEnvelope extends Check {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!fromIsSafeMedium && !toIsSafeMedium) {
|
||||
else if (inAir) {
|
||||
// In-air move.
|
||||
// TODO: Common in-air accounting check with parameters.
|
||||
if (data.debug) {
|
||||
@ -263,11 +265,11 @@ public class VehicleEnvelope extends Check {
|
||||
tags.add("ascend_at_all");
|
||||
return true;
|
||||
}
|
||||
// TODO: Workaround: 60+ in-air phase for 2* lastyDist > yDist > 2 * (lastyDist + MagicVehicle.boatGravityMax). Possibly once per in-air phase.
|
||||
// Absolute vertical distance to set back.
|
||||
// TODO: Add something like this.
|
||||
// final double setBackYdistance = to.getY() - data.vehicleSetBacks.getValidSafeMediumEntry().getY();
|
||||
// if (data.sfJumpPhase > 4) {
|
||||
// TODO: Realistic cap.
|
||||
// double estimate = Math.min(2.0, MagicVehicle.boatGravityMin * ((double) data.sfJumpPhase / 4.0) * ((double) data.sfJumpPhase / 4.0 + 1.0) / 2.0);
|
||||
// if (setBackYdistance > -estimate) {
|
||||
// tags.add("slow_fall_vdistsb");
|
||||
@ -275,15 +277,24 @@ public class VehicleEnvelope extends Check {
|
||||
// }
|
||||
// }
|
||||
// Slow falling (vdist).
|
||||
final double minDescend = -MagicVehicle.boatGravityMin * data.sfJumpPhase;
|
||||
final double maxDescend = -MagicVehicle.boatGravityMax * data.sfJumpPhase - 0.5;
|
||||
if (data.sfJumpPhase > 1 && thisMove.vDistance > -MagicVehicle.boatVerticalFallTarget
|
||||
&& thisMove.vDistance > - MagicVehicle.boatGravityMin * data.sfJumpPhase) {
|
||||
&& thisMove.vDistance > minDescend) {
|
||||
tags.add("slow_fall_vdist");
|
||||
return true;
|
||||
violation = true;
|
||||
}
|
||||
// Fast falling (vdist).
|
||||
if (data.sfJumpPhase > 1 && thisMove.vDistance < -MagicVehicle.boatGravityMax * data.sfJumpPhase - 0.5) {
|
||||
else if (data.sfJumpPhase > 1 && thisMove.vDistance < maxDescend) {
|
||||
tags.add("fast_fall_vdist");
|
||||
return true;
|
||||
violation = true;
|
||||
}
|
||||
if (violation) {
|
||||
// Post violation detection workarounds.
|
||||
if (MagicVehicle.oddInAir(thisMove, minDescend, maxDescend, data)) {
|
||||
violation = false;
|
||||
checkDescendMuch = checkAscendMuch = false; // (Full envelope has been checked.)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -299,24 +310,41 @@ public class VehicleEnvelope extends Check {
|
||||
// Maximum ascend speed.
|
||||
if (checkAscendMuch && thisMove.vDistance > MagicVehicle.maxAscend) {
|
||||
tags.add("ascend_much");
|
||||
return true;
|
||||
violation = true;
|
||||
}
|
||||
// Maximum descend speed.
|
||||
if (checkDescendMuch && thisMove.vDistance < -MagicVehicle.maxDescend) {
|
||||
// TODO: At times it looks like one move is skipped, resulting in double distance ~ -5 and at the same time 'vehicle moved too quickly'.
|
||||
// TODO: Test with log this to console to see the order of things.
|
||||
tags.add("descend_much");
|
||||
violation = true;
|
||||
}
|
||||
|
||||
// No violation.
|
||||
// TODO: sfJumpPhase is abused for in-air move counting here.
|
||||
if (toIsSafeMedium) {
|
||||
data.vehicleSetBacks.setSafeMediumEntry(to);
|
||||
data.sfJumpPhase = 0;
|
||||
if (!violation) {
|
||||
// No violation.
|
||||
// TODO: sfJumpPhase is abused for in-air move counting here.
|
||||
if (inAir) {
|
||||
data.sfJumpPhase ++;
|
||||
}
|
||||
else {
|
||||
// Adjust set-back.
|
||||
if (toIsSafeMedium) {
|
||||
data.vehicleSetBacks.setSafeMediumEntry(to);
|
||||
data.sfJumpPhase = 0;
|
||||
}
|
||||
else if (fromIsSafeMedium) {
|
||||
data.vehicleSetBacks.setSafeMediumEntry(from);
|
||||
data.sfJumpPhase = 0;
|
||||
}
|
||||
// Reset the resetNotInAir workarounds.
|
||||
data.ws.resetConditions(WRPT.G_RESET_NOTINAIR);
|
||||
}
|
||||
data.vehicleSetBacks.setLastMoveEntry(to);
|
||||
// TODO: Workaround - reset moving set-backs.
|
||||
|
||||
}
|
||||
else if (fromIsSafeMedium) {
|
||||
data.vehicleSetBacks.setSafeMediumEntry(from);
|
||||
data.sfJumpPhase = 0;
|
||||
}
|
||||
else {
|
||||
data.sfJumpPhase ++;
|
||||
}
|
||||
data.vehicleSetBacks.setLastMoveEntry(to);
|
||||
return false;
|
||||
|
||||
return violation;
|
||||
}
|
||||
|
||||
private boolean checkMinecart(final Player player, final Entity vehicle,
|
||||
|
@ -35,8 +35,8 @@ public class WRPT extends SimpleWorkaroundRegistry {
|
||||
public static final String W_M_SF_WEB_MICROGRAVITY2 = "m.sf.web.microgravity2";
|
||||
|
||||
// oddSlope
|
||||
public static final String W_M_SF_SLOPE1 = "m.sf.WRPT.SLOPE1";
|
||||
public static final String W_M_SF_SLOPE2 = "m.sf.WRPT.SLOPE2";
|
||||
public static final String W_M_SF_SLOPE1 = "m.sf.slope1";
|
||||
public static final String W_M_SF_SLOPE2 = "m.sf.slope2";
|
||||
|
||||
// TODO: oddLiquid
|
||||
|
||||
@ -46,12 +46,24 @@ public class WRPT extends SimpleWorkaroundRegistry {
|
||||
|
||||
// (TODO: oddElytra)
|
||||
|
||||
// Vehicle: oddInAirDescend
|
||||
/**
|
||||
* Vehicle descending in-air, skip one vehicle move event during late in-air
|
||||
* phase.
|
||||
*/
|
||||
public static final String W_M_V_ENV_INAIR_SKIP = "m.v.env.inair.skip";
|
||||
/** Just a counter for back to surface for in-water moves (water-water). */
|
||||
public static final String W_M_V_ENV_INWATER_BTS = "m.v.env.inwater.bts";
|
||||
|
||||
///////////////////////
|
||||
// Group ids.
|
||||
///////////////////////
|
||||
|
||||
// MOVING_SURVIVALFLY
|
||||
/** Group: Reset when not in air jump phase. */
|
||||
/**
|
||||
* Group: Reset when not in air jump phase. Both used for players and
|
||||
* vehicles with players inside.
|
||||
*/
|
||||
public static final String G_RESET_NOTINAIR = "reset.notinair";
|
||||
|
||||
///////////////////////
|
||||
@ -73,6 +85,7 @@ public class WRPT extends SimpleWorkaroundRegistry {
|
||||
// Reset once on ground or reset-condition.
|
||||
final WorkaroundCountDown[] resetNotInAir = new WorkaroundCountDown[] {
|
||||
new WorkaroundCountDown(W_M_SF_SLIME_JP_2X0, 1),
|
||||
new WorkaroundCountDown(W_M_V_ENV_INAIR_SKIP, 1),
|
||||
};
|
||||
ws_moving.addAll(Arrays.asList(resetNotInAir));
|
||||
setWorkaroundBluePrint(resetNotInAir);
|
||||
@ -80,13 +93,15 @@ public class WRPT extends SimpleWorkaroundRegistry {
|
||||
|
||||
// Just counters.
|
||||
final String[] counters = new String[] {
|
||||
// Player
|
||||
W_M_SF_WEB_0V1,
|
||||
W_M_SF_WEB_0V2,
|
||||
W_M_SF_WEB_MICROGRAVITY1,
|
||||
W_M_SF_WEB_MICROGRAVITY2,
|
||||
W_M_SF_SLOPE1,
|
||||
W_M_SF_SLOPE2,
|
||||
// TODO: ALL workaorunds.
|
||||
// Vehicle
|
||||
W_M_V_ENV_INWATER_BTS
|
||||
};
|
||||
for (final String id : counters) {
|
||||
final WorkaroundCounter counter = new WorkaroundCounter(id);
|
||||
|
@ -53,7 +53,7 @@ public class TeleportUtil {
|
||||
vehicle.eject();
|
||||
// TODO: Confirm eject worked, handle if not.
|
||||
vehicleTeleported = vehicle.teleport(LocUtil.clone(location), TeleportCause.PLUGIN);
|
||||
vehicle.setVelocity(new Vector(0.0, 0.0, 0.0)); // TODO: Does not solve 1.9.2 rubber band issue.
|
||||
vehicle.setVelocity(new Vector(0.0, 0.0, 0.0)); // TODO: Likely not relevant, should remove.
|
||||
}
|
||||
}
|
||||
else if (passenger == null) {
|
||||
@ -65,7 +65,8 @@ public class TeleportUtil {
|
||||
data.prepareSetBack(location);
|
||||
playerTeleported = player.teleport(LocUtil.clone(location));
|
||||
data.resetTeleported(); // Just in case.
|
||||
player.setVelocity(new Vector(0.0, 0.0, 0.0)); // TODO: Does not solve 1.9.2 rubber band issue.
|
||||
// TODO: Consider resetting player set-backs.
|
||||
player.setVelocity(new Vector(0.0, 0.0, 0.0)); // TODO: Likely not relevant, should remove.
|
||||
// TODO: Magic 1.0, plus is this valid with horse, dragon...
|
||||
if (playerIsPassenger && playerTeleported && vehicleTeleported && player.getLocation().distance(vehicle.getLocation(useLoc)) < 1.0) {
|
||||
// Somewhat check against tp showing something wrong (< 1.0).
|
||||
|
Loading…
Reference in New Issue
Block a user