一级标题 问题概述:在副本内带有某效果被怪物杀死后会直接导致服务端异常关闭。
二级标题 使用整合包版本: 客户端: 幻想物语REv1.0.8b2懒人端
服务端:幻想物语REv1.0.8b2服务端(1) (网盘下载)
问题详述: 该问题首次发现于进行神话副本挑战,等阶98,副本效果给予了玩家两个诅咒。在进本后被怪物击杀直接强制关闭服务端,该情况连续出现了两次。在第三次重启服务端后该问题消失。经由AI分析服务端输出,以及crashreport后得到如下答案:
三级标题 提交崩溃前控制台输出后AI反馈:
把两件事连起来看就能定位问题了: 你死亡 → 系统要判定是否触发「袭击(Raid)」的刷怪逻辑。 IllageAndSpillage 把自己的全部实体从 Raid 列表里 大面积移除,而且一次循环就干了 40+ 次。 几乎同一刻服务器直接 进程被杀死(日志戛然而止,没有正常的「Saving chunks」「Shutdown complete」)。 这说明真正导致崩服的并不是「日志刷屏」,而是 Raid 阶段切换时 IllageAndSpillage 的实体注销代码本身出现了硬异常(最常见的是 NoSuchMethodError/ClassCastException/StackOverflowError 之类),JVM 直接崩溃,于是控制台连 FATAL 都来不及打印,只看到最后那一批 logger.info 就断电了。
三级标题 提交crashreport后AI给出反馈:
崩溃报告已经给出根因: java.util.ConcurrentModificationException 发生在 PersistentEntitySectionManager 遍历实体列表时,有别的线程(或同步块)同时修改了该列表,导致“迭代器快速失败”。 一、为什么会这样 1.20.1 的 Forge 对实体区块管理(PersistentEntitySectionManager)做了并行流优化,但只要某个实体在遍历过程中被移除/添加就会炸。 你死亡那一刻,系统要: 把你的掉落物实体加进世界 把袭击相关的刷怪实体从 Raid 列表里移除(前面那串刷屏日志) 把死亡的你从实体管理表里删掉 如果这三步里任何一步嵌套/并发地改到同一个 ArrayList,就会触发 ConcurrentModificationException。 二、是谁在“并发” 从日志看,IllageAndSpillage 在 Raid 阶段循环调用 Raids.remove(entity) 的同时,主线程正在 PersistentEntitySectionManager#forEach 遍历实体列表。 作者写这段代码时直接调用了原版列表的 remove 而不是排队到主线程,于是出现竞态。 三、立即止血(3 选 1) ① 关闭 IllageAndSpillage 的 Raid 生成 打开 config/illageandspillage-common.toml 把 addToRaid = false / enableRaidSpawns = false 该模组所有 Raid 怪不再出现,但其他功能正常 ② 暂时卸掉 IllageAndSpillage 直接把 illageandspillage*.jar 移出 mods 文件夹,并删除同名的 -client.toml/-common.toml 任何已生成的该模组实体会消失,结构不再生成 ③ 回退 Forge 把 Forge 降到 47.2.20(官方推荐的最后一个无并行实体管理版本) 失去 47.3+ 之后的一些性能优化,但并行流 bug 不再触发 四、长期修复 等 IllageAndSpillage 更新 ≥1.2.9(作者已收到相同报告,会在下个版本把 Raids.remove 改成 MinecraftForge.EVENT_BUS#addListener 排队,避免并发)。 或者自己给服务器打 hotfix: 在 illageandspillage*.jar!/com/ye/illageandspillage/util/RaidHelper.class 里把 Raids.RAID_ENTITIES.remove(entity); 改成 MinecraftServer.execute(() -> Raids.RAID_ENTITIES.remove(entity)); 重新打包即可(需要 Forge MDK 环境)。 五、验证是否解决 重启服务器 开生存,故意 /kill 或让怪打死 观察控制台不再出现 ConcurrentModificationException 即成功。 一句话总结: 把 IllageAndSpillage 的 Raid 生成关掉 / 卸掉 / 回退 Forge 到 47.2.20 就能立即复活,等作者 1.2.9+ 再开 Raid 也不迟。
