Just Enough Characters

Just Enough Characters

3M Downloads

[Bug]在整合包SevTech中会导致游戏无法进入世界

Yesterday17 opened this issue · 10 comments

commented

JECh版本: JustEnoughCharacters-1.12.0-2.2.2.jar
SevTech版本: 3.0.6 (Release)

控制台并没有特殊的日志输出,但是会卡在Loading Terrarian那里。
最后一条日志是和JEI有关的,移除JECh后恢复正常。

怀疑是和GameStage的兼容问题。

commented

Emm 这两天我一直在测试这个 可以排除内存原因么
我这炸鸡内存带这几个新包很吃力

commented

@Towdium 应该可以 我给的8G 已提交内存一直没满
从任务管理器来看,卡住之后的GPU占用一直为0%,且保持CPU占用基本不变。
从F3来看,卡住之前的内存占用只有3000MB不到。

下面是节选的日志,我觉得应该就是和GameStage(ItemStage)的冲突问题了。

[20:11:17] [Netty Server IO #1/INFO] [gamestages]: Syncing data for Yesterday17 requested.
[20:11:17] [main/INFO] [journeymap]: Custom modded block handling enabled for bibliocraft
[20:11:17] [main/INFO] [net.minecraft.advancements.AdvancementList]: Loaded 75 advancements
[20:11:17] [main/INFO] [gamestages]: Syncing recived for Yesterday17
[20:11:17] [main/INFO] [Item Stages]: Syncing 16145 items with JEI!.
[20:11:32] [Server thread/INFO] [net.minecraft.network.NetHandlerPlayServer]: Yesterday17 lost connection: 连接超时
[20:11:32] [Server thread/INFO] [net.minecraft.server.MinecraftServer]: Yesterday17退出了游戏
[20:11:32] [Server thread/INFO] [net.minecraft.network.NetHandlerPlayServer]: Stopping singleplayer server as player logged out
commented

大概发现问题了
itemstage有个功能是把禁用的物品从jei物品列表中移除
这个过程会调用到搜索树来寻找对应的物品
jei原来的实现几乎是不需要消耗时间的(是的,jei的实现全部用的缓存,所以不用遍历)
但是jech的实现实际上需要遍历整个物品列表(对于原版大约是2ms完成一次遍历)

像这种巨型整合包遍历一次可能会超过100ms (i5 4200H 实测50ms左右)
然后这两个包大概要移除上千个物品
也就是说在读图的时候会执行上千次搜索
大概就要花几百秒这样子

所以大概率是性能问题 算是以前没有考虑过的情景
我想想怎么修...

临时的方案是在执行特殊搜索的时候使用基于hash的全字匹配(常数级)
在平时用的时候再切换回来
虽然现在搞点小把戏黑过去可能还算可行
根本方法还是优化算法到常数级啊(不可能的)

附一张惨不忍睹的截图
screenshot from 2018-04-30 17-03-42

commented

@Yesterday17 在加载的时候不要动MC窗口 加载过个10分钟会加载完,不被T出游戏
然后在日志中会多一条类似
[10:14:33] [main/INFO]: Receiving (new or changed) Player Data for player aallggg.

[10:14:33] [main/INFO]: Loaded 24 advancements

[10:14:34] [main/INFO]: Syncing recived for aallggg

[10:14:34] [main/INFO]: Syncing 3744 items with JEI!.

[10:14:34] [main/INFO]: Ingredients are being removed at runtime: 3744 net.minecraft.item.ItemStack

[10:21:16] [main/INFO]: Finished JEI Sync, took 402105ms. 3744 hidden, 0 shown.

同步时间爆炸。
我在玩modern skyblock3的时候出现这个问题的

commented

感觉这个是没救了,JEI每删除一个物品遍历一次 大包删除几千个 要重新遍历几千次 这好像无解咯 TAT

commented

@alg1988 方法还是有的,就是要黑的地方多一点...

commented

@Towdium 大佬加油!

commented
commented

@Yesterday17 这个不能从 Game Stage 切入,因为运行时隐藏本身是 JEI 的特性,就算 Game Stage 的调用可以修复,其他 mod 调用的时候还是会有问题。

最终的方法是检测 stacktrace,如果调用的来源是 JEI 的特定方法,就使用 JEI 原来的实现,如果是在进行列表搜索,再使用遍历搜索。

顺便把遍历的性能再次优化了,现在的话就算用遍历搜索我这边也能正常进游戏了,虽然会卡一两分钟。

文件我发到 curse 了,如果还有问题的话贴在这个 issue 后边就好。

commented

稍微更新一下进度,昨天943说有人更新之后依然进不了存档,我当时在自己机器上测试了,发现居然我自己也进不去(皮)。当时我以为是我传错文件了,后来发现事情并没有那么简单。

出现这个问题的是 2.3.0 版本,修复在 2.3.1 版本。前面说到 2.3.0 用了 stacktrace 来检测 jei 调用的来源,实际上是匹配了方法名“findMatchingElements”,但是这是基于 jei-1.12.2:4.9.1.168 的实现做的。后来发现相关代码 jei 刚刚重写过,老版本用的是“removeIngredient”,加上之后对于老版本 jei 的兼容就正常了。目前我还不会建议大家手动升级整合包里的 jei 版本,我之前尝试了一下问题很多。

至于 2.3.0 版本为什么有的人就能正常进游戏了。这是因为这个版本显著优化了搜索性能,所以如果你的配置很好的话,即使用遍历也足够快了。测试显示windows下边可能性能更好,原因可能是多线程管理策略的不同。943那边大概是半分钟左右完成遍历。

这个匹配逻辑之后又改了,之前“findMatchingElements”和“removeIngredient”是用来匹配内部搜索,在内部搜索的时候就使用 jei 原生实现。最新的实现用了“getSearchResults”(新版 jei)和“search”(老版 jei),只在玩家搜索列表的时候调用拼音搜索,这样我估计能再过滤掉一些潜在的兼容性问题。