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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 61 additions & 2 deletions src/main/java/meteordevelopment/meteorclient/MixinPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public class MixinPlugin implements IMixinConfigPlugin {
private static boolean isBaritonePresent;
private static boolean isMetallumPresent;

private static boolean isModernSodium;

@Override
public void onLoad(String mixinPackage) {
if (loaded) return;
Expand All @@ -38,9 +40,57 @@ public void onLoad(String mixinPackage) {
isBaritonePresent = FabricLoader.getInstance().isModLoaded("baritone") || FabricLoader.getInstance().isModLoaded("baritone-meteor");
isMetallumPresent = FabricLoader.getInstance().isModLoaded("metallum");

isModernSodium = detectModernSodium();

loaded = true;
}

private static boolean detectModernSodium() {
var sodium = FabricLoader.getInstance().getModContainer("sodium");
if (sodium.isEmpty()) {
return false;
}

String version = sodium.get().getMetadata().getVersion().getFriendlyString();

String versionMatch = version.replaceFirst(".*?(0\\.\\d+\\.\\d+).*", "$1");

if (versionMatch.isEmpty() || versionMatch.equals(version)) {
String normalized = version.toLowerCase();
int idx = normalized.indexOf("0.");
if (idx >= 0) {
versionMatch = normalized.substring(idx);
int end = versionMatch.indexOf('-');
if (end >= 0) versionMatch = versionMatch.substring(0, end);
}
}

if (versionMatch.isEmpty()) {
return false;
}

String[] parts = versionMatch.split("\\.");
if (parts.length < 2) {
return false;
}

try {
int major = Integer.parseInt(parts[0]);
int minor = Integer.parseInt(parts[1]);
int patch = parts.length > 2 ? Integer.parseInt(parts[2]) : 0;

// 0.9.2 and below -> old
// 0.9.3 and above -> new
if (major == 0 && minor == 9) {
return patch >= 3;
}

return major > 0 || minor > 9;
} catch (NumberFormatException e) {
return false;
}
}

@Override
public String getRefMapperConfig() {
return null;
Expand All @@ -53,7 +103,17 @@ public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
} else if (mixinClassName.endsWith("PlayerEntityRendererMixin")) {
return !isOriginsPresent;
} else if (mixinClassName.startsWith(mixinPackage + ".sodium")) {
return isSodiumPresent;
if (!isSodiumPresent) return false;

if (mixinClassName.endsWith("SodiumDefaultFluidRendererOldMixin")) {
return !isModernSodium;
}

if (mixinClassName.endsWith("SodiumDefaultFluidRendererNewMixin")) {
return isModernSodium;
}

return true;
} else if (mixinClassName.startsWith(mixinPackage + ".indigo")) {
return isIndigoPresent;
} else if (mixinClassName.startsWith(mixinPackage + ".lithium")) {
Expand All @@ -64,7 +124,6 @@ public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
return isMetallumPresent;
}


return true;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client).
* Copyright (c) Meteor Development.
*/

package meteordevelopment.meteorclient.mixin.sodium;

import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import com.llamalad7.mixinextras.sugar.Local;
import meteordevelopment.meteorclient.systems.modules.Modules;
import meteordevelopment.meteorclient.systems.modules.render.Xray;
import net.caffeinemc.mods.sodium.client.model.color.ColorProvider;
import net.caffeinemc.mods.sodium.client.model.light.LightPipeline;
import net.caffeinemc.mods.sodium.client.model.quad.ModelQuadViewMutable;
import net.caffeinemc.mods.sodium.client.model.quad.properties.ModelQuadFacing;
import net.caffeinemc.mods.sodium.client.render.chunk.compile.buffers.ChunkModelBuilder;
import net.caffeinemc.mods.sodium.client.render.chunk.compile.pipeline.DefaultFluidRenderer;
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.material.DefaultMaterials;
import net.caffeinemc.mods.sodium.client.render.chunk.terrain.material.Material;
import net.caffeinemc.mods.sodium.client.render.chunk.translucent_sorting.TranslucentGeometryCollector;
import net.caffeinemc.mods.sodium.client.world.LevelSlice;
import net.minecraft.client.renderer.block.BlockAndTintGetter;
import net.minecraft.client.renderer.block.FluidModel;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.FluidState;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
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.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(value = DefaultFluidRenderer.class, remap = false)
public abstract class SodiumDefaultFluidRendererNewMixin {
@Final
@Shadow
private int[] quadColors;

@Unique
private int xrayAlpha;
@Unique
private boolean forceXrayFluidSides;
@Unique
private Xray xray;

@Inject(method = "<init>", at = @At("TAIL"))
private void onInit(CallbackInfo ci) {
xray = Modules.get().get(Xray.class);
}

@Inject(method = "render", at = @At("HEAD"), cancellable = true)
private void onRender(LevelSlice level, BlockState blockState, FluidState fluidState, BlockPos blockPos, BlockPos offset, TranslucentGeometryCollector collector, ChunkModelBuilder meshBuilder, Material material, ColorProvider<FluidState> colorProvider, FluidModel sprites, CallbackInfo ci) {
xrayAlpha = Xray.getFluidAlpha(fluidState, blockPos);
forceXrayFluidSides = xray.isActive();

// Cancel block rendering when alpha is 0, required for Iris support but unnecessary to check for shaders, we already force be disabled when Xray is enabled
if (xrayAlpha == 0) {
forceXrayFluidSides = false;
ci.cancel();
}
}

@ModifyReturnValue(method = "isFullBlockFluidSideVisible", at = @At("RETURN"))
private boolean onIsFullBlockFluidSideVisible(boolean original, BlockGetter view, BlockPos selfPos, Direction facing, FluidState fluid, @Local(name = "otherState") BlockState otherState) {
if (original || !forceXrayFluidSides || facing.getAxis().isVertical()) return original;
if (!xray.isBlocked(otherState.getBlock(), null)) return false;

return !otherState.getFluidState().getType().isSame(fluid.getType());
}

@ModifyReturnValue(method = "isFullBlockFluidSelfVisible(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/Direction;)Z", at = @At("RETURN"))
private boolean onIsFullBlockFluidSelfVisible(boolean original, BlockState selfBlockState, Direction facing) {
if (!forceXrayFluidSides || facing.getAxis().isVertical()) return original;

// Xray should ignore the block's own occlusion for fluid faces we are intentionally exposing.
return true;
}

@ModifyReturnValue(method = "isSliceFluidSelfVisible(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/Direction;FF)Z", at = @At("RETURN"))
private boolean onIsSliceFluidSelfVisible(boolean original, BlockState selfBlockState, Direction facing, float minThickness, float maxThickness) {
if (!forceXrayFluidSides || facing.getAxis().isVertical()) return original;

// Xray should ignore self-occlusion when the fluid face is being forced visible.
return true;
}

@ModifyReturnValue(method = "isFluidSideExposed(Lnet/minecraft/client/renderer/block/BlockAndTintGetter;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/Direction;F)Z", at = @At("RETURN"))
private boolean onIsFluidSideExposed(boolean original, BlockAndTintGetter world, BlockState ownBlockState, BlockPos neighborPos, Direction facing, float height) {
BlockState neighborBlockState = world.getBlockState(neighborPos);

if (original || !forceXrayFluidSides || facing.getAxis().isVertical()) return original;
if (!xray.isBlocked(neighborBlockState.getBlock(), null)) return false;

return !neighborBlockState.getFluidState().getType().isSame(ownBlockState.getFluidState().getType());
}

@Inject(method = "getUpFaceExposureByNeighbors", at = @At("HEAD"), cancellable = true)
private void onGetUpFaceExposureByNeighbors(BlockAndTintGetter level, BlockPos origin, FluidState fluidState, CallbackInfoReturnable<Integer> cir) {
if (forceXrayFluidSides) cir.setReturnValue(3);
}

@Inject(method = "updateQuad", at = @At("TAIL"))
private void onUpdateQuad(ModelQuadViewMutable quad, LevelSlice level, BlockPos pos, LightPipeline lighter, Direction dir, ModelQuadFacing facing, float brightness, ColorProvider<FluidState> colorProvider, FluidState fluidState, CallbackInfo ci) {
if (xrayAlpha != -1) {
for (int i = 0; i < 4; i++) {
quadColors[i] = (quadColors[i] & 0x00FFFFFF) | (xrayAlpha << 24);
}
}
}

@ModifyArg(method = "render", at = @At(value = "INVOKE", target = "Lnet/caffeinemc/mods/sodium/client/render/chunk/compile/pipeline/DefaultFluidRenderer;writeQuad(Lnet/caffeinemc/mods/sodium/client/render/chunk/compile/buffers/ChunkModelBuilder;Lnet/caffeinemc/mods/sodium/client/render/chunk/translucent_sorting/TranslucentGeometryCollector;Lnet/caffeinemc/mods/sodium/client/render/chunk/terrain/material/Material;Lnet/minecraft/core/BlockPos;Lnet/caffeinemc/mods/sodium/client/model/quad/ModelQuadView;Lnet/caffeinemc/mods/sodium/client/model/quad/properties/ModelQuadFacing;Z)V"), index = 2)
private Material modifyMaterial(Material material) {
if (xrayAlpha != -1) {
return DefaultMaterials.TRANSLUCENT;
}
return material;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

@Mixin(value = DefaultFluidRenderer.class, remap = false)
public abstract class SodiumDefaultFluidRendererMixin {
public abstract class SodiumDefaultFluidRendererOldMixin {
@Final
@Shadow
private int[] quadColors;
Expand Down
3 changes: 2 additions & 1 deletion src/main/resources/meteor-client-sodium.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"AbstractBlockRenderContextMixin",
"SodiumBlockRendererMixin",
"SodiumChunkBuilderMeshingTaskMixin",
"SodiumDefaultFluidRendererMixin",
"SodiumDefaultFluidRendererOldMixin",
"SodiumDefaultFluidRendererNewMixin",
"SodiumFluidRendererImplDefaultRenderContextMixin",
"SodiumFluidRendererImplMixin",
"SodiumLightDataAccessMixin",
Expand Down