diff --git a/src/main/java/dev/brighten/ac/check/Action.java b/src/main/java/dev/brighten/ac/check/Action.java index 9ed2e3b..8f09317 100644 --- a/src/main/java/dev/brighten/ac/check/Action.java +++ b/src/main/java/dev/brighten/ac/check/Action.java @@ -1,8 +1,6 @@ package dev.brighten.ac.check; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Retention(RetentionPolicy.RUNTIME) -public @interface Action { +@FunctionalInterface +public interface Action { + void invoke(T event); } diff --git a/src/main/java/dev/brighten/ac/check/CheckManager.java b/src/main/java/dev/brighten/ac/check/CheckManager.java index 68943ec..afc4e18 100644 --- a/src/main/java/dev/brighten/ac/check/CheckManager.java +++ b/src/main/java/dev/brighten/ac/check/CheckManager.java @@ -2,18 +2,15 @@ package dev.brighten.ac.check; import dev.brighten.ac.Anticheat; import dev.brighten.ac.utils.ClassScanner; -import dev.brighten.ac.utils.Tuple; import dev.brighten.ac.utils.reflections.types.WrappedClass; -import dev.brighten.ac.utils.reflections.types.WrappedMethod; import lombok.Getter; -import java.util.*; +import java.util.ArrayList; +import java.util.List; @Getter 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, @@ -33,62 +30,6 @@ public class CheckManager { Anticheat.INSTANCE.alog(true, "&7Adding check to CheckManager: " + checkData.name()); - synchronized (events) { - // 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) -> { - if(array == null) array = new WrappedMethod[0]; - - // Adding preexisting cached WrappedMethod into List for further additions - List methodList = new ArrayList<>(Arrays.asList(array)); - - // Adding all precached Check-specific WrappedMethod into global cache of WrappedMethods. - methodList.addAll(methods); - - System.out.println("Registering " + packetClass.toString()); - - // 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]); - }); - } - } - }); - } - checkClasses.add(check); } diff --git a/src/main/java/dev/brighten/ac/check/CheckStatic.java b/src/main/java/dev/brighten/ac/check/CheckStatic.java index 7497d57..29b3b08 100644 --- a/src/main/java/dev/brighten/ac/check/CheckStatic.java +++ b/src/main/java/dev/brighten/ac/check/CheckStatic.java @@ -2,24 +2,27 @@ package dev.brighten.ac.check; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.packet.wrapper.WPacket; +import dev.brighten.ac.utils.Tuple; import dev.brighten.ac.utils.reflections.types.WrappedClass; import dev.brighten.ac.utils.reflections.types.WrappedConstructor; -import dev.brighten.ac.utils.reflections.types.WrappedMethod; +import dev.brighten.ac.utils.reflections.types.WrappedField; import lombok.Getter; import net.minecraft.server.v1_8_R3.Packet; +import org.bukkit.Bukkit; import org.bukkit.event.Event; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; public class CheckStatic { @Getter private final WrappedClass checkClass; private WrappedConstructor initConst; @Getter - private final Map, List> events = new HashMap<>(); + private final List>> actions = new ArrayList<>(), + timedActions = new ArrayList<>(); public CheckStatic(WrappedClass checkClass) { this.checkClass = checkClass; @@ -28,19 +31,36 @@ public class CheckStatic { private void processClass() { initConst = checkClass.getConstructor(APlayer.class); - for (WrappedMethod method : checkClass.getDeclaredMethods()) { - if(!method.isAnnotationPresent(Action.class) - || method.getParameters().length == 0) continue; - Class type = method.getParameterTypes()[0]; + for (WrappedField field : checkClass.getFields()) { + if(!Action.class.isAssignableFrom(field.getType()) + || TimedAction.class.isAssignableFrom(field.getType())) continue; - if(Packet.class.isAssignableFrom(type) - || WPacket.class.isAssignableFrom(type) || Event.class.isAssignableFrom(type)) { - events.compute(type, (key, list) -> { - if(list == null) list = new ArrayList<>(); + Type genericType = field.getField().getGenericType(); + Type type = null; - list.add(method); - return list; - }); + if(genericType instanceof ParameterizedType) { + type = ((ParameterizedType) genericType).getActualTypeArguments()[0]; + } else type = genericType; + + if(type == null) { + Bukkit.getLogger().warning("Could not get type for field " + field.getField().getName() + + " in class " + checkClass.getClass().getSimpleName()); + + continue; + } + + if(!Packet.class.isAssignableFrom((Class) type) + && !WPacket.class.isAssignableFrom((Class) type) + && !Event.class.isAssignableFrom((Class) type)) { + Bukkit.getLogger().warning("Type " + ((Class) type).getSimpleName() + " is not a valid type for field " + + field.getField().getName() + " in class " + checkClass.getClass().getSimpleName()); + continue; + } + + if(field.getType().equals(Action.class)) { + actions.add(new Tuple<>(field, (Class)type)); + } else { //This will always be TimedAction + timedActions.add(new Tuple<>(field, (Class)type)); } } } diff --git a/src/main/java/dev/brighten/ac/check/TimedAction.java b/src/main/java/dev/brighten/ac/check/TimedAction.java new file mode 100644 index 0000000..4a53c89 --- /dev/null +++ b/src/main/java/dev/brighten/ac/check/TimedAction.java @@ -0,0 +1,6 @@ +package dev.brighten.ac.check; + +@FunctionalInterface +public interface TimedAction { + void invoke(T event, long timestamp); +} 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 e9309f1..f433937 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 @@ -21,8 +21,8 @@ public class Aim extends Check { private float buffer; protected Timer lastGrid = new TickTimer(3); - @Action - public void flying(WPacketPlayInFlying packet) { + + Action onFlying = (packet) -> { if(!packet.isLooked()) return; if(player.getMovement().getYawGcdList().size() < 40) { @@ -61,8 +61,7 @@ public class Aim extends Check { debug((flagged ? Color.Green : "") +"sensitivity: mcp=%.4f, cx=%.4f, cy=%.4f, dx=%.1f, dy=%.1f", player.getMovement().getSensitivityMcp(), player.getMovement().getCurrentSensX(), player.getMovement().getCurrentSensY(), deltaX, deltaY); - - } + }; /* * This is an attempt to reverse the logistics of cinematic camera without having to run a full on prediction using diff --git a/src/main/java/dev/brighten/ac/check/impl/combat/Hitbox.java b/src/main/java/dev/brighten/ac/check/impl/combat/Hitbox.java index e149919..ad0a0e4 100644 --- a/src/main/java/dev/brighten/ac/check/impl/combat/Hitbox.java +++ b/src/main/java/dev/brighten/ac/check/impl/combat/Hitbox.java @@ -36,22 +36,20 @@ public class Hitbox extends Check { super(player); } - @Action - public void onUse(WPacketPlayInUseEntity packet) { + Action useEntity = packet -> { if(packet.getAction() == WPacketPlayInUseEntity.EnumEntityUseAction.ATTACK && allowedEntityTypes.contains(packet.getEntity(player.getBukkitPlayer().getWorld()).getType())) { attacks.add(new Tuple<>(packet.getEntity(player.getBukkitPlayer().getWorld()), player.getMovement().getTo().getLoc().clone())); } - } + }; //TODO Figure out how to make the check more sensitive without compromising network stability //Aka figure out how to minimize the amount of previous locations needed to process to keep network //stability. like shortening the amount stored, or removing older ones. - @Action - public void onFlying(WPacketPlayInFlying packet) { + Action onFlying = packet -> { if(player.getInfo().isCreative() || player.getInfo().isInVehicle()) { attacks.clear(); - return; + return; } Tuple target; @@ -116,8 +114,8 @@ public class Hitbox extends Check { || player.getInfo().getLastElytra().isNotPassed(40); List directions = new ArrayList<>(Arrays.asList(MathUtils.getDirection( - player.getMovement().getTo().getLoc().yaw, - player.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))); @@ -180,6 +178,6 @@ public class Hitbox extends Check { debug("Missed!"); } } - } + }; } 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 f3b5f25..959ee31 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 @@ -23,8 +23,7 @@ public class FlyA extends Check { private float buffer; private static double mult = 0.98f; - @Action - public void onFlying(WPacketPlayInFlying packet) { + Action flying = packet -> { if(!packet.isMoved() || (player.getMovement().getDeltaXZ() == 0 && player.getMovement().getDeltaY() == 0)) { return; @@ -79,5 +78,5 @@ public class FlyA extends Check { 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 45db4b2..62a416d 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 @@ -18,8 +18,7 @@ public class FlyB extends Check { private Timer lastNearGround = new TickTimer(); private float buffer; - @Action - public void onFlying(WPacketPlayInFlying packet) { + Action flying = packet -> { if(player.getInfo().isNearGround()) lastNearGround.reset(); if(!packet.isMoved() || player.getInfo().isGeneralCancel()) return; @@ -36,5 +35,5 @@ public class FlyB extends Check { player.getMovement().getDeltaY(), player.getMovement().getLDeltaY()); } } else if(buffer > 0) buffer-= 0.05f; - } + }; } 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 index 712dc22..db9bd23 100644 --- a/src/main/java/dev/brighten/ac/check/impl/nofall/NoFallA.java +++ b/src/main/java/dev/brighten/ac/check/impl/nofall/NoFallA.java @@ -17,8 +17,7 @@ public class NoFallA extends Check { private static double divisor = 1. / 64.; private float buffer; - @Action - public void onFlying(WPacketPlayInFlying packet) { + Action flying = packet -> { if(player.getInfo().isGeneralCancel() || (player.getMovement().getDeltaXZ() == 0 && player.getMovement().getDeltaY() == 0) || player.getBlockInfo().inLiquid @@ -33,10 +32,10 @@ public class NoFallA extends Check { 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 + && 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()); @@ -55,5 +54,5 @@ public class NoFallA extends Check { 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 index 3f82b44..3d194d6 100644 --- a/src/main/java/dev/brighten/ac/check/impl/nofall/NoFallB.java +++ b/src/main/java/dev/brighten/ac/check/impl/nofall/NoFallB.java @@ -18,8 +18,7 @@ public class NoFallB extends Check { private int airBuffer, groundBuffer; - @Action - public void onFlying(WPacketPlayInFlying packet, long timestamp) { + Action flying = packet -> { if(player.getMovement().getLastTeleport().isNotPassed(3) || player.getMovement().getMoveTicks() < 2 || player.getInfo().canFly @@ -62,5 +61,5 @@ public class NoFallB extends Check { 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 b4e2a53..a7084ac 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 @@ -33,9 +33,7 @@ public class Horizontal extends Check { super(player); } - @Action - public void onFlying(WPacketPlayInFlying packet) { - + Action flying = packet -> { Block underBlock = BlockUtils.getBlock(player.getMovement().getTo().getLoc() .toLocation(player.getBukkitPlayer().getWorld()) .subtract(0, 1, 0)), @@ -264,7 +262,7 @@ public class Horizontal extends Check { player.getBlockInfo().onSoulSand); } lastLastClientGround = player.getMovement().getFrom().isOnGround(); - } + }; private static final float[] SIN_TABLE_FAST = new float[4096], SIN_TABLE_FAST_NEW = new float[4096]; private static final float[] SIN_TABLE = new float[65536]; 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 64da15e..d8b7910 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 @@ -18,14 +18,12 @@ public class VelocityA extends Check { super(player); player.onVelocity(velocity -> { - currentVelocity = velocity.clone(); debug("did velocity: " + currentVelocity.getY()); }); } - @Action - public void onFlying(WPacketPlayInFlying packet) { + Action flying = packet -> { if(currentVelocity != null && currentVelocity.getY() > 0 && !player.getBlockInfo().inWeb && !player.getBlockInfo().onClimbable @@ -57,5 +55,5 @@ public class VelocityA extends Check { } else if(currentVelocity != null) { debug("not null: " + currentVelocity.getY()); } - } + }; } 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 a5897ea..3c99a26 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 @@ -38,16 +38,14 @@ public class VelocityB extends Check { private int ticks; private static final double[] moveValues = new double[] {-0.98, 0, 0.98}; - @Action - public void onUseEntity(WPacketPlayInUseEntity packet) { + Action usePacket = packet -> { if(!useEntity && packet.getAction().equals(WPacketPlayInUseEntity.EnumEntityUseAction.ATTACK)) { useEntity = true; } - } + }; - @Action - public void onFlying(WPacketPlayInFlying packet) { + Action flying = packet -> { check: { if((pvX != 0 || pvZ != 0) && (player.getMovement().getDeltaX() != 0 || player.getMovement().getDeltaY() != 0 @@ -178,7 +176,7 @@ public class VelocityB extends Check { useEntity = false; fromFriction = player.getInfo().getBlockBelow() .map(b -> CraftMagicNumbers.getBlock(b.getType()).frictionFactor).orElse(0.6f); - } + }; private void moveFlying(double strafe, double forward, double friction) { double f = strafe * strafe + forward * forward; 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 index 050438b..8eeda06 100644 --- a/src/main/java/dev/brighten/ac/check/impl/world/BlockA.java +++ b/src/main/java/dev/brighten/ac/check/impl/world/BlockA.java @@ -33,9 +33,8 @@ public class BlockA extends Check { private final MaxDouble verbose = new MaxDouble(20); private Queue> blockPlacements = new LinkedBlockingQueue<>(); - @Action - public void onBlockPlace(WPacketPlayInBlockPlace event) { - Location loc = event.getBlockPos().toBukkitVector().toLocation(player.getBukkitPlayer().getWorld()); + Action blockPlace = packet -> { + Location loc = packet.getBlockPos().toBukkitVector().toLocation(player.getBukkitPlayer().getWorld()); Optional optionalBlock = BlockUtils.getBlockAsync(loc); if(!optionalBlock.isPresent()) return; @@ -43,7 +42,7 @@ public class BlockA extends Check { final Block block = optionalBlock.get(); CollisionBox box = BlockData.getData(block.getType()).getBox(block, player.getPlayerVersion()); - debug(event.getBlockPos().toString()); + debug(packet.getBlockPos().toString()); if(!(box instanceof SimpleCollisionBox)) { debug("Not SimpleCollisionBox: " + box.getClass().getSimpleName() + ";" + block.getType()); return; @@ -62,10 +61,9 @@ public class BlockA extends Check { } blockPlacements.add(new Tuple<>(block, simpleBox.expand(0.1))); - } + }; - @Action - public void onFlying(WPacketPlayInFlying packet) { + Action flying = packet -> { Tuple tuple; while((tuple = blockPlacements.poll()) != null) { @@ -75,9 +73,9 @@ public class BlockA extends Check { final KLocation to = player.getMovement().getTo().getLoc().clone(), from = player.getMovement().getFrom().getLoc().clone(); - to.y+= player.getInfo().sneaking ? (ProtocolVersion.getGameVersion().isOrAbove(ProtocolVersion.V1_14) + to.y += player.getInfo().sneaking ? (ProtocolVersion.getGameVersion().isOrAbove(ProtocolVersion.V1_14) ? 1.27f : 1.54f) : 1.62f; - from.y+= player.getInfo().lsneaking ? (ProtocolVersion.getGameVersion().isOrAbove(ProtocolVersion.V1_14) + from.y += player.getInfo().lsneaking ? (ProtocolVersion.getGameVersion().isOrAbove(ProtocolVersion.V1_14) ? 1.27f : 1.54f) : 1.62f; final RayCollision rayTo = new RayCollision(to.toVector(), @@ -87,8 +85,8 @@ public class BlockA extends Check { final boolean collided = rayTo.isCollided(box) || rayFrom.isCollided(box); - if(!collided) { - if(verbose.add() > 4) { + if (!collided) { + if (verbose.add() > 4) { flag("to=[x=%.1f y=%.1f z=%.1f yaw=%.1f pitch=%.1f] loc=[%.1f,%.1f,%.1f]", to.x, to.y, to.z, to.yaw, from.pitch, block.getLocation().getX(), block.getLocation().getY(), block.getLocation().getZ()); @@ -97,5 +95,5 @@ public class BlockA extends Check { debug("collided=%s verbose=%s", collided, verbose.value()); } - } + }; } 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 index 9e103cb..dc1c97e 100644 --- a/src/main/java/dev/brighten/ac/check/impl/world/BlockB.java +++ b/src/main/java/dev/brighten/ac/check/impl/world/BlockB.java @@ -14,8 +14,7 @@ public class BlockB extends Check { super(player); } - @Action - public void onBlock(BlockPlaceEvent event) { + Action blockPlaceEvent = event -> { Block ba = event.getBlockAgainst(); if (!event.getBlockPlaced().getType().isBlock()) return; @@ -27,5 +26,5 @@ public class BlockB extends Check { if (distance >= 1.3 && 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 index 31988c3..8de63e3 100644 --- a/src/main/java/dev/brighten/ac/check/impl/world/BlockC.java +++ b/src/main/java/dev/brighten/ac/check/impl/world/BlockC.java @@ -20,8 +20,7 @@ public class BlockC extends Check { super(player); } - @Action - public void onFlying(WPacketPlayInFlying packet) { + Action flying = packet -> { if(player.getInfo().isCreative() || player.getMovement().isExcuseNextFlying()) return; long timestamp = System.currentTimeMillis(); if(place) { @@ -33,10 +32,9 @@ public class BlockC extends Check { } else if(buffer > 0) buffer-= 0.25f; place = false; } - } + }; - @Action - public void onBlockPlace(WPacketPlayInBlockPlace packet) { + Action blockPlace = packet -> { if(player.pastLocations.isEmpty()) return; KLocation lastMovePacket = player.pastLocations.getLast().one; @@ -50,5 +48,5 @@ public class BlockC extends Check { lastPlace = timestamp; place = true; } else if(buffer > 0) buffer-= 0.25f; - } + }; } diff --git a/src/main/java/dev/brighten/ac/data/APlayer.java b/src/main/java/dev/brighten/ac/data/APlayer.java index 76a6891..ea6e6a8 100644 --- a/src/main/java/dev/brighten/ac/data/APlayer.java +++ b/src/main/java/dev/brighten/ac/data/APlayer.java @@ -1,8 +1,10 @@ package dev.brighten.ac.data; import dev.brighten.ac.Anticheat; +import dev.brighten.ac.check.Action; import dev.brighten.ac.check.Check; import dev.brighten.ac.check.CheckStatic; +import dev.brighten.ac.check.TimedAction; import dev.brighten.ac.data.handlers.BlockInformation; import dev.brighten.ac.data.handlers.GeneralInformation; import dev.brighten.ac.data.handlers.LagInformation; @@ -21,7 +23,7 @@ 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.reflections.types.WrappedField; import dev.brighten.ac.utils.timer.Timer; import dev.brighten.ac.utils.timer.impl.MillisTimer; import lombok.Getter; @@ -83,6 +85,9 @@ public class APlayer { private final List> onVelocityTasks = new ArrayList<>(); public final EvictingList> pastLocations = new EvictingList<>(20); + private final Map, Action[]> events = new HashMap<>(); + private final Map, TimedAction[]> eventsWithTimestamp = new HashMap<>(); + @Setter @Getter private boolean sendingPackets; @@ -131,6 +136,38 @@ public class APlayer { Check.alertsEnabled.add(getUuid()); getBukkitPlayer().spigot().sendMessage(Messages.ALERTS_ON); } + + // Enabling checks for players on join + for (CheckStatic checkClass : Anticheat.INSTANCE.getCheckManager().getCheckClasses()) { + Check check = checkClass.playerInit(this); + + for (Tuple> tuple : checkClass.getActions()) { + Action action = tuple.one.get(check); + + events.compute(tuple.two, (packetClass, array) -> { + if (array == null) { + return new Action[]{action}; + } else { + Action[] newArray = Arrays.copyOf(array, array.length + 1); + newArray[array.length] = action; + return newArray; + } + }); + } + for (Tuple> tuple : checkClass.getTimedActions()) { + TimedAction action = tuple.one.get(check); + + eventsWithTimestamp.compute(tuple.two, (packetClass, array) -> { + if (array == null) { + return new TimedAction[]{action}; + } else { + TimedAction[] newArray = Arrays.copyOf(array, array.length + 1); + newArray[array.length] = action; + return newArray; + } + }); + } + } } protected void unload() { @@ -141,40 +178,26 @@ public class APlayer { } public void callEvent(Event event) { - for (Check check : checks) { - WrappedMethod[] methods = Anticheat.INSTANCE.getCheckManager().getEvents() - .get(new Tuple>(check.getCheckData().name(), event.getClass())); - - if(methods != null) { - for (WrappedMethod method : methods) { - method.invoke(check, event); - } + if(events.containsKey(event.getClass())) { + Action[] actions = (Action[]) events.get(event.getClass()); + for (Action action : actions) { + action.invoke(event); } } } //TODO When using WPacket wrappers only, make this strictly WPacket param based only 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())); - - if(methods != null) { - - for (WrappedMethod method : - methods) { - method.invoke(check, packet); - } + if(events.containsKey(packet.getClass())) { + Action[] actions = (Action[]) events.get(packet.getClass()); + for (Action action : actions) { + action.invoke(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); - } + } + if(eventsWithTimestamp.containsKey(packet.getClass())) { + TimedAction[] actions = (TimedAction[]) eventsWithTimestamp.get(packet.getClass()); + for (TimedAction action : actions) { + action.invoke(packet, timestamp); } } } diff --git a/src/main/java/dev/brighten/ac/handler/keepalive/KeepaliveProcessor.java b/src/main/java/dev/brighten/ac/handler/keepalive/KeepaliveProcessor.java index 1cae990..370e42f 100644 --- a/src/main/java/dev/brighten/ac/handler/keepalive/KeepaliveProcessor.java +++ b/src/main/java/dev/brighten/ac/handler/keepalive/KeepaliveProcessor.java @@ -19,7 +19,7 @@ public class KeepaliveProcessor implements Runnable { private BukkitTask task; - public KeepAlive currentKeepalive = new KeepAlive(0, (short)0); + public KeepAlive currentKeepalive = new KeepAlive(0, (short) 0); public int tick; public int totalPlayers, laggyPlayers; @@ -49,9 +49,17 @@ public class KeepaliveProcessor implements Runnable { for (APlayer value : Anticheat.INSTANCE.getPlayerRegistry().aplayerMap.values()) { totalPlayers++; - if(value.getLagInfo().getLastPingDrop().isNotPassed(2) + if (value.getLagInfo().getLastPingDrop().isNotPassed(2) || value.getLagInfo().getLastClientTransaction().isPassed(135L)) laggyPlayers++; + if (tick % 5 == 0) { + double dh = Math.min(value.getMovement().getDeltaXZ(), 1), + dy = Math.min(1, Math.abs(value.getMovement().getDeltaY())); + + value.getInfo().nearbyEntities = value.getBukkitPlayer() + .getNearbyEntities(2 + dh, 3 + dy, 2 + dh); + } + PacketPlayOutTransaction transaction = new PacketPlayOutTransaction(0, currentKeepalive.id, false); HandlerAbstract.getHandler().sendPacket(value.getBukkitPlayer(), transaction); @@ -67,27 +75,27 @@ public class KeepaliveProcessor implements Runnable { } public Optional getResponse(APlayer data) { - if(!lastResponses.containsKey(data.getBukkitPlayer().getUniqueId().hashCode())) + if (!lastResponses.containsKey(data.getBukkitPlayer().getUniqueId().hashCode())) return Optional.empty(); return getKeepById(lastResponses.get(data.getBukkitPlayer().getUniqueId().hashCode())); } public void start() { - if(task == null) { + if (task == null) { task = RunUtils.taskTimer(this, Anticheat.INSTANCE, 20L, 0L); } } public void addResponse(APlayer data, short id) { getKeepById(id).ifPresent(ka -> { - lastResponses.put(data.getBukkitPlayer().getUniqueId().hashCode(), (Short)id); + lastResponses.put(data.getBukkitPlayer().getUniqueId().hashCode(), (Short) id); ka.received(data); }); } public void stop() { - if(task != null) { + if (task != null) { task.cancel(); task = null; }