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.common.wrappers.world.ServerLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.ServerApi; import com.seibel.distanthorizons.core.api.internal.ServerApi;
import com.seibel.distanthorizons.core.api.internal.SharedApi; 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.server.level.ServerLevel;
import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkAccess;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 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) public static void onChunkSave(ServerLevel level, ChunkAccess chunk, CallbackInfoReturnable<Boolean> ci)
{ {
IServerLevelWrapper levelWrapper = ServerLevelWrapper.getWrapper(level);
// is this position already being updated? // 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; return;
} }
@@ -73,8 +76,8 @@ public class MixinChunkMapCommon
// submit the update event // submit the update event
ServerApi.INSTANCE.serverChunkSaveEvent( ServerApi.INSTANCE.serverChunkSaveEvent(
new ChunkWrapper(chunk, ServerLevelWrapper.getWrapper(level)), new ChunkWrapper(chunk, levelWrapper),
ServerLevelWrapper.getWrapper(level) 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.mimicObject.*;
import com.seibel.distanthorizons.common.wrappers.worldGeneration.params.GlobalWorldGenParams; import com.seibel.distanthorizons.common.wrappers.worldGeneration.params.GlobalWorldGenParams;
import com.seibel.distanthorizons.core.api.internal.SharedApi; 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.generation.DhLightingEngine;
import com.seibel.distanthorizons.core.level.IDhServerLevel; import com.seibel.distanthorizons.core.level.IDhServerLevel;
import com.seibel.distanthorizons.core.config.Config; 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, // usually ignoring the chunk's position is unnecessary,
// but this improves performance if a chunk update event does sneak through // 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() this.chunkSaveIgnoreTimer.schedule(new TimerTask()
{ {
@Override @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); }, 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.common.wrappers.worldGeneration.params.GlobalWorldGenParams;
import com.seibel.distanthorizons.core.api.internal.ClientApi; import com.seibel.distanthorizons.core.api.internal.ClientApi;
import com.seibel.distanthorizons.core.api.internal.SharedApi; 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.config.Config;
import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector; import com.seibel.distanthorizons.core.dependencyInjection.ModAccessorInjector;
import com.seibel.distanthorizons.core.enums.MinecraftTextFormat; import com.seibel.distanthorizons.core.enums.MinecraftTextFormat;
import com.seibel.distanthorizons.core.generation.DhLightingEngine; 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.level.IDhServerLevel;
import com.seibel.distanthorizons.core.logging.DhLogger; import com.seibel.distanthorizons.core.logging.DhLogger;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
@@ -190,7 +193,7 @@ public class InternalServerGenerator
while (chunkPosIterator.hasNext()) while (chunkPosIterator.hasNext())
{ {
ChunkPos chunkPos = chunkPosIterator.next(); 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; ServerLevel level = this.params.mcServerLevel;
// ignore chunk update events for this position // 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 #if MC_VER < MC_1_21_5
int chunkLevel = 33; // 33 is equivalent to FULL Chunk 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> * mitigates out of memory issues in the vanilla chunk system. <br>
* See: https://github.com/pop4959/Chunky/pull/383 * 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(() -> level.getChunkSource().chunkMap.mainThreadExecutor.execute(() ->
{ {
@@ -295,7 +302,19 @@ public class InternalServerGenerator
this.chunkSaveIgnoreTimer.schedule(new TimerTask() this.chunkSaveIgnoreTimer.schedule(new TimerTask()
{ {
@Override @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); }, MS_TO_IGNORE_CHUNK_AFTER_COMPLETION);
} }
@@ -132,7 +132,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
executor.execute(() -> executor.execute(() ->
{ {
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper(level); 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 we have access to the server, use the chunk save event instead
if (MC.clientConnectedToDedicatedServer()) 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 // executor to prevent locking up the render/event thread
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor(); AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
@@ -158,8 +160,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
{ {
//LOGGER.trace("attack block at blockPos: " + blockPos); //LOGGER.trace("attack block at blockPos: " + blockPos);
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level); SharedApi.INSTANCE.applyChunkUpdate(
SharedApi.INSTANCE.chunkBlockChangedEvent(
new ChunkWrapper(chunk, wrappedLevel), new ChunkWrapper(chunk, wrappedLevel),
wrappedLevel wrappedLevel
); );
@@ -183,7 +184,9 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
if (hitResult.getType() == HitResult.Type.BLOCK if (hitResult.getType() == HitResult.Type.BLOCK
&& !hitResult.isInside()) && !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 // executor to prevent locking up the render/event thread
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor(); AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
@@ -196,8 +199,7 @@ public class FabricClientProxy implements AbstractModInitializer.IEventProxy
{ {
//LOGGER.trace("use block at blockPos: " + hitResult.getBlockPos()); //LOGGER.trace("use block at blockPos: " + hitResult.getBlockPos());
IClientLevelWrapper wrappedLevel = ClientLevelWrapper.getWrapper((ClientLevel) level); SharedApi.INSTANCE.applyChunkUpdate(
SharedApi.INSTANCE.chunkBlockChangedEvent(
new ChunkWrapper(chunk, wrappedLevel), new ChunkWrapper(chunk, wrappedLevel),
wrappedLevel wrappedLevel
); );
@@ -65,7 +65,7 @@ public class MixinClientPacketListener
executor.execute(() -> executor.execute(() ->
{ {
IClientLevelWrapper clientLevel = ClientLevelWrapper.getWrapper((ClientLevel) this.level); 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 (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 #if MC_VER < MC_1_19_2
LevelAccessor level = event.getWorld(); LevelAccessor level = event.getWorld();
#else #else
LevelAccessor level = event.getLevel(); LevelAccessor level = event.getLevel();
#endif #endif
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(level);
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(wrappedLevel, event.getPos().getX(), event.getPos().getZ()))
{
return;
}
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor(); AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
if (executor != null) if (executor != null)
{ {
executor.execute(() -> executor.execute(() ->
{ {
ChunkAccess chunk = level.getChunk(event.getPos()); 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 (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 #if MC_VER < MC_1_19_2
LevelAccessor level = event.getWorld(); LevelAccessor level = event.getWorld();
#else #else
LevelAccessor level = event.getLevel(); LevelAccessor level = event.getLevel();
#endif #endif
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(level);
if (SharedApi.isChunkAtBlockPosAlreadyUpdating(wrappedLevel, event.getPos().getX(), event.getPos().getZ()))
{
return;
}
AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor(); AbstractExecutorService executor = ThreadPoolUtil.getFileHandlerExecutor();
if (executor != null) if (executor != null)
{ {
executor.execute(() -> executor.execute(() ->
{ {
ChunkAccess chunk = level.getChunk(event.getPos()); 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 @SubscribeEvent
public void clientChunkLoadEvent(ChunkEvent.Load event) public void clientChunkLoadEvent(ChunkEvent.Load event)
@@ -234,8 +227,8 @@ public class ForgeClientProxy implements AbstractModInitializer.IEventProxy
if (MC.clientConnectedToDedicatedServer()) if (MC.clientConnectedToDedicatedServer())
{ {
ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(GetEventLevel(event)); ILevelWrapper wrappedLevel = ProxyUtil.getLevelWrapper(GetEventLevel(event));
IChunkWrapper chunk = new ChunkWrapper(event.getChunk(), wrappedLevel); IChunkWrapper chunkWrapper = new ChunkWrapper(event.getChunk(), wrappedLevel);
SharedApi.INSTANCE.chunkLoadEvent(chunk, wrappedLevel); SharedApi.INSTANCE.applyChunkUpdate(chunkWrapper, wrappedLevel);
} }
} }
@@ -119,7 +119,10 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
{ {
if (MC.clientConnectedToDedicatedServer()) 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; return;
} }
@@ -132,9 +135,8 @@ public class NeoforgeClientProxy implements AbstractModInitializer.IEventProxy
{ {
//LOGGER.trace("interact or block place event at blockPos: " + event.getPos()); //LOGGER.trace("interact or block place event at blockPos: " + event.getPos());
LevelAccessor level = event.getLevel();
ChunkAccess chunk = level.getChunk(event.getPos()); 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 (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; return;
} }
@@ -157,18 +162,12 @@ 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());
LevelAccessor level = event.getLevel();
ChunkAccess chunk = level.getChunk(event.getPos()); 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);
}