From f790ed8b768c44ffc79aad3cdf2ced2dd87cef50 Mon Sep 17 00:00:00 2001 From: Dawson Date: Thu, 19 Jun 2025 14:51:43 -0400 Subject: [PATCH] Issues with false positives in Hitboxes remain --- Anticheat/pom.xml | 2 +- .../main/java/dev/brighten/ac/Anticheat.java | 5 - .../java/dev/brighten/ac/check/Check.java | 2 + .../dev/brighten/ac/check/CheckManager.java | 11 +- .../dev/brighten/ac/check/CheckSettings.java | 10 + .../brighten/ac/check/impl/combat/Hitbox.java | 2 +- .../ac/check/impl/movement/Phase.java | 20 +- .../brighten/ac/check/impl/world/BlockA.java | 2 +- .../dev/brighten/ac/command/LogsCommand.java | 4 +- .../brighten/ac/data/info/CheckHandler.java | 54 +++-- .../dev/brighten/ac/data/obj/ActionStore.java | 1 + .../ac/data/obj/CancellableActionStore.java | 1 + .../ac/data/obj/TimedActionStore.java | 1 + .../brighten/ac/handler/BBRevealHandler.java | 36 +-- .../brighten/ac/handler/MovementHandler.java | 5 +- .../brighten/ac/handler/PacketHandler.java | 61 ++--- .../brighten/ac/handler/VelocityHandler.java | 18 +- .../handler/keepalive/KeepaliveProcessor.java | 23 +- .../java/dev/brighten/ac/utils/Materials.java | 4 +- .../dev/brighten/ac/utils/ServerInjector.java | 2 + .../brighten/ac/utils/world/BlockData.java | 222 +++++++++--------- .../ac/utils/world/blocks/DynamicStair.java | 2 +- .../ac/utils/world/blocks/DynamicWall.java | 2 +- .../ac/utils/world/types/RayCollision.java | 20 +- Anticheat/src/main/resources/plugin.yml | 2 +- .../java/dev/brighten/ac/utils/KLocation.java | 7 +- 26 files changed, 272 insertions(+), 247 deletions(-) diff --git a/Anticheat/pom.xml b/Anticheat/pom.xml index 6fbbab8..0507987 100644 --- a/Anticheat/pom.xml +++ b/Anticheat/pom.xml @@ -83,7 +83,7 @@ shade - false + true co.aikar diff --git a/Anticheat/src/main/java/dev/brighten/ac/Anticheat.java b/Anticheat/src/main/java/dev/brighten/ac/Anticheat.java index 0647c42..04f9737 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/Anticheat.java +++ b/Anticheat/src/main/java/dev/brighten/ac/Anticheat.java @@ -2,7 +2,6 @@ package dev.brighten.ac; import co.aikar.commands.*; import com.github.retrooper.packetevents.PacketEvents; -import com.github.retrooper.packetevents.PacketEventsAPI; import com.github.retrooper.packetevents.event.PacketListenerPriority; import com.google.common.util.concurrent.ThreadFactoryBuilder; import dev.brighten.ac.api.AnticheatAPI; @@ -13,8 +12,6 @@ import dev.brighten.ac.data.APlayer; import dev.brighten.ac.data.PlayerRegistry; import dev.brighten.ac.data.info.CheckHandler; import dev.brighten.ac.depends.LibraryLoader; -import dev.brighten.ac.depends.MavenLibrary; -import dev.brighten.ac.depends.Repository; import dev.brighten.ac.handler.BBRevealHandler; import dev.brighten.ac.handler.PacketHandler; import dev.brighten.ac.handler.entity.FakeEntityTracker; @@ -194,7 +191,6 @@ public class Anticheat extends JavaPlugin { this.playerRegistry = new PlayerRegistry(); this.keepaliveProcessor = new KeepaliveProcessor(); - keepaliveProcessor.start(); Bukkit.getOnlinePlayers().forEach(playerRegistry::generate); this.packetHandler = new PacketHandler(); @@ -243,7 +239,6 @@ public class Anticheat extends JavaPlugin { PacketEvents.getAPI().terminate(); - keepaliveProcessor.stop(); keepaliveProcessor.keepAlives.clear(); diff --git a/Anticheat/src/main/java/dev/brighten/ac/check/Check.java b/Anticheat/src/main/java/dev/brighten/ac/check/Check.java index 49dbbfe..a8fc81a 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/check/Check.java +++ b/Anticheat/src/main/java/dev/brighten/ac/check/Check.java @@ -97,6 +97,8 @@ public class Check implements ECheck { } public void correctMovement(KLocation toLoc) { + if(!isCancellable()) return; + CancelResult result = CancelResult.builder().cancelled(false).build(); for (AnticheatEvent event : AnticheatAPI.INSTANCE.getAllEvents()) { diff --git a/Anticheat/src/main/java/dev/brighten/ac/check/CheckManager.java b/Anticheat/src/main/java/dev/brighten/ac/check/CheckManager.java index 4c37ac3..2f21b22 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/check/CheckManager.java +++ b/Anticheat/src/main/java/dev/brighten/ac/check/CheckManager.java @@ -14,7 +14,7 @@ import java.util.Optional; public class CheckManager { private final Map checkClasses = new HashMap<>(); private final Map idToName = new HashMap<>(); - private final Map, CheckSettings> checkSettings = new HashMap<>(); + private final Map checkSettings = new HashMap<>(); public CheckManager() { synchronized (checkClasses) { for (WrappedClass aClass : new ClassScanner().getClasses(CheckData.class)) { @@ -38,10 +38,7 @@ public class CheckManager { generateConfigSettings(checkData); settings = Optional.of(CheckSettings.settingsFromData(checkData)); } - - checkSettings.put(checkClass.getParent(), settings.get()); - - Anticheat.INSTANCE.alog(true, "&7Adding check to CheckManager: " + checkData.name()); + checkSettings.put(checkData.checkId(), settings.get()); checkClasses.put(checkData.name(), check); idToName.put(checkData.checkId(), checkData.name()); @@ -62,8 +59,8 @@ public class CheckManager { return Optional.empty(); } - public CheckSettings getCheckSettings(Class checkClass) { - return checkSettings.get(checkClass); + public CheckSettings getCheckSettings(String checkId) { + return checkSettings.get(checkId); } private void generateConfigSettings(CheckData data) { diff --git a/Anticheat/src/main/java/dev/brighten/ac/check/CheckSettings.java b/Anticheat/src/main/java/dev/brighten/ac/check/CheckSettings.java index 55281b8..97be5a5 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/check/CheckSettings.java +++ b/Anticheat/src/main/java/dev/brighten/ac/check/CheckSettings.java @@ -18,4 +18,14 @@ public class CheckSettings { .punishVl(data.punishVl()) .build(); } + + @Override + public String toString() { + return "CheckSettings{" + + "enabled=" + enabled + + ", punishable=" + punishable + + ", cancellable=" + cancellable + + ", punishVl=" + punishVl + + '}'; + } } diff --git a/Anticheat/src/main/java/dev/brighten/ac/check/impl/combat/Hitbox.java b/Anticheat/src/main/java/dev/brighten/ac/check/impl/combat/Hitbox.java index dfc4d00..dc7ced8 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/check/impl/combat/Hitbox.java +++ b/Anticheat/src/main/java/dev/brighten/ac/check/impl/combat/Hitbox.java @@ -73,7 +73,7 @@ public class Hitbox extends Check { final Tuple eloc = optionalEloc.get(); - final KLocation to = target.two; + final KLocation to = target.two.clone(); if(eloc.one.x == 0 && eloc.one.y == 0 & eloc.one.z == 0) { return; diff --git a/Anticheat/src/main/java/dev/brighten/ac/check/impl/movement/Phase.java b/Anticheat/src/main/java/dev/brighten/ac/check/impl/movement/Phase.java index 67e5a1c..5de995c 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/check/impl/movement/Phase.java +++ b/Anticheat/src/main/java/dev/brighten/ac/check/impl/movement/Phase.java @@ -87,7 +87,9 @@ public class Phase extends Check { POSITIONS.clear(); } else if(teleportLoc != null) { final Location finalLoc = teleportLoc.clone(); // This is to make sure it isn't set null later. - Anticheat.INSTANCE.getRunUtils().task(() -> player.getBukkitPlayer().teleport(finalLoc)); + if(isCancellable()) { + Anticheat.INSTANCE.getRunUtils().task(() -> player.getBukkitPlayer().teleport(finalLoc)); + } return true; } @@ -97,7 +99,9 @@ public class Phase extends Check { final Location fromLoc = player.getMovement().getFrom().getLoc() .toLocation(player.getBukkitPlayer().getWorld()); - Anticheat.INSTANCE.getRunUtils().task(() -> player.getBukkitPlayer().teleport(fromLoc)); + if(isCancellable()) { + Anticheat.INSTANCE.getRunUtils().task(() -> player.getBukkitPlayer().teleport(fromLoc)); + } return true; } @@ -136,11 +140,13 @@ public class Phase extends Check { double totalDelta = dx + dy + dz; if(totalDelta > 0.0001) { - Anticheat.INSTANCE.getRunUtils().task(() -> { - teleportLoc = calculatedTo - .toLocation(player.getBukkitPlayer().getWorld()); - player.getBukkitPlayer().teleport(teleportLoc); - }); + if(isCancellable()) { + Anticheat.INSTANCE.getRunUtils().task(() -> { + teleportLoc = calculatedTo + .toLocation(player.getBukkitPlayer().getWorld()); + player.getBukkitPlayer().teleport(teleportLoc); + }); + } flag("x=%.4f, y=%.4f, z=%.4f", dx, dy, dz); } diff --git a/Anticheat/src/main/java/dev/brighten/ac/check/impl/world/BlockA.java b/Anticheat/src/main/java/dev/brighten/ac/check/impl/world/BlockA.java index 9d0b094..3c96f59 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/check/impl/world/BlockA.java +++ b/Anticheat/src/main/java/dev/brighten/ac/check/impl/world/BlockA.java @@ -37,7 +37,7 @@ public class BlockA extends Check { WrappedBlock block = player.getBlockUpdateHandler().getBlock(loc); - CollisionBox box = BlockData.getData(block.getType()).getBox(block, player.getPlayerVersion()); + CollisionBox box = BlockData.getData(block.getType()).getBox(player, block, player.getPlayerVersion()); debug(packet.getBlockPosition().toString()); if(!(box instanceof final SimpleCollisionBox simpleBox)) { diff --git a/Anticheat/src/main/java/dev/brighten/ac/command/LogsCommand.java b/Anticheat/src/main/java/dev/brighten/ac/command/LogsCommand.java index 2ffca70..5296917 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/command/LogsCommand.java +++ b/Anticheat/src/main/java/dev/brighten/ac/command/LogsCommand.java @@ -168,9 +168,7 @@ public class LogsCommand extends BaseCommand { for (String key : violations.keySet()) { if (Anticheat.INSTANCE.getCheckManager().isCheck(key)) { CheckSettings checkData = Anticheat.INSTANCE.getCheckManager() - .getCheckSettings(Anticheat.INSTANCE.getCheckManager().getCheckClasses() - .get(Anticheat.INSTANCE.getCheckManager().getIdToName().get(key)) - .getCheckClass().getParent()); + .getCheckSettings(key); int vl = violations.get(key), maxVL = checkData.getPunishVl(); boolean developer = false; diff --git a/Anticheat/src/main/java/dev/brighten/ac/data/info/CheckHandler.java b/Anticheat/src/main/java/dev/brighten/ac/data/info/CheckHandler.java index c334939..cf49561 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/data/info/CheckHandler.java +++ b/Anticheat/src/main/java/dev/brighten/ac/data/info/CheckHandler.java @@ -67,16 +67,22 @@ public class CheckHandler { for (CheckStatic toHook : TO_HOOK) { KListener listener = toHook.playerInit(player); + + CheckData data = toHook.getCheckClass().getAnnotation(CheckData.class); + + String checkId = data != null ? data.checkId() : UUID.randomUUID().toString(); synchronized (EVENTS) { for (Tuple> tuple : toHook.getActions()) { WAction action = tuple.one.get(listener); EVENTS.compute(tuple.two, (packetClass, array) -> { if (array == null) { - return new ActionStore[] {new ActionStore(action, toHook.getCheckClass().getParent())}; + return new ActionStore[] {new ActionStore(action, + toHook.getCheckClass().getParent(), checkId)}; } else { ActionStore[] newArray = Arrays.copyOf(array, array.length + 1); - newArray[array.length] = new ActionStore(action, toHook.getCheckClass().getParent()); + newArray[array.length] = new ActionStore(action, + toHook.getCheckClass().getParent(), checkId); return newArray; } }); @@ -88,10 +94,12 @@ public class CheckHandler { EVENTS_TIMESTAMP.compute(tuple.two, (packetClass, array) -> { if (array == null) { - return new TimedActionStore[] {new TimedActionStore(action, toHook.getCheckClass().getParent())}; + return new TimedActionStore[] {new TimedActionStore(action, + toHook.getCheckClass().getParent(), checkId)}; } else { TimedActionStore[] newArray = Arrays.copyOf(array, array.length + 1); - newArray[array.length] = new TimedActionStore(action, toHook.getCheckClass().getParent()); + newArray[array.length] = new TimedActionStore(action, + toHook.getCheckClass().getParent(), checkId); return newArray; } }); @@ -105,10 +113,12 @@ public class CheckHandler { EVENTS_CANCELLABLE.compute(tuple.two, (packetClass, array) -> { if (array == null) { - return new CancellableActionStore[] {new CancellableActionStore(action, toHook.getCheckClass().getParent())}; + return new CancellableActionStore[] {new CancellableActionStore(action, + toHook.getCheckClass().getParent(), checkId)}; } else { CancellableActionStore[] newArray = Arrays.copyOf(array, array.length + 1); - newArray[array.length] = new CancellableActionStore(action, toHook.getCheckClass().getParent()); + newArray[array.length] = new CancellableActionStore(action, + toHook.getCheckClass().getParent(), checkId); return newArray; } }); @@ -118,7 +128,7 @@ public class CheckHandler { for (CheckStatic checkClass : Anticheat.INSTANCE.getCheckManager().getCheckClasses().values()) { CheckData data = checkClass.getCheckClass().getAnnotation(CheckData.class); - + String checkId = data != null ? data.checkId() : UUID.randomUUID().toString(); //Version checks if(player.getPlayerVersion().isNewerThan(data.maxVersion()) || player.getPlayerVersion().isOlderThan(data.minVersion())) { Anticheat.INSTANCE.alog("Player " + player.getBukkitPlayer().getName() + @@ -130,7 +140,7 @@ public class CheckHandler { Check check = checkClass.playerInit(player); CheckSettings settings = Anticheat.INSTANCE.getCheckManager() - .getCheckSettings(checkClass.getCheckClass().getParent()); + .getCheckSettings(checkId); if(settings == null) { throw new RuntimeException("Settings for check" + check.getName() + " do not exist!"); @@ -149,10 +159,10 @@ public class CheckHandler { EVENTS.compute(tuple.two, (packetClass, array) -> { if (array == null) { - return new ActionStore[] {new ActionStore(action, checkClass.getCheckClass().getParent())}; + return new ActionStore[] {new ActionStore(action, checkClass.getCheckClass().getParent(), checkId)}; } else { ActionStore[] newArray = Arrays.copyOf(array, array.length + 1); - newArray[array.length] = new ActionStore(action, checkClass.getCheckClass().getParent()); + newArray[array.length] = new ActionStore(action, checkClass.getCheckClass().getParent(), checkId); return newArray; } }); @@ -164,10 +174,10 @@ public class CheckHandler { EVENTS_TIMESTAMP.compute(tuple.two, (packetClass, array) -> { if (array == null) { - return new TimedActionStore[] {new TimedActionStore(action, checkClass.getCheckClass().getParent())}; + return new TimedActionStore[] {new TimedActionStore(action, checkClass.getCheckClass().getParent(), checkId)}; } else { TimedActionStore[] newArray = Arrays.copyOf(array, array.length + 1); - newArray[array.length] = new TimedActionStore(action, checkClass.getCheckClass().getParent()); + newArray[array.length] = new TimedActionStore(action, checkClass.getCheckClass().getParent(), checkId); return newArray; } }); @@ -181,10 +191,10 @@ public class CheckHandler { EVENTS_CANCELLABLE.compute(tuple.two, (packetClass, array) -> { if (array == null) { - return new CancellableActionStore[] {new CancellableActionStore(action, checkClass.getCheckClass().getParent())}; + return new CancellableActionStore[] {new CancellableActionStore(action, checkClass.getCheckClass().getParent(), checkId)}; } else { CancellableActionStore[] newArray = Arrays.copyOf(array, array.length + 1); - newArray[array.length] = new CancellableActionStore(action, checkClass.getCheckClass().getParent()); + newArray[array.length] = new CancellableActionStore(action, checkClass.getCheckClass().getParent(), checkId); return newArray; } }); @@ -215,9 +225,9 @@ public class CheckHandler { if(EVENTS.containsKey(event.getClass())) { ActionStore[] actions = (ActionStore[]) EVENTS.get(event.getClass()); for (ActionStore action : actions) { - var checkSettings = Anticheat.INSTANCE.getCheckManager().getCheckSettings(action.getCheckClass()); + var checkSettings = Anticheat.INSTANCE.getCheckManager().getCheckSettings(action.getCheckId()); if(checkSettings != null && !Anticheat.INSTANCE.getCheckManager() - .getCheckSettings(action.getCheckClass()).isEnabled()) + .getCheckSettings(action.getCheckId()).isEnabled()) continue; action.getAction().invoke(event); @@ -233,9 +243,9 @@ public class CheckHandler { synchronized (EVENTS) { ActionStore[] actions = (ActionStore[]) EVENTS.get(packet.getClass()); for (ActionStore action : actions) { - var checkSettings = Anticheat.INSTANCE.getCheckManager().getCheckSettings(action.getCheckClass()); + var checkSettings = Anticheat.INSTANCE.getCheckManager().getCheckSettings(action.getCheckId()); if(checkSettings != null && !Anticheat.INSTANCE.getCheckManager() - .getCheckSettings(action.getCheckClass()).isEnabled()) + .getCheckSettings(action.getCheckId()).isEnabled()) continue; action.getAction().invoke(packet); } @@ -246,9 +256,9 @@ public class CheckHandler { TimedActionStore[] actions = (TimedActionStore[]) EVENTS_TIMESTAMP.get(packet.getClass()); for (TimedActionStore action : actions) { - var checkSettings = Anticheat.INSTANCE.getCheckManager().getCheckSettings(action.getCheckClass()); + var checkSettings = Anticheat.INSTANCE.getCheckManager().getCheckSettings(action.getCheckId()); if(checkSettings != null && !Anticheat.INSTANCE.getCheckManager() - .getCheckSettings(action.getCheckClass()).isEnabled()) + .getCheckSettings(action.getCheckId()).isEnabled()) continue; action.getAction().invoke(packet, timestamp); } @@ -260,9 +270,9 @@ public class CheckHandler { CancellableActionStore[] actions = (CancellableActionStore[]) EVENTS_CANCELLABLE.get(packet.getClass()); for (CancellableActionStore action : actions) { - var checkSettings = Anticheat.INSTANCE.getCheckManager().getCheckSettings(action.getCheckClass()); + var checkSettings = Anticheat.INSTANCE.getCheckManager().getCheckSettings(action.getCheckId()); if(checkSettings != null && !Anticheat.INSTANCE.getCheckManager() - .getCheckSettings(action.getCheckClass()).isEnabled()) + .getCheckSettings(action.getCheckId()).isEnabled()) continue; if(action.getAction().invoke(packet)) { diff --git a/Anticheat/src/main/java/dev/brighten/ac/data/obj/ActionStore.java b/Anticheat/src/main/java/dev/brighten/ac/data/obj/ActionStore.java index 68f8aa6..3a1d4ec 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/data/obj/ActionStore.java +++ b/Anticheat/src/main/java/dev/brighten/ac/data/obj/ActionStore.java @@ -13,6 +13,7 @@ import java.util.UUID; public class ActionStore { private final WAction action; private final Class checkClass; + private final String checkId; //To ensure duplicate actions are not added to the list private final UUID uuid = UUID.randomUUID(); diff --git a/Anticheat/src/main/java/dev/brighten/ac/data/obj/CancellableActionStore.java b/Anticheat/src/main/java/dev/brighten/ac/data/obj/CancellableActionStore.java index 0df8e42..15e463a 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/data/obj/CancellableActionStore.java +++ b/Anticheat/src/main/java/dev/brighten/ac/data/obj/CancellableActionStore.java @@ -13,6 +13,7 @@ import java.util.UUID; public class CancellableActionStore { private final WCancellable action; private final Class checkClass; + private final String checkId; private final UUID uuid = UUID.randomUUID(); @Override diff --git a/Anticheat/src/main/java/dev/brighten/ac/data/obj/TimedActionStore.java b/Anticheat/src/main/java/dev/brighten/ac/data/obj/TimedActionStore.java index 666b9c7..b25c1c8 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/data/obj/TimedActionStore.java +++ b/Anticheat/src/main/java/dev/brighten/ac/data/obj/TimedActionStore.java @@ -13,6 +13,7 @@ import java.util.UUID; public class TimedActionStore { private final WTimedAction action; private final Class checkClass; + private final String checkId; //To ensure duplicate actions are not added to the list private final UUID uuid = UUID.randomUUID(); diff --git a/Anticheat/src/main/java/dev/brighten/ac/handler/BBRevealHandler.java b/Anticheat/src/main/java/dev/brighten/ac/handler/BBRevealHandler.java index 7950baa..c02974b 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/handler/BBRevealHandler.java +++ b/Anticheat/src/main/java/dev/brighten/ac/handler/BBRevealHandler.java @@ -4,12 +4,10 @@ import com.github.retrooper.packetevents.protocol.particle.type.ParticleTypes; import dev.brighten.ac.Anticheat; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.utils.ItemBuilder; -import dev.brighten.ac.utils.Materials; import dev.brighten.ac.utils.annotation.Init; import dev.brighten.ac.utils.math.IntVector; import dev.brighten.ac.utils.world.BlockData; import dev.brighten.ac.utils.world.EntityData; -import io.github.retrooper.packetevents.util.SpigotConversionUtil; import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.chat.ComponentBuilder; import org.bukkit.Material; @@ -50,28 +48,20 @@ public class BBRevealHandler implements Listener { if(player == null || !player.getWrappedPlayer().getItemInHand().isSimilar(wand)) return; if(event.getAction() == Action.RIGHT_CLICK_BLOCK) { - if(Materials.checkFlag(SpigotConversionUtil.fromBukkitItemMaterial(event.getClickedBlock().getType()).getPlacedType() - , Materials.COLLIDABLE)) { - IntVector blockLoc = new IntVector(event.getClickedBlock().getX(), - event.getClickedBlock().getY(), event.getClickedBlock().getZ()); - Set blocksToShow = this.blocksToShow - .computeIfAbsent(event.getPlayer().getUniqueId(), k -> new HashSet<>()); - if(blocksToShow.contains(blockLoc)) { - blocksToShow.remove(blockLoc); - event.getPlayer().spigot().sendMessage(new ComponentBuilder("No longer showing block: ") - .color(ChatColor.RED).append(event.getClickedBlock().getType().name()).color(ChatColor.WHITE) - .create()); - } else { - blocksToShow.add(blockLoc); - event.getPlayer().spigot().sendMessage(new ComponentBuilder("Now showing block: ") - .color(ChatColor.GREEN).append(event.getClickedBlock().getType().name()).color(ChatColor.WHITE) - .append(" (collidable=" + Materials.checkFlag(SpigotConversionUtil.fromBukkitItemMaterial(event.getClickedBlock().getType()).getPlacedType(), Materials.COLLIDABLE) + ")") - .color(ChatColor.GRAY) - .create()); - } + IntVector blockLoc = new IntVector(event.getClickedBlock().getX(), + event.getClickedBlock().getY(), event.getClickedBlock().getZ()); + Set blocksToShow = this.blocksToShow + .computeIfAbsent(event.getPlayer().getUniqueId(), k -> new HashSet<>()); + if(blocksToShow.contains(blockLoc)) { + blocksToShow.remove(blockLoc); + event.getPlayer().spigot().sendMessage(new ComponentBuilder("No longer showing block: ") + .color(ChatColor.RED).append(event.getClickedBlock().getType().name()).color(ChatColor.WHITE) + .create()); } else { - event.getPlayer().spigot().sendMessage(new ComponentBuilder("Block is not collidable!") - .color(ChatColor.RED) + blocksToShow.add(blockLoc); + event.getPlayer().spigot().sendMessage(new ComponentBuilder("Now showing block: ") + .color(ChatColor.GREEN).append(event.getClickedBlock().getType().name()).color(ChatColor.WHITE) + .color(ChatColor.GRAY) .create()); } event.setCancelled(true); diff --git a/Anticheat/src/main/java/dev/brighten/ac/handler/MovementHandler.java b/Anticheat/src/main/java/dev/brighten/ac/handler/MovementHandler.java index 5c899a7..69b879f 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/handler/MovementHandler.java +++ b/Anticheat/src/main/java/dev/brighten/ac/handler/MovementHandler.java @@ -227,6 +227,8 @@ public class MovementHandler { result.getTags().add("vanilla"); } else if(fastMath == FastMathType.FAST_NEW) { result.getTags().add("fast_new"); + } else if(fastMath == FastMathType.MODERN_VANILLA) { + result.getTags().add("modern_vanilla"); } if(forward > 0) { @@ -360,7 +362,7 @@ public class MovementHandler { player.getInfo().setBlockOnTo(Optional.of(player.getBlockUpdateHandler() .getBlock(new IntVector(to.getLoc())))); player.getInfo().setBlockBelow(Optional.of(player.getBlockUpdateHandler() - .getBlock(new IntVector(to.getLoc().subtract(0, 1, 0))))); + .getBlock(new IntVector(to.getLoc().clone().subtract(0, 1, 0))))); if (packet.hasPositionChanged()) { // Updating player bounding box @@ -834,6 +836,7 @@ it if (to.getBox().max().lengthSquared() == 0) { //Needs initializing setTo(packet); from.setLoc(to); + player.getBukkitPlayer().sendMessage("Initializing location"); } else { from.setLoc(to); setTo(packet); diff --git a/Anticheat/src/main/java/dev/brighten/ac/handler/PacketHandler.java b/Anticheat/src/main/java/dev/brighten/ac/handler/PacketHandler.java index 750e8eb..5b7dd17 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/handler/PacketHandler.java +++ b/Anticheat/src/main/java/dev/brighten/ac/handler/PacketHandler.java @@ -333,32 +333,10 @@ public class PacketHandler { player.getInfo().getVelocityHistory().add(velocity); player.getInfo().setDoingVelocity(true); - player.runKeepaliveAction(ka -> player.getVelocityHandler().onPre(packet)); - player.runKeepaliveAction(ka -> { - if (player.getInfo().getVelocityHistory().contains(velocity)) - player.getOnVelocityTasks().forEach(task -> task.accept(velocity)); - - player.getVelocityHandler().onPost(packet); - if (player.getInfo().getVelocityHistory().contains(velocity)) { - player.getInfo().setDoingVelocity(false); - player.getInfo().getVelocity().reset(); - synchronized (player.getInfo().getVelocityHistory()) { - player.getInfo().getVelocityHistory().remove(velocity); - } - } - }, 1); - } else if(event.getPacketType() == PacketType.Play.Server.ENTITY_VELOCITY) { - WrapperPlayServerEntityVelocity packet = new WrapperPlayServerEntityVelocity(event); - - wrapped = packet; - - if(packet.getEntityId() == player.getBukkitPlayer().getEntityId()) { - Vector3d velocity = packet.getVelocity(); - player.getInfo().getVelocityHistory().add(velocity); - player.getInfo().setDoingVelocity(true); - - player.runKeepaliveAction(ka -> player.getVelocityHandler().onPre(packet)); - player.runKeepaliveAction(ka -> { + player.runInstantAction(ia -> { + if(!ia.isEnd()) { + player.getVelocityHandler().onPre(packet); + } else { if (player.getInfo().getVelocityHistory().contains(velocity)) player.getOnVelocityTasks().forEach(task -> task.accept(velocity)); @@ -370,7 +348,36 @@ public class PacketHandler { player.getInfo().getVelocityHistory().remove(velocity); } } - }, 1); + } + }, true); + player.runKeepaliveAction(ka -> player.getVelocityHandler().onComplete(packet), 2); + } else if(event.getPacketType() == PacketType.Play.Server.ENTITY_VELOCITY) { + WrapperPlayServerEntityVelocity packet = new WrapperPlayServerEntityVelocity(event); + + wrapped = packet; + + if(packet.getEntityId() == player.getBukkitPlayer().getEntityId()) { + Vector3d velocity = packet.getVelocity(); + player.getInfo().getVelocityHistory().add(velocity); + player.getInfo().setDoingVelocity(true); + player.runInstantAction(ia -> { + if (!ia.isEnd()) { + player.getVelocityHandler().onPre(packet); + } else { + if (player.getInfo().getVelocityHistory().contains(velocity)) + player.getOnVelocityTasks().forEach(task -> task.accept(velocity)); + + player.getVelocityHandler().onPost(packet); + if (player.getInfo().getVelocityHistory().contains(velocity)) { + player.getInfo().setDoingVelocity(false); + player.getInfo().getVelocity().reset(); + synchronized (player.getInfo().getVelocityHistory()) { + player.getInfo().getVelocityHistory().remove(velocity); + } + } + } + }, true); + player.runKeepaliveAction(ka -> player.getVelocityHandler().onComplete(packet), 2); } } else if(event.getPacketType() == PacketType.Play.Server.RESPAWN) { wrapped = new WrapperPlayServerRespawn(event); diff --git a/Anticheat/src/main/java/dev/brighten/ac/handler/VelocityHandler.java b/Anticheat/src/main/java/dev/brighten/ac/handler/VelocityHandler.java index 5849bf1..aeb25fd 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/handler/VelocityHandler.java +++ b/Anticheat/src/main/java/dev/brighten/ac/handler/VelocityHandler.java @@ -9,7 +9,10 @@ import dev.brighten.ac.utils.Tuple; import lombok.RequiredArgsConstructor; import lombok.val; -import java.util.*; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; import java.util.function.Consumer; @RequiredArgsConstructor @@ -31,6 +34,7 @@ public class VelocityHandler { if(packet.getEntityId() != PLAYER.getBukkitPlayer().getEntityId()) return; VELOCITY_MAP.add(new Tuple<>(packet.getVelocity(), false)); + PLAYER.getInfo().getVelocity().reset(); } public void onPre(WrapperPlayServerExplosion packet) { @@ -39,6 +43,7 @@ public class VelocityHandler { if(kb == null) return; VELOCITY_MAP.add(new Tuple<>(kb, false)); + PLAYER.getInfo().getVelocity().reset(); } public void onPost(WrapperPlayServerEntityVelocity packet) { @@ -62,8 +67,19 @@ public class VelocityHandler { } } + public void onComplete(WrapperPlayServerExplosion packet) { + // If the velocity is not confirmed, remove it. + VELOCITY_MAP.removeIf(value -> value.one.equals(packet.getKnockback())); + } + + public void onComplete(WrapperPlayServerEntityVelocity packet) { + // If the velocity is not confirmed, remove it. + VELOCITY_MAP.removeIf(value -> value.one.equals(packet.getVelocity())); + } + public List getPossibleVectors() { return VELOCITY_MAP.stream() + .filter(set -> !set.two) .map(set -> set.one) .toList(); } diff --git a/Anticheat/src/main/java/dev/brighten/ac/handler/keepalive/KeepaliveProcessor.java b/Anticheat/src/main/java/dev/brighten/ac/handler/keepalive/KeepaliveProcessor.java index 858162d..8168e1b 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/handler/keepalive/KeepaliveProcessor.java +++ b/Anticheat/src/main/java/dev/brighten/ac/handler/keepalive/KeepaliveProcessor.java @@ -1,22 +1,17 @@ package dev.brighten.ac.handler.keepalive; -import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPing; import dev.brighten.ac.Anticheat; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.packet.TransactionServerWrapper; -import dev.brighten.ac.utils.BukkitRunnable; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMaps; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.shorts.Short2ObjectArrayMap; -import org.bukkit.scheduler.BukkitTask; import java.util.Map; import java.util.Optional; -public class KeepaliveProcessor implements BukkitRunnable { - - private BukkitTask task; +public class KeepaliveProcessor { public KeepAlive currentKeepalive = new KeepAlive((short) 0); public short tick; @@ -29,8 +24,7 @@ public class KeepaliveProcessor implements BukkitRunnable { public KeepaliveProcessor() { } - @Override - public void run(BukkitTask task) { + public void run() { tick++; if(tick > Short.MAX_VALUE - 2) { @@ -76,23 +70,10 @@ public class KeepaliveProcessor implements BukkitRunnable { return getKeepById(lastResponses.get(data.getBukkitPlayer().getUniqueId().hashCode())); } - public void start() { - if (task == null) { - task = Anticheat.INSTANCE.getRunUtils().taskTimer(this, 20L, 0L); - } - } - public void addResponse(APlayer data, short id) { getKeepById(id).ifPresent(ka -> { lastResponses.put(data.getBukkitPlayer().getUniqueId().hashCode(), (Short) id); ka.received(data); }); } - - public void stop() { - if (task != null) { - task.cancel(); - task = null; - } - } } diff --git a/Anticheat/src/main/java/dev/brighten/ac/utils/Materials.java b/Anticheat/src/main/java/dev/brighten/ac/utils/Materials.java index d18d0eb..d82e977 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/utils/Materials.java +++ b/Anticheat/src/main/java/dev/brighten/ac/utils/Materials.java @@ -2,6 +2,8 @@ package dev.brighten.ac.utils; import com.github.retrooper.packetevents.protocol.world.states.type.StateType; import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes; +import dev.brighten.ac.utils.world.BlockData; +import dev.brighten.ac.utils.world.types.NoCollisionBox; import org.bukkit.Material; import java.util.HashMap; @@ -33,7 +35,7 @@ public class Materials { flag |= SOLID; } - if(mat.isBlocking()) { + if(!(BlockData.getData(mat).getDefaultBox() instanceof NoCollisionBox)) { flag |= COLLIDABLE; } diff --git a/Anticheat/src/main/java/dev/brighten/ac/utils/ServerInjector.java b/Anticheat/src/main/java/dev/brighten/ac/utils/ServerInjector.java index c8404a2..0844b0c 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/utils/ServerInjector.java +++ b/Anticheat/src/main/java/dev/brighten/ac/utils/ServerInjector.java @@ -38,6 +38,8 @@ public class ServerInjector { public void onSize() { Runnable toRun; + Anticheat.INSTANCE.getKeepaliveProcessor().run(); + while((toRun = Anticheat.INSTANCE.getOnTickEnd().poll()) != null) { toRun.run(); } diff --git a/Anticheat/src/main/java/dev/brighten/ac/utils/world/BlockData.java b/Anticheat/src/main/java/dev/brighten/ac/utils/world/BlockData.java index b1b7295..958a176 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/utils/world/BlockData.java +++ b/Anticheat/src/main/java/dev/brighten/ac/utils/world/BlockData.java @@ -4,6 +4,7 @@ import com.github.retrooper.packetevents.PacketEvents; import com.github.retrooper.packetevents.manager.server.ServerVersion; import com.github.retrooper.packetevents.protocol.player.ClientVersion; import com.github.retrooper.packetevents.protocol.world.BlockFace; +import com.github.retrooper.packetevents.protocol.world.states.defaulttags.BlockTags; import com.github.retrooper.packetevents.protocol.world.states.enums.*; import com.github.retrooper.packetevents.protocol.world.states.type.StateType; import com.github.retrooper.packetevents.protocol.world.states.type.StateTypes; @@ -13,8 +14,6 @@ import dev.brighten.ac.utils.BlockUtils; import dev.brighten.ac.utils.math.IntVector; import dev.brighten.ac.utils.world.blocks.*; import dev.brighten.ac.utils.world.types.*; -import io.github.retrooper.packetevents.util.SpigotConversionUtil; -import org.bukkit.block.Block; import java.util.*; import java.util.stream.Stream; @@ -42,7 +41,7 @@ public enum BlockData { boxes.add(new HexCollisionBox(0.0D, 0.0D, 15.0D, 16.0D, 16.0D, 16.0D)); // This is where fire differs from vine with its hitbox - if (block.getBlockState().getType() == StateTypes.FIRE && boxes.isNull()) + if (block.getBlockState().getType() == com.github.retrooper.packetevents.protocol.world.states.type.StateTypes.FIRE && boxes.isNull()) return new HexCollisionBox(0.0D, 0.0D, 0.0D, 16.0D, 1.0D, 16.0D); return boxes; @@ -88,36 +87,80 @@ public enum BlockData { } }, StateTypes.ANVIL, StateTypes.CHIPPED_ANVIL, StateTypes.DAMAGED_ANVIL) - ,_WALL(new DynamicWall(), StateTypes.values().stream() - .filter(mat -> mat.getName().contains("WALL")) - .toArray(StateType[]::new)), + ,_WALL(new DynamicWall(), BlockTags.WALLS.getStates().toArray(new StateType[0])), - _SKULL((protocol, player, b) -> { - BlockFace face = b.getBlockState().getFacing(); - return switch (face) { - case EAST -> new SimpleCollisionBox(0.25F, 0.25F, 0.5F, 0.75F, 0.75F, 1.0F); - case NORTH -> new SimpleCollisionBox(0.25F, 0.25F, 0.0F, 0.75F, 0.75F, 0.5F); - case SOUTH -> new SimpleCollisionBox(0.5F, 0.25F, 0.25F, 1.0F, 0.75F, 0.75F); - case DOWN -> new SimpleCollisionBox(0.0F, 0.25F, 0.25F, 0.5F, 0.75F, 0.75F); - default -> new SimpleCollisionBox(0.25F, 0.0F, 0.25F, 0.75F, 0.5F, 0.75F); //WEST - }; - }, StateTypes.values().stream().filter(mat -> mat.getName().contains("SKULL") - || mat.getName().contains("HEAD")).toArray(StateType[]::new)), + _SKULL(new SimpleCollisionBox(0.25F, 0.0F, 0.25F, 0.75F, 0.5F, 0.75F), + StateTypes.CREEPER_HEAD, StateTypes.ZOMBIE_HEAD, StateTypes.DRAGON_HEAD, StateTypes.PLAYER_HEAD, + StateTypes.SKELETON_SKULL, StateTypes.WITHER_SKELETON_SKULL, StateTypes.HEAVY_CORE), + _PIGLIN_SKULL(new HexCollisionBox(3.0D, 0.0D, 3.0D, 13.0D, 8.0D, 13.0D), + StateTypes.PIGLIN_HEAD), + _WALL_SKULL((protocol, player, b) -> switch (b.getBlockState().getFacing()) { + case SOUTH -> new SimpleCollisionBox(0.25F, 0.25F, 0.0F, 0.75F, 0.75F, 0.5F); + case WEST -> new SimpleCollisionBox(0.5F, 0.25F, 0.25F, 1.0F, 0.75F, 0.75F); + case EAST -> new SimpleCollisionBox(0.0F, 0.25F, 0.25F, 0.5F, 0.75F, 0.75F); + default -> new SimpleCollisionBox(0.25F, 0.25F, 0.5F, 0.75F, 0.75F, 1.0F); + }, StateTypes.CREEPER_WALL_HEAD, StateTypes.DRAGON_WALL_HEAD, StateTypes.PLAYER_WALL_HEAD, StateTypes.ZOMBIE_WALL_HEAD, + StateTypes.SKELETON_WALL_SKULL, StateTypes.WITHER_SKELETON_WALL_SKULL), + _PIGLIN_WALL_SKULL((protocol, player, b) -> switch (b.getBlockState().getFacing()) { + case SOUTH -> new HexCollisionBox(3.0D, 4.0D, 0.0D, 13.0D, 12.0D, 8.0D); + case EAST -> new HexCollisionBox(0.0D, 4.0D, 3.0D, 8.0D, 12.0D, 13.0D); + case WEST -> new HexCollisionBox(8.0D, 4.0D, 3.0D, 16.0D, 12.0D, 13.0D); + default -> new HexCollisionBox(3.0D, 4.0D, 8.0D, 13.0D, 12.0D, 16.0D); + }, StateTypes.PIGLIN_WALL_HEAD), - _DOOR(new DoorHandler(), StateTypes.values().stream() - .filter(mat -> !mat.getName().contains("TRAP") && !mat.getName().contains("ITEM") - && mat.getName().contains("DOOR") - // Potential cause for ClassCastException to MaterialData instead of Door - && !mat.getName().equals("WOOD_DOOR") && !mat.getName().equals("IRON_DOOR")) - .toArray(StateType[]::new)), + _DOOR(new DoorHandler(), BlockTags.DOORS.getStates().toArray(new StateType[0])), _HOPPER(new HopperBounding(), StateTypes.HOPPER), _CAKE((protocol, player, block) -> { double f1 = (1 + block.getBlockState().getBites() * 2) / 16D; return new SimpleCollisionBox(f1, 0, 0.0625, 1 - 0.0625, 0.5, 1 - 0.0625); - }, StateTypes.values().stream().filter(m -> m.getName().contains("CAKE")).toArray(StateType[]::new)), + }, StateTypes.CAKE), + _COCOA_BEAN((protocol, player, block) -> { + int age = block.getBlockState().getAge(); + if (protocol.isNewerThanOrEquals(ClientVersion.V_1_9_1) && protocol.isOlderThan(ClientVersion.V_1_11)) + age = Math.min(age, 1); + switch (block.getBlockState().getFacing()) { + case EAST: + switch (age) { + case 0: + return new HexCollisionBox(11.0D, 7.0D, 6.0D, 15.0D, 12.0D, 10.0D); + case 1: + return new HexCollisionBox(9.0D, 5.0D, 5.0D, 15.0D, 12.0D, 11.0D); + case 2: + return new HexCollisionBox(7.0D, 3.0D, 4.0D, 15.0D, 12.0D, 12.0D); + } + case WEST: + switch (age) { + case 0: + return new HexCollisionBox(1.0D, 7.0D, 6.0D, 5.0D, 12.0D, 10.0D); + case 1: + return new HexCollisionBox(1.0D, 5.0D, 5.0D, 7.0D, 12.0D, 11.0D); + case 2: + return new HexCollisionBox(1.0D, 3.0D, 4.0D, 9.0D, 12.0D, 12.0D); + } + case NORTH: + switch (age) { + case 0: + return new HexCollisionBox(6.0D, 7.0D, 1.0D, 10.0D, 12.0D, 5.0D); + case 1: + return new HexCollisionBox(5.0D, 5.0D, 1.0D, 11.0D, 12.0D, 7.0D); + case 2: + return new HexCollisionBox(4.0D, 3.0D, 1.0D, 12.0D, 12.0D, 9.0D); + } + case SOUTH: + switch (age) { + case 0: + return new HexCollisionBox(6.0D, 7.0D, 11.0D, 10.0D, 12.0D, 15.0D); + case 1: + return new HexCollisionBox(5.0D, 5.0D, 9.0D, 11.0D, 12.0D, 15.0D); + case 2: + return new HexCollisionBox(4.0D, 3.0D, 7.0D, 12.0D, 12.0D, 15.0D); + } + } + return NoCollisionBox.INSTANCE; + }, StateTypes.COCOA), _LADDER((protocol, player, b) -> { float var3 = 0.125F; BlockFace facing = b.getBlockState().getFacing(); @@ -141,12 +184,9 @@ public enum BlockData { new SimpleCollisionBox(0.375F, 0.0F, 0.0F, 0.625F, 1.5F, 1.0F); default -> NoCollisionBox.INSTANCE; }; - }, StateTypes.values().stream().filter(mat -> mat.getName().contains("FENCE") && mat.getName().contains("GATE")) - .toArray(StateType[]::new)), + }, BlockTags.FENCE_GATES.getStates().toArray(new StateType[0])), - _FENCE(new DynamicFence(), StateTypes.values().stream() - .filter(mat -> mat.getName().equals("FENCE") || mat.getName().endsWith("FENCE")) - .toArray(StateType[]::new)), + _FENCE(new DynamicFence(), BlockTags.FENCES.getStates().toArray(new StateType[0])), _PANE(new DynamicPane(), StateTypes.values().stream() .filter(s -> s.getName().endsWith("PANE")) .toArray(StateType[]::new)), @@ -167,12 +207,9 @@ public enum BlockData { } return new SimpleCollisionBox(0, 0.5, 0, 1, 1, 1); - }, StateTypes.values().stream().filter(mat -> - mat.getName().contains("STEP") || mat.getName().contains("SLAB")) - .filter(mat -> !mat.getName().contains("DOUBLE")) - .toArray(StateType[]::new)), + }, BlockTags.SLABS.getStates().toArray(new StateType[0])), - _STAIR(new DynamicStair(), StateTypes.values().stream().filter(mat -> mat.getName().contains("STAIRS")) + _STAIR(new DynamicStair(), StateTypes.values().stream().filter(mat -> mat.getName().toUpperCase().contains("STAIRS")) .toArray(StateType[]::new)), _CHEST((protocol, player, b) -> { @@ -221,13 +258,18 @@ public enum BlockData { }, StateTypes.LILY_PAD), _BED(new SimpleCollisionBox(0.0F, 0.0F, 0.0F, 1.0F, 0.5625, 1.0F), - StateTypes.values().stream().filter(mat -> mat.getName().contains("BED") && !mat.getName().contains("ROCK")) + StateTypes.values().stream().filter(mat -> mat.getName().toUpperCase().contains("BED") && !mat.getName().toUpperCase().contains("ROCK")) .toArray(StateType[]::new)), + _WALL_SIGN((protocol, player, block) -> switch (block.getBlockState().getFacing()) { + case NORTH, SOUTH -> new HexCollisionBox(0.0, 14.0, 6.0, 16.0, 16.0, 10.0); + case WEST, EAST -> new HexCollisionBox(6.0, 14.0, 0.0, 10.0, 16.0, 16.0); + default -> NoCollisionBox.INSTANCE; + }, BlockTags.WALL_HANGING_SIGNS.getStates().toArray(new StateType[0])), _TRAPDOOR(new TrapDoorHandler(), StateTypes.values().stream() - .filter(mat -> mat.getName().contains("TRAP_DOOR") - || mat.getName().contains("TRAPDOOR")).toArray(StateType[]::new)), + .filter(mat -> mat.getName().toUpperCase().contains("TRAP_DOOR") + || mat.getName().toUpperCase().contains("TRAPDOOR")).toArray(StateType[]::new)), _STUPID(new SimpleCollisionBox(0.0F, 0.0F, 0.0F, 1.0F, 0.125F, 1.0F), StateTypes.COMPARATOR), @@ -260,67 +302,30 @@ public enum BlockData { _POT(new SimpleCollisionBox(0.3125, 0.0, 0.3125, 0.6875, 0.375, 0.6875), StateTypes.FLOWER_POT), - _WALL_SIGN((version, player, block) -> { - - double var4 = 0.28125; - double var5 = 0.78125; - double var6 = 0; - double var7 = 1.0; - double var8 = 0.125; - - return switch (block.getBlockState().getFacing()) { - case NORTH -> new SimpleCollisionBox(var6, var4, 1.0 - var8, var7, var5, 1.0); - case SOUTH -> new SimpleCollisionBox(var6, var4, 0.0, var7, var5, var8); - case WEST -> new SimpleCollisionBox(1.0 - var8, var4, var6, 1.0, var5, var7); - case EAST -> new SimpleCollisionBox(0.0, var4, var6, var8, var5, var7); - default -> new SimpleCollisionBox(0, 0, 0, 1, 1, 1); - }; - }, StateTypes.values().stream().filter(mat -> mat.getName().contains("WALL_SIGN")) - .toArray(StateType[]::new)), - - _SIGN(new SimpleCollisionBox(0.25, 0.0, 0.25, 0.75, 1.0, 0.75), - StateTypes.values().stream().filter(m -> m.getName().endsWith("_SIGN") || m.getName().startsWith("SIGN")) - .toArray(StateType[]::new)), - _BUTTON((version, player, block) -> { - BlockFace face = block.getBlockState().getFacing(); - - face = face.getOppositeFace(); - boolean flag = block.getBlockState().isPowered(); //is powered; - double f2 = (float)(flag ? 1 : 2) / 16.0; - return switch (face) { - case EAST -> new SimpleCollisionBox(0.0, 0.375, 0.3125, f2, 0.625, 0.6875); - case WEST -> new SimpleCollisionBox(1.0 - f2, 0.375, 0.3125, 1.0, 0.625, 0.6875); - case SOUTH -> new SimpleCollisionBox(0.3125, 0.375, 0.0, 0.6875, 0.625, f2); - case NORTH -> new SimpleCollisionBox(0.3125, 0.375, 1.0 - f2, 0.6875, 0.625, 1.0); - case UP -> new SimpleCollisionBox(0.3125, 0.0, 0.375, 0.6875, 0.0 + f2, 0.625); - case DOWN -> new SimpleCollisionBox(0.3125, 1.0 - f2, 0.375, 0.6875, 1.0, 0.625); - default -> NoCollisionBox.INSTANCE; - }; - }, StateTypes.values().stream().filter(mat -> mat.getName().contains("BUTTON")).toArray(StateType[]::new)), - - _LEVER((version, player, block) -> { - BlockFace face = block.getBlockState().getFacing(); - - double f = 0.1875; - return switch (face) { - case EAST -> new SimpleCollisionBox(0.0, 0.2, 0.5 - f, f * 2.0, 0.8, 0.5 + f); - case WEST -> new SimpleCollisionBox(1.0 - f * 2.0, 0.2, 0.5 - f, 1.0, 0.8, 0.5 + f); - case SOUTH -> new SimpleCollisionBox(0.5 - f, 0.2, 0.0, 0.5 + f, 0.8, f * 2.0); - case NORTH -> new SimpleCollisionBox(0.5 - f, 0.2, 1.0 - f * 2.0, 0.5 + f, 0.8, 1.0); - case UP -> new SimpleCollisionBox(0.25, 0.0, 0.25, 0.75, 0.6, 0.75); - case DOWN -> new SimpleCollisionBox(0.25, 0.4, 0.25, 0.75, 1.0, 0.75); - default -> NoCollisionBox.INSTANCE; - }; - }, StateTypes.LEVER), - _NONE(NoCollisionBox.INSTANCE, Stream.of(StateTypes.TORCH, StateTypes.REDSTONE_TORCH, StateTypes.REDSTONE_WIRE, StateTypes.REDSTONE_WALL_TORCH, StateTypes.POWERED_RAIL, StateTypes.WALL_TORCH, StateTypes.RAIL, StateTypes.ACTIVATOR_RAIL, StateTypes.DETECTOR_RAIL, StateTypes.AIR, StateTypes.FERN, - StateTypes.TRIPWIRE, StateTypes.TRIPWIRE_HOOK) + StateTypes.TRIPWIRE, StateTypes.TRIPWIRE_HOOK, StateTypes.TWISTING_VINES_PLANT, StateTypes.WEEPING_VINES_PLANT, + StateTypes.TWISTING_VINES, StateTypes.WEEPING_VINES, StateTypes.CAVE_VINES, StateTypes.CAVE_VINES_PLANT, + StateTypes.TALL_SEAGRASS, StateTypes.SEAGRASS, StateTypes.SHORT_GRASS, StateTypes.FERN, StateTypes.NETHER_SPROUTS, + StateTypes.DEAD_BUSH, StateTypes.SUGAR_CANE, StateTypes.SWEET_BERRY_BUSH, StateTypes.WARPED_ROOTS, + StateTypes.CRIMSON_ROOTS, StateTypes.TORCHFLOWER_CROP, StateTypes.PINK_PETALS, StateTypes.TALL_GRASS, + StateTypes.LARGE_FERN, StateTypes.BAMBOO_SAPLING, StateTypes.HANGING_ROOTS, + StateTypes.SMALL_DRIPLEAF, StateTypes.END_PORTAL, StateTypes.LEVER, StateTypes.PUMPKIN_STEM, StateTypes.MELON_STEM, + StateTypes.ATTACHED_MELON_STEM, StateTypes.ATTACHED_PUMPKIN_STEM, StateTypes.BEETROOTS, StateTypes.POTATOES, + StateTypes.WHEAT, StateTypes.CARROTS, StateTypes.NETHER_WART, StateTypes.MOVING_PISTON, StateTypes.AIR, StateTypes.CAVE_AIR, + StateTypes.VOID_AIR, StateTypes.LIGHT, StateTypes.WATER) .toArray(StateType[]::new)), _NONE2(NoCollisionBox.INSTANCE, StateTypes.values().stream() - .filter(mat -> mat.getName().contains("PLATE")).toArray(StateType[]::new)); + .filter(state -> state.getName().toUpperCase().contains("PLATE") + || !(state.isSolid() + || state == StateTypes.LAVA + || state == StateTypes.SCAFFOLDING + || state == StateTypes.PITCHER_CROP + || state == StateTypes.HEAVY_CORE + || state == StateTypes.PALE_MOSS_CARPET || BlockTags.WALL_HANGING_SIGNS.contains(state))) + .toArray(StateType[]::new)); private CollisionBox box; private CollisionFactory dynamic; @@ -340,28 +345,23 @@ public enum BlockData { this.materials = mList.toArray(new StateType[0]); } - public CollisionBox getBox(Block block, ClientVersion version) { - if (this.box != null) - return this.box.copy().offset(block.getX(), block.getY(), block.getZ()); - var convert = SpigotConversionUtil.fromBukkitMaterialData(block.getState().getData()); - return new DynamicCollisionBox(dynamic, null, new WrappedBlock(new IntVector(block.getLocation()), - convert.getType(), - convert), - version) - .offset(block.getX(), block.getY(), block.getZ()); + public CollisionBox getDefaultBox() { + if (this.box != null) { + return this.box.copy(); + } else { + return new DynamicCollisionBox(dynamic, null, null, + PacketEvents.getAPI().getServerManager().getVersion().toClientVersion()); + } } - public CollisionBox getBox(WrappedBlock block, ClientVersion version) { - if (this.box != null) - return this.box.copy().offset(block.getLocation().getX(), block.getLocation().getY(), block.getLocation().getZ()); - return new DynamicCollisionBox(dynamic, null, block, version) - .offset(block.getLocation().getX(), block.getLocation().getY(), block.getLocation().getZ()); + public CollisionBox getBox(APlayer player, WrappedBlock block, ClientVersion version) { + return getBox(player, block.getLocation(), version); } public CollisionBox getBox(APlayer player, IntVector block, ClientVersion version) { if (this.box != null) return this.box.copy().offset(block.getX(), block.getY(), block.getZ()); - return new DynamicCollisionBox(dynamic, null, player.getBlockUpdateHandler().getBlock(block), version) + return new DynamicCollisionBox(dynamic, player, player.getBlockUpdateHandler().getBlock(block), version) .offset(block.getX(), block.getY(), block.getZ()); } @@ -369,12 +369,14 @@ public enum BlockData { static { for (BlockData data : values()) { - for (StateType mat : data.materials) lookup.put(mat, data); + for (StateType state : data.materials) { + lookup.put(state, data); + } } } - public static BlockData getData(StateType material) { - BlockData data = lookup.get(material); + public static BlockData getData(StateType state) { + BlockData data = lookup.get(state); return data != null ? data : _DEFAULT; } } \ No newline at end of file diff --git a/Anticheat/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicStair.java b/Anticheat/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicStair.java index 45d4602..55aba14 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicStair.java +++ b/Anticheat/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicStair.java @@ -35,7 +35,7 @@ public class DynamicStair implements CollisionFactory { private static EnumShape getStairsShape(APlayer player, WrappedBlock originalStairs) { BlockFace facing = originalStairs.getBlockState().getFacing(); - Optional offsetOne = BlockUtils.getRelative(player, originalStairs.getLocation(), facing); + Optional offsetOne = player == null ? Optional.empty() : BlockUtils.getRelative(player, originalStairs.getLocation(), facing); if(offsetOne.isEmpty()) return EnumShape.STRAIGHT; diff --git a/Anticheat/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicWall.java b/Anticheat/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicWall.java index 1ac8847..0fdaca4 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicWall.java +++ b/Anticheat/src/main/java/dev/brighten/ac/utils/world/blocks/DynamicWall.java @@ -56,7 +56,7 @@ public class DynamicWall implements CollisionFactory { } private static boolean wallConnects(ClientVersion v, APlayer player, WrappedBlock fenceBlock, BlockFace direction) { - Optional targetBlock = BlockUtils.getRelative(player, fenceBlock.getLocation(), direction, 1); + Optional targetBlock = player == null ? Optional.empty() : BlockUtils.getRelative(player, fenceBlock.getLocation(), direction, 1); if(targetBlock.isEmpty()) return false; diff --git a/Anticheat/src/main/java/dev/brighten/ac/utils/world/types/RayCollision.java b/Anticheat/src/main/java/dev/brighten/ac/utils/world/types/RayCollision.java index a6535cb..6892315 100644 --- a/Anticheat/src/main/java/dev/brighten/ac/utils/world/types/RayCollision.java +++ b/Anticheat/src/main/java/dev/brighten/ac/utils/world/types/RayCollision.java @@ -7,12 +7,12 @@ import com.github.retrooper.packetevents.protocol.world.states.type.StateType; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.handler.block.WrappedBlock; import dev.brighten.ac.utils.Helper; +import dev.brighten.ac.utils.Materials; import dev.brighten.ac.utils.Tuple; import dev.brighten.ac.utils.math.RayTrace; import dev.brighten.ac.utils.world.BlockData; import dev.brighten.ac.utils.world.CollisionBox; import me.hydro.emulator.util.mcp.MathHelper; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.LivingEntity; import org.bukkit.util.Vector; @@ -138,12 +138,11 @@ public class RayCollision implements CollisionBox { Helper.drawRay(this, 3, particle, Arrays.asList(players)); } - public List boxesOnRay(APlayer world, double distance) { + public List boxesOnRay(APlayer player, double distance) { int amount = Math.round((float) (distance / 0.5)); Location[] locs = new Location[Math.max(2, amount)]; //We do a max to prevent NegativeArraySizeException. List boxes = new ArrayList<>(); - boolean primaryThread = Bukkit.isPrimaryThread(); ClientVersion version = PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(); for (int i = 0; i < locs.length; i++) { @@ -153,7 +152,7 @@ public class RayCollision implements CollisionBox { int fy = MathHelper.floor_double(originY + (directionY * ix)); int fz = MathHelper.floor_double(originZ + (directionZ * ix)); - WrappedBlock block = world.getBlockUpdateHandler().getBlock(fx, fy, fz); + WrappedBlock block = player.getBlockUpdateHandler().getBlock(fx, fy, fz); if (block == null) continue; @@ -161,7 +160,7 @@ public class RayCollision implements CollisionBox { if (!type.isBlocking()) continue; - CollisionBox box = BlockData.getData(type).getBox(block, version); + CollisionBox box = BlockData.getData(type).getBox(player, block, version); if (!isCollided(box)) continue; @@ -171,11 +170,10 @@ public class RayCollision implements CollisionBox { return boxes; } - public WrappedBlock getClosestBlockOfType(APlayer world, int bitmask, double distance) { + public WrappedBlock getClosestBlockOfType(APlayer player, int bitmask, double distance) { int amount = Math.round((float) (distance / 0.5)); - Location[] locs = new Location[Math.max(2, amount)]; //We do a max to prevent NegativeArraySizeException. - boolean primaryThread = Bukkit.isPrimaryThread(); + Location[] locs = new Location[Math.max(2, amount)]; //We do a max ClientVersion version = PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(); for (int i = 0; i < locs.length; i++) { @@ -185,15 +183,15 @@ public class RayCollision implements CollisionBox { int fy = MathHelper.floor_double(originY + (directionY * ix)); int fz = MathHelper.floor_double(originZ + (directionZ * ix)); - WrappedBlock block = world.getBlockUpdateHandler().getBlock(fx, fy, fz); + WrappedBlock block = player.getBlockUpdateHandler().getBlock(fx, fy, fz); - if (block == null) continue; + if(block == null || !Materials.checkFlag(block.getType(), bitmask)) continue; final StateType type = block.getType(); if (!type.isBlocking()) continue; - CollisionBox box = BlockData.getData(type).getBox(block, version); + CollisionBox box = BlockData.getData(type).getBox(player, block, version); if (!isCollided(box)) continue; diff --git a/Anticheat/src/main/resources/plugin.yml b/Anticheat/src/main/resources/plugin.yml index d79067d..86da6d1 100644 --- a/Anticheat/src/main/resources/plugin.yml +++ b/Anticheat/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: Kauri -version: 3.0-DEV +version: 3.0 main : dev.brighten.ac.Anticheat author: funkemunky softdepend: [ViaVersion, ProtocolSupport] \ No newline at end of file diff --git a/Compat/src/main/java/dev/brighten/ac/utils/KLocation.java b/Compat/src/main/java/dev/brighten/ac/utils/KLocation.java index 2ab1046..7ee98f4 100644 --- a/Compat/src/main/java/dev/brighten/ac/utils/KLocation.java +++ b/Compat/src/main/java/dev/brighten/ac/utils/KLocation.java @@ -63,10 +63,13 @@ public class KLocation implements Cloneable { return new Location(world, x, y, z, yaw, pitch); } - @SuppressWarnings("MethodDoesntCallSuperMethod") @Override public KLocation clone() { - return new KLocation(x, y, z, yaw, pitch, timeStamp); + try { + return (KLocation) super.clone(); + } catch (CloneNotSupportedException e) { + return new KLocation(x, y, z, yaw, pitch, timeStamp); + } } public double distanceSquared(KLocation other) {