diff --git a/src/main/java/com/lambda/mixin/entity/EntityMixin.java b/src/main/java/com/lambda/mixin/entity/EntityMixin.java
index 5e6708562..133d41280 100644
--- a/src/main/java/com/lambda/mixin/entity/EntityMixin.java
+++ b/src/main/java/com/lambda/mixin/entity/EntityMixin.java
@@ -22,7 +22,9 @@
import com.lambda.event.events.EntityEvent;
import com.lambda.event.events.PlayerEvent;
import com.lambda.interaction.request.rotating.RotationManager;
+import com.lambda.module.modules.render.NoRender;
import com.lambda.util.math.Vec2d;
+import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import net.minecraft.entity.Entity;
import net.minecraft.entity.MovementType;
import net.minecraft.entity.data.TrackedData;
@@ -130,4 +132,14 @@ public void onTrackedDataSet(TrackedData> data, CallbackInfo ci) {
Entity entity = (Entity) (Object) this;
EventFlow.post(new EntityEvent.Update(entity, data));
}
+
+ @ModifyExpressionValue(method = "isInvisible", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getFlag(I)Z"))
+ private boolean modifyGetFlagInvisible(boolean original) {
+ return (NoRender.INSTANCE.isDisabled() || !NoRender.getNoInvisibility()) && original;
+ }
+
+ @ModifyExpressionValue(method = "isGlowing", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getFlag(I)Z"))
+ private boolean modifyGetFlagGlowing(boolean original) {
+ return (NoRender.INSTANCE.isDisabled() || !NoRender.getNoGlow()) && original;
+ }
}
diff --git a/src/main/java/com/lambda/mixin/network/ClientPlayNetworkHandlerMixin.java b/src/main/java/com/lambda/mixin/network/ClientPlayNetworkHandlerMixin.java
index c3bd1bc00..e546b7b7b 100644
--- a/src/main/java/com/lambda/mixin/network/ClientPlayNetworkHandlerMixin.java
+++ b/src/main/java/com/lambda/mixin/network/ClientPlayNetworkHandlerMixin.java
@@ -103,12 +103,4 @@ public boolean onServerMetadata(ClientPlayNetworkHandler clientPlayNetworkHandle
void injectVelocity(ExplosionS2CPacket packet, CallbackInfo ci) {
if (Velocity.getExplosion() && Velocity.INSTANCE.isEnabled()) ci.cancel();
}
-
- /**
- * Cancels the world particle if {@link NoRender#getNoExplosion()} is true
- */
- @Inject(method = "onExplosion(Lnet/minecraft/network/packet/s2c/play/ExplosionS2CPacket;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;addParticleClient(Lnet/minecraft/particle/ParticleEffect;DDDDDD)V"), cancellable = true)
- void injectParticles(ExplosionS2CPacket packet, CallbackInfo ci) {
- if (NoRender.getNoExplosion() && NoRender.INSTANCE.isEnabled()) ci.cancel();
- }
-}
+}
\ No newline at end of file
diff --git a/src/main/java/com/lambda/mixin/render/AbstractSignBlockEntityRendererMixin.java b/src/main/java/com/lambda/mixin/render/AbstractSignBlockEntityRendererMixin.java
new file mode 100644
index 000000000..6f1d4c5c5
--- /dev/null
+++ b/src/main/java/com/lambda/mixin/render/AbstractSignBlockEntityRendererMixin.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2025 Lambda
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see
{@code
@@ -39,6 +49,8 @@
// FixMe: This crashes the game
@Mixin(BackgroundRenderer.class)
public class BackgroundRendererMixin {
+ @Shadow @Final private static List FOG_MODIFIERS;
+
@Redirect(method = "getFogColor", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/Vec3d;getX()D"))
private static double redirectRed(Vec3d baseColor) {
return WorldColors.fogOfWarColor(baseColor).getX();
@@ -59,4 +71,15 @@ private static int redirectWaterFogColor(Biome biome) {
return WorldColors.waterFogColor(biome.getWaterFogColor());
}
+ @Inject(method = "getFogModifier(Lnet/minecraft/entity/Entity;F)Lnet/minecraft/client/render/BackgroundRenderer$StatusEffectFogModifier;", at = @At("HEAD"), cancellable = true)
+ private static void injectFogModifier(Entity entity, float tickProgress, CallbackInfoReturnable cir){
+ if (entity instanceof LivingEntity livingEntity) {
+ Stream modifiers = FOG_MODIFIERS
+ .stream()
+ .filter((modifier) ->
+ modifier.shouldApply(livingEntity, tickProgress) && NoRender.shouldAcceptFog(modifier)
+ );
+ cir.setReturnValue(modifiers.findFirst().orElse(null));
+ }
+ }
}
diff --git a/src/main/java/com/lambda/mixin/render/BeaconBlockEntityRendererMixin.java b/src/main/java/com/lambda/mixin/render/BeaconBlockEntityRendererMixin.java
new file mode 100644
index 000000000..a3d4b5e38
--- /dev/null
+++ b/src/main/java/com/lambda/mixin/render/BeaconBlockEntityRendererMixin.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2025 Lambda
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lambda.mixin.render;
+
+import com.lambda.module.modules.render.NoRender;
+import net.minecraft.block.entity.BlockEntity;
+import net.minecraft.client.render.VertexConsumerProvider;
+import net.minecraft.client.render.block.entity.BeaconBlockEntityRenderer;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.util.math.Vec3d;
+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(BeaconBlockEntityRenderer.class)
+public class BeaconBlockEntityRendererMixin {
+ @Inject(method = "render", at = @At("HEAD"), cancellable = true)
+ private void injectRender(BlockEntity entity, float tickProgress, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, Vec3d cameraPos, CallbackInfo ci) {
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoBeaconBeams()) ci.cancel();
+ }
+}
diff --git a/src/main/java/com/lambda/mixin/render/BlockEntityRenderDispatcherMixin.java b/src/main/java/com/lambda/mixin/render/BlockEntityRenderDispatcherMixin.java
new file mode 100644
index 000000000..268b07043
--- /dev/null
+++ b/src/main/java/com/lambda/mixin/render/BlockEntityRenderDispatcherMixin.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2025 Lambda
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lambda.mixin.render;
+
+import com.lambda.module.modules.render.NoRender;
+import net.minecraft.block.entity.BlockEntity;
+import net.minecraft.client.render.VertexConsumerProvider;
+import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
+import net.minecraft.client.render.block.entity.BlockEntityRenderer;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.util.math.Vec3d;
+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(BlockEntityRenderDispatcher.class)
+public class BlockEntityRenderDispatcherMixin {
+ @Inject(method = "render(Lnet/minecraft/client/render/block/entity/BlockEntityRenderer;Lnet/minecraft/block/entity/BlockEntity;FLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;Lnet/minecraft/util/math/Vec3d;)V", at = @At("HEAD"), cancellable = true)
+ private static void injectRender(BlockEntityRenderer renderer, BlockEntity blockEntity, float tickProgress, MatrixStack matrices, VertexConsumerProvider vertexConsumers, Vec3d cameraPos, CallbackInfo ci) {
+ if (NoRender.shouldOmitBlockEntity(blockEntity)) ci.cancel();
+ }
+}
diff --git a/src/main/java/com/lambda/mixin/render/BossBarHudMixin.java b/src/main/java/com/lambda/mixin/render/BossBarHudMixin.java
new file mode 100644
index 000000000..3b36abf94
--- /dev/null
+++ b/src/main/java/com/lambda/mixin/render/BossBarHudMixin.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2025 Lambda
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lambda.mixin.render;
+
+import com.lambda.module.modules.render.NoRender;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.hud.BossBarHud;
+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(BossBarHud.class)
+public class BossBarHudMixin {
+ @Inject(method = "render", at = @At("HEAD"), cancellable = true)
+ private void injectRender(DrawContext context, CallbackInfo ci) {
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoBossBar()) ci.cancel();
+ }
+}
diff --git a/src/main/java/com/lambda/mixin/render/CameraMixin.java b/src/main/java/com/lambda/mixin/render/CameraMixin.java
index f1f8f9fb5..ed91975c5 100644
--- a/src/main/java/com/lambda/mixin/render/CameraMixin.java
+++ b/src/main/java/com/lambda/mixin/render/CameraMixin.java
@@ -21,6 +21,8 @@
import com.lambda.module.modules.player.Freecam;
import com.lambda.module.modules.render.CameraTweaks;
import com.lambda.module.modules.render.FreeLook;
+import com.lambda.module.modules.render.NoRender;
+import net.minecraft.block.enums.CameraSubmersionType;
import net.minecraft.client.render.Camera;
import net.minecraft.entity.Entity;
import net.minecraft.world.BlockView;
@@ -145,4 +147,9 @@ private void onUpdateSetRotationArgs(Args args) {
args.set(1, FreeLook.INSTANCE.getCamera().getPitchF());
}
}
+
+ @Inject(method = "getSubmersionType", at = @At("HEAD"), cancellable = true)
+ private void injectGetSubmersionType(CallbackInfoReturnable cir) {
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoFluidOverlay()) cir.setReturnValue(CameraSubmersionType.NONE);
+ }
}
diff --git a/src/main/java/com/lambda/mixin/render/ElytraFeatureRendererMixin.java b/src/main/java/com/lambda/mixin/render/ElytraFeatureRendererMixin.java
index 464e9e71a..6562c893f 100644
--- a/src/main/java/com/lambda/mixin/render/ElytraFeatureRendererMixin.java
+++ b/src/main/java/com/lambda/mixin/render/ElytraFeatureRendererMixin.java
@@ -17,13 +17,18 @@
package com.lambda.mixin.render;
+import com.lambda.module.modules.render.NoRender;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
+import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.feature.ElytraFeatureRenderer;
import net.minecraft.client.render.entity.state.BipedEntityRenderState;
+import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier;
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(ElytraFeatureRenderer.class)
public class ElytraFeatureRendererMixin {
@@ -40,4 +45,9 @@ private static Identifier getTexture(Identifier original, BipedEntityRenderState
return original;
}
+
+ @Inject(method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/state/BipedEntityRenderState;FF)V", at = @At("HEAD"), cancellable = true)
+ private void injectRender(MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, BipedEntityRenderState bipedEntityRenderState, float f, float g, CallbackInfo ci) {
+ if (NoRender.INSTANCE.isEnabled()&& NoRender.getNoElytra()) ci.cancel();
+ }
}
diff --git a/src/main/java/com/lambda/mixin/render/EnchantingTableBlockEntityRendererMixin.java b/src/main/java/com/lambda/mixin/render/EnchantingTableBlockEntityRendererMixin.java
new file mode 100644
index 000000000..f80ca373d
--- /dev/null
+++ b/src/main/java/com/lambda/mixin/render/EnchantingTableBlockEntityRendererMixin.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2025 Lambda
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lambda.mixin.render;
+
+import com.lambda.module.modules.render.NoRender;
+import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
+import net.minecraft.client.render.VertexConsumer;
+import net.minecraft.client.render.block.entity.EnchantingTableBlockEntityRenderer;
+import net.minecraft.client.render.entity.model.BookModel;
+import net.minecraft.client.util.math.MatrixStack;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+
+@Mixin(EnchantingTableBlockEntityRenderer.class)
+public class EnchantingTableBlockEntityRendererMixin {
+ @WrapWithCondition(method = "render(Lnet/minecraft/block/entity/EnchantingTableBlockEntity;FLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/util/math/Vec3d;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/entity/model/BookModel;render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;II)V"))
+ private boolean wrapRender(BookModel instance, MatrixStack matrixStack, VertexConsumer vertexConsumer, int i, int j) {
+ return NoRender.INSTANCE.isDisabled() || !NoRender.getNoEnchantingTableBook();
+ }
+}
diff --git a/src/main/java/com/lambda/mixin/render/EntityRendererMixin.java b/src/main/java/com/lambda/mixin/render/EntityRendererMixin.java
new file mode 100644
index 000000000..69af3188a
--- /dev/null
+++ b/src/main/java/com/lambda/mixin/render/EntityRendererMixin.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2025 Lambda
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lambda.mixin.render;
+
+import com.lambda.module.modules.render.NoRender;
+import net.minecraft.client.render.Frustum;
+import net.minecraft.client.render.VertexConsumerProvider;
+import net.minecraft.client.render.entity.EntityRenderer;
+import net.minecraft.client.render.entity.state.EntityRenderState;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.entity.Entity;
+import net.minecraft.text.Text;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+
+@Mixin(EntityRenderer.class)
+public class EntityRendererMixin {
+ @Inject(method = "shouldRender(Lnet/minecraft/entity/Entity;Lnet/minecraft/client/render/Frustum;DDD)Z", at = @At("HEAD"), cancellable = true)
+ private void injectShouldRender(Entity entity, Frustum frustum, double x, double y, double z, CallbackInfoReturnable cir) {
+ if (NoRender.shouldOmitEntity(entity)) cir.cancel();
+ }
+
+ @Inject(method = "renderLabelIfPresent", at = @At("HEAD"), cancellable = true)
+ private void injectRenderLabelIfPresent(EntityRenderState state, Text text, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) {
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoNametags()) ci.cancel();
+ }
+}
diff --git a/src/main/java/com/lambda/mixin/render/GameRendererMixin.java b/src/main/java/com/lambda/mixin/render/GameRendererMixin.java
index fe6a2ac6b..48afd23af 100644
--- a/src/main/java/com/lambda/mixin/render/GameRendererMixin.java
+++ b/src/main/java/com/lambda/mixin/render/GameRendererMixin.java
@@ -20,6 +20,8 @@
import com.lambda.event.EventFlow;
import com.lambda.event.events.RenderEvent;
import com.lambda.graphics.RenderMain;
+import com.lambda.module.modules.render.NoRender;
+import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.minecraft.client.render.Camera;
@@ -27,6 +29,7 @@
import net.minecraft.client.render.RenderTickCounter;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.client.util.ObjectAllocator;
+import net.minecraft.item.ItemStack;
import org.joml.Matrix4f;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@@ -60,4 +63,14 @@ void onRenderWorld(WorldRenderer instance, ObjectAllocator allocator, RenderTick
RenderMain.render3D(positionMatrix, projectionMatrix);
}
+
+ @ModifyExpressionValue(method = "renderWorld", at = @At(value = "INVOKE", target = "Ljava/lang/Math;max(FF)F", ordinal = 0))
+ private float modifyMax(float original) {
+ return (NoRender.INSTANCE.isEnabled() && NoRender.getNoNausea()) ? 0 : original;
+ }
+
+ @Inject(method = "showFloatingItem", at = @At("HEAD"), cancellable = true)
+ private void injectShowFloatingItem(ItemStack floatingItem, CallbackInfo ci) {
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoFloatingItemAnimation()) ci.cancel();
+ }
}
diff --git a/src/main/java/com/lambda/mixin/render/HeadFeatureRendererMixin.java b/src/main/java/com/lambda/mixin/render/HeadFeatureRendererMixin.java
new file mode 100644
index 000000000..38834b1ac
--- /dev/null
+++ b/src/main/java/com/lambda/mixin/render/HeadFeatureRendererMixin.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2025 Lambda
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lambda.mixin.render;
+
+import com.lambda.module.modules.render.NoRender;
+import net.minecraft.client.render.VertexConsumerProvider;
+import net.minecraft.client.render.entity.feature.HeadFeatureRenderer;
+import net.minecraft.client.render.entity.state.LivingEntityRenderState;
+import net.minecraft.client.util.math.MatrixStack;
+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(HeadFeatureRenderer.class)
+public class HeadFeatureRendererMixin {
+ @Inject(method = "render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/state/LivingEntityRenderState;FF)V", at = @At("HEAD"), cancellable = true)
+ private void injectRender(MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, LivingEntityRenderState livingEntityRenderState, float f, float g, CallbackInfo ci) {
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoArmor() && NoRender.getIncludeNoOtherHeadItems()) ci.cancel();
+ }
+}
diff --git a/src/main/java/com/lambda/mixin/render/InGameHudMixin.java b/src/main/java/com/lambda/mixin/render/InGameHudMixin.java
index d225a9b9b..407ef5998 100644
--- a/src/main/java/com/lambda/mixin/render/InGameHudMixin.java
+++ b/src/main/java/com/lambda/mixin/render/InGameHudMixin.java
@@ -18,13 +18,20 @@
package com.lambda.mixin.render;
import com.lambda.gui.DearImGui;
+import com.lambda.module.modules.render.NoRender;
+import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.hud.InGameHud;
import net.minecraft.client.render.RenderTickCounter;
+import net.minecraft.entity.Entity;
+import net.minecraft.scoreboard.ScoreboardObjective;
+import net.minecraft.util.Identifier;
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.ModifyArgs;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import org.spongepowered.asm.mixin.injection.invoke.arg.Args;
@Mixin(InGameHud.class)
public class InGameHudMixin {
@@ -35,4 +42,52 @@ public class InGameHudMixin {
private void onRender(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) {
DearImGui.INSTANCE.render();
}
+
+ @Inject(method = "renderNauseaOverlay", at = @At("HEAD"), cancellable = true)
+ private void injectRenderNauseaOverlay(DrawContext context, float nauseaStrength, CallbackInfo ci) {
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoNausea()) ci.cancel();
+ }
+
+ @Inject(method = "renderPortalOverlay", at = @At("HEAD"), cancellable = true)
+ private void injectRenderPortalOverlay(DrawContext context, float nauseaStrength, CallbackInfo ci) {
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoPortalOverlay()) ci.cancel();
+ }
+
+ @Inject(method = "renderVignetteOverlay", at = @At("HEAD"), cancellable = true)
+ private void injectRenderVignetteOverlay(DrawContext context, Entity entity, CallbackInfo ci) {
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoVignette()) ci.cancel();
+ }
+
+ @Inject(method = "renderStatusEffectOverlay", at = @At("HEAD"), cancellable = true)
+ private void injectRenderStatusEffectOverlay(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) {
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoStatusEffects()) ci.cancel();
+ }
+
+ @Inject(method = "renderSpyglassOverlay", at = @At("HEAD"), cancellable = true)
+ private void injectRenderSpyglassOverlay(DrawContext context, float scale, CallbackInfo ci) {
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoSpyglassOverlay()) ci.cancel();
+ }
+
+ @ModifyArgs(method = "renderMiscOverlays", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/InGameHud;renderOverlay(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/util/Identifier;F)V"))
+ private void modifyRenderOverlayArgs(Args args) {
+ if (!((Identifier) args.get(1)).getPath().contains("pumpkin")) return;
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoPumpkinOverlay()) {
+ args.set(2, 0f);
+ }
+ }
+
+ @ModifyExpressionValue(method = "renderMiscOverlays", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/network/ClientPlayerEntity;getFrozenTicks()I"))
+ private int modifyIsFirstPerson(int original) {
+ return (NoRender.INSTANCE.isEnabled() && NoRender.getNoPowderedSnowOverlay()) ? 0 : original;
+ }
+
+ @Inject(method = "renderScoreboardSidebar(Lnet/minecraft/client/gui/DrawContext;Lnet/minecraft/scoreboard/ScoreboardObjective;)V", at = @At("HEAD"), cancellable = true)
+ private void injectRenderScoreboardSidebar(DrawContext drawContext, ScoreboardObjective objective, CallbackInfo ci) {
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoScoreBoard()) ci.cancel();
+ }
+
+ @Inject(method = "renderCrosshair", at = @At("HEAD"), cancellable = true)
+ private void injectRenderCrosshair(DrawContext context, RenderTickCounter tickCounter, CallbackInfo ci) {
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoCrosshair()) ci.cancel();
+ }
}
diff --git a/src/main/java/com/lambda/mixin/render/InGameOverlayRendererMixin.java b/src/main/java/com/lambda/mixin/render/InGameOverlayRendererMixin.java
index 6e314ba2b..8cdf4eecd 100644
--- a/src/main/java/com/lambda/mixin/render/InGameOverlayRendererMixin.java
+++ b/src/main/java/com/lambda/mixin/render/InGameOverlayRendererMixin.java
@@ -33,13 +33,13 @@
public class InGameOverlayRendererMixin {
@Inject(method = "renderFireOverlay", at = @At("HEAD"), cancellable = true)
private static void onRenderFireOverlay(MatrixStack matrices, VertexConsumerProvider vertexConsumers, CallbackInfo ci) {
- if (NoRender.INSTANCE.isEnabled() && NoRender.getNoBurning()) ci.cancel();
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoFireOverlay()) ci.cancel();
}
@ModifyArg(method = "renderFireOverlay", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;translate(FFF)V"), index = 1)
private static float onRenderFireOverlayTranslate(float x) {
if (NoRender.INSTANCE.isEnabled()) {
- return (float) NoRender.getFireOverlayYOffset();
+ return (float) NoRender.getFireOverlayYOffset() - 0.3f;
} else {
return -0.3f;
}
@@ -47,7 +47,7 @@ private static float onRenderFireOverlayTranslate(float x) {
@Inject(method = "renderUnderwaterOverlay", at = @At("HEAD"), cancellable = true)
private static void onRenderUnderwaterOverlay(MinecraftClient client, MatrixStack matrices, VertexConsumerProvider vertexConsumers, CallbackInfo ci) {
- if (NoRender.INSTANCE.isEnabled() && NoRender.getNoUnderwater()) ci.cancel();
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoFluidOverlay()) ci.cancel();
}
@Inject(method = "renderInWallOverlay", at = @At("HEAD"), cancellable = true)
diff --git a/src/main/java/com/lambda/mixin/render/LivingEntityRendererMixin.java b/src/main/java/com/lambda/mixin/render/LivingEntityRendererMixin.java
index ce93b0ff5..e9fff0577 100644
--- a/src/main/java/com/lambda/mixin/render/LivingEntityRendererMixin.java
+++ b/src/main/java/com/lambda/mixin/render/LivingEntityRendererMixin.java
@@ -23,7 +23,6 @@
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import net.minecraft.client.render.entity.LivingEntityRenderer;
import net.minecraft.entity.LivingEntity;
-import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
diff --git a/src/main/java/com/lambda/mixin/render/MobSpawnerBlockEntityRendererMixin.java b/src/main/java/com/lambda/mixin/render/MobSpawnerBlockEntityRendererMixin.java
new file mode 100644
index 000000000..e2233bf31
--- /dev/null
+++ b/src/main/java/com/lambda/mixin/render/MobSpawnerBlockEntityRendererMixin.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2025 Lambda
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lambda.mixin.render;
+
+import com.lambda.module.modules.render.NoRender;
+import net.minecraft.block.entity.MobSpawnerBlockEntity;
+import net.minecraft.client.render.VertexConsumerProvider;
+import net.minecraft.client.render.block.entity.MobSpawnerBlockEntityRenderer;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.util.math.Vec3d;
+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(MobSpawnerBlockEntityRenderer.class)
+public class MobSpawnerBlockEntityRendererMixin {
+ @Inject(method = "render(Lnet/minecraft/block/entity/MobSpawnerBlockEntity;FLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IILnet/minecraft/util/math/Vec3d;)V", at = @At("HEAD"), cancellable = true)
+ private void injectRender(MobSpawnerBlockEntity mobSpawnerBlockEntity, float f, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, int j, Vec3d vec3d, CallbackInfo ci) {
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoSpawnerMob()) ci.cancel();
+ }
+}
diff --git a/src/main/java/com/lambda/mixin/render/ParticleManagerMixin.java b/src/main/java/com/lambda/mixin/render/ParticleManagerMixin.java
new file mode 100644
index 000000000..654e32316
--- /dev/null
+++ b/src/main/java/com/lambda/mixin/render/ParticleManagerMixin.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2025 Lambda
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lambda.mixin.render;
+
+import com.lambda.module.modules.render.NoRender;
+import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import net.minecraft.client.particle.Particle;
+import net.minecraft.client.particle.ParticleManager;
+import net.minecraft.client.particle.ParticleTextureSheet;
+import net.minecraft.client.render.Camera;
+import net.minecraft.client.render.VertexConsumerProvider;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Unique;
+import org.spongepowered.asm.mixin.injection.At;
+
+import java.util.LinkedList;
+import java.util.Queue;
+import java.util.stream.Collectors;
+
+@Mixin(ParticleManager.class)
+public class ParticleManagerMixin {
+ // prevents the particles from being stored and potential overhead. Downside being they need to spawn back in rather than just enabling rendering again
+// @Inject(method = "addParticle(Lnet/minecraft/client/particle/Particle;)V", at = @At("HEAD"), cancellable = true)
+// private void injectAddParticle(Particle particle, CallbackInfo ci) {
+// if (NoRender.shouldOmitParticle(particle)) ci.cancel();
+// }
+
+ @WrapOperation(method = "renderParticles(Lnet/minecraft/client/render/Camera;FLnet/minecraft/client/render/VertexConsumerProvider$Immediate;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/ParticleManager;renderParticles(Lnet/minecraft/client/render/Camera;FLnet/minecraft/client/render/VertexConsumerProvider$Immediate;Lnet/minecraft/client/particle/ParticleTextureSheet;Ljava/util/Queue;)V"))
+ private void wrapRenderParticles(Camera camera, float tickProgress, VertexConsumerProvider.Immediate vertexConsumers, ParticleTextureSheet sheet, Queue particles, Operation original) {
+ original.call(camera, tickProgress, vertexConsumers, sheet, filterParticles(particles));
+ }
+
+ @WrapOperation(method = "renderParticles(Lnet/minecraft/client/render/Camera;FLnet/minecraft/client/render/VertexConsumerProvider$Immediate;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/ParticleManager;renderCustomParticles(Lnet/minecraft/client/render/Camera;FLnet/minecraft/client/render/VertexConsumerProvider$Immediate;Ljava/util/Queue;)V"))
+ private void wrapRenderParticles(Camera camera, float tickProgress, VertexConsumerProvider.Immediate vertexConsumers, Queue particles, Operation original) {
+ original.call(camera, tickProgress, vertexConsumers, filterParticles(particles));
+ }
+
+ @Unique
+ private Queue filterParticles(Queue particles) {
+ return particles.stream().filter(particle ->
+ !NoRender.shouldOmitParticle(particle)).collect(Collectors.toCollection(LinkedList::new)
+ );
+ }
+}
diff --git a/src/main/java/com/lambda/mixin/render/ScreenMixin.java b/src/main/java/com/lambda/mixin/render/ScreenMixin.java
index 2acb68348..1780bb8a7 100644
--- a/src/main/java/com/lambda/mixin/render/ScreenMixin.java
+++ b/src/main/java/com/lambda/mixin/render/ScreenMixin.java
@@ -18,16 +18,18 @@
package com.lambda.mixin.render;
import com.lambda.gui.components.QuickSearch;
+import com.lambda.module.modules.render.NoRender;
+import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(Screen.class)
public class ScreenMixin {
-
@Inject(method = "keyPressed", at = @At("HEAD"), cancellable = true)
private void onKeyPressed(int keyCode, int scanCode, int modifiers, CallbackInfoReturnable cir) {
if (keyCode == GLFW.GLFW_KEY_ESCAPE && QuickSearch.INSTANCE.isOpen()) {
@@ -35,4 +37,9 @@ private void onKeyPressed(int keyCode, int scanCode, int modifiers, CallbackInfo
cir.setReturnValue(true);
}
}
+
+ @Inject(method = "renderInGameBackground", at = @At("HEAD"), cancellable = true)
+ private void injectRenderInGameBackground(DrawContext context, CallbackInfo ci) {
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoGuiShadow()) ci.cancel();
+ }
}
diff --git a/src/main/java/com/lambda/mixin/render/WorldBorderRenderingMixin.java b/src/main/java/com/lambda/mixin/render/WorldBorderRenderingMixin.java
new file mode 100644
index 000000000..a5e6f9269
--- /dev/null
+++ b/src/main/java/com/lambda/mixin/render/WorldBorderRenderingMixin.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2025 Lambda
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package com.lambda.mixin.render;
+
+import com.lambda.module.modules.render.NoRender;
+import net.minecraft.client.render.WorldBorderRendering;
+import net.minecraft.util.math.Vec3d;
+import net.minecraft.world.border.WorldBorder;
+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(WorldBorderRendering.class)
+public class WorldBorderRenderingMixin {
+ @Inject(method = "render", at = @At("HEAD"), cancellable = true)
+ private void injectRender(WorldBorder border, Vec3d cameraPos, double viewDistanceBlocks, double farPlaneDistance, CallbackInfo ci) {
+ if (NoRender.INSTANCE.isEnabled() && NoRender.getNoWorldBorder()) ci.cancel();
+ }
+}
diff --git a/src/main/java/com/lambda/mixin/render/WorldRendererMixin.java b/src/main/java/com/lambda/mixin/render/WorldRendererMixin.java
index 7d05ddc7a..6282db8b8 100644
--- a/src/main/java/com/lambda/mixin/render/WorldRendererMixin.java
+++ b/src/main/java/com/lambda/mixin/render/WorldRendererMixin.java
@@ -19,12 +19,18 @@
import com.lambda.module.modules.player.Freecam;
import com.lambda.module.modules.render.CameraTweaks;
+import com.lambda.module.modules.render.NoRender;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.WorldRenderer;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.effect.StatusEffects;
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.ModifyArg;
import org.spongepowered.asm.mixin.injection.Redirect;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(WorldRenderer.class)
public class WorldRendererMixin {
@@ -37,4 +43,14 @@ private boolean renderIsThirdPerson(Camera camera) {
private boolean renderSetupTerrainModifyArg(boolean hasForcedFrustum) {
return Freecam.INSTANCE.isEnabled() || CameraTweaks.INSTANCE.isEnabled() || hasForcedFrustum;
}
+
+ @Inject(method = "hasBlindnessOrDarkness(Lnet/minecraft/client/render/Camera;)Z", at = @At(value = "HEAD"), cancellable = true)
+ private void modifyEffectCheck(Camera camera, CallbackInfoReturnable cir) {
+ Entity entity = camera.getFocusedEntity();
+ if (entity instanceof LivingEntity livingEntity && NoRender.INSTANCE.isEnabled()) {
+ boolean blind = livingEntity.hasStatusEffect(StatusEffects.BLINDNESS) && !NoRender.getNoBlindness();
+ boolean dark = livingEntity.hasStatusEffect(StatusEffects.DARKNESS) && !NoRender.getNoDarkness();
+ cir.setReturnValue(blind || dark);
+ }
+ }
}
diff --git a/src/main/java/com/lambda/mixin/world/ClientWorldMixin.java b/src/main/java/com/lambda/mixin/world/ClientWorldMixin.java
index de277f637..ec117bbbb 100644
--- a/src/main/java/com/lambda/mixin/world/ClientWorldMixin.java
+++ b/src/main/java/com/lambda/mixin/world/ClientWorldMixin.java
@@ -21,7 +21,6 @@
import com.lambda.event.events.EntityEvent;
import com.lambda.event.events.WorldEvent;
import com.lambda.module.modules.render.WorldColors;
-import com.lambda.util.math.ColorKt;
import net.minecraft.block.BlockState;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.Entity;
diff --git a/src/main/kotlin/com/lambda/module/modules/render/NoRender.kt b/src/main/kotlin/com/lambda/module/modules/render/NoRender.kt
index aee68a3aa..1636feb8c 100644
--- a/src/main/kotlin/com/lambda/module/modules/render/NoRender.kt
+++ b/src/main/kotlin/com/lambda/module/modules/render/NoRender.kt
@@ -19,17 +19,173 @@ package com.lambda.module.modules.render
import com.lambda.module.Module
import com.lambda.module.tag.ModuleTag
+import com.lambda.util.DynamicReflectionSerializer.remappedName
+import com.lambda.util.NamedEnum
+import com.lambda.util.reflections.scanResult
+import io.github.classgraph.ClassInfo
+import net.minecraft.block.entity.BlockEntity
+import net.minecraft.client.particle.Particle
+import net.minecraft.client.render.BackgroundRenderer.StatusEffectFogModifier
+import net.minecraft.entity.Entity
+import net.minecraft.entity.SpawnGroup
+import net.minecraft.entity.effect.StatusEffects
+//ToDo: Implement unimplemented settings. (Keep in mind compatibility with other mods like sodium)
object NoRender : Module(
name = "NoRender",
description = "Disables rendering of certain things",
tag = ModuleTag.RENDER,
) {
- @JvmStatic val noDarkness by setting("No Darkness", true)
- @JvmStatic val noBurning by setting("No Burning Overlay", true)
- @JvmStatic val fireOverlayYOffset by setting("Fire Overlay Y Offset", -0.3, -0.8..0.0, 0.1) { !noBurning }
- @JvmStatic val noUnderwater by setting("No Underwater Overlay", true)
- @JvmStatic val noInWall by setting("No In Wall Overlay", true)
- @JvmStatic val noChatVerificationToast by setting("No Chat Verification Toast", true)
- @JvmStatic val noExplosion by setting("No Explosions", true)
-}
+ private val entities = scanResult
+ .getSubclasses(Entity::class.java)
+ .filter { !it.isAbstract && it.name.startsWith("net.minecraft") }
+
+ private val particleMap = createParticleNameMap()
+ private val blockEntityMap = createBlockEntityNameMap()
+ private val playerEntityMap = createEntityNameMap("net.minecraft.client.network.")
+ private val bossEntityMap = createEntityNameMap("net.minecraft.entity.boss.")
+ private val decorationEntityMap = createEntityNameMap("net.minecraft.entity.decoration.")
+ private val mobEntityMap = createEntityNameMap("net.minecraft.entity.mob.")
+ private val passiveEntityMap = createEntityNameMap("net.minecraft.entity.passive.")
+ private val projectileEntityMap = createEntityNameMap("net.minecraft.entity.projectile.")
+ private val vehicleEntityMap = createEntityNameMap("net.minecraft.entity.vehicle.")
+ private val miscEntityMap = createEntityNameMap("net.minecraft.entity.", strictDir = true)
+
+ private enum class Group(override val displayName: String) : NamedEnum {
+ Hud("Hud"),
+ Entity("Entity"),
+ World("World"),
+ Effect("Effect")
+ }
+
+ @JvmStatic val noBlindness by setting("No Blindness", true).group(Group.Effect)
+ @JvmStatic val noDarkness by setting("No Darkness", true).group(Group.Effect)
+ @JvmStatic val noNausea by setting("No Nausea", true).group(Group.Effect)
+
+ @JvmStatic val noFireOverlay by setting("No Fire Overlay", false).group(Group.Hud)
+ @JvmStatic val fireOverlayYOffset by setting("Fire Overlay Y Offset", 0.3, -0.4..0.4, 0.02) { !noFireOverlay }.group(Group.Hud)
+ @JvmStatic val noPortalOverlay by setting("No Portal Overlay", true).group(Group.Hud)
+ @JvmStatic val noFluidOverlay by setting("No Fluid Overlay", true).group(Group.Hud)
+ @JvmStatic val noPowderedSnowOverlay by setting("No Powdered Snow Overlay", true).group(Group.Hud)
+ @JvmStatic val noInWall by setting("No In Wall Overlay", true).group(Group.Hud)
+ @JvmStatic val noPumpkinOverlay by setting("No Pumpkin Overlay", true).group(Group.Hud)
+ @JvmStatic val noVignette by setting("No Vignette", true).group(Group.Hud)
+ @JvmStatic val noChatVerificationToast by setting("No Chat Verification Toast", true).group(Group.Hud)
+ @JvmStatic val noSpyglassOverlay by setting("No Spyglass Overlay", false).group(Group.Hud)
+ @JvmStatic val noGuiShadow by setting("No Gui Shadow", false).group(Group.Hud)
+ @JvmStatic val noFloatingItemAnimation by setting("No Floating Item Animation", false, "Disables floating item animations, typically used when a totem pops").group(Group.Hud)
+ @JvmStatic val noCrosshair by setting("No Crosshair", false).group(Group.Hud)
+ @JvmStatic val noBossBar by setting("No Boss Bar", false).group(Group.Hud)
+ @JvmStatic val noScoreBoard by setting("No Score Board", false).group(Group.Hud)
+ @JvmStatic val noStatusEffects by setting("No Status Effects", false).group(Group.Hud)
+
+ @JvmStatic val noArmor by setting("No Armor", false).group(Group.Entity)
+ @JvmStatic val noElytra by setting("No Elytra", false).group(Group.Entity)
+ @JvmStatic val includeNoOtherHeadItems by setting("Include No Other Head Items", false) { noArmor }.group(Group.Entity)
+ @JvmStatic val noInvisibility by setting("No Invisibility", true).group(Group.Entity)
+ @JvmStatic val noGlow by setting("No Glow", false).group(Group.Entity)
+ @JvmStatic val noNametags by setting("No Nametags", false).group(Group.Entity)
+// RenderLayer.getArmorEntityGlint(), RenderLayer.getGlint(), RenderLayer.getGlintTranslucent(), RenderLayer.getEntityGlint()
+// @JvmStatic val noEnchantmentGlint by setting("No Enchantment Glint", false).group(Group.Entity)
+// @JvmStatic val noDeadEntities by setting("No Dead Entities", false).group(Group.Entity)
+ private val playerEntities by setting("Player Entities", playerEntityMap.values.toSet(), emptySet(), "Player entities to omit from rendering").group(Group.Entity)
+ private val bossEntities by setting("Boss Entities", bossEntityMap.values.toSet(), emptySet(), "Boss entities to omit from rendering").group(Group.Entity)
+ private val decorationEntities by setting("Decoration Entities", decorationEntityMap.values.toSet(), emptySet(), "Decoration entities to omit from rendering").group(Group.Entity)
+ private val mobEntities by setting("Mob Entities", mobEntityMap.values.toSet(), emptySet(), "Mob entities to omit from rendering").group(Group.Entity)
+ private val passiveEntities by setting("Passive Entities", passiveEntityMap.values.toSet(), emptySet(), "Passive entities to omit from rendering").group(Group.Entity)
+ private val projectileEntities by setting("Projectile Entities", projectileEntityMap.values.toSet(), emptySet(), "Projectile entities to omit from rendering").group(Group.Entity)
+ private val vehicleEntities by setting("Vehicle Entities", vehicleEntityMap.values.toSet(), emptySet(), "Vehicle entities to omit from rendering").group(Group.Entity)
+ private val miscEntities by setting("Misc Entities", miscEntityMap.values.toSet(), emptySet(), "Miscellaneous entities to omit from rendering").group(Group.Entity)
+ private val blockEntities by setting("Block Entities", blockEntityMap.values.toSet(), emptySet(), "Block entities to omit from rendering").group(Group.Entity)
+
+ @JvmStatic val noSignText by setting("No Sign Text", false).group(Group.World)
+ @JvmStatic val noWorldBorder by setting("No World Border", false).group(Group.World)
+ @JvmStatic val noEnchantingTableBook by setting("No Enchanting Table Book", false).group(Group.World)
+ // Couldn't get to work with block entities without crashing with sodium on boot
+// @JvmStatic val noBlockBreakingOverlay by setting("No Block Breaking Overlay", false).group(Group.World)
+ @JvmStatic val noBeaconBeams by setting("No Beacon Beams", false).group(Group.World)
+ @JvmStatic val noSpawnerMob by setting("No Spawner Mob", false).group(Group.World)
+ private val particles by setting("Particles", particleMap.values.toSet(), emptySet(), "Particles to omit from rendering").group(Group.World)
+
+ private fun createParticleNameMap() =
+ scanResult
+ .getSubclasses(Particle::class.java)
+ .filter { !it.isAbstract }.createNameMap("net.minecraft.client.particle.", "Particle")
+
+ private fun createEntityNameMap(directory: String, strictDir: Boolean = false) =
+ entities.createNameMap(directory, "Entity", strictDir)
+
+ private fun createBlockEntityNameMap() =
+ scanResult
+ .getSubclasses(BlockEntity::class.java)
+ .filter { !it.isAbstract }.createNameMap("net.minecraft.block.entity", "BlockEntity")
+
+ private fun Collection.createNameMap(
+ directory: String,
+ removePattern: String = "",
+ strictDirectory: Boolean = false
+ ) = map {
+ val remappedName = it.name.remappedName
+ val displayName = remappedName
+ .substring(remappedName.indexOfLast { it == '.' } + 1)
+ .replace(removePattern, "")
+ .fancyFormat()
+ MappingInfo(it.simpleName, remappedName, displayName)
+ }
+ .sortedBy { it.displayName.lowercase() }
+ .filter { info ->
+ if (strictDirectory)
+ info.remapped.startsWith(directory) && !info.remapped.substring(directory.length).contains(".")
+ else info.remapped.startsWith(directory)
+ }
+ .associate { it.raw to it.displayName }
+
+ private fun String.fancyFormat() =
+ replace("$", " - ").replace("(?
+ miscEntityMap[simpleName] in miscEntities ||
+ playerEntityMap[simpleName] in playerEntities ||
+ projectileEntityMap[simpleName] in projectileEntities ||
+ vehicleEntityMap[simpleName] in vehicleEntities ||
+ decorationEntityMap[simpleName] in decorationEntities ||
+ passiveEntityMap[simpleName] in passiveEntities ||
+ mobEntityMap[simpleName] in mobEntities ||
+ bossEntityMap[simpleName] in bossEntities
+ SpawnGroup.WATER_AMBIENT,
+ SpawnGroup.WATER_CREATURE,
+ SpawnGroup.AMBIENT,
+ SpawnGroup.AXOLOTLS,
+ SpawnGroup.CREATURE,
+ SpawnGroup.UNDERGROUND_WATER_CREATURE -> passiveEntityMap[simpleName] in passiveEntities
+ SpawnGroup.MONSTER -> mobEntityMap[simpleName] in mobEntities
+ }
+ }
+
+ @JvmStatic
+ fun shouldOmitBlockEntity(blockEntity: BlockEntity) =
+ isEnabled && blockEntityMap[blockEntity.javaClass.simpleName] in blockEntities
+
+ @JvmStatic
+ fun shouldAcceptFog(modifier: StatusEffectFogModifier) =
+ when {
+ isDisabled -> true
+ modifier.statusEffect == StatusEffects.BLINDNESS && noBlindness -> false
+ modifier.statusEffect == StatusEffects.DARKNESS && noDarkness -> false
+ else -> true
+ }
+
+ private data class MappingInfo(
+ val raw: String,
+ val remapped: String,
+ val displayName: String
+ )
+}
\ No newline at end of file
diff --git a/src/main/kotlin/com/lambda/util/DynamicException.kt b/src/main/kotlin/com/lambda/util/DynamicException.kt
index 1b3d82292..d62331f8c 100644
--- a/src/main/kotlin/com/lambda/util/DynamicException.kt
+++ b/src/main/kotlin/com/lambda/util/DynamicException.kt
@@ -17,7 +17,7 @@
package com.lambda.util
-import com.lambda.util.DynamicReflectionSerializer.remappedName
+import com.lambda.util.DynamicReflectionSerializer.simpleRemappedName
import java.io.PrintStream
import java.io.PrintWriter
@@ -25,8 +25,8 @@ class DynamicException(original: Throwable) : Throwable(original) {
private fun Array.remapClassNames() =
map { element ->
StackTraceElement(
- element.className.remappedName,
- element.methodName.remappedName,
+ element.className.simpleRemappedName,
+ element.methodName.simpleRemappedName,
element.fileName,
element.lineNumber
)
diff --git a/src/main/kotlin/com/lambda/util/DynamicReflectionSerializer.kt b/src/main/kotlin/com/lambda/util/DynamicReflectionSerializer.kt
index a0ffc7ae1..1d30c3008 100644
--- a/src/main/kotlin/com/lambda/util/DynamicReflectionSerializer.kt
+++ b/src/main/kotlin/com/lambda/util/DynamicReflectionSerializer.kt
@@ -33,11 +33,13 @@ import net.minecraft.nbt.NbtCompound
import net.minecraft.registry.RegistryKey
import net.minecraft.registry.entry.RegistryEntry
import net.minecraft.screen.ScreenHandlerType
+import net.minecraft.text.MutableText
import net.minecraft.text.Text
import net.minecraft.util.Identifier
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.ChunkPos
import org.apache.logging.log4j.Logger
+import java.io.File
import java.lang.reflect.InaccessibleObjectException
import java.util.*
import kotlin.jvm.optionals.getOrDefault
@@ -66,6 +68,7 @@ object DynamicReflectionSerializer : Loadable {
TranslationStorage::class,
ChunkPos::class,
Text::class,
+ MutableText::class,
org.slf4j.Logger::class,
String::class,
)
@@ -75,44 +78,59 @@ object DynamicReflectionSerializer : Loadable {
private const val INDENT = 2
- private val mappings = runBlocking {
+ private val simpleMappings = runBlocking {
"${LambdaAPI.mappings}/${LambdaAPI.GAME_VERSION}"
- .downloadIfNotPresent(cache.resolveFile(LambdaAPI.GAME_VERSION))
- .map { file ->
- val standardMappings = file.readLines()
- .map { it.split(' ') }
- .filter { it.size == 2 }
- .associate { (obf, deobf) -> obf to deobf }
-
- buildMap {
- putAll(standardMappings)
-
- standardMappings.forEach { (obf, deobf) ->
- put(obf.split('$').last(), deobf)
- if ('$' !in obf) return@forEach
- put(obf.replace('$', '.'), deobf)
- val parts = obf.split('$')
- if (!parts.all { it.startsWith("class_") }) return@forEach
- (1 until parts.size).forEach { i ->
- put("${parts.take(i).joinToString("$")}.${parts.drop(i).joinToString("$")}", deobf)
- }
- }
- }
+ .downloadIfNotPresent(cache.resolveFile("${LambdaAPI.GAME_VERSION}-simple"))
+ .map(::buildMappingsMap)
+ .getOrElse {
+ LOG.error("Unable to download simplified deobfuscated qualifiers", it)
+ emptyMap()
}
+ }
+
+ private val qualifiedMappings = runBlocking {
+ "${LambdaAPI.mappings}/${LambdaAPI.GAME_VERSION}-qualified"
+ .downloadIfNotPresent(cache.resolveFile(LambdaAPI.GAME_VERSION))
+ .map(::buildMappingsMap)
.getOrElse {
LOG.error("Unable to download deobfuscated qualifiers", it)
emptyMap()
}
}
+ val String.simpleRemappedName get() = simpleMappings.getOrDefault(this, this)
+ val String.remappedName get() = qualifiedMappings.getOrDefault(this, this)
+
+ private fun buildMappingsMap(file: File): Map {
+ val standardMappings = file.readLines()
+ .map { it.split(' ') }
+ .filter { it.size == 2 }
+ .associate { (obf, deobf) -> obf to deobf }
+
+ return buildMap {
+ putAll(standardMappings)
+ standardMappings.forEach { (obf, deobf) ->
+ val parts = obf.split('$')
+ put(parts.last(), deobf)
+ if ('$' !in obf) return@forEach
+ put(obf.replace('$', '.'), deobf)
+ if (!parts.all { it.startsWith("class_") }) return@forEach
+ (1 until parts.size).forEach { i ->
+ put("${parts.take(i).joinToString("$")}.${parts.drop(i).joinToString("$")}", deobf)
+ }
+ }
+ }
+ }
- val String.remappedName get() = mappings.getOrDefault(this, this)
-
- fun KClass.dynamicName(remap: Boolean) =
- if (remap) qualifiedName?.remappedName else simpleName
+ fun KClass.dynamicName(remap: Boolean, simple: Boolean = true) =
+ if (remap)
+ if (simple) qualifiedName?.simpleRemappedName else qualifiedName?.remappedName
+ else if (simple) simpleName else qualifiedName
- fun KProperty1.dynamicName(remap: Boolean) =
- if (remap) name.remappedName else name
+ fun KProperty1.dynamicName(remap: Boolean, simple: Boolean = true) =
+ if (remap)
+ if (simple) name.simpleRemappedName else name.remappedName
+ else name
fun Any.dynamicString(
maxRecursionDepth: Int = 6,
@@ -121,14 +139,15 @@ object DynamicReflectionSerializer : Loadable {
visitedObjects: MutableSet = HashSet(),
builder: StringBuilder = StringBuilder(),
remap: Boolean = !Lambda.isDebug,
+ simple: Boolean = true
): String {
if (visitedObjects.contains(this)) {
- builder.appendLine("$indent${this::class.dynamicName(remap)} (Circular Reference)")
+ builder.appendLine("$indent${this::class.dynamicName(remap, simple)} (Circular Reference)")
return builder.toString()
}
visitedObjects.add(this)
- builder.appendLine("$indent${this::class.dynamicName(remap)}")
+ builder.appendLine("$indent${this::class.dynamicName(remap, simple)}")
this::class.memberProperties
.forEach { processField(it, indent, builder, currentDepth, maxRecursionDepth, visitedObjects, remap) }
@@ -197,5 +216,5 @@ object DynamicReflectionSerializer : Loadable {
}
}
- override fun load() = "Loaded ${mappings.size} deobfuscated qualifier"
+ override fun load() = "Loaded ${simpleMappings.size} deobfuscated qualifier"
}
diff --git a/src/main/resources/lambda.accesswidener b/src/main/resources/lambda.accesswidener
index 46df51c1f..0cc97047a 100644
--- a/src/main/resources/lambda.accesswidener
+++ b/src/main/resources/lambda.accesswidener
@@ -9,8 +9,8 @@ transitive-accessible field net/minecraft/client/input/Input movementVector Lnet
transitive-accessible field net/minecraft/client/MinecraftClient renderTaskQueue Ljava/util/Queue;
transitive-accessible field net/minecraft/client/option/KeyBinding boundKey Lnet/minecraft/client/util/InputUtil$Key;
transitive-accessible method net/minecraft/client/MinecraftClient getWindowTitle ()Ljava/lang/String;
-accessible field net/minecraft/client/option/KeyBinding KEYS_BY_ID Ljava/util/Map;
-accessible method net/minecraft/client/option/KeyBinding reset ()V
+transitive-accessible field net/minecraft/client/option/KeyBinding KEYS_BY_ID Ljava/util/Map;
+transitive-accessible method net/minecraft/client/option/KeyBinding reset ()V
# World
transitive-accessible field net/minecraft/client/world/ClientWorld entityManager Lnet/minecraft/world/entity/ClientEntityManager;
@@ -26,6 +26,7 @@ transitive-accessible method net/minecraft/item/BlockItem placeFromNbt (Lnet/min
transitive-accessible method net/minecraft/item/BlockItem postPlacement (Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/World;Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/item/ItemStack;Lnet/minecraft/block/BlockState;)Z
transitive-accessible method net/minecraft/item/BlockItem getPlaceSound (Lnet/minecraft/block/BlockState;)Lnet/minecraft/sound/SoundEvent;
transitive-accessible field net/minecraft/state/State owner Ljava/lang/Object;
+transitive-accessible class net/minecraft/client/render/BackgroundRenderer$StatusEffectFogModifier
# Entity
transitive-accessible field net/minecraft/entity/projectile/FireworkRocketEntity shooter Lnet/minecraft/entity/LivingEntity;
diff --git a/src/main/resources/lambda.mixins.common.json b/src/main/resources/lambda.mixins.common.json
index d306b5035..6a274c926 100644
--- a/src/main/resources/lambda.mixins.common.json
+++ b/src/main/resources/lambda.mixins.common.json
@@ -27,8 +27,13 @@
"network.HandshakeC2SPacketMixin",
"network.LoginHelloC2SPacketMixin",
"network.LoginKeyC2SPacketMixin",
+ "render.AbstractSignBlockEntityRendererMixin",
+ "render.ArmorFeatureRendererMixin",
"render.BackgroundRendererMixin",
+ "render.BeaconBlockEntityRendererMixin",
+ "render.BlockEntityRenderDispatcherMixin",
"render.BlockRenderManagerMixin",
+ "render.BossBarHudMixin",
"render.CameraMixin",
"render.CapeFeatureRendererMixin",
"render.ChatHudMixin",
@@ -37,13 +42,18 @@
"render.DebugHudMixin",
"render.DebugRendererMixin",
"render.ElytraFeatureRendererMixin",
+ "render.EnchantingTableBlockEntityRendererMixin",
+ "render.EntityRendererMixin",
"render.GameRendererMixin",
"render.GlStateManagerMixin",
+ "render.HeadFeatureRendererMixin",
"render.HeldItemRendererMixin",
"render.InGameHudMixin",
"render.InGameOverlayRendererMixin",
"render.LightmapTextureManagerMixin",
"render.LivingEntityRendererMixin",
+ "render.MobSpawnerBlockEntityRendererMixin",
+ "render.ParticleManagerMixin",
"render.PlayerListHudMixin",
"render.RenderLayersMixin",
"render.ScreenHandlerMixin",
@@ -51,6 +61,7 @@
"render.SplashOverlayMixin",
"render.SplashOverlayMixin$LogoTextureMixin",
"render.TooltipComponentMixin",
+ "render.WorldBorderRenderingMixin",
"render.WorldRendererMixin",
"world.BlockCollisionSpliteratorMixin",
"world.ClientChunkManagerMixin",