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(ILangWrapper.class, LangWrapper.INSTANCE);
SingletonInjector.INSTANCE.bind(IVersionConstants.class, VersionConstants.INSTANCE); SingletonInjector.INSTANCE.bind(IVersionConstants.class, VersionConstants.INSTANCE);
SingletonInjector.INSTANCE.bind(IWrapperFactory.class, WrapperFactory.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); SingletonInjector.INSTANCE.bind(IDhApiCustomRenderObjectFactory.class, GenericRenderObjectFactory.INSTANCE);
} }
@@ -19,8 +19,6 @@ import java.util.concurrent.ConcurrentHashMap;
public class KeyedClientLevelManager implements IKeyedClientLevelManager public class KeyedClientLevelManager implements IKeyedClientLevelManager
{ {
public static final KeyedClientLevelManager INSTANCE = new KeyedClientLevelManager();
/** Stores the server-provided keys indexed by dimension name for persistence. */ /** Stores the server-provided keys indexed by dimension name for persistence. */
private final Map<String, KeyInfo> keysByDimensionName = new ConcurrentHashMap<>(); 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 // // level override logic //
//======================// //======================//
@@ -52,19 +38,9 @@ public class KeyedClientLevelManager implements IKeyedClientLevelManager
@Override @Override
@Nullable @Nullable
public IServerKeyedClientLevel getServerKeyedLevel() public IServerKeyedClientLevel getServerKeyedLevel(IClientLevelWrapper levelWrapper)
{ {
#if MC_VER > MC_1_12_2 if (levelWrapper == null)
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; return null;
} }
@@ -73,6 +49,8 @@ public class KeyedClientLevelManager implements IKeyedClientLevelManager
// This prevents multiple threads from creating duplicate wrappers for the same level. // This prevents multiple threads from creating duplicate wrappers for the same level.
synchronized (this.keyedLevelsCache) synchronized (this.keyedLevelsCache)
{ {
ClientLevel level = (ClientLevel) levelWrapper.getWrappedMcObject();
// Check the cache first // Check the cache first
IServerKeyedClientLevel cached = this.keyedLevelsCache.get(level); IServerKeyedClientLevel cached = this.keyedLevelsCache.get(level);
if (cached != null) if (cached != null)
@@ -103,32 +81,14 @@ public class KeyedClientLevelManager implements IKeyedClientLevelManager
} }
@Override @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 this.keysByDimensionName.put(dimensionResource, new KeyInfo(serverKey, levelKey));
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.enabled = true; 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) synchronized (this.keyedLevelsCache)
{ {
this.keyedLevelsCache.keySet().removeIf(level -> this.keyedLevelsCache.keySet().removeIf(level -> {
{
#if MC_VER <= MC_1_12_2 #if MC_VER <= MC_1_12_2
String levelDim = level.provider.getDimensionType().getName() + ":" + level.provider.getDimension(); String levelDim = level.provider.getDimensionType().getName() + ":" + level.provider.getDimension();
#elif MC_VER <= MC_1_21_10 #elif MC_VER <= MC_1_21_10
@@ -137,13 +97,15 @@ public class KeyedClientLevelManager implements IKeyedClientLevelManager
String levelDim = level.dimension().identifier().toString(); String levelDim = level.dimension().identifier().toString();
#endif #endif
return levelDim.equals(finalTargetDimensionName); return levelDim.equals(dimensionResource);
}); });
} }
// 4. Return the keyed wrapper for whatever level the core passed us, if (clientLevel == null || !clientLevel.getDimensionName().equals(dimensionResource)) {
// but only if it matches the dimension we just keyed. return null;
return this.getServerKeyedLevel((#if MC_VER > MC_1_12_2 ClientLevel #else WorldClient #endif) clientLevel.getWrappedMcObject()); }
return this.getServerKeyedLevel(clientLevel);
} }
@Override @Override
@@ -641,7 +641,7 @@ public class MinecraftClientWrapper extends AbstractMinecraftSharedWrapper imple
@Nullable @Nullable
@Override @Override
public IServerLevelWrapper getWrappedServerLevelWithDimensionResourceLocation(String dimensionResourceLocation) public IServerLevelWrapper getLevelWrapper(String dimensionResourceLocation)
{ {
if (!this.hasSinglePlayerServer()) if (!this.hasSinglePlayerServer())
{ {
@@ -88,7 +88,7 @@ public class MinecraftServerWrapper extends AbstractMinecraftSharedWrapper
@Nullable @Nullable
@Override @Override
public IServerLevelWrapper getWrappedServerLevelWithDimensionResourceLocation(String dimensionResourceLocation) public IServerLevelWrapper getLevelWrapper(String dimensionResourceLocation)
{ {
if (this.dedicatedServer == null) if (this.dedicatedServer == null)
{ {
@@ -87,7 +87,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
private static final Map< private static final Map<
#if MC_VER <= MC_1_12_2 WorldClient #else ClientLevel #endif, #if MC_VER <= MC_1_12_2 WorldClient #else ClientLevel #endif,
WeakReference<ClientLevelWrapper>> LEVEL_WRAPPER_REF_BY_CLIENT_LEVEL = Collections.synchronizedMap(new WeakHashMap<>()); 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 #if MC_VER <= MC_1_12_2
private static final Minecraft MINECRAFT = Minecraft.getMinecraft(); private static final Minecraft MINECRAFT = Minecraft.getMinecraft();
@@ -233,7 +233,7 @@ public class ClientLevelWrapper implements IClientLevelWrapper
{ {
if (KEYED_CLIENT_LEVEL_MANAGER.isEnabled()) 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) if (keyedLevel != levelWrapper)
{ {
return getWrapper(level); 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 // 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 (overrideLevel != null)
{ {
// if the currently loaded level wrapper doesn't match what's incoming, unload it // 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 * this name is cached to prevent issues during shutdown where
* the server variables needed may no longer be available. * 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) public ServerLevelWrapper(#if MC_VER <= MC_1_12_2 WorldServer #else ServerLevel #endif level)
{ {
this.level = level; this.level = level;
this.KeyedLevelDimensionName = this.createKeyedLevelDimensionName(); this.keyedLevelDimensionName = this.createKeyedLevelDimensionName();
} }
//endregion //endregion
@@ -137,7 +137,7 @@ public class ServerLevelWrapper implements IServerLevelWrapper
} }
@Override @Override
public String getKeyedLevelDimensionName() { return this.KeyedLevelDimensionName; } public String getKeyedLevelDimensionName() { return this.keyedLevelDimensionName; }
private String createKeyedLevelDimensionName() private String createKeyedLevelDimensionName()
{ {