Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.lambda.event.EventFlow;
import com.lambda.event.events.ChatEvent;
import com.lambda.event.events.InventoryEvent;
import com.lambda.event.events.PlayerEvent;
import com.lambda.event.events.WorldEvent;
import com.lambda.interaction.managers.inventory.InventoryManager;
import com.lambda.module.modules.movement.Velocity;
Expand All @@ -29,15 +30,21 @@
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import net.minecraft.client.MinecraftClient;
import com.llamalad7.mixinextras.sugar.Local;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.PlayerListEntry;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityPosition;
import net.minecraft.entity.Entity;
import net.minecraft.network.packet.s2c.play.*;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import java.util.Set;

@Mixin(ClientPlayNetworkHandler.class)
public class ClientPlayNetworkHandlerMixin {
Expand Down Expand Up @@ -130,6 +137,27 @@ void onSendMessage(String content, Operation<Void> original) {
original.call(event.getMessage());
}

@Inject(method = "onPlayerRespawn", at = @At("TAIL"))
void onPlayerRespawn(PlayerRespawnS2CPacket packet, CallbackInfo ci) {
EventFlow.post(new PlayerEvent.World.Respawn(packet));
}

@Inject(method = "onPlayerPositionLook", at = @At("TAIL"))
void onPlayerPositionLook(PlayerPositionLookS2CPacket packet, CallbackInfo ci) {
EventFlow.post(new PlayerEvent.World.PositionLook(packet));
}

@Inject(method = "setPosition", at = @At("TAIL"))
private static void onSetPosition(EntityPosition pos, Set<PositionFlag> flags, Entity entity, boolean bl,
CallbackInfoReturnable<Boolean> cir) {
if (cir.getReturnValue() == false) {
var player = MinecraftClient.getInstance().player;
assert player != null;
var event = new PlayerEvent.World.SetPosition(player.getEntityPos(), player.getVelocity(), player.getYaw(), player.getPitch());
EventFlow.post(event);
}
}

@Inject(method = "onOverlayMessage", at = @At("HEAD"), cancellable = true)
void onOverlayMessage(OverlayMessageS2CPacket packet, CallbackInfo ci) {
if (NoRender.getNo2b2tActionText() && packet.text().getString().equals("2b2t.org")) {
Expand Down
20 changes: 20 additions & 0 deletions src/main/kotlin/com/lambda/event/events/PlayerEvent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@ package com.lambda.event.events
import com.lambda.event.Event
import com.lambda.event.callback.Cancellable
import com.lambda.event.callback.ICancellable
import net.minecraft.network.packet.s2c.play.PlayerPositionLookS2CPacket
import net.minecraft.network.packet.s2c.play.PlayerRespawnS2CPacket
import net.minecraft.screen.ScreenHandler
import net.minecraft.screen.slot.SlotActionType
import net.minecraft.util.Hand
import net.minecraft.util.hit.BlockHitResult
import net.minecraft.util.hit.EntityHitResult
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction
import net.minecraft.util.math.Vec3d

/**
* Represents various events that can be triggered by the player during gameplay.
Expand Down Expand Up @@ -138,4 +141,21 @@ sealed class PlayerEvent {
val action: SlotActionType,
val screenHandler: ScreenHandler,
) : ICancellable by Cancellable()

sealed class World {
data class Respawn(
val packet: PlayerRespawnS2CPacket
) : Event

data class PositionLook(
val packet: PlayerPositionLookS2CPacket
) : Event

data class SetPosition(
val position: Vec3d,
val velocity: Vec3d,
val yaw: Float,
val pitch: Float
) : Event
}
}
54 changes: 45 additions & 9 deletions src/main/kotlin/com/lambda/module/modules/render/Freecam.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package com.lambda.module.modules.render

import com.lambda.Lambda
import com.lambda.Lambda.mc
import com.lambda.config.AutomationConfig.Companion.setDefaultAutomationConfig
import com.lambda.config.applyEdits
Expand All @@ -28,11 +29,14 @@ import com.lambda.event.events.TickEvent
import com.lambda.event.listener.SafeListener.Companion.listen
import com.lambda.interaction.managers.rotating.IRotationRequest.Companion.rotationRequest
import com.lambda.interaction.managers.rotating.Rotation
import com.lambda.interaction.managers.rotating.RotationConfig
import com.lambda.interaction.managers.rotating.RotationMode
import com.lambda.interaction.managers.rotating.visibilty.lookAt
import com.lambda.module.Module
import com.lambda.module.tag.ModuleTag
import com.lambda.threading.runSafe
import com.lambda.threading.runSafeAutomated
import com.lambda.util.Communication.info
import com.lambda.util.Describable
import com.lambda.util.NamedEnum
import com.lambda.util.extension.rotation
Expand Down Expand Up @@ -73,30 +77,34 @@ object Freecam : Module(
autoDisable = true,
) {
private val mode by setting("Mode", Mode.Free, "Freecam movement mode")
private val speed by setting("Speed", 0.5, 0.1..1.0, 0.1, "Freecam movement speed", unit = "m/s") { mode == Mode.Free }
private val sprint by setting("Sprint Multiplier", 3.0, 0.1..10.0, 0.1, description = "Set below 1.0 to fly slower on sprint.") { mode == Mode.Free }
private val speed by setting("Speed", 0.5, 0.1..1.0, 0.1, "Freecam movement speed", unit = "m/s")
private val reach by setting("Reach", 10.0, 1.0..100.0, 1.0, "Freecam reach distance")
private val rotateMode by setting("Rotate Mode", FreecamRotationMode.None, "Rotation mode").onValueChange { _, it -> if (it == FreecamRotationMode.LookAtTarget) mc.crosshairTarget = BlockHitResult.createMissed(Vec3d.ZERO, Direction.UP, BlockPos.ORIGIN) }
private val relative by setting("Relative", false, "Moves freecam relative to player position") { mode == Mode.Free }.onValueChange { _, it -> if (it) lastPlayerPosition = player.pos }
private val keepYLevel by setting("Keep Y Level", false, "Don't change the camera y-level on player movement") { mode == Mode.Free && relative }
private val rotateMode by setting("Rotate Mode", FreecamRotationMode.None, "Rotation mode")
.onValueChange { _, it -> if (it == FreecamRotationMode.LookAtTarget) mc.crosshairTarget = BlockHitResult.createMissed(Vec3d.ZERO, Direction.UP, BlockPos.ORIGIN) }
private val relative by setting("Relative", false, "Moves freecam relative to player position")
.onValueChange { _, it -> if (it) lastPlayerPosition = player.pos }
private val keepYLevel by setting("Keep Y Level", false, "Don't change the camera y-level on player movement") { relative }

// Follow Player settings
private val followMaxDistance by setting("String Length", 10.0, 2.0..50.0, 0.5, "Maximum distance before the string pulls the camera", unit = "m") { mode == Mode.FollowPlayer }
private val followTrackPlayer by setting("Track Player", false, "Keeps looking at the followed player") { mode == Mode.FollowPlayer }

override val rotationConfig = RotationConfig.Instant(RotationMode.Lock)

private var lastPerspective = Perspective.FIRST_PERSON
private var lastPlayerPosition: Vec3d = Vec3d.ZERO
private var prevPosition: Vec3d = Vec3d.ZERO
private var position: Vec3d = Vec3d.ZERO
private val lerpPos: Vec3d
get() {
val tickProgress = mc.gameRenderer.camera.lastTickProgress
val tickProgress = Lambda.mc.gameRenderer.camera.lastTickProgress
return prevPosition.interpolate(tickProgress, position)
}

private var rotation: Rotation = Rotation.ZERO
private var rotation: Rotation = Rotation.ZERO
private var velocity: Vec3d = Vec3d.ZERO
private var loading = false

@JvmStatic
fun updateCam() {
Expand Down Expand Up @@ -147,12 +155,35 @@ object Freecam : Module(
when (rotateMode) {
FreecamRotationMode.None -> return@listen
FreecamRotationMode.KeepRotation -> rotationRequest { rotation(rotation) }.submit()
FreecamRotationMode.LookAtTarget -> mc.crosshairTarget?.let { rotationRequest { rotation(lookAt(it.pos)) }.submit() }
FreecamRotationMode.LookAtTarget ->
mc.crosshairTarget?.let {
runSafeAutomated {
rotationRequest { rotation(lookAt(it.pos)) }.submit()
}
}
}
}

listen<PlayerEvent.World.Respawn> {
loading = true
info("Respawned, waiting for position look packet to update freecam position...")
}

listen<PlayerEvent.World.SetPosition> {
info("Received position look packet, updating freecam position")
info("New position: ${it.position}")
if (loading) {
loading = false
position = player.eyePos
rotation = player.rotation
}
}

listen<PlayerEvent.ChangeLookDirection> {
rotation = rotation.withDelta(it.deltaYaw * SENSITIVITY_FACTOR, it.deltaPitch * SENSITIVITY_FACTOR)
rotation = rotation.withDelta(
it.deltaYaw * SENSITIVITY_FACTOR,
it.deltaPitch * SENSITIVITY_FACTOR
)
it.cancel()
}

Expand All @@ -173,9 +204,11 @@ object Freecam : Module(
val moveDir = calcMoveRad(rotation.yawF, input.roundedForward, input.roundedStrafing)
var moveVec = movementVector(moveDir, input.verticalMovement) * speed * sprintModifier
if (!input.isInputting) moveVec *= Vec3d(0.0, 1.0, 0.0)

// Apply movement
velocity += moveVec
velocity *= 0.6

// Update position
prevPosition = position
position += velocity
Expand Down Expand Up @@ -225,7 +258,10 @@ object Freecam : Module(
}

listen<RenderEvent.UpdateTarget>({ 1 }) { event -> // Higher priority then RotationManager to run before RotationManager modifies mc.crosshairTarget
mc.crosshairTarget = rotation.rayCast(reach, lerpPos).orMiss // Can't be null (otherwise mc will spam "Null returned as 'hitResult', this shouldn't happen!")
mc.crosshairTarget = rotation
.rayCast(reach, lerpPos)
.orMiss // Can't be null (otherwise mc will spam "Null returned as 'hitResult', this shouldn't happen!")

mc.crosshairTarget?.let { if (it.type != HitResult.Type.MISS) event.cancel() }
}
}
Expand Down