Fixed native POI ownership

- Native structure POI changes persist dirty chunk sections before deferred updates
- Chunk load reconciles final POI states on the owning thread
- Matching POI records retain claimed tickets
- Native flag detection keeps unsupported server behavior intact
- Regression tests cover persistence and failed repair retries
This commit is contained in:
Brian Neumann-Fopiano committed 2026-09-06 13:34:30 -04:00
1 parent f3b6a0ec1b
commit a28614c04e
7 files changed
+474 -3

No files matched your search

@@ -245,6 +245,9 @@ public interface INMSBinding {
default void flushChunkIO(World world) {
}
default void reconcileNativeStructurePois(Chunk chunk) {
}
void injectBiomesFromMantle(Chunk e, Mantle<Matter> mantle);
ItemStack applyCustomNbt(ItemStack itemStack, KMap<String, Object> customNbt) throws IllegalArgumentException;
@@ -20,6 +20,7 @@ package art.arcane.iris.engine;
import art.arcane.iris.platform.bukkit.BukkitWorldBinding;
import art.arcane.iris.core.IrisSettings;
import art.arcane.iris.core.nms.INMS;
import art.arcane.iris.engine.data.cache.Cache;
import art.arcane.iris.engine.framework.Engine;
import art.arcane.iris.engine.framework.EngineAssignedWorldManager;
@@ -212,6 +213,8 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
return;
}
INMS.get().reconcileNativeStructurePois(e);
if (cleanupServiceStopped || cleanupService == null || cleanupService.isShutdown()) {
return;
}
@@ -0,0 +1,52 @@
package art.arcane.iris.engine;
import art.arcane.iris.core.nms.INMS;
import art.arcane.iris.core.nms.INMSBinding;
import art.arcane.iris.engine.framework.Engine;
import org.bukkit.Chunk;
import org.junit.Test;
import org.mockito.MockedStatic;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.CALLS_REAL_METHODS;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class IrisWorldManagerNativePoiTest {
@Test
public void chunkLoadReconcilesPoisWithoutAnOptionalCleanupExecutor() {
IrisWorldManager manager = mock(IrisWorldManager.class, CALLS_REAL_METHODS);
Engine engine = mock(Engine.class);
Chunk chunk = mock(Chunk.class);
INMSBinding binding = mock(INMSBinding.class);
when(manager.getEngine()).thenReturn(engine);
try (MockedStatic<INMS> nms = mockStatic(INMS.class)) {
nms.when(INMS::get).thenReturn(binding);
manager.onChunkLoad(chunk, false);
}
verify(binding).reconcileNativeStructurePois(chunk);
}
@Test
public void chunkLoadPropagatesPoiFailuresToTheRuntimeEventReporter() {
IrisWorldManager manager = mock(IrisWorldManager.class, CALLS_REAL_METHODS);
Engine engine = mock(Engine.class);
Chunk chunk = mock(Chunk.class);
INMSBinding binding = mock(INMSBinding.class);
IllegalStateException failure = new IllegalStateException("Native POI storage failure");
when(manager.getEngine()).thenReturn(engine);
doThrow(failure).when(binding).reconcileNativeStructurePois(chunk);
try (MockedStatic<INMS> nms = mockStatic(INMS.class)) {
nms.when(INMS::get).thenReturn(binding);
assertSame(failure, assertThrows(IllegalStateException.class,
() -> manager.onChunkLoad(chunk, true)));
}
}
}