False positive fixes

- Added new Speed check
- Fixing false positives with Fly (C) under blocks
- Fixed false positives with stepping on Fly (C) and Fly (D)
- Fixed liquid false positives with Fly (C) and (D)
- Fixed horizontal friction-based false positives, like switching between ice and regular blocks (used wrong friction)
- Fixed NoFall (B) false positive when in liquid and under block pressing space bar
This commit is contained in:
Dawson
2022-08-27 14:27:56 -04:00
parent 5e071e3690
commit 25606997fa
18 changed files with 201 additions and 23 deletions
+4 -2
View File
@@ -113,14 +113,16 @@ public class Anticheat extends JavaPlugin {
getConfig().set("database.password", UUID.randomUUID().toString());
}
HandlerAbstract.init();
this.keepaliveProcessor = new KeepaliveProcessor();
this.checkManager = new CheckManager();
this.playerRegistry = new PlayerRegistry();
this.packetHandler = new PacketHandler();
logManager = new LoggerManager();
keepaliveProcessor.start();
HandlerAbstract.init();
logManager.init();
alog(Color.Green + "Loading WorldInfo system...");
@@ -113,7 +113,8 @@ public class Check implements ECheck {
if(!toDebug.equals(player.getUuid())) continue;
ComponentBuilder builder = new ComponentBuilder("[DEBUG] ").color(ChatColor.RED);
ComponentBuilder builder = new ComponentBuilder("[ " + getName() + ": " + player.getBukkitPlayer().getName() + "] ")
.color(ChatColor.RED);
BaseComponent[] message =
builder.append(String.format(information, variables)).color(ChatColor.GRAY).create();
@@ -50,7 +50,9 @@ public class Aim extends Check {
boolean increasing = deltaYaw > deltaX || deltaPitch > deltaY;
boolean flagged = false;
if(player.getMovement().getPitchGCD() < 0.007 && lastGrid.isPassed() && player.getMovement().getLastHighRate().isNotPassed(3)) {
if(player.getMovement().getPitchGCD() < 0.007 && lastGrid.isPassed()
&& !player.getMovement().isCinematic()
&& player.getMovement().getLastHighRate().isNotPassed(3)) {
if(deltaPitch < 10 && ++buffer > 8) {
flag("%s", player.getMovement().getPitchGCD());
}
@@ -37,8 +37,14 @@ public class FlyC extends Check {
// Adding all possible velocity deltaY.
player.getVelocityHandler().getPossibleVectors().forEach(vec -> possibleHeights.add(vec.getY()));
if(player.getBlockInfo().onHalfBlock) {
possibleHeights.add(0.5);
}
jumpCheck: {
if(!jumped) break jumpCheck;
if(!jumped || player.getInfo().blockAbove.isNotPassed(1)
|| player.getInfo().slimeTimer.isNotPassed(1)
|| player.getInfo().lastLiquid.isNotPassed(1)) break jumpCheck;
// We want to check all possible heights
for (Double possibleHeight : possibleHeights) {
@@ -18,7 +18,8 @@ public class FlyD extends Check {
@Async
WAction<WPacketPlayInFlying> flyingPacket = packet -> {
if(!packet.isMoved() || player.getMovement().getMoveTicks() <= 2) return;
if(!packet.isMoved() || player.getMovement().getMoveTicks() <= 2
|| player.getBlockInfo().miscNear || player.getInfo().isGeneralCancel()) return;
double deltaY = player.getMovement().getDeltaY();
if(deltaY > 0)
@@ -52,6 +52,7 @@ public class NoFallB extends Check {
&& player.getInfo().isNearGround();
if(!packet.isOnGround() && player.getInfo().vehicleSwitch.isPassed(20)
&& !player.getBlockInfo().inLiquid
&& ((player.getInfo().isServerGround() || player.getBlockInfo().blocksBelow)
&& dground && !player.getBlockInfo().onHalfBlock)) {
if((airBuffer +=10) > 30) {
@@ -8,6 +8,7 @@ import dev.brighten.ac.data.APlayer;
import dev.brighten.ac.packet.ProtocolVersion;
import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying;
import dev.brighten.ac.utils.BlockUtils;
import dev.brighten.ac.utils.KLocation;
import dev.brighten.ac.utils.MathHelper;
import dev.brighten.ac.utils.math.IntVector;
import org.bukkit.Material;
@@ -24,7 +25,7 @@ public class Horizontal extends Check {
private float buffer;
private Vector velocity;
private int vTicks;
private KLocation previousFrom;
private static final boolean[] TRUE_FALSE = new boolean[]{true, false};
public double strafe, forward;
@@ -34,15 +35,15 @@ public class Horizontal extends Check {
}
WAction<WPacketPlayInFlying> flying = packet -> {
Block underBlock = BlockUtils.getBlock(player.getMovement().getTo().getLoc()
.toLocation(player.getBukkitPlayer().getWorld())
.subtract(0, 1, 0)),
lastUnderBlock = BlockUtils.getBlock(player.getMovement().getFrom().getLoc()
.toLocation(player.getBukkitPlayer().getWorld())
.subtract(0, 1, 0));
check:
{
Block underBlock = BlockUtils.getBlock((previousFrom != null ? player.getMovement().getFrom().getLoc() : player.getMovement().getTo().getLoc())
.toLocation(player.getBukkitPlayer().getWorld())
.subtract(0, 1, 0)),
lastUnderBlock = BlockUtils.getBlock((previousFrom != null ? previousFrom : player.getMovement().getFrom().getLoc())
.toLocation(player.getBukkitPlayer().getWorld())
.subtract(0, 1, 0));
if (underBlock == null || lastUnderBlock == null)
break check;
@@ -147,7 +148,7 @@ public class Horizontal extends Check {
}
//Less than 0.05
if(((lmotionX * lmotionX) + (lmotionZ * lmotionZ)) < 0.0025 && player.getMovement().getDeltaXZ() < 0.1) {
if(((lmotionX * lmotionX) + (lmotionZ * lmotionZ)) < 0.0025 && player.getMovement().getDeltaXZ() < 0.2) {
break check;
}
// Attack slowdown
@@ -262,11 +263,12 @@ public class Horizontal extends Check {
} else debug("bad movement");
} else if (buffer > 0) buffer -= 0.05f;
debug("smallest=%s pm=%.5f dxz=%.5f b=%.1f f/s=%.2f,%.2f soulsand=%s", smallestDelta, pmotion,
debug("smallest=%s f=%s lf=%s pm=%.5f dxz=%.5f b=%.1f f/s=%.2f,%.2f soulsand=%s ", smallestDelta, frictionList, lfrictionList, pmotion,
player.getMovement().getDeltaXZ(), buffer, forward, strafe,
player.getBlockInfo().onSoulSand);
}
lastLastClientGround = player.getMovement().getFrom().isOnGround();
previousFrom = player.getMovement().getFrom().getLoc().clone();
};
private static final float[] SIN_TABLE_FAST = new float[4096], SIN_TABLE_FAST_NEW = new float[4096];
@@ -0,0 +1,134 @@
package dev.brighten.ac.check.impl.movement.speed;
import dev.brighten.ac.api.check.CheckType;
import dev.brighten.ac.check.Check;
import dev.brighten.ac.check.CheckData;
import dev.brighten.ac.check.WAction;
import dev.brighten.ac.data.APlayer;
import dev.brighten.ac.packet.ProtocolVersion;
import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying;
import dev.brighten.ac.utils.PlayerUtils;
import dev.brighten.ac.utils.TagsBuilder;
import org.bukkit.potion.PotionEffectType;
@CheckData(name = "Speed", checkId = "speed", type = CheckType.MOVEMENT)
public class Speed extends Check {
public Speed(APlayer player) {
super(player);
}
private double ldxz = .12f;
private float friction = 0.91f;
private float buffer;
WAction<WPacketPlayInFlying> flyingPacket = packet -> {
if(player.getMovement().isExcuseNextFlying()) return;
checkProccesing:
{
if (!packet.isMoved())
break checkProccesing;
float drag = friction;
TagsBuilder tags = new TagsBuilder();
double moveFactor = player.getBukkitPlayer().getWalkSpeed() / 2f;
moveFactor+= moveFactor * 0.3f;
if(player.getPotionHandler().hasPotionEffect(PotionEffectType.SPEED))
moveFactor += (PlayerUtils.getPotionEffectLevel(player.getBukkitPlayer(), PotionEffectType.SPEED)
* (0.20000000298023224D)) * moveFactor;
if(player.getPotionHandler().hasPotionEffect(PotionEffectType.SLOW))
moveFactor += (PlayerUtils.getPotionEffectLevel(player.getBukkitPlayer(), PotionEffectType.SLOW)
* (-0.15000000596046448D)) * moveFactor;
if (player.getMovement().getFrom().isOnGround()) {
tags.addTag("ground");
drag *= 0.91f;
moveFactor *= 0.16277136 / (drag * drag * drag);
if (player.getMovement().getFrom().isOnGround() && !player.getMovement().getTo().isOnGround()
&& player.getMovement().getDeltaY() > 0.2) {
tags.addTag("jumped");
moveFactor += 0.2;
}
} else {
tags.addTag("air");
drag = 0.91f;
moveFactor = 0.026f;
}
if(player.getBlockInfo().inWater) {
tags.addTag("water");
drag = player.getPlayerVersion().isOrAbove(ProtocolVersion.V1_13) ? 0.9f : 0.8f;
moveFactor = 0.034;
if(player.getInfo().lastLiquid.getResetStreak() < 3) {
tags.addTag("water-enter");
moveFactor*= 1.35;
}
} else if(player.getInfo().lastLiquid.isNotPassed(3)) {
moveFactor*= 1.35;
tags.addTag("water-leave");
}
if(player.getMovement().getLastTeleport().isNotPassed(6)
|| player.getInfo().getLastRespawn().isNotPassed(6)) {
tags.addTag("teleport");
moveFactor+= 0.1;
moveFactor*= 5;
}
//In 1.9+, entity collisions add acceleration to their movement.
if(player.getInfo().lastEntityCollision.isNotPassed(2)) {
tags.addTag("entity-collision");
moveFactor+= 0.05;
}
//Pistons have the ability to move players 1 whole block
if(player.getBlockInfo().pistonNear) {
tags.addTag("piston");
moveFactor+= 1;
}
if(player.getBlockInfo().inWeb
//Ensuring they aren't just entering or leaving web
&& player.getInfo().getLastWeb().getResetStreak() > 1) {
tags.addTag("web");
moveFactor*= 0.4;
}
if(player.getBlockInfo().onSoulSand && player.getMovement().getFrom().isOnGround()
//Ensuring the player is actually standing on the block and recieving slow
&& packet.getY() % (1) == 0.875) {
tags.addTag("soulsand");
moveFactor*= 0.88;
}
double ratio = (player.getMovement().getDeltaXZ() - ldxz) / moveFactor * 100;
if (ratio > 100.8
&& !player.getBlockInfo().inHoney
&& !player.getBlockInfo().inScaffolding
&& player.getInfo().velocity.isPassed(2)
&& player.getInfo().lastLiquid.isPassed(2)
&& !player.getInfo().generalCancel) {
if(++buffer > 2) {
vl++;
flag("p=%.1f%% dxz=%.3f a/g=%s,%s tags=%s",
ratio, player.getMovement().getDeltaXZ(), player.getMovement().getAirTicks(), player.getMovement().getGroundTicks(),
tags.build());
buffer = Math.min(5, buffer); //Preventing runaway flagging
}
} else if(buffer > 0) buffer-= 0.2f;
debug("ratio=%.1f tags=%s tp=%s buffer=%.1f", ratio, tags.build(),
player.getInfo().getLastLiquid().getPassed(), buffer);
ldxz = player.getMovement().getDeltaXZ() * drag;
}
friction = player.getBlockInfo().currentFriction;
};
}
@@ -123,6 +123,7 @@ public class AnticheatCommand extends BaseCommand {
Anticheat.INSTANCE.getScheduler().execute(() -> {
List<String> logs = new ArrayList<>();
System.out.println("shit 1");
Anticheat.INSTANCE.getLogManager().runQuery("select * from logs where uuid=" + uuid.hashCode(), rs -> {
Log log = Log.builder()
.uuid(UUID.fromString(rs.getString("uuid")))
@@ -132,6 +133,8 @@ public class AnticheatCommand extends BaseCommand {
.time(rs.getLong("time"))
.build();
System.out.println("Shit");
logs.add("Flagged " + Anticheat.INSTANCE.getCheckManager().getIdToName().get(log.getCheckId()) + " data: " + log.getData() + " VL: " + log.getVl() + " at " + log.getTime());
});
String url = null;
@@ -371,8 +371,10 @@ public class BlockInformation {
if(entityBox.isCollided(normalBox.copy().offset(0, -.1, 0)))
player.getInfo().setServerGround(true);
if(entityBox.isCollided(normalBox))
if(entityBox.isCollided(normalBox)) {
collidedWithEntity = true;
player.getInfo().getLastEntityCollision().reset();
}
}
//Bukkit.broadcastMessage("chigga5");
@@ -26,8 +26,9 @@ public class GeneralInformation {
lastSneak = new TickTimer(), velocity = new TickTimer(), lastCancel = new TickTimer(),
slimeTimer = new TickTimer(), lastElytra = new TickTimer(), blockAbove = new TickTimer(),
lastPlace = new TickTimer(), climbTimer = new TickTimer(), lastUseItem = new TickTimer(),
lastRespawn = new TickTimer(), lastEntityCollision = new TickTimer(), lastWeb = new TickTimer(),
lastLiquid = new TickTimer(), lastBlockDig = new TickTimer(), lastBlockPlace = new TickTimer(),
lastBlockUpdate = new TickTimer();
lastBlockUpdate = new TickTimer(), lastMiscNear = new TickTimer(), lastHalfBlock = new TickTimer();
public LivingEntity target;
public boolean serverGround, lastServerGround, canFly, nearGround, worldLoaded, generalCancel, inVehicle, creative,
sneaking, lsneaking, sprinting, gliding, riptiding, wasOnSlime, onLadder, doingVelocity, breakingBlock;
@@ -230,6 +230,7 @@ public class MovementHandler {
if (player.getInfo().isGliding()) player.getInfo().getLastElytra().reset();
if (player.getInfo().isSneaking()) player.getInfo().getLastSneak().reset();
if (player.getBlockInfo().inLiquid) player.getInfo().getLastLiquid().reset();
if(player.getBlockInfo().inWeb) player.getInfo().lastWeb.reset();
player.getInfo().setGeneralCancel(player.getBukkitPlayer().getAllowFlight()
|| moveTicks == 0
@@ -3,7 +3,6 @@ package dev.brighten.ac.handler;
import dev.brighten.ac.Anticheat;
import dev.brighten.ac.data.APlayer;
import dev.brighten.ac.data.obj.NormalAction;
import dev.brighten.ac.handler.thread.ThreadHandler;
import dev.brighten.ac.packet.ProtocolVersion;
import dev.brighten.ac.packet.wrapper.PacketType;
import dev.brighten.ac.packet.wrapper.in.*;
@@ -178,6 +177,7 @@ public class PacketHandler {
if(player.getPlayerVersion().isBelow(ProtocolVersion.V1_14)) {
player.runKeepaliveAction(k -> player.getBukkitPlayer().setSprinting(false), 1);
}
player.runKeepaliveAction(ka -> player.getInfo().lastRespawn.reset());
break;
}
case SERVER_POSITION: {
@@ -29,7 +29,6 @@ public class KeepaliveProcessor implements Runnable {
final Int2ObjectMap<Short> lastResponses = Int2ObjectMaps.synchronize(new Int2ObjectOpenHashMap<>());
public KeepaliveProcessor() {
start();
}
@Override
@@ -46,7 +45,6 @@ public class KeepaliveProcessor implements Runnable {
currentKeepalive.startStamp = System.currentTimeMillis();
totalPlayers = laggyPlayers = 0;
if(Anticheat.INSTANCE.getPlayerRegistry() == null) return; //Temp fix for startup errors on plugman reload
for (APlayer value : Anticheat.INSTANCE.getPlayerRegistry().aplayerMap.values()) {
totalPlayers++;
@@ -47,7 +47,7 @@ public class LoggerManager {
Log log = null;
int amount = 0;
while((log = logList.poll()) != null) {
objectsToInsert.add(log.getUuid().toString());
objectsToInsert.add(log.getUuid().hashCode());
objectsToInsert.add(log.getCheckId());
objectsToInsert.add(log.getVl());
objectsToInsert.add(log.getData());
@@ -24,6 +24,8 @@ public abstract class HandlerAbstract{
if(ProtocolVersion.getGameVersion().isOrAbove(ProtocolVersion.V1_8)) {
handler = new ModernHandler();
} else handler = new LegacyHandler();
Bukkit.getOnlinePlayers().forEach(handler::add);
}
public static void shutdown() {
@@ -0,0 +1,22 @@
package dev.brighten.ac.utils;
import java.util.ArrayList;
import java.util.List;
public class TagsBuilder {
private final List<String> tags = new ArrayList<>();
public TagsBuilder addTag(String string) {
tags.add(string);
return this;
}
public String build() {
return String.join(", ", tags);
}
public int getSize() {
return tags.size();
}
}
@@ -27,8 +27,8 @@ public class EntityData {
//We cast this as a float since the fields are floats.
return new SimpleCollisionBox(new Vector(), fieldWidth.get(ventity),
fieldLength.get(ventity));
return new SimpleCollisionBox(new Vector(), (float)fieldWidth.get(ventity),
(float)fieldLength.get(ventity));
}).copy();
}