fix: improve threaded world compatibility and chunk reads in 1.1.15

Add regression tests and per-dimension progress diagnostics. Document the unresolved C2ME random-initialization redirect conflict.
This commit is contained in:
Disy committed 2026-10-03 21:24:31 +08:00
1 parent 74cae0b581
commit 32b11aee87
42 files changed
+1506 -381

No files matched your search

@@ -6,6 +6,8 @@ import dev.modzuozhi.core.dimthread.EntityTickParallel;
import dev.modzuozhi.core.dimthread.ISectionKeyAccessor;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.util.AbortableIterationConsumer;
import net.minecraft.world.level.entity.EntityAccess;
import net.minecraft.world.level.entity.EntitySection;
@@ -75,27 +77,46 @@ public abstract class EntitySectionMixin implements ISectionKeyAccessor {
AABB aabb, AbortableIterationConsumer<EntityAccess> consumer,
Operation<AbortableIterationConsumer.Continuation> original
) {
// 内容遍历/查询:分片读锁(共享,传感器/碰撞查询并发执行)
// Never invoke arbitrary mod callbacks under a read lock: a callback can move/remove
// an entity, attempting to upgrade this lock to a write lock and deadlocking itself.
List<EntityAccess> matches = new ArrayList<>();
AbortableIterationConsumer.Continuation result;
EntityTickParallel.lockSectionRead(this.modzuozhi_sectionKey);
try {
return original.call(aabb, consumer);
result = original.call(aabb, (AbortableIterationConsumer<EntityAccess>) entity -> {
matches.add(entity);
return AbortableIterationConsumer.Continuation.CONTINUE;
});
} finally {
EntityTickParallel.unlockSectionRead(this.modzuozhi_sectionKey);
}
for (EntityAccess entity : matches) {
if (consumer.accept(entity).shouldAbort()) return AbortableIterationConsumer.Continuation.ABORT;
}
return result;
}
@WrapMethod(method = "getEntities(Lnet/minecraft/world/level/entity/EntityTypeTest;Lnet/minecraft/world/phys/AABB;Lnet/minecraft/util/AbortableIterationConsumer;)Lnet/minecraft/util/AbortableIterationConsumer$Continuation;")
private AbortableIterationConsumer.Continuation modzuozhi_lockedGetEntitiesTyped(
EntityTypeTest<EntityAccess, ?> typeTest, AABB aabb,
AbortableIterationConsumer<?> consumer,
private <U extends EntityAccess> AbortableIterationConsumer.Continuation modzuozhi_lockedGetEntitiesTyped(
EntityTypeTest<EntityAccess, U> typeTest, AABB aabb,
AbortableIterationConsumer<U> consumer,
Operation<AbortableIterationConsumer.Continuation> original
) {
List<U> matches = new ArrayList<>();
AbortableIterationConsumer.Continuation result;
EntityTickParallel.lockSectionRead(this.modzuozhi_sectionKey);
try {
return original.call(typeTest, aabb, consumer);
result = original.call(typeTest, aabb, (AbortableIterationConsumer<U>) entity -> {
matches.add(entity);
return AbortableIterationConsumer.Continuation.CONTINUE;
});
} finally {
EntityTickParallel.unlockSectionRead(this.modzuozhi_sectionKey);
}
for (U entity : matches) {
if (consumer.accept(entity).shouldAbort()) return AbortableIterationConsumer.Continuation.ABORT;
}
return result;
}
/**