diff --git a/API/pom.xml b/API/pom.xml new file mode 100644 index 0000000..2d1a4d7 --- /dev/null +++ b/API/pom.xml @@ -0,0 +1,62 @@ + + + + 4.0.0 + + dev.brighten.ac + API + 1.0 + + + UTF-8 + + + + + + funkemunky-releases + https://nexus.funkemunky.cc/content/repositories/releases/ + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 8 + 8 + -XDignore.symbol.file + false + + + org.projectlombok + lombok + 1.18.20 + + + + + + + + + + org.projectlombok + lombok + 1.18.24 + provided + + + org.github.spigot + 1.8.8 + 1.8.8 + provided + + + + \ No newline at end of file diff --git a/API/src/main/java/dev/brighten/ac/api/AnticheatAPI.java b/API/src/main/java/dev/brighten/ac/api/AnticheatAPI.java new file mode 100644 index 0000000..cdceced --- /dev/null +++ b/API/src/main/java/dev/brighten/ac/api/AnticheatAPI.java @@ -0,0 +1,45 @@ +package dev.brighten.ac.api; + +import dev.brighten.ac.api.event.AnticheatEvent; +import org.bukkit.plugin.Plugin; + +import java.util.*; + +public class AnticheatAPI { + + public static AnticheatAPI INSTANCE; + private final Map> registeredEvents = new HashMap<>(); + public AnticheatAPI() { + INSTANCE = this; + } + + public void registerEvent(Plugin plugin, AnticheatEvent event) { + registeredEvents.compute(plugin.getName(), (key, list) -> { + if(list == null) { + list = new ArrayList<>(); + } + + list.add(event); + return list; + }); + } + + public void unregisterEvents(Plugin plugin) { + registeredEvents.remove(plugin.getName()); + } + + public List getAllEvents() { + final List allEvents = new ArrayList<>(); + + synchronized (registeredEvents) { + for (List events : registeredEvents.values()) { + allEvents.addAll(events); + } + } + + allEvents.sort(Comparator.comparing(e -> e.priority().getSlot())); + + return allEvents; + } + +} diff --git a/src/main/java/dev/brighten/ac/check/CheckType.java b/API/src/main/java/dev/brighten/ac/api/check/CheckType.java similarity index 62% rename from src/main/java/dev/brighten/ac/check/CheckType.java rename to API/src/main/java/dev/brighten/ac/api/check/CheckType.java index 5d7bfb8..d191498 100644 --- a/src/main/java/dev/brighten/ac/check/CheckType.java +++ b/API/src/main/java/dev/brighten/ac/api/check/CheckType.java @@ -1,7 +1,8 @@ -package dev.brighten.ac.check; +package dev.brighten.ac.api.check; public enum CheckType { COMBAT, + AUTOCLICKER, MOVEMENT, BLOCK, INTERACT, diff --git a/API/src/main/java/dev/brighten/ac/api/check/ECheck.java b/API/src/main/java/dev/brighten/ac/api/check/ECheck.java new file mode 100644 index 0000000..d362fd3 --- /dev/null +++ b/API/src/main/java/dev/brighten/ac/api/check/ECheck.java @@ -0,0 +1,9 @@ +package dev.brighten.ac.api.check; + +public interface ECheck { + String getName(); + + float getVl(); + + CheckType getCheckType(); +} diff --git a/API/src/main/java/dev/brighten/ac/api/event/AnticheatEvent.java b/API/src/main/java/dev/brighten/ac/api/event/AnticheatEvent.java new file mode 100644 index 0000000..d55fb6a --- /dev/null +++ b/API/src/main/java/dev/brighten/ac/api/event/AnticheatEvent.java @@ -0,0 +1,24 @@ +package dev.brighten.ac.api.event; + + +import dev.brighten.ac.api.check.ECheck; +import dev.brighten.ac.api.event.result.CancelResult; +import dev.brighten.ac.api.event.result.FlagResult; +import dev.brighten.ac.api.event.result.PunishResult; +import org.bukkit.entity.Player; +import org.bukkit.event.EventPriority; + +import java.util.List; + +public interface AnticheatEvent { + + PunishResult onPunish(Player player, ECheck check, List commands, boolean cancelled); + + FlagResult onFlag(Player player, ECheck check, String information, boolean cancelled); + + CancelResult onCancel(Player player, ECheck check, boolean cancelled); + + EventPriority priority(); + + +} diff --git a/API/src/main/java/dev/brighten/ac/api/event/result/CancelResult.java b/API/src/main/java/dev/brighten/ac/api/event/result/CancelResult.java new file mode 100644 index 0000000..70b551c --- /dev/null +++ b/API/src/main/java/dev/brighten/ac/api/event/result/CancelResult.java @@ -0,0 +1,10 @@ +package dev.brighten.ac.api.event.result; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class CancelResult { + private final boolean cancelled; +} diff --git a/API/src/main/java/dev/brighten/ac/api/event/result/FlagResult.java b/API/src/main/java/dev/brighten/ac/api/event/result/FlagResult.java new file mode 100644 index 0000000..9918230 --- /dev/null +++ b/API/src/main/java/dev/brighten/ac/api/event/result/FlagResult.java @@ -0,0 +1,10 @@ +package dev.brighten.ac.api.event.result; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class FlagResult { + private final boolean cancelled; +} diff --git a/API/src/main/java/dev/brighten/ac/api/event/result/PunishResult.java b/API/src/main/java/dev/brighten/ac/api/event/result/PunishResult.java new file mode 100644 index 0000000..46a47b6 --- /dev/null +++ b/API/src/main/java/dev/brighten/ac/api/event/result/PunishResult.java @@ -0,0 +1,14 @@ +package dev.brighten.ac.api.event.result; + +import lombok.Builder; +import lombok.Getter; + +import java.util.List; + +@Builder +@Getter +public class PunishResult { + private final boolean cancelled; + private String broadcastMessage; + private List commands; +} diff --git a/pom.xml b/pom.xml index cd8e339..40c2d7c 100644 --- a/pom.xml +++ b/pom.xml @@ -105,6 +105,12 @@ 1.8.8 provided + + dev.brighten.ac + API + 1.0 + compile + org.github.spigot 1.7.10 diff --git a/src/main/java/dev/brighten/ac/Anticheat.java b/src/main/java/dev/brighten/ac/Anticheat.java index c7582ab..da357ad 100644 --- a/src/main/java/dev/brighten/ac/Anticheat.java +++ b/src/main/java/dev/brighten/ac/Anticheat.java @@ -3,11 +3,13 @@ package dev.brighten.ac; import co.aikar.commands.BaseCommand; import co.aikar.commands.BukkitCommandManager; import com.google.common.util.concurrent.ThreadFactoryBuilder; +import dev.brighten.ac.api.AnticheatAPI; import dev.brighten.ac.check.Check; import dev.brighten.ac.check.CheckManager; import dev.brighten.ac.data.PlayerRegistry; import dev.brighten.ac.handler.PacketHandler; import dev.brighten.ac.handler.keepalive.KeepaliveProcessor; +import dev.brighten.ac.handler.protocolsupport.ProtocolAPI; import dev.brighten.ac.packet.handler.HandlerAbstract; import dev.brighten.ac.packet.listener.PacketProcessor; import dev.brighten.ac.utils.*; @@ -72,14 +74,24 @@ public class Anticheat extends JavaPlugin { .setUncaughtExceptionHandler((t, e) -> RunUtils.task(e::printStackTrace)) .build()); + saveDefaultConfig(); + commandManager = new BukkitCommandManager(this); commandManager.enableUnstableAPI("help"); new CommandPropertiesManager(commandManager, getDataFolder(), getResource("command-messages.properties")); - this.keepaliveProcessor = new KeepaliveProcessor(); packetProcessor = new PacketProcessor(); + + new AnticheatAPI(); + + initializeScanner(getClass(), this, + null, + true, + true); + + this.keepaliveProcessor = new KeepaliveProcessor(); this.checkManager = new CheckManager(); this.playerRegistry = new PlayerRegistry(); this.packetHandler = new PacketHandler(); @@ -95,11 +107,6 @@ public class Anticheat extends JavaPlugin { } catch (Exception e) { e.printStackTrace(); } - - initializeScanner(getClass(), this, - null, - true, - true); } public void onDisable() { @@ -110,12 +117,15 @@ public class Anticheat extends JavaPlugin { HandlerAbstract.shutdown(); HandlerList.unregisterAll(this); packetProcessor.shutdown(); + packetProcessor = null; checkManager.getCheckClasses().clear(); Check.alertsEnabled.clear(); Check.debugInstances.clear(); checkManager = null; keepaliveProcessor.keepAlives.cleanUp(); keepaliveProcessor = null; + ProtocolAPI.INSTANCE = null; + tps = null; Bukkit.getScheduler().cancelTasks(this); @@ -129,8 +139,16 @@ public class Anticheat extends JavaPlugin { } catch (Exception e) { throw new RuntimeException(e); } + + AnticheatAPI.INSTANCE = null; + + onTickEnd.clear(); + onTickEnd = null; + packetHandler = null; } + + public void initializeScanner(Class mainClass, Plugin plugin, ClassLoader loader, boolean loadListeners, boolean loadCommands) { initializeScanner(mainClass, plugin, loader, ClassScanner.scanFile(null, mainClass), loadListeners, diff --git a/src/main/java/dev/brighten/ac/check/Check.java b/src/main/java/dev/brighten/ac/check/Check.java index d377cc9..7cce012 100644 --- a/src/main/java/dev/brighten/ac/check/Check.java +++ b/src/main/java/dev/brighten/ac/check/Check.java @@ -1,6 +1,13 @@ package dev.brighten.ac.check; import dev.brighten.ac.Anticheat; +import dev.brighten.ac.api.AnticheatAPI; +import dev.brighten.ac.api.check.CheckType; +import dev.brighten.ac.api.check.ECheck; +import dev.brighten.ac.api.event.AnticheatEvent; +import dev.brighten.ac.api.event.result.CancelResult; +import dev.brighten.ac.api.event.result.FlagResult; +import dev.brighten.ac.api.event.result.PunishResult; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.utils.*; import dev.brighten.ac.utils.timer.Timer; @@ -12,16 +19,18 @@ import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.ComponentBuilder; import net.md_5.bungee.api.chat.HoverEvent; import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.Bukkit; import java.util.*; +import java.util.stream.Collectors; -public abstract class Check { +public class Check implements ECheck { public final APlayer player; @Getter private final CheckData checkData; @Getter - private int vl; + private float vl; private long lastFlagRun; private final Timer lastAlert = new MillisTimer(); @@ -34,6 +43,16 @@ public abstract class Check { this.checkData = getClass().getAnnotation(CheckData.class); } + @Override + public String getName() { + return checkData.name(); + } + + @Override + public CheckType getCheckType() { + return checkData.type(); + } + private String formatAlert(String toFormat, String info) { return addPlaceHolders(Color.translate(toFormat.replace("%desc%", String.join("\n", MiscUtils @@ -45,10 +64,20 @@ public abstract class Check { return string.replace("%player%", player.getBukkitPlayer().getName()) .replace("%check%", checkData.name()) .replace("%name%", player.getBukkitPlayer().getName()) + .replace("%p", String.valueOf(player.getLagInfo().getTransPing())) + .replace("%t", String.valueOf(MathUtils.round(Anticheat.INSTANCE.getTps(), 2))) .replace("%vl%", String.valueOf(MathUtils.round(vl, 1))); } public void cancel() { + CancelResult result = CancelResult.builder().cancelled(false).build(); + + for (AnticheatEvent event : AnticheatAPI.INSTANCE.getAllEvents()) { + result = event.onCancel(player.getBukkitPlayer(), this, result.isCancelled()); + } + + if(result.isCancelled()) return; + if(checkData.type() == CheckType.COMBAT) { player.hitsToCancel++; } else { @@ -84,6 +113,10 @@ public abstract class Check { } public void flag(String information, Object... variables) { + flag(true, information, variables); + } + + public void flag(boolean punish, String information, Object... variables) { vl++; if(System.currentTimeMillis() - lastFlagRun < 50L) return; @@ -92,12 +125,18 @@ public abstract class Check { vl = 0; lastFlagRun = System.currentTimeMillis(); - final String finalInformation = String.format(information, variables); + final String info = String.format(information, variables); + + FlagResult currentResult = FlagResult.builder().cancelled(false).build(); + + for (AnticheatEvent event : AnticheatAPI.INSTANCE.getAllEvents()) { + currentResult = event.onFlag(player.getBukkitPlayer(), this, info, + currentResult.isCancelled()); + } + + if(currentResult.isCancelled()) return; boolean dev = Anticheat.INSTANCE.getTps() < 18; - final String info = finalInformation - .replace("%p", String.valueOf(player.getLagInfo().getTransPing())) - .replace("%t", String.valueOf(MathUtils.round(Anticheat.INSTANCE.getTps(), 2))); //if(vl > 0) Anticheat.INSTANCE.loggerManager.addLog(player, this, info); //Sending Discord webhook alert @@ -122,10 +161,31 @@ public abstract class Check { Anticheat.INSTANCE.getPlayerRegistry().getPlayer(uuid) .ifPresent(apl -> apl.getBukkitPlayer().spigot().sendMessage(toSend)); } + + if(punish && vl > checkData.punishVl()) { + punish(); + } lastAlert.reset(); }); } + public void punish() { + PunishResult result = PunishResult.builder().cancelled(false).build(); + + List commands = CheckConfig.punishmentCommands.stream().map(this::addPlaceHolders) + .collect(Collectors.toList()); + for (AnticheatEvent event : AnticheatAPI.INSTANCE.getAllEvents()) { + result = event.onPunish(player.getBukkitPlayer(),this, commands, result.isCancelled()); + } + PunishResult finalResult = result; + RunUtils.task(() -> { + for (String punishmentCommand : finalResult.getCommands()) { + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), punishmentCommand); + } + }); + vl = 0; + } + private TextComponent createTxt(String txt) { return createTxt(txt, ""); } diff --git a/src/main/java/dev/brighten/ac/check/CheckConfig.java b/src/main/java/dev/brighten/ac/check/CheckConfig.java new file mode 100644 index 0000000..23a4789 --- /dev/null +++ b/src/main/java/dev/brighten/ac/check/CheckConfig.java @@ -0,0 +1,14 @@ +package dev.brighten.ac.check; + +import dev.brighten.ac.utils.ConfigSetting; +import dev.brighten.ac.utils.Init; + +import java.util.Arrays; +import java.util.List; + +@Init +public class CheckConfig { + + @ConfigSetting(name = "punishments.commands") + public static List punishmentCommands = Arrays.asList("kick %player% Unfair Advantage (%check%)"); +} diff --git a/src/main/java/dev/brighten/ac/check/CheckData.java b/src/main/java/dev/brighten/ac/check/CheckData.java index ffaca6d..3ffff1c 100644 --- a/src/main/java/dev/brighten/ac/check/CheckData.java +++ b/src/main/java/dev/brighten/ac/check/CheckData.java @@ -1,5 +1,8 @@ package dev.brighten.ac.check; +import dev.brighten.ac.api.check.CheckType; +import dev.brighten.ac.packet.ProtocolVersion; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -7,4 +10,9 @@ import java.lang.annotation.RetentionPolicy; public @interface CheckData { String name(); CheckType type(); + + int punishVl() default 10; + + ProtocolVersion minVersion() default ProtocolVersion.V1_7; + ProtocolVersion maxVersion() default ProtocolVersion.V1_19; } diff --git a/src/main/java/dev/brighten/ac/check/CheckStatic.java b/src/main/java/dev/brighten/ac/check/CheckStatic.java index 29b3b08..95fd6bb 100644 --- a/src/main/java/dev/brighten/ac/check/CheckStatic.java +++ b/src/main/java/dev/brighten/ac/check/CheckStatic.java @@ -32,8 +32,8 @@ public class CheckStatic { private void processClass() { initConst = checkClass.getConstructor(APlayer.class); for (WrappedField field : checkClass.getFields()) { - if(!Action.class.isAssignableFrom(field.getType()) - || TimedAction.class.isAssignableFrom(field.getType())) continue; + if(!WAction.class.isAssignableFrom(field.getType()) + && !TimedWAction.class.isAssignableFrom(field.getType())) continue; Type genericType = field.getField().getGenericType(); Type type = null; @@ -57,7 +57,7 @@ public class CheckStatic { continue; } - if(field.getType().equals(Action.class)) { + if(field.getType().equals(WAction.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/TimedWAction.java similarity index 73% rename from src/main/java/dev/brighten/ac/check/TimedAction.java rename to src/main/java/dev/brighten/ac/check/TimedWAction.java index 4a53c89..8e2f335 100644 --- a/src/main/java/dev/brighten/ac/check/TimedAction.java +++ b/src/main/java/dev/brighten/ac/check/TimedWAction.java @@ -1,6 +1,6 @@ package dev.brighten.ac.check; @FunctionalInterface -public interface TimedAction { +public interface TimedWAction { void invoke(T event, long timestamp); } diff --git a/src/main/java/dev/brighten/ac/check/Action.java b/src/main/java/dev/brighten/ac/check/WAction.java similarity index 72% rename from src/main/java/dev/brighten/ac/check/Action.java rename to src/main/java/dev/brighten/ac/check/WAction.java index 8f09317..f58f92d 100644 --- a/src/main/java/dev/brighten/ac/check/Action.java +++ b/src/main/java/dev/brighten/ac/check/WAction.java @@ -1,6 +1,6 @@ package dev.brighten.ac.check; @FunctionalInterface -public interface Action { +public interface WAction { void invoke(T event); } 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 f433937..0a76805 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 @@ -1,9 +1,9 @@ package dev.brighten.ac.check.impl.combat; -import dev.brighten.ac.check.Action; +import dev.brighten.ac.check.WAction; import dev.brighten.ac.check.Check; import dev.brighten.ac.check.CheckData; -import dev.brighten.ac.check.CheckType; +import dev.brighten.ac.api.check.CheckType; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; import dev.brighten.ac.utils.Color; @@ -22,7 +22,7 @@ public class Aim extends Check { protected Timer lastGrid = new TickTimer(3); - Action onFlying = (packet) -> { + WAction onFlying = (packet) -> { if(!packet.isLooked()) return; if(player.getMovement().getYawGcdList().size() < 40) { 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 ad0a0e4..2ed5424 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 @@ -1,9 +1,9 @@ package dev.brighten.ac.check.impl.combat; -import dev.brighten.ac.check.Action; +import dev.brighten.ac.check.WAction; import dev.brighten.ac.check.Check; import dev.brighten.ac.check.CheckData; -import dev.brighten.ac.check.CheckType; +import dev.brighten.ac.api.check.CheckType; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; @@ -36,7 +36,7 @@ public class Hitbox extends Check { super(player); } - Action useEntity = packet -> { + WAction 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())); @@ -46,7 +46,7 @@ public class Hitbox extends Check { //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 onFlying = packet -> { + WAction onFlying = packet -> { if(player.getInfo().isCreative() || player.getInfo().isInVehicle()) { attacks.clear(); return; diff --git a/src/main/java/dev/brighten/ac/check/impl/combat/autoclicker/AutoclickerA.java b/src/main/java/dev/brighten/ac/check/impl/combat/autoclicker/AutoclickerA.java new file mode 100644 index 0000000..4ce8370 --- /dev/null +++ b/src/main/java/dev/brighten/ac/check/impl/combat/autoclicker/AutoclickerA.java @@ -0,0 +1,41 @@ +package dev.brighten.ac.check.impl.combat.autoclicker; + +import dev.brighten.ac.check.Check; +import dev.brighten.ac.check.CheckData; +import dev.brighten.ac.api.check.CheckType; +import dev.brighten.ac.check.WAction; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.packet.ProtocolVersion; +import dev.brighten.ac.packet.wrapper.in.WPacketPlayInArmAnimation; +import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; + +@CheckData(name = "AutoClicker (A)", type = CheckType.AUTOCLICKER, maxVersion = ProtocolVersion.V1_8_9) +public class AutoclickerA extends Check { + public AutoclickerA(APlayer player) { + super(player); + } + + private int flyingTicks, cps; + + WAction flying = (packet) -> { + flyingTicks++; + if(flyingTicks >= 20) { + if(cps > 22) { + if(cps > 30) { + punish(); + } + flag("cps=%s", cps); + } + cps = 0; + } + }; + + WAction armAnimation = packet -> { + if(!player.getInfo().breakingBlock + && player.getInfo().getLastBlockDig().isPassed(1) + && player.getInfo().getLastBlockPlace().isPassed(1)) { + cps++; + } + debug("breaking=%s", player.getInfo().breakingBlock); + }; +} diff --git a/src/main/java/dev/brighten/ac/check/impl/combat/autoclicker/AutoclickerB.java b/src/main/java/dev/brighten/ac/check/impl/combat/autoclicker/AutoclickerB.java new file mode 100644 index 0000000..c2ff20e --- /dev/null +++ b/src/main/java/dev/brighten/ac/check/impl/combat/autoclicker/AutoclickerB.java @@ -0,0 +1,34 @@ +package dev.brighten.ac.check.impl.combat.autoclicker; + +import dev.brighten.ac.check.Check; +import dev.brighten.ac.check.CheckData; +import dev.brighten.ac.api.check.CheckType; +import dev.brighten.ac.check.TimedWAction; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.packet.wrapper.in.WPacketPlayInArmAnimation; +import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; + +@CheckData(name = "Autoclicker (B)", type = CheckType.AUTOCLICKER) +public class AutoclickerB extends Check { + public AutoclickerB(APlayer player) { + super(player); + } + + private long lastFlying; + private int buffer; + + TimedWAction flyingPacket = (packet, timestamp) -> { + if(player.getMovement().getLastTeleport().isPassed(1)) + lastFlying = timestamp; + }; + + TimedWAction animation = (packet, timestamp) -> { + if(timestamp - lastFlying < 10 && player.getLagInfo().getLastPacketDrop().isPassed(1)) { + if(++buffer > 4) { + flag("delta=%s", timestamp - lastFlying); + } + } else if(buffer > 0) buffer--; + + debug("delta=%sms", timestamp - lastFlying); + }; +} 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 959ee31..fab5c2a 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 @@ -1,9 +1,9 @@ package dev.brighten.ac.check.impl.fly; -import dev.brighten.ac.check.Action; +import dev.brighten.ac.check.WAction; import dev.brighten.ac.check.Check; import dev.brighten.ac.check.CheckData; -import dev.brighten.ac.check.CheckType; +import dev.brighten.ac.api.check.CheckType; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; @@ -23,7 +23,7 @@ public class FlyA extends Check { private float buffer; private static double mult = 0.98f; - Action flying = packet -> { + WAction flying = packet -> { if(!packet.isMoved() || (player.getMovement().getDeltaXZ() == 0 && player.getMovement().getDeltaY() == 0)) { return; 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 62a416d..d321297 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 @@ -1,9 +1,9 @@ package dev.brighten.ac.check.impl.fly; -import dev.brighten.ac.check.Action; +import dev.brighten.ac.check.WAction; import dev.brighten.ac.check.Check; import dev.brighten.ac.check.CheckData; -import dev.brighten.ac.check.CheckType; +import dev.brighten.ac.api.check.CheckType; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; import dev.brighten.ac.utils.timer.Timer; @@ -18,7 +18,7 @@ public class FlyB extends Check { private Timer lastNearGround = new TickTimer(); private float buffer; - Action flying = packet -> { + WAction flying = packet -> { if(player.getInfo().isNearGround()) lastNearGround.reset(); if(!packet.isMoved() || player.getInfo().isGeneralCancel()) return; 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 db9bd23..9986bd6 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 @@ -1,9 +1,9 @@ package dev.brighten.ac.check.impl.nofall; -import dev.brighten.ac.check.Action; +import dev.brighten.ac.check.WAction; import dev.brighten.ac.check.Check; import dev.brighten.ac.check.CheckData; -import dev.brighten.ac.check.CheckType; +import dev.brighten.ac.api.check.CheckType; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; @@ -17,7 +17,7 @@ public class NoFallA extends Check { private static double divisor = 1. / 64.; private float buffer; - Action flying = packet -> { + WAction flying = packet -> { if(player.getInfo().isGeneralCancel() || (player.getMovement().getDeltaXZ() == 0 && player.getMovement().getDeltaY() == 0) || player.getBlockInfo().inLiquid 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 3d194d6..0eed846 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 @@ -1,9 +1,9 @@ package dev.brighten.ac.check.impl.nofall; -import dev.brighten.ac.check.Action; +import dev.brighten.ac.check.WAction; import dev.brighten.ac.check.Check; import dev.brighten.ac.check.CheckData; -import dev.brighten.ac.check.CheckType; +import dev.brighten.ac.api.check.CheckType; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; @@ -18,7 +18,7 @@ public class NoFallB extends Check { private int airBuffer, groundBuffer; - Action flying = packet -> { + WAction flying = packet -> { if(player.getMovement().getLastTeleport().isNotPassed(3) || player.getMovement().getMoveTicks() < 2 || player.getInfo().canFly diff --git a/src/main/java/dev/brighten/ac/check/impl/order/Place.java b/src/main/java/dev/brighten/ac/check/impl/order/Place.java new file mode 100644 index 0000000..c9b8b64 --- /dev/null +++ b/src/main/java/dev/brighten/ac/check/impl/order/Place.java @@ -0,0 +1,35 @@ +package dev.brighten.ac.check.impl.order; + +import dev.brighten.ac.api.check.CheckType; +import dev.brighten.ac.check.Check; +import dev.brighten.ac.check.CheckData; +import dev.brighten.ac.check.TimedWAction; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.packet.wrapper.in.WPacketPlayInBlockPlace; +import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; + +@CheckData(name = "Order (Place)", type = CheckType.ORDER, punishVl = 4) +public class Place extends Check { + public Place(APlayer player) { + super(player); + } + + private long lastFlying; + private int buffer; + + TimedWAction placePacket = (packet, timestamp) -> { + if(timestamp - lastFlying < 10 && player.getLagInfo().getLastPacketDrop().isPassed(1)) { + if(++buffer > 4) { + buffer = 5; + flag("delta=%sms", timestamp - lastFlying); + } + } else if(buffer > 0) buffer--; + + debug("buffer=%s delta=%sms", buffer, timestamp - lastFlying); + }; + + TimedWAction flying = (packet, timestamp) -> { + if(player.getMovement().getLastTeleport().isPassed(1)) + lastFlying = timestamp; + }; +} diff --git a/src/main/java/dev/brighten/ac/check/impl/order/UseEntity.java b/src/main/java/dev/brighten/ac/check/impl/order/UseEntity.java new file mode 100644 index 0000000..f8d894e --- /dev/null +++ b/src/main/java/dev/brighten/ac/check/impl/order/UseEntity.java @@ -0,0 +1,34 @@ +package dev.brighten.ac.check.impl.order; + +import dev.brighten.ac.check.Check; +import dev.brighten.ac.check.CheckData; +import dev.brighten.ac.api.check.CheckType; +import dev.brighten.ac.check.TimedWAction; +import dev.brighten.ac.data.APlayer; +import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; +import dev.brighten.ac.packet.wrapper.in.WPacketPlayInUseEntity; + +@CheckData(name = "Order (Use)", type = CheckType.ORDER) +public class UseEntity extends Check { + + private long lastFlying; + private int buffer; + + public UseEntity(APlayer player) { + super(player); + } + + TimedWAction useEntity = (packet, timestamp) -> { + if(timestamp - lastFlying < 10 && player.getLagInfo().getLastPacketDrop().isPassed(1)) { + if(++buffer > 5) { + buffer = 6; + flag("delta=%s", timestamp - lastFlying); + } + } else if(buffer > 0) buffer--; + }; + + TimedWAction flying = (packet, timestamp) -> { + if(player.getMovement().getLastTeleport().isPassed(0)) + lastFlying = timestamp; + }; +} 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 a7084ac..d4192c3 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 @@ -1,9 +1,9 @@ package dev.brighten.ac.check.impl.speed; -import dev.brighten.ac.check.Action; +import dev.brighten.ac.check.WAction; import dev.brighten.ac.check.Check; import dev.brighten.ac.check.CheckData; -import dev.brighten.ac.check.CheckType; +import dev.brighten.ac.api.check.CheckType; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; @@ -33,7 +33,7 @@ public class Horizontal extends Check { super(player); } - Action flying = packet -> { + WAction flying = packet -> { Block underBlock = BlockUtils.getBlock(player.getMovement().getTo().getLoc() .toLocation(player.getBukkitPlayer().getWorld()) .subtract(0, 1, 0)), 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 d8b7910..59da101 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 @@ -1,9 +1,9 @@ package dev.brighten.ac.check.impl.velocity; -import dev.brighten.ac.check.Action; +import dev.brighten.ac.check.WAction; import dev.brighten.ac.check.Check; import dev.brighten.ac.check.CheckData; -import dev.brighten.ac.check.CheckType; +import dev.brighten.ac.api.check.CheckType; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; import org.bukkit.util.Vector; @@ -23,7 +23,7 @@ public class VelocityA extends Check { }); } - Action flying = packet -> { + WAction flying = packet -> { if(currentVelocity != null && currentVelocity.getY() > 0 && !player.getBlockInfo().inWeb && !player.getBlockInfo().onClimbable 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 3c99a26..27b7193 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 @@ -1,9 +1,9 @@ package dev.brighten.ac.check.impl.velocity; -import dev.brighten.ac.check.Action; +import dev.brighten.ac.check.WAction; import dev.brighten.ac.check.Check; import dev.brighten.ac.check.CheckData; -import dev.brighten.ac.check.CheckType; +import dev.brighten.ac.api.check.CheckType; import dev.brighten.ac.check.impl.speed.Horizontal; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; @@ -38,14 +38,14 @@ public class VelocityB extends Check { private int ticks; private static final double[] moveValues = new double[] {-0.98, 0, 0.98}; - Action usePacket = packet -> { + WAction usePacket = packet -> { if(!useEntity && packet.getAction().equals(WPacketPlayInUseEntity.EnumEntityUseAction.ATTACK)) { useEntity = true; } }; - Action flying = packet -> { + WAction flying = packet -> { check: { if((pvX != 0 || pvZ != 0) && (player.getMovement().getDeltaX() != 0 || player.getMovement().getDeltaY() != 0 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 8eeda06..0b61aa1 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 @@ -1,9 +1,9 @@ package dev.brighten.ac.check.impl.world; -import dev.brighten.ac.check.Action; +import dev.brighten.ac.check.WAction; import dev.brighten.ac.check.Check; import dev.brighten.ac.check.CheckData; -import dev.brighten.ac.check.CheckType; +import dev.brighten.ac.api.check.CheckType; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.packet.ProtocolVersion; import dev.brighten.ac.packet.wrapper.in.WPacketPlayInBlockPlace; @@ -33,7 +33,7 @@ public class BlockA extends Check { private final MaxDouble verbose = new MaxDouble(20); private Queue> blockPlacements = new LinkedBlockingQueue<>(); - Action blockPlace = packet -> { + WAction blockPlace = packet -> { Location loc = packet.getBlockPos().toBukkitVector().toLocation(player.getBukkitPlayer().getWorld()); Optional optionalBlock = BlockUtils.getBlockAsync(loc); @@ -63,7 +63,7 @@ public class BlockA extends Check { blockPlacements.add(new Tuple<>(block, simpleBox.expand(0.1))); }; - Action flying = packet -> { + WAction flying = packet -> { Tuple tuple; while((tuple = blockPlacements.poll()) != null) { 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 dc1c97e..41cb2e0 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 @@ -1,9 +1,9 @@ package dev.brighten.ac.check.impl.world; -import dev.brighten.ac.check.Action; +import dev.brighten.ac.check.WAction; import dev.brighten.ac.check.Check; import dev.brighten.ac.check.CheckData; -import dev.brighten.ac.check.CheckType; +import dev.brighten.ac.api.check.CheckType; import dev.brighten.ac.data.APlayer; import org.bukkit.block.Block; import org.bukkit.event.block.BlockPlaceEvent; @@ -14,7 +14,7 @@ public class BlockB extends Check { super(player); } - Action blockPlaceEvent = event -> { + WAction blockPlaceEvent = event -> { Block ba = event.getBlockAgainst(); if (!event.getBlockPlaced().getType().isBlock()) return; 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 8de63e3..7698146 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 @@ -1,9 +1,9 @@ package dev.brighten.ac.check.impl.world; -import dev.brighten.ac.check.Action; +import dev.brighten.ac.check.WAction; import dev.brighten.ac.check.Check; import dev.brighten.ac.check.CheckData; -import dev.brighten.ac.check.CheckType; +import dev.brighten.ac.api.check.CheckType; import dev.brighten.ac.data.APlayer; import dev.brighten.ac.packet.wrapper.in.WPacketPlayInBlockPlace; import dev.brighten.ac.packet.wrapper.in.WPacketPlayInFlying; @@ -20,7 +20,7 @@ public class BlockC extends Check { super(player); } - Action flying = packet -> { + WAction flying = packet -> { if(player.getInfo().isCreative() || player.getMovement().isExcuseNextFlying()) return; long timestamp = System.currentTimeMillis(); if(place) { @@ -34,7 +34,7 @@ public class BlockC extends Check { } }; - Action blockPlace = packet -> { + WAction blockPlace = packet -> { if(player.pastLocations.isEmpty()) return; KLocation lastMovePacket = player.pastLocations.getLast().one; diff --git a/src/main/java/dev/brighten/ac/command/AnticheatCommand.java b/src/main/java/dev/brighten/ac/command/AnticheatCommand.java index b4b1be9..cb17fff 100644 --- a/src/main/java/dev/brighten/ac/command/AnticheatCommand.java +++ b/src/main/java/dev/brighten/ac/command/AnticheatCommand.java @@ -15,8 +15,10 @@ import io.netty.buffer.Unpooled; import lombok.val; import net.minecraft.server.v1_8_R3.PacketDataSerializer; import net.minecraft.server.v1_8_R3.PacketPlayOutCustomPayload; +import net.minecraft.server.v1_8_R3.PacketPlayOutTitle; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; +import org.bukkit.craftbukkit.v1_8_R3.util.CraftChatMessage; import org.bukkit.entity.Player; import java.io.UnsupportedEncodingException; @@ -86,6 +88,7 @@ public class AnticheatCommand extends BaseCommand { } @Subcommand("alerts") + @HelpCommand @CommandPermission("anticheat.command.alerts") @Description("Toggle anticheat alerts") public void onAlerts(Player pl) { @@ -105,6 +108,14 @@ public class AnticheatCommand extends BaseCommand { } } + @Subcommand("title") + @Private + public void onTitle(CommandSender sender, OnlinePlayer target, String title) { + PacketPlayOutTitle packetSubtitle = new PacketPlayOutTitle(PacketPlayOutTitle.EnumTitleAction.TITLE, CraftChatMessage.fromString(Color.translate(title))[0]); + HandlerAbstract.getHandler().sendPacket(target.getPlayer(), packetSubtitle); + sender.sendMessage(Color.Green + "Sent title!"); + } + @Subcommand("playerinfo|info|pi") @Description("Get player's information") @Syntax("[player]") diff --git a/src/main/java/dev/brighten/ac/data/APlayer.java b/src/main/java/dev/brighten/ac/data/APlayer.java index ea6e6a8..37821f3 100644 --- a/src/main/java/dev/brighten/ac/data/APlayer.java +++ b/src/main/java/dev/brighten/ac/data/APlayer.java @@ -1,10 +1,7 @@ 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.check.*; import dev.brighten.ac.data.handlers.BlockInformation; import dev.brighten.ac.data.handlers.GeneralInformation; import dev.brighten.ac.data.handlers.LagInformation; @@ -85,8 +82,8 @@ 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<>(); + private final Map, WAction[]> events = new HashMap<>(); + private final Map, TimedWAction[]> eventsWithTimestamp = new HashMap<>(); @Setter @Getter @@ -127,8 +124,51 @@ public class APlayer { this.blockInfo = new BlockInformation(this); // Grabbing the protocol version of the player. - Anticheat.INSTANCE.getScheduler().execute(() -> - playerVersion = ProtocolVersion.getVersion(ProtocolAPI.INSTANCE.getPlayerVersion(getBukkitPlayer()))); + Anticheat.INSTANCE.getScheduler().execute(() -> { + playerVersion = ProtocolVersion.getVersion(ProtocolAPI.INSTANCE.getPlayerVersion(getBukkitPlayer())); + + // Enabling checks for players on join + for (CheckStatic checkClass : Anticheat.INSTANCE.getCheckManager().getCheckClasses()) { + CheckData data = checkClass.getCheckClass().getAnnotation(CheckData.class); + + //Version checks + if(playerVersion.isAbove(data.maxVersion()) || playerVersion.isBelow(data.minVersion())) { + Anticheat.INSTANCE.alog("Player " + getBukkitPlayer().getName() + + " is not on the right version for check " + data.name() + + " (version: " + playerVersion.name() + ")"); + continue; + } + + Check check = checkClass.playerInit(this); + + for (Tuple> tuple : checkClass.getActions()) { + WAction action = tuple.one.get(check); + + events.compute(tuple.two, (packetClass, array) -> { + if (array == null) { + return new WAction[]{action}; + } else { + WAction[] newArray = Arrays.copyOf(array, array.length + 1); + newArray[array.length] = action; + return newArray; + } + }); + } + for (Tuple> tuple : checkClass.getTimedActions()) { + TimedWAction action = tuple.one.get(check); + + eventsWithTimestamp.compute(tuple.two, (packetClass, array) -> { + if (array == null) { + return new TimedWAction[]{action}; + } else { + TimedWAction[] newArray = Arrays.copyOf(array, array.length + 1); + newArray[array.length] = action; + return newArray; + } + }); + } + } + }); // Enabling alerts for players on join if they have the permissions to if(getBukkitPlayer().hasPermission("anticheat.command.alerts") @@ -136,38 +176,6 @@ 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() { @@ -179,8 +187,8 @@ public class APlayer { public void callEvent(Event event) { if(events.containsKey(event.getClass())) { - Action[] actions = (Action[]) events.get(event.getClass()); - for (Action action : actions) { + WAction[] actions = (WAction[]) events.get(event.getClass()); + for (WAction action : actions) { action.invoke(event); } } @@ -189,14 +197,14 @@ public class APlayer { //TODO When using WPacket wrappers only, make this strictly WPacket param based only public void callPacket(Object packet, long timestamp) { if(events.containsKey(packet.getClass())) { - Action[] actions = (Action[]) events.get(packet.getClass()); - for (Action action : actions) { + WAction[] actions = (WAction[]) events.get(packet.getClass()); + for (WAction action : actions) { action.invoke(packet); } } if(eventsWithTimestamp.containsKey(packet.getClass())) { - TimedAction[] actions = (TimedAction[]) eventsWithTimestamp.get(packet.getClass()); - for (TimedAction action : actions) { + TimedWAction[] actions = (TimedWAction[]) eventsWithTimestamp.get(packet.getClass()); + for (TimedWAction action : actions) { action.invoke(packet, timestamp); } } 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 a2f2780..c80c145 100644 --- a/src/main/java/dev/brighten/ac/data/handlers/GeneralInformation.java +++ b/src/main/java/dev/brighten/ac/data/handlers/GeneralInformation.java @@ -26,10 +26,10 @@ public class GeneralInformation { lastSneak = new TickTimer(), velocity = new TickTimer(), lastCancel = new TickTimer(), slimeTimer = new TickTimer(), lastElytra = new TickTimer(), blockAbove = new TickTimer(), lastPlace = new TickTimer(), climbTimer = new TickTimer(), lastUseItem = new TickTimer(), - lastLiquid = new TickTimer(); + lastLiquid = new TickTimer(), lastBlockDig = new TickTimer(), lastBlockPlace = new TickTimer(); public LivingEntity target; public boolean serverGround, lastServerGround, canFly, nearGround, worldLoaded, generalCancel, inVehicle, creative, - sneaking, lsneaking, sprinting, gliding, riptiding, wasOnSlime, onLadder, doingVelocity; + sneaking, lsneaking, sprinting, gliding, riptiding, wasOnSlime, onLadder, doingVelocity, breakingBlock; public List nearbyEntities = Collections.emptyList(); public PastLocation targetPastLocation = new PastLocation(); public KLocation lastKnownGoodPosition; diff --git a/src/main/java/dev/brighten/ac/handler/PacketHandler.java b/src/main/java/dev/brighten/ac/handler/PacketHandler.java index 8b26fd2..9eb096a 100644 --- a/src/main/java/dev/brighten/ac/handler/PacketHandler.java +++ b/src/main/java/dev/brighten/ac/handler/PacketHandler.java @@ -275,6 +275,8 @@ public class PacketHandler { IntVector pos = packet.getBlockPos(); ItemStack stack = packet.getItemStack(); + player.getInfo().getLastBlockPlace().reset(); + // Used item if(pos.getX() == -1 && (pos.getY() == 255 | pos.getY() == -1) && pos.getZ() == -1 && stack != null @@ -288,6 +290,7 @@ public class PacketHandler { case BLOCK_DIG: { WPacketPlayInBlockDig packet = (WPacketPlayInBlockDig) packetObject; + player.getInfo().getLastBlockDig().reset(); player.getBlockUpdateHandler().onDig(packet); break; } diff --git a/src/main/java/dev/brighten/ac/handler/protocolsupport/ProtocolAPI.java b/src/main/java/dev/brighten/ac/handler/protocolsupport/ProtocolAPI.java index 9ea71c6..7bc1555 100644 --- a/src/main/java/dev/brighten/ac/handler/protocolsupport/ProtocolAPI.java +++ b/src/main/java/dev/brighten/ac/handler/protocolsupport/ProtocolAPI.java @@ -1,5 +1,6 @@ package dev.brighten.ac.handler.protocolsupport; +import dev.brighten.ac.Anticheat; import dev.brighten.ac.handler.protocolsupport.impl.NoAPI; import dev.brighten.ac.handler.protocolsupport.impl.ProtocolSupport; import dev.brighten.ac.handler.protocolsupport.impl.ViaVersionAPI; @@ -21,9 +22,14 @@ public class ProtocolAPI { public ProtocolAPI() { if(Bukkit.getPluginManager().isPluginEnabled("ViaVersion")) { + Anticheat.INSTANCE.alog("Using ViaVersion for ProtocolAPI"); INSTANCE = new ViaVersionAPI(); } else if(Bukkit.getPluginManager().isPluginEnabled("ProtocolSupport")) { + Anticheat.INSTANCE.alog("Using ProtocolSupport for ProtocolAPI"); INSTANCE = new ProtocolSupport(); - } else INSTANCE = new NoAPI(); + } else { + Anticheat.INSTANCE.alog("Using Vanilla API for ProtocolAPI"); + INSTANCE = new NoAPI(); + } } } diff --git a/src/main/java/dev/brighten/ac/listener/GeneralListener.java b/src/main/java/dev/brighten/ac/listener/GeneralListener.java index 70ef3a4..bc42ce7 100644 --- a/src/main/java/dev/brighten/ac/listener/GeneralListener.java +++ b/src/main/java/dev/brighten/ac/listener/GeneralListener.java @@ -5,15 +5,18 @@ 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.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.event.player.PlayerTeleportEvent; @Init public class GeneralListener implements Listener { - @EventHandler + @EventHandler(priority = EventPriority.HIGH) public void onDamage(EntityDamageByEntityEvent event) { if(event.getDamager() instanceof Player) { APlayer player = Anticheat.INSTANCE.getPlayerRegistry().getPlayer(event.getDamager().getUniqueId()). @@ -28,17 +31,25 @@ public class GeneralListener implements Listener { } } - @EventHandler + @EventHandler(priority = EventPriority.MONITOR) + public void onInteract(PlayerInteractEvent event) { + Anticheat.INSTANCE.getPlayerRegistry().getPlayer(event.getPlayer().getUniqueId()).ifPresent(player -> { + player.getInfo().breakingBlock = event.getAction().equals(Action.LEFT_CLICK_BLOCK); + }); + } + + @EventHandler(priority = EventPriority.MONITOR) public void onTeleport(PlayerTeleportEvent event) { - if(event.getFrom().getWorld().equals(event.getTo().getWorld())) return; + if(event.getFrom().getWorld().equals(event.getTo().getWorld()) || event.isCancelled()) return; Anticheat.INSTANCE.getPlayerRegistry().getPlayer(event.getPlayer().getUniqueId()) .ifPresent(player -> player.getBlockUpdateHandler().onWorldChange()); } - @EventHandler + @EventHandler(priority = EventPriority.MONITOR) public void onPlace(BlockPlaceEvent event) { - Anticheat.INSTANCE.getPlayerRegistry().getPlayer(event.getPlayer().getUniqueId()) - .ifPresent(player -> player.callEvent(event)); + if(!event.isCancelled()) + Anticheat.INSTANCE.getPlayerRegistry().getPlayer(event.getPlayer().getUniqueId()) + .ifPresent(player -> player.callEvent(event)); } } diff --git a/src/main/java/dev/brighten/ac/packet/ProtocolVersion.java b/src/main/java/dev/brighten/ac/packet/ProtocolVersion.java index 11de52d..b2546a4 100644 --- a/src/main/java/dev/brighten/ac/packet/ProtocolVersion.java +++ b/src/main/java/dev/brighten/ac/packet/ProtocolVersion.java @@ -54,6 +54,8 @@ public enum ProtocolVersion { V1_18_2(758, "v1_18_R2"), V1_19(759, "v1_19_R1"), + v1_19_1(760, "v1_19_R1"), + UNKNOWN(-1, "UNKNOWN"); @Getter diff --git a/src/main/java/dev/brighten/ac/packet/handler/HandlerAbstract.java b/src/main/java/dev/brighten/ac/packet/handler/HandlerAbstract.java index 7072d17..5bf7df8 100644 --- a/src/main/java/dev/brighten/ac/packet/handler/HandlerAbstract.java +++ b/src/main/java/dev/brighten/ac/packet/handler/HandlerAbstract.java @@ -31,7 +31,6 @@ public abstract class HandlerAbstract{ public static void shutdown() { Bukkit.getOnlinePlayers().forEach(handler::remove); handler = null; - } public abstract void add(Player player); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index fdc66cd..7a1bbdc 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,4 +1,5 @@ name: Anticheat main: dev.brighten.ac.Anticheat version: 1.0 -author: funkemunky \ No newline at end of file +author: funkemunky +softdepend: [ViaVersion] \ No newline at end of file