diff --git a/src/main/java/dev/brighten/ac/check/Check.java b/src/main/java/dev/brighten/ac/check/Check.java index 414f53b..d377cc9 100644 --- a/src/main/java/dev/brighten/ac/check/Check.java +++ b/src/main/java/dev/brighten/ac/check/Check.java @@ -15,17 +15,17 @@ import net.md_5.bungee.api.chat.TextComponent; import java.util.*; -@Getter public abstract class Check { - private final APlayer player; - + public final APlayer player; + @Getter private final CheckData checkData; + @Getter private int vl; private long lastFlagRun; private final Timer lastAlert = new MillisTimer(); - public static List alertsEnabled = new ArrayList<>(); + public static Set alertsEnabled = new HashSet<>(); public static final Map>> debugInstances = new HashMap<>(); diff --git a/src/main/java/dev/brighten/ac/check/CheckManager.java b/src/main/java/dev/brighten/ac/check/CheckManager.java index 56edc20..68943ec 100644 --- a/src/main/java/dev/brighten/ac/check/CheckManager.java +++ b/src/main/java/dev/brighten/ac/check/CheckManager.java @@ -13,6 +13,7 @@ import java.util.*; public class CheckManager { private final List checkClasses = new ArrayList<>(); private final Map>, WrappedMethod[]> events = new HashMap<>(); + private final Map>, WrappedMethod[]> eventsWithTimestamp = new HashMap<>(); public CheckManager() { for (WrappedClass aClass : ClassScanner.getClasses(CheckData.class, @@ -36,7 +37,7 @@ public class CheckManager { // Loop through all the methods in Check that contain @Action annotation by Class check.getEvents().forEach((actionClass, methods) -> { // Check if array is already cached for Class and return Array if so, if not create new Array - events.compute(new Tuple>(checkData.name(), actionClass), (packetClass, array) -> { + /*events.compute(new Tuple>(checkData.name(), actionClass), (packetClass, array) -> { if(array == null) array = new WrappedMethod[0]; // Adding preexisting cached WrappedMethod into List for further additions @@ -49,7 +50,42 @@ public class CheckManager { // Returning newly created array for use in detections. return methodList.toArray(new WrappedMethod[0]); - }); + });*/ + for (WrappedMethod method : methods) { + if(method.getParameters().length == 1) { + events.compute(new Tuple<>(checkData.name(), actionClass), (packetClass, array) -> { + if(array == null) array = new WrappedMethod[0]; + + // Adding preexisting cached WrappedMethod into List for further additions + List methodList = new ArrayList<>(Arrays.asList(array)); + + methodList.add(method); + + // Adding all precached Check-specific WrappedMethod into global cache of WrappedMethods. + + System.out.println("Registering regualr method: " + packetClass.toString()); + + // Returning newly created array for use in detections. + return methodList.toArray(new WrappedMethod[0]); + }); + } else if(method.getParameters().length == 2 && method.getParameterTypes()[1].equals(long.class)) { + eventsWithTimestamp.compute(new Tuple<>(checkData.name(), actionClass), (packetClass, array) -> { + if(array == null) array = new WrappedMethod[0]; + + // Adding preexisting cached WrappedMethod into List for further additions + List methodList = new ArrayList<>(Arrays.asList(array)); + + methodList.add(method); + + // Adding all precached Check-specific WrappedMethod into global cache of WrappedMethods. + + System.out.println("Registering regualr method: " + packetClass.toString()); + + // Returning newly created array for use in detections. + return methodList.toArray(new WrappedMethod[0]); + }); + } + } }); } diff --git a/src/main/java/dev/brighten/ac/check/impl/combat/Aim.java b/src/main/java/dev/brighten/ac/check/impl/combat/Aim.java index 4774e5d..e9309f1 100644 --- a/src/main/java/dev/brighten/ac/check/impl/combat/Aim.java +++ b/src/main/java/dev/brighten/ac/check/impl/combat/Aim.java @@ -25,25 +25,25 @@ public class Aim extends Check { public void flying(WPacketPlayInFlying packet) { if(!packet.isLooked()) return; - if(getPlayer().getMovement().getYawGcdList().size() < 40) { + if(player.getMovement().getYawGcdList().size() < 40) { if(buffer > 0) buffer--; return; } - final float deltaYaw = Math.abs(getPlayer().getMovement().getDeltaYaw()); - final float deltaPitch = Math.abs(getPlayer().getMovement().getDeltaPitch()); - final float deltaX = deltaYaw / getPlayer().getMovement().getYawMode(), - deltaY = deltaPitch / getPlayer().getMovement().getPitchMode(); + final float deltaYaw = Math.abs(player.getMovement().getDeltaYaw()); + final float deltaPitch = Math.abs(player.getMovement().getDeltaPitch()); + final float deltaX = deltaYaw / player.getMovement().getYawMode(), + deltaY = deltaPitch / player.getMovement().getPitchMode(); - final double gridX = getGrid(getPlayer().getMovement().getYawGcdList()), - gridY = getGrid(getPlayer().getMovement().getPitchGcdList()); + final double gridX = getGrid(player.getMovement().getYawGcdList()), + gridY = getGrid(player.getMovement().getPitchGcdList()); if(gridX < 0.005 || gridY < 0.005) lastGrid.reset(); if(deltaX > 200 || deltaY > 200) { debug("sensitivity instability: mcp=%.4f, cx=%.4f, cy=%.4f, dx=%.1f, dy=%.1f", - getPlayer().getMovement().getSensitivityMcp(), getPlayer().getMovement().getCurrentSensX(), - getPlayer().getMovement().getCurrentSensY(), deltaX, deltaY); + player.getMovement().getSensitivityMcp(), player.getMovement().getCurrentSensX(), + player.getMovement().getCurrentSensY(), deltaX, deltaY); if(buffer > 0) buffer--; return; } @@ -51,16 +51,16 @@ public class Aim extends Check { boolean increasing = deltaYaw > deltaX || deltaPitch > deltaY; boolean flagged = false; - if(getPlayer().getMovement().getPitchGCD() < 0.007 && lastGrid.isPassed() && getPlayer().getMovement().getLastHighRate().isNotPassed(3)) { + if(player.getMovement().getPitchGCD() < 0.007 && lastGrid.isPassed() && player.getMovement().getLastHighRate().isNotPassed(3)) { if(deltaPitch < 10 && ++buffer > 8) { - flag("%s", getPlayer().getMovement().getPitchGCD()); + flag("%s", player.getMovement().getPitchGCD()); } flagged = true; } else buffer = 0; debug((flagged ? Color.Green : "") +"sensitivity: mcp=%.4f, cx=%.4f, cy=%.4f, dx=%.1f, dy=%.1f", - getPlayer().getMovement().getSensitivityMcp(), getPlayer().getMovement().getCurrentSensX(), - getPlayer().getMovement().getCurrentSensY(), deltaX, deltaY); + player.getMovement().getSensitivityMcp(), player.getMovement().getCurrentSensX(), + player.getMovement().getCurrentSensY(), deltaX, deltaY); } diff --git a/src/main/java/dev/brighten/ac/check/impl/combat/Reach.java b/src/main/java/dev/brighten/ac/check/impl/combat/Reach.java index 4c2d6fc..c6889d8 100644 --- a/src/main/java/dev/brighten/ac/check/impl/combat/Reach.java +++ b/src/main/java/dev/brighten/ac/check/impl/combat/Reach.java @@ -39,8 +39,8 @@ public class Reach extends Check { @Action public void onUse(WPacketPlayInUseEntity packet) { if(packet.getAction() == WPacketPlayInUseEntity.EnumEntityUseAction.ATTACK - && allowedEntityTypes.contains(packet.getEntity(getPlayer().getBukkitPlayer().getWorld()).getType())) { - attacks.add(new Tuple<>(packet.getEntity(getPlayer().getBukkitPlayer().getWorld()), getPlayer().getMovement().getTo().getLoc().clone())); + && allowedEntityTypes.contains(packet.getEntity(player.getBukkitPlayer().getWorld()).getType())) { + attacks.add(new Tuple<>(packet.getEntity(player.getBukkitPlayer().getWorld()), player.getMovement().getTo().getLoc().clone())); } } @@ -49,7 +49,7 @@ public class Reach extends Check { //stability. like shortening the amount stored, or removing older ones. @Action public void onFlying(WPacketPlayInFlying packet) { - if(getPlayer().getInfo().isCreative() || getPlayer().getInfo().isInVehicle()) { + if(player.getInfo().isCreative() || player.getInfo().isInVehicle()) { attacks.clear(); return; } @@ -57,7 +57,7 @@ public class Reach extends Check { while((target = attacks.poll()) != null) { //Updating new entity loc - Optional optionalEloc = getPlayer().getEntityLocationHandler().getEntityLocation(target.one); + Optional optionalEloc = player.getEntityLocationHandler().getEntityLocation(target.one); if(!optionalEloc.isPresent()) { return; @@ -82,7 +82,7 @@ public class Reach extends Check { SimpleCollisionBox box = (SimpleCollisionBox) EntityData.getEntityBox(oldLocation.toVector(), target.one); - if(getPlayer().getPlayerVersion().isBelow(ProtocolVersion.V1_9)) { + if(player.getPlayerVersion().isBelow(ProtocolVersion.V1_9)) { box = box.expand(0.1325); } else box = box.expand(0.0325); boxes.add(box); @@ -91,7 +91,7 @@ public class Reach extends Check { SimpleCollisionBox box = (SimpleCollisionBox) EntityData.getEntityBox(oldLocation.toVector(), target.one); - if(getPlayer().getPlayerVersion().isBelow(ProtocolVersion.V1_9)) { + if(player.getPlayerVersion().isBelow(ProtocolVersion.V1_9)) { box = box.expand(0.1325); } else box = box.expand(0.0325); boxes.add(box); @@ -101,7 +101,7 @@ public class Reach extends Check { SimpleCollisionBox box = (SimpleCollisionBox) EntityData.getEntityBox(oldLocation.toVector(), target.one); - if(getPlayer().getPlayerVersion().isBelow(ProtocolVersion.V1_9)) { + if(player.getPlayerVersion().isBelow(ProtocolVersion.V1_9)) { box = box.expand(0.1325); } else box = box.expand(0.0325); boxes.add(box); @@ -112,14 +112,14 @@ public class Reach extends Check { int hits = 0; - boolean didSneakOrElytra = getPlayer().getInfo().getLastElytra().isNotPassed(40) - || getPlayer().getInfo().getLastElytra().isNotPassed(40); + boolean didSneakOrElytra = player.getInfo().getLastElytra().isNotPassed(40) + || player.getInfo().getLastElytra().isNotPassed(40); List directions = new ArrayList<>(Arrays.asList(MathUtils.getDirection( - getPlayer().getMovement().getTo().getLoc().yaw, - getPlayer().getMovement().getTo().getLoc().pitch), - MathUtils.getDirection(getPlayer().getMovement().getFrom().getLoc().yaw, - getPlayer().getMovement().getTo().getLoc().pitch))); + player.getMovement().getTo().getLoc().yaw, + player.getMovement().getTo().getLoc().pitch), + MathUtils.getDirection(player.getMovement().getFrom().getLoc().yaw, + player.getMovement().getTo().getLoc().pitch))); if(!didSneakOrElytra) { to.y+= 1.62f; @@ -140,7 +140,7 @@ public class Reach extends Check { //Checking all possible eyeheights since client actions notoriously desync from the server side } else { for (Vector direction : directions) { - for (double eyeHeight : getPlayer().getMovement().getEyeHeights()) { + for (double eyeHeight : player.getMovement().getEyeHeights()) { for (SimpleCollisionBox targetBox : boxes) { final AxisAlignedBB vanillaBox = new AxisAlignedBB(targetBox); diff --git a/src/main/java/dev/brighten/ac/check/impl/fly/FlyA.java b/src/main/java/dev/brighten/ac/check/impl/fly/FlyA.java index 6a683a1..c16c0c4 100644 --- a/src/main/java/dev/brighten/ac/check/impl/fly/FlyA.java +++ b/src/main/java/dev/brighten/ac/check/impl/fly/FlyA.java @@ -25,18 +25,18 @@ public class FlyA extends Check { @Action public void onFlying(WPacketPlayInFlying packet) { - if(!packet.isMoved() || (getPlayer().getMovement().getDeltaXZ() == 0 - && getPlayer().getMovement().getDeltaY() == 0)) { + if(!packet.isMoved() || (player.getMovement().getDeltaXZ() == 0 + && player.getMovement().getDeltaY() == 0)) { return; } - boolean onGround = getPlayer().getMovement().getTo().isOnGround() && getPlayer().getBlockInformation().blocksBelow, - fromGround = getPlayer().getMovement().getFrom().isOnGround(); - double lDeltaY = fromGround ? 0 : getPlayer().getMovement().getLDeltaY(); + boolean onGround = player.getMovement().getTo().isOnGround() && player.getBlockInfo().blocksBelow, + fromGround = player.getMovement().getFrom().isOnGround(); + double lDeltaY = fromGround ? 0 : player.getMovement().getLDeltaY(); double predicted = onGround ? lDeltaY : (lDeltaY - 0.08) * mult; - if(fromGround && !onGround && getPlayer().getMovement().getDeltaY() > 0) { - predicted = MovementUtils.getJumpHeight(getPlayer()); + if(fromGround && !onGround && player.getMovement().getDeltaY() > 0) { + predicted = MovementUtils.getJumpHeight(player); } if(Math.abs(predicted) < 0.005 && ProtocolVersion.getGameVersion().isOrAbove(ProtocolVersion.V1_9)) { @@ -46,33 +46,33 @@ public class FlyA extends Check { if(lastPos.isPassed(60L)) { double toCheck = (predicted - 0.08) * mult; - if(Math.abs(getPlayer().getMovement().getDeltaY() - toCheck) - < Math.abs(getPlayer().getMovement().getDeltaY() - predicted)) { + if(Math.abs(player.getMovement().getDeltaY() - toCheck) + < Math.abs(player.getMovement().getDeltaY() - predicted)) { predicted = toCheck; } } - double deltaPredict = MathUtils.getDelta(getPlayer().getMovement().getDeltaY(), predicted); + double deltaPredict = MathUtils.getDelta(player.getMovement().getDeltaY(), predicted); - if(!getPlayer().getInfo().isGeneralCancel() - && getPlayer().getInfo().getBlockAbove().isPassed(1) - && !getPlayer().getInfo().isOnLadder() - && !getPlayer().getBlockInformation().inWeb - && !getPlayer().getBlockInformation().inScaffolding - && !getPlayer().getBlockInformation().inLiquid - && !getPlayer().getBlockInformation().fenceBelow - && !getPlayer().getBlockInformation().onHalfBlock - && getPlayer().getInfo().getVelocity().isPassed(1) - && !getPlayer().getBlockInformation().onSlime && deltaPredict > 0.016) { + if(!player.getInfo().isGeneralCancel() + && player.getInfo().getBlockAbove().isPassed(1) + && !player.getInfo().isOnLadder() + && !player.getBlockInfo().inWeb + && !player.getBlockInfo().inScaffolding + && !player.getBlockInfo().inLiquid + && !player.getBlockInfo().fenceBelow + && !player.getBlockInfo().onHalfBlock + && player.getInfo().getVelocity().isPassed(1) + && !player.getBlockInfo().onSlime && deltaPredict > 0.016) { if(++buffer > 5) { buffer = 5; - flag("dY=%.3f p=%.3f dx=%.3f", getPlayer().getMovement().getDeltaY(), predicted, - getPlayer().getMovement().getDeltaXZ()); + flag("dY=%.3f p=%.3f dx=%.3f", player.getMovement().getDeltaY(), predicted, + player.getMovement().getDeltaXZ()); } } else buffer-= buffer > 0 ? 0.25f : 0; - debug("dY=%.3f p=%.3f dx=%.3f b=%s velocity=%s", getPlayer().getMovement().getDeltaY(), predicted, - getPlayer().getMovement().getDeltaXZ(), buffer, getPlayer().getInfo().getVelocity().getPassed()); + debug("dY=%.3f p=%.3f dx=%.3f b=%s velocity=%s", player.getMovement().getDeltaY(), predicted, + player.getMovement().getDeltaXZ(), buffer, player.getInfo().getVelocity().getPassed()); lastPos.reset(); } diff --git a/src/main/java/dev/brighten/ac/check/impl/fly/FlyB.java b/src/main/java/dev/brighten/ac/check/impl/fly/FlyB.java index cc423dd..9223452 100644 --- a/src/main/java/dev/brighten/ac/check/impl/fly/FlyB.java +++ b/src/main/java/dev/brighten/ac/check/impl/fly/FlyB.java @@ -17,17 +17,17 @@ public class FlyB extends Check { @Action public void onFlying(WPacketPlayInFlying packet) { - if(getPlayer().getInfo().isNearGround()) lastNearGround.reset(); - if(!packet.isMoved() || getPlayer().getInfo().isGeneralCancel()) return; + if(player.getInfo().isNearGround()) lastNearGround.reset(); + if(!packet.isMoved() || player.getInfo().isGeneralCancel()) return; - if(getPlayer().getMovement().getDeltaY() - getPlayer().getMovement().getLDeltaY() > 0.01 - && getPlayer().getMovement().getMoveTicks() > 3 - && getPlayer().getInfo().getLastPlace().isPassed(3) + if(player.getMovement().getDeltaY() - player.getMovement().getLDeltaY() > 0.01 + && player.getMovement().getMoveTicks() > 3 + && player.getInfo().getLastPlace().isPassed(3) && lastNearGround.isPassed(2) - && getPlayer().getInfo().getVelocity().isPassed(2) - && getPlayer().getMovement().getDeltaY() > 0) { + && player.getInfo().getVelocity().isPassed(2) + && player.getMovement().getDeltaY() > 0) { flag("%.4f>-%.4f", - getPlayer().getMovement().getDeltaY(), getPlayer().getMovement().getLDeltaY()); + player.getMovement().getDeltaY(), player.getMovement().getLDeltaY()); } } } diff --git a/src/main/java/dev/brighten/ac/check/impl/nofall/NoFallA.java b/src/main/java/dev/brighten/ac/check/impl/nofall/NoFallA.java new file mode 100644 index 0000000..a8a98ca --- /dev/null +++ b/src/main/java/dev/brighten/ac/check/impl/nofall/NoFallA.java @@ -0,0 +1,59 @@ +package dev.brighten.ac.check.impl.nofall; + +import dev.brighten.ac.check.Action; +import dev.brighten.ac.check.Check; +import dev.brighten.ac.check.CheckData; +import dev.brighten.ac.check.CheckType; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; + +@CheckData(name = "NoFall (A)", type = CheckType.MOVEMENT) +public class NoFallA extends Check { + + public NoFallA(APlayer player) { + super(player); + } + + private static double divisor = 1. / 64.; + private float buffer; + + @Action + public void onFlying(WPacketPlayInFlying packet) { + if(!player.getInfo().isGeneralCancel() + || (player.getMovement().getDeltaXZ() == 0 && player.getMovement().getDeltaY() == 0) + || player.getBlockInfo().inLiquid + || player.getMovement().getLastTeleport().isNotPassed(1) + || !packet.isMoved()) { + if(buffer > 0) buffer-= 0.5f; + return; + } + + boolean onGround = packet.isOnGround(); + boolean flag = false; + + if(onGround) { + flag = Math.abs(player.getMovement().getDeltaY()) > 0.1 + && player.getInfo().slimeTimer.isPassed(2) + && player.getInfo().getBlockAbove().isPassed(3) + && !player.getInfo().isServerGround() + && (player.getMovement().getDeltaY() >= 0 + && (Math.abs(player.getMovement().getTo().getLoc().y) % divisor != 0 + || Math.abs(player.getMovement().getDeltaY()) % divisor != 0) + || player.getMovement().getDeltaY() <= player.getMovement().getLDeltaY()); + } else { + flag = player.getMovement().getDeltaY() == 0 && player.getMovement().getLDeltaY() == 0 + && player.getInfo().climbTimer.isPassed(3) + && player.getInfo().slimeTimer.isPassed(2); + } + + if(flag) { + if(++buffer > 1) { + flag("[%.1f] g=%s;dy=%.4f;ldy=%.4f", buffer, onGround, + player.getMovement().getDeltaY(), player.getMovement().getLDeltaY()); + } + } else if(buffer > 0) buffer-= 0.25f; + + debug("[%.1f] g=%s;dy=%.4f;ldy=%.4f", buffer, onGround, + player.getMovement().getDeltaY(), player.getMovement().getLDeltaY()); + } +} diff --git a/src/main/java/dev/brighten/ac/check/impl/nofall/NoFallB.java b/src/main/java/dev/brighten/ac/check/impl/nofall/NoFallB.java new file mode 100644 index 0000000..3f82b44 --- /dev/null +++ b/src/main/java/dev/brighten/ac/check/impl/nofall/NoFallB.java @@ -0,0 +1,66 @@ +package dev.brighten.ac.check.impl.nofall; + +import dev.brighten.ac.check.Action; +import dev.brighten.ac.check.Check; +import dev.brighten.ac.check.CheckData; +import dev.brighten.ac.check.CheckType; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; + +@CheckData(name = "NoFall (B)", type = CheckType.MOVEMENT) +public class NoFallB extends Check { + + public NoFallB(APlayer player) { + super(player); + } + + private static double divisor = 1. / 64.; + + private int airBuffer, groundBuffer; + + @Action + public void onFlying(WPacketPlayInFlying packet, long timestamp) { + if(player.getMovement().getLastTeleport().isNotPassed(3) + || player.getMovement().getMoveTicks() < 2 + || player.getInfo().canFly + || player.getInfo().creative + || player.getBlockInfo().miscNear + || player.getInfo().inVehicle + || player.getInfo().climbTimer.isNotPassed(3) + || player.getCreation().isPassed(2000L) + || player.getInfo().slimeTimer.isNotPassed(3)) { + if(groundBuffer > 0) groundBuffer--; + if(airBuffer > 0) airBuffer--; + return; // If we are waiting for them to teleport, don't check. + } + + // If they are saying they are on the ground + if(packet.isOnGround() + && player.getInfo().vehicleSwitch.isPassed(20) + && !player.getBlockInfo().blocksBelow + && !player.getBlockInfo().blocksNear + && !player.getInfo().isServerGround()) { + groundBuffer+= 2; + if(groundBuffer > 14) { + flag("[%.1f] g=%s;dy=%.4f;ldy=%.4f", groundBuffer, true, + player.getMovement().getDeltaY(), player.getMovement().getLDeltaY()); + } + } else if(groundBuffer > 0) groundBuffer--; + + final boolean dground = Math.abs(player.getMovement().getDeltaY()) % divisor < 1E-4 + && player.getInfo().isNearGround(); + + if(!packet.isOnGround() && player.getInfo().vehicleSwitch.isPassed(20) + && ((player.getInfo().isServerGround() || player.getBlockInfo().blocksBelow) + && dground && !player.getBlockInfo().onHalfBlock)) { + if((airBuffer +=10) > 30) { + flag("[%.1f] g=%s;dy=%.4f;ldy=%.4f", airBuffer, false, + player.getMovement().getDeltaY(), player.getMovement().getLDeltaY()); + } + } else if(airBuffer > 0) airBuffer-= 4; + + debug("[%s,%s] g=%s;sg-%s;bbelow=%s;dy=%.4f;ldy=%.4f", groundBuffer, airBuffer, packet.isOnGround(), + player.getInfo().isServerGround(), player.getBlockInfo().blocksBelow, player.getMovement().getDeltaY(), + player.getMovement().getLDeltaY()); + } +} diff --git a/src/main/java/dev/brighten/ac/check/impl/speed/Horizontal.java b/src/main/java/dev/brighten/ac/check/impl/speed/Horizontal.java index 5896c25..be9de5f 100644 --- a/src/main/java/dev/brighten/ac/check/impl/speed/Horizontal.java +++ b/src/main/java/dev/brighten/ac/check/impl/speed/Horizontal.java @@ -36,11 +36,11 @@ public class Horizontal extends Check { @Action public void onFlying(WPacketPlayInFlying packet) { - Block underBlock = BlockUtils.getBlock(getPlayer().getMovement().getTo().getLoc() - .toLocation(getPlayer().getBukkitPlayer().getWorld()) + Block underBlock = BlockUtils.getBlock(player.getMovement().getTo().getLoc() + .toLocation(player.getBukkitPlayer().getWorld()) .subtract(0, 1, 0)), - lastUnderBlock = BlockUtils.getBlock(getPlayer().getMovement().getFrom().getLoc() - .toLocation(getPlayer().getBukkitPlayer().getWorld()) + lastUnderBlock = BlockUtils.getBlock(player.getMovement().getFrom().getLoc() + .toLocation(player.getBukkitPlayer().getWorld()) .subtract(0, 1, 0)); check: @@ -48,23 +48,23 @@ public class Horizontal extends Check { if (underBlock == null || lastUnderBlock == null) break check; - Deque frictionList = getPlayer().getBlockUpdateHandler() + Deque frictionList = player.getBlockUpdateHandler() .getPossibleMaterials(new IntVector(underBlock.getX(), underBlock.getY(), underBlock.getZ())), - lfrictionList = getPlayer().getBlockUpdateHandler() + lfrictionList = player.getBlockUpdateHandler() .getPossibleMaterials(new IntVector(lastUnderBlock.getX(), lastUnderBlock.getY(), lastUnderBlock.getZ())); if (!packet.isMoved() - || getPlayer().getInfo().getVelocity().isNotPassed(1) - || getPlayer().getInfo().isGeneralCancel() - || getPlayer().getBlockInformation().onClimbable - || getPlayer().getBlockInformation().inLiquid - || getPlayer().getBlockInformation().collidesHorizontally) { + || player.getInfo().getVelocity().isNotPassed(1) + || player.getInfo().isGeneralCancel() + || player.getBlockInfo().onClimbable + || player.getBlockInfo().inLiquid + || player.getBlockInfo().collidesHorizontally) { break check; } double smallestDelta = Double.MAX_VALUE; double pmotionx = 0, pmotionz = 0; - boolean onGround = getPlayer().getMovement().getFrom().isOnGround(); + boolean onGround = player.getMovement().getFrom().isOnGround(); loop: { @@ -103,19 +103,19 @@ public class Horizontal extends Check { forward *= 0.9800000190734863F; strafe *= 0.9800000190734863F; - double aiMoveSpeed = getPlayer().getBukkitPlayer().getWalkSpeed() / 2; + double aiMoveSpeed = player.getBukkitPlayer().getWalkSpeed() / 2; float drag = 0.91f; - double lmotionX = getPlayer().getMovement().getLDeltaX(), - lmotionZ = getPlayer().getMovement().getLDeltaZ(); + double lmotionX = player.getMovement().getLDeltaX(), + lmotionZ = player.getMovement().getLDeltaZ(); if(motionModifiers) { - if(getPlayer().getBlockInformation().onSoulSand - && getPlayer().getBlockInformation().collisionMaterialCount. + if(player.getBlockInfo().onSoulSand + && player.getBlockInfo().collisionMaterialCount. containsKey(Material.SOUL_SAND)) { for(int i = 0 - ; i < getPlayer().getBlockInformation() + ; i < player.getBlockInfo() .collisionMaterialCount .get(Material.SOUL_SAND) ; i++) { @@ -124,7 +124,7 @@ public class Horizontal extends Check { } } - if(getPlayer().getBlockInformation().inWeb) { + if(player.getBlockInfo().inWeb) { lmotionX*= 0.25; lmotionZ*= 0.25; } @@ -135,7 +135,7 @@ public class Horizontal extends Check { lmotionZ *= (lastLastClientGround ? lfriction : 1) * 0.9100000262260437D; //Running multiplication done after previous prediction - if (getPlayer().getPlayerVersion().isOrAbove(ProtocolVersion.V1_9)) { + if (player.getPlayerVersion().isOrAbove(ProtocolVersion.V1_9)) { if (Math.abs(lmotionX) < 0.003) lmotionX = 0; if (Math.abs(lmotionZ) < 0.003) @@ -155,12 +155,12 @@ public class Horizontal extends Check { if (sprinting) aiMoveSpeed += aiMoveSpeed * 0.30000001192092896D; - if (getPlayer().getPotionHandler().hasPotionEffect(PotionEffectType.SPEED)) - aiMoveSpeed += (getPlayer().getPotionHandler().getEffectByType(PotionEffectType.SPEED) + if (player.getPotionHandler().hasPotionEffect(PotionEffectType.SPEED)) + aiMoveSpeed += (player.getPotionHandler().getEffectByType(PotionEffectType.SPEED) .get() .getAmplifier() + 1) * (double) 0.20000000298023224D * aiMoveSpeed; - if (getPlayer().getPotionHandler().hasPotionEffect(PotionEffectType.SLOW)) - aiMoveSpeed += (getPlayer().getPotionHandler().getEffectByType(PotionEffectType.SLOW) + if (player.getPotionHandler().hasPotionEffect(PotionEffectType.SLOW)) + aiMoveSpeed += (player.getPotionHandler().getEffectByType(PotionEffectType.SLOW) .get() .getAmplifier() + 1) * (double) -0.15000000596046448D * aiMoveSpeed; @@ -171,14 +171,14 @@ public class Horizontal extends Check { f5 = (float) (aiMoveSpeed * (0.16277136F / (drag * drag * drag))); if (sprinting && jumped) { - float rot = getPlayer().getMovement().getTo().getLoc().yaw * 0.017453292F; + float rot = player.getMovement().getTo().getLoc().yaw * 0.017453292F; lmotionX -= sin(fastMath, rot) * 0.2F; lmotionZ += cos(fastMath, rot) * 0.2F; } } else f5 = sprinting ? 0.025999999F : 0.02f; - if (getPlayer().getPlayerVersion().isOrAbove(ProtocolVersion.V1_9)) { + if (player.getPlayerVersion().isOrAbove(ProtocolVersion.V1_9)) { double keyedMotion = forward * forward + strafe * strafe; if (keyedMotion >= 1.0E-4F) { @@ -187,9 +187,9 @@ public class Horizontal extends Check { strafe *= keyedMotion; final float yawSin = sin(fastMath, - getPlayer().getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F), + player.getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F), yawCos = cos(fastMath, - getPlayer().getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F); + player.getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F); lmotionX += (strafe * yawCos - forward * yawSin); lmotionZ += (forward * yawCos + strafe * yawSin); @@ -203,16 +203,16 @@ public class Horizontal extends Check { strafe *= keyedMotion; final float yawSin = sin(fastMath, - getPlayer().getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F), + player.getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F), yawCos = cos(fastMath, - getPlayer().getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F); + player.getMovement().getTo().getLoc().yaw * (float) Math.PI / 180.F); lmotionX += (strafe * yawCos - forward * yawSin); lmotionZ += (forward * yawCos + strafe * yawSin); } } - double diffX = getPlayer().getMovement().getDeltaX() - lmotionX, - diffZ = getPlayer().getMovement().getDeltaZ() - lmotionZ; + double diffX = player.getMovement().getDeltaX() - lmotionX, + diffZ = player.getMovement().getDeltaZ() - lmotionZ; double delta = (diffX * diffX) + (diffZ * diffZ); if (delta < smallestDelta) { @@ -224,9 +224,9 @@ public class Horizontal extends Check { this.strafe = s * 0.98f; this.forward = f * 0.98f; - if (getPlayer().getInfo().getLastCancel().isPassed(2)) - getPlayer().getInfo() - .setLastKnownGoodPosition(getPlayer() + if (player.getInfo().getLastCancel().isPassed(2)) + player.getInfo() + .setLastKnownGoodPosition(player .getMovement().getFrom().getLoc() .clone()); break loop; @@ -247,21 +247,24 @@ public class Horizontal extends Check { double pmotion = Math.hypot(pmotionx, pmotionz); - if (getPlayer().getMovement().getDeltaXZ() > pmotion - && smallestDelta > (getPlayer().getBlockInformation().onSoulSand ? 0.01 : 5E-13) - && getPlayer().getMovement().getDeltaXZ() > 0.1) { + if (player.getMovement().getDeltaXZ() > pmotion + && smallestDelta > (player.getBlockInfo().onSoulSand ? 0.01 : 5E-13) + && player.getMovement().getDeltaXZ() > 0.1) { if ((buffer += smallestDelta > 58E-4 ? 1 : 0.5) > 3) { buffer = Math.min(3.5f, buffer); //Ensuring we don't have a run-away buffer flag("smallest=%s b=%.1f to=%s dxz=%.2f", smallestDelta, buffer, - getPlayer().getMovement().getTo().getLoc(), getPlayer().getMovement().getDeltaXZ()); + player.getMovement().getTo().getLoc(), player.getMovement().getDeltaXZ()); + } else { + debug("bad movement"); + cancel(); } } else if (buffer > 0) buffer -= 0.1f; debug("smallest=%s pm=%.5f dxz=%.5f b=%.1f f/s=%.2f,%.2f soulsand=%s", smallestDelta, pmotion, - getPlayer().getMovement().getDeltaXZ(), buffer, forward, strafe, - getPlayer().getBlockInformation().onSoulSand); + player.getMovement().getDeltaXZ(), buffer, forward, strafe, + player.getBlockInfo().onSoulSand); } - lastLastClientGround = getPlayer().getMovement().getFrom().isOnGround(); + lastLastClientGround = player.getMovement().getFrom().isOnGround(); } private static final float[] SIN_TABLE_FAST = new float[4096], SIN_TABLE_FAST_NEW = new float[4096]; diff --git a/src/main/java/dev/brighten/ac/check/impl/velocity/VelocityA.java b/src/main/java/dev/brighten/ac/check/impl/velocity/VelocityA.java index d9508e0..64da15e 100644 --- a/src/main/java/dev/brighten/ac/check/impl/velocity/VelocityA.java +++ b/src/main/java/dev/brighten/ac/check/impl/velocity/VelocityA.java @@ -27,18 +27,18 @@ public class VelocityA extends Check { @Action public void onFlying(WPacketPlayInFlying packet) { if(currentVelocity != null && currentVelocity.getY() > 0 - && !getPlayer().getBlockInformation().inWeb - && !getPlayer().getBlockInformation().onClimbable - && getPlayer().getInfo().getBlockAbove().isPassed(6) - && !getPlayer().getBlockInformation().onSlime - && !getPlayer().getInfo().isGeneralCancel()) { - double pct = getPlayer().getMovement().getDeltaY() / currentVelocity.getY() * 100; + && !player.getBlockInfo().inWeb + && !player.getBlockInfo().onClimbable + && player.getInfo().getBlockAbove().isPassed(6) + && !player.getBlockInfo().onSlime + && !player.getInfo().isGeneralCancel()) { + double pct = player.getMovement().getDeltaY() / currentVelocity.getY() * 100; if(currentVelocity.getY() < 0.005 - || getPlayer().getBlockInformation().collidesHorizontally - || getPlayer().getInfo().getLastAbilities().isNotPassed(3) - || getPlayer().getBlockInformation().collidesVertically - || getPlayer().getInfo().getVelocity().isPassed(7)) { + || player.getBlockInfo().collidesHorizontally + || player.getInfo().getLastAbilities().isNotPassed(3) + || player.getBlockInfo().collidesVertically + || player.getInfo().getVelocity().isPassed(7)) { currentVelocity = null; return; } @@ -51,7 +51,7 @@ public class VelocityA extends Check { } else if(buffer > 0) buffer-= 0.5; debug("pct=%.1f%% buffer=%.1f dy=%.4f vy=%.4f", pct, buffer, - getPlayer().getMovement().getDeltaY(), currentVelocity.getY()); + player.getMovement().getDeltaY(), currentVelocity.getY()); currentVelocity.setY((currentVelocity.getY() - 0.08) * 0.98); } else if(currentVelocity != null) { diff --git a/src/main/java/dev/brighten/ac/check/impl/velocity/VelocityB.java b/src/main/java/dev/brighten/ac/check/impl/velocity/VelocityB.java index 2d7b3c7..8b7bceb 100644 --- a/src/main/java/dev/brighten/ac/check/impl/velocity/VelocityB.java +++ b/src/main/java/dev/brighten/ac/check/impl/velocity/VelocityB.java @@ -2,6 +2,8 @@ package dev.brighten.ac.check.impl.velocity; import dev.brighten.ac.check.Action; import dev.brighten.ac.check.Check; +import dev.brighten.ac.check.CheckData; +import dev.brighten.ac.check.CheckType; import dev.brighten.ac.check.impl.speed.Horizontal; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; @@ -16,7 +18,7 @@ import java.util.Comparator; import java.util.List; import java.util.Optional; -//@CheckData(name = "Velocity (B)", type = CheckType.MOVEMENT) +@CheckData(name = "Velocity (B)", type = CheckType.MOVEMENT) public class VelocityB extends Check { public VelocityB(APlayer player) { super(player); @@ -47,28 +49,29 @@ public class VelocityB extends Check { @Action public void onFlying(WPacketPlayInFlying packet) { check: { - if((pvX != 0 || pvZ != 0) && (getPlayer().getMovement().getDeltaX() != 0 - || getPlayer().getMovement().getDeltaY() != 0 - || getPlayer().getMovement().getDeltaZ() != 0)) { + if((pvX != 0 || pvZ != 0) && (player.getMovement().getDeltaX() != 0 + || player.getMovement().getDeltaY() != 0 + || player.getMovement().getDeltaZ() != 0)) { boolean found = false; double drag = 0.91; - if(getPlayer().getBlockInformation().blocksNear - || getPlayer().getBlockInformation().blocksAbove - || getPlayer().getBlockInformation().inLiquid - || getPlayer().getLagInfo().getLastPingDrop().isNotPassed()) { + if(player.getBlockInfo().blocksNear + || player.getBlockInfo().blocksAbove + || player.getBlockInfo().inLiquid + || player.getLagInfo().getLastPacketDrop().isNotPassed(2) + || player.getLagInfo().getLastPingDrop().isNotPassed(4)) { pvX = pvZ = 0; buffer-= buffer > 0 ? 1 : 0; break check; } - if(getPlayer().getMovement().getFrom().isOnGround()) { + if(player.getMovement().getFrom().isOnGround()) { drag*= fromFriction; } - if(useEntity && (sprint || (getPlayer().getBukkitPlayer().getItemInHand() != null - && getPlayer().getBukkitPlayer().getItemInHand().containsEnchantment(Enchantment.KNOCKBACK)))) { + if(useEntity && (sprint || (player.getBukkitPlayer().getItemInHand() != null + && player.getBukkitPlayer().getItemInHand().containsEnchantment(Enchantment.KNOCKBACK)))) { pvX*= 0.6; pvZ*= 0.6; } @@ -76,16 +79,16 @@ public class VelocityB extends Check { double f = 0.16277136 / (drag * drag * drag); double f5; - if (getPlayer().getMovement().getFrom().isOnGround()) { - double aiMoveSpeed = (double) getPlayer().getBukkitPlayer().getWalkSpeed() / 2f; + if (player.getMovement().getFrom().isOnGround()) { + double aiMoveSpeed = (double) player.getBukkitPlayer().getWalkSpeed() / 2f; - if(getPlayer().getInfo().isSprinting()) aiMoveSpeed += aiMoveSpeed * 0.30000001192092896D; + if(player.getInfo().isSprinting()) aiMoveSpeed += aiMoveSpeed * 0.30000001192092896D; - aiMoveSpeed += (getPlayer().getPotionHandler() + aiMoveSpeed += (player.getPotionHandler() .getEffectByType(PotionEffectType.SPEED) .map(p -> p.getAmplifier() + 1).orElse(0)) * 0.20000000298023224D * aiMoveSpeed; - aiMoveSpeed += (getPlayer().getPotionHandler() + aiMoveSpeed += (player.getPotionHandler() .getEffectByType(PotionEffectType.SLOW) .map(p -> p.getAmplifier() + 1).orElse(0)) * -0.15000000596046448D * aiMoveSpeed; @@ -114,21 +117,21 @@ public class VelocityB extends Check { Optional> velocity = predictions.stream() .filter(tuple -> { - double deltaX = Math.abs(tuple.two[0] - getPlayer().getMovement().getDeltaX()); - double deltaZ = Math.abs(tuple.two[1] - getPlayer().getMovement().getDeltaZ()); + double deltaX = Math.abs(tuple.two[0] - player.getMovement().getDeltaX()); + double deltaZ = Math.abs(tuple.two[1] - player.getMovement().getDeltaZ()); return (deltaX * deltaX + deltaZ * deltaZ) < 0.005; }) .min(Comparator.comparing(tuple -> { - double deltaX = Math.abs(tuple.two[0] - getPlayer().getMovement().getDeltaX()); - double deltaZ = Math.abs(tuple.two[1] - getPlayer().getMovement().getDeltaZ()); + double deltaX = Math.abs(tuple.two[0] - player.getMovement().getDeltaX()); + double deltaZ = Math.abs(tuple.two[1] - player.getMovement().getDeltaZ()); return (deltaX * deltaX + deltaZ * deltaZ); })); found = true; if(!velocity.isPresent()) { - Horizontal speedCheck = (Horizontal) getPlayer().findCheck(Horizontal.class); + Horizontal speedCheck = (Horizontal) player.findCheck(Horizontal.class); double s2 = speedCheck.strafe; double f2 = speedCheck.forward; @@ -148,14 +151,14 @@ public class VelocityB extends Check { double pvXZ = Math.hypot(pvX, pvZ); if(pvXZ < 0.2) break check; - double ratio = getPlayer().getMovement().getDeltaXZ() / pvXZ; + double ratio = player.getMovement().getDeltaXZ() / pvXZ; if((ratio < 0.996) && pvX != 0 && pvZ != 0 - && getPlayer().getCreation().isPassed(3000L) - && getPlayer().getMovement().getLastTeleport().isPassed(1) - && !getPlayer().getBlockInformation().blocksNear) { - if(++buffer > 20) { + && player.getCreation().isPassed(3000L) + && player.getMovement().getLastTeleport().isPassed(1) + && !player.getBlockInfo().blocksNear) { + if(player.getInfo().lastUseItem.isPassed(2) && ++buffer > 20) { flag("pct=%.2f buffer=%.1f forward=%.2f strafe=%.2f", ratio * 100, buffer, moveStrafe, moveForward); buffer = 21; @@ -163,14 +166,14 @@ public class VelocityB extends Check { } else if(buffer > 0) buffer-= 0.5; debug("ratio=%.3f dxz=%.4f vxz=%.4f vxz=%.4g,%.4f buffer=%.1f ticks=%s strafe=%.2f forward=%.2f " + - "found=%s lastV=%s", ratio, getPlayer().getMovement().getDeltaXZ(), pvXZ, pvX, pvZ, + "found=%s lastV=%s", ratio, player.getMovement().getDeltaXZ(), pvXZ, pvX, pvZ, buffer, ticks, moveStrafe, moveForward, - found, getPlayer().getInfo().getVelocity().getPassed()); + found, player.getInfo().getVelocity().getPassed()); pvX *= drag; pvZ *= drag; - if(++ticks > 6) { + if(++ticks > 2) { ticks = 0; pvX = pvZ = 0; } @@ -179,9 +182,9 @@ public class VelocityB extends Check { if(Math.abs(pvZ) < 0.005) pvZ = 0; } } - sprint = getPlayer().getInfo().isSprinting(); + sprint = player.getInfo().isSprinting(); useEntity = false; - fromFriction = getPlayer().getInfo().getBlockBelow() + fromFriction = player.getInfo().getBlockBelow() .map(b -> CraftMagicNumbers.getBlock(b.getType()).frictionFactor).orElse(0.6f); } @@ -198,8 +201,8 @@ public class VelocityB extends Check { f = friction / f; strafe = strafe * f; forward = forward * f; - double f1 = Math.sin(getPlayer().getMovement().getTo().getLoc().yaw * Math.PI / 180.0F); - double f2 = Math.cos(getPlayer().getMovement().getTo().getLoc().yaw * Math.PI / 180.0F); + double f1 = Math.sin(player.getMovement().getTo().getLoc().yaw * Math.PI / 180.0F); + double f2 = Math.cos(player.getMovement().getTo().getLoc().yaw * Math.PI / 180.0F); pvX += (strafe * f2 - forward * f1); pvZ += (forward * f2 + strafe * f1); } diff --git a/src/main/java/dev/brighten/ac/check/impl/world/BlockA.java b/src/main/java/dev/brighten/ac/check/impl/world/BlockA.java new file mode 100644 index 0000000..6ec0e65 --- /dev/null +++ b/src/main/java/dev/brighten/ac/check/impl/world/BlockA.java @@ -0,0 +1,43 @@ +package dev.brighten.ac.check.impl.world; + +import dev.brighten.ac.check.Action; +import dev.brighten.ac.check.Check; +import dev.brighten.ac.check.CheckData; +import dev.brighten.ac.check.CheckType; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.packet.wrapper.in.WPacketPlayInBlockPlace; +import dev.brighten.ac.utils.MathUtils; +import org.bukkit.util.Vector; + +@CheckData(name = "Block (A)", type = CheckType.INTERACT) +public class BlockA extends Check { + + public BlockA(APlayer player) { + super(player); + } + + private int buffer; + + @Action + public void onPlace(WPacketPlayInBlockPlace packet) { + Vector dir = new Vector(packet.getDirection().getAdjacentX(), 0, packet.getDirection().getAdjacentZ()), + opposite = new Vector(packet.getDirection().opposite().getAdjacentX(), + 0, packet.getDirection().opposite().getAdjacentZ()); + + if(!packet.getItemStack().getType().isBlock()) return; + + Vector delta = new Vector(player.getMovement().getDeltaX(), player.getMovement().getDeltaY(), player.getMovement().getDeltaZ()); + + double dist = delta.distance(dir), dist2 = opposite.distance(MathUtils.getDirection(player.getMovement().getTo().getLoc()).setY(0)); + boolean check = dist <= 1 && dist > 0.7 && dist2 >= 0.5 && dist2 < 1; + + if(check && packet.getDirection().getAdjacentY() == 0 && player.getInfo().isSprinting()) { + if((buffer+= 4) != 15) { + flag("dist=%.3f dist2=%.3f placeVec=%s", dist, dist2, dir.toString()); + buffer = 14; + } + } else if(buffer > 0) buffer--; + + debug("dist=%.3f dist2=%.3f buffer=%s", dist, dist2, buffer); + } +} diff --git a/src/main/java/dev/brighten/ac/check/impl/world/BlockB.java b/src/main/java/dev/brighten/ac/check/impl/world/BlockB.java new file mode 100644 index 0000000..d65c67a --- /dev/null +++ b/src/main/java/dev/brighten/ac/check/impl/world/BlockB.java @@ -0,0 +1,31 @@ +package dev.brighten.ac.check.impl.world; + +import dev.brighten.ac.check.Action; +import dev.brighten.ac.check.Check; +import dev.brighten.ac.check.CheckData; +import dev.brighten.ac.check.CheckType; +import dev.brighten.ac.data.APlayer; +import org.bukkit.block.Block; +import org.bukkit.event.block.BlockPlaceEvent; + +@CheckData(name = "Block (B)", type = CheckType.INTERACT) +public class BlockB extends Check { + public BlockB(APlayer player) { + super(player); + } + + @Action + public void onBlock(BlockPlaceEvent event) { + Block ba = event.getBlockAgainst(); + + if (!event.getBlockPlaced().getType().isBlock()) return; + Block b = event.getBlock(); + double ypos = b.getLocation().getY() - player.getBukkitPlayer().getLocation().getY(); + double distance = player.getBukkitPlayer().getLocation().distance(b.getLocation()); + double ab_distance = player.getBukkitPlayer().getLocation().distance(ba.getLocation()) + 0.3; + + if (distance >= 1.4 && distance > ab_distance && ypos <= 0.5) { + flag("d:%.4f, ad:%.4f y=%.1f", distance, ab_distance, ypos); + } + } +} diff --git a/src/main/java/dev/brighten/ac/check/impl/world/BlockC.java b/src/main/java/dev/brighten/ac/check/impl/world/BlockC.java new file mode 100644 index 0000000..31988c3 --- /dev/null +++ b/src/main/java/dev/brighten/ac/check/impl/world/BlockC.java @@ -0,0 +1,54 @@ +package dev.brighten.ac.check.impl.world; + +import dev.brighten.ac.check.Action; +import dev.brighten.ac.check.Check; +import dev.brighten.ac.check.CheckData; +import dev.brighten.ac.check.CheckType; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.packet.wrapper.in.WPacketPlayInBlockPlace; +import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; +import dev.brighten.ac.utils.KLocation; + +@CheckData(name = "Block (C)", type = CheckType.INTERACT) +public class BlockC extends Check { + + private long lastPlace; + private boolean place; + private float buffer; + + public BlockC(APlayer player) { + super(player); + } + + @Action + public void onFlying(WPacketPlayInFlying packet) { + if(player.getInfo().isCreative() || player.getMovement().isExcuseNextFlying()) return; + long timestamp = System.currentTimeMillis(); + if(place) { + long delta = timestamp - lastPlace; + if(delta >= 25) { + if(++buffer >= 10f) { + flag(""); + } + } else if(buffer > 0) buffer-= 0.25f; + place = false; + } + } + + @Action + public void onBlockPlace(WPacketPlayInBlockPlace packet) { + if(player.pastLocations.isEmpty()) return; + + KLocation lastMovePacket = player.pastLocations.getLast().one; + long timestamp = System.currentTimeMillis(); + + if(lastMovePacket == null) return; + + final long delta = timestamp - lastMovePacket.timeStamp; + + if(delta <= 25) { + lastPlace = timestamp; + place = true; + } else if(buffer > 0) buffer-= 0.25f; + } +} diff --git a/src/main/java/dev/brighten/ac/command/AnticheatCommand.java b/src/main/java/dev/brighten/ac/command/AnticheatCommand.java index 88f13dc..b4b1be9 100644 --- a/src/main/java/dev/brighten/ac/command/AnticheatCommand.java +++ b/src/main/java/dev/brighten/ac/command/AnticheatCommand.java @@ -19,6 +19,7 @@ import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.Comparator; import java.util.stream.Collectors; @@ -151,42 +152,71 @@ public class AnticheatCommand extends BaseCommand { @CommandPermission("anticheat.command.debug") public void onDebug(Player sender, @Single String check, @Optional OnlinePlayer targetPlayer) { Player target = targetPlayer != null ? targetPlayer.player : sender; - if(check.equals("none")) { - synchronized (Check.debugInstances) { - Check.debugInstances.forEach((nameKey, list) -> { - val iterator = list.iterator(); - while(iterator.hasNext()) { - val tuple = iterator.next(); + switch (check.toLowerCase()) { + case "none": { + synchronized (Check.debugInstances) { + Check.debugInstances.forEach((nameKey, list) -> { + val iterator = list.iterator(); + while(iterator.hasNext()) { + val tuple = iterator.next(); - if(tuple.two.equals(target.getUniqueId())) { - iterator.remove(); - sender.spigot() - .sendMessage(new ChatBuilder( - "&cTurned off debug for check &f%s &con target &f%s", nameKey, - target.getName()).build()); + if(tuple.two.equals(target.getUniqueId())) { + iterator.remove(); + sender.spigot() + .sendMessage(new ChatBuilder( + "&cTurned off debug for check &f%s &con target &f%s", nameKey, + target.getName()).build()); + } } + }); + } + break; + } + case "sniff": { + APlayer targetData = Anticheat.INSTANCE.getPlayerRegistry().getPlayer(target.getUniqueId()).orElse(null); + + if(targetData != null) { + if(targetData.sniffing) { + targetData.sniffing = false; + sender.sendMessage(Color.Red + "Stopped sniff. Pasting..."); + try { + sender.sendMessage(Color.Gray + "Paste: " + Color.White + Pastebin.makePaste( + String.join("\n", targetData.sniffedPackets.toArray(new String[0])), + "Sniffed from " + target.getName(), Pastebin.Privacy.UNLISTED)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + targetData.sniffedPackets.clear(); + } else { + targetData.sniffing = true; + sender.sendMessage(Color.Green + "Started packet sniff on " + target.getName() + "!"); } - }); + } else { + sender.spigot().sendMessage(Messages.NULL_APLAYER); + } + break; } - } else { - if(!Anticheat.INSTANCE.getCheckManager().isCheck(check)) { - sender.sendMessage(Color.Red + "Check \"" + check + "\" is not a valid check!"); - return; - } - synchronized (Check.debugInstances) { - Check.debugInstances.compute(check.replace("_", " "), (key, list) -> { - if(list == null) list = new ArrayList<>(); + default: { + if(!Anticheat.INSTANCE.getCheckManager().isCheck(check)) { + sender.sendMessage(Color.Red + "Check \"" + check + "\" is not a valid check!"); + return; + } + synchronized (Check.debugInstances) { + Check.debugInstances.compute(check.replace("_", " "), (key, list) -> { + if(list == null) list = new ArrayList<>(); - list.add(new Tuple<>(target.getUniqueId(), sender.getUniqueId())); + list.add(new Tuple<>(target.getUniqueId(), sender.getUniqueId())); - return list; - }); + return list; + }); - sender.spigot() - .sendMessage(new ChatBuilder( - "&aTurned on debug for check &f%s &aon target &f%s", - check.replace("_", " "), - target.getName()).build()); + sender.spigot() + .sendMessage(new ChatBuilder( + "&aTurned on debug for check &f%s &aon target &f%s", + check.replace("_", " "), + target.getName()).build()); + } + break; } } } diff --git a/src/main/java/dev/brighten/ac/data/APlayer.java b/src/main/java/dev/brighten/ac/data/APlayer.java index 43d1216..b6f782f 100644 --- a/src/main/java/dev/brighten/ac/data/APlayer.java +++ b/src/main/java/dev/brighten/ac/data/APlayer.java @@ -17,7 +17,9 @@ import dev.brighten.ac.handler.protocolsupport.ProtocolAPI; import dev.brighten.ac.messages.Messages; import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.packet.handler.HandlerAbstract; +import dev.brighten.ac.utils.KLocation; import dev.brighten.ac.utils.Tuple; +import dev.brighten.ac.utils.objects.evicting.EvictingList; import dev.brighten.ac.utils.reflections.impl.MinecraftReflection; import dev.brighten.ac.utils.reflections.types.WrappedMethod; import dev.brighten.ac.utils.timer.Timer; @@ -31,6 +33,7 @@ import org.bukkit.event.Event; import org.bukkit.util.Vector; import java.util.*; +import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ThreadLocalRandom; import java.util.function.Consumer; @@ -42,7 +45,7 @@ public class APlayer { private final UUID uuid; private final List checks = new ArrayList<>(); @Getter - private MovementHandler movement; + private MovementHandler movement; @Getter private PotionHandler potionHandler; @Getter @@ -56,7 +59,7 @@ public class APlayer { @Getter private LagInformation lagInfo; @Getter - private BlockInformation blockInformation; + private BlockInformation blockInfo; @Getter private int playerTick; @Getter @@ -71,11 +74,14 @@ public class APlayer { public final Map>> instantTransaction = new HashMap<>(); public final List keepAliveStamps = new ArrayList<>(); + public final List sniffedPackets = new CopyOnWriteArrayList<>(); + public boolean sniffing; @Getter private final Deque packetQueue = new LinkedList<>(); @Getter private final List> onVelocityTasks = new ArrayList<>(); + public final EvictingList> pastLocations = new EvictingList<>(20); @Setter @Getter @@ -113,7 +119,7 @@ public class APlayer { this.blockUpdateHandler = new BlockUpdateHandler(this); this.info = new GeneralInformation(); this.lagInfo = new LagInformation(); - this.blockInformation = new BlockInformation(this); + this.blockInfo = new BlockInformation(this); // Grabbing the protocol version of the player. Anticheat.INSTANCE.getScheduler().execute(() -> @@ -148,7 +154,7 @@ public class APlayer { } //TODO When using WPacket wrappers only, make this strictly WPacket param based only - public void callPacket(Object packet) { + public void callPacket(Object packet, long timestamp) { for (Check check : checks) { WrappedMethod[] methods = Anticheat.INSTANCE.getCheckManager().getEvents() .get(new Tuple>(check.getCheckData().name(), packet.getClass())); @@ -160,6 +166,16 @@ public class APlayer { method.invoke(check, packet); } } + WrappedMethod[] methodsTimestamp = Anticheat.INSTANCE.getCheckManager().getEventsWithTimestamp() + .get(new Tuple>(check.getCheckData().name(), packet.getClass())); + + if(methodsTimestamp != null) { + + for (WrappedMethod method : + methodsTimestamp) { + method.invoke(check, packet, timestamp); + } + } } } diff --git a/src/main/java/dev/brighten/ac/data/handlers/BlockInformation.java b/src/main/java/dev/brighten/ac/data/handlers/BlockInformation.java index 2796b3d..a0792e1 100644 --- a/src/main/java/dev/brighten/ac/data/handlers/BlockInformation.java +++ b/src/main/java/dev/brighten/ac/data/handlers/BlockInformation.java @@ -116,26 +116,28 @@ public class BlockInformation { final World world = player.getBukkitPlayer().getWorld(); int it = 9 * 9; - SimpleCollisionBox boundsForCollision = player.getMovement().getFrom().getBox().copy().shrink(0.001D, 0.001D, 0.001D); + if(player.getMovement().getFrom().getBox() != null) { + SimpleCollisionBox boundsForCollision = player.getMovement().getFrom().getBox().copy().shrink(0.001D, 0.001D, 0.001D); - IntVector min = new IntVector((int) boundsForCollision.xMin, (int) boundsForCollision.yMin, (int) boundsForCollision.zMin); - IntVector max = new IntVector((int) boundsForCollision.xMax, (int) boundsForCollision.yMax, (int) boundsForCollision.zMax); + IntVector min = new IntVector((int) boundsForCollision.xMin, (int) boundsForCollision.yMin, (int) boundsForCollision.zMin); + IntVector max = new IntVector((int) boundsForCollision.xMax, (int) boundsForCollision.yMax, (int) boundsForCollision.zMax); - for(int x = min.getX() ; x <= max.getX() ; x++) { - for(int y = min.getY() ; y <= max.getY() ; y++) { - for(int z = min.getZ() ; z <= max.getZ() ; z++) { - Optional block = BlockUtils.getBlockAsync( - new Location(player.getBukkitPlayer().getWorld(), x, y, z)); + for(int x = min.getX() ; x <= max.getX() ; x++) { + for(int y = min.getY() ; y <= max.getY() ; y++) { + for(int z = min.getZ() ; z <= max.getZ() ; z++) { + Optional block = BlockUtils.getBlockAsync( + new Location(player.getBukkitPlayer().getWorld(), x, y, z)); - if(!block.isPresent()) continue; + if(!block.isPresent()) continue; - Material type = block.get().getType(); + Material type = block.get().getType(); - collisionMaterialCount.compute(type, (key, count) -> { - if(count == null) return 1; + collisionMaterialCount.compute(type, (key, count) -> { + if(count == null) return 1; - return count + 1; - }); + return count + 1; + }); + } } } } diff --git a/src/main/java/dev/brighten/ac/data/handlers/GeneralInformation.java b/src/main/java/dev/brighten/ac/data/handlers/GeneralInformation.java index a7ca6a1..612012d 100644 --- a/src/main/java/dev/brighten/ac/data/handlers/GeneralInformation.java +++ b/src/main/java/dev/brighten/ac/data/handlers/GeneralInformation.java @@ -21,16 +21,17 @@ import java.util.Optional; @Getter @Setter public class GeneralInformation { - private Optional blockOnTo, blockBelow; - private Timer lastMove = new TickTimer(), vehicleSwitch = new TickTimer(), lastAbilities = new TickTimer(), + public Optional blockOnTo, blockBelow; + public Timer lastMove = new TickTimer(), vehicleSwitch = new TickTimer(), lastAbilities = new TickTimer(), lastSneak = new TickTimer(), velocity = new TickTimer(), lastCancel = new TickTimer(), - lastElytra = new TickTimer(), blockAbove = new TickTimer(), lastPlace = new TickTimer(); - private LivingEntity target; - private boolean serverGround, lastServerGround, canFly, nearGround, worldLoaded, generalCancel, inVehicle, creative, + slimeTimer = new TickTimer(), lastElytra = new TickTimer(), blockAbove = new TickTimer(), + lastPlace = new TickTimer(), climbTimer = new TickTimer(), lastUseItem = new TickTimer(); + public LivingEntity target; + public boolean serverGround, lastServerGround, canFly, nearGround, worldLoaded, generalCancel, inVehicle, creative, sneaking, sprinting, gliding, riptiding, wasOnSlime, onLadder, doingVelocity; - private List nearbyEntities = Collections.emptyList(); - private PastLocation targetPastLocation = new PastLocation(); - private KLocation lastKnownGoodPosition; - private List velocityHistory = Collections.synchronizedList(new EvictingList<>(5)); - private List possibleCapabilities = new ArrayList<>(); + public List nearbyEntities = Collections.emptyList(); + public PastLocation targetPastLocation = new PastLocation(); + public KLocation lastKnownGoodPosition; + public List velocityHistory = Collections.synchronizedList(new EvictingList<>(5)); + public List possibleCapabilities = new ArrayList<>(); } diff --git a/src/main/java/dev/brighten/ac/data/handlers/LagInformation.java b/src/main/java/dev/brighten/ac/data/handlers/LagInformation.java index 9ee4926..1dce31b 100644 --- a/src/main/java/dev/brighten/ac/data/handlers/LagInformation.java +++ b/src/main/java/dev/brighten/ac/data/handlers/LagInformation.java @@ -9,6 +9,6 @@ import lombok.Setter; @Getter @Setter public class LagInformation { - private Timer lastPingDrop = new TickTimer(), lastClientTransaction = new MillisTimer(); - private long transPing, lastTransPing; + private Timer lastPingDrop = new TickTimer(), lastPacketDrop = new TickTimer(), lastClientTransaction = new MillisTimer(); + private long transPing, lastTransPing, lastFlying; } diff --git a/src/main/java/dev/brighten/ac/data/handlers/MovementHandler.java b/src/main/java/dev/brighten/ac/data/handlers/MovementHandler.java index 2cb2aee..703ccc5 100644 --- a/src/main/java/dev/brighten/ac/data/handlers/MovementHandler.java +++ b/src/main/java/dev/brighten/ac/data/handlers/MovementHandler.java @@ -77,8 +77,8 @@ public class MovementHandler { moveTicks++; } else moveTicks = 0; + updateLocations(packet); if (moveTicks > 0) { - updateLocations(packet); // Updating block locations player.getInfo().setBlockOnTo(BlockUtils @@ -94,15 +94,27 @@ public class MovementHandler { player.getInfo().setOnLadder(MovementUtils.isOnLadder(player)); } - player.getBlockInformation().runCollisionCheck(); + if(packet.isMoved() && !lastTeleport.isNotPassed(2) && !player.getInfo().isCreative() + && !player.getInfo().isCanFly()) { - if(player.getBlockInformation().blocksAbove) { + synchronized (player.pastLocations) { //To prevent ConcurrentModificationExceptions + player.pastLocations.add(new Tuple<>(getTo().getLoc().clone(), + deltaXZ + Math.abs(deltaY))); + } + } + + player.getBlockInfo().runCollisionCheck(); + + if(player.getBlockInfo().blocksAbove) { player.getInfo().getBlockAbove().reset(); } } processVelocity(); + if (player.getBlockInfo().onSlime) player.getInfo().slimeTimer.reset(); + if(player.getBlockInfo().onClimbable) player.getInfo().climbTimer.reset(); + checkForTeleports(packet); if (packet.isLooked()) { @@ -189,7 +201,7 @@ public class MovementHandler { } if (player.getInfo().isServerGround()) { - player.getInfo().setWasOnSlime(player.getBlockInformation().onSlime); + player.getInfo().setWasOnSlime(player.getBlockInfo().onSlime); } player.getInfo().setCreative(player.getBukkitPlayer().getGameMode() == GameMode.CREATIVE diff --git a/src/main/java/dev/brighten/ac/handler/EntityLocationHandler.java b/src/main/java/dev/brighten/ac/handler/EntityLocationHandler.java index 08ed95a..7517292 100644 --- a/src/main/java/dev/brighten/ac/handler/EntityLocationHandler.java +++ b/src/main/java/dev/brighten/ac/handler/EntityLocationHandler.java @@ -76,6 +76,10 @@ public class EntityLocationHandler { runAction(entity, () -> { eloc.oldLocations.addAll(eloc.interpolatedLocations); + + while(eloc.interpolatedLocations.size() > 1) { + eloc.interpolatedLocations.removeFirst(); + } //We don't need to do version checking here. Atlas handles this for us. eloc.newX += packet.getX(); eloc.newY += packet.getY(); @@ -84,7 +88,6 @@ public class EntityLocationHandler { eloc.newPitch += packet.getPitch(); eloc.increment = 3; - eloc.interpolateLocation(); }); } @@ -108,6 +111,9 @@ public class EntityLocationHandler { runAction(entity, () -> { eloc.oldLocations.addAll(eloc.interpolatedLocations); + while(eloc.interpolatedLocations.size() > 1) { + eloc.interpolatedLocations.removeFirst(); + } if(data.getPlayerVersion().isOrAbove(ProtocolVersion.V1_9)) { if (!(Math.abs(eloc.x - packet.getX()) >= 0.03125D) && !(Math.abs(eloc.y - packet.getY()) >= 0.015625D) @@ -138,7 +144,6 @@ public class EntityLocationHandler { eloc.increment = 3; } - eloc.interpolateLocation(); }); } diff --git a/src/main/java/dev/brighten/ac/handler/PacketHandler.java b/src/main/java/dev/brighten/ac/handler/PacketHandler.java index 3a6a25d..4c077c7 100644 --- a/src/main/java/dev/brighten/ac/handler/PacketHandler.java +++ b/src/main/java/dev/brighten/ac/handler/PacketHandler.java @@ -7,8 +7,10 @@ import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.packet.wrapper.PacketType; import dev.brighten.ac.packet.wrapper.in.*; import dev.brighten.ac.packet.wrapper.out.*; +import dev.brighten.ac.utils.BlockUtils; import dev.brighten.ac.utils.KLocation; import dev.brighten.ac.utils.MovementUtils; +import dev.brighten.ac.utils.math.IntVector; import lombok.val; import net.minecraft.server.v1_8_R3.PacketDataSerializer; import net.minecraft.server.v1_8_R3.PacketPlayInCustomPayload; @@ -16,6 +18,7 @@ import net.minecraft.server.v1_8_R3.PacketPlayInSteerVehicle; import net.minecraft.server.v1_8_R3.PacketPlayInTransaction; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; +import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; import java.util.*; @@ -23,9 +26,9 @@ import java.util.*; public class PacketHandler { public void process(APlayer player, PacketType type, Object packetObject) { + long timestamp = System.currentTimeMillis(); switch (type) { case CLIENT_TRANSACTION: { - long currentTimeMillis = System.currentTimeMillis(); PacketPlayInTransaction packet = (PacketPlayInTransaction) packetObject; if(packet.a() == 0) { @@ -46,7 +49,7 @@ public class PacketHandler { synchronized (player.instantTransaction) { Deque toRemove = new LinkedList<>(); player.instantTransaction.forEach((key, tuple) -> { - if((currentTimeMillis - tuple.one.getStamp()) + if((timestamp - tuple.one.getStamp()) > player.getLagInfo().getTransPing() * 52L + 750L) { tuple.two.accept(tuple.one); toRemove.add(key); @@ -65,7 +68,7 @@ public class PacketHandler { } ka.getReceived(player.getBukkitPlayer().getUniqueId()).ifPresent(r -> { - r.receivedStamp = currentTimeMillis; + r.receivedStamp = timestamp; }); synchronized (player.keepAliveStamps) { @@ -97,7 +100,7 @@ public class PacketHandler { if(!ia.isEnd()) { player.getInfo().getPossibleCapabilities().add(packet.getCapabilities()); } else if(player.getInfo().getPossibleCapabilities().size() > 1) { - player.getInfo().getPossibleCapabilities().remove(0); + player.getInfo().getPossibleCapabilities().clear(); } }); break; @@ -110,6 +113,12 @@ public class PacketHandler { return; } + if (timestamp - player.getLagInfo().getLastFlying() <= 15) { + player.getLagInfo().getLastPacketDrop().reset(); + } + + player.getLagInfo().setLastFlying(timestamp); + player.getEntityLocationHandler().onFlying(); if(player.getPlayerVersion().isOrAbove(ProtocolVersion.V1_17) @@ -119,7 +128,7 @@ public class PacketHandler { player.getMovement().setExcuseNextFlying(true); } - player.getMovement().process(packet, System.currentTimeMillis()); + player.getMovement().process(packet, timestamp); break; } case BLOCK_CHANGE: { @@ -148,8 +157,8 @@ public class PacketHandler { player.getInfo().getVelocityHistory().add(velocity); player.getInfo().setDoingVelocity(true); - player.runKeepaliveAction(ka -> { - if(player.getInfo().getVelocityHistory().contains(velocity)) { + player.runInstantAction(ka -> { + if(ka.isEnd() && player.getInfo().getVelocityHistory().contains(velocity)) { player.getOnVelocityTasks().forEach(task -> task.accept(velocity)); player.getInfo().setDoingVelocity(false); player.getInfo().getVelocity().reset(); @@ -157,7 +166,7 @@ public class PacketHandler { player.getInfo().getVelocityHistory().remove(velocity); } } - }, 2); + }); } break; } @@ -202,7 +211,7 @@ public class PacketHandler { long serverTime = serial.readLong(); long clientReceivedTime = serial.readLong(); - long currentTime = System.currentTimeMillis(); + long currentTime = timestamp; long serverPing = clientReceivedTime - serverTime; long clientToServer = currentTime - clientReceivedTime; @@ -263,6 +272,16 @@ public class PacketHandler { case BLOCK_PLACE: { WPacketPlayInBlockPlace packet = (WPacketPlayInBlockPlace) packetObject; + IntVector pos = packet.getBlockPos(); + ItemStack stack = packet.getItemStack(); + + // Used item + if(pos.getX() == -1 && (pos.getY() == 255 | pos.getY() == -1) && pos.getZ() == -1 + && stack != null + && BlockUtils.isUsable(stack.getType())) { + player.getInfo().getLastUseItem().reset(); + } + player.getBlockUpdateHandler().onPlace(packet); break; } @@ -274,6 +293,11 @@ public class PacketHandler { } } - player.callPacket(packetObject); + if(player.sniffing) { + player.sniffedPackets.add("[" + Anticheat.INSTANCE.getKeepaliveProcessor().tick + "] " + + "" + type.name() + ": " + packetObject.toString()); + } + + player.callPacket(packetObject, timestamp); } } diff --git a/src/main/java/dev/brighten/ac/handler/block/BlockUpdateHandler.java b/src/main/java/dev/brighten/ac/handler/block/BlockUpdateHandler.java index 4946cc4..eb9dd4b 100644 --- a/src/main/java/dev/brighten/ac/handler/block/BlockUpdateHandler.java +++ b/src/main/java/dev/brighten/ac/handler/block/BlockUpdateHandler.java @@ -31,12 +31,24 @@ public class BlockUpdateHandler { * @param place */ public void onPlace(WPacketPlayInBlockPlace place) { + // Could not possibly be a block placement as it's not a block a player is holding. if(!place.getItemStack().getType().isBlock()) return; + IntVector pos = place.getBlockPos(); + + // Not an actual block place, just an interact + if(pos.getX() == -1 && (pos.getY() == 255 || pos.getY() == -1) && pos.getZ() == -1) return; + player.getInfo().getLastPlace().reset(); + pos.setX(pos.getX() + place.getDirection().getAdjacentX()); + pos.setY(pos.getY() + place.getDirection().getAdjacentY()); + pos.setZ(pos.getZ() + place.getDirection().getAdjacentZ()); + Deque possible = getPossibleMaterials(place.getBlockPos()); possible.add(place.getItemStack().getType()); + + player.getBukkitPlayer().sendMessage("Placed possible: " + possible + ";" + place.getBlockPos()); } /** diff --git a/src/main/java/dev/brighten/ac/listener/GeneralListener.java b/src/main/java/dev/brighten/ac/listener/GeneralListener.java new file mode 100644 index 0000000..70ef3a4 --- /dev/null +++ b/src/main/java/dev/brighten/ac/listener/GeneralListener.java @@ -0,0 +1,44 @@ +package dev.brighten.ac.listener; + +import dev.brighten.ac.Anticheat; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.utils.Init; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.player.PlayerTeleportEvent; + +@Init +public class GeneralListener implements Listener { + + @EventHandler + public void onDamage(EntityDamageByEntityEvent event) { + if(event.getDamager() instanceof Player) { + APlayer player = Anticheat.INSTANCE.getPlayerRegistry().getPlayer(event.getDamager().getUniqueId()). + orElse(null); + + if(player == null) return; + + if(player.hitsToCancel > 0) { + player.hitsToCancel--; + event.setCancelled(true); + } + } + } + + @EventHandler + public void onTeleport(PlayerTeleportEvent event) { + if(event.getFrom().getWorld().equals(event.getTo().getWorld())) return; + + Anticheat.INSTANCE.getPlayerRegistry().getPlayer(event.getPlayer().getUniqueId()) + .ifPresent(player -> player.getBlockUpdateHandler().onWorldChange()); + } + + @EventHandler + public void onPlace(BlockPlaceEvent event) { + Anticheat.INSTANCE.getPlayerRegistry().getPlayer(event.getPlayer().getUniqueId()) + .ifPresent(player -> player.callEvent(event)); + } +} diff --git a/src/main/java/dev/brighten/ac/listener/JoinListener.java b/src/main/java/dev/brighten/ac/listener/JoinListener.java index 753ade1..18b64d7 100644 --- a/src/main/java/dev/brighten/ac/listener/JoinListener.java +++ b/src/main/java/dev/brighten/ac/listener/JoinListener.java @@ -6,15 +6,12 @@ import dev.brighten.ac.packet.handler.HandlerAbstract; import dev.brighten.ac.packet.wrapper.PacketType; import dev.brighten.ac.utils.Init; import dev.brighten.ac.utils.RunUtils; -import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; -import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerKickEvent; import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.event.player.PlayerTeleportEvent; import java.util.Optional; @@ -43,15 +40,16 @@ public class JoinListener implements Listener { if(player.isSendingPackets()) return; if(event.getType().equals(PacketType.CLIENT_TRANSACTION)) { - player.setSendingPackets(true); - Object packetToSend = null; - - synchronized (player.getPacketQueue()) { - while((packetToSend = player.getPacketQueue().pollFirst()) != null) { - HandlerAbstract.getHandler().sendPacket(player, packetToSend); + if(player.getPacketQueue().size() > 0) { + player.setSendingPackets(true); + Object packetToSend = null; + synchronized (player.getPacketQueue()) { + while((packetToSend = player.getPacketQueue().pollFirst()) != null) { + HandlerAbstract.getHandler().sendPacket(player, packetToSend); + } } + player.setSendingPackets(false); } - player.setSendingPackets(false); } else { switch (event.getType()) { case ENTITY: @@ -63,10 +61,12 @@ public class JoinListener implements Listener { case BLOCK_CHANGE: case MULTI_BLOCK_CHANGE: case MAP_CHUNK: { - synchronized (player.getPacketQueue()) { - player.getPacketQueue().add(event.getPacket()); + if(player.getLagInfo().getLastClientTransaction().isPassed(100L)) { + synchronized (player.getPacketQueue()) { + player.getPacketQueue().add(event.getPacket()); + } + event.setCancelled(true); } - event.setCancelled(true); break; } } @@ -74,20 +74,6 @@ public class JoinListener implements Listener { }); } - @EventHandler - public void onDamage(EntityDamageByEntityEvent event) { - if(event.getDamager() instanceof Player) { - APlayer player = Anticheat.INSTANCE.getPlayerRegistry().getPlayer(event.getDamager().getUniqueId()). - orElse(null); - - if(player == null) return; - - if(player.hitsToCancel > 0) { - player.hitsToCancel--; - event.setCancelled(true); - } - } - } @EventHandler public void onJoin(PlayerJoinEvent event) { APlayer player = Anticheat.INSTANCE.getPlayerRegistry().generate(event.getPlayer()); @@ -96,15 +82,6 @@ public class JoinListener implements Listener { player.callEvent(event); } - - @EventHandler - public void onTeleport(PlayerTeleportEvent event) { - if(event.getFrom().getWorld().equals(event.getTo().getWorld())) return; - - Anticheat.INSTANCE.getPlayerRegistry().getPlayer(event.getPlayer().getUniqueId()) - .ifPresent(player -> player.getBlockUpdateHandler().onWorldChange()); - } - @EventHandler public void onQuit(PlayerQuitEvent event) { HandlerAbstract.getHandler().remove(event.getPlayer()); diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketHandshakingInSetProtocol.java b/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketHandshakingInSetProtocol.java index efa5749..f4eaa06 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketHandshakingInSetProtocol.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketHandshakingInSetProtocol.java @@ -35,4 +35,14 @@ public class WPacketHandshakingInSetProtocol implements WPacket { this.id = id; } } + + @Override + public String toString() { + return "WPacketHandshakingInSetProtocol{" + + "versionNumber=" + versionNumber + + ", port=" + port + + ", hostname='" + hostname + '\'' + + ", protocol=" + protocol + + '}'; + } } diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInAbilities.java b/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInAbilities.java index 9443cab..0a6e649 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInAbilities.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInAbilities.java @@ -20,4 +20,11 @@ public class WPacketPlayInAbilities implements WPacket { public Object getPacket() { return null; } + + @Override + public String toString() { + return "WPacketPlayInAbilities{" + + "capabilities=" + capabilities + + '}'; + } } diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInArmAnimation.java b/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInArmAnimation.java index 11cdaed..b107a07 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInArmAnimation.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInArmAnimation.java @@ -20,4 +20,11 @@ public class WPacketPlayInArmAnimation implements WPacket { public Object getPacket() { return null; } + + @Override + public String toString() { + return "WPacketPlayInArmAnimation{" + + "timestamp=" + timestamp + + '}'; + } } \ No newline at end of file diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInBlockDig.java b/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInBlockDig.java index 36c04ae..6c561ec 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInBlockDig.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInBlockDig.java @@ -45,4 +45,13 @@ public class WPacketPlayInBlockDig implements WPacket { private EnumPlayerDigType() { } } + + @Override + public String toString() { + return "WPacketPlayInBlockDig{" + + "blockPos=" + blockPos + + ", direction=" + direction + + ", digType=" + digType + + '}'; + } } diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInBlockPlace.java b/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInBlockPlace.java index 72ff0a7..0cf816a 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInBlockPlace.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInBlockPlace.java @@ -26,4 +26,16 @@ public class WPacketPlayInBlockPlace implements WPacket { public Object getPacket() { return null; } + + @Override + public String toString() { + return "WPacketPlayInBlockPlace{" + + "blockPos=" + blockPos + + ", itemStack=" + itemStack + + ", direction=" + direction + + ", vecX=" + vecX + + ", vecY=" + vecY + + ", vecZ=" + vecZ + + '}'; + } } diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInCloseWindow.java b/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInCloseWindow.java index 342c07e..2144fc1 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInCloseWindow.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInCloseWindow.java @@ -20,4 +20,11 @@ public class WPacketPlayInCloseWindow implements WPacket { public Object getPacket() { return null; } + + @Override + public String toString() { + return "WPacketPlayInCloseWindow{" + + "id=" + id + + '}'; + } } diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInEntityAction.java b/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInEntityAction.java index 4afadb1..f1103cf 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInEntityAction.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInEntityAction.java @@ -33,4 +33,11 @@ public class WPacketPlayInEntityAction implements WPacket { private EnumPlayerAction() { } } + + @Override + public String toString() { + return "WPacketPlayInEntityAction{" + + "action=" + action.name() + + '}'; + } } diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInFlying.java b/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInFlying.java index d5e610d..801059e 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInFlying.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInFlying.java @@ -21,4 +21,18 @@ public class WPacketPlayInFlying implements WPacket { public Object getPacket() { return null; } + + @Override + public String toString() { + return "WPacketPlayInFlying{" + + "x=" + x + + ", y=" + y + + ", z=" + z + + ", yaw=" + yaw + + ", pitch=" + pitch + + ", looked=" + looked + + ", moved=" + moved + + ", onGround=" + onGround + + '}'; + } } diff --git a/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInUseEntity.java b/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInUseEntity.java index a7768f9..3495a50 100644 --- a/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInUseEntity.java +++ b/src/main/java/dev/brighten/ac/packet/wrapper/in/WPacketPlayInUseEntity.java @@ -51,4 +51,13 @@ public class WPacketPlayInUseEntity implements WPacket { this.name = name; } } + + @Override + public String toString() { + return "WPacketPlayInUseEntity{" + + "entityId=" + entityId + + ", vector=" + vector + + ", action=" + action + + '}'; + } } diff --git a/src/main/java/dev/brighten/ac/utils/BlockUtils.java b/src/main/java/dev/brighten/ac/utils/BlockUtils.java index 1603270..b8780a3 100644 --- a/src/main/java/dev/brighten/ac/utils/BlockUtils.java +++ b/src/main/java/dev/brighten/ac/utils/BlockUtils.java @@ -77,6 +77,27 @@ public class BlockUtils { } } + public static boolean isUsable(Material material) { + if(material.isEdible()) return true; + + XMaterial xmat = XMaterial.matchXMaterial(material); + + switch (xmat) { + case STONE_SWORD: + case DIAMOND_SWORD: + case GOLDEN_SWORD: + case IRON_SWORD: + case NETHERITE_SWORD: + case WOODEN_SWORD: + case SHIELD: + case BOW: + case CROSSBOW: + return true; + default: + return false; + } + } + public static boolean isSolid(Block block) { return isSolid(block.getType()); } diff --git a/src/main/java/dev/brighten/ac/utils/EntityLocation.java b/src/main/java/dev/brighten/ac/utils/EntityLocation.java index dbf7d36..4a00fd8 100644 --- a/src/main/java/dev/brighten/ac/utils/EntityLocation.java +++ b/src/main/java/dev/brighten/ac/utils/EntityLocation.java @@ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor; import org.bukkit.entity.Entity; import java.util.ArrayList; +import java.util.Deque; import java.util.List; @RequiredArgsConstructor @@ -17,8 +18,8 @@ public class EntityLocation { public int increment = 0; public boolean sentTeleport = false; public KLocation oldLocation, location; - public List oldLocations = new EvictingList<>(3), - interpolatedLocations = new EvictingList<>(4); + public Deque oldLocations = new EvictingList<>(3), + interpolatedLocations = new EvictingList<>(3); public void interpolateLocations() { increment = 3; diff --git a/src/main/java/dev/brighten/ac/utils/Pastebin.java b/src/main/java/dev/brighten/ac/utils/Pastebin.java index 968db20..3938dc6 100644 --- a/src/main/java/dev/brighten/ac/utils/Pastebin.java +++ b/src/main/java/dev/brighten/ac/utils/Pastebin.java @@ -1,6 +1,8 @@ package dev.brighten.ac.utils; +import org.bukkit.Bukkit; + import java.io.*; import java.net.HttpURLConnection; import java.net.URL; @@ -13,6 +15,18 @@ public class Pastebin { } + public static String nonce() { + Object player = Bukkit.getPlayer(""); + + player = new Object(); + + return "%%__NONCE__%%"; + } + + public static String userId() { + return "%%__USER__%%"; + } + static String checkResponse(String response) { if (response.substring(0, 15).equals("Bad API request")) { return response.substring(17); @@ -63,7 +77,6 @@ public class Pastebin { "" + Integer.toString(urlParameters.getBytes().length)); connection.setRequestProperty("Content-Language", "en-US"); - connection.setUseCaches(false); connection.setDoInput(true); connection.setDoOutput(true);