Skip to content

v1.7.3 - Entity Lookup Remove Guard

Pre-release
Pre-release

Choose a tag to compare

@OLKMO OLKMO released this 19 Jul 11:14

新增修复:entity-lookup-remove-guard

拦截 PersistentEntitySectionManager.stopTracking 中的 EntityLookup.remove 调用,捕获 Int2ObjectLinkedOpenHashMap.fixPointers 抛出的 ArrayIndexOutOfBoundsException,避免单个实体移除失败导致整个服务端 tick 崩溃。

New Fix: entity-lookup-remove-guard

Catches ArrayIndexOutOfBoundsException thrown by Int2ObjectLinkedOpenHashMap.fixPointers inside EntityLookup.remove during PersistentEntitySectionManager.stopTracking, preventing single-entity removal failures from crashing the server tick loop.


修复的崩溃 / Crash being fixed

java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 513
    at it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap.fixPointers(Int2ObjectLinkedOpenHashMap.java:979)
    at it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap.removeEntry(Int2ObjectLinkedOpenHashMap.java:263)
    at it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap.remove(Int2ObjectLinkedOpenHashMap.java:372)
    at net.minecraft.world.level.entity.EntityLookup.remove(EntityLookup.java:52)
    at net.minecraft.world.level.entity.PersistentEntitySectionManager.stopTracking(PersistentEntitySectionManager.java:157)
    ...
    at net.minecraft.server.MinecraftServer.tickServer(MinecraftServer.java:1383)

根因 / Root cause

Sable 的 SubLevel 实体管理(跨维度/多线程)破坏了 EntityLookup 内部 Int2ObjectLinkedOpenHashMap 的链表状态。当某个 entry 的 prev/next 指针被设为 -1(表示"无链接"的哨兵值)却被当作数组下标访问时,fixPointers 抛出 Index -1 out of bounds for length N。异常沿 PersistentEntitySectionManager.stopTrackingupdateChunkStatusChunkMap.onFullChunkStatusChangeChunkHolder.demoteFullChunkMinecraftServer.tickServer 一路传播,导致 tick 循环崩溃。

Sable's SubLevel entity management (cross-dimension / multi-threaded) corrupts the internal linked-map state of EntityLookup's backing Int2ObjectLinkedOpenHashMap. When an entry's prev / next pointer is set to -1 (sentinel meaning "no link") but later accessed as an array index, fixPointers throws Index -1 out of bounds for length N. The exception propagates up through PersistentEntitySectionManager.stopTracking -> updateChunkStatus -> ChunkMap.onFullChunkStatusChange -> ChunkHolder.demoteFullChunk -> MinecraftServer.tickServer, crashing the tick loop.

实现方式 / How

  • PersistentEntitySectionManager.stopTracking 中的 EntityLookup.remove 调用上加 @Redirect

  • 在调用点捕获 ArrayIndexOutOfBoundsException(以及其他 Throwable

  • 每次发生时输出一条 WARN 日志(包含实体引用),便于排查

  • tick 继续正常运行,仅跳过出错实体的移除操作

  • @Redirect on the EntityLookup.remove invocation inside PersistentEntitySectionManager.stopTracking

  • Catches ArrayIndexOutOfBoundsException (and any other Throwable) at the call site

  • Emits a single WARN log per occurrence with the entity reference for diagnosis

  • Tick continues normally; only the offending entity's removal is skipped

注意事项 / Caveats

这是治标修复。它让服务器保持运行但不会修复 Int2ObjectLinkedOpenHashMap 的底层状态——损坏的 entry 仍然存在,可能在后续 remove 调用中再次出现。真正的修复应在 Sable 的实体卸载 / SubLevel 实体追踪代码中(参见 sable.mixins.json:entity.entity_unloading.PersistentEntitySectionManagerMixinsable.mixins.json:entity.server_entities_tick.ChunkMapMixin)。

This is a symptomatic fix. It keeps the server alive but does not repair the underlying Int2ObjectLinkedOpenHashMap state — the corrupted entry remains and may surface again on subsequent remove calls. The true fix belongs in Sable's entity unloading / SubLevel entity tracking code (see sable.mixins.json:entity.entity_unloading.PersistentEntitySectionManagerMixin and sable.mixins.json:entity.server_entities_tick.ChunkMapMixin).

兼容性 / Compatibility

  • Mixin 目标 / Mixin target: net.minecraft.world.level.entity.PersistentEntitySectionManager
  • Redirect 目标 / Redirect target: stopTracking 中的 EntityLookup.remove(Entity) 调用
  • Sable 的 PersistentEntitySectionManagerMixin 使用 @Inject 注入在不同方法(processChunkUnload)上,因此不会发生 handler 冲突 / Sable's PersistentEntitySectionManagerMixin uses @Inject on a different method (processChunkUnload), so there is no handler conflict.

产物 / Artifact

  • FuckSable-Unofficial-1.7.3.jar

环境兼容 / Environment

  • Sable 1.x 与 2.x / Sable 1.x and 2.x
  • NeoForge 1.21.1
  • Mohist/Youer 混合服务端 / Mohist/Youer hybrid servers