diff --git a/src/main/java/ac/grim/grimac/checks/impl/packetorder/PacketOrderO.java b/src/main/java/ac/grim/grimac/checks/impl/packetorder/PacketOrderO.java new file mode 100644 index 0000000000..eaad366da1 --- /dev/null +++ b/src/main/java/ac/grim/grimac/checks/impl/packetorder/PacketOrderO.java @@ -0,0 +1,60 @@ +package ac.grim.grimac.checks.impl.packetorder; + +import ac.grim.grimac.checks.CheckData; +import ac.grim.grimac.checks.type.BlockPlaceCheck; +import ac.grim.grimac.player.GrimPlayer; +import ac.grim.grimac.utils.anticheat.update.BlockPlace; +import com.github.retrooper.packetevents.PacketEvents; +import com.github.retrooper.packetevents.event.PacketReceiveEvent; +import com.github.retrooper.packetevents.manager.server.ServerVersion; +import com.github.retrooper.packetevents.protocol.player.ClientVersion; +import com.github.retrooper.packetevents.protocol.player.InteractionHand; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying; + +@CheckData(name = "PacketOrderO", experimental = true) +public class PacketOrderO extends BlockPlaceCheck { + public PacketOrderO(final GrimPlayer player) { + super(player); + } + + private boolean sentMainhand; + + @Override + public void onBlockPlace(BlockPlace place) { + if (!isSupported()) { + return; + } + + if (place.getHand() == InteractionHand.OFF_HAND) { + if (!sentMainhand) { + if (flagAndAlert("Skipped Mainhand") && shouldModifyPackets() && shouldCancel()) { + place.resync(); + } + } + + sentMainhand = false; + } else { + if (sentMainhand) { + if (flagAndAlert("Skipped Offhand") && shouldModifyPackets() && shouldCancel()) { + place.resync(); + } + } + + sentMainhand = !place.isBlock(); + } + } + + @Override + public void onPacketReceive(PacketReceiveEvent event) { + if (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType()) && !player.packetStateData.lastPacketWasTeleport && !player.packetStateData.lastPacketWasOnePointSeventeenDuplicate) { + if (sentMainhand) { + sentMainhand = false; + flagAndAlert("Skipped Offhand (Tick)"); + } + } + } + + private boolean isSupported() { + return player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_13) && PacketEvents.getAPI().getServerManager().getVersion().isNewerThanOrEquals(ServerVersion.V_1_9); + } +} diff --git a/src/main/java/ac/grim/grimac/checks/impl/packetorder/PacketOrderP.java b/src/main/java/ac/grim/grimac/checks/impl/packetorder/PacketOrderP.java new file mode 100644 index 0000000000..e58f1e7e7d --- /dev/null +++ b/src/main/java/ac/grim/grimac/checks/impl/packetorder/PacketOrderP.java @@ -0,0 +1,63 @@ +package ac.grim.grimac.checks.impl.packetorder; + +import ac.grim.grimac.checks.Check; +import ac.grim.grimac.checks.CheckData; +import ac.grim.grimac.checks.type.PacketCheck; +import ac.grim.grimac.player.GrimPlayer; +import com.github.retrooper.packetevents.event.PacketReceiveEvent; +import com.github.retrooper.packetevents.protocol.packettype.PacketType; +import com.github.retrooper.packetevents.protocol.player.ClientVersion; +import com.github.retrooper.packetevents.protocol.player.InteractionHand; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity.InteractAction; +import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientPlayerFlying; + +@CheckData(name = "PacketOrderP", experimental = true) +public class PacketOrderP extends Check implements PacketCheck { + public PacketOrderP(final GrimPlayer player) { + super(player); + } + + private boolean sentMainhand; + private int requiredEntity; + private boolean requiredSneaking; + + @Override + public void onPacketReceive(PacketReceiveEvent event) { + if (event.getPacketType() == PacketType.Play.Client.INTERACT_ENTITY && player.getClientVersion().isNewerThanOrEquals(ClientVersion.V_1_9)) { + final WrapperPlayClientInteractEntity packet = new WrapperPlayClientInteractEntity(event); + InteractAction action = packet.getAction(); + if (action != InteractAction.ATTACK) { + final boolean sneaking = packet.isSneaking().orElse(false); + final int entity = packet.getEntityId(); + + if (packet.getHand() == InteractionHand.OFF_HAND) { + if (action == InteractAction.INTERACT) { + if (!sentMainhand) { + if (flagAndAlert("Skipped Mainhand") && shouldModifyPackets()) { + event.setCancelled(true); + player.onPacketCancel(); + } + } + sentMainhand = false; + } else if (sneaking != requiredSneaking || entity != requiredEntity) { + String verbose = "requiredEntity=" + requiredEntity + ", entity=" + entity + + ", requiredSneaking=" + requiredSneaking + ", sneaking=" + sneaking; + if (flagAndAlert(verbose) && shouldModifyPackets()) { + event.setCancelled(true); + player.onPacketCancel(); + } + } + } else { + requiredEntity = entity; + requiredSneaking = sneaking; + sentMainhand = true; + } + } + } + + if (WrapperPlayClientPlayerFlying.isFlying(event.getPacketType()) && !player.packetStateData.lastPacketWasTeleport && !player.packetStateData.lastPacketWasOnePointSeventeenDuplicate) { + sentMainhand = false; + } + } +} diff --git a/src/main/java/ac/grim/grimac/manager/CheckManager.java b/src/main/java/ac/grim/grimac/manager/CheckManager.java index 5856b1a82b..e6b9a84ab9 100644 --- a/src/main/java/ac/grim/grimac/manager/CheckManager.java +++ b/src/main/java/ac/grim/grimac/manager/CheckManager.java @@ -103,6 +103,7 @@ public CheckManager(GrimPlayer player) { .put(PacketOrderC.class, new PacketOrderC(player)) .put(PacketOrderD.class, new PacketOrderD(player)) .put(PacketOrderK.class, new PacketOrderK(player)) + .put(PacketOrderP.class, new PacketOrderP(player)) .put(NoSlowB.class, new NoSlowB(player)) .put(SetbackBlocker.class, new SetbackBlocker(player)) // Must be last class otherwise we can't check while blocking packets .build(); @@ -164,6 +165,7 @@ public CheckManager(GrimPlayer player) { .put(PositionPlace.class, new PositionPlace(player)) .put(RotationPlace.class, new RotationPlace(player)) .put(PacketOrderN.class, new PacketOrderN(player)) + .put(PacketOrderO.class, new PacketOrderO(player)) .put(DuplicateRotPlace.class, new DuplicateRotPlace(player)) .put(GhostBlockMitigation.class, new GhostBlockMitigation(player)) .build();