Skip to content

Commit

Permalink
sprint event
Browse files Browse the repository at this point in the history
  • Loading branch information
1zun4 committed Jan 8, 2025
1 parent e629c57 commit a7a1d5a
Show file tree
Hide file tree
Showing 10 changed files with 162 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,13 @@

package net.ccbluex.liquidbounce.injection.mixins.minecraft.client;

import net.ccbluex.liquidbounce.features.module.modules.combat.criticals.ModuleCriticals;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import net.ccbluex.liquidbounce.features.module.modules.movement.ModuleSprint;
import net.minecraft.client.input.Input;
import net.minecraft.util.PlayerInput;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(Input.class)
public abstract class MixinInput {
Expand All @@ -41,16 +39,14 @@ public abstract class MixinInput {
@Shadow
public PlayerInput playerInput;

@Inject(method = "hasForwardMovement", cancellable = true, at = @At("RETURN"))
private void hookOmnidirectionalSprintA(final CallbackInfoReturnable<Boolean> callbackInfoReturnable) {
if (ModuleCriticals.WhenSprinting.INSTANCE.getRunning() && ModuleCriticals.WhenSprinting.INSTANCE.getStopSprinting() == ModuleCriticals.WhenSprinting.StopSprintingMode.LEGIT) {
callbackInfoReturnable.setReturnValue(false);
return;
@ModifyReturnValue(method = "hasForwardMovement", at = @At("RETURN"))
private boolean hookOmnidirectionalSprint(boolean original) {
// Allow omnidirectional sprinting
if (ModuleSprint.INSTANCE.shouldSprintOmnidirectionally()) {
return Math.abs(movementForward) > 1.0E-5F || Math.abs(movementSideways) > 1.0E-5F;
}

final boolean hasMovement = Math.abs(movementForward) > 1.0E-5F || Math.abs(movementSideways) > 1.0E-5F;

callbackInfoReturnable.setReturnValue(!ModuleSprint.INSTANCE.shouldPreventSprint() && (ModuleSprint.INSTANCE.shouldSprintOmnidirectionally() ? hasMovement : callbackInfoReturnable.getReturnValue()));
return original;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.ccbluex.liquidbounce.event.EventManager;
import net.ccbluex.liquidbounce.event.events.MovementInputEvent;
import net.ccbluex.liquidbounce.features.module.modules.combat.ModuleSuperKnockback;
import net.ccbluex.liquidbounce.event.events.SprintEvent;
import net.ccbluex.liquidbounce.features.module.modules.movement.ModuleInventoryMove;
import net.ccbluex.liquidbounce.features.module.modules.movement.ModuleSprint;
import net.ccbluex.liquidbounce.utils.aiming.RotationManager;
import net.ccbluex.liquidbounce.utils.input.InputTracker;
import net.ccbluex.liquidbounce.utils.movement.DirectionalInput;
Expand Down Expand Up @@ -61,9 +60,10 @@ private boolean hookInventoryMove(KeyBinding instance, Operation<Boolean> origin
}

/**
* At settings.backKey.isPressed()
* Later in the code, the sprint key is checked for being pressed. We need to update the state of the key
* as well.
*/
@Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/option/KeyBinding;isPressed()Z", ordinal = 1))
@Inject(method = "tick", at = @At("HEAD"))
private void hookInventoryMoveSprint(CallbackInfo ci) {
if (ModuleInventoryMove.INSTANCE.shouldHandleInputs(this.settings.sprintKey)) {
this.settings.sprintKey.setPressed(InputTracker.INSTANCE.isPressedOnAny(this.settings.sprintKey));
Expand All @@ -76,28 +76,20 @@ private PlayerInput modifyInput(PlayerInput original) {
EventManager.INSTANCE.callEvent(event);
var directionalInput = changeDirection(event.getDirectionalInput());

var sprintEvent = new SprintEvent(original.sprint(), SprintEvent.Source.INPUT);
EventManager.INSTANCE.callEvent(sprintEvent);

return new PlayerInput(
directionalInput.getForwards(),
directionalInput.getBackwards(),
directionalInput.getLeft(),
directionalInput.getRight(),
event.getJump(),
event.getSneak(),
playerInput.sprint()
sprintEvent.getSprint()
);
}

@Inject(method = "tick", at = @At("RETURN"))
private void injectStopMove(CallbackInfo ci) {
if (ModuleSuperKnockback.INSTANCE.shouldStopMoving()) {
this.movementForward = 0f;

if (ModuleSprint.INSTANCE.shouldSprintOmnidirectionally()) {
this.movementSideways = 0f;
}
}
}

@Unique
private DirectionalInput changeDirection(DirectionalInput input) {
var player = MinecraftClient.getInstance().player;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,6 @@
import net.ccbluex.liquidbounce.event.EventManager;
import net.ccbluex.liquidbounce.event.EventState;
import net.ccbluex.liquidbounce.event.events.*;
import net.ccbluex.liquidbounce.features.module.modules.combat.ModuleSuperKnockback;
import net.ccbluex.liquidbounce.features.module.modules.combat.criticals.ModuleCriticals;
import net.ccbluex.liquidbounce.features.module.modules.combat.killaura.ModuleKillAura;
import net.ccbluex.liquidbounce.features.module.modules.exploit.ModuleAntiHunger;
import net.ccbluex.liquidbounce.features.module.modules.exploit.ModulePortalMenu;
import net.ccbluex.liquidbounce.features.module.modules.movement.ModuleEntityControl;
import net.ccbluex.liquidbounce.features.module.modules.movement.ModuleNoPush;
Expand Down Expand Up @@ -308,48 +304,42 @@ private float hookSprintIgnoreHunger(float constant) {

@ModifyExpressionValue(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/option/KeyBinding;isPressed()Z"))
private boolean hookAutoSprint(boolean original) {
return !ModuleSuperKnockback.INSTANCE.shouldBlockSprinting() && !ModuleKillAura.INSTANCE.shouldBlockSprinting()
&& (ModuleSprint.INSTANCE.getRunning() || original);
}

@ModifyExpressionValue(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isWalking()Z"))
private boolean hookOmnidirectionalSprintB(boolean original) {
return liquid_bounce$isOmniWalking();
var event = new SprintEvent(original, SprintEvent.Source.MOVEMENT_TICK);
EventManager.INSTANCE.callEvent(event);
return event.getSprint();
}

@ModifyExpressionValue(method = "canStartSprinting", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isBlind()Z"))
private boolean hookSprintIgnoreBlindness(boolean original) {
return !ModuleSprint.INSTANCE.shouldIgnoreBlindness() && original;
}

@ModifyExpressionValue(method = "canStartSprinting", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;isWalking()Z"))
private boolean hookOmnidirectionalSprintC(boolean original) {
return liquid_bounce$isOmniWalking();
}

@ModifyExpressionValue(method = "tickMovement", at = @At(value = "FIELD", target = "Lnet/minecraft/client/network/ClientPlayerEntity;horizontalCollision:Z"))
private boolean hookSprintIgnoreCollision(boolean original) {
return !ModuleSprint.INSTANCE.shouldIgnoreCollision() && original;
}

@Unique
private boolean liquid_bounce$isOmniWalking() {
boolean hasMovement = Math.abs(input.movementForward) > 1.0E-5F || Math.abs(input.movementSideways) > 1.0E-5F;
boolean isWalking = (double) Math.abs(input.movementForward) >= 0.8 || (double) Math.abs(input.movementSideways) >= 0.8;
boolean modifiedIsWalking = this.isSubmergedInWater() ? hasMovement : isWalking;
return ModuleSprint.INSTANCE.shouldSprintOmnidirectionally() ? modifiedIsWalking : this.isWalking();
@ModifyReturnValue(method = "isWalking", at = @At("RETURN"))
private boolean hookIsWalking(boolean original) {
if (!ModuleSprint.INSTANCE.shouldSprintOmnidirectionally()) {
return original;
}

var hasMovement = Math.abs(input.movementForward) > 1.0E-5F ||
Math.abs(input.movementSideways) > 1.0E-5F;
var isWalking = (double) Math.abs(input.movementForward) >= 0.8 ||
(double) Math.abs(input.movementSideways) >= 0.8;
return this.isSubmergedInWater() ? hasMovement : isWalking;
}

@ModifyExpressionValue(method = "sendSprintingPacket", at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/network/ClientPlayerEntity;isSprinting()Z")
)
private boolean hookNoHungerSprint(boolean original) {
if (ModuleCriticals.WhenSprinting.INSTANCE.getRunning() && ModuleCriticals.WhenSprinting.INSTANCE.getStopSprinting() == ModuleCriticals.WhenSprinting.StopSprintingMode.ON_NETWORK) {
return false;
}

return !(ModuleAntiHunger.INSTANCE.getRunning() && ModuleAntiHunger.INSTANCE.getNoSprint()) && original;
private boolean hookNetworkSprint(boolean original) {
var event = new SprintEvent(original, SprintEvent.Source.NETWORK);
EventManager.INSTANCE.callEvent(event);
return event.getSprint();
}

@WrapWithCondition(method = "closeScreen", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;setScreen(Lnet/minecraft/client/gui/screen/Screen;)V"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ val ALL_EVENT_CLASSES: Array<KClass<out Event>> = arrayOf(
KeyboardCharEvent::class,
InputHandleEvent::class,
MovementInputEvent::class,
SprintEvent::class,
KeyEvent::class,
MouseRotationEvent::class,
KeybindChangeEvent::class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,20 @@ class KeyEvent(val key: InputUtil.Key, val action: Int) : Event()
object InputHandleEvent : Event()

@Nameable("movementInput")
class MovementInputEvent(var directionalInput: DirectionalInput, var jump: Boolean, var sneak: Boolean) : Event()
class MovementInputEvent(
var directionalInput: DirectionalInput,
var jump: Boolean,
var sneak: Boolean
) : Event()

@Nameable("sprint")
class SprintEvent(var sprint: Boolean, val source: Source) : Event() {
enum class Source {
INPUT,
MOVEMENT_TICK,
NETWORK
}
}

@Nameable("mouseRotation")
class MouseRotationEvent(var cursorDeltaX: Double, var cursorDeltaY: Double) : CancellableEvent()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,17 @@ package net.ccbluex.liquidbounce.features.module.modules.combat
import net.ccbluex.liquidbounce.config.types.Choice
import net.ccbluex.liquidbounce.config.types.ChoiceConfigurable
import net.ccbluex.liquidbounce.config.types.ToggleableConfigurable
import net.ccbluex.liquidbounce.event.DummyEvent
import net.ccbluex.liquidbounce.event.Sequence
import net.ccbluex.liquidbounce.event.events.AttackEntityEvent
import net.ccbluex.liquidbounce.event.events.MovementInputEvent
import net.ccbluex.liquidbounce.event.events.SprintEvent
import net.ccbluex.liquidbounce.event.handler
import net.ccbluex.liquidbounce.event.sequenceHandler
import net.ccbluex.liquidbounce.features.module.Category
import net.ccbluex.liquidbounce.features.module.ClientModule
import net.ccbluex.liquidbounce.features.module.modules.combat.criticals.ModuleCriticals
import net.ccbluex.liquidbounce.utils.kotlin.EventPriorityConvention
import net.ccbluex.liquidbounce.utils.math.minus
import net.ccbluex.liquidbounce.utils.movement.DirectionalInput
import net.minecraft.entity.Entity
import net.minecraft.entity.LivingEntity
import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket
Expand All @@ -55,33 +58,12 @@ object ModuleSuperKnockback : ClientModule("SuperKnockback", Category.COMBAT, al
tree(OnlyOnMove)
}

var sequence: Sequence<DummyEvent>? = null

init {
modes.onChange {
reset()
it
}
}

override val running: Boolean
get() {
val running = super.running

// Reset if the module is not handling events anymore
if (!running) {
reset()
}

return running
}

object Packet : Choice("Packet") {
override val parent: ChoiceConfigurable<Choice>
get() = modes

@Suppress("unused")
val attackHandler = handler<AttackEntityEvent> { event ->
private val attackHandler = handler<AttackEntityEvent> { event ->
if (event.isCancelled) {
return@handler
}
Expand Down Expand Up @@ -114,23 +96,34 @@ object ModuleSuperKnockback : ClientModule("SuperKnockback", Category.COMBAT, al

private val reSprintTicks by intRange("ReSprint", 0..1, 0..10, "ticks")

var antiSprint = false
private var cancelSprint = false

@Suppress("unused")
val attackHandler = handler<AttackEntityEvent> { event ->
if (event.isCancelled || !shouldOperate(event.entity) || !shouldStopSprinting(event) || sequence != null) {
return@handler
private val attackHandler = sequenceHandler<AttackEntityEvent> { event ->
if (event.isCancelled || !shouldOperate(event.entity) || !shouldStopSprinting(event)) {
return@sequenceHandler
}

runWithDummyEvent {
antiSprint = true

it.waitUntil { !player.isSprinting && !player.lastSprinting }
it.waitTicks(reSprintTicks.random())
cancelSprint = true
waitUntil { !player.isSprinting && !player.lastSprinting }
waitTicks(reSprintTicks.random())
cancelSprint = false
}

antiSprint = false
@Suppress("unused")
private val movementHandler = handler<SprintEvent>(
priority = EventPriorityConvention.FIRST_PRIORITY
) { event ->
if (cancelSprint) {
event.sprint = false
}
}

override fun disable() {
cancelSprint = false
super.disable()
}

}

object WTap : Choice("WTap") {
Expand All @@ -142,27 +135,34 @@ object ModuleSuperKnockback : ClientModule("SuperKnockback", Category.COMBAT, al
private val ticksUntilAllowedMovement by intRange("UntilAllowedMovement", 0..1, 0..10,
"ticks")

var stopMoving = false
private var cancelMovement = false

@Suppress("unused")
val attackHandler = handler<AttackEntityEvent> { event ->
if (event.isCancelled || !shouldOperate(event.entity) || !shouldStopSprinting(event) || sequence != null) {
return@handler
private val attackHandler = sequenceHandler<AttackEntityEvent> { event ->
if (event.isCancelled || !shouldOperate(event.entity) || !shouldStopSprinting(event)) {
return@sequenceHandler
}

runWithDummyEvent {
it.waitTicks(ticksUntilMovementBlock.random())
stopMoving = true
it.waitUntil { !player.input.hasForwardMovement() }
it.waitTicks(ticksUntilAllowedMovement.random())
stopMoving = false
waitTicks(ticksUntilMovementBlock.random())
cancelMovement = true
waitUntil { !player.input.hasForwardMovement() }
waitTicks(ticksUntilAllowedMovement.random())
cancelMovement = false
}

@Suppress("unused")
private val movementHandler = handler<MovementInputEvent> { event ->
if (cancelMovement) {
event.directionalInput = DirectionalInput.NONE
}
}
}

fun shouldBlockSprinting() = running && SprintTap.isSelected && SprintTap.antiSprint
override fun disable() {
cancelMovement = false
super.disable()
}

fun shouldStopMoving() = running && WTap.isSelected && WTap.stopMoving
}

private fun shouldStopSprinting(event: AttackEntityEvent): Boolean {
val enemy = event.entity
Expand Down Expand Up @@ -201,20 +201,4 @@ object ModuleSuperKnockback : ClientModule("SuperKnockback", Category.COMBAT, al
return true
}

private fun reset() {
sequence?.cancel()
sequence = null

WTap.stopMoving = false
SprintTap.antiSprint = false
}

private fun runWithDummyEvent(action: suspend (Sequence<DummyEvent>) -> Unit) {
sequence = Sequence(this, {
action(this)
}, DummyEvent)

sequence = null
}

}
Loading

0 comments on commit a7a1d5a

Please sign in to comment.