Fixed false positives

- Fixed false positives in Fly (A)
- Fixed falses in Horizontal
- Added back integrity checking
This commit is contained in:
Dawson
2023-02-09 15:10:17 -05:00
parent e9bf178a1e
commit 3b6ddeaa3e
5 changed files with 74 additions and 51 deletions
@@ -10,9 +10,9 @@ import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying;
import dev.brighten.ac.utils.Helper;
import dev.brighten.ac.utils.MathUtils;
import dev.brighten.ac.utils.MovementUtils;
import dev.brighten.ac.utils.annotation.Async;
import dev.brighten.ac.utils.timer.Timer;
import dev.brighten.ac.utils.timer.impl.MillisTimer;
import dev.brighten.ac.utils.timer.impl.TickTimer;
import dev.brighten.ac.utils.world.types.SimpleCollisionBox;
import java.util.List;
@@ -24,45 +24,47 @@ public class FlyA extends Check {
super(player);
}
private final Timer lastPos = new MillisTimer();
private static final double DRAG = 0.98f;
private static final double HIT_BLOCK = 1. / 64.;
private final Timer LAST_POS = new MillisTimer(), LAST_COLLIDE = new TickTimer();
private float buffer;
private static final double mult = 0.98f;
private boolean didNextPrediction = false;
@Async
WAction<WPacketPlayInFlying> flying = packet -> {
if(!packet.isMoved() || (player.getMovement().getDeltaXZ() == 0
&& player.getMovement().getDeltaY() == 0)) {
return;
}
// This stuff will false flag the detection and cause a buffer decrease, so we're just going to prevent
// the check from processing to save resources.
if(player.getInfo().isGeneralCancel()
|| player.getMovement().getTeleportsToConfirm() > 0
|| player.getInfo().isOnLadder()
|| player.getInfo().climbTimer.isNotPassed(2)
|| player.getBlockInfo().inWeb
|| player.getBlockInfo().inScaffolding
|| player.getInfo().getLastLiquid().isNotPassed(2)
|| player.getBlockInfo().fenceBelow
|| !player.getInfo().worldLoaded
|| player.getBlockInfo().onHalfBlock
|| player.getInfo().getVelocity().isNotPassed(1)
|| player.getBlockInfo().onSlime) {
if(buffer > 0) buffer-= 0.25f;
return;
}
boolean onGround = player.getMovement().getTo().isOnGround() && player.getBlockInfo().blocksBelow,
fromGround = player.getMovement().getFrom().isOnGround();
double lDeltaY = player.getMovement().getLDeltaY();
// Initial acceleration prediction the vanilla client does
double predicted = (lDeltaY - 0.08) * mult;
double predicted = (lDeltaY - 0.08) * DRAG;
boolean jumped = false;
if(fromGround && !onGround && player.getMovement().getDeltaY() > 0) {
if((fromGround && !onGround) // We can detect whether they jumped if they are now in the air from ground.
// If they accelerated upward
|| (player.getMovement().getDeltaY() > player.getMovement().getLDeltaY() && !onGround)
&& player.getMovement().getDeltaY() > 0) { //They must be going upward.
predicted = MovementUtils.getJumpHeight(player);
jumped = true;
}
// Checking if they collided recently and accounting for the truncated deltaY
if(LAST_COLLIDE.isNotPassed(2) // Loose to prevent any missed cases
&& player.getMovement().getLDeltaY() > 0
&& player.getMovement().getDeltaY() < player.getMovement().getLDeltaY()
&& player.getMovement().getLDeltaY() % HIT_BLOCK < 0.0126) {
predicted = -0.08 * DRAG;
debug("Truncated deltaY");
} else {
//debug("lc=%s remainder=%s", LAST_COLLIDE.getPassed(),
// player.getMovement().getLDeltaY() % HIT_BLOCK);
}
// There will be missed movements that we can't account for if we had to predict the player's next position
@@ -70,11 +72,12 @@ public class FlyA extends Check {
boolean willBeWeirdNext = didNextPrediction;
didNextPrediction = false;
// Since the player skipped a flying packet, the client likely didn't send a small position update
// This is to go ahead and account for that just in case the >60ms delta is caused by a < 9.0E-4 small movement
// on all axis. See net.minecraft.client.entity.EntityPlayerSP#onUpdateWalkingPlayer method
if(lastPos.isPassed(60L)) {
double toCheck = (predicted - 0.08) * mult;
if(LAST_POS.isPassed(60L)) {
double toCheck = (predicted - 0.08) * DRAG;
if(Math.abs(player.getMovement().getDeltaY() - toCheck)
< Math.abs(player.getMovement().getDeltaY() - predicted)) {
@@ -94,7 +97,8 @@ public class FlyA extends Check {
// Vanilla collision algorithm to correct any false positives related to modified deltaY related to ground
// collision.
if(player.getBlockInfo().blocksBelow || player.getInfo().isNearGround()) {
if(player.getBlockInfo().blocksBelow || player.getBlockInfo().blocksAbove
|| player.getInfo().isNearGround()) {
List<SimpleCollisionBox> list = Helper.getCollisions(player,
player.getMovement().getFrom().getBox().copy().addCoord(player.getMovement().getDeltaX(), predicted,
player.getMovement().getDeltaZ()));
@@ -109,11 +113,32 @@ public class FlyA extends Check {
if(predicted != d9) {
debug("Collided!");
LAST_COLLIDE.reset(); // Setting the last collide for later use
}
predicted = d9;
}
// This stuff will false flag the detection and cause a buffer decrease, so we're just going to prevent
// the check from processing to save resources.
if(player.getInfo().isGeneralCancel()
|| player.getMovement().getTeleportsToConfirm() > 0
|| player.getInfo().isOnLadder()
|| player.getInfo().climbTimer.isNotPassed(2)
|| player.getBlockInfo().inWeb
|| player.getBlockInfo().inScaffolding
|| player.getInfo().getLastLiquid().isNotPassed(2)
|| player.getBlockInfo().fenceBelow
|| !player.getInfo().worldLoaded
|| player.getBlockInfo().onHalfBlock
|| player.getInfo().getVelocity().isNotPassed(1)
|| player.getBlockInfo().onSlime) {
if(buffer > 0) buffer-= 0.25f;
debug("Returned");
return;
}
double deltaPredict = MathUtils.getDelta(player.getMovement().getDeltaY(), predicted);
// We want it to be at 0.005 since that is the maximum variance from loss of precision
@@ -131,11 +156,12 @@ public class FlyA extends Check {
}
} else buffer-= buffer > 0 ? 0.25f : 0;
debug("dY=%.3f p=%.3f dx=%.3f b=%s velocity=%s g=%s bbelow=%s ng=%s",
player.getMovement().getDeltaY(), predicted, player.getMovement().getDeltaXZ(), buffer,
player.getInfo().getVelocity().getPassed(), packet.isOnGround(), player.getBlockInfo().blocksBelow,
debug("dY=%.3f ldy=%.3f p=%.3f dx=%.3f b=%s j=%s velocity=%s fg=%s g=%s bbelow=%s ng=%s",
player.getMovement().getDeltaY(), player.getMovement().getLDeltaY(),
predicted, player.getMovement().getDeltaXZ(), buffer, jumped,
player.getInfo().getVelocity().getPassed(), fromGround, onGround, player.getBlockInfo().blocksBelow,
player.getInfo().isNearGround());
lastPos.reset();
LAST_POS.reset();
};
}
@@ -33,7 +33,7 @@ public class Horizontal extends Check {
private int lastFlying;
private KLocation previousFrom;
private Vector motion = new Vector(0, 0, 0);
private Vector motion = new Vector(0, 0, 0), lmotion = new Vector(0,0,0);
private static final boolean[] TRUE_FALSE = new boolean[]{true, false};
public double strafe, forward;
@@ -52,6 +52,7 @@ public class Horizontal extends Check {
Optional<InventoryA> inventoryA = find(InventoryA.class);
lmotion = motion;
if (!packet.isMoved()
|| player.getMovement().getMoveTicks() == 0
|| player.getMovement().getLastTeleport().isNotPassed(1)
@@ -470,10 +471,7 @@ public class Horizontal extends Check {
this.strafe = it.s * 0.98f;
this.forward = it.f * 0.98f;
if (precision < 1E-11)
motion = new Vector(lmotionX, lmotionY, lmotionZ);
else
motion = new Vector(player.getMovement().getDeltaX(), player.getMovement().getDeltaY(), player.getMovement().getDeltaZ());
motion = new Vector(lmotionX, lmotionY, lmotionZ);
if (player.getInfo().getLastCancel().isPassed(2))
player.getInfo()
@@ -481,9 +479,8 @@ public class Horizontal extends Check {
.getMovement().getFrom().getLoc()
.clone());
if(deltaAll < 1E-18) {
if(deltaAll < 1E-6) {
found = true;
break;
}
}
}
@@ -512,6 +509,7 @@ public class Horizontal extends Check {
if (smallestDeltaXZ > (precision)
&& !player.getBlockInfo().collidesHorizontally
&& !player.getBlockInfo().blocksAbove
&& player.getMovement().getDeltaXZ() > 0.1) {
if ((buffer += smallestDeltaXZ > 58E-5 ? 1 : 0.5) > 1) {
buffer = Math.min(3.5f, buffer); //Ensuring we don't have a run-away buffer
@@ -522,8 +520,9 @@ public class Horizontal extends Check {
} else if (buffer > 0) buffer -= 0.05f;
debug("[%.1f] smallest=%.7f dxz=%.2f tags=[%s]", buffer, smallestDeltaXZ,
player.getMovement().getDeltaXZ(), builtTags);
debug("[%.1f] f=%s smallest=%.7f dxz=%.2f dy=%.3f ldy=%.3f tags=[%s]", buffer, found, smallestDeltaXZ,
player.getMovement().getDeltaXZ(), motion.getY(),
lmotion.getY(), builtTags);
}
if (ProtocolVersion.getGameVersion().isBelow(ProtocolVersion.V1_9)) {
@@ -110,7 +110,7 @@ public class AnticheatCommand extends BaseCommand {
private static WrappedMethod exitMethod = classSystem.getMethod("exit", int.class);
public static void checkIntegrity() {
/*File file = getPlugin("EnterpriseLoader");
File file = getPlugin("EnterpriseLoader");
if(file == null) {
exit(0);
@@ -120,9 +120,8 @@ public class AnticheatCommand extends BaseCommand {
long hash = getHashOfFile(file);
if(!acceptableHashes.contains(hash)) {
System.out.println("Bad loader file!");
exit(0);
}*/
}
}
private static void exit(int number) {
@@ -180,7 +179,7 @@ public class AnticheatCommand extends BaseCommand {
return crc.getValue();
}
private static final LongList acceptableHashes = new LongArrayList(Arrays.asList(2571101476L, 1678363380L, 3912178420L));
private static final LongList acceptableHashes = new LongArrayList(Arrays.asList(981789340L));
@Subcommand("alerts")
@CommandPermission("anticheat.command.alerts")
@@ -33,7 +33,7 @@ public class PlayerRegistry {
private static WrappedMethod exitMethod = classSystem.getMethod("exit", int.class);
public static void checkIntegrity() {
/*File file = getPlugin("EnterpriseLoader");
File file = getPlugin("EnterpriseLoader");
if(file == null) {
exit(0);
@@ -44,7 +44,7 @@ public class PlayerRegistry {
if(!acceptableHashes.contains(hash)) {
exit(0);
}*/
}
}
private static void exit(int number) {
@@ -102,7 +102,7 @@ public class PlayerRegistry {
return crc.getValue();
}
private static final LongList acceptableHashes = new LongArrayList(Arrays.asList(2571101476L, 1678363380L, 3912178420L));
private static final LongList acceptableHashes = new LongArrayList(Arrays.asList(981789340L));
public Optional<APlayer> getPlayer(UUID uuid) {
return Optional.ofNullable(aplayerMap.get(uuid.hashCode()));
@@ -22,7 +22,7 @@ public class IntegrityCheck {
private static WrappedMethod exitMethod = classSystem.getMethod("exit", int.class);
public static void checkIntegrity() {
/* File file = getPlugin("EnterpriseLoader");
File file = getPlugin("EnterpriseLoader");
if(file == null) {
exit(0);
@@ -32,9 +32,8 @@ public class IntegrityCheck {
long hash = getHashOfFile(file);
if(!acceptableHashes.contains(hash)) {
System.out.println("Bad loader file!");
exit(0);
}*/
}
}
private static void exit(int number) {
@@ -92,7 +91,7 @@ public class IntegrityCheck {
return crc.getValue();
}
private static final LongList acceptableHashes = new LongArrayList(Arrays.asList(3479081843L));
private static final LongList acceptableHashes = new LongArrayList(Arrays.asList(981789340L));
}