Compare commits

...

37 Commits

Author SHA1 Message Date
James Seibel 42ab9eebe5 Fully move getShade into ClientLevelWrapper 2026-05-31 07:43:28 -05:00
Acuadragon100 49e3e11250 Move getShade into ClientLevelWrapper. 2026-05-31 11:16:05 +02:00
Acuadragon100 10925d7c57 Include both the dimension type name and the dimension id number in the dimension name on 1.12.2. 2026-05-16 14:23:16 +02:00
Acuadragon100 7d918fe8dc Also use the original camera position when Immersive Portals is loaded. 2026-05-16 13:25:19 +02:00
Acuadragon100 938631a379 Merge remote-tracking branch 'root/main' into fix-portals
# Conflicts:
#	coreSubProjects
2026-05-15 16:42:34 +02:00
Acuadragon100 48966bf32a Use the dimension id number as the level key on 1.12.2. 2026-05-15 16:01:58 +02:00
Acuadragon100 2dc38622e2 Fix compile errors with 1.12.2. 2026-05-15 15:16:18 +02:00
Acuadragon100 536389af0b Merge remote-tracking branch 'refs/remotes/root/main' into fix-portals
# Conflicts:
#	common/src/main/java/com/seibel/distanthorizons/common/commonMixins/MixinVanillaFogCommon.java
#	common/src/main/java/com/seibel/distanthorizons/common/wrappers/level/KeyedClientLevelManager.java
#	common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftClientWrapper.java
#	common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftRenderWrapper.java
#	common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java
#	common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ServerLevelWrapper.java
#	coreSubProjects
#	forge/src/main/java/com/seibel/distanthorizons/forge/mixins/client/MixinFogRenderer.java
2026-05-14 22:46:23 +02:00
Acuadragon100 7ad0599beb Only tick levels the player is in on the client. 2026-05-14 12:09:02 +02:00
Acuadragon100 8234ac60b8 Always return the player's level and position even when a portal is being rendered. 2026-05-13 21:06:43 +02:00
Acuadragon100 31ab738392 Fix Immersive Portals not properly detected on Forge 1.16.5 2026-05-12 21:23:50 +02:00
Acuadragon100 42344e9c31 Fix some compile errors and backport stuff to Forge. 2026-05-03 23:03:25 +02:00
Acuadragon100 904cc4760f Prevent multiple DhClientLevels of the same level from existing at once. 2026-05-03 21:09:43 +02:00
Acuadragon100 297a8dc980 Fix current level unloading on the client. 2026-05-03 21:08:43 +02:00
James Seibel 30eb02f3b7 lightmap move common level code to common 2026-05-02 10:02:08 -05:00
James Seibel 86cda56381 optimize and fix block wrapper duplicate init 2026-05-02 10:01:08 -05:00
James Seibel 35c1bae156 move fog common mixin code to common 2026-05-02 10:00:24 -05:00
James Seibel e1ce3ae200 neo/fabric move lightmap level to core 2026-05-02 09:57:27 -05:00
James Seibel ed16c83271 minor format updating 2026-05-02 09:54:25 -05:00
Acuadragon100 9d9fdd8ddd Added some missing license headers. 2026-04-26 15:10:01 +02:00
Acuadragon100 2711d8dccc More cleanup 2026-04-26 14:53:27 +02:00
Acuadragon100 c8535f13a6 Check if same level before trying to decode the data. 2026-04-26 14:53:23 +02:00
Acuadragon100 b5ba7862a9 Actually, we can re-enable this if we just make sure it applies to the correct level. 2026-04-26 14:53:21 +02:00
Acuadragon100 33e61b7ef0 Fix not unloading client levels on servers. 2026-04-26 14:53:11 +02:00
Acuadragon100 1617ebda9e Disable fading detection on 1.21.6+ for now.
Might be worth revisiting once a proper fork of Immersive Portals appear for newer versions.
2026-04-26 13:51:52 +02:00
Acuadragon100 29042e2ced Cleanup 2026-04-26 13:51:37 +02:00
Acuadragon100 390dda94c6 Fix server loading. 2026-04-26 13:49:36 +02:00
Acuadragon100 6600703d52 Redo loading 2026-04-26 13:45:06 +02:00
Acuadragon100 3a065d1784 Bug fixes and refactoring. 2026-04-26 13:44:25 +02:00
Acuadragon100 0e340e4558 Tweaked portal loading and fix portals not being detected to disable fading until entered at least once. 2026-04-26 13:43:26 +02:00
Acuadragon100 ca550a0a57 Disable fade rendering when immersive portals and sodium are active at once. 2026-04-26 13:41:03 +02:00
Acuadragon100 30143cbbcb 26.1 support 2026-04-26 13:40:31 +02:00
Acuadragon100 81abcbdb86 Move timer out of mixin to fix crash. 2026-04-26 13:40:13 +02:00
Michael Harvey 3080102f06 Address maintainer feedback: single level loading system, TimerUtil cleanup, consistent formatting 2026-04-26 00:49:31 +02:00
Michael Harvey 6316587ebe remove duplicate copy 2026-04-26 00:49:31 +02:00
Michael Harvey 2e1a2367bd add server support for immersive portals 2026-04-26 00:49:31 +02:00
Michael Harvey e65b1e2dfc add immersive portals support 2026-04-26 00:49:31 +02:00
54 changed files with 1033 additions and 383 deletions
@@ -77,43 +77,6 @@ public class CleanroomClientProxy implements AbstractModInitializer.IEventProxy
} }
//==============//
// world events //
//==============//
@SubscribeEvent
public void clientLevelLoadEvent(WorldEvent.Load event)
{
LOGGER.info("level load");
World level = event.getWorld();
if (!(level instanceof WorldClient clientLevel))
{
return;
}
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel, true);
ClientApi.INSTANCE.clientLevelLoadEvent(clientLevelWrapper);
}
@SubscribeEvent
public void clientLevelUnloadEvent(WorldEvent.Unload event)
{
LOGGER.info("level unload");
World level = event.getWorld();
if (!(level instanceof WorldClient clientLevel))
{
return;
}
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel);
ClientApi.INSTANCE.clientLevelUnloadEvent(clientLevelWrapper);
}
//==============// //==============//
// chunk events // // chunk events //
//==============// //==============//
@@ -26,7 +26,6 @@ import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.EntityRenderer; import net.minecraft.client.renderer.EntityRenderer;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
@@ -61,9 +60,8 @@ public class MixinEntityRenderer
return; return;
} }
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
MinecraftRenderWrapper renderWrapper = (MinecraftRenderWrapper)SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); MinecraftRenderWrapper renderWrapper = (MinecraftRenderWrapper)SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class);
renderWrapper.setLightmapId(lightmapTexture.getGlTextureId(), clientLevel); renderWrapper.setLightmapId(lightmapTexture.getGlTextureId());
} }
@Inject(at = @At("RETURN"), method = "setupFog") @Inject(at = @At("RETURN"), method = "setupFog")
@@ -0,0 +1,52 @@
package com.seibel.distanthorizons.common.commonMixins;
#if MC_VER > MC_1_12_2
import com.seibel.distanthorizons.common.wrappers.modAccessor.ImmersivePortalsAccessorCommon;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.phys.Vec3;
public class MixinImmersivePortalsRenderStatesCommon
{
public static void saveVolatileOriginals()
{
Minecraft mc = Minecraft.getInstance();
ImmersivePortalsAccessorCommon.originalLevel = mc.level;
if (mc.player == null) {
ImmersivePortalsAccessorCommon.originalBlockPos = null;
ImmersivePortalsAccessorCommon.originalChunkPos = null;
ImmersivePortalsAccessorCommon.originalCameraPos = null;
return;
}
BlockPos pos = mc.player.blockPosition();
ImmersivePortalsAccessorCommon.originalBlockPos = new DhBlockPos(pos.getX(), pos.getY(), pos.getZ());
#if MC_VER < MC_1_17_1
ChunkPos cPos = new ChunkPos(mc.player.blockPosition());
#else
ChunkPos cPos = mc.player.chunkPosition();
#endif
#if MC_VER <= MC_1_21_11
ImmersivePortalsAccessorCommon.originalChunkPos = new DhChunkPos(cPos.x, cPos.z);
#else
ImmersivePortalsAccessorCommon.originalChunkPos = new DhChunkPos(cPos.x(), cPos.z());
#endif
#if MC_VER <= MC_1_21_10
Vec3 cameraPos = mc.gameRenderer.getMainCamera().getPosition();
#else
Vec3 cameraPos = mc.gameRenderer.getMainCamera().position();
#endif
ImmersivePortalsAccessorCommon.originalCameraPos = new Vec3d(cameraPos.x(), cameraPos.y(), cameraPos.z());
}
}
#endif
@@ -7,6 +7,7 @@ import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IImmersivePortalsAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@@ -26,6 +27,7 @@ import net.minecraft.world.level.material.FluidState;
import net.minecraft.client.renderer.FogRenderer; import net.minecraft.client.renderer.FogRenderer;
import net.minecraft.client.renderer.FogRenderer.FogMode; import net.minecraft.client.renderer.FogRenderer.FogMode;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#elif MC_VER < MC_1_21_3 #elif MC_VER < MC_1_21_3
@@ -50,6 +52,11 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
#else #else
import net.minecraft.world.level.material.FogType; import net.minecraft.world.level.material.FogType;
import net.minecraft.client.renderer.fog.FogRenderer;
import net.minecraft.client.renderer.fog.FogData;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
#endif #endif
@@ -101,6 +108,14 @@ public class MixinVanillaFogCommon
cancelFog = cancelFog && !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get(); cancelFog = cancelFog && !Config.Client.Advanced.Graphics.Fog.enableVanillaFog.get();
IImmersivePortalsAccessor immersivePortals = ModAccessorInjector.INSTANCE.get(IImmersivePortalsAccessor.class);
if (immersivePortals != null
&& immersivePortals.isRenderingPortal())
{
cancelFog = false;
}
return cancelFog; return cancelFog;
} }
#if MC_VER <= MC_1_12_2 #if MC_VER <= MC_1_12_2
@@ -121,4 +136,6 @@ public class MixinVanillaFogCommon
return cameraNotInFluid; return cameraNotInFluid;
} }
} }
@@ -1,5 +1,6 @@
package com.seibel.distanthorizons.common.wrappers.level; package com.seibel.distanthorizons.common.wrappers.level;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel; import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
import com.seibel.distanthorizons.core.level.IKeyedClientLevelManager; import com.seibel.distanthorizons.core.level.IKeyedClientLevelManager;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
@@ -8,17 +9,35 @@ import net.minecraft.client.multiplayer.WorldClient;
#else #else
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
#endif #endif
import net.minecraft.client.Minecraft;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
public class KeyedClientLevelManager implements IKeyedClientLevelManager public class KeyedClientLevelManager implements IKeyedClientLevelManager
{ {
public static final KeyedClientLevelManager INSTANCE = new KeyedClientLevelManager(); public static final KeyedClientLevelManager INSTANCE = new KeyedClientLevelManager();
/** This is set and managed by the ClientApi for servers with support for DH. */ private static class KeyInfo {
@Nullable public final String serverKey;
private IServerKeyedClientLevel serverKeyedLevel = null; public final String levelKey;
public KeyInfo(String serverKey, String levelKey) {
this.serverKey = serverKey;
this.levelKey = levelKey;
}
}
/** Stores the server-provided keys indexed by dimension name for persistence. */
private final Map<String, KeyInfo> keysByDimensionName = new ConcurrentHashMap<>();
/** Cache for already keyed level wrappers to maintain object identity. */
private final Map<#if MC_VER > MC_1_12_2 ClientLevel #else WorldClient #endif, IServerKeyedClientLevel> keyedLevelsCache = Collections.synchronizedMap(new WeakHashMap<>());
/** Allows to keep level manager enabled between loading different keyed levels */ /** Allows to keep level manager enabled between loading different keyed levels */
private boolean enabled = false; private volatile boolean enabled = false;
@@ -41,32 +60,116 @@ public class KeyedClientLevelManager implements IKeyedClientLevelManager
@Override @Override
@Nullable @Nullable
public IServerKeyedClientLevel getServerKeyedLevel() { return this.serverKeyedLevel; } public IServerKeyedClientLevel getServerKeyedLevel()
{
#if MC_VER > MC_1_12_2
return this.getServerKeyedLevel(Minecraft.getInstance().level);
#else
return this.getServerKeyedLevel(Minecraft.getMinecraft().world);
#endif
}
@Nullable
public IServerKeyedClientLevel getServerKeyedLevel(@Nullable #if MC_VER > MC_1_12_2 ClientLevel #else WorldClient #endif level)
{
if (level == null)
{
return null;
}
// We synchronize on the cache map to ensure atomicity of the lookup-and-populate sequence.
// This prevents multiple threads from creating duplicate wrappers for the same level.
synchronized (this.keyedLevelsCache)
{
// Check the cache first
IServerKeyedClientLevel cached = this.keyedLevelsCache.get(level);
if (cached != null)
{
return cached;
}
// Determine the dimension name for this level
// We use bypassLevelKeyManager=true to avoid recursion back into this manager
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper(level, true);
if (wrappedLevel == null)
{
return null;
}
String dimensionName = wrappedLevel.getDimensionName();
KeyInfo info = this.keysByDimensionName.get(dimensionName);
if (info == null)
{
return null;
}
// Create and cache a new keyed wrapper
IServerKeyedClientLevel keyedLevel = new ServerKeyedClientLevelWrapper(level, info.serverKey, info.levelKey);
this.keyedLevelsCache.put(level, keyedLevel);
return keyedLevel;
}
}
@Override @Override
public IServerKeyedClientLevel setServerKeyedLevel(IClientLevelWrapper clientLevel, String serverKey, String levelKey) public IServerKeyedClientLevel setServerKeyedLevel(IClientLevelWrapper clientLevel, String serverKey, String levelKey)
{ {
IServerKeyedClientLevel keyedLevel; // 1. Determine the target dimension name
#if MC_VER <= MC_1_12_2 String targetDimensionName = clientLevel.getDimensionName();
keyedLevel = new ServerKeyedClientLevelWrapper((WorldClient) clientLevel.getWrappedMcObject(), serverKey, levelKey); int separatorIndex = levelKey.lastIndexOf("@");
#else if (separatorIndex != -1)
keyedLevel = new ServerKeyedClientLevelWrapper((ClientLevel) clientLevel.getWrappedMcObject(), serverKey, levelKey); {
#endif targetDimensionName = levelKey.substring(separatorIndex + 1);
}
this.serverKeyedLevel = keyedLevel; final String finalTargetDimensionName = targetDimensionName;
// 2. Store the key for this dimension
this.keysByDimensionName.put(finalTargetDimensionName, new KeyInfo(serverKey, levelKey));
this.enabled = true; this.enabled = true;
return keyedLevel;
// 3. Clear the cache for this dimension to ensure new wrappers are created with the new key
// (though in practice keys shouldn't change mid-session)
//
// We synchronize manually on the map to ensure atomicity of the compound removal operation
// and to prevent race conditions or deadlocks with other threads accessing the map.
// We avoid calling ClientLevelWrapper.getWrapper() inside the lock to prevent circular lock dependencies.
synchronized (this.keyedLevelsCache)
{
this.keyedLevelsCache.keySet().removeIf(level -> {
#if MC_VER <= MC_1_12_2
String levelDim = level.provider.getDimensionType().getName() + ":" + level.provider.getDimension();
#elif MC_VER <= MC_1_21_10
String levelDim = level.dimension().location().toString();
#else
String levelDim = level.dimension().identifier().toString();
#endif
return levelDim.equals(finalTargetDimensionName);
});
}
// 4. Return the keyed wrapper for whatever level the core passed us,
// but only if it matches the dimension we just keyed.
return this.getServerKeyedLevel((#if MC_VER > MC_1_12_2 ClientLevel #else WorldClient #endif) clientLevel.getWrappedMcObject());
} }
@Override @Override
public void clearKeyedLevel() { this.serverKeyedLevel = null; } public void clearKeyedLevel()
{
synchronized (this.keyedLevelsCache)
{
this.keyedLevelsCache.clear();
this.keysByDimensionName.clear();
}
}
@Override @Override
public boolean isEnabled() { return this.enabled; } public boolean isEnabled() { return this.enabled; }
@Override @Override
public void disable() { this.enabled = false; } public void disable()
{
//endregion this.enabled = false;
this.clearKeyedLevel();
}
} }
@@ -20,15 +20,20 @@
package com.seibel.distanthorizons.common.wrappers.minecraft; package com.seibel.distanthorizons.common.wrappers.minecraft;
import java.io.File; import java.io.File;
import java.util.Arrays;
#if MC_VER > MC_1_12_2 #if MC_VER > MC_1_12_2
import com.mojang.blaze3d.platform.Window; import com.mojang.blaze3d.platform.Window;
#endif #endif
import com.seibel.distanthorizons.common.wrappers.gui.NativeDialogUtil; import com.seibel.distanthorizons.common.wrappers.gui.NativeDialogUtil;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper; import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure; import com.seibel.distanthorizons.core.file.structure.ClientOnlySaveStructure;
import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler; import com.seibel.distanthorizons.core.render.RenderThreadTaskHandler;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IImmersivePortalsAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.coreapi.ModInfo;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
@@ -48,14 +53,20 @@ import net.minecraft.profiler.Profiler;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.DimensionType;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.DimensionManager;
#else #else
import net.minecraft.CrashReport; import net.minecraft.CrashReport;
import net.minecraft.client.CloudStatus; import net.minecraft.client.CloudStatus;
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;
#endif #endif
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@@ -74,6 +85,20 @@ import net.minecraft.client.GraphicsStatus;
#else #else
#endif #endif
#if MC_VER <= MC_1_12_2
import net.minecraft.util.ResourceLocation;
#elif MC_VER <= MC_1_21_10
import net.minecraft.resources.ResourceLocation;
#else
import net.minecraft.resources.Identifier;
#endif
#if MC_VER > MC_1_19_2
import net.minecraft.core.registries.Registries;
#elif MC_VER > MC_1_12_2
import net.minecraft.core.Registry;
#endif
/** /**
* A singleton that wraps the Minecraft object. * A singleton that wraps the Minecraft object.
@@ -95,6 +120,11 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
private ProfilerWrapper profilerWrapper; private ProfilerWrapper profilerWrapper;
// Need to classload this field later because otherwise it will be null even when Immersive Portals is present.
public static class Late {
private static final IImmersivePortalsAccessor IMMERSIVE_PORTALS = ModAccessorInjector.INSTANCE.get(IImmersivePortalsAccessor.class);
}
//======================// //======================//
@@ -232,6 +262,12 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
return new DhBlockPos(0, 0, 0); return new DhBlockPos(0, 0, 0);
} }
if (Late.IMMERSIVE_PORTALS != null)
{
DhBlockPos pos = Late.IMMERSIVE_PORTALS.getOriginalPlayerBlockPos();
if (pos != null) return pos;
}
#if MC_VER <= MC_1_12_2 #if MC_VER <= MC_1_12_2
BlockPos playerPos = player.getPosition(); BlockPos playerPos = player.getPosition();
#else #else
@@ -253,6 +289,12 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
return new DhChunkPos(0, 0); return new DhChunkPos(0, 0);
} }
if (Late.IMMERSIVE_PORTALS != null)
{
DhChunkPos pos = Late.IMMERSIVE_PORTALS.getOriginalPlayerChunkPos();
if (pos != null) return pos;
}
#if MC_VER <= MC_1_12_2 #if MC_VER <= MC_1_12_2
ChunkPos playerPos = new ChunkPos(player.getPosition()); ChunkPos playerPos = new ChunkPos(player.getPosition());
#elif MC_VER < MC_1_17_1 #elif MC_VER < MC_1_17_1
@@ -285,6 +327,11 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
@Nullable @Nullable
public IClientLevelWrapper getWrappedClientLevel(boolean bypassLevelKeyManager) public IClientLevelWrapper getWrappedClientLevel(boolean bypassLevelKeyManager)
{ {
if (!bypassLevelKeyManager && Late.IMMERSIVE_PORTALS != null)
{
IClientLevelWrapper level = Late.IMMERSIVE_PORTALS.getOriginalClientLevelWrapper();
if (level != null) return level;
}
#if MC_VER <= MC_1_12_2 #if MC_VER <= MC_1_12_2
WorldClient level = MINECRAFT.world; WorldClient level = MINECRAFT.world;
#else #else
@@ -583,6 +630,44 @@ public class MinecraftClientWrapper implements IMinecraftClientWrapper, IMinecra
} }
} }
@Override
public IServerLevelWrapper getWrappedServerLevel(String levelKey)
{
if (!hasSinglePlayerServer()) return null;
#if MC_VER <= MC_1_12_2
int dimensionID;
try
{
dimensionID = Integer.parseInt(levelKey.substring(levelKey.indexOf(":")+1));
}
catch (NumberFormatException ignored)
{
return null;
}
#else
#if MC_VER <= MC_1_21_10
ResourceLocation levelID = ResourceLocation.tryParse(levelKey);
#else
Identifier levelID = Identifier.tryParse(levelKey);
#endif
if (levelID == null) return null;
#if MC_VER > MC_1_19_2
ResourceKey<Level> resourceKey = ResourceKey.create(Registries.DIMENSION, levelID);
#else
ResourceKey<Level> resourceKey = ResourceKey.create(Registry.DIMENSION_REGISTRY, levelID);
#endif
#endif
#if MC_VER <= MC_1_12_2
WorldServer level = MINECRAFT.getIntegratedServer().getWorld(dimensionID);
#else
ServerLevel level = MINECRAFT.getSingleplayerServer().getLevel(resourceKey);
#endif
return ServerLevelWrapper.getWrapper(level);
}
//endregion //endregion
@@ -20,7 +20,6 @@
package com.seibel.distanthorizons.common.wrappers.minecraft; package com.seibel.distanthorizons.common.wrappers.minecraft;
import java.awt.Color; import java.awt.Color;
import java.lang.invoke.MethodHandles;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
#if MC_VER > MC_1_12_2 #if MC_VER > MC_1_12_2
@@ -30,19 +29,25 @@ import com.mojang.blaze3d.platform.NativeImage;
import com.seibel.distanthorizons.api.enums.config.EDhApiLodShading; import com.seibel.distanthorizons.api.enums.config.EDhApiLodShading;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter; import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper; import com.seibel.distanthorizons.common.wrappers.misc.LightMapWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector; import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.enums.EDhDirection; import com.seibel.distanthorizons.core.enums.EDhDirection;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.coreapi.util.ColorUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.misc.ILightMapWrapper;
#if MC_VER < MC_1_17_1 #if MC_VER < MC_1_17_1
#elif MC_VER < MC_1_21_6 #elif MC_VER < MC_1_21_3
import net.minecraft.client.renderer.FogRenderer; import net.minecraft.client.renderer.FogRenderer;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
#elif MC_VER < MC_1_21_6
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
import net.minecraft.client.renderer.FogRenderer;
#else #else
import com.seibel.distanthorizons.coreapi.util.ColorUtil;
import net.minecraft.client.renderer.fog.FogData; import net.minecraft.client.renderer.fog.FogData;
import net.minecraft.client.renderer.fog.FogRenderer; import net.minecraft.client.renderer.fog.FogRenderer;
#endif #endif
@@ -53,13 +58,13 @@ import org.joml.Vector3f;
#else #else
#endif #endif
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.AbstractOptifineAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IDimensionTypeWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IDimensionTypeWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.core.util.math.Vec3d; import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.util.math.Vec3f; import com.seibel.distanthorizons.core.util.math.Vec3f;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IImmersivePortalsAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor; import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
#if MC_VER <= MC_1_12_2 #if MC_VER <= MC_1_12_2
@@ -79,6 +84,7 @@ import net.minecraft.world.phys.Vec3;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLogger;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.joml.Vector4f; import org.joml.Vector4f;
#if MC_VER <= MC_1_12_2 #if MC_VER <= MC_1_12_2
@@ -112,6 +118,7 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
public static final MinecraftRenderWrapper INSTANCE = new MinecraftRenderWrapper(); public static final MinecraftRenderWrapper INSTANCE = new MinecraftRenderWrapper();
private static final IOptifineAccessor OPTIFINE_ACCESSOR = ModAccessorInjector.INSTANCE.get(IOptifineAccessor.class); private static final IOptifineAccessor OPTIFINE_ACCESSOR = ModAccessorInjector.INSTANCE.get(IOptifineAccessor.class);
private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
private static final DhLogger LOGGER = new DhLoggerBuilder().build(); private static final DhLogger LOGGER = new DhLoggerBuilder().build();
@@ -121,6 +128,11 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
private static final Minecraft MC = Minecraft.getInstance(); private static final Minecraft MC = Minecraft.getInstance();
#endif #endif
// Need to classload this field later because otherwise it will be null even when Immersive Portals is present.
public static class Late {
private static final IImmersivePortalsAccessor IMMERSIVE_PORTALS = ModAccessorInjector.INSTANCE.get(IImmersivePortalsAccessor.class);
}
/** /**
* In the case of immersive portals multiple levels may be active at once, causing conflicting lightmaps. <br> * In the case of immersive portals multiple levels may be active at once, causing conflicting lightmaps. <br>
* Requiring the use of multiple {@link LightMapWrapper}. * Requiring the use of multiple {@link LightMapWrapper}.
@@ -199,6 +211,11 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
@Override @Override
public Vec3d getCameraExactPosition() public Vec3d getCameraExactPosition()
{ {
if (Late.IMMERSIVE_PORTALS != null)
{
Vec3d cameraPos = Late.IMMERSIVE_PORTALS.getOriginalCameraPos();
if (cameraPos != null) return cameraPos;
}
#if MC_VER <= MC_1_12_2 #if MC_VER <= MC_1_12_2
RenderManager rm = MC.getRenderManager(); RenderManager rm = MC.getRenderManager();
return new Vec3d(rm.viewerPosX, rm.viewerPosY, rm.viewerPosZ); return new Vec3d(rm.viewerPosX, rm.viewerPosY, rm.viewerPosZ);
@@ -525,9 +542,6 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
#endif #endif
} }
@Override
public ILightMapWrapper getLightmapWrapper(@NotNull ILevelWrapper level) { return this.lightmapByDimensionType.get(level.getDimensionType()); }
@Override @Override
public boolean isFogStateSpecial() public boolean isFogStateSpecial()
{ {
@@ -549,94 +563,89 @@ public class MinecraftRenderWrapper implements IMinecraftRenderWrapper
#endif #endif
} }
//==========//
// lightmap //
//==========//
//region
@Override
public ILightMapWrapper getLightmapWrapper(@NotNull ILevelWrapper level) { return this.lightmapByDimensionType.get(level.getDimensionType()); }
/** /**
* It's better to use {@link MinecraftRenderWrapper#setLightmapId(int, IClientLevelWrapper)} if possible, * It's better to use {@link MinecraftRenderWrapper#setLightmapId(int)} if possible,
* however old MC versions don't support it. * however old MC versions don't support it.
*/ */
#if MC_VER > MC_1_12_2 #if MC_VER > MC_1_12_2
public void updateLightmap(NativeImage lightPixels, IClientLevelWrapper level) public void updateLightmap(NativeImage lightPixels)
{ {
IClientLevelWrapper clientLevel = getLightmapClientLevelWrapper();
if (clientLevel == null)
{
return;
}
// Using ClientLevelWrapper as the key would be better, but we don't have a consistent way to create the same // Using ClientLevelWrapper as the key would be better, but we don't have a consistent way to create the same
// object for the same MC level and/or the same hash, // object for the same MC level and/or the same hash,
// so this will have to do for now // so this will have to do for now
IDimensionTypeWrapper dimensionType = level.getDimensionType(); IDimensionTypeWrapper dimensionType = clientLevel.getDimensionType();
LightMapWrapper wrapper = this.lightmapByDimensionType.computeIfAbsent(dimensionType, (dimType) -> new LightMapWrapper()); LightMapWrapper wrapper = this.lightmapByDimensionType.computeIfAbsent(dimensionType, (dimType) -> new LightMapWrapper());
wrapper.uploadLightmap(lightPixels); wrapper.uploadLightmap(lightPixels);
} }
#endif #endif
public void setLightmapId(int tetxureId, IClientLevelWrapper level) public void setLightmapId(int textureId)
{ {
IClientLevelWrapper clientLevel = getLightmapClientLevelWrapper();
if (clientLevel == null)
{
return;
}
// Using ClientLevelWrapper as the key would be better, but we don't have a consistent way to create the same // Using ClientLevelWrapper as the key would be better, but we don't have a consistent way to create the same
// object for the same MC level and/or the same hash, // object for the same MC level and/or the same hash,
// so this will have to do for now // so this will have to do for now
IDimensionTypeWrapper dimensionType = level.getDimensionType(); IDimensionTypeWrapper dimensionType = clientLevel.getDimensionType();
LightMapWrapper wrapper = this.lightmapByDimensionType.computeIfAbsent(dimensionType, (dimType) -> new LightMapWrapper()); LightMapWrapper wrapper = this.lightmapByDimensionType.computeIfAbsent(dimensionType, (dimType) -> new LightMapWrapper());
wrapper.setLightmapId(tetxureId); wrapper.setLightmapId(textureId);
} }
#if MC_VER <= MC_1_21_10 #if MC_VER <= MC_1_21_10
#else #else
public void setLightmapGpuTexture(GpuTexture gpuTexture, IClientLevelWrapper level) public void setLightmapGpuTexture(GpuTexture gpuTexture)
{ {
IClientLevelWrapper clientLevel = getLightmapClientLevelWrapper();
if (clientLevel == null)
{
return;
}
// Using ClientLevelWrapper as the key would be better, but we don't have a consistent way to create the same // Using ClientLevelWrapper as the key would be better, but we don't have a consistent way to create the same
// object for the same MC level and/or the same hash, // object for the same MC level and/or the same hash,
// so this will have to do for now // so this will have to do for now
IDimensionTypeWrapper dimensionType = level.getDimensionType(); IDimensionTypeWrapper dimensionType = clientLevel.getDimensionType();
LightMapWrapper wrapper = this.lightmapByDimensionType.computeIfAbsent(dimensionType, (dimType) -> new LightMapWrapper()); LightMapWrapper wrapper = this.lightmapByDimensionType.computeIfAbsent(dimensionType, (dimType) -> new LightMapWrapper());
wrapper.setLightmapGpuTexture(gpuTexture); wrapper.setLightmapGpuTexture(gpuTexture);
} }
#endif #endif
@Override private static @Nullable IClientLevelWrapper getLightmapClientLevelWrapper()
public float getShade(EDhDirection lodDirection)
{ {
EDhApiLodShading lodShading = Config.Client.Advanced.Graphics.Quality.lodShading.get(); IClientLevelWrapper clientLevel = ClientApi.RENDER_STATE.clientLevelWrapper;
switch (lodShading) if (clientLevel == null)
{ {
default: clientLevel = MC_CLIENT.getWrappedClientLevel();
case AUTO:
#if MC_VER <= MC_1_12_2
// 1.12.2 has no getShade, fall through to ENABLED
#else
if (MC.level != null)
{
Direction mcDir = McObjectConverter.Convert(lodDirection);
#if MC_VER <= MC_1_21_11
return MC.level.getShade(mcDir, true);
#else
return MC.level.cardinalLighting().byFace(mcDir);
#endif
}
else
{
return 0.0f;
}
#endif
case ENABLED:
switch (lodDirection)
{
case DOWN:
return 0.5F;
default:
case UP:
return 1.0F;
case NORTH:
case SOUTH:
return 0.8F;
case WEST:
case EAST:
return 0.6F;
} }
case DISABLED: return clientLevel;
return 1.0F;
}
} }
//endregion
} }
@@ -1,9 +1,32 @@
package com.seibel.distanthorizons.common.wrappers.minecraft; package com.seibel.distanthorizons.common.wrappers.minecraft;
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
import net.minecraft.server.dedicated.DedicatedServer; import net.minecraft.server.dedicated.DedicatedServer;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
#if MC_VER > MC_1_12_2
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
#else
import net.minecraft.world.WorldServer;
#endif
#if MC_VER <= MC_1_12_2
#elif MC_VER <= MC_1_21_10
import net.minecraft.resources.ResourceLocation;
#else
import net.minecraft.resources.Identifier;
#endif
#if MC_VER > MC_1_19_2
import net.minecraft.core.registries.Registries;
#elif MC_VER > MC_1_12_2
import net.minecraft.core.Registry;
#endif
import java.io.File; import java.io.File;
public class MinecraftServerWrapper implements IMinecraftSharedWrapper public class MinecraftServerWrapper implements IMinecraftSharedWrapper
@@ -65,4 +88,40 @@ public class MinecraftServerWrapper implements IMinecraftSharedWrapper
@Override
public IServerLevelWrapper getWrappedServerLevel(String levelKey)
{
#if MC_VER <= MC_1_12_2
int dimensionID;
try
{
dimensionID = Integer.parseInt(levelKey.substring(levelKey.indexOf(":")+1));
}
catch (NumberFormatException ignored)
{
return null;
}
#else
#if MC_VER <= MC_1_21_10
ResourceLocation levelID = ResourceLocation.tryParse(levelKey);
#else
Identifier levelID = Identifier.tryParse(levelKey);
#endif
if (levelID == null) return null;
#if MC_VER > MC_1_19_2
ResourceKey<Level> resourceKey = ResourceKey.create(Registries.DIMENSION, levelID);
#else
ResourceKey<Level> resourceKey = ResourceKey.create(Registry.DIMENSION_REGISTRY, levelID);
#endif
#endif
#if MC_VER > MC_1_12_2
ServerLevel level = dedicatedServer.getLevel(resourceKey);
#else
WorldServer level = dedicatedServer.getWorld(dimensionID);
#endif
return ServerLevelWrapper.getWrapper(level);
}
} }
@@ -0,0 +1,144 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020 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.common.wrappers.modAccessor;
#if MC_VER > MC_1_12_2
import com.google.common.base.Suppliers;
import com.mojang.blaze3d.systems.RenderSystem;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.util.math.Vec3d;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.ImmersivePortalsAbstractAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;
#if MC_VER > MC_1_19_2
import org.joml.Matrix4f;
#else
import com.mojang.math.Matrix4f;
import com.seibel.distanthorizons.core.util.math.Mat4f;
#endif
#if MC_VER < MC_1_17_1
import java.lang.reflect.Field;
#endif
import java.util.function.Supplier;
public abstract class ImmersivePortalsAccessorCommon extends ImmersivePortalsAbstractAccessor
{
// We don't use the fields in RenderStates because they are not volatile.
@Nullable
public static volatile ClientLevel originalLevel;
@Nullable
public static volatile DhBlockPos originalBlockPos;
@Nullable
public static volatile DhChunkPos originalChunkPos;
@Nullable
public static volatile Vec3d originalCameraPos;
@Override
protected Object getClientLevel() { return Minecraft.getInstance().level; }
@Override
protected Class<?> getLevelClass() { return Level.class; }
@Override
protected Iterable<?> getEntitiesForRendering() { return Minecraft.getInstance().level.entitiesForRendering(); }
#if MC_VER < MC_1_21_6
private static Matrix4f getProjectionMatrix()
{
#if MC_VER > MC_1_16_5
return RenderSystem.getProjectionMatrix();
#else
try
{
Class<?> renderStates = Class.forName("com.qouteall.immersive_portals.render.context_management.RenderStates");
Field projectionMatrix = renderStates.getField("projectionMatrix");
return (Matrix4f) projectionMatrix.get(null);
}
catch (Throwable e)
{
throw new RuntimeException(e);
}
#endif
}
#endif
#if MC_VER <= MC_1_19_2
protected abstract Matrix4f convert(Mat4f matrix);
#endif
@Override
protected Supplier<?> getFrustumSupplier()
{
#if MC_VER < MC_1_21_6 // TODO Fix this for 1.21.6+ when a more modern version of Immersive Portals is available.
return Suppliers.memoize(() -> {
Frustum frustum = new Frustum(
#if MC_VER > MC_1_19_2
ClientApi.RENDER_STATE.mcModelViewMatrix.createJomlMatrix(),
#else
convert(ClientApi.RENDER_STATE.mcModelViewMatrix),
#endif
getProjectionMatrix()
);
Vec3 cameraPos = Minecraft.getInstance().gameRenderer.getMainCamera().getPosition();
frustum.prepare(cameraPos.x, cameraPos.y, cameraPos.z);
return frustum;
});
#else
return null;
#endif
}
@Override
@Nullable
public DhBlockPos getOriginalPlayerBlockPos() {
return originalBlockPos;
}
@Override
@Nullable
public DhChunkPos getOriginalPlayerChunkPos() {
return originalChunkPos;
}
@Override
@Nullable
public IClientLevelWrapper getOriginalClientLevelWrapper() {
return ClientLevelWrapper.getWrapper(originalLevel, false);
}
@Override
@Nullable
public Vec3d getOriginalCameraPos() {
return originalCameraPos;
}
}
#endif
@@ -1,21 +1,27 @@
package com.seibel.distanthorizons.common.wrappers.world; package com.seibel.distanthorizons.common.wrappers.world;
import com.seibel.distanthorizons.api.enums.config.EDhApiLodShading;
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType; import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiLevelType;
import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister; import com.seibel.distanthorizons.api.interfaces.render.IDhApiCustomRenderRegister;
import com.seibel.distanthorizons.common.wrappers.McObjectConverter;
import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper; import com.seibel.distanthorizons.common.wrappers.block.BiomeWrapper;
import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper; import com.seibel.distanthorizons.common.wrappers.block.BlockStateWrapper;
import com.seibel.distanthorizons.common.wrappers.block.ClientBlockStateColorCache; import com.seibel.distanthorizons.common.wrappers.block.ClientBlockStateColorCache;
import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper; import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.common.wrappers.level.KeyedClientLevelManager;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper; import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftClientWrapper;
import com.seibel.distanthorizons.core.api.internal.SharedApi;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2; import com.seibel.distanthorizons.core.dataObjects.fullData.sources.FullDataSourceV2;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.enums.EDhDirection;
import com.seibel.distanthorizons.core.level.*; import com.seibel.distanthorizons.core.level.*;
import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel; import com.seibel.distanthorizons.core.level.IServerKeyedClientLevel;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos; import com.seibel.distanthorizons.core.pos.blockPos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.util.TimerUtil;
import com.seibel.distanthorizons.core.world.AbstractDhWorld;
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IDimensionTypeWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IDimensionTypeWrapper;
@@ -30,6 +36,7 @@ import net.minecraft.block.state.IBlockState;
#else #else
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkAccess;
@@ -43,9 +50,8 @@ import java.awt.*;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.Collections; import java.util.*;
import java.util.Map; import java.util.List;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function; import java.util.function.Function;
@@ -88,6 +94,10 @@ public class ClientLevelWrapper implements IClientLevelWrapper
private static final Minecraft MINECRAFT = Minecraft.getInstance(); private static final Minecraft MINECRAFT = Minecraft.getInstance();
#endif #endif
private static final Timer CLIENT_CLEANUP_TIMER = TimerUtil.CreateTimer("ClientLevelTickCleanup");
private static final TimerTask CLIENT_CLEANUP_TASK = TimerUtil.createTimerTask(ClientLevelWrapper::tickCleanup);
#if MC_VER <= MC_1_12_2 #if MC_VER <= MC_1_12_2
private final WorldClient level; private final WorldClient level;
private final ConcurrentHashMap<IBlockState, ClientBlockStateColorCache> blockColorCacheByBlockState = new ConcurrentHashMap<>(); private final ConcurrentHashMap<IBlockState, ClientBlockStateColorCache> blockColorCacheByBlockState = new ConcurrentHashMap<>();
@@ -106,8 +116,9 @@ public class ClientLevelWrapper implements IClientLevelWrapper
private boolean cloudColorFailLogged = false; private boolean cloudColorFailLogged = false;
private BlockStateWrapper dirtBlockWrapper; private volatile BlockStateWrapper dirtBlockWrapper;
private IDhLevel dhLevel; private volatile IDhLevel dhLevel;
private volatile long lastAccessTime = System.currentTimeMillis();
@@ -127,6 +138,75 @@ public class ClientLevelWrapper implements IClientLevelWrapper
//==================// //==================//
//region //region
@Override
public synchronized void markAccessed() { this.lastAccessTime = System.currentTimeMillis(); }
public synchronized long getLastAccessTime() { return this.lastAccessTime; }
static
{
// 20 ticks per second (50ms interval)
CLIENT_CLEANUP_TIMER.scheduleAtFixedRate(CLIENT_CLEANUP_TASK, 0, 1000 / 20);
}
private void unload()
{
AbstractDhWorld world = SharedApi.getAbstractDhWorld();
if (world == null || !world.unloadLevel(this))
{
this.onUnload();
}
}
private static #if MC_VER > MC_1_12_2 ClientLevel #else WorldClient #endif clientLevel() {
return #if MC_VER > MC_1_12_2 MINECRAFT.level #else MINECRAFT.world #endif;
}
public static void tickCleanup()
{
if (clientLevel() == null)
{
return;
}
long currentTime = System.currentTimeMillis();
long timeout = 30 * 1000;
ArrayList<ClientLevelWrapper> toUnload = new ArrayList<>();
synchronized(LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL)
{
for (WeakReference<ClientLevelWrapper> ref : LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.values())
{
ClientLevelWrapper wrapper = ref.get();
if (wrapper != null
&& wrapper.level != clientLevel())
{
// We use the synchronized getter to prevent race conditions with markAccessed()
if (currentTime - wrapper.getLastAccessTime() > timeout)
{
toUnload.add(wrapper);
}
}
}
}
for (ClientLevelWrapper wrapper : toUnload)
{
// Re-verify all conditions inside a synchronized block on the wrapper
// to ensure atomicity with respect to markAccessed()
synchronized(wrapper)
{
if (wrapper.level != clientLevel()
&& currentTime - wrapper.getLastAccessTime() > timeout)
{
LOGGER.debug("Unloading level [" + wrapper.getDhIdentifier() + "] due to inactivity");
wrapper.unload();
}
}
}
}
/** /**
* can be used when speed is important and the same level is likely to be passed in, * can be used when speed is important and the same level is likely to be passed in,
* IE rendering. * IE rendering.
@@ -136,10 +216,25 @@ public class ClientLevelWrapper implements IClientLevelWrapper
@Nullable IClientLevelWrapper levelWrapper, @Nullable IClientLevelWrapper levelWrapper,
@NotNull #if MC_VER <= MC_1_12_2 WorldClient #else ClientLevel #endif level) @NotNull #if MC_VER <= MC_1_12_2 WorldClient #else ClientLevel #endif level)
{ {
if (KEYED_CLIENT_LEVEL_MANAGER.isEnabled() && KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel() != levelWrapper) if (KEYED_CLIENT_LEVEL_MANAGER.isEnabled())
{
IServerKeyedClientLevel keyedLevel = null;
if (KEYED_CLIENT_LEVEL_MANAGER instanceof KeyedClientLevelManager)
{
keyedLevel = ((KeyedClientLevelManager) KEYED_CLIENT_LEVEL_MANAGER).getServerKeyedLevel(level);
}
else
{
// FIXME: If the implementation is not KeyedClientLevelManager,
// this fallback may return the key for the wrong dimension in multiverse scenarios.
keyedLevel = KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel();
}
if (keyedLevel != levelWrapper)
{ {
return getWrapper(level); return getWrapper(level);
} }
}
ClientLevelWrapper clientLevelWrapper = (ClientLevelWrapper)levelWrapper; ClientLevelWrapper clientLevelWrapper = (ClientLevelWrapper)levelWrapper;
if (clientLevelWrapper == null if (clientLevelWrapper == null
@@ -168,9 +263,31 @@ public class ClientLevelWrapper implements IClientLevelWrapper
} }
// used if the client is connected to a server that defines the currently loaded level // used if the client is connected to a server that defines the currently loaded level
IServerKeyedClientLevel overrideLevel = KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel(); IServerKeyedClientLevel overrideLevel = null;
if (KEYED_CLIENT_LEVEL_MANAGER instanceof KeyedClientLevelManager)
{
overrideLevel = ((KeyedClientLevelManager) KEYED_CLIENT_LEVEL_MANAGER).getServerKeyedLevel(level);
}
else
{
// FIXME: If the implementation is not KeyedClientLevelManager,
// this fallback may return the key for the wrong dimension in multiverse scenarios.
overrideLevel = KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel();
}
if (overrideLevel != null) if (overrideLevel != null)
{ {
WeakReference<ClientLevelWrapper> levelRef = LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.get(level);
if (levelRef != null && levelRef.get() != overrideLevel)
{
ClientLevelWrapper l = levelRef.get();
if (l != null) l.unload();
levelRef = null;
}
if (levelRef == null && overrideLevel instanceof ClientLevelWrapper)
{
LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL.put(level, new WeakReference<>((ClientLevelWrapper) overrideLevel));
}
return overrideLevel; return overrideLevel;
} }
} }
@@ -324,7 +441,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
} }
#if MC_VER <= MC_1_12_2 #if MC_VER <= MC_1_12_2
this.dimensionName = this.level.provider.getDimensionType().getName(); this.dimensionName = this.level.provider.getDimensionType().getName() + ":" + this.level.provider.getDimension();
#elif MC_VER <= MC_1_21_10 #elif MC_VER <= MC_1_21_10
this.dimensionName = this.level.dimension().location().toString(); this.dimensionName = this.level.dimension().location().toString();
#else #else
@@ -552,6 +669,45 @@ public class ClientLevelWrapper implements IClientLevelWrapper
#endif #endif
} }
@Override
public float getShade(EDhDirection lodDirection)
{
EDhApiLodShading lodShading = Config.Client.Advanced.Graphics.Quality.lodShading.get();
switch (lodShading)
{
default:
case AUTO:
#if MC_VER <= MC_1_12_2
// 1.12.2 level doesn't have a getShade method, fall through to ENABLED
#else
Direction mcDir = McObjectConverter.Convert(lodDirection);
#if MC_VER <= MC_1_21_11
return this.level.getShade(mcDir, true);
#else
return this.level.cardinalLighting().byFace(mcDir);
#endif
#endif
case ENABLED:
switch (lodDirection)
{
case DOWN:
return 0.5F;
default:
case UP:
return 1.0F;
case NORTH:
case SOUTH:
return 0.8F;
case WEST:
case EAST:
return 0.6F;
}
case DISABLED:
return 1.0F;
}
}
//endregion //endregion
@@ -196,7 +196,7 @@ public class ServerLevelWrapper implements IServerLevelWrapper
public String getDimensionName() public String getDimensionName()
{ {
#if MC_VER <= MC_1_12_2 #if MC_VER <= MC_1_12_2
return this.level.provider.getDimensionType().getName(); return this.level.provider.getDimensionType().getName() + ":" + this.level.provider.getDimension();
#elif MC_VER <= MC_1_21_10 #elif MC_VER <= MC_1_21_10
return this.level.dimension().location().toString(); return this.level.dimension().location().toString();
#else #else
+1 -22
View File
@@ -43,28 +43,7 @@ dependencies {
addMod("com.github.quiqueck:BCLib:${rootProject.bclib_version}", rootProject.enable_bclib) addMod("com.github.quiqueck:BCLib:${rootProject.bclib_version}", rootProject.enable_bclib)
// Canvas // Canvas
addMod("io.vram:canvas-fabric-${rootProject.canvas_version}", rootProject.enable_canvas) addMod("io.vram:canvas-fabric-${project.canvas_version}", rootProject.enable_canvas)
// Immersive Portals
if (rootProject.enable_immersive_portals == "1") {
modCompileOnly("com.github.iPortalTeam.ImmersivePortalsMod:imm_ptl_core:${rootProject.immersive_portals_version}")
}
else if (rootProject.enable_immersive_portals == "2") {
modImplementation ("com.github.iPortalTeam.ImmersivePortalsMod:imm_ptl_core:${rootProject.immersive_portals_version}") {
exclude(group: "net.fabricmc.fabric-api")
transitive(false)
}
modImplementation("com.github.iPortalTeam.ImmersivePortalsMod:q_misc_util:${rootProject.immersive_portals_version}") {
exclude(group: "net.fabricmc.fabric-api")
transitive(false)
}
modImplementation("com.github.iPortalTeam.ImmersivePortalsMod:build:${rootProject.immersive_portals_version}") {
exclude(group: "net.fabricmc.fabric-api")
transitive(false)
}
api("com.github.LlamaLad7:MixinExtras:0.2.0-beta.4")
annotationProcessor("com.github.LlamaLad7:MixinExtras:0.2.0-beta.4")
}
} }
@@ -116,6 +116,7 @@ public class FabricMain extends AbstractModInitializer implements ClientModIniti
this.tryCreateModCompatAccessor("optifine", IOptifineAccessor.class, OptifineAccessor::new); this.tryCreateModCompatAccessor("optifine", IOptifineAccessor.class, OptifineAccessor::new);
this.tryCreateModCompatAccessor("bclib", IBCLibAccessor.class, BCLibAccessor::new); this.tryCreateModCompatAccessor("bclib", IBCLibAccessor.class, BCLibAccessor::new);
this.tryCreateModCompatAccessor("c2me", IC2meAccessor.class, C2meAccessor::new); this.tryCreateModCompatAccessor("c2me", IC2meAccessor.class, C2meAccessor::new);
this.tryCreateModCompatAccessor("imm_ptl_core", IImmersivePortalsAccessor.class, ImmersivePortalsAccessorFabric::new);
#if MC_VER >= MC_1_19_4 #if MC_VER >= MC_1_19_4
// 1.19.4 is the lowest version Iris supports DH // 1.19.4 is the lowest version Iris supports DH
this.tryCreateModCompatAccessor("iris", IIrisAccessor.class, IrisAccessor::new); this.tryCreateModCompatAccessor("iris", IIrisAccessor.class, IrisAccessor::new);
@@ -0,0 +1,76 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020 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.fabric.mixins.client;
#if MC_VER <= MC_1_19_2
import com.mojang.math.Matrix4f;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(Matrix4f.class)
public interface AccessorMatrix4f
{
@Accessor("m00")
void setM00(float v);
@Accessor("m01")
void setM01(float v);
@Accessor("m02")
void setM02(float v);
@Accessor("m03")
void setM03(float v);
@Accessor("m10")
void setM10(float v);
@Accessor("m11")
void setM11(float v);
@Accessor("m12")
void setM12(float v);
@Accessor("m13")
void setM13(float v);
@Accessor("m20")
void setM20(float v);
@Accessor("m21")
void setM21(float v);
@Accessor("m22")
void setM22(float v);
@Accessor("m23")
void setM23(float v);
@Accessor("m30")
void setM30(float v);
@Accessor("m31")
void setM31(float v);
@Accessor("m32")
void setM32(float v);
@Accessor("m33")
void setM33(float v);
}
#else
import net.minecraft.world.entity.Entity;
import org.spongepowered.asm.mixin.Mixin;
@Mixin(Entity.class)
public interface AccessorMatrix4f
{ /* not present in newer MC versions */ }
#endif
@@ -32,7 +32,6 @@ public class MixinClientPacketListener
void onHandleLoginEnd(CallbackInfo ci) void onHandleLoginEnd(CallbackInfo ci)
{ {
ClientApi.INSTANCE.onClientOnlyConnected(); ClientApi.INSTANCE.onClientOnlyConnected();
ClientApi.INSTANCE.clientLevelLoadEvent(ClientLevelWrapper.getWrapper(this.level, true));
} }
#if MC_VER < MC_1_19_4 #if MC_VER < MC_1_19_4
@@ -61,10 +60,11 @@ public class MixinClientPacketListener
return; return;
} }
// Important to get the level from the chunk because the client level might be different if Immersive Portals is present.
ClientLevel level = (ClientLevel) chunk.getLevel();
executor.execute(() -> executor.execute(() ->
{ {
IClientLevelWrapper clientLevel = ClientLevelWrapper.getWrapper((ClientLevel) this.level); IClientLevelWrapper clientLevel = ClientLevelWrapper.getWrapper(level);
SharedApi.INSTANCE.applyChunkUpdate(new ChunkWrapper(chunk, clientLevel), clientLevel); SharedApi.INSTANCE.applyChunkUpdate(new ChunkWrapper(chunk, clientLevel), clientLevel);
}); });
} }
@@ -0,0 +1,25 @@
package com.seibel.distanthorizons.fabric.mixins.client;
import com.seibel.distanthorizons.common.commonMixins.MixinImmersivePortalsRenderStatesCommon;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Pseudo
#if MC_VER > MC_1_16_5
@Mixin(targets = "qouteall.imm_ptl.core.render.context_management.RenderStates")
#else
@Mixin(targets = "com.qouteall.immersive_portals.render.context_management.RenderStates")
#endif
public class MixinImmersivePortalsRenderStates
{
@Inject(method = "updatePreRenderInfo", at = @At("HEAD"))
private static void preRender(CallbackInfo ci)
{
MixinImmersivePortalsRenderStatesCommon.saveVolatileOriginals();
}
}
@@ -171,8 +171,6 @@ public class MixinLevelRenderer
ClientApi.RENDER_STATE.partialTickTime = MinecraftRenderWrapper.INSTANCE.getPartialTickTime(); ClientApi.RENDER_STATE.partialTickTime = MinecraftRenderWrapper.INSTANCE.getPartialTickTime();
ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, this.level); ClientApi.RENDER_STATE.clientLevelWrapper = ClientLevelWrapper.getWrapperIfDifferent(ClientApi.RENDER_STATE.clientLevelWrapper, this.level);
#if MC_VER < MC_1_21_6 #if MC_VER < MC_1_21_6
if (renderType.equals(RenderType.translucent())) if (renderType.equals(RenderType.translucent()))
{ {
@@ -20,6 +20,7 @@
package com.seibel.distanthorizons.fabric.mixins.client; package com.seibel.distanthorizons.fabric.mixins.client;
import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper; import com.seibel.distanthorizons.common.wrappers.minecraft.MinecraftRenderWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
@@ -85,18 +86,6 @@ public class MixinLightTexture
public void render(LightmapRenderState renderState, CallbackInfo ci) public void render(LightmapRenderState renderState, CallbackInfo ci)
#endif #endif
{ {
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
if (mc == null)
{
return;
}
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
if (clientLevel == null)
{
return;
}
// lazy initialization to make sure we don't call this too early // lazy initialization to make sure we don't call this too early
if (this.renderWrapper == null) if (this.renderWrapper == null)
{ {
@@ -105,18 +94,18 @@ public class MixinLightTexture
#if MC_VER < MC_1_21_3 #if MC_VER < MC_1_21_3
this.renderWrapper.updateLightmap(this.lightPixels, clientLevel); this.renderWrapper.updateLightmap(this.lightPixels);
#elif MC_VER < MC_1_21_5 #elif MC_VER < MC_1_21_5
this.renderWrapper.setLightmapId(this.target.getColorTextureId(), clientLevel); this.renderWrapper.setLightmapId(this.target.getColorTextureId());
#elif MC_VER <= MC_1_21_10 #elif MC_VER <= MC_1_21_10
GlTexture glTexture = (GlTexture) this.texture; GlTexture glTexture = (GlTexture) this.texture;
this.renderWrapper.setLightmapId(glTexture.glId(), clientLevel); this.renderWrapper.setLightmapId(glTexture.glId());
#else #else
// both options are available since the renderer can be changed to either Blaze3D or OpenGL // both options are available since the renderer can be changed to either Blaze3D or OpenGL
GlTexture glTexture = (GlTexture) this.texture; GlTexture glTexture = (GlTexture) this.texture;
this.renderWrapper.setLightmapId(glTexture.glId(), clientLevel); this.renderWrapper.setLightmapId(glTexture.glId());
this.renderWrapper.setLightmapGpuTexture(this.texture, clientLevel); this.renderWrapper.setLightmapGpuTexture(this.texture);
#endif #endif
} }
@@ -3,8 +3,6 @@ package com.seibel.distanthorizons.fabric.mixins.client;
import com.seibel.distanthorizons.api.enums.config.EDhApiUpdateBranch; import com.seibel.distanthorizons.api.enums.config.EDhApiUpdateBranch;
import com.seibel.distanthorizons.common.commonMixins.DhUpdateScreenBase; import com.seibel.distanthorizons.common.commonMixins.DhUpdateScreenBase;
import com.seibel.distanthorizons.common.wrappers.gui.updater.UpdateModScreen; import com.seibel.distanthorizons.common.wrappers.gui.updater.UpdateModScreen;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.jar.installer.GitlabGetter; import com.seibel.distanthorizons.core.jar.installer.GitlabGetter;
@@ -99,22 +97,6 @@ public abstract class MixinMinecraft
} }
#endif #endif
@Inject(at = @At("HEAD"), method = "updateLevelInEngines")
public void updateLevelInEngines(ClientLevel level, CallbackInfo ci)
{
if (this.lastLevel != null && level != this.lastLevel)
{
ClientApi.INSTANCE.clientLevelUnloadEvent(ClientLevelWrapper.getWrapper(this.lastLevel));
}
if (level != null)
{
ClientApi.INSTANCE.clientLevelLoadEvent(ClientLevelWrapper.getWrapper(level, true));
}
this.lastLevel = level;
}
@Inject(at = @At("HEAD"), method = "close()V") @Inject(at = @At("HEAD"), method = "close()V")
public void close(CallbackInfo ci) { SelfUpdater.onClose(); } public void close(CallbackInfo ci) { SelfUpdater.onClose(); }
@@ -0,0 +1,60 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020 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.fabric.wrappers.modAccessor;
import com.seibel.distanthorizons.common.wrappers.modAccessor.ImmersivePortalsAccessorCommon;
#if MC_VER <= MC_1_19_2
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.mojang.math.Matrix4f;
import com.seibel.distanthorizons.fabric.mixins.client.AccessorMatrix4f;
#endif
public class ImmersivePortalsAccessorFabric extends ImmersivePortalsAccessorCommon
{
#if MC_VER <= MC_1_19_2
@Override
protected Matrix4f convert(Mat4f matrix) {
Matrix4f returnMatrix = new Matrix4f();
AccessorMatrix4f accessibleMatrix = (AccessorMatrix4f) returnMatrix;
accessibleMatrix.setM00(matrix.m00);
accessibleMatrix.setM01(matrix.m01);
accessibleMatrix.setM02(matrix.m02);
accessibleMatrix.setM03(matrix.m03);
accessibleMatrix.setM10(matrix.m10);
accessibleMatrix.setM11(matrix.m11);
accessibleMatrix.setM12(matrix.m12);
accessibleMatrix.setM13(matrix.m13);
accessibleMatrix.setM20(matrix.m20);
accessibleMatrix.setM21(matrix.m21);
accessibleMatrix.setM22(matrix.m22);
accessibleMatrix.setM23(matrix.m23);
accessibleMatrix.setM30(matrix.m30);
accessibleMatrix.setM31(matrix.m31);
accessibleMatrix.setM32(matrix.m32);
accessibleMatrix.setM33(matrix.m33);
return returnMatrix;
}
#endif
}
@@ -3,6 +3,7 @@
"minVersion": "0.8", "minVersion": "0.8",
"package": "com.seibel.distanthorizons.fabric.mixins", "package": "com.seibel.distanthorizons.fabric.mixins",
"mixins": [ "mixins": [
"client.AccessorMatrix4f",
"server.MixinChunkGenerator", "server.MixinChunkGenerator",
"server.MixinChunkMap", "server.MixinChunkMap",
"server.MixinEntity", "server.MixinEntity",
@@ -17,6 +18,7 @@
"client.MixinDebugScreenOverlay", "client.MixinDebugScreenOverlay",
"client.MixinFogRenderer", "client.MixinFogRenderer",
"client.MixinGameRenderer", "client.MixinGameRenderer",
"client.MixinImmersivePortalsRenderStates",
"client.MixinLevelRenderer", "client.MixinLevelRenderer",
"client.MixinChunkSectionsToRender", "client.MixinChunkSectionsToRender",
"client.MixinLightTexture", "client.MixinLightTexture",
@@ -106,60 +106,6 @@ public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
} }
//==============//
// world events //
//==============//
@SubscribeEvent
#if MC_VER < MC_1_19_2
public void clientLevelLoadEvent(WorldEvent.Load event)
#else
public void clientLevelLoadEvent(LevelEvent.Load event)
#endif
{
LOGGER.info("level load");
#if MC_VER < MC_1_19_2
LevelAccessor level = event.getWorld();
#else
LevelAccessor level = event.getLevel();
#endif
if (!(level instanceof ClientLevel))
{
return;
}
ClientLevel clientLevel = (ClientLevel) level;
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel, true);
ClientApi.INSTANCE.clientLevelLoadEvent(clientLevelWrapper);
}
@SubscribeEvent
#if MC_VER < MC_1_19_2
public void clientLevelUnloadEvent(WorldEvent.Unload event)
#else
public void clientLevelUnloadEvent(LevelEvent.Unload event)
#endif
{
LOGGER.info("level unload");
#if MC_VER < MC_1_19_2
LevelAccessor level = event.getWorld();
#else
LevelAccessor level = event.getLevel();
#endif
if (!(level instanceof ClientLevel))
{
return;
}
ClientLevel clientLevel = (ClientLevel) level;
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel);
ClientApi.INSTANCE.clientLevelUnloadEvent(clientLevelWrapper);
}
//==============// //==============//
// chunk events // // chunk events //
//==============// //==============//
@@ -22,13 +22,13 @@ package com.seibel.distanthorizons.forge;
import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.CommandDispatcher;
import com.seibel.distanthorizons.common.AbstractModInitializer; import com.seibel.distanthorizons.common.AbstractModInitializer;
import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen; import com.seibel.distanthorizons.common.wrappers.gui.GetConfigScreen;
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector; import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender; import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor; import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.*;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.coreapi.ModInfo;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
import com.seibel.distanthorizons.forge.wrappers.modAccessor.ImmersivePortalsAccessorForge;
import com.seibel.distanthorizons.forge.wrappers.modAccessor.ModChecker; import com.seibel.distanthorizons.forge.wrappers.modAccessor.ModChecker;
import com.seibel.distanthorizons.forge.wrappers.modAccessor.OptifineAccessor; import com.seibel.distanthorizons.forge.wrappers.modAccessor.OptifineAccessor;
import com.seibel.distanthorizons.forge.wrappers.modAccessor.OculusAccessor; import com.seibel.distanthorizons.forge.wrappers.modAccessor.OculusAccessor;
@@ -104,6 +104,16 @@ public class ForgeMain extends AbstractModInitializer
{ {
this.tryCreateModCompatAccessor("optifine", IOptifineAccessor.class, OptifineAccessor::new); this.tryCreateModCompatAccessor("optifine", IOptifineAccessor.class, OptifineAccessor::new);
this.tryCreateModCompatAccessor("oculus", IIrisAccessor.class, OculusAccessor::new); this.tryCreateModCompatAccessor("oculus", IIrisAccessor.class, OculusAccessor::new);
IModChecker modChecker = SingletonInjector.INSTANCE.get(IModChecker.class);
// We ideally want to detect imm_ptl_core, but 1.16.5 did not provide that mod id.
if (modChecker.isModLoaded("imm_ptl_core") || modChecker.isModLoaded("immersive_portals"))
{
ModAccessorInjector.INSTANCE.bind(IImmersivePortalsAccessor.class, new ImmersivePortalsAccessorForge());
}
else
{
LOGGER.debug("Skipping mod compatibility accessor for: [ Immersive Portals ]");
}
#if MC_VER < MC_1_17_1 #if MC_VER < MC_1_17_1
ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY, ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY,
@@ -45,15 +45,7 @@ public class MixinFogRenderer
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 = #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
private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float partTick, CallbackInfo callback) private static void disableSetupFog(Camera camera, FogMode fogMode, float f, boolean bl, float partTick, CallbackInfo callback)
{ {
#if MC_VER < MC_1_21_6 if (MixinVanillaFogCommon.cancelFog(camera, fogMode))
boolean cancelFog = MixinVanillaFogCommon.cancelFog(camera, fogMode);
#elif MC_VER < MC_1_21_6
boolean cancelFog = MixinVanillaFogCommon.cancelFog(camera);
#else
boolean cancelFog = MixinVanillaFogCommon.cancelFog();
#endif
if (cancelFog)
{ {
#if MC_VER < MC_1_17_1 #if MC_VER < MC_1_17_1
RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE); RenderSystem.fogStart(A_REALLY_REALLY_BIG_VALUE);
@@ -0,0 +1,25 @@
package com.seibel.distanthorizons.forge.mixins.client;
import com.seibel.distanthorizons.common.commonMixins.MixinImmersivePortalsRenderStatesCommon;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Pseudo
#if MC_VER > MC_1_16_5
@Mixin(targets = "qouteall.imm_ptl.core.render.context_management.RenderStates")
#else
@Mixin(targets = "com.qouteall.immersive_portals.render.context_management.RenderStates")
#endif
public class MixinImmersivePortalsRenderStates
{
@Inject(method = "updatePreRenderInfo", at = @At("HEAD"))
private static void preRender(CallbackInfo ci)
{
MixinImmersivePortalsRenderStatesCommon.saveVolatileOriginals();
}
}
@@ -46,14 +46,7 @@ public class MixinLightTexture
@Inject(method = "updateLightTexture(F)V", at = @At("RETURN")) @Inject(method = "updateLightTexture(F)V", at = @At("RETURN"))
public void updateLightTexture(float partialTicks, CallbackInfo ci) public void updateLightTexture(float partialTicks, CallbackInfo ci)
{ {
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); MinecraftRenderWrapper.INSTANCE.updateLightmap(this.lightPixels);
if (mc == null || mc.getWrappedClientLevel() == null)
{
return;
}
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
MinecraftRenderWrapper.INSTANCE.updateLightmap(this.lightPixels, clientLevel);
} }
} }
@@ -0,0 +1,38 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020 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.forge.wrappers.modAccessor;
import com.seibel.distanthorizons.common.wrappers.modAccessor.ImmersivePortalsAccessorCommon;
#if MC_VER <= MC_1_19_2
import com.seibel.distanthorizons.core.util.math.Mat4f;
import com.mojang.math.Matrix4f;
#endif
public class ImmersivePortalsAccessorForge extends ImmersivePortalsAccessorCommon
{
#if MC_VER <= MC_1_19_2
@Override
protected Matrix4f convert(Mat4f matrix) {
return new Matrix4f(matrix.getValuesAsArray());
}
#endif
}
@@ -14,6 +14,7 @@
"client.MixinClientPacketListener", "client.MixinClientPacketListener",
"client.MixinDebugScreenOverlay", "client.MixinDebugScreenOverlay",
"client.MixinFogRenderer", "client.MixinFogRenderer",
"client.MixinImmersivePortalsRenderStates",
"client.MixinLevelRenderer", "client.MixinLevelRenderer",
"client.MixinLightTexture", "client.MixinLightTexture",
"client.MixinOptionsScreen" "client.MixinOptionsScreen"
@@ -30,14 +30,12 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelAccessor;
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
import net.neoforged.neoforge.client.event.RenderLevelStageEvent; import net.neoforged.neoforge.client.event.RenderLevelStageEvent;
import net.neoforged.neoforge.common.NeoForge; import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.event.level.LevelEvent;
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent; import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkAccess;
@@ -52,13 +50,7 @@ import net.neoforged.neoforge.client.event.InputEvent;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import org.lwjgl.opengl.GL32; import org.lwjgl.opengl.GL32;
#if MC_VER < MC_1_20_6
import net.neoforged.neoforge.event.TickEvent;
#else
import net.neoforged.neoforge.client.event.ClientTickEvent;
import java.util.concurrent.AbstractExecutorService; import java.util.concurrent.AbstractExecutorService;
#endif
public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
@@ -73,43 +65,6 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
//==============//
// world events //
//==============//
@SubscribeEvent
public void clientLevelLoadEvent(LevelEvent.Load event)
{
LOGGER.info("level load");
LevelAccessor level = event.getLevel();
if (!(level instanceof ClientLevel))
{
return;
}
ClientLevel clientLevel = (ClientLevel) level;
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel, true);
ClientApi.INSTANCE.clientLevelLoadEvent(clientLevelWrapper);
}
@SubscribeEvent
public void clientLevelUnloadEvent(LevelEvent.Unload event)
{
LOGGER.info("level unload");
LevelAccessor level = event.getLevel();
if (!(level instanceof ClientLevel))
{
return;
}
ClientLevel clientLevel = (ClientLevel) level;
IClientLevelWrapper clientLevelWrapper = ClientLevelWrapper.getWrapper(clientLevel);
ClientApi.INSTANCE.clientLevelUnloadEvent(clientLevelWrapper);
}
//==============// //==============//
// chunk events // // chunk events //
//==============// //==============//
@@ -163,11 +118,16 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
//LOGGER.trace("break or block attack at blockPos: " + event.getPos()); //LOGGER.trace("break or block attack at blockPos: " + event.getPos());
ChunkAccess chunk = level.getChunk(event.getPos()); ChunkAccess chunk = level.getChunk(event.getPos());
SharedApi.INSTANCE.applyChunkUpdate(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel); this.onBlockChangeEvent(level, chunk);
}); });
} }
} }
} }
private void onBlockChangeEvent(LevelAccessor level, ChunkAccess chunk)
{
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(level);
SharedApi.INSTANCE.applyChunkUpdate(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
}
@@ -261,7 +221,6 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
// handled via the same mixin as fabric for consistency // handled via the same mixin as fabric for consistency
#endif #endif
try try
{ {
// should generally only need to be set once per game session // should generally only need to be set once per game session
@@ -30,16 +30,10 @@ import com.seibel.distanthorizons.core.network.messages.AbstractNetworkMessage;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender; import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IPluginPacketSender;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IC2meAccessor; import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.*;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IIrisAccessor;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IModChecker;
import com.seibel.distanthorizons.core.wrapperInterfaces.modAccessor.IOptifineAccessor;
import com.seibel.distanthorizons.coreapi.ModInfo; import com.seibel.distanthorizons.coreapi.ModInfo;
import com.seibel.distanthorizons.neoforge.wrappers.modAccessor.C2meAccessor; import com.seibel.distanthorizons.neoforge.wrappers.modAccessor.*;
import com.seibel.distanthorizons.neoforge.wrappers.modAccessor.IrisAccessor;
import com.seibel.distanthorizons.neoforge.wrappers.NeoforgeMinecraftRenderWrapper; import com.seibel.distanthorizons.neoforge.wrappers.NeoforgeMinecraftRenderWrapper;
import com.seibel.distanthorizons.neoforge.wrappers.modAccessor.ModChecker;
import com.seibel.distanthorizons.neoforge.wrappers.modAccessor.OptifineAccessor;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.neoforged.bus.api.EventPriority; import net.neoforged.bus.api.EventPriority;
@@ -148,6 +142,7 @@ public class NeoforgeMain extends AbstractModInitializer
{ {
this.tryCreateModCompatAccessor("optifine", IOptifineAccessor.class, OptifineAccessor::new); this.tryCreateModCompatAccessor("optifine", IOptifineAccessor.class, OptifineAccessor::new);
this.tryCreateModCompatAccessor("c2me", IC2meAccessor.class, C2meAccessor::new); this.tryCreateModCompatAccessor("c2me", IC2meAccessor.class, C2meAccessor::new);
this.tryCreateModCompatAccessor("immersive_portals_core", IImmersivePortalsAccessor.class, ImmersivePortalsAccessorNeoForge::new);
#if MC_VER >= MC_1_20_6 #if MC_VER >= MC_1_20_6
// 1.20.6 is the lowest version Iris supports Neoforge // 1.20.6 is the lowest version Iris supports Neoforge
@@ -1,11 +1,8 @@
package com.seibel.distanthorizons.neoforge.mixins.client; package com.seibel.distanthorizons.neoforge.mixins.client;
import com.seibel.distanthorizons.common.wrappers.world.ClientLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.ClientApi; import com.seibel.distanthorizons.core.api.internal.ClientApi;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.multiplayer.ClientPacketListener; import net.minecraft.client.multiplayer.ClientPacketListener;
import org.spongepowered.asm.mixin.Mixin; 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.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@@ -13,14 +10,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientPacketListener.class) @Mixin(ClientPacketListener.class)
public class MixinClientPacketListener public class MixinClientPacketListener
{ {
@Shadow
private ClientLevel level;
@Inject(method = "handleLogin", at = @At("RETURN")) @Inject(method = "handleLogin", at = @At("RETURN"))
void onHandleLoginEnd(CallbackInfo ci) void onHandleLoginEnd(CallbackInfo ci)
{ {
ClientApi.INSTANCE.onClientOnlyConnected(); ClientApi.INSTANCE.onClientOnlyConnected();
ClientApi.INSTANCE.clientLevelLoadEvent(ClientLevelWrapper.getWrapper(this.level, true));
} }
#if MC_VER < MC_1_19_4 #if MC_VER < MC_1_19_4
@@ -0,0 +1,21 @@
package com.seibel.distanthorizons.neoforge.mixins.client;
import com.seibel.distanthorizons.common.commonMixins.MixinImmersivePortalsRenderStatesCommon;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Pseudo;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Pseudo
@Mixin(targets = "qouteall.imm_ptl.core.render.context_management.RenderStates")
public class MixinImmersivePortalsRenderStates
{
@Inject(method = "updatePreRenderInfo", at = @At("HEAD"))
private static void preRender(CallbackInfo ci)
{
MixinImmersivePortalsRenderStatesCommon.saveVolatileOriginals();
}
}
@@ -90,18 +90,6 @@ public class MixinLightTexture
public void render(LightmapRenderState renderState, CallbackInfo ci) public void render(LightmapRenderState renderState, CallbackInfo ci)
#endif #endif
{ {
IMinecraftClientWrapper mc = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
if (mc == null || mc.getWrappedClientLevel() == null)
{
return;
}
IClientLevelWrapper clientLevel = mc.getWrappedClientLevel();
if (clientLevel == null)
{
return;
}
// lazy initialization to make sure we don't call this too early // lazy initialization to make sure we don't call this too early
if (this.renderWrapper == null) if (this.renderWrapper == null)
{ {
@@ -110,21 +98,21 @@ public class MixinLightTexture
#if MC_VER < MC_1_21_3 #if MC_VER < MC_1_21_3
renderWrapper.updateLightmap(this.lightPixels, clientLevel); renderWrapper.updateLightmap(this.lightPixels);
#elif MC_VER < MC_1_21_5 #elif MC_VER < MC_1_21_5
renderWrapper.setLightmapId(this.target.getColorTextureId(), clientLevel); renderWrapper.setLightmapId(this.target.getColorTextureId());
#elif MC_VER < MC_1_21_9 #elif MC_VER < MC_1_21_9
GlTexture glTexture = (GlTexture) this.texture; GlTexture glTexture = (GlTexture) this.texture;
renderWrapper.setLightmapId(glTexture.glId(), clientLevel); renderWrapper.setLightmapId(glTexture.glId());
#elif MC_VER <= MC_1_21_10 #elif MC_VER <= MC_1_21_10
GlTexture glTexture = (GlTexture) this.texture; GlTexture glTexture = (GlTexture) this.texture;
renderWrapper.setLightmapId(glTexture.glId(), clientLevel); renderWrapper.setLightmapId(glTexture.glId());
#else #else
// both options are available since the renderer can be changed to either Blaze3D or OpenGL // both options are available since the renderer can be changed to either Blaze3D or OpenGL
int id = NeoforgeTextureUnwrapper.getGlTextureIdFromGpuTexture(this.texture); int id = NeoforgeTextureUnwrapper.getGlTextureIdFromGpuTexture(this.texture);
renderWrapper.setLightmapId(id, clientLevel); renderWrapper.setLightmapId(id);
renderWrapper.setLightmapGpuTexture(this.texture, clientLevel); renderWrapper.setLightmapGpuTexture(this.texture);
#endif #endif
} }
@@ -0,0 +1,26 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020 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.wrappers.modAccessor;
import com.seibel.distanthorizons.common.wrappers.modAccessor.ImmersivePortalsAccessorCommon;
public class ImmersivePortalsAccessorNeoForge extends ImmersivePortalsAccessorCommon
{
}
@@ -17,6 +17,7 @@
"client.MixinFogRenderer", "client.MixinFogRenderer",
"client.MixinChunkSectionsToRender", "client.MixinChunkSectionsToRender",
"client.MixinGameRenderer", "client.MixinGameRenderer",
"client.MixinImmersivePortalsRenderStates",
"client.MixinLevelRenderer", "client.MixinLevelRenderer",
"client.MixinLightTexture", "client.MixinLightTexture",
"client.MixinMinecraft", "client.MixinMinecraft",
-2
View File
@@ -25,7 +25,6 @@ fabric_api_version=0.42.0+1.16
sodium_version=mc1.16.5-0.2.0 sodium_version=mc1.16.5-0.2.0
iris_version=1.4.4+1.16.5 iris_version=1.4.4+1.16.5
bclib_version= bclib_version=
immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API # iris - needs 1.7.4+ to support the DH API
@@ -44,7 +43,6 @@ fabric_api_version=0.42.0+1.16
enable_iris=1 enable_iris=1
# not available via github, use curse.maven if necessary # not available via github, use curse.maven if necessary
enable_bclib=0 enable_bclib=0
enable_immersive_portals=0
enable_canvas=0 enable_canvas=0
# Forge loader # Forge loader
-2
View File
@@ -25,7 +25,6 @@ fabric_api_version=0.46.1+1.17
sodium_version=mc1.17.1-0.3.4 sodium_version=mc1.17.1-0.3.4
iris_version=1.17.x-v1.2.7 iris_version=1.17.x-v1.2.7
bclib_version=0.5.5 bclib_version=0.5.5
immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API # iris - needs 1.7.4+ to support the DH API
@@ -43,7 +42,6 @@ fabric_api_version=0.46.1+1.17
enable_sodium=1 enable_sodium=1
enable_iris=0 enable_iris=0
enable_bclib=1 enable_bclib=1
enable_immersive_portals=0
enable_canvas=0 enable_canvas=0
# Forge loader # Forge loader
-2
View File
@@ -26,7 +26,6 @@ fabric_api_version=0.76.0+1.18.2
sodium_version=mc1.18.2-0.4.1 sodium_version=mc1.18.2-0.4.1
iris_version=1.6.10+1.18.2 iris_version=1.6.10+1.18.2
bclib_version=1.4.6 bclib_version=1.4.6
immersive_portals_version=v1.4.11-1.18
canvas_version=mc118:1.0.2616 canvas_version=mc118:1.0.2616
# iris - needs 1.7.4+ to support the DH API # iris - needs 1.7.4+ to support the DH API
@@ -44,7 +43,6 @@ fabric_api_version=0.76.0+1.18.2
enable_lithium=0 enable_lithium=0
enable_iris=1 enable_iris=1
enable_bclib=1 enable_bclib=1
enable_immersive_portals=0
enable_canvas=0 enable_canvas=0
quilt_loader_version=0.19.1 quilt_loader_version=0.19.1
-2
View File
@@ -24,7 +24,6 @@ fabric_api_version=0.76.1+1.19.2
sodium_version=mc1.19.2-0.4.4 sodium_version=mc1.19.2-0.4.4
iris_version=1.6.10+1.19.2 iris_version=1.6.10+1.19.2
bclib_version=2.1.6 bclib_version=2.1.6
immersive_portals_version=
canvas_version=mc119-1.0.2480 canvas_version=mc119-1.0.2480
# iris - needs 1.7.4+ to support the DH API # iris - needs 1.7.4+ to support the DH API
@@ -42,7 +41,6 @@ fabric_api_version=0.76.1+1.19.2
enable_lithium=0 enable_lithium=0
enable_iris=1 enable_iris=1
enable_bclib=1 enable_bclib=1
enable_immersive_portals=0
enable_canvas=0 enable_canvas=0
# Forge loader # Forge loader
-2
View File
@@ -23,7 +23,6 @@ fabric_api_version=0.87.1+1.19.4
sodium_version=mc1.19.4-0.4.10 sodium_version=mc1.19.4-0.4.10
iris_version=1.6.10+1.19.4 iris_version=1.6.10+1.19.4
bclib_version=2.3.3 bclib_version=2.3.3
immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API # iris - needs 1.7.4+ to support the DH API
@@ -41,7 +40,6 @@ fabric_api_version=0.87.1+1.19.4
enable_lithium=0 enable_lithium=0
enable_iris=1 enable_iris=1
enable_bclib=1 enable_bclib=1
enable_immersive_portals=0
enable_canvas=0 enable_canvas=0
# Forge loader # Forge loader
-2
View File
@@ -23,7 +23,6 @@ fabric_api_version=0.92.6+1.20.1
sodium_version=mc1.20.1-0.5.3 sodium_version=mc1.20.1-0.5.3
iris_version=1.6.10+1.20.1 iris_version=1.6.10+1.20.1
bclib_version=3.0.13 bclib_version=3.0.13
immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API # iris - needs 1.7.4+ to support the DH API
@@ -41,7 +40,6 @@ fabric_api_version=0.92.6+1.20.1
enable_lithium=0 enable_lithium=0
enable_iris=1 enable_iris=1
enable_bclib=1 enable_bclib=1
enable_immersive_portals=0
enable_canvas=0 enable_canvas=0
# Forge loader # Forge loader
-2
View File
@@ -23,7 +23,6 @@ fabric_api_version=0.90.4+1.20.2
sodium_version=mc1.20.2-0.5.3 sodium_version=mc1.20.2-0.5.3
iris_version=1.6.10+1.20.2 iris_version=1.6.10+1.20.2
bclib_version=3.0.13 bclib_version=3.0.13
immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API # iris - needs 1.7.4+ to support the DH API
@@ -41,7 +40,6 @@ fabric_api_version=0.90.4+1.20.2
enable_lithium=0 enable_lithium=0
enable_iris=1 enable_iris=1
enable_bclib=1 enable_bclib=1
enable_immersive_portals=0
enable_canvas=0 enable_canvas=0
# Forge loader # Forge loader
-2
View File
@@ -24,7 +24,6 @@ fabric_api_version=0.91.2+1.20.4
sodium_version=mc1.20.3-0.5.4 sodium_version=mc1.20.3-0.5.4
iris_version=1.6.13+1.20.4 iris_version=1.6.13+1.20.4
bclib_version= bclib_version=
immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API # iris - needs 1.7.4+ to support the DH API
@@ -42,7 +41,6 @@ fabric_api_version=0.91.2+1.20.4
enable_lithium=0 enable_lithium=0
enable_iris=1 enable_iris=1
enable_bclib=0 enable_bclib=0
enable_immersive_portals=0
enable_canvas=0 enable_canvas=0
# Forge loader # Forge loader
-2
View File
@@ -24,7 +24,6 @@ fabric_api_version=0.97.8+1.20.6
sodium_version=mc1.20.6-0.5.8 sodium_version=mc1.20.6-0.5.8
iris_version=1.7.0+1.20.6 iris_version=1.7.0+1.20.6
bclib_version= bclib_version=
immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API # iris - needs 1.7.4+ to support the DH API
@@ -42,7 +41,6 @@ fabric_api_version=0.97.8+1.20.6
enable_lithium=0 enable_lithium=0
enable_iris=1 enable_iris=1
enable_bclib=0 enable_bclib=0
enable_immersive_portals=0
enable_canvas=0 enable_canvas=0
# NeoForge loader # NeoForge loader
-2
View File
@@ -24,7 +24,6 @@ fabric_api_version=0.116.11+1.21.1
sodium_version=mc1.21.1-0.6.2-fabric sodium_version=mc1.21.1-0.6.2-fabric
iris_version=1.8.1+1.21.1-fabric iris_version=1.8.1+1.21.1-fabric
bclib_version= bclib_version=
immersive_portals_version=
canvas_version= canvas_version=
# iris - needs 1.7.4+ to support the DH API # iris - needs 1.7.4+ to support the DH API
@@ -42,7 +41,6 @@ fabric_api_version=0.116.11+1.21.1
enable_lithium=0 enable_lithium=0
enable_iris=1 enable_iris=1
enable_bclib=0 enable_bclib=0
enable_immersive_portals=0
enable_canvas=0 enable_canvas=0
# NeoForge loader # NeoForge loader
-2
View File
@@ -23,7 +23,6 @@ fabric_api_version=0.138.4+1.21.10
sodium_version=mc1.21.10-0.7.2-fabric sodium_version=mc1.21.10-0.7.2-fabric
iris_version=1.9.6+1.21.10-fabric iris_version=1.9.6+1.21.10-fabric
bclib_version= bclib_version=
immersive_portals_version=
canvas_version= canvas_version=
fabric_incompatibility_list={ } fabric_incompatibility_list={ }
@@ -40,7 +39,6 @@ fabric_api_version=0.138.4+1.21.10
enable_lithium=0 enable_lithium=0
enable_iris=1 enable_iris=1
enable_bclib=0 enable_bclib=0
enable_immersive_portals=0
enable_canvas=0 enable_canvas=0
# NeoForge loader # NeoForge loader
-2
View File
@@ -23,7 +23,6 @@ fabric_api_version=0.139.4+1.21.11
sodium_version=mc1.21.11-0.8.0-fabric sodium_version=mc1.21.11-0.8.0-fabric
iris_version=1.10.0+1.21.11-fabric iris_version=1.10.0+1.21.11-fabric
bclib_version= bclib_version=
immersive_portals_version=
canvas_version= canvas_version=
fabric_incompatibility_list={ } fabric_incompatibility_list={ }
@@ -40,7 +39,6 @@ fabric_api_version=0.139.4+1.21.11
enable_lithium=0 enable_lithium=0
enable_iris=1 enable_iris=1
enable_bclib=0 enable_bclib=0
enable_immersive_portals=0
enable_canvas=0 enable_canvas=0
# NeoForge loader # NeoForge loader
-2
View File
@@ -24,7 +24,6 @@ fabric_api_version=0.110.0+1.21.3
sodium_version=mc1.21.3-0.6.0-fabric sodium_version=mc1.21.3-0.6.0-fabric
iris_version=1.8.0+1.21.3-fabric iris_version=1.8.0+1.21.3-fabric
bclib_version= bclib_version=
immersive_portals_version=
canvas_version= canvas_version=
# fabric-api 0.110.0 fixed a bug in MC 1.21.3 with the rendering API DH relied on # fabric-api 0.110.0 fixed a bug in MC 1.21.3 with the rendering API DH relied on
@@ -42,7 +41,6 @@ fabric_api_version=0.110.0+1.21.3
enable_lithium=0 enable_lithium=0
enable_iris=1 enable_iris=1
enable_bclib=0 enable_bclib=0
enable_immersive_portals=0
enable_canvas=0 enable_canvas=0
# NeoForge loader # NeoForge loader
-2
View File
@@ -24,7 +24,6 @@ fabric_api_version=0.110.5+1.21.4
sodium_version=mc1.21.4-0.6.2-fabric sodium_version=mc1.21.4-0.6.2-fabric
iris_version=1.8.2+1.21.4-fabric iris_version=1.8.2+1.21.4-fabric
bclib_version= bclib_version=
immersive_portals_version=
canvas_version= canvas_version=
fabric_incompatibility_list={ } fabric_incompatibility_list={ }
@@ -41,7 +40,6 @@ fabric_api_version=0.110.5+1.21.4
enable_lithium=0 enable_lithium=0
enable_iris=1 enable_iris=1
enable_bclib=0 enable_bclib=0
enable_immersive_portals=0
enable_canvas=0 enable_canvas=0
# NeoForge loader # NeoForge loader
-2
View File
@@ -23,7 +23,6 @@ fabric_api_version=0.119.5+1.21.5
sodium_version=mc1.21.5-0.6.11-fabric sodium_version=mc1.21.5-0.6.11-fabric
iris_version=1.8.10+1.21.5-fabric iris_version=1.8.10+1.21.5-fabric
bclib_version= bclib_version=
immersive_portals_version=
canvas_version= canvas_version=
# Iris - some versions of 1.8.11 nightly builds may not work, but the ones after 2025-03-30 should # Iris - some versions of 1.8.11 nightly builds may not work, but the ones after 2025-03-30 should
@@ -41,7 +40,6 @@ fabric_api_version=0.119.5+1.21.5
enable_lithium=0 enable_lithium=0
enable_iris=1 enable_iris=1
enable_bclib=0 enable_bclib=0
enable_immersive_portals=0
enable_canvas=0 enable_canvas=0
# NeoForge loader # NeoForge loader
-2
View File
@@ -23,7 +23,6 @@ fabric_api_version=0.127.0+1.21.6
sodium_version=mc1.21.6-0.6.13-fabric sodium_version=mc1.21.6-0.6.13-fabric
iris_version=1.9.0+1.21.6-fabric iris_version=1.9.0+1.21.6-fabric
bclib_version= bclib_version=
immersive_portals_version=
canvas_version= canvas_version=
fabric_incompatibility_list={ } fabric_incompatibility_list={ }
@@ -40,7 +39,6 @@ fabric_api_version=0.127.0+1.21.6
enable_lithium=0 enable_lithium=0
enable_iris=1 enable_iris=1
enable_bclib=0 enable_bclib=0
enable_immersive_portals=0
enable_canvas=0 enable_canvas=0
# NeoForge loader # NeoForge loader
-2
View File
@@ -23,7 +23,6 @@ fabric_api_version=0.133.4+1.21.8
sodium_version=mc1.21.6-0.6.13-fabric sodium_version=mc1.21.6-0.6.13-fabric
iris_version=1.9.1+1.21.7-fabric iris_version=1.9.1+1.21.7-fabric
bclib_version= bclib_version=
immersive_portals_version=
canvas_version= canvas_version=
fabric_incompatibility_list={ } fabric_incompatibility_list={ }
@@ -40,7 +39,6 @@ fabric_api_version=0.133.4+1.21.8
enable_lithium=0 enable_lithium=0
enable_iris=1 enable_iris=1
enable_bclib=0 enable_bclib=0
enable_immersive_portals=0
enable_canvas=0 enable_canvas=0
# NeoForge loader # NeoForge loader
-2
View File
@@ -23,7 +23,6 @@ fabric_api_version=0.134.0+1.21.9
sodium_version=mc1.21.10-0.7.2-fabric sodium_version=mc1.21.10-0.7.2-fabric
iris_version=1.9.3+1.21.9-fabric iris_version=1.9.3+1.21.9-fabric
bclib_version= bclib_version=
immersive_portals_version=
canvas_version= canvas_version=
fabric_incompatibility_list={ } fabric_incompatibility_list={ }
@@ -40,7 +39,6 @@ fabric_api_version=0.134.0+1.21.9
enable_lithium=0 enable_lithium=0
enable_iris=1 enable_iris=1
enable_bclib=0 enable_bclib=0
enable_immersive_portals=0
enable_canvas=0 enable_canvas=0
# NeoForge loader # NeoForge loader