Skip to content

Commit e80368d

Browse files
committed
Fix freecam causing a stuck loading screen when changing dimensions
1 parent 3fc5d5c commit e80368d

3 files changed

Lines changed: 65 additions & 0 deletions

File tree

src/main/java/com/lambda/mixin/network/ClientPlayNetworkHandlerMixin.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,27 @@
2020
import com.lambda.event.EventFlow;
2121
import com.lambda.event.events.ChatEvent;
2222
import com.lambda.event.events.InventoryEvent;
23+
import com.lambda.event.events.PlayerEvent;
2324
import com.lambda.event.events.WorldEvent;
2425
import com.lambda.interaction.managers.inventory.InventoryManager;
2526
import com.lambda.module.modules.movement.Velocity;
2627
import com.lambda.module.modules.render.NoRender;
2728
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
2829
import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod;
2930
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
31+
import net.minecraft.client.MinecraftClient;
3032
import net.minecraft.client.network.ClientPlayNetworkHandler;
3133
import net.minecraft.client.network.PlayerListEntry;
34+
import net.minecraft.entity.Entity;
35+
import net.minecraft.entity.EntityPosition;
3236
import net.minecraft.network.packet.s2c.play.*;
3337
import org.spongepowered.asm.mixin.Mixin;
3438
import org.spongepowered.asm.mixin.injection.At;
3539
import org.spongepowered.asm.mixin.injection.Inject;
3640
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
41+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
42+
43+
import java.util.Set;
3744

3845
@Mixin(ClientPlayNetworkHandler.class)
3946
public class ClientPlayNetworkHandlerMixin {
@@ -125,4 +132,25 @@ void onSendMessage(String content, Operation<Void> original) {
125132
if (!EventFlow.post(event).isCanceled())
126133
original.call(event.getMessage());
127134
}
135+
136+
@Inject(method = "onPlayerRespawn", at = @At("TAIL"))
137+
void onPlayerRespawn(PlayerRespawnS2CPacket packet, CallbackInfo ci) {
138+
EventFlow.post(new PlayerEvent.World.Respawn(packet));
139+
}
140+
141+
@Inject(method = "onPlayerPositionLook", at = @At("TAIL"))
142+
void onPlayerPositionLook(PlayerPositionLookS2CPacket packet, CallbackInfo ci) {
143+
EventFlow.post(new PlayerEvent.World.PositionLook(packet));
144+
}
145+
146+
@Inject(method = "setPosition", at = @At("TAIL"))
147+
private static void onSetPosition(EntityPosition pos, Set<PositionFlag> flags, Entity entity, boolean bl,
148+
CallbackInfoReturnable<Boolean> cir) {
149+
if (cir.getReturnValue() == false) {
150+
var player = MinecraftClient.getInstance().player;
151+
assert player != null;
152+
var event = new PlayerEvent.World.SetPosition(player.getEntityPos(), player.getVelocity(), player.getYaw(), player.getPitch());
153+
EventFlow.post(event);
154+
}
155+
}
128156
}

src/main/kotlin/com/lambda/event/events/PlayerEvent.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@ package com.lambda.event.events
2020
import com.lambda.event.Event
2121
import com.lambda.event.callback.Cancellable
2222
import com.lambda.event.callback.ICancellable
23+
import net.minecraft.network.packet.s2c.play.PlayerPositionLookS2CPacket
24+
import net.minecraft.network.packet.s2c.play.PlayerRespawnS2CPacket
2325
import net.minecraft.screen.ScreenHandler
2426
import net.minecraft.screen.slot.SlotActionType
2527
import net.minecraft.util.Hand
2628
import net.minecraft.util.hit.BlockHitResult
2729
import net.minecraft.util.hit.EntityHitResult
2830
import net.minecraft.util.math.BlockPos
2931
import net.minecraft.util.math.Direction
32+
import net.minecraft.util.math.Vec3d
3033

3134
/**
3235
* Represents various events that can be triggered by the player during gameplay.
@@ -138,4 +141,21 @@ sealed class PlayerEvent {
138141
val action: SlotActionType,
139142
val screenHandler: ScreenHandler,
140143
) : ICancellable by Cancellable()
144+
145+
sealed class World {
146+
data class Respawn(
147+
val packet: PlayerRespawnS2CPacket
148+
) : Event
149+
150+
data class PositionLook(
151+
val packet: PlayerPositionLookS2CPacket
152+
) : Event
153+
154+
data class SetPosition(
155+
val position: Vec3d,
156+
val velocity: Vec3d,
157+
val yaw: Float,
158+
val pitch: Float
159+
) : Event
160+
}
141161
}

src/main/kotlin/com/lambda/module/modules/player/Freecam.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import com.lambda.interaction.managers.rotating.visibilty.lookAt
3131
import com.lambda.module.Module
3232
import com.lambda.module.tag.ModuleTag
3333
import com.lambda.threading.runSafeAutomated
34+
import com.lambda.util.Communication.info
3435
import com.lambda.util.Describable
3536
import com.lambda.util.NamedEnum
3637
import com.lambda.util.extension.rotation
@@ -83,6 +84,7 @@ object Freecam : Module(
8384

8485
private var rotation: Rotation = Rotation.ZERO
8586
private var velocity: Vec3d = Vec3d.ZERO
87+
private var loading = false
8688

8789
@JvmStatic
8890
fun updateCam() {
@@ -123,6 +125,21 @@ object Freecam : Module(
123125
}
124126
}
125127

128+
listen<PlayerEvent.World.Respawn> {
129+
loading = true
130+
info("Respawned, waiting for position look packet to update freecam position...")
131+
}
132+
133+
listen<PlayerEvent.World.SetPosition> {
134+
info("Received position look packet, updating freecam position")
135+
info("New position: ${it.position}")
136+
if (loading) {
137+
loading = false
138+
position = player.eyePos
139+
rotation = player.rotation
140+
}
141+
}
142+
126143
listen<PlayerEvent.ChangeLookDirection> {
127144
rotation = rotation.withDelta(
128145
it.deltaYaw * SENSITIVITY_FACTOR,

0 commit comments

Comments
 (0)