diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/DependencySetup.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/DependencySetup.java index 7e6affedf..2a25a4be2 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/DependencySetup.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/DependencySetup.java @@ -66,7 +66,7 @@ public class DependencySetup SingletonInjector.INSTANCE.bind(ILangWrapper.class, LangWrapper.INSTANCE); SingletonInjector.INSTANCE.bind(IVersionConstants.class, VersionConstants.INSTANCE); SingletonInjector.INSTANCE.bind(IWrapperFactory.class, WrapperFactory.INSTANCE); - SingletonInjector.INSTANCE.bind(IKeyedClientLevelManager.class, KeyedClientLevelManager.INSTANCE); + SingletonInjector.INSTANCE.bind(IKeyedClientLevelManager.class, new KeyedClientLevelManager()); SingletonInjector.INSTANCE.bind(IDhApiCustomRenderObjectFactory.class, GenericRenderObjectFactory.INSTANCE); } diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/level/KeyedClientLevelManager.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/level/KeyedClientLevelManager.java index 9e8e210a5..58262555b 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/level/KeyedClientLevelManager.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/level/KeyedClientLevelManager.java @@ -19,8 +19,6 @@ import java.util.concurrent.ConcurrentHashMap; public class KeyedClientLevelManager implements IKeyedClientLevelManager { - public static final KeyedClientLevelManager INSTANCE = new KeyedClientLevelManager(); - /** Stores the server-provided keys indexed by dimension name for persistence. */ private final Map keysByDimensionName = new ConcurrentHashMap<>(); @@ -33,18 +31,6 @@ public class KeyedClientLevelManager implements IKeyedClientLevelManager - - //=============// - // constructor // - //=============// - //region - - private KeyedClientLevelManager() { } - - //endregion - - - //======================// // level override logic // //======================// @@ -52,19 +38,9 @@ public class KeyedClientLevelManager implements IKeyedClientLevelManager @Override @Nullable - 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) + public IServerKeyedClientLevel getServerKeyedLevel(IClientLevelWrapper levelWrapper) { - if (level == null) + if (levelWrapper == null) { return null; } @@ -73,6 +49,8 @@ public class KeyedClientLevelManager implements IKeyedClientLevelManager // This prevents multiple threads from creating duplicate wrappers for the same level. synchronized (this.keyedLevelsCache) { + ClientLevel level = (ClientLevel) levelWrapper.getWrappedMcObject(); + // Check the cache first IServerKeyedClientLevel cached = this.keyedLevelsCache.get(level); if (cached != null) @@ -103,47 +81,31 @@ public class KeyedClientLevelManager implements IKeyedClientLevelManager } @Override - public IServerKeyedClientLevel setServerKeyedLevel(IClientLevelWrapper clientLevel, String serverKey, String levelKey) + public IServerKeyedClientLevel setServerKeyedLevel(IClientLevelWrapper clientLevel, String dimensionResource, String serverKey, String levelKey) { - // 1. Determine the target dimension name - String targetDimensionName = clientLevel.getDimensionName(); - int separatorIndex = levelKey.lastIndexOf("@"); - if (separatorIndex != -1) - { - targetDimensionName = levelKey.substring(separatorIndex + 1); - } - - final String finalTargetDimensionName = targetDimensionName; - - // 2. Store the key for this dimension - this.keysByDimensionName.put(finalTargetDimensionName, new KeyInfo(serverKey, levelKey)); + this.keysByDimensionName.put(dimensionResource, new KeyInfo(serverKey, levelKey)); this.enabled = true; - // 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 + 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 + #else + String levelDim = level.dimension().identifier().toString(); + #endif - return levelDim.equals(finalTargetDimensionName); + return levelDim.equals(dimensionResource); }); } - // 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()); + if (clientLevel == null || !clientLevel.getDimensionName().equals(dimensionResource)) { + return null; + } + + return this.getServerKeyedLevel(clientLevel); } @Override diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftClientWrapper.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftClientWrapper.java index b6dd9853a..b21e9f9b9 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftClientWrapper.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftClientWrapper.java @@ -641,7 +641,7 @@ public class MinecraftClientWrapper extends AbstractMinecraftSharedWrapper imple @Nullable @Override - public IServerLevelWrapper getWrappedServerLevelWithDimensionResourceLocation(String dimensionResourceLocation) + public IServerLevelWrapper getLevelWrapper(String dimensionResourceLocation) { if (!this.hasSinglePlayerServer()) { diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftServerWrapper.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftServerWrapper.java index 04d6c8be9..26e9516c4 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftServerWrapper.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/minecraft/MinecraftServerWrapper.java @@ -88,7 +88,7 @@ public class MinecraftServerWrapper extends AbstractMinecraftSharedWrapper @Nullable @Override - public IServerLevelWrapper getWrappedServerLevelWithDimensionResourceLocation(String dimensionResourceLocation) + public IServerLevelWrapper getLevelWrapper(String dimensionResourceLocation) { if (this.dedicatedServer == null) { diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java index ae8c919e2..2fb3fb8c4 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ClientLevelWrapper.java @@ -87,7 +87,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper private static final Map< #if MC_VER <= MC_1_12_2 WorldClient #else ClientLevel #endif, WeakReference> LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL = Collections.synchronizedMap(new WeakHashMap<>()); - private static final KeyedClientLevelManager KEYED_CLIENT_LEVEL_MANAGER = KeyedClientLevelManager.INSTANCE; + private static final KeyedClientLevelManager KEYED_CLIENT_LEVEL_MANAGER = (KeyedClientLevelManager) SingletonInjector.INSTANCE.get(IKeyedClientLevelManager.class); #if MC_VER <= MC_1_12_2 private static final Minecraft MINECRAFT = Minecraft.getMinecraft(); @@ -233,7 +233,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper { if (KEYED_CLIENT_LEVEL_MANAGER.isEnabled()) { - IServerKeyedClientLevel keyedLevel = KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel(level); + IServerKeyedClientLevel keyedLevel = KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel(getWrapper(level, true)); if (keyedLevel != levelWrapper) { return getWrapper(level); @@ -267,7 +267,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper } // used if the client is connected to a server that defines the currently loaded level - IServerKeyedClientLevel overrideLevel = KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel(level); + IServerKeyedClientLevel overrideLevel = KEYED_CLIENT_LEVEL_MANAGER.getServerKeyedLevel(getWrapper(level, true)); if (overrideLevel != null) { // if the currently loaded level wrapper doesn't match what's incoming, unload it diff --git a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ServerLevelWrapper.java b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ServerLevelWrapper.java index b98870288..7e311df5b 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ServerLevelWrapper.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/wrappers/world/ServerLevelWrapper.java @@ -83,7 +83,7 @@ public class ServerLevelWrapper implements IServerLevelWrapper * this name is cached to prevent issues during shutdown where * the server variables needed may no longer be available. */ - private final String KeyedLevelDimensionName; + private final String keyedLevelDimensionName; @@ -112,7 +112,7 @@ public class ServerLevelWrapper implements IServerLevelWrapper public ServerLevelWrapper(#if MC_VER <= MC_1_12_2 WorldServer #else ServerLevel #endif level) { this.level = level; - this.KeyedLevelDimensionName = this.createKeyedLevelDimensionName(); + this.keyedLevelDimensionName = this.createKeyedLevelDimensionName(); } //endregion @@ -137,7 +137,7 @@ public class ServerLevelWrapper implements IServerLevelWrapper } @Override - public String getKeyedLevelDimensionName() { return this.KeyedLevelDimensionName; } + public String getKeyedLevelDimensionName() { return this.keyedLevelDimensionName; } private String createKeyedLevelDimensionName() { diff --git a/coreSubProjects b/coreSubProjects index 8a4f99190..4e99594a3 160000 --- a/coreSubProjects +++ b/coreSubProjects @@ -1 +1 @@ -Subproject commit 8a4f991906883075f39c7bad2605c4fad6c6b4fe +Subproject commit 4e99594a3f023900918c024d8e521624bb4f1d4e