diff --git a/src/main/java/com/v5/mixins/CameraMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/CameraMixin.java similarity index 53% rename from src/main/java/com/v5/mixins/CameraMixin.java rename to src/main/java/com/chattriggers/ctjs/internal/mixins/CameraMixin.java index b2c6df68..234bd829 100644 --- a/src/main/java/com/v5/mixins/CameraMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/CameraMixin.java @@ -1,6 +1,6 @@ -package com.v5.mixins; +package com.chattriggers.ctjs.internal.mixins; -import com.v5.storage.V5MixinStorage; +import com.chattriggers.ctjs.api.client.Client; import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; @@ -25,18 +25,15 @@ public abstract class CameraMixin { @Inject(method = "alignWithEntity", at = @At("TAIL")) private void v5$applyCameraOverride(float partialTick, CallbackInfo ci) { - Object yaw = V5MixinStorage.get("cameraOverrideYaw", null); - Object pitch = V5MixinStorage.get("cameraOverridePitch", null); - if (V5MixinStorage.getBoolean("freelookEnabled", false) - && yaw instanceof Number yawNumber - && pitch instanceof Number pitchNumber) { + Float yaw = Client.getCameraYaw(); + Float pitch = Client.getCameraPitch(); + if (Client.isFreelook() && yaw != null && pitch != null) { LocalPlayer player = Minecraft.getInstance().player; if (player != null) { - float yawRadians = yawNumber.floatValue() * Mth.DEG_TO_RAD; - float pitchRadians = pitchNumber.floatValue() * Mth.DEG_TO_RAD; + float yawRadians = yaw * Mth.DEG_TO_RAD; + float pitchRadians = pitch * Mth.DEG_TO_RAD; float cosPitch = Mth.cos(pitchRadians); - Object storedDistance = V5MixinStorage.get("freelookCameraDistance", 4.0); - double distance = storedDistance instanceof Number number ? Mth.clamp(number.doubleValue(), 1.0, 12.0) : 4.0; + double distance = Client.getFreelookDistance(); Vec3 eyePos = player.getEyePosition(partialTick); this.setPosition(eyePos.add( Mth.sin(yawRadians) * cosPitch * distance, @@ -44,16 +41,12 @@ public abstract class CameraMixin { -Mth.cos(yawRadians) * cosPitch * distance)); } } else { - Object override = V5MixinStorage.get("cameraOverridePos", null); - if (override instanceof Vec3 pos) { - this.setPosition(pos); - } + Vec3 position = Client.getCameraPosition(); + if (position != null) this.setPosition(position); } - if (yaw instanceof Number yawNumber && pitch instanceof Number pitchNumber) { - this.setRotation(yawNumber.floatValue(), pitchNumber.floatValue()); - } + if (yaw != null && pitch != null) this.setRotation(yaw, pitch); - if (V5MixinStorage.getBoolean("freecamEnabled", false)) this.detached = true; + if (Client.isFreecam()) this.detached = true; } } diff --git a/src/main/java/com/chattriggers/ctjs/internal/mixins/ChatComponentMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/ChatComponentMixin.java index 04baf2b7..796d1117 100644 --- a/src/main/java/com/chattriggers/ctjs/internal/mixins/ChatComponentMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/ChatComponentMixin.java @@ -1,5 +1,6 @@ package com.chattriggers.ctjs.internal.mixins; +import com.chattriggers.ctjs.api.client.Client; import com.chattriggers.ctjs.api.message.ChatLib; import net.minecraft.client.gui.components.ChatComponent; import net.minecraft.client.multiplayer.chat.GuiMessage; @@ -11,6 +12,7 @@ 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.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.List; @@ -21,6 +23,16 @@ public class ChatComponentMixin { @Shadow private List allMessages; + @ModifyVariable( + method = "addMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/MessageSignature;Lnet/minecraft/client/multiplayer/chat/GuiMessageSource;Lnet/minecraft/client/multiplayer/chat/GuiMessageTag;)V", + at = @At("HEAD"), + ordinal = 0, + argsOnly = true + ) + private Component v5$addMessage(Component original) { + return Client.processName(original); + } + @Inject(method = "clearMessages", at = @At("TAIL")) private void injectClear(boolean clearHistory, CallbackInfo ci) { ChatLib.INSTANCE.onChatHudClearChat$ctjs(); diff --git a/src/main/java/com/chattriggers/ctjs/internal/mixins/ConnectionMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/ConnectionMixin.java index aa885bb5..8fb2a3ed 100644 --- a/src/main/java/com/chattriggers/ctjs/internal/mixins/ConnectionMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/ConnectionMixin.java @@ -1,14 +1,15 @@ package com.chattriggers.ctjs.internal.mixins; +import com.chattriggers.ctjs.api.triggers.PacketEvent; import com.chattriggers.ctjs.internal.engine.CTEvents; import com.chattriggers.ctjs.api.triggers.TriggerType; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import net.minecraft.network.Connection; +import net.minecraft.network.PacketListener; import net.minecraft.network.protocol.PacketFlow; -import net.minecraft.network.PacketSendListener; import net.minecraft.network.protocol.Packet; -import org.jetbrains.annotations.Nullable; +import net.minecraft.network.protocol.game.ClientboundBundlePacket; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -34,6 +35,15 @@ private void injectHandlePacket(ChannelHandlerContext channelHandlerContext, Pac CTEvents.PACKET_RECEIVED.invoker().receive(packet, ci); } + @Inject(method = "genericsFtw", at = @At("HEAD")) + private static void triggerPacketEvent(Packet packet, PacketListener listener, CallbackInfo ci) { + if (packet instanceof ClientboundBundlePacket bundlePacket) { + bundlePacket.subPackets().forEach(PacketEvent.RECEIVE.invoker()::trigger); + } else { + PacketEvent.RECEIVE.invoker().trigger(packet); + } + } + @Inject( method = "send(Lnet/minecraft/network/protocol/Packet;Lio/netty/channel/ChannelFutureListener;)V", at = @At("HEAD"), diff --git a/src/main/java/com/v5/mixins/ConnectionProxyMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/ConnectionProxyMixin.java similarity index 97% rename from src/main/java/com/v5/mixins/ConnectionProxyMixin.java rename to src/main/java/com/chattriggers/ctjs/internal/mixins/ConnectionProxyMixin.java index e535c710..b2f52911 100644 --- a/src/main/java/com/v5/mixins/ConnectionProxyMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/ConnectionProxyMixin.java @@ -1,4 +1,4 @@ -package com.v5.mixins; +package com.chattriggers.ctjs.internal.mixins; import com.chattriggers.ctjs.api.client.Proxy; import com.chattriggers.ctjs.api.client.ProxyInfo; diff --git a/src/main/java/com/v5/mixins/CrossCollisionBlockMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/CrossCollisionBlockMixin.java similarity index 94% rename from src/main/java/com/v5/mixins/CrossCollisionBlockMixin.java rename to src/main/java/com/chattriggers/ctjs/internal/mixins/CrossCollisionBlockMixin.java index de3ba779..e937e5f2 100644 --- a/src/main/java/com/v5/mixins/CrossCollisionBlockMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/CrossCollisionBlockMixin.java @@ -1,4 +1,4 @@ -package com.v5.mixins; +package com.chattriggers.ctjs.internal.mixins; import net.minecraft.world.level.block.CrossCollisionBlock; import net.minecraft.world.level.block.StainedGlassPaneBlock; diff --git a/src/main/java/com/v5/mixins/EntityRendererMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/EntityRendererMixin.java similarity index 82% rename from src/main/java/com/v5/mixins/EntityRendererMixin.java rename to src/main/java/com/chattriggers/ctjs/internal/mixins/EntityRendererMixin.java index 05fac2d7..1c1954eb 100644 --- a/src/main/java/com/v5/mixins/EntityRendererMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/EntityRendererMixin.java @@ -1,6 +1,6 @@ -package com.v5.mixins; +package com.chattriggers.ctjs.internal.mixins; -import com.v5.storage.V5MixinStorage; +import com.chattriggers.ctjs.api.client.Client; import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.network.chat.Component; import org.spongepowered.asm.mixin.Mixin; @@ -17,7 +17,7 @@ public class EntityRendererMixin { return; } - Component updated = V5MixinStorage.applyMethod("nameProcessor", original, Component.class); + Component updated = Client.processName(original); if (updated != original) { cir.setReturnValue(updated); } diff --git a/src/main/java/com/v5/mixins/FirmamentModAnnouncerMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/FirmamentModAnnouncerMixin.java similarity index 92% rename from src/main/java/com/v5/mixins/FirmamentModAnnouncerMixin.java rename to src/main/java/com/chattriggers/ctjs/internal/mixins/FirmamentModAnnouncerMixin.java index e2bcd92f..330c4fde 100644 --- a/src/main/java/com/v5/mixins/FirmamentModAnnouncerMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/FirmamentModAnnouncerMixin.java @@ -1,4 +1,4 @@ -package com.v5.mixins; +package com.chattriggers.ctjs.internal.mixins; import com.llamalad7.mixinextras.injector.wrapmethod.WrapMethod; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; diff --git a/src/main/java/com/v5/mixins/FramerateLimitTrackerMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/FramerateLimitTrackerMixin.java similarity index 93% rename from src/main/java/com/v5/mixins/FramerateLimitTrackerMixin.java rename to src/main/java/com/chattriggers/ctjs/internal/mixins/FramerateLimitTrackerMixin.java index 1b75ad86..6185a791 100644 --- a/src/main/java/com/v5/mixins/FramerateLimitTrackerMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/FramerateLimitTrackerMixin.java @@ -1,4 +1,4 @@ -package com.v5.mixins; +package com.chattriggers.ctjs.internal.mixins; import com.mojang.blaze3d.platform.FramerateLimitTracker; import org.spongepowered.asm.mixin.Mixin; diff --git a/src/main/java/com/v5/mixins/FrustumMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/FrustumMixin.java similarity index 80% rename from src/main/java/com/v5/mixins/FrustumMixin.java rename to src/main/java/com/chattriggers/ctjs/internal/mixins/FrustumMixin.java index 5eff1c18..65aa002e 100644 --- a/src/main/java/com/v5/mixins/FrustumMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/FrustumMixin.java @@ -1,6 +1,6 @@ -package com.v5.mixins; +package com.chattriggers.ctjs.internal.mixins; -import com.v5.storage.V5MixinStorage; +import com.chattriggers.ctjs.api.client.Client; import net.minecraft.client.renderer.culling.Frustum; import org.joml.FrustumIntersection; import org.spongepowered.asm.mixin.Mixin; @@ -14,6 +14,6 @@ public class FrustumMixin { private void v5$showEverythingInFreecam(double minX, double minY, double minZ, double maxX, double maxY, double maxZ, CallbackInfoReturnable cir) { - if (V5MixinStorage.getBoolean("freecamEnabled", false)) cir.setReturnValue(FrustumIntersection.INSIDE); + if (Client.isFreecam()) cir.setReturnValue(FrustumIntersection.INSIDE); } } diff --git a/src/main/java/com/chattriggers/ctjs/internal/mixins/GuiMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/GuiMixin.java index 405174ba..837037ec 100644 --- a/src/main/java/com/chattriggers/ctjs/internal/mixins/GuiMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/GuiMixin.java @@ -1,5 +1,6 @@ package com.chattriggers.ctjs.internal.mixins; +import com.chattriggers.ctjs.api.render.DrawContextHolder; import com.chattriggers.ctjs.api.world.Scoreboard; import com.chattriggers.ctjs.internal.engine.CTEvents; import gg.essential.universal.UMatrixStack; @@ -14,6 +15,11 @@ @Mixin(Gui.class) public class GuiMixin { + @Inject(method = "extractRenderState", at = @At("HEAD")) + private void captureContext(GuiGraphicsExtractor context, DeltaTracker tickCounter, CallbackInfo ci) { + DrawContextHolder.setCurrentContext(context); + } + @Inject(method = "extractScoreboardSidebar", at = @At("HEAD"), cancellable = true) private void injectRenderScoreboard(GuiGraphicsExtractor matrices, DeltaTracker tickCounter, CallbackInfo ci) { if (!Scoreboard.getShouldRender()) diff --git a/src/main/java/com/v5/mixins/GameRendererMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/GuiRendererMixin.java similarity index 81% rename from src/main/java/com/v5/mixins/GameRendererMixin.java rename to src/main/java/com/chattriggers/ctjs/internal/mixins/GuiRendererMixin.java index b47641c2..464cda9a 100644 --- a/src/main/java/com/v5/mixins/GameRendererMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/GuiRendererMixin.java @@ -1,7 +1,7 @@ -package com.v5.mixins; +package com.chattriggers.ctjs.internal.mixins; -import com.mojang.blaze3d.buffers.GpuBufferSlice; import com.chattriggers.ctjs.api.render.NVGRenderer; +import com.mojang.blaze3d.buffers.GpuBufferSlice; import net.minecraft.client.gui.render.GuiRenderer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -9,14 +9,14 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(GuiRenderer.class) -public class GameRendererMixin { +public class GuiRendererMixin { @Inject(method = "render", at = @At("HEAD")) private void beforeRender(GpuBufferSlice fogBuffer, CallbackInfo ci) { NVGRenderer.runPreDrawables(); } @Inject(method = "render", at = @At("TAIL")) - private void onRender(GpuBufferSlice fogBuffer, CallbackInfo ci) { + private void afterRender(GpuBufferSlice fogBuffer, CallbackInfo ci) { NVGRenderer.runDrawables(); } } diff --git a/src/main/java/com/v5/mixins/ItemInHandRendererMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/ItemInHandRendererMixin.java similarity index 91% rename from src/main/java/com/v5/mixins/ItemInHandRendererMixin.java rename to src/main/java/com/chattriggers/ctjs/internal/mixins/ItemInHandRendererMixin.java index 03f0b0da..504c5675 100644 --- a/src/main/java/com/v5/mixins/ItemInHandRendererMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/ItemInHandRendererMixin.java @@ -1,6 +1,6 @@ -package com.v5.mixins; +package com.chattriggers.ctjs.internal.mixins; -import com.v5.storage.V5MixinStorage; +import com.chattriggers.ctjs.api.client.Client; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.ItemInHandRenderer; import net.minecraft.world.InteractionHand; @@ -53,7 +53,6 @@ public class ItemInHandRendererMixin { } private LivingEntity v5$getSpectatedEntity() { - Object target = V5MixinStorage.get("freecamSpectatedEntity", null); - return target instanceof LivingEntity entity ? entity : null; + return Client.getSpectatedEntity(); } } diff --git a/src/main/java/com/v5/mixins/JoinMultiplayerScreenMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/JoinMultiplayerScreenMixin.java similarity index 97% rename from src/main/java/com/v5/mixins/JoinMultiplayerScreenMixin.java rename to src/main/java/com/chattriggers/ctjs/internal/mixins/JoinMultiplayerScreenMixin.java index b0923e24..d1f8a2f2 100644 --- a/src/main/java/com/v5/mixins/JoinMultiplayerScreenMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/JoinMultiplayerScreenMixin.java @@ -1,4 +1,4 @@ -package com.v5.mixins; +package com.chattriggers.ctjs.internal.mixins; import com.chattriggers.ctjs.api.client.ProxyManagerScreen; import net.minecraft.client.gui.GuiGraphicsExtractor; diff --git a/src/main/java/com/v5/mixins/KeyboardHandlerMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/KeyboardHandlerMixin.java similarity index 90% rename from src/main/java/com/v5/mixins/KeyboardHandlerMixin.java rename to src/main/java/com/chattriggers/ctjs/internal/mixins/KeyboardHandlerMixin.java index 5131ed32..87069459 100644 --- a/src/main/java/com/v5/mixins/KeyboardHandlerMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/KeyboardHandlerMixin.java @@ -1,8 +1,7 @@ -package com.v5.mixins; +package com.chattriggers.ctjs.internal.mixins; import com.chattriggers.ctjs.api.client.Client; import com.mojang.blaze3d.platform.InputConstants; -import com.v5.storage.V5MixinStorage; import net.minecraft.client.KeyboardHandler; import net.minecraft.client.Minecraft; import net.minecraft.client.Options; @@ -22,7 +21,7 @@ public class KeyboardHandlerMixin { } Minecraft client = Minecraft.getInstance(); - if (!V5MixinStorage.getBoolean("freecamEnabled", false) || client.screen != null) { + if (!Client.isFreecam() || client.screen != null) { return; } diff --git a/src/main/java/com/chattriggers/ctjs/internal/mixins/LevelRendererMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/LevelRendererMixin.java index 54273df5..3bffe511 100644 --- a/src/main/java/com/chattriggers/ctjs/internal/mixins/LevelRendererMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/LevelRendererMixin.java @@ -1,8 +1,10 @@ package com.chattriggers.ctjs.internal.mixins; +import com.chattriggers.ctjs.api.client.Client; import com.chattriggers.ctjs.internal.listeners.WorldListener; import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.mojang.blaze3d.buffers.GpuBufferSlice; +import com.mojang.blaze3d.framegraph.FrameGraphBuilder; import com.mojang.blaze3d.resource.GraphicsResourceAllocator; import com.mojang.blaze3d.resource.ResourceHandle; import com.mojang.blaze3d.vertex.PoseStack; @@ -10,6 +12,7 @@ import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.chunk.ChunkSectionsToRender; +import net.minecraft.client.renderer.culling.Frustum; import net.minecraft.client.renderer.state.level.BlockOutlineRenderState; import net.minecraft.client.renderer.state.level.CameraRenderState; import net.minecraft.client.renderer.state.level.LevelRenderState; @@ -19,6 +22,7 @@ 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.ModifyVariable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @@ -26,6 +30,18 @@ public abstract class LevelRendererMixin { private float ctjs$tickDelta = 1.0F; + @ModifyVariable(method = "cullTerrain", at = @At("HEAD"), argsOnly = true) + private boolean v5$useSpectatorCullingInFreecam(boolean spectator) { + return spectator || Client.isFreecam(); + } + + @Inject(method = "addMainPass", at = @At("HEAD"), cancellable = true) + private void v5$renderMain(FrameGraphBuilder frameGraphBuilder, Frustum frustum, Matrix4fc matrix4f, GpuBufferSlice gpuBufferSlice, boolean renderBlockOutline, LevelRenderState worldRenderState, DeltaTracker deltaTracker, ProfilerFiller profiler, ChunkSectionsToRender chunkSectionsToRender, CallbackInfo ci) { + if (Client.isMacroEnabled() && Client.getRenderLimiter() == Client.RenderLimiter.NO_RENDER) { + ci.cancel(); + } + } + @Inject( method = "renderBlockOutline", at = @At( diff --git a/src/main/java/com/chattriggers/ctjs/internal/mixins/MinecraftMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/MinecraftMixin.java index 49516b09..c0dc424f 100644 --- a/src/main/java/com/chattriggers/ctjs/internal/mixins/MinecraftMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/MinecraftMixin.java @@ -6,12 +6,19 @@ import com.chattriggers.ctjs.internal.engine.CTEvents; import com.chattriggers.ctjs.api.triggers.TriggerType; import com.chattriggers.ctjs.internal.engine.module.ModuleManager; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import net.minecraft.client.CameraType; +import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; +import net.minecraft.client.Options; import net.minecraft.client.gui.screens.Overlay; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.multiplayer.ServerData; import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.sounds.SoundSource; import org.jetbrains.annotations.Nullable; +import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -21,10 +28,115 @@ @Mixin(Minecraft.class) public abstract class MinecraftMixin { @Shadow @Nullable public ClientLevel level; + @Shadow @Final public Options options; @Shadow public abstract ServerData getCurrentServer(); @Shadow public abstract boolean hasSingleplayerServer(); + private Integer v5$savedDistance; + private CameraType v5$savedPerspective; + private Integer v5$savedFps; + private Float v5$savedMasterVolume; + + @ModifyExpressionValue( + method = "pauseIfInactive", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/client/Options;pauseOnLostFocus:Z", + opcode = Opcodes.GETFIELD + ) + ) + private boolean v5$pauseIfInactive(boolean original) { + return false; + } + + @ModifyExpressionValue( + method = "handleKeybinds", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/MouseHandler;isMouseGrabbed()Z" + ) + ) + private boolean v5$allowAttackWhileUngrabbed(boolean original) { + return original || Client.isUngrabbed() || Client.automatedAttackHeld; + } + + @Inject(method = "handleKeybinds()V", at = @At("HEAD")) + private void v5$handleInputEvents(CallbackInfo ci) { + if (!Client.isInputLocked()) { + return; + } + + for (KeyMapping key : options.keyHotbarSlots) { + if (key.consumeClick()) { + key.setDown(false); + } + } + } + + @Inject(method = "tick()V", at = @At("HEAD")) + private void v5$tickRenderLimiter(CallbackInfo ci) { + int currentDist = options.renderDistance().get(); + CameraType currentPerspective = options.getCameraType(); + int currentFps = options.framerateLimit().get(); + float currentMasterVolume = options.getFinalSoundSourceVolume(SoundSource.MASTER); + + boolean macroEnabled = Client.isMacroEnabled(); + Client.RenderLimiter renderLimiter = Client.getRenderLimiter(); + boolean forcePerspective = Client.isForcePerspective(); + boolean limitFps = Client.getLimitFps(); + boolean muteGame = Client.getMuteGame(); + + if (macroEnabled && renderLimiter == Client.RenderLimiter.LIMIT_CHUNKS) { + if (v5$savedDistance == null) v5$savedDistance = currentDist; + if (currentDist != 2) { + options.renderDistance().set(2); + } + } else if (v5$savedDistance != null) { + if (currentDist != v5$savedDistance) { + options.renderDistance().set(v5$savedDistance); + } + v5$savedDistance = null; + } + + if (macroEnabled && forcePerspective) { + if (v5$savedPerspective == null) v5$savedPerspective = currentPerspective; + if (currentPerspective != CameraType.THIRD_PERSON_BACK) { + options.setCameraType(CameraType.THIRD_PERSON_BACK); + } + } else if (v5$savedPerspective != null) { + if (currentPerspective != v5$savedPerspective) { + options.setCameraType(v5$savedPerspective); + } + v5$savedPerspective = null; + } + + if (macroEnabled && limitFps) { + if (v5$savedFps == null) v5$savedFps = currentFps; + if (currentFps != 30) { + options.framerateLimit().set(30); + } + } else if (v5$savedFps != null) { + if (currentFps != v5$savedFps) { + int restoreValue = v5$savedFps > 240 ? 260 : v5$savedFps; + options.framerateLimit().set(restoreValue); + } + v5$savedFps = null; + } + + if (macroEnabled && muteGame) { + if (v5$savedMasterVolume == null) v5$savedMasterVolume = currentMasterVolume; + if (Float.compare(currentMasterVolume, 0.0F) != 0) { + options.getSoundSourceOptionInstance(SoundSource.MASTER).set(0.0D); + } + } else if (v5$savedMasterVolume != null) { + if (Float.compare(currentMasterVolume, v5$savedMasterVolume) != 0) { + options.getSoundSourceOptionInstance(SoundSource.MASTER).set((double) v5$savedMasterVolume); + } + v5$savedMasterVolume = null; + } + } + @Inject(method = "setLevel", at = @At("HEAD")) private void injectWorldUnload(ClientLevel world, CallbackInfo ci) { if (world == null) diff --git a/src/main/java/com/chattriggers/ctjs/internal/mixins/MouseHandlerMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/MouseHandlerMixin.java index cbe3409d..8d14b4a3 100644 --- a/src/main/java/com/chattriggers/ctjs/internal/mixins/MouseHandlerMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/MouseHandlerMixin.java @@ -1,23 +1,115 @@ package com.chattriggers.ctjs.internal.mixins; +import com.chattriggers.ctjs.api.client.Client; import com.chattriggers.ctjs.internal.engine.CTEvents; import com.chattriggers.ctjs.internal.listeners.MouseListener; import com.llamalad7.mixinextras.sugar.Local; +import com.mojang.blaze3d.platform.InputConstants; +import net.minecraft.client.Minecraft; import net.minecraft.client.MouseHandler; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.input.MouseButtonInfo; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.util.Mth; import org.objectweb.asm.Opcodes; 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.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.lwjgl.glfw.GLFW; @Mixin(MouseHandler.class) public class MouseHandlerMixin { @Shadow private MouseButtonInfo activeButton; + private int v5$guiMouseButton = -1; + + private boolean v5$cameraLookEnabled() { + return Client.isFreecam() || Client.isFreelook(); + } + + @Inject(method = "onButton", at = @At("HEAD"), cancellable = true) + private void v5$cancelFreecamClick(long window, MouseButtonInfo button, int action, CallbackInfo ci) { + Minecraft client = Minecraft.getInstance(); + if (action == GLFW.GLFW_PRESS && client.screen != null) { + v5$guiMouseButton = button.button(); + } else if (action == GLFW.GLFW_RELEASE) { + if (button.button() == v5$guiMouseButton) { + v5$guiMouseButton = -1; + } else if (!v5$cameraLookEnabled() || (button.button() != 0 && button.button() != 1)) { + Client.releaseHeldKey(InputConstants.Type.MOUSE.getOrCreate(button.button())); + } + } + + if (v5$cameraLookEnabled() + && client.screen == null + && (button.button() == 0 || button.button() == 1)) { + ci.cancel(); + } + } + + @Redirect( + method = "turnPlayer(D)V", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/player/LocalPlayer;turn(DD)V" + ) + ) + private void v5$turnFreecam(LocalPlayer player, double yawDelta, double pitchDelta) { + if (!v5$cameraLookEnabled()) { + player.turn(yawDelta, pitchDelta); + return; + } + + Float yaw = Client.getCameraYaw(); + Float pitch = Client.getCameraPitch(); + Client.setCameraRotation( + (yaw != null ? yaw : player.getYRot()) + (float) yawDelta * 0.15F, + Mth.clamp((pitch != null ? pitch : player.getXRot()) + (float) pitchDelta * 0.15F, -90.0F, 90.0F) + ); + } + + @Inject(method = "grabMouse()V", at = @At("HEAD"), cancellable = true) + private void v5$lockCursor(CallbackInfo ci) { + if (Client.isUngrabbed()) { + Client.resumeHeldKeys(); + ci.cancel(); + } + } + + @Inject(method = "grabMouse()V", at = @At("TAIL")) + private void v5$restoreHeldKeys(CallbackInfo ci) { + Client.resumeHeldKeys(); + } + + @Inject(method = "turnPlayer(D)V", at = @At("HEAD"), cancellable = true) + private void v5$updateMouse(CallbackInfo ci) { + if (Client.isUngrabbed()) { + ci.cancel(); + } + } + + @Inject(method = "onScroll(JDD)V", at = @At("HEAD"), cancellable = true) + private void v5$onMouseScroll(long window, double horizontalScroll, double verticalScroll, CallbackInfo ci) { + Minecraft client = Minecraft.getInstance(); + if (Client.isFreelook() && client.screen == null) { + Client.setFreelookDistance(Client.getFreelookDistance() - verticalScroll); + ci.cancel(); + return; + } + + if (!Client.isInputLocked()) { + return; + } + + if (client.screen == null) { + ci.cancel(); + } + } + @Inject( method = "onButton", at = @At( diff --git a/src/main/java/com/chattriggers/ctjs/internal/mixins/PlayerTabOverlayMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/PlayerTabOverlayMixin.java index 3109d2d9..6bc2f641 100644 --- a/src/main/java/com/chattriggers/ctjs/internal/mixins/PlayerTabOverlayMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/PlayerTabOverlayMixin.java @@ -1,7 +1,9 @@ package com.chattriggers.ctjs.internal.mixins; +import com.chattriggers.ctjs.api.client.Client; import com.chattriggers.ctjs.api.triggers.TriggerType; import com.chattriggers.ctjs.api.world.TabList; +import com.llamalad7.mixinextras.injector.ModifyReturnValue; import net.minecraft.client.gui.GuiGraphicsExtractor; import net.minecraft.client.gui.components.PlayerTabOverlay; import net.minecraft.world.scores.Scoreboard; @@ -14,6 +16,11 @@ @Mixin(PlayerTabOverlay.class) public class PlayerTabOverlayMixin { + @ModifyReturnValue(method = "getNameForDisplay", at = @At("RETURN")) + private Component v5$getPlayerName(Component original) { + return Client.processName(original); + } + @Inject(method = "extractRenderState", at = @At("HEAD"), cancellable = true) private void injectRenderPlayerList(GuiGraphicsExtractor context, int scaledWindowWidth, Scoreboard scoreboard, Objective objective, CallbackInfo ci) { TriggerType.RENDER_PLAYER_LIST.triggerAll(ci); diff --git a/src/main/java/com/v5/mixins/VisGraphMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/VisGraphMixin.java similarity index 78% rename from src/main/java/com/v5/mixins/VisGraphMixin.java rename to src/main/java/com/chattriggers/ctjs/internal/mixins/VisGraphMixin.java index 69d21a58..0bafd2bf 100644 --- a/src/main/java/com/v5/mixins/VisGraphMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/VisGraphMixin.java @@ -1,6 +1,6 @@ -package com.v5.mixins; +package com.chattriggers.ctjs.internal.mixins; -import com.v5.storage.V5MixinStorage; +import com.chattriggers.ctjs.api.client.Client; import net.minecraft.client.renderer.chunk.VisGraph; import net.minecraft.core.BlockPos; import org.spongepowered.asm.mixin.Mixin; @@ -12,6 +12,6 @@ public class VisGraphMixin { @Inject(method = "setOpaque", at = @At("HEAD"), cancellable = true) private void v5$disableFreecamOcclusion(BlockPos pos, CallbackInfo ci) { - if (V5MixinStorage.getBoolean("freecamEnabled", false)) ci.cancel(); + if (Client.isFreecam()) ci.cancel(); } } diff --git a/src/main/java/com/v5/mixins/YggdrasilServicesKeyInfoMixin.java b/src/main/java/com/chattriggers/ctjs/internal/mixins/YggdrasilServicesKeyInfoMixin.java similarity index 94% rename from src/main/java/com/v5/mixins/YggdrasilServicesKeyInfoMixin.java rename to src/main/java/com/chattriggers/ctjs/internal/mixins/YggdrasilServicesKeyInfoMixin.java index 6833b7af..609eca92 100644 --- a/src/main/java/com/v5/mixins/YggdrasilServicesKeyInfoMixin.java +++ b/src/main/java/com/chattriggers/ctjs/internal/mixins/YggdrasilServicesKeyInfoMixin.java @@ -1,4 +1,4 @@ -package com.v5.mixins; +package com.chattriggers.ctjs.internal.mixins; import com.mojang.authlib.yggdrasil.YggdrasilServicesKeyInfo; import org.slf4j.Logger; @@ -20,4 +20,4 @@ public class YggdrasilServicesKeyInfoMixin { private void redirectLoggerError(Logger instance, String s, Object o, Object o1) { // Do nothing - suppress the log } -} \ No newline at end of file +} diff --git a/src/main/java/com/v5/mixins/BlockMixin.java b/src/main/java/com/v5/mixins/BlockMixin.java deleted file mode 100644 index 218df85e..00000000 --- a/src/main/java/com/v5/mixins/BlockMixin.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.v5.mixins; - -import com.v5.storage.V5MixinStorage; -import java.util.Set; -import net.minecraft.world.level.block.Block; -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; - -@Mixin(Block.class) -public class BlockMixin { - private static final Set TARGET_KEYS = - Set.of( - "block.minecraft.melon", - "block.minecraft.pumpkin", - "block.minecraft.carrots", - "block.minecraft.potatoes", - "block.minecraft.wheat", - "block.minecraft.nether_wart", - "block.minecraft.sugar_cane", - "block.minecraft.cactus", - "block.minecraft.cocoa", - "block.minecraft.melon_stem", - "block.minecraft.pumpkin_stem", - "block.minecraft.carved_pumpkin"); - - @Inject(method = "spawnDestroyParticles", at = @At("HEAD"), cancellable = true) - private void v5$spawnBreakParticles(CallbackInfo ci) { - if (!V5MixinStorage.getBoolean("hideParticles", false)) { - return; - } - - String blockKey = ((Block) (Object) this).getDescriptionId(); - if (TARGET_KEYS.contains(blockKey)) { - ci.cancel(); - } - } -} diff --git a/src/main/java/com/v5/mixins/ChatComponentMixin.java b/src/main/java/com/v5/mixins/ChatComponentMixin.java deleted file mode 100644 index c7e3ef10..00000000 --- a/src/main/java/com/v5/mixins/ChatComponentMixin.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.v5.mixins; - -import com.v5.storage.V5MixinStorage; -import net.minecraft.client.gui.components.ChatComponent; -import net.minecraft.network.chat.Component; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.ModifyVariable; - -@Mixin(ChatComponent.class) -public class ChatComponentMixin { - @ModifyVariable( - method = "addMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/MessageSignature;Lnet/minecraft/client/multiplayer/chat/GuiMessageSource;Lnet/minecraft/client/multiplayer/chat/GuiMessageTag;)V", - at = @At("HEAD"), - ordinal = 0, - argsOnly = true) - private Component v5$addMessage(Component original) { - return V5MixinStorage.applyMethod("nameProcessor", original, Component.class); - } -} diff --git a/src/main/java/com/v5/mixins/ConnectionMixin.java b/src/main/java/com/v5/mixins/ConnectionMixin.java deleted file mode 100644 index 5c12c7e4..00000000 --- a/src/main/java/com/v5/mixins/ConnectionMixin.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.v5.mixins; - -import com.chattriggers.ctjs.api.triggers.PacketEvent; -import net.minecraft.network.Connection; -import net.minecraft.network.PacketListener; -import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.game.ClientboundBundlePacket; -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; - -@Mixin(Connection.class) -public class ConnectionMixin { - - @Inject(method = "genericsFtw", at = @At("HEAD")) - private static void onPacketReceived(Packet packet, PacketListener listener, CallbackInfo ci) { - if (packet instanceof ClientboundBundlePacket bundlePacket) { - for (Packet subPacket : bundlePacket.subPackets()) { - PacketEvent.RECEIVE.invoker().trigger(subPacket); - } - } else { - PacketEvent.RECEIVE.invoker().trigger(packet); - } - } -} diff --git a/src/main/java/com/v5/mixins/DrawContextCapture.java b/src/main/java/com/v5/mixins/DrawContextCapture.java deleted file mode 100644 index 8cdd1364..00000000 --- a/src/main/java/com/v5/mixins/DrawContextCapture.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.v5.mixins; - -import net.minecraft.client.gui.GuiGraphicsExtractor; -import net.minecraft.client.gui.Gui; -import net.minecraft.client.DeltaTracker; -import com.chattriggers.ctjs.api.render.DrawContextHolder; -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; - -@Mixin(Gui.class) -public class DrawContextCapture { - @Inject(method = "extractRenderState", at = @At("HEAD")) - private void captureContext(GuiGraphicsExtractor context, DeltaTracker tickCounter, CallbackInfo ci) { - DrawContextHolder.setCurrentContext(context); - } -} diff --git a/src/main/java/com/v5/mixins/LevelRendererMixin.java b/src/main/java/com/v5/mixins/LevelRendererMixin.java deleted file mode 100644 index cd455219..00000000 --- a/src/main/java/com/v5/mixins/LevelRendererMixin.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.v5.mixins; - -import com.mojang.blaze3d.buffers.GpuBufferSlice; -import com.mojang.blaze3d.framegraph.FrameGraphBuilder; -import com.v5.storage.V5MixinStorage; -import net.minecraft.client.DeltaTracker; -import net.minecraft.client.renderer.LevelRenderer; -import net.minecraft.client.renderer.chunk.ChunkSectionsToRender; -import net.minecraft.client.renderer.culling.Frustum; -import net.minecraft.client.renderer.state.level.LevelRenderState; -import net.minecraft.util.profiling.ProfilerFiller; -import org.joml.Matrix4fc; -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.ModifyVariable; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(LevelRenderer.class) -public class LevelRendererMixin { - - @ModifyVariable(method = "cullTerrain", at = @At("HEAD"), argsOnly = true) - private boolean v5$useSpectatorCullingInFreecam(boolean spectator) { - return spectator || V5MixinStorage.getBoolean("freecamEnabled", false); - } - - @Inject(method = "addMainPass", at = @At("HEAD"), cancellable = true) - private void v5$renderMain(FrameGraphBuilder frameGraphBuilder, Frustum frustum, Matrix4fc matrix4f, GpuBufferSlice gpuBufferSlice, boolean renderBlockOutline, LevelRenderState worldRenderState, DeltaTracker deltaTracker, ProfilerFiller profiler, ChunkSectionsToRender chunkSectionsToRender, CallbackInfo ci) { - if (V5MixinStorage.getBoolean("macroEnabled", false) - && "No Render".equals(V5MixinStorage.getString("renderLimiter", "Off"))) { - ci.cancel(); - } - } -} diff --git a/src/main/java/com/v5/mixins/MinecraftMixin.java b/src/main/java/com/v5/mixins/MinecraftMixin.java deleted file mode 100644 index c574372a..00000000 --- a/src/main/java/com/v5/mixins/MinecraftMixin.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.v5.mixins; - -import com.chattriggers.ctjs.api.client.Client; -import com.v5.storage.V5MixinStorage; -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import net.minecraft.client.Minecraft; -import net.minecraft.client.Options; -import net.minecraft.client.KeyMapping; -import net.minecraft.client.CameraType; -import net.minecraft.sounds.SoundSource; -import org.objectweb.asm.Opcodes; -import org.spongepowered.asm.mixin.Final; -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.CallbackInfo; - -@Mixin(Minecraft.class) -public class MinecraftMixin { - - @Shadow @Final public Options options; - - @ModifyExpressionValue( - method = "pauseIfInactive", - at = @At( - value = "FIELD", - target = "Lnet/minecraft/client/Options;pauseOnLostFocus:Z", - opcode = Opcodes.GETFIELD - )) - private boolean v5$pauseIfInactive(boolean original) { - return false; - } - - @ModifyExpressionValue( - method = "handleKeybinds", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/MouseHandler;isMouseGrabbed()Z" - ) - ) - private boolean v5$allowAttackWhileUngrabbed(boolean original) { - return original || V5MixinStorage.getBoolean("ungrabbed", false) || Client.automatedAttackHeld; - } - - @Inject(method = "handleKeybinds()V", at = @At("HEAD")) - private void v5$handleInputEvents(CallbackInfo ci) { - if (!V5MixinStorage.getBoolean("inputLocked", false)) { - return; - } - - for (KeyMapping key : options.keyHotbarSlots) { - if (key.consumeClick()) { - key.setDown(false); - } - } - } - - @Inject(method = "tick()V", at = @At("HEAD")) - private void v5$tickRenderLimiter(CallbackInfo ci) { - int currentDist = options.renderDistance().get(); - CameraType currentPerspective = options.getCameraType(); - int currentFps = options.framerateLimit().get(); - float currentMasterVolume = options.getFinalSoundSourceVolume(SoundSource.MASTER); - - boolean macroEnabled = V5MixinStorage.getBoolean("macroEnabled", false); - String renderLimiter = V5MixinStorage.getString("renderLimiter", "Off"); - boolean forcePerspective = V5MixinStorage.getBoolean("forcePerspective", false); - boolean limitFps = V5MixinStorage.getBoolean("limitFps", false); - boolean muteGame = V5MixinStorage.getBoolean("muteGame", false); - - Object savedDistanceObj = V5MixinStorage.get("savedDistance", null); - if (macroEnabled && "Limit Chunks".equals(renderLimiter)) { - if (savedDistanceObj == null) { - V5MixinStorage.set("savedDistance", currentDist); - } - if (currentDist != 2) { - options.renderDistance().set(2); - } - } else if (savedDistanceObj instanceof Number savedDistanceNum) { - int savedDistance = savedDistanceNum.intValue(); - if (currentDist != savedDistance) { - options.renderDistance().set(savedDistance); - } - V5MixinStorage.set("savedDistance", null); - } - - Object savedPerspectiveObj = V5MixinStorage.get("savedPerspective", null); - if (macroEnabled && forcePerspective) { - if (savedPerspectiveObj == null) { - V5MixinStorage.set("savedPerspective", currentPerspective); - } - if (currentPerspective != CameraType.THIRD_PERSON_BACK) { - options.setCameraType(CameraType.THIRD_PERSON_BACK); - } - } else if (savedPerspectiveObj instanceof CameraType savedPerspective) { - if (currentPerspective != savedPerspective) { - options.setCameraType(savedPerspective); - } - V5MixinStorage.set("savedPerspective", null); - } - - Object savedFpsObj = V5MixinStorage.get("savedFps", null); - if (macroEnabled && limitFps) { - if (savedFpsObj == null) { - V5MixinStorage.set("savedFps", currentFps); - } - if (currentFps != 30) { - options.framerateLimit().set(30); - } - } else if (savedFpsObj instanceof Number savedFpsNum) { - int savedFps = savedFpsNum.intValue(); - if (currentFps != savedFps) { - int restoreValue = savedFps > 240 ? 260 : savedFps; - options.framerateLimit().set(restoreValue); - } - V5MixinStorage.set("savedFps", null); - } - - Object savedMasterVolumeObj = V5MixinStorage.get("savedMasterVolume", null); - if (macroEnabled && muteGame) { - if (savedMasterVolumeObj == null) { - V5MixinStorage.set("savedMasterVolume", currentMasterVolume); - } - if (Float.compare(currentMasterVolume, 0.0F) != 0) { - options.getSoundSourceOptionInstance(SoundSource.MASTER).set(0.0D); - } - } else if (savedMasterVolumeObj instanceof Number savedMasterVolumeNum) { - float savedMasterVolume = savedMasterVolumeNum.floatValue(); - if (Float.compare(currentMasterVolume, savedMasterVolume) != 0) { - options.getSoundSourceOptionInstance(SoundSource.MASTER).set((double) savedMasterVolume); - } - V5MixinStorage.set("savedMasterVolume", null); - } - } -} diff --git a/src/main/java/com/v5/mixins/MouseHandlerMixin.java b/src/main/java/com/v5/mixins/MouseHandlerMixin.java deleted file mode 100644 index 995a8b0a..00000000 --- a/src/main/java/com/v5/mixins/MouseHandlerMixin.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.v5.mixins; - -import com.chattriggers.ctjs.api.client.Client; -import com.mojang.blaze3d.platform.InputConstants; -import com.v5.storage.V5MixinStorage; -import net.minecraft.client.Minecraft; -import net.minecraft.client.MouseHandler; -import net.minecraft.client.input.MouseButtonInfo; -import net.minecraft.client.player.LocalPlayer; -import net.minecraft.util.Mth; -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.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.lwjgl.glfw.GLFW; - -@Mixin(MouseHandler.class) -public class MouseHandlerMixin { - private int v5$guiMouseButton = -1; - - private boolean v5$cameraLookEnabled() { - return V5MixinStorage.getBoolean("freecamEnabled", false) - || V5MixinStorage.getBoolean("freelookEnabled", false); - } - - @Inject(method = "onButton", at = @At("HEAD"), cancellable = true) - private void v5$cancelFreecamClick(long window, MouseButtonInfo button, int action, CallbackInfo ci) { - Minecraft client = Minecraft.getInstance(); - if (action == GLFW.GLFW_PRESS && client.screen != null) { - v5$guiMouseButton = button.button(); - } else if (action == GLFW.GLFW_RELEASE) { - if (button.button() == v5$guiMouseButton) { - v5$guiMouseButton = -1; - } else if (!v5$cameraLookEnabled() || (button.button() != 0 && button.button() != 1)) { - Client.releaseHeldKey(InputConstants.Type.MOUSE.getOrCreate(button.button())); - } - } - - if (v5$cameraLookEnabled() - && client.screen == null - && (button.button() == 0 || button.button() == 1)) { - ci.cancel(); - } - } - - @Redirect( - method = "turnPlayer(D)V", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/player/LocalPlayer;turn(DD)V")) - private void v5$turnFreecam(LocalPlayer player, double yawDelta, double pitchDelta) { - if (!v5$cameraLookEnabled()) { - player.turn(yawDelta, pitchDelta); - return; - } - - Object yaw = V5MixinStorage.get("cameraOverrideYaw", player.getYRot()); - Object pitch = V5MixinStorage.get("cameraOverridePitch", player.getXRot()); - if (yaw instanceof Number yawNumber && pitch instanceof Number pitchNumber) { - V5MixinStorage.set("cameraOverrideYaw", yawNumber.floatValue() + (float) yawDelta * 0.15F); - V5MixinStorage.set( - "cameraOverridePitch", - Mth.clamp(pitchNumber.floatValue() + (float) pitchDelta * 0.15F, -90.0F, 90.0F)); - } - } - - @Inject(method = "grabMouse()V", at = @At("HEAD"), cancellable = true) - private void v5$lockCursor(CallbackInfo ci) { - if (V5MixinStorage.getBoolean("ungrabbed", false)) { - Client.resumeHeldKeys(); - ci.cancel(); - } - } - - @Inject(method = "grabMouse()V", at = @At("TAIL")) - private void v5$restoreHeldKeys(CallbackInfo ci) { - Client.resumeHeldKeys(); - } - - @Inject(method = "turnPlayer(D)V", at = @At("HEAD"), cancellable = true) - private void v5$updateMouse(CallbackInfo ci) { - if (V5MixinStorage.getBoolean("ungrabbed", false)) { - ci.cancel(); - } - } - - @Inject(method = "onScroll(JDD)V", at = @At("HEAD"), cancellable = true) - private void v5$onMouseScroll(long window, double horizontalScroll, double verticalScroll, CallbackInfo ci) { - Minecraft client = Minecraft.getInstance(); - if (V5MixinStorage.getBoolean("freelookEnabled", false) && client.screen == null) { - Object storedDistance = V5MixinStorage.get("freelookCameraDistance", 4.0); - double distance = storedDistance instanceof Number number ? number.doubleValue() : 4.0; - V5MixinStorage.set("freelookCameraDistance", Mth.clamp(distance - verticalScroll, 1.0, 12.0)); - ci.cancel(); - return; - } - - if (!V5MixinStorage.getBoolean("inputLocked", false)) { - return; - } - - if (client != null && client.screen == null) { - ci.cancel(); - } - } -} diff --git a/src/main/java/com/v5/mixins/PlayerTabOverlayMixin.java b/src/main/java/com/v5/mixins/PlayerTabOverlayMixin.java deleted file mode 100644 index 332969e8..00000000 --- a/src/main/java/com/v5/mixins/PlayerTabOverlayMixin.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.v5.mixins; - -import com.llamalad7.mixinextras.injector.ModifyReturnValue; -import com.v5.storage.V5MixinStorage; -import net.minecraft.client.gui.components.PlayerTabOverlay; -import net.minecraft.network.chat.Component; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(PlayerTabOverlay.class) -public class PlayerTabOverlayMixin { - @ModifyReturnValue(method = "getNameForDisplay", at = @At("RETURN")) - private Component v5$getPlayerName(Component original) { - return V5MixinStorage.applyMethod("nameProcessor", original, Component.class); - } -} diff --git a/src/main/java/com/v5/storage/V5MixinStorage.java b/src/main/java/com/v5/storage/V5MixinStorage.java deleted file mode 100644 index bbe77f62..00000000 --- a/src/main/java/com/v5/storage/V5MixinStorage.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.v5.storage; - -import com.chattriggers.ctjs.internal.engine.JSLoader; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.function.Function; -import org.mozilla.javascript.Callable; -import org.mozilla.javascript.ScriptRuntime; -import org.mozilla.javascript.Undefined; - -public final class V5MixinStorage { - private static final String METHOD_PREFIX = "method_"; - private static final Map STORAGE = new HashMap<>(); - - private V5MixinStorage() {} - - public static Object get(String key, Object defaultValue) { - return STORAGE.getOrDefault(key, defaultValue); - } - - public static boolean getBoolean(String key, boolean defaultValue) { - Object value = get(key, defaultValue); - if (value == null || value == Undefined.instance) { - return defaultValue; - } - - if (value instanceof Boolean bool) { - return bool; - } - - if (value instanceof Number number) { - return number.doubleValue() != 0.0D; - } - - if (value instanceof CharSequence sequence) { - String normalized = sequence.toString().trim().toLowerCase(Locale.ROOT); - if ("true".equals(normalized)) return true; - if ("false".equals(normalized)) return false; - return defaultValue; - } - - return convertOrDefault(value, ScriptRuntime::toBoolean, defaultValue); - } - - public static String getString(String key, String defaultValue) { - Object value = get(key, defaultValue); - if (value == null || value == Undefined.instance) { - return defaultValue; - } - - if (value instanceof String str) { - return str; - } - - return convertOrDefault(value, ScriptRuntime::toString, defaultValue); - } - - public static void set(String key, Object value) { - STORAGE.put(key, value); - } - - public static void clear() { - Object savedDistance = STORAGE.get("savedDistance"); - Object savedPerspective = STORAGE.get("savedPerspective"); - Object savedFps = STORAGE.get("savedFps"); - Object savedMasterVolume = STORAGE.get("savedMasterVolume"); - STORAGE.clear(); - if (savedDistance != null) STORAGE.put("savedDistance", savedDistance); - if (savedPerspective != null) STORAGE.put("savedPerspective", savedPerspective); - if (savedFps != null) STORAGE.put("savedFps", savedFps); - if (savedMasterVolume != null) STORAGE.put("savedMasterVolume", savedMasterVolume); - } - - public static T applyMethod(String methodName, T original, Class expectedType) { - Object value = STORAGE.get(METHOD_PREFIX + methodName); - if (!(value instanceof Callable callable)) { - return original; - } - - try { - Object result = JSLoader.invokeMixin(callable, new Object[] { original }); - if (result == null || result == Undefined.instance) { - return original; - } - - if (expectedType.isInstance(result)) { - return expectedType.cast(result); - } - } catch (Throwable ignored) { - } - - return original; - } - - private static T convertOrDefault(Object value, Function converter, T defaultValue) { - try { - return converter.apply(value); - } catch (Throwable ignored) { - return defaultValue; - } - } -} diff --git a/src/main/kotlin/com/chattriggers/ctjs/api/client/Client.kt b/src/main/kotlin/com/chattriggers/ctjs/api/client/Client.kt index 6444345a..e77d9ff2 100644 --- a/src/main/kotlin/com/chattriggers/ctjs/api/client/Client.kt +++ b/src/main/kotlin/com/chattriggers/ctjs/api/client/Client.kt @@ -1,8 +1,10 @@ package com.chattriggers.ctjs.api.client +import com.chattriggers.ctjs.CTJS import com.chattriggers.ctjs.api.inventory.Slot import com.chattriggers.ctjs.api.message.TextComponent import com.chattriggers.ctjs.api.world.World +import com.chattriggers.ctjs.internal.engine.JSLoader import com.chattriggers.ctjs.internal.listeners.ClientListener import com.chattriggers.ctjs.internal.mixins.ChatScreenAccessor import com.chattriggers.ctjs.internal.mixins.AbstractSignEditScreenAccessor @@ -32,11 +34,40 @@ import com.mojang.realmsclient.RealmsMainScreen import net.minecraft.network.protocol.Packet import net.minecraft.network.protocol.game.ServerGamePacketListener import net.minecraft.network.chat.Component +import net.minecraft.world.entity.LivingEntity +import net.minecraft.world.phys.Vec3 +import org.mozilla.javascript.Callable +import org.mozilla.javascript.Undefined object Client { + enum class RenderLimiter { + OFF, + LIMIT_CHUNKS, + NO_RENDER, + } + internal var referenceSystemTime: Long = 0 private val heldKeys = mutableSetOf() + @JvmStatic @Volatile var isFreecam = false + @JvmStatic @Volatile var isFreelook = false + @JvmStatic @Volatile var isUngrabbed = false + @JvmStatic @Volatile var isInputLocked = false + @JvmStatic @Volatile var isMacroEnabled = false + @JvmStatic @Volatile var isForcePerspective = false + @JvmStatic @Volatile var limitFps = false + @JvmStatic @Volatile var muteGame = false + @JvmStatic @Volatile var renderLimiter = RenderLimiter.OFF + @Volatile private var cameraYaw: Float? = null + @Volatile private var cameraPitch: Float? = null + @JvmStatic @Volatile var cameraPosition: Vec3? = null + @JvmStatic @Volatile var freelookDistance = 4.0 + set(value) { + field = value.coerceIn(1.0, 12.0) + } + @JvmStatic @Volatile var spectatedEntity: LivingEntity? = null + @Volatile private var nameProcessor: Callable? = null + @JvmField internal var automatedAttackHeld = false @@ -46,6 +77,42 @@ object Client { @JvmField val camera = CameraWrapper() + @JvmStatic + fun setCameraRotation(yaw: Float, pitch: Float) { + cameraYaw = yaw + cameraPitch = pitch + } + + @JvmStatic + fun clearCameraRotation() { + cameraYaw = null + cameraPitch = null + } + + @JvmStatic + fun getCameraYaw(): Float? = cameraYaw + + @JvmStatic + fun getCameraPitch(): Float? = cameraPitch + + @JvmStatic + fun setNameProcessor(processor: Callable?) { + nameProcessor = processor + } + + @JvmStatic + fun processName(original: Component): Component { + val processor = nameProcessor ?: return original + if (!CTJS.isLoaded) return original + + return try { + val result = JSLoader.invokeMixin(processor, arrayOf(original)) + if (result != null && result != Undefined.instance && result is Component) result else original + } catch (_: Throwable) { + original + } + } + /** * Gets Minecraft's Minecraft object * diff --git a/src/main/resources/ctjs.mixins.json b/src/main/resources/ctjs.mixins.json index 8745973f..e4275cff 100644 --- a/src/main/resources/ctjs.mixins.json +++ b/src/main/resources/ctjs.mixins.json @@ -9,6 +9,7 @@ "BlockEntityRenderStateMixin", "BookViewScreenAccessor", "BossHealthOverlayAccessor", + "CameraMixin", "ChatComponentAccessor", "ChatComponentMixin", "ChatScreenAccessor", @@ -20,16 +21,26 @@ "MultiPlayerGameModeMixin", "ClientPacketListenerAccessor", "ClientLevelAccessor", + "ConnectionProxyMixin", "CreativeModeInventoryScreenMixin", + "CrossCollisionBlockMixin", + "EntityRendererMixin", "EntityRenderDispatcherMixin", "EntityRenderStateMixin", + "FirmamentModAnnouncerMixin", + "FramerateLimitTrackerMixin", + "FrustumMixin", "OptionsAccessor", "OptionsMixin", "AbstractContainerScreenAccessor", "AbstractContainerScreenMixin", "GuiMixin", + "GuiRendererMixin", + "ItemInHandRendererMixin", + "JoinMultiplayerScreenMixin", "KeyMappingAccessor", "KeyMappingAccessor$Category", + "KeyboardHandlerMixin", "MinecraftAccessor", "MinecraftMixin", "MouseHandlerMixin", @@ -40,6 +51,8 @@ "PlayerTabOverlayMixin", "RenderTickCounterMixin", "LevelRendererMixin", + "VisGraphMixin", + "YggdrasilServicesKeyInfoMixin", "commands.ClientSuggestionProviderMixin", "commands.ClientPacketListenerMixin", "sound.SoundAccessor", diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 2e573bd0..46a76720 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -27,7 +27,7 @@ "com.chattriggers.ctjs.api.world.pathfinding.Swift" ] }, - "mixins": ["ctjs.mixins.json", "v5.mixins.json"], + "mixins": ["ctjs.mixins.json"], "depends": { "minecraft": "=$minecraft_version", "fabricloader": ">=$loader_version", diff --git a/src/main/resources/v5.mixins.json b/src/main/resources/v5.mixins.json deleted file mode 100644 index 66d21dc0..00000000 --- a/src/main/resources/v5.mixins.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "required": true, - "minVersion": "0.8", - "package": "com.v5.mixins", - "compatibilityLevel": "JAVA_25", - "client": [ - "BlockMixin", - "CameraMixin", - "ChatComponentMixin", - "ConnectionProxyMixin", - "CrossCollisionBlockMixin", - "DrawContextCapture", - "EntityRendererMixin", - "FirmamentModAnnouncerMixin", - "FramerateLimitTrackerMixin", - "FrustumMixin", - "GameRendererMixin", - "ItemInHandRendererMixin", - "KeyboardHandlerMixin", - "MinecraftMixin", - "MouseHandlerMixin", - "JoinMultiplayerScreenMixin", - "PlayerTabOverlayMixin", - "LevelRendererMixin", - "VisGraphMixin", - "YggdrasilServicesKeyInfoMixin" - ], - "mixins": [ - "ConnectionMixin" - ], - "injectors": { - "defaultRequire": 1 - } -}