elin吧 关注:14,912贴子:108,446
  • 26回复贴,共1

便利性Mod 删档BUG复盘

只看楼主收藏回复

太长不看版:将..Whitelist.Enable..设置为true之后可以自动避免一切新增class生效(这也会拦截你禁用的class以及失效的class(还没测试这个功能,但至少接口是这么设计的),暂时没写已有class的新功能的拦截逻辑)
---
仔细检查了一下,这是一个很低级的错误(本来的写法也是,以为那么写没BUG的写法也是)
最开始,我写的是
.SetAndAdvance(OpCodes.Pop, null)
.InsertAndAdvance(new CodeInstruction(OpCodes.Ldc_I4_0, null))
考虑到游戏在那个位置的写法是
callvirt GameDifficulty Game::get_Difficulty()
ldfld bool GameDifficulty::deleteGameOnDeath <- set and advance
(下一个语句的labei): (下一条语句) <-在此insert and advance
我害怕下一个语句可能出现的label(目前并没有)可能会影响insert and advance被重复执行,于是我交换了set和insert的顺序
.InsertAndAdvance(new CodeInstruction(OpCodes.Ldc_I4_0, null))
.SetAndAdvance(OpCodes.Pop, null)
这样修改之后,我们将得到
(label0:) callvirt GameDifficulty Game::get_Difficulty()
(label1:) <- insert and advance
ldfld bool GameDifficulty::deleteGameOnDeath <-在此insert and advance
(下一个语句的labei): (下一条语句)
这里我并不确定(label1:)跟insert哪个在前,但都无所谓,因为这是ldfld,不会有编译器丧心病狂地把label打到ldfld上,因此游戏理应可以完美地执行我们的目标
这就是BUG的成因。
---
昨天玩的时候我就检测到这个BUG了(因为永恒誓约模式下仍然会被删档)
我很轻松地调整了两个语句的顺序,并计划今天上传
因为这两个语句看上去很具有欺骗性:
OpCodes.Ldc_I4_0, null // 读取false
OpCodes.Pop, null // pop 前面读取的false
这两个指令合起来非常像一个nop,因此我下意识以为这么写没问题
---
仔细观察,我们可以发现,代码其实是
before:
callvirt GameDifficulty Game::get_Difficulty()
ldfld bool GameDifficulty::deleteGameOnDeath <- codematcher指向这里
brfalse Label84
insert and advance:
callvirt GameDifficulty Game::get_Difficulty()
ldc.i4.0
ldfld bool GameDifficulty::deleteGameOnDeath <- codematcher指向这里
brfalse Label84
set and advance:
callvirt GameDifficulty Game::get_Difficulty()
ldc.i4.0
pop <- codematcher指向这里
brfalse Label84
after(等价于)
callvirt GameDifficulty Game::get_Difficulty()
nop
brfalse Label84
于是这个BUG吃掉了一条指令,直接把get_Difficulty()拿来算brfalse了
很不巧get_Difficulty() 的结果会被视为true
这就导致了BUG的发生


IP属地:云南1楼2024-12-08 11:57回复


    IP属地:中国台湾来自Android客户端2楼2024-12-08 12:28
    回复
      所以存档就这么莫名其妙的没了???


      IP属地:黑龙江3楼2024-12-08 12:39
      收起回复
        elin没提供类似spongemixin那样的高级语言修改代码的机制吗,要手撕C#IL是吧


        IP属地:四川来自Android客户端4楼2024-12-08 12:41
        收起回复
          在删档的那一刻,他失去了所有力气与手段,他知道,他败了。


          IP属地:西藏来自Android客户端5楼2024-12-08 13:11
          收起回复
            最恐怖的地方还是暂时没有任何手段恢复,除非自己之前自行备份存档了elin的家园和配方系统决定了重开的代价比elona要大上非常多。。。吃一堑长一智,记得及时备份存档哦


            IP属地:陕西来自Android客户端6楼2024-12-08 13:16
            收起回复
              大佬不如趁此机会直接把便利性mod加上自动备份功能


              IP属地:山西来自Android客户端7楼2024-12-08 13:22
              收起回复
                最有技术力的一集,不过我只看得懂python,膜拜大佬


                IP属地:广东来自Android客户端8楼2024-12-08 13:33
                收起回复
                  还好我在创意工坊看到个二周目的mod止了点损


                  IP属地:江苏来自iPhone客户端9楼2024-12-08 14:25
                  回复
                    没事,大佬的作品为我们带来了无数便利,这也是无心之过,以后我多注意手动备份就是了


                    IP属地:美国10楼2024-12-08 16:06
                    回复
                      还好的,正好重新规划一下


                      IP属地:江苏来自iPhone客户端11楼2024-12-08 21:24
                      回复
                        好家伙,还好我当时开了白名单只弄了钓鱼加速,改了挺多配置的,建议还是默认关闭更多功能,可以提示下,然后有需要再打开


                        IP属地:广东13楼2024-12-11 15:31
                        回复