From a1710d4831cc22a61887d26c98a42367d4376450 Mon Sep 17 00:00:00 2001 From: chri-k Date: Sun, 8 Jun 2025 23:20:54 +0300 Subject: [PATCH 1/9] freecam: add new modes --- .../meteorclient/mixin/EntityMixin.java | 6 +- .../meteorclient/mixin/GameRendererMixin.java | 10 +- .../systems/modules/render/Freecam.java | 154 +++++++++++++++++- 3 files changed, 154 insertions(+), 16 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/EntityMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/EntityMixin.java index 85933cd36a..f5c5b0c6b8 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/EntityMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/EntityMixin.java @@ -212,8 +212,10 @@ private void updateChangeLookDirection(double cursorDeltaX, double cursorDeltaY, FreeLook freeLook = Modules.get().get(FreeLook.class); if (freecam.isActive()) { - freecam.changeLookDirection(cursorDeltaX * 0.15, cursorDeltaY * 0.15); - ci.cancel(); + if (!freecam.getOverride()) { + freecam.changeLookDirection(cursorDeltaX * 0.15, cursorDeltaY * 0.15); + ci.cancel(); + } } else if (Modules.get().isActive(HighwayBuilder.class)) { Camera camera = mc.gameRenderer.getCamera(); diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/GameRendererMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/GameRendererMixin.java index da47a1b032..274b736321 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/GameRendererMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/GameRendererMixin.java @@ -167,7 +167,7 @@ private void updateTargetedEntityInvoke(float tickDelta, CallbackInfo info) { Freecam freecam = Modules.get().get(Freecam.class); boolean highwayBuilder = Modules.get().isActive(HighwayBuilder.class); - if ((freecam.isActive() || highwayBuilder) && client.getCameraEntity() != null && !freecamSet) { + if (((freecam.isActive() && !freecam.getOverride()) || highwayBuilder) && client.getCameraEntity() != null && !freecamSet) { info.cancel(); Entity cameraE = client.getCameraEntity(); @@ -186,10 +186,10 @@ private void updateTargetedEntityInvoke(float tickDelta, CallbackInfo info) { cameraE.setYaw(camera.getYaw()); cameraE.setPitch(camera.getPitch()); } else { - ((IVec3d) cameraE.getPos()).meteor$set(freecam.pos.x, freecam.pos.y - cameraE.getEyeHeight(cameraE.getPose()), freecam.pos.z); - cameraE.lastX = freecam.prevPos.x; - cameraE.lastY = freecam.prevPos.y - cameraE.getEyeHeight(cameraE.getPose()); - cameraE.lastZ = freecam.prevPos.z; + ((IVec3d) cameraE.getPos()).meteor$set(freecam.getX(1), freecam.getY(1) - cameraE.getEyeHeight(cameraE.getPose()), freecam.getZ(1)); + cameraE.lastX = freecam.getX(0); + cameraE.lastY = freecam.getY(0) - cameraE.getEyeHeight(cameraE.getPose()); + cameraE.lastZ = freecam.getZ(0); cameraE.setYaw(freecam.yaw); cameraE.setPitch(freecam.pitch); cameraE.lastYaw = freecam.lastYaw; diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java index e642520fee..35f9506e30 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java @@ -14,20 +14,19 @@ import meteordevelopment.meteorclient.events.packets.PacketEvent; import meteordevelopment.meteorclient.events.world.ChunkOcclusionEvent; import meteordevelopment.meteorclient.events.world.TickEvent; -import meteordevelopment.meteorclient.settings.BoolSetting; -import meteordevelopment.meteorclient.settings.DoubleSetting; -import meteordevelopment.meteorclient.settings.Setting; -import meteordevelopment.meteorclient.settings.SettingGroup; +import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.systems.modules.Modules; import meteordevelopment.meteorclient.systems.modules.movement.GUIMove; import meteordevelopment.meteorclient.utils.Utils; +import meteordevelopment.meteorclient.utils.misc.Keybind; import meteordevelopment.meteorclient.utils.misc.input.Input; import meteordevelopment.meteorclient.utils.misc.input.KeyAction; import meteordevelopment.meteorclient.utils.player.Rotations; import meteordevelopment.orbit.EventHandler; import meteordevelopment.orbit.EventPriority; +import net.minecraft.client.option.KeyBinding; import net.minecraft.client.option.Perspective; import net.minecraft.entity.Entity; import net.minecraft.network.packet.s2c.play.DeathMessageS2CPacket; @@ -42,6 +41,7 @@ public class Freecam extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); + private final SettingGroup sgControl = settings.createGroup("Controls"); private final Setting speed = sgGeneral.add(new DoubleSetting.Builder() .name("speed") @@ -117,8 +117,42 @@ public class Freecam extends Module { .build() ); - public final Vector3d pos = new Vector3d(); - public final Vector3d prevPos = new Vector3d(); + private final Setting relativePos = sgGeneral.add(new BoolSetting.Builder() + .name("relative") + .description("Camera moves along with the player") + .defaultValue(false) + .onChanged(this::onRelativeToggle) + .build() + ); + + private final Setting relativeBind = sgControl.add(new KeybindSetting.Builder() + .name("toggle-relative") + .description("Press this bind to toggle the relative setting (bind will not trigger other actions)") + .build() + ); + + private final Setting returnBind = sgControl.add(new KeybindSetting.Builder() + .name("return") + .description("Press this bind to return camera to player (bind will not trigger other actions)") + .build() + ); + + private final Setting overrideBind = sgControl.add(new KeybindSetting.Builder() + .name("switch-control") + .description("Press this bind to switch control between player and camera (bind will not trigger other actions)") + .build() + ); + + private final Setting overrideBindHold = sgControl.add(new BoolSetting.Builder() + .name("switch-back-on-release") + .description("Switch control back when bind is released") + .defaultValue(true) + .build() + ); + + // Will be relative to player if relativePos is set + private final Vector3d pos = new Vector3d(); + private final Vector3d prevPos = new Vector3d(); private Perspective perspective; private double speedValue; @@ -131,6 +165,8 @@ public class Freecam extends Module { private boolean forward, backward, right, left, up, down, isSneaking; + private boolean override = false; + public Freecam() { super(Categories.Render, "freecam", "Allows the camera to move away from the player."); } @@ -169,8 +205,11 @@ public void onActivate() { up = mc.options.jumpKey.isPressed(); down = mc.options.sneakKey.isPressed(); + override = false; + unpress(); if (reloadChunks.get()) mc.worldRenderer.reload(); + resetCamera(); } @Override @@ -277,12 +316,44 @@ private void onTick(TickEvent.Post event) { prevPos.set(pos); pos.set(pos.x + velX, pos.y + velY, pos.z + velZ); + if (relativePos.get()) { + Vec3d delta = mc.player.getPos().subtract(mc.player.getLastRenderPos()); + prevPos.sub(delta.x, delta.y, delta.z); + } + } + + // Shadow other keybinds to not waste keyboard space when freecam is off + @EventHandler(priority = EventPriority.HIGHEST) + public void onKeyHigh(KeyEvent event) { + + if (mc.options.chatKey.matchesKey(event.key, 0)) return; + if (KeyBinding.byId("key.meteor-client.open-gui").matchesKey(event.key, 0)) return; + + if (checkGuiMove()) return; + if (handleOverrideBind()) event.cancel(); + if (override) return; + if (handleReturnBind()) event.cancel(); + if (handleRelativeBind()) event.cancel(); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void onMouseButtonHigh(MouseButtonEvent event) { + + if (mc.options.chatKey.matchesMouse(event.button)) return; + if (KeyBinding.byId("key.meteor-client.open-gui").matchesMouse(event.button)) return; + + if (checkGuiMove()) return; + if (handleOverrideBind()) event.cancel(); + if (override) return; + if (handleReturnBind()) event.cancel(); + if (handleRelativeBind()) event.cancel(); } @EventHandler public void onKey(KeyEvent event) { if (Input.isKeyPressed(GLFW.GLFW_KEY_F3)) return; if (checkGuiMove()) return; + if (override) return; boolean cancel = true; @@ -320,6 +391,7 @@ else if (mc.options.sneakKey.matchesKey(event.key, 0)) { @EventHandler private void onMouseButton(MouseButtonEvent event) { if (checkGuiMove()) return; + if (override) return; boolean cancel = true; @@ -356,6 +428,8 @@ else if (mc.options.sneakKey.matchesMouse(event.button)) { @EventHandler(priority = EventPriority.LOW) private void onMouseScroll(MouseScrollEvent event) { + if (override) return; + if (speedScrollSensitivity.get() > 0 && mc.currentScreen == null) { speedValue += event.value * 0.25 * (speedScrollSensitivity.get() * speedValue); if (speedValue < 0.1) speedValue = 0.1; @@ -393,6 +467,17 @@ else if (event.packet instanceof HealthUpdateS2CPacket packet) { } } + private void onRelativeToggle(boolean relative) { + if (mc.cameraEntity == null) return; + if (relative) { + pos.sub(mc.cameraEntity.getX(), mc.cameraEntity.getY(), mc.cameraEntity.getZ()); + prevPos.sub(mc.cameraEntity.getX(), mc.cameraEntity.getY(), mc.cameraEntity.getZ()); + } else { + pos.add(mc.cameraEntity.getX(), mc.cameraEntity.getY(), mc.cameraEntity.getZ()); + prevPos.add(mc.cameraEntity.getX(), mc.cameraEntity.getY(), mc.cameraEntity.getZ()); + } + } + private boolean checkGuiMove() { // TODO: This is very bad but you all can cope :cope: GUIMove guiMove = Modules.get().get(GUIMove.class); @@ -400,6 +485,45 @@ private boolean checkGuiMove() { return (mc.currentScreen != null && guiMove.isActive() && guiMove.skip()); } + private void resetCamera() { + if (mc.cameraEntity == null) return; + if (relativePos.get()) pos.set(0, mc.cameraEntity.getEyeHeight(mc.cameraEntity.getPose()), 0); + else pos.set(mc.cameraEntity.getX(), mc.cameraEntity.getEyeY(), mc.cameraEntity.getZ()); + pitch = mc.cameraEntity.getPitch(); + yaw = mc.cameraEntity.getYaw(); + + prevPos.set(pos); + lastYaw = yaw; + lastPitch = pitch; + } + + private boolean overrideBindIsHeld = false; + private boolean handleOverrideBind() { + if (overrideBindIsHeld == overrideBind.get().isPressed()) return false; + overrideBindIsHeld = overrideBind.get().isPressed(); + if (overrideBindIsHeld || (overrideBindHold.get() && !overrideBindIsHeld)) { + up = down = left = right = forward = backward = false; + override ^= true; + } + return true; + } + + private boolean returnBindIsHeld = false; + private boolean handleReturnBind() { + boolean changed = returnBindIsHeld != returnBind.get().isPressed(); + returnBindIsHeld = returnBind.get().isPressed(); + if (changed && returnBindIsHeld) resetCamera(); + return changed; + } + + private boolean relativeBindIsHeld = false; + private boolean handleRelativeBind() { + boolean changed = relativeBindIsHeld != relativeBind.get().isPressed(); + relativeBindIsHeld = relativeBind.get().isPressed(); + if (changed && relativeBindIsHeld) relativePos.set(!relativePos.get()); + return changed; + } + public void changeLookDirection(double deltaX, double deltaY) { lastYaw = yaw; lastPitch = pitch; @@ -419,19 +543,31 @@ public boolean staySneaking() { } public double getX(float tickDelta) { - return MathHelper.lerp(tickDelta, prevPos.x, pos.x); + double x = MathHelper.lerp(tickDelta, prevPos.x, pos.x); + if (relativePos.get()) x += mc.cameraEntity.getX(); + return x; } public double getY(float tickDelta) { - return MathHelper.lerp(tickDelta, prevPos.y, pos.y); + double y = MathHelper.lerp(tickDelta, prevPos.y, pos.y); + if (relativePos.get()) y += mc.cameraEntity.getY(); + return y; } public double getZ(float tickDelta) { - return MathHelper.lerp(tickDelta, prevPos.z, pos.z); + double z = MathHelper.lerp(tickDelta, prevPos.z, pos.z); + if (relativePos.get()) z += mc.cameraEntity.getZ(); + return z; } public double getYaw(float tickDelta) { + if (override || !mc.isWindowFocused()) return yaw; return MathHelper.lerp(tickDelta, lastYaw, yaw); } public double getPitch(float tickDelta) { + if (override || !mc.isWindowFocused()) return pitch; return MathHelper.lerp(tickDelta, lastPitch, pitch); } + + public boolean getOverride() { + return override; + } } From 4241674a3d2c8505b2e0edaf14feb6883249ab63 Mon Sep 17 00:00:00 2001 From: chri-k Date: Sun, 8 Jun 2025 23:54:05 +0300 Subject: [PATCH 2/9] freecam: option to preserve crosshair target --- .../meteorclient/mixin/GameRendererMixin.java | 2 +- .../meteorclient/systems/modules/render/Freecam.java | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/GameRendererMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/GameRendererMixin.java index 274b736321..b87550f029 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/GameRendererMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/GameRendererMixin.java @@ -167,7 +167,7 @@ private void updateTargetedEntityInvoke(float tickDelta, CallbackInfo info) { Freecam freecam = Modules.get().get(Freecam.class); boolean highwayBuilder = Modules.get().isActive(HighwayBuilder.class); - if (((freecam.isActive() && !freecam.getOverride()) || highwayBuilder) && client.getCameraEntity() != null && !freecamSet) { + if ((freecam.shouldChangeCrosshairTarget() || highwayBuilder) && client.getCameraEntity() != null && !freecamSet) { info.cancel(); Entity cameraE = client.getCameraEntity(); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java index 35f9506e30..cc4d6fe0ab 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java @@ -68,6 +68,13 @@ public class Freecam extends Module { .build() ); + private final Setting preserveTarget = sgGeneral.add(new BoolSetting.Builder() + .name("preserve-crosshair-target") + .description("Target the block the player is looking at instead of the block the camera is looking at") + .defaultValue(false) + .build() + ); + private final Setting toggleOnDamage = sgGeneral.add(new BoolSetting.Builder() .name("toggle-on-damage") .description("Disables freecam when you take damage.") @@ -570,4 +577,8 @@ public double getPitch(float tickDelta) { public boolean getOverride() { return override; } + + public boolean shouldChangeCrosshairTarget() { + return isActive() && !override && !preserveTarget.get(); + } } From 1eff06293ee209681e30fbb75e2940bbef0ad7cf Mon Sep 17 00:00:00 2001 From: chri-k Date: Mon, 9 Jun 2025 00:07:08 +0300 Subject: [PATCH 3/9] [fix] freecam: weird interaction with rotate --- .../meteorclient/systems/modules/render/Freecam.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java index cc4d6fe0ab..92e3b1d4d8 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java @@ -264,7 +264,7 @@ private void onTick(TickEvent.Post event) { double velY = 0; double velZ = 0; - if (rotate.get()) { + if (rotate.get() && shouldChangeCrosshairTarget()) { BlockPos crossHairPos; Vec3d crossHairPosition; From 064bbdd79dc988007b34794def51d4537cf70a3a Mon Sep 17 00:00:00 2001 From: chri-k Date: Sat, 2 Aug 2025 18:52:40 +0300 Subject: [PATCH 4/9] [fix] targeting --- .../meteorclient/mixin/GameRendererMixin.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/GameRendererMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/GameRendererMixin.java index b59d3237ec..730d43ad9b 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/GameRendererMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/GameRendererMixin.java @@ -192,13 +192,14 @@ private void updateTargetedEntityInvoke(float tickDelta, CallbackInfo info) { cameraE.setPitch(camera.getPitch()); } else { ((IVec3d) cameraE.getPos()).meteor$set(freecam.getX(1), freecam.getY(1) - cameraE.getEyeHeight(cameraE.getPose()), freecam.getZ(1)); - cameraE.lastX = freecam.getX(0); - cameraE.lastY = freecam.getY(0) - cameraE.getEyeHeight(cameraE.getPose()); - cameraE.lastZ = freecam.getZ(0); + cameraE.lastX = freecam.getX(1); + cameraE.lastY = freecam.getY(1) - cameraE.getEyeHeight(cameraE.getPose()); + cameraE.lastZ = freecam.getZ(1); cameraE.setYaw(freecam.yaw); cameraE.setPitch(freecam.pitch); - cameraE.lastYaw = freecam.lastYaw; - cameraE.lastPitch = freecam.lastPitch; + cameraE.lastYaw = freecam.yaw; + cameraE.lastPitch = freecam.pitch; + tickDelta = 1; } freecamSet = true; From 7d1b1355f51510de5595340ed8a4f5a36262fb77 Mon Sep 17 00:00:00 2001 From: chri-k Date: Sat, 2 Aug 2025 19:30:47 +0300 Subject: [PATCH 5/9] Freecam.withPos() --- .../meteorclient/mixin/GameRendererMixin.java | 42 ++------- .../systems/modules/render/Freecam.java | 94 +++++++++++++++++++ 2 files changed, 104 insertions(+), 32 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/mixin/GameRendererMixin.java b/src/main/java/meteordevelopment/meteorclient/mixin/GameRendererMixin.java index 730d43ad9b..af6728a69d 100644 --- a/src/main/java/meteordevelopment/meteorclient/mixin/GameRendererMixin.java +++ b/src/main/java/meteordevelopment/meteorclient/mixin/GameRendererMixin.java @@ -176,44 +176,22 @@ private void updateTargetedEntityInvoke(float tickDelta, CallbackInfo info) { info.cancel(); Entity cameraE = client.getCameraEntity(); - double x = cameraE.getX(); - double y = cameraE.getY(); - double z = cameraE.getZ(); - double lastX = cameraE.lastX; - double lastY = cameraE.lastY; - double lastZ = cameraE.lastZ; - float yaw = cameraE.getYaw(); - float pitch = cameraE.getPitch(); - float lastYaw = cameraE.lastYaw; - float lastPitch = cameraE.lastPitch; - + freecamSet = true; if (highwayBuilder) { + float yaw = cameraE.getYaw(); + float pitch = cameraE.getPitch(); + cameraE.setYaw(camera.getYaw()); cameraE.setPitch(camera.getPitch()); + + updateCrosshairTarget(tickDelta); + + cameraE.setYaw(yaw); + cameraE.setPitch(pitch); } else { - ((IVec3d) cameraE.getPos()).meteor$set(freecam.getX(1), freecam.getY(1) - cameraE.getEyeHeight(cameraE.getPose()), freecam.getZ(1)); - cameraE.lastX = freecam.getX(1); - cameraE.lastY = freecam.getY(1) - cameraE.getEyeHeight(cameraE.getPose()); - cameraE.lastZ = freecam.getZ(1); - cameraE.setYaw(freecam.yaw); - cameraE.setPitch(freecam.pitch); - cameraE.lastYaw = freecam.yaw; - cameraE.lastPitch = freecam.pitch; - tickDelta = 1; + Freecam.withPos(() -> updateCrosshairTarget(tickDelta)); } - - freecamSet = true; - updateCrosshairTarget(tickDelta); freecamSet = false; - - ((IVec3d) cameraE.getPos()).meteor$set(x, y, z); - cameraE.lastX = lastX; - cameraE.lastY = lastY; - cameraE.lastZ = lastZ; - cameraE.setYaw(yaw); - cameraE.setPitch(pitch); - cameraE.lastYaw = lastYaw; - cameraE.lastPitch = lastPitch; } } diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java index 0eb0a55b8e..289cc96793 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java @@ -6,6 +6,7 @@ package meteordevelopment.meteorclient.systems.modules.render; +import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.events.game.GameLeftEvent; import meteordevelopment.meteorclient.events.game.OpenScreenEvent; import meteordevelopment.meteorclient.events.meteor.KeyEvent; @@ -14,6 +15,7 @@ import meteordevelopment.meteorclient.events.packets.PacketEvent; import meteordevelopment.meteorclient.events.world.ChunkOcclusionEvent; import meteordevelopment.meteorclient.events.world.TickEvent; +import meteordevelopment.meteorclient.mixininterface.IVec3d; import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; @@ -21,6 +23,7 @@ import meteordevelopment.meteorclient.systems.modules.movement.GUIMove; import meteordevelopment.meteorclient.utils.Utils; import meteordevelopment.meteorclient.utils.misc.Keybind; +import meteordevelopment.meteorclient.utils.misc.Producer; import meteordevelopment.meteorclient.utils.misc.input.Input; import meteordevelopment.meteorclient.utils.misc.input.KeyAction; import meteordevelopment.meteorclient.utils.player.Rotations; @@ -33,12 +36,15 @@ import net.minecraft.network.packet.s2c.play.HealthUpdateS2CPacket; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.EntityHitResult; +import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import org.joml.Vector3d; import org.lwjgl.glfw.GLFW; +import java.util.concurrent.Callable; + public class Freecam extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); private final SettingGroup sgControl = settings.createGroup("Controls"); @@ -564,6 +570,94 @@ public double getZ(float tickDelta) { if (relativePos.get()) z += mc.cameraEntity.getZ(); return z; } + public Vec3d getPos(float tickDelta) { + return new Vec3d(getX(tickDelta), getY(tickDelta), getZ(tickDelta)); + } + public Vec3d getPos() { + return new Vec3d(getX(1), getY(1), getZ(1)); + } + + static public R withPos(Producer c) { + Freecam f = Modules.get().get(Freecam.class); + + Entity cameraE = MeteorClient.mc.getCameraEntity(); + + if (!f.shouldChangeCrosshairTarget()) return c.create(); + + double x = cameraE.getX(); + double y = cameraE.getY(); + double z = cameraE.getZ(); + double lastX = cameraE.lastX; + double lastY = cameraE.lastY; + double lastZ = cameraE.lastZ; + float yaw = cameraE.getYaw(); + float pitch = cameraE.getPitch(); + float lastYaw = cameraE.lastYaw; + float lastPitch = cameraE.lastPitch; + + cameraE.lastX = f.getX(1); + cameraE.lastY = f.getY(1) - cameraE.getEyeHeight(cameraE.getPose()); + cameraE.lastZ = f.getZ(1); + cameraE.setYaw(yaw); + cameraE.setPitch(pitch); + cameraE.lastYaw = yaw; + cameraE.lastPitch = pitch; + + R r = c.create(); + + ((IVec3d) cameraE.getPos()).meteor$set(x, y, z); + cameraE.lastX = lastX; + cameraE.lastY = lastY; + cameraE.lastZ = lastZ; + cameraE.setYaw(yaw); + cameraE.setPitch(pitch); + cameraE.lastYaw = lastYaw; + cameraE.lastPitch = lastPitch; + + return r; + } + + static public void withPos(Runnable c) { + Freecam f = Modules.get().get(Freecam.class); + + Entity cameraE = MeteorClient.mc.getCameraEntity(); + + if (!f.shouldChangeCrosshairTarget()) { + c.run(); + return; + } + + double x = cameraE.getX(); + double y = cameraE.getY(); + double z = cameraE.getZ(); + double lastX = cameraE.lastX; + double lastY = cameraE.lastY; + double lastZ = cameraE.lastZ; + float yaw = cameraE.getYaw(); + float pitch = cameraE.getPitch(); + float lastYaw = cameraE.lastYaw; + float lastPitch = cameraE.lastPitch; + + cameraE.lastX = f.getX(1); + cameraE.lastY = f.getY(1) - cameraE.getEyeHeight(cameraE.getPose()); + cameraE.lastZ = f.getZ(1); + cameraE.setYaw(yaw); + cameraE.setPitch(pitch); + cameraE.lastYaw = yaw; + cameraE.lastPitch = pitch; + + c.run(); + + ((IVec3d) cameraE.getPos()).meteor$set(x, y, z); + cameraE.lastX = lastX; + cameraE.lastY = lastY; + cameraE.lastZ = lastZ; + cameraE.setYaw(yaw); + cameraE.setPitch(pitch); + cameraE.lastYaw = lastYaw; + cameraE.lastPitch = lastPitch; + } + public double getYaw(float tickDelta) { if (override || !mc.isWindowFocused()) return yaw; From a4f6c0bea1fea5a14f86b83d446b1a4ead523710 Mon Sep 17 00:00:00 2001 From: chri-k Date: Sat, 2 Aug 2025 22:00:53 +0300 Subject: [PATCH 6/9] [fix] air-place --- .../systems/modules/player/AirPlace.java | 11 +++++- .../systems/modules/render/Freecam.java | 38 +++++++++++-------- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AirPlace.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AirPlace.java index d617e40295..cf03acb7f1 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AirPlace.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AirPlace.java @@ -5,12 +5,17 @@ package meteordevelopment.meteorclient.systems.modules.player; +import com.terraformersmc.modmenu.util.mod.Mod; +import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.events.render.Render3DEvent; import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.renderer.ShapeMode; import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.systems.modules.Modules; +import meteordevelopment.meteorclient.systems.modules.render.Freecam; +import meteordevelopment.meteorclient.utils.render.color.Color; import meteordevelopment.meteorclient.utils.render.color.SettingColor; import meteordevelopment.meteorclient.utils.world.BlockUtils; import meteordevelopment.orbit.EventHandler; @@ -19,6 +24,10 @@ import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.Box; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.BlockStateRaycastContext; +import net.minecraft.world.RaycastContext; public class AirPlace extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); @@ -82,7 +91,7 @@ public AirPlace() { @EventHandler private void onTick(TickEvent.Post event) { double r = customRange.get() ? range.get() : mc.player.getBlockInteractionRange(); - hitResult = mc.getCameraEntity().raycast(r, 0, false); + hitResult = Freecam.withPos(() -> mc.getCameraEntity().raycast(r, 0, false)); if (!(hitResult instanceof BlockHitResult blockHitResult) || !(mc.player.getMainHandStack().getItem() instanceof BlockItem) && !(mc.player.getMainHandStack().getItem() instanceof SpawnEggItem)) return; diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java index 289cc96793..073da2faae 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java @@ -580,7 +580,7 @@ public Vec3d getPos() { static public R withPos(Producer c) { Freecam f = Modules.get().get(Freecam.class); - Entity cameraE = MeteorClient.mc.getCameraEntity(); + Entity cameraE = MeteorClient.mc.cameraEntity; if (!f.shouldChangeCrosshairTarget()) return c.create(); @@ -595,13 +595,16 @@ static public R withPos(Producer c) { float lastYaw = cameraE.lastYaw; float lastPitch = cameraE.lastPitch; - cameraE.lastX = f.getX(1); - cameraE.lastY = f.getY(1) - cameraE.getEyeHeight(cameraE.getPose()); - cameraE.lastZ = f.getZ(1); - cameraE.setYaw(yaw); - cameraE.setPitch(pitch); - cameraE.lastYaw = yaw; - cameraE.lastPitch = pitch; + Vec3d lastPos = f.getPos(0); + + ((IVec3d) cameraE.getPos()).meteor$set(f.getX(1), f.getY(1) - cameraE.getEyeHeight(cameraE.getPose()), f.getZ(1)); + cameraE.lastX = lastPos.x; + cameraE.lastY = lastPos.y - cameraE.getEyeHeight(cameraE.getPose()); + cameraE.lastZ = lastPos.z; + cameraE.setYaw(f.yaw); + cameraE.setPitch(f.pitch); + cameraE.lastYaw = f.lastYaw; + cameraE.lastPitch = f.lastPitch; R r = c.create(); @@ -620,7 +623,7 @@ static public R withPos(Producer c) { static public void withPos(Runnable c) { Freecam f = Modules.get().get(Freecam.class); - Entity cameraE = MeteorClient.mc.getCameraEntity(); + Entity cameraE = MeteorClient.mc.cameraEntity; if (!f.shouldChangeCrosshairTarget()) { c.run(); @@ -638,13 +641,16 @@ static public void withPos(Runnable c) { float lastYaw = cameraE.lastYaw; float lastPitch = cameraE.lastPitch; - cameraE.lastX = f.getX(1); - cameraE.lastY = f.getY(1) - cameraE.getEyeHeight(cameraE.getPose()); - cameraE.lastZ = f.getZ(1); - cameraE.setYaw(yaw); - cameraE.setPitch(pitch); - cameraE.lastYaw = yaw; - cameraE.lastPitch = pitch; + Vec3d lastPos = f.getPos(0); + + ((IVec3d) cameraE.getPos()).meteor$set(f.getX(1), f.getY(1) - cameraE.getEyeHeight(cameraE.getPose()), f.getZ(1)); + cameraE.lastX = lastPos.x; + cameraE.lastY = lastPos.y - cameraE.getEyeHeight(cameraE.getPose()); + cameraE.lastZ = lastPos.z; + cameraE.setYaw(f.yaw); + cameraE.setPitch(f.pitch); + cameraE.lastYaw = f.lastYaw; + cameraE.lastPitch = f.lastPitch; c.run(); From 4f7bd163af43426d06940d7e00d68882f46e87d9 Mon Sep 17 00:00:00 2001 From: chri-k Date: Sun, 12 Oct 2025 17:49:01 +0300 Subject: [PATCH 7/9] [cleanup] silly code deduplication --- .../systems/modules/render/Freecam.java | 42 +------------------ 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java index 073da2faae..c882676c36 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java @@ -621,47 +621,7 @@ static public R withPos(Producer c) { } static public void withPos(Runnable c) { - Freecam f = Modules.get().get(Freecam.class); - - Entity cameraE = MeteorClient.mc.cameraEntity; - - if (!f.shouldChangeCrosshairTarget()) { - c.run(); - return; - } - - double x = cameraE.getX(); - double y = cameraE.getY(); - double z = cameraE.getZ(); - double lastX = cameraE.lastX; - double lastY = cameraE.lastY; - double lastZ = cameraE.lastZ; - float yaw = cameraE.getYaw(); - float pitch = cameraE.getPitch(); - float lastYaw = cameraE.lastYaw; - float lastPitch = cameraE.lastPitch; - - Vec3d lastPos = f.getPos(0); - - ((IVec3d) cameraE.getPos()).meteor$set(f.getX(1), f.getY(1) - cameraE.getEyeHeight(cameraE.getPose()), f.getZ(1)); - cameraE.lastX = lastPos.x; - cameraE.lastY = lastPos.y - cameraE.getEyeHeight(cameraE.getPose()); - cameraE.lastZ = lastPos.z; - cameraE.setYaw(f.yaw); - cameraE.setPitch(f.pitch); - cameraE.lastYaw = f.lastYaw; - cameraE.lastPitch = f.lastPitch; - - c.run(); - - ((IVec3d) cameraE.getPos()).meteor$set(x, y, z); - cameraE.lastX = lastX; - cameraE.lastY = lastY; - cameraE.lastZ = lastZ; - cameraE.setYaw(yaw); - cameraE.setPitch(pitch); - cameraE.lastYaw = lastYaw; - cameraE.lastPitch = lastPitch; + withPos(() -> { c.run(); return null; }); // this is silly } From 82cec7d7a8cc7f8f2142305ac08e0917d85ac203 Mon Sep 17 00:00:00 2001 From: chri-k Date: Sun, 12 Oct 2025 17:50:18 +0300 Subject: [PATCH 8/9] [cleanup] whitespace --- .../meteorclient/systems/modules/render/Freecam.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java index c882676c36..fc12791fea 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java @@ -623,8 +623,7 @@ static public R withPos(Producer c) { static public void withPos(Runnable c) { withPos(() -> { c.run(); return null; }); // this is silly } - - + public double getYaw(float tickDelta) { if (override || !mc.isWindowFocused()) return yaw; return MathHelper.lerp(tickDelta, lastYaw, yaw); From b12d7ba3f7f0539c8e93d4e53aee8523493471e2 Mon Sep 17 00:00:00 2001 From: chri-k Date: Sun, 12 Oct 2025 18:14:47 +0300 Subject: [PATCH 9/9] [feat] ignore-shift-in-GUI --- .../systems/modules/render/Freecam.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java index fc12791fea..487c81c38f 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Freecam.java @@ -36,15 +36,12 @@ import net.minecraft.network.packet.s2c.play.HealthUpdateS2CPacket; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.EntityHitResult; -import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import org.joml.Vector3d; import org.lwjgl.glfw.GLFW; -import java.util.concurrent.Callable; - public class Freecam extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); private final SettingGroup sgControl = settings.createGroup("Controls"); @@ -74,6 +71,13 @@ public class Freecam extends Module { .build() ); + private final Setting ignoreShift = sgControl.add(new BoolSetting.Builder() + .name("ignore-shift-in-GUI") + .description("Ignore left shift in GUIs. (only significant if GUI-move is on)") + .defaultValue(true) + .build() + ); + private final Setting preserveTarget = sgGeneral.add(new BoolSetting.Builder() .name("preserve-crosshair-target") .description("Target the block the player is looking at instead of the block the camera is looking at") @@ -368,6 +372,9 @@ public void onKey(KeyEvent event) { if (checkGuiMove()) return; if (override) return; + // ignore shift specifically and not sneak, since that is hard-coded + if (ignoreShift.get() && mc.currentScreen != null && event.key == GLFW.GLFW_KEY_LEFT_SHIFT) return; + boolean cancel = true; if (mc.options.forwardKey.matchesKey(event.key, 0)) { @@ -623,7 +630,7 @@ static public R withPos(Producer c) { static public void withPos(Runnable c) { withPos(() -> { c.run(); return null; }); // this is silly } - + public double getYaw(float tickDelta) { if (override || !mc.isWindowFocused()) return yaw; return MathHelper.lerp(tickDelta, lastYaw, yaw); @@ -640,4 +647,10 @@ public boolean getOverride() { public boolean shouldChangeCrosshairTarget() { return isActive() && !override && !preserveTarget.get(); } + + enum GUIMoveMode { + Completely, + Shift, + None + } }