Add original level resource to level init

This commit is contained in:
s809
2026-06-07 01:32:52 +05:00
parent 656bf17191
commit 4a2f7178ee
7 changed files with 29 additions and 67 deletions
@@ -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);
}
@@ -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<String, KeyInfo> 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
@@ -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())
{
@@ -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)
{
@@ -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<ClientLevelWrapper>> 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
@@ -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()
{