Add MC 1.21.3 support for Neoforge (no fabric)

This commit is contained in:
James Seibel
2024-11-02 11:21:03 -05:00
parent 8eba8cb40b
commit 8be161b381
50 changed files with 1195 additions and 671 deletions
@@ -25,7 +25,6 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRen
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 com.mojang.blaze3d.systems.RenderSystem;
@@ -35,10 +34,18 @@ import net.minecraft.client.renderer.FogRenderer.FogMode;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
#if MC_VER < MC_1_17_1
import net.minecraft.world.level.material.FluidState;
#else
org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#elif MC_VER < MC_1_21_3
import net.minecraft.world.level.material.FogType;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#else
import net.minecraft.client.renderer.FogParameters;
import net.minecraft.world.level.material.FogType;
import org.joml.Vector4f;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
#endif
@@ -46,24 +53,30 @@ import net.minecraft.world.level.material.FogType;
@Mixin(FogRenderer.class)
public class MixinFogRenderer
{
// Using this instead of Float.MAX_VALUE because Sodium don't like it.
private static final float A_REALLY_REALLY_BIG_VALUE = 420694206942069.F;
private static final float A_EVEN_LARGER_VALUE = 42069420694206942069.F;
#if MC_VER == MC_1_17_1 || MC_VER == MC_1_18_2
@Inject(at = @At("RETURN"),
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V",
remap = #if MC_VER == MC_1_17_1 || MC_VER == MC_1_18_2 false #else true #endif ) // Remap messiness due to this being weird in forge
remap = false)
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float partTick, CallbackInfo callback)
#elif MC_VER < MC_1_21_3
@Inject(at = @At("RETURN"),
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;FZF)V",
remap = true)
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float partTick, CallbackInfo callback)
#else
@Inject(at = @At("RETURN"),
method = "setupFog(Lnet/minecraft/client/Camera;Lnet/minecraft/client/renderer/FogRenderer$FogMode;Lorg/joml/Vector4f;FZF)Lnet/minecraft/client/renderer/FogParameters;",
remap = true, cancellable = true)
private static void disableSetupFog(Camera camera, FogMode fogMode, Vector4f vector4f, float f, boolean bl, float partTick, CallbackInfoReturnable<FogParameters> callback)
#endif
{
#if MC_VER < MC_1_17_1
FluidState fluidState = camera.getFluidInCamera();
boolean cameraNotInFluid = fluidState.isEmpty();
#else
FogType fogTypes = camera.getFluidInCamera();
boolean cameraNotInFluid = fogTypes == FogType.NONE;
#endif
boolean cameraNotInFluid = cameraNotInFluid(camera);
Entity entity = camera.getEntity();
boolean isSpecialFog = (entity instanceof LivingEntity) && ((LivingEntity) entity).hasEffect(MobEffects.BLINDNESS);
@@ -74,11 +87,27 @@ public class MixinFogRenderer
#if MC_VER < MC_1_17_1
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
RenderSystem.fogEnd(A_EVEN_LARGER_VALUE);
#else
#elif MC_VER < MC_1_21_3
RenderSystem.setShaderFogStart(A_REALLY_REALLY_BIG_VALUE);
RenderSystem.setShaderFogEnd(A_EVEN_LARGER_VALUE);
#else
callback.setReturnValue(FogParameters.NO_FOG);
#endif
}
}
private static boolean cameraNotInFluid(Camera camera)
{
#if MC_VER < MC_1_17_1
FluidState fluidState = camera.getFluidInCamera();
boolean cameraNotInFluid = fluidState.isEmpty();
#else
FogType fogTypes = camera.getFluidInCamera();
boolean cameraNotInFluid = fogTypes == FogType.NONE;
#endif
return cameraNotInFluid;
}
}
@@ -1,58 +0,0 @@
package com.seibel.distanthorizons.neoforge.mixins.client;
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import net.minecraft.client.renderer.GameRenderer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
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;
// TODO: Check if this port from fabric works
@Mixin(GameRenderer.class)
public class MixinGameRenderer
{
private static final Logger LOGGER = LogManager.getLogger(MixinGameRenderer.class.getSimpleName());
#if MC_VER >= MC_1_17_1
// FIXME: This I think will dup multiple renderStartupEvent calls...
@Inject(method = {"reloadShaders", "preloadUiShader"}, at = @At("TAIL"))
public void onStartupShaders(CallbackInfo ci)
{
LOGGER.info("Starting up renderer (forge)");
if (!DependencySetupDoneCheck.isDone)
{
LOGGER.warn("Dependency setup is not done yet, skipping renderer this startup event!");
return;
}
ClientApi.INSTANCE.rendererStartupEvent();
}
@Inject(method = "shutdownShaders", at = @At("HEAD"))
public void onShutdownShaders(CallbackInfo ci)
{
LOGGER.info("Shutting down renderer (forge)");
if (!DependencySetupDoneCheck.isDone)
{
LOGGER.warn("Dependency setup is not done yet, skipping renderer this shutdown event!");
return;
}
ClientApi.INSTANCE.rendererShutdownEvent();
}
#else
@Inject(method = {"loadEffect"}, at = @At("TAIL"))
public void onStartupShaders(CallbackInfo ci) {
ClientApi.INSTANCE.rendererStartupEvent();
}
@Inject(method = "shutdownEffect", at = @At("HEAD"))
public void onShutdownShaders(CallbackInfo ci) {
ClientApi.INSTANCE.rendererShutdownEvent();
}
#endif
}
@@ -122,8 +122,10 @@ public class MixinLevelRenderer
float frameTime;
#if MC_VER < MC_1_21_1
frameTime = Minecraft.getInstance().getFrameTime();
#else
#elif MC_VER < MC_1_21_3
frameTime = Minecraft.getInstance().getTimer().getRealtimeDeltaTicks();
#else
frameTime = Minecraft.getInstance().deltaTracker.getRealtimeDeltaTicks();
#endif
@@ -20,14 +20,17 @@
package com.seibel.distanthorizons.neoforge.mixins.client;
import com.mojang.blaze3d.pipeline.TextureTarget;
import com.mojang.blaze3d.platform.NativeImage;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.render.glObject.GLState;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import net.minecraft.client.renderer.LightTexture;
import org.lwjgl.opengl.GL32;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -38,6 +41,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(LightTexture.class)
public class MixinLightTexture
{
#if MC_VER < MC_1_21_3
@Shadow
@Final
private NativeImage lightPixels;
@@ -55,5 +59,21 @@ public class MixinLightTexture
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
MinecraftRenderWrapper.INSTANCE.updateLightmap(this.lightPixels, clientLevel);
}
#else
@Shadow @Final private TextureTarget target;
@Inject(method = "updateLightTexture(F)V", at = @At("RETURN"))
public void updateLightTexture(float partialTicks, CallbackInfo ci)
{
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
if (mc == null || mc.getWrappedClientLevel() == null)
{
return;
}
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
MinecraftRenderWrapper.INSTANCE.setLightmapId(this.target.getColorTextureId(), clientLevel);
}
#endif
}
@@ -31,11 +31,16 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
#if MC_VER >= MC_1_21_1
#if MC_VER < MC_1_20_6
import net.minecraft.world.level.portal.DimensionTransition;
#elif MC_VER < MC_1_21_1
import net.neoforged.neoforge.common.util.ITeleporter;
#elif MC_VER < MC_1_21_3
import net.minecraft.world.level.portal.DimensionTransition;
#else
import net.minecraft.world.level.portal.TeleportTransition;
#endif
@Mixin(ServerPlayer.class)
public class MixinServerPlayer implements IMixinServerPlayer
{
@@ -44,27 +49,37 @@ public class MixinServerPlayer implements IMixinServerPlayer
private ServerLevel distantHorizons$dimensionChangeDestination;
@Unique
@Override
@Nullable
public ServerLevel distantHorizons$getDimensionChangeDestination()
{ return this.distantHorizons$dimensionChangeDestination; }
#if MC_VER < MC_1_20_6
@Inject(at = @At("HEAD"), method = "changeDimension")
public void changeDimension(ServerLevel destination, CallbackInfoReturnable<Entity> cir)
{ this.distantHorizons$dimensionChangeDestination = destination; }
#elif MC_VER < MC_1_21_1
@Inject(at = @At("HEAD"), method = "changeDimension")
public void changeDimension(ServerLevel destination, ITeleporter teleporter, CallbackInfoReturnable<Entity> cir)
{ this.distantHorizons$dimensionChangeDestination = destination; }
#elif MC_VER < MC_1_21_3
@Inject(at = @At("HEAD"), method = "changeDimension")
#if MC_VER >= MC_1_21_1
public void changeDimension(DimensionTransition dimensionTransition, CallbackInfoReturnable<Entity> cir)
{ this.distantHorizons$dimensionChangeDestination = dimensionTransition.newLevel(); }
#else
public void changeDimension(ServerLevel destination, CallbackInfoReturnable<Entity> cir)
{ this.distantHorizons$dimensionChangeDestination = destination; }
@Inject(at = @At("HEAD"), method = "teleport")
public void changeDimension(TeleportTransition teleportTransition, CallbackInfoReturnable<ServerPlayer> cir)
{ this.distantHorizons$dimensionChangeDestination = teleportTransition.newLevel(); }
#endif
#if MC_VER >= MC_1_20_1
@Inject(at = @At("RETURN"), method = "setServerLevel")
public void setServerLevel(ServerLevel level, CallbackInfo ci)
#else
#if MC_VER < MC_1_20_1
@Inject(at = @At("RETURN"), method = "setLevel")
public void setLevel(ServerLevel level, CallbackInfo ci)
#else
@Inject(at = @At("RETURN"), method = "setServerLevel")
public void setServerLevel(ServerLevel level, CallbackInfo ci)
#endif
{
this.distantHorizons$dimensionChangeDestination = null;
@@ -0,0 +1,78 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2023 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.distanthorizons.neoforge.mixins.server;
#if MC_VER < MC_1_21_3
import org.spongepowered.asm.mixin.Mixin;
/**
* {@link MixinUtilBackgroundThread} was used for versions before 1.21.3
* This is just a dummy class/mixin to make the compiler happy.
*
* @see MixinUtilBackgroundThread
*/
@Mixin(net.minecraft.Util.class) // TODO we should allow version specific mixins so we don't have to create dummy mixins that exist for all MC versions
public class MixinTracingExecutor
{
}
#else
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
import com.seibel.distanthorizons.core.util.objects.RunOnThisThreadExecutorService;
import net.minecraft.TracingExecutor;
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.CallbackInfoReturnable;
import java.util.concurrent.Executor;
/**
* This is needed for DH's world gen so we can run
* world gen on our own threads instead of using MC thread pools.
*
* @see MixinUtilBackgroundThread
* @see RunOnThisThreadExecutorService
*/
@Mixin(TracingExecutor.class)
public class MixinTracingExecutor
{
// TODO put in a common location
private static boolean isWorldGenThread()
{ return DependencySetupDoneCheck.isDone && DependencySetupDoneCheck.getIsCurrentThreadDistantGeneratorThread.get(); }
// Util.backgroundExecutor().forName("init_biomes")
// needed for world gen
// replaced with TracingExecutor in MC 1.21.3+
@Inject(method = "forName(Ljava/lang/String;)Ljava/util/concurrent/Executor;", at = @At("HEAD"), cancellable = true)
private void forName(String executorName, CallbackInfoReturnable<Executor> ci)
{
if (isWorldGenThread())
{
// run this task on the current DH thread instead of a new MC thread
ci.setReturnValue(new RunOnThisThreadExecutorService());
}
}
}
#endif
@@ -22,57 +22,75 @@ package com.seibel.distanthorizons.neoforge.mixins.server;
import java.util.concurrent.ExecutorService;
import java.util.function.Supplier;
import com.seibel.distanthorizons.core.util.objects.RunOnThisThreadExecutorService;
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.CallbackInfoReturnable;
import com.seibel.distanthorizons.common.wrappers.DependencySetupDoneCheck;
import com.seibel.distanthorizons.core.util.objects.DummyRunExecutorService;
import net.minecraft.Util;
/**
* This is needed for DH's world gen so we can run
* world gen on our own threads instead of using MC thread pools.
*
* @see MixinTracingExecutor
* @see RunOnThisThreadExecutorService
*/
@Mixin(Util.class)
public class MixinUtilBackgroundThread
{
private static boolean shouldApplyOverride()
{
return DependencySetupDoneCheck.isDone && DependencySetupDoneCheck.getIsCurrentThreadDistantGeneratorThread.get();
}
private static boolean isWorldGenThread()
{ return DependencySetupDoneCheck.isDone && DependencySetupDoneCheck.getIsCurrentThreadDistantGeneratorThread.get(); }
#if MC_VER < MC_1_21_3
@Inject(method = "backgroundExecutor", at = @At("HEAD"), cancellable = true)
private static void overrideUtil$backgroundExecutor(CallbackInfoReturnable<ExecutorService> ci)
{
if (shouldApplyOverride())
if (isWorldGenThread())
{
//ApiShared.LOGGER.info("util backgroundExecutor triggered");
ci.setReturnValue(new DummyRunExecutorService());
// run this task on the current DH thread instead of a new MC thread
ci.setReturnValue(new RunOnThisThreadExecutorService());
}
}
#else
// replaced with TracingExecutor in MC 1.21.3+
#endif
#if MC_VER >= MC_1_17_1
#if MC_VER < MC_1_17_1
#elif MC_VER < MC_1_21_3
@Inject(method = "wrapThreadWithTaskName(Ljava/lang/String;Ljava/lang/Runnable;)Ljava/lang/Runnable;",
at = @At("HEAD"), cancellable = true)
private static void overrideUtil$wrapThreadWithTaskName(String string, Runnable r, CallbackInfoReturnable<Runnable> ci)
{
if (shouldApplyOverride())
if (isWorldGenThread())
{
//ApiShared.LOGGER.info("util wrapThreadWithTaskName(Runnable) triggered");
ci.setReturnValue(r);
}
}
#else
// replaced with TracingExecutor in MC 1.21.3+
#endif
#if MC_VER >= MC_1_18_2
#if MC_VER < MC_1_18_2
#elif MC_VER < MC_1_21_3
@Inject(method = "wrapThreadWithTaskName(Ljava/lang/String;Ljava/util/function/Supplier;)Ljava/util/function/Supplier;",
at = @At("HEAD"), cancellable = true)
private static void overrideUtil$wrapThreadWithTaskNameForSupplier(String string, Supplier<?> r, CallbackInfoReturnable<Supplier<?>> ci)
{
if (shouldApplyOverride())
if (isWorldGenThread())
{
//ApiShared.LOGGER.info("util wrapThreadWithTaskName(Supplier) triggered");
ci.setReturnValue(r);
}
}
#else
// replaced with TracingExecutor in MC 1.21.3+
#endif
}
@@ -1,24 +1,24 @@
{
"required": true,
"minVersion": "0.8",
"package": "com.seibel.distanthorizons.neoforge.mixins",
"mixins": [
"server.MixinUtilBackgroundThread",
"server.MixinChunkGenerator",
"server.MixinTFChunkGenerator",
"server.MixinChunkMap",
"server.MixinServerPlayer"
],
"client": [
"client.MixinClientPacketListener",
"client.MixinDebugScreenOverlay",
"client.MixinFogRenderer",
"client.MixinGameRenderer",
"client.MixinLevelRenderer",
"client.MixinLightTexture",
"client.MixinOptionsScreen",
"client.MixinTextureUtil"
],
"server": [],
"plugin": "com.seibel.distanthorizons.neoforge.mixins.NeoforgeMixinPlugin"
"required": true,
"minVersion": "0.8",
"package": "com.seibel.distanthorizons.neoforge.mixins",
"mixins": [
"server.MixinChunkGenerator",
"server.MixinChunkMap",
"server.MixinServerPlayer",
"server.MixinTFChunkGenerator",
"server.MixinTracingExecutor",
"server.MixinUtilBackgroundThread"
],
"client": [
"client.MixinClientPacketListener",
"client.MixinDebugScreenOverlay",
"client.MixinFogRenderer",
"client.MixinLevelRenderer",
"client.MixinLightTexture",
"client.MixinOptionsScreen",
"client.MixinTextureUtil"
],
"server": [],
"plugin": "com.seibel.distanthorizons.neoforge.mixins.NeoforgeMixinPlugin"
}