From f947528674553adc966c1f6afc59728cebc7e6dd Mon Sep 17 00:00:00 2001 From: Marccccccccccccccc Date: Sun, 30 Nov 2025 00:35:36 +0100 Subject: [PATCH 1/3] Add cancel missed attacks feature in no-interact --- .../meteorclient/mixin/MinecraftClientMixin.java | 16 ++++++++++++++++ .../systems/modules/player/NoInteract.java | 9 +++++++++ 2 files changed, 25 insertions(+) diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/MinecraftClientMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/MinecraftClientMixin.java index 47c3ab99dd..ab898ec337 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/MinecraftClientMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/MinecraftClientMixin.java @@ -26,6 +26,7 @@ import meteordevelopment.meteorclient.systems.modules.movement.GUIMove; import meteordevelopment.meteorclient.systems.modules.player.FastUse; import meteordevelopment.meteorclient.systems.modules.player.Multitask; +import meteordevelopment.meteorclient.systems.modules.player.NoInteract; import meteordevelopment.meteorclient.systems.modules.render.ESP; import meteordevelopment.meteorclient.systems.modules.world.HighwayBuilder; import meteordevelopment.meteorclient.utils.Utils; @@ -45,6 +46,7 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; +import net.minecraft.util.Hand; import net.minecraft.util.hit.HitResult; import net.minecraft.util.profiler.Profilers; import org.jetbrains.annotations.Nullable; @@ -84,6 +86,9 @@ public abstract class MinecraftClientMixin implements IMinecraftClient { @Nullable public ClientPlayerEntity player; + @Shadow + private HitResult crosshairTarget; + @Shadow @Final @Mutable @@ -119,6 +124,17 @@ private void onTick(CallbackInfo info) { @Inject(method = "doAttack", at = @At("HEAD")) private void onAttack(CallbackInfoReturnable cir) { CPSUtils.onAttack(); + + NoInteract noInteract = Modules.get().get(NoInteract.class); + MinecraftClient client = (MinecraftClient) (Object) this; + + if (noInteract.isActive() && + noInteract.shouldCancelMissedAttacks() && + client.crosshairTarget != null && + client.crosshairTarget.getType() == HitResult.Type.MISS) { + cir.setReturnValue(false); + player.swingHand(Hand.MAIN_HAND, false); + } } @Inject(method = "doItemUse", at = @At("HEAD")) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoInteract.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoInteract.java index 4bea37d511..f98dbecd4f 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoInteract.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoInteract.java @@ -31,6 +31,12 @@ public class NoInteract extends Module { private final SettingGroup sgBlocks = settings.createGroup("Blocks"); private final SettingGroup sgEntities = settings.createGroup("Entities"); + private final Setting cancelMissedAttacks = sgEntities.add(new BoolSetting.Builder() + .name("missed-attacks") + .description("Cancels attacks that didn't hit anything.") + .defaultValue(false) + .build() + ); // Blocks private final Setting> blockMine = sgBlocks.add(new BlockListSetting.Builder() @@ -252,4 +258,7 @@ public enum InteractMode { Both, None } + public boolean shouldCancelMissedAttacks() { + return cancelMissedAttacks.get(); + } } From a90834826e62e4aaa3e454d542206b4c5849b445 Mon Sep 17 00:00:00 2001 From: Marccccccccccccccc Date: Sun, 30 Nov 2025 00:50:04 +0100 Subject: [PATCH 2/3] fix crash due to no cancellable = true --- .../meteorclient/mixin/MinecraftClientMixin.java | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/MinecraftClientMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/MinecraftClientMixin.java index ab898ec337..2f5afeb936 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/MinecraftClientMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/MinecraftClientMixin.java @@ -121,17 +121,14 @@ private void onTick(CallbackInfo info) { Profilers.get().pop(); } - @Inject(method = "doAttack", at = @At("HEAD")) + @Inject(method = "doAttack", at = @At("HEAD"), cancellable = true) private void onAttack(CallbackInfoReturnable cir) { CPSUtils.onAttack(); NoInteract noInteract = Modules.get().get(NoInteract.class); - MinecraftClient client = (MinecraftClient) (Object) this; - if (noInteract.isActive() && - noInteract.shouldCancelMissedAttacks() && - client.crosshairTarget != null && - client.crosshairTarget.getType() == HitResult.Type.MISS) { + if (noInteract.isActive() && noInteract.shouldCancelMissedAttacks() && + crosshairTarget != null && crosshairTarget.getType() == HitResult.Type.MISS) { cir.setReturnValue(false); player.swingHand(Hand.MAIN_HAND, false); } From e0609d792d77d390c2712fb54d01091e17c82a95 Mon Sep 17 00:00:00 2001 From: Marccccccccccccccc Date: Sun, 7 Dec 2025 15:38:46 +0100 Subject: [PATCH 3/3] Make it a separate Module --- .../mixin/MinecraftClientMixin.java | 49 ++++++++++++-- .../meteorclient/systems/modules/Modules.java | 1 + .../systems/modules/combat/NoMissDelay.java | 64 +++++++++++++++++++ .../systems/modules/player/NoInteract.java | 10 --- 4 files changed, 109 insertions(+), 15 deletions(-) create mode 100644 src/main/java/meteordevelopment/meteorclient/systems/modules/combat/NoMissDelay.java diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/MinecraftClientMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/MinecraftClientMixin.java index 2f5afeb936..3fa3f63072 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/MinecraftClientMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/MinecraftClientMixin.java @@ -23,10 +23,10 @@ import meteordevelopment.meteorclient.mixininterface.IMinecraftClient; import meteordevelopment.meteorclient.systems.config.Config; import meteordevelopment.meteorclient.systems.modules.Modules; +import meteordevelopment.meteorclient.systems.modules.combat.NoMissDelay; import meteordevelopment.meteorclient.systems.modules.movement.GUIMove; import meteordevelopment.meteorclient.systems.modules.player.FastUse; import meteordevelopment.meteorclient.systems.modules.player.Multitask; -import meteordevelopment.meteorclient.systems.modules.player.NoInteract; import meteordevelopment.meteorclient.systems.modules.render.ESP; import meteordevelopment.meteorclient.systems.modules.world.HighwayBuilder; import meteordevelopment.meteorclient.utils.Utils; @@ -44,6 +44,8 @@ import net.minecraft.client.util.Window; import net.minecraft.client.world.ClientWorld; import net.minecraft.entity.Entity; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.util.Hand; @@ -59,6 +61,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicBoolean; @Mixin(value = MinecraftClient.class, priority = 1001) public abstract class MinecraftClientMixin implements IMinecraftClient { @@ -121,19 +124,55 @@ private void onTick(CallbackInfo info) { Profilers.get().pop(); } + // NoMissDelay + @Inject(method = "doAttack", at = @At("HEAD"), cancellable = true) private void onAttack(CallbackInfoReturnable cir) { CPSUtils.onAttack(); - NoInteract noInteract = Modules.get().get(NoInteract.class); + NoMissDelay noMissDelay = Modules.get().get(NoMissDelay.class); + + if (!noMissDelay.isActive()) return; + if (noMissDelay.getOnlywithsword() && !hasAttackCooldown(player.getMainHandStack())) return; + + if (noMissDelay.getCancelnoncrits() && player.getAttackCooldownProgress(0.5F) < 1.0F) { + cir.setReturnValue(false); + if (noMissDelay.shouldSwing()) player.swingHand(Hand.MAIN_HAND, false); + return; + } + + if (crosshairTarget == null) { + cir.setReturnValue(false); + if (noMissDelay.shouldSwing()) player.swingHand(Hand.MAIN_HAND, false); + return; + } + + HitResult.Type type = crosshairTarget.getType(); - if (noInteract.isActive() && noInteract.shouldCancelMissedAttacks() && - crosshairTarget != null && crosshairTarget.getType() == HitResult.Type.MISS) { + if (type == HitResult.Type.MISS || + (noMissDelay.getCancelblockattacks() && type == HitResult.Type.BLOCK)) { cir.setReturnValue(false); - player.swingHand(Hand.MAIN_HAND, false); + if (noMissDelay.shouldSwing()) player.swingHand(Hand.MAIN_HAND, false); } } + private static boolean hasAttackCooldown(ItemStack stack) { + if (stack.isEmpty()) return false; + + AtomicBoolean hasAttack = new AtomicBoolean(false); //Thread safe just in case + + stack.applyAttributeModifiers(EquipmentSlot.MAINHAND, + (attribute, modifier) -> { + if (attribute.equals(EntityAttributes.ATTACK_DAMAGE) || + attribute.equals(EntityAttributes.ATTACK_SPEED)) { + hasAttack.set(true); + } + } + ); + + return hasAttack.get(); + } + @Inject(method = "doItemUse", at = @At("HEAD")) private void onDoItemUse(CallbackInfo info) { doItemUseCalled = true; diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/Modules.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/Modules.java index 43a1bb1136..9bc47ed370 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/Modules.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/Modules.java @@ -385,6 +385,7 @@ private void initCombat() { add(new AnchorAura()); add(new AntiAnvil()); add(new AntiBed()); + add(new NoMissDelay()); add(new ArrowDodge()); add(new AutoAnvil()); add(new AutoArmor()); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/NoMissDelay.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/NoMissDelay.java new file mode 100644 index 0000000000..8d35a48c1d --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/NoMissDelay.java @@ -0,0 +1,64 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.systems.modules.combat; + +import meteordevelopment.meteorclient.settings.BoolSetting; +import meteordevelopment.meteorclient.settings.Setting; +import meteordevelopment.meteorclient.settings.SettingGroup; +import meteordevelopment.meteorclient.systems.modules.Categories; +import meteordevelopment.meteorclient.systems.modules.Module; + +public class NoMissDelay extends Module { + private final SettingGroup sgGeneral = settings.getDefaultGroup(); + + public NoMissDelay() { + super(Categories.Combat, "no-miss-delay", "Cancels attacks that would miss"); + } + + private final Setting cancelblockattacks = sgGeneral.add(new BoolSetting.Builder() + .name("block-attacks") + .description("Cancels attacks that hit a block.") + .defaultValue(false) + .build() + ); + + private final Setting onlywithsword = sgGeneral.add(new BoolSetting.Builder() + .name("only-weapons") + .description("Cancels attacks only when holding a weapon") + .defaultValue(false) + .build() + ); + + private final Setting swing = sgGeneral.add(new BoolSetting.Builder() + .name("swing") + .description("Wheter to swing the hand when cancelling attacks") + .defaultValue(false) + .build() + ); + + private final Setting cancelnoncrits = sgGeneral.add(new BoolSetting.Builder() + .name("cancel-non-crits") + .description("Whether to cancel attacks that are not critical hits") + .defaultValue(false) + .build() + ); + + public boolean shouldSwing() { + return swing.get(); + } + + public boolean getCancelblockattacks() { + return cancelblockattacks.get(); + } + + public boolean getOnlywithsword() { + return onlywithsword.get(); + } + + public boolean getCancelnoncrits() { + return cancelnoncrits.get(); + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoInteract.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoInteract.java index f98dbecd4f..e737f80fcc 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoInteract.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoInteract.java @@ -30,13 +30,6 @@ public class NoInteract extends Module { private final SettingGroup sgBlocks = settings.createGroup("Blocks"); private final SettingGroup sgEntities = settings.createGroup("Entities"); - - private final Setting cancelMissedAttacks = sgEntities.add(new BoolSetting.Builder() - .name("missed-attacks") - .description("Cancels attacks that didn't hit anything.") - .defaultValue(false) - .build() - ); // Blocks private final Setting> blockMine = sgBlocks.add(new BlockListSetting.Builder() @@ -258,7 +251,4 @@ public enum InteractMode { Both, None } - public boolean shouldCancelMissedAttacks() { - return cancelMissedAttacks.get(); - } }