Fix chunks applying to the wrong dimension

This commit is contained in:
James Seibel
2026-02-18 22:05:30 -06:00
parent c5bfdbc430
commit 2866aefb90
8 changed files with 86 additions and 52 deletions
@@ -4,6 +4,7 @@ import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.ServerApi;
import com.seibel.distanthorizons.core.api.internal.SharedApi;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.chunk.ChunkAccess;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@@ -13,8 +14,10 @@ public class MixinChunkMapCommon
public static void onChunkSave(ServerLevel level, ChunkAccess chunk, CallbackInfoReturnable<Boolean> ci)
{
IServerLevelWrapper levelWrapper = ServerLevelWrapper.getWrapper(level);
// is this position already being updated?
if (SharedApi.isChunkAtChunkPosAlreadyUpdating(chunk.getPos().x, chunk.getPos().z))
if (SharedApi.isChunkAtChunkPosAlreadyUpdating(levelWrapper, chunk.getPos().x, chunk.getPos().z))
{
return;
}
@@ -73,8 +76,8 @@ public class MixinChunkMapCommon
// submit the update event
ServerApi.INSTANCE.serverChunkSaveEvent(
new ChunkWrapper(chunk, ServerLevelWrapper.getWrapper(level)),
ServerLevelWrapper.getWrapper(level)
new ChunkWrapper(chunk, levelWrapper),
levelWrapper
);
}
@@ -29,6 +29,8 @@ import com.seibel.distanthorizons.common.wrappers.worldGeneration.chunkFileHandl
import com.seibel.distanthorizons.common.wrappers.worldGeneration.mimicObject.*;
import com.seibel.distanthorizons.common.wrappers.worldGeneration.params.GlobalWorldGenParams;
import com.seibel.distanthorizons.core.api.internal.SharedApi;
import com.seibel.distanthorizons.core.api.internal.chunkUpdating.ChunkUpdateQueueManager;
import com.seibel.distanthorizons.core.api.internal.chunkUpdating.WorldChunkUpdateManager;
import com.seibel.distanthorizons.core.generation.DhLightingEngine;
import com.seibel.distanthorizons.core.level.IDhServerLevel;
import com.seibel.distanthorizons.core.config.Config;
@@ -590,7 +592,11 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm
// usually ignoring the chunk's position is unnecessary,
// but this improves performance if a chunk update event does sneak through
SharedApi.CHUNK_UPDATE_QUEUE_MANAGER.addPosToIgnore(chunkWrapper.getChunkPos());
ChunkUpdateQueueManager updateManager = WorldChunkUpdateManager.INSTANCE.getByLevelWrapper(this.dhServerLevel.getServerLevelWrapper());
if (updateManager != null)
{
updateManager.addPosToIgnore(chunkWrapper.getChunkPos());
}
});
@@ -716,7 +722,19 @@ public final class BatchGenerationEnvironment implements IBatchGeneratorEnvironm
this.chunkSaveIgnoreTimer.schedule(new TimerTask()
{
@Override
public void run() { SharedApi.CHUNK_UPDATE_QUEUE_MANAGER.removePosToIgnore(chunkWrapper.getChunkPos()); }
public void run()
{
ChunkUpdateQueueManager updateManager = WorldChunkUpdateManager.INSTANCE.getByLevelWrapper(BatchGenerationEnvironment.this.dhServerLevel.getServerLevelWrapper());
if (updateManager != null)
{
updateManager.addPosToIgnore(chunkWrapper.getChunkPos());
}
else
{
// shouldn't happen, but just in case
LOGGER.warn("Unable to find chunk update manager for server level ["+BatchGenerationEnvironment.this.dhServerLevel+"], chunk updates may fail.");
}
}
}, MS_TO_IGNORE_CHUNK_AFTER_COMPLETION);
}
}
@@ -5,10 +5,13 @@ import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.common.wrappers.worldGeneration.params.GlobalWorldGenParams;
import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.api.internal.SharedApi;
import com.seibel.distanthorizons.core.api.internal.chunkUpdating.ChunkUpdateQueueManager;
import com.seibel.distanthorizons.core.api.internal.chunkUpdating.WorldChunkUpdateManager;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
import com.seibel.distanthorizons.core.enums.MinecraftTextFormat;
import com.seibel.distanthorizons.core.generation.DhLightingEngine;
import com.seibel.distanthorizons.core.level.DhServerLevel;
import com.seibel.distanthorizons.core.level.IDhServerLevel;
import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
@@ -190,7 +193,7 @@ public class InternalServerGenerator
while (chunkPosIterator.hasNext())
{
ChunkPos chunkPos = chunkPosIterator.next();
this.releaseChunkFromServer(this.params.mcServerLevel, chunkPos);
this.releaseChunkFromServer(this.params.mcServerLevel, this.params.dhServerLevel, chunkPos);
}
}
}
@@ -234,7 +237,11 @@ public class InternalServerGenerator
ServerLevel level = this.params.mcServerLevel;
// ignore chunk update events for this position
SharedApi.CHUNK_UPDATE_QUEUE_MANAGER.addPosToIgnore(new DhChunkPos(chunkPos.x, chunkPos.z));
ChunkUpdateQueueManager updateManager = WorldChunkUpdateManager.INSTANCE.getByLevelWrapper(this.params.dhServerLevel.getServerLevelWrapper());
if (updateManager != null)
{
updateManager.addPosToIgnore(new DhChunkPos(chunkPos.x, chunkPos.z));
}
#if MC_VER < MC_1_21_5
int chunkLevel = 33; // 33 is equivalent to FULL Chunk
@@ -270,7 +277,7 @@ public class InternalServerGenerator
* mitigates out of memory issues in the vanilla chunk system. <br>
* See: https://github.com/pop4959/Chunky/pull/383
*/
private void releaseChunkFromServer(ServerLevel level, ChunkPos chunkPos)
private void releaseChunkFromServer(ServerLevel level, IDhServerLevel dhLevel, ChunkPos chunkPos)
{
level.getChunkSource().chunkMap.mainThreadExecutor.execute(() ->
{
@@ -295,7 +302,19 @@ public class InternalServerGenerator
this.chunkSaveIgnoreTimer.schedule(new TimerTask()
{
@Override
public void run() { SharedApi.CHUNK_UPDATE_QUEUE_MANAGER.removePosToIgnore(new DhChunkPos(chunkPos.x, chunkPos.z)); }
public void run()
{
ChunkUpdateQueueManager updateManager = WorldChunkUpdateManager.INSTANCE.getByLevelWrapper(dhLevel.getServerLevelWrapper());
if (updateManager != null)
{
updateManager.addPosToIgnore(new DhChunkPos(chunkPos.x, chunkPos.z));
}
else
{
// shouldn't happen, but just in case
LOGGER.warn("Unable to find chunk update manager for server level ["+dhLevel+"], chunk updates may fail.");
}
}
}, MS_TO_IGNORE_CHUNK_AFTER_COMPLETION);
}
@@ -132,7 +132,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
executor.execute(() ->
{
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper(level);
SharedApi.INSTANCE.chunkLoadEvent(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
SharedApi.INSTANCE.applyChunkUpdate(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
});
}
}
@@ -145,7 +145,9 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
// if we have access to the server, use the chunk save event instead
if (MC.clientConnectedToDedicatedServer())
{
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(blockPos.getX(), blockPos.getZ()))
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level);
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(wrappedLevel, blockPos.getX(), blockPos.getZ()))
{
// executor to prevent locking up the render/event thread
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
@@ -158,8 +160,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
{
//LOGGER.trace("attack block at blockPos: " + blockPos);
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level);
SharedApi.INSTANCE.chunkBlockChangedEvent(
SharedApi.INSTANCE.applyChunkUpdate(
new ChunkWrapper(chunk, wrappedLevel),
wrappedLevel
);
@@ -183,7 +184,9 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
if (hitResult.getType() == HitResult.Type.BLOCK
&& !hitResult.isInside())
{
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(hitResult.getBlockPos().getX(), hitResult.getBlockPos().getZ()))
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level);
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(wrappedLevel, hitResult.getBlockPos().getX(), hitResult.getBlockPos().getZ()))
{
// executor to prevent locking up the render/event thread
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
@@ -196,8 +199,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
{
//LOGGER.trace("use block at blockPos: " + hitResult.getBlockPos());
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level);
SharedApi.INSTANCE.chunkBlockChangedEvent(
SharedApi.INSTANCE.applyChunkUpdate(
new ChunkWrapper(chunk, wrappedLevel),
wrappedLevel
);
@@ -65,7 +65,7 @@ public class MixinClientPacketListener
executor.execute(() ->
{
IClientLevelWrapper clientLevel = ClientLevelWrapper.getWrapper((ClientLevel) this.level);
SharedApi.INSTANCE.chunkLoadEvent(new ChunkWrapper(chunk, clientLevel), clientLevel);
SharedApi.INSTANCE.applyChunkUpdate(new ChunkWrapper(chunk, clientLevel), clientLevel);
});
}
@@ -169,26 +169,25 @@ public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
{
if (MC.clientConnectedToDedicatedServer())
{
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(event.getPos().getX(), event.getPos().getZ()))
{
return;
}
//LOGGER.trace("interact or block place event at blockPos: " + event.getPos());
#if MC_VER < MC_1_19_2
LevelAccessor level = event.getWorld();
#else
LevelAccessor level = event.getLevel();
#endif
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(level);
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(wrappedLevel, event.getPos().getX(), event.getPos().getZ()))
{
return;
}
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
if (executor != null)
{
executor.execute(() ->
{
ChunkAccess chunk = level.getChunk(event.getPos());
this.onBlockChangeEvent(level, chunk);
SharedApi.INSTANCE.applyChunkUpdate(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
});
}
}
@@ -198,35 +197,29 @@ public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
{
if (MC.clientConnectedToDedicatedServer())
{
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(event.getPos().getX(), event.getPos().getZ()))
{
return;
}
//LOGGER.trace("break or block attack at blockPos: " + event.getPos());
#if MC_VER < MC_1_19_2
LevelAccessor level = event.getWorld();
#else
LevelAccessor level = event.getLevel();
#endif
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(level);
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(wrappedLevel, event.getPos().getX(), event.getPos().getZ()))
{
return;
}
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
if (executor != null)
{
executor.execute(() ->
{
ChunkAccess chunk = level.getChunk(event.getPos());
this.onBlockChangeEvent(level, chunk);
SharedApi.INSTANCE.applyChunkUpdate(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
});
}
}
}
private void onBlockChangeEvent(LevelAccessor level, ChunkAccess chunk)
{
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(level);
SharedApi.INSTANCE.chunkBlockChangedEvent(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
}
@SubscribeEvent
public void clientChunkLoadEvent(ChunkEvent.Load event)
@@ -234,8 +227,8 @@ public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
if (MC.clientConnectedToDedicatedServer())
{
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(GetEventLevel(event));
IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), wrappedLevel);
SharedApi.INSTANCE.chunkLoadEvent(chunk, wrappedLevel);
IChunkWrapper chunkWrapper = new ChunkWrapper(event.getChunk(), wrappedLevel);
SharedApi.INSTANCE.applyChunkUpdate(chunkWrapper, wrappedLevel);
}
}
@@ -119,7 +119,10 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
{
if (MC.clientConnectedToDedicatedServer())
{
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(event.getPos().getX(), event.getPos().getZ()))
LevelAccessor level = event.getLevel();
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(level);
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(wrappedLevel, event.getPos().getX(), event.getPos().getZ()))
{
return;
}
@@ -132,9 +135,8 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
{
//LOGGER.trace("interact or block place event at blockPos: " + event.getPos());
LevelAccessor level = event.getLevel();
ChunkAccess chunk = level.getChunk(event.getPos());
this.onBlockChangeEvent(level, chunk);
SharedApi.INSTANCE.applyChunkUpdate(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
});
}
}
@@ -144,7 +146,10 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
{
if (MC.clientConnectedToDedicatedServer())
{
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(event.getPos().getX(), event.getPos().getZ()))
LevelAccessor level = event.getLevel();
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(level);
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(wrappedLevel, event.getPos().getX(), event.getPos().getZ()))
{
return;
}
@@ -157,18 +162,12 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
{
//LOGGER.trace("break or block attack at blockPos: " + event.getPos());
LevelAccessor level = event.getLevel();
ChunkAccess chunk = level.getChunk(event.getPos());
this.onBlockChangeEvent(level, chunk);
SharedApi.INSTANCE.applyChunkUpdate(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
});
}
}
}
private void onBlockChangeEvent(LevelAccessor level, ChunkAccess chunk)
{
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(level);
SharedApi.INSTANCE.chunkBlockChangedEvent(new ChunkWrapper(chunk, wrappedLevel), wrappedLevel);
}