开发教程 拯救你的存档!TR追踪分析成功修复问题存档

哇嘎吖噜哒

Lv2
LV
0
 
IP属地
未知
2019/06/15
16
11
  • · 发布于未知
今年上半年的时候,蒸汽之城服务器的地图存档就曾因为开发人员失误,让mod带bug更新,造成了地图存档崩坏无法读取,然后开发组便尝试采用了追踪调试来修复存档。因为是初次操作,最终耗时两小时才成功删除错误信息,完成了存档修复。但就现在总结经验而言,其实存档修复并没有想象中的那么难,只需要找准问题出错的地方,基本就能解决了。
最近逛贴吧总能看到一部分人在发帖抱怨自己存档加载失败了,下面的回复基本都是说炸档了,没救了,删了吧,基本没见有什么办法挽救存档。鉴于之前自己修复存档的经历,便打算再找一个存档修复一下,然后分享一波,给大家提供一个思路。
然后我就在贴吧随便找了个帖子,修复了一下存档用来做示例:https://tieba.baidu.com/p/6345677550
c5ec6863b91aa12ba4b4f0903a7066d7_b23a791ed21b0ef4e9d71725d2c451da80cb3e82.jpg
 
最后编辑:

哇嘎吖噜哒

Lv2
LV
0
 
IP属地
未知
2019/06/15
16
11
  • · 发布于未知
首先是准备需要用到的东西

1.问题存档:
1NaBpqJMnIrFi6V.png


2.泰拉瑞亚服务器端(一般来讲只要你的泰拉瑞亚是完整安装的都会有这个玩意):
PNBVOAMg3WrfTIL.png

选中的这俩,上面的是原版的,下面的是mod版的,
此次修复的存档是mod版存档所以用的下面这个,各位按需选择就行。
另外不直接追踪游戏客户端主要还是由于游戏客户端代码太多,不方便。

3.dnSpy 32位版本:
神器,直接百度就能下载。一定要是32位或者支持32位调试的。
官方下载地址:https://github.com/0xd4d/dnSpy/releases
 
最后编辑:

哇嘎吖噜哒

Lv2
LV
0
 
IP属地
未知
2019/06/15
16
11
  • · 发布于未知
首先我们直接启动服务器端,加载地图看一眼是哪个地方出问题
7aM5yegqNS1rsZt.png

可以看到存档是被加载完毕了的,但还是失败
说明应该是加载完成地图的后续操作出现问题了
 
最后编辑:

哇嘎吖噜哒

Lv2
LV
0
 
IP属地
未知
2019/06/15
16
11
  • · 发布于未知
大致猜问题是出在加载存档以后,开始追踪吧
让我们请出dnSpy,把服务器端的程序拖到dnSpy左边程序资源管理器,
然后定位到Terraria.Main.DedServ()
这个方法(函数)的作用就是启动服务,里面涉及到了刚才提到的加载存档
iUpPLCNhHmfKJzX.png

找到这个WorldGen.serverLoadWorld();打上断点,然后开始追踪!
 
最后编辑:

哇嘎吖噜哒

Lv2
LV
0
 
IP属地
未知
2019/06/15
16
11
  • · 发布于未知
点击启动或按F5开始调试,启动服务器端,选择存档后等待断点触发
nIiBHFku52Zgwvf.png

此时断点已经被触发,服务器端没有报错,说明问题还在后面,
那么我们就分析一下这个serverLoadWorld()函数有什么操作
右键点击这个函数并在新标签页中打开,dnSpy就开始反编译WorldGen这个类,
而我们分析只需要找函数即可,所以我们取消掉反编译并在左边程序集资源管理器找到这个serverLoadWorld()函数
4NyMLAQ2Vtmw5IE.png

可以看出这个函数是新建了一个线程,真正涉及到存档操作的应该是这个WorldGen.serverLoadWorldCallBack函数。
 
最后编辑:

哇嘎吖噜哒

Lv2
LV
0
 
IP属地
未知
2019/06/15
16
11
  • · 发布于未知
在左边程序集资源管理器找到这个serverLoadWorldCallBack()函数(其实就在serverLoadWorld()下面)并查看代码
URpY3vsoEKWrxjP.png

这里给第一行代码加上断点,然后点击继续等待断点触发
 
最后编辑:

哇嘎吖噜哒

Lv2
LV
0
 
IP属地
未知
2019/06/15
16
11
  • · 发布于未知
断点触发以后,我们便需要开始真正进行追踪了
使用这个逐过程(或者F10)追踪程序,直到程序出错(即跳转到catch)
基本上每点一次就会跳出一次反编译,还是要取消并返回
直到跳转到catch,说明程序捕捉了异常,那么跳转到catch之前执行的语句就是有问题的语句
rd6M5AcEvXhKm29.png
 
最后编辑:

哇嘎吖噜哒

Lv2
LV
0
 
IP属地
未知
2019/06/15
16
11
  • · 发布于未知
我们点一下重新开始(或者按下Ctrl+Shift+F5),还是选择地图启动服务器,让断点触发
然后找到之前跳转到catch的语句,进行分析
对于我找的示例,是在执行这一句时出错跳转到了catch(黄色箭头这句)
35kpBJOqxVZCm6Q.png

那么我们右键这行代码的方法loadWorld,在新标签页中打开,依然在首行加上断点,然后继续逐过程
9DI3psCVTG5EqxO.png
 
最后编辑:

哇嘎吖噜哒

Lv2
LV
0
 
IP属地
未知
2019/06/15
16
11
  • · 发布于未知
直到我们执行到这行代码时,程序又跳转到了catch
Yp4Xb6fvhLqwimQ.png

说明要找的问题还得继续深入追踪
 
最后编辑:

哇嘎吖噜哒

Lv2
LV
0
 
IP属地
未知
2019/06/15
16
11
  • · 发布于未知
还是一样的右键这个Load,在新标签页中打开,然后首行加断点,逐过程
lqma5XRG4FKEWS2.png

这一次是在执行这句LoadContainers时跳转到了catch
Ie5PnxB9yzrLN2w.png

依然是右键这个LoadContainers,在新标签页中打开,首行打断点,然后逐过程
Lf36QPlkoJOZcWw.png

不过可以看出现在的代码已经很少了,所以要开始留意进行分析了
分析的方法就是观察dnSpy下面局部变量的变化
当我们运行完下面的ItemIO.Load的时候,报错出现了
GCmMxAkpEOaYcdw.png

可以看到错误类型是NullReferenceException,也就说明这个ItemIO.Load的参数里面有null的值,注意到局部变量中的teitemFrame字段也确实是null,那么问题就找到了
 
最后编辑:

哇嘎吖噜哒

Lv2
LV
0
 
IP属地
未知
2019/06/15
16
11
  • · 发布于未知
那么到底是什么导致的这个问题呢,老实说我也不清楚
这个teitemFrame是来自于tag的,而这个tag似乎也并没有什么问题,至于为什么报错就得问问tmodloader的开发者了
fuIh8wr2pLMP4Js.png
 
最后编辑:

哇嘎吖噜哒

Lv2
LV
0
 
IP属地
未知
2019/06/15
16
11
  • · 发布于未知
接下来就是进行修复,最简单有效的办法就是忽略掉错误
i_f25.png

先停止调试,然后右键这个LoadContainers,编辑方法(C#)
既然是因为teitemFrame为null导致的错误,那我们加上一个判断就万事大吉了
4rtzT6BEsPNqIVD.png

编译,然后在dnSpy左上角菜单栏点文件->保存模块,这里建议给文件重新命名一下,我就加了个DEBUG
AMPbwnfSk23WcRx.png
 
最后编辑:

哇嘎吖噜哒

Lv2
LV
0
 
IP属地
未知
2019/06/15
16
11
  • · 发布于未知
接下来就是见证的时刻了,让我们启动这个tModLoaderServer_DEBUG.exe,然后加载存档
c2K9wFqgz35oJEr.png

服务器成功启动!那说明存档读取的问题被成功忽略了,那么这个存档就大概率修复了
执行一遍save保存存档,再退出服务器端
然后启动游戏客户端,让我们看看存档咋样了
SXFpcrK1JbTaREg.png

Perfect!
 
最后编辑:

哇嘎吖噜哒

Lv2
LV
0
 
IP属地
未知
2019/06/15
16
11
  • · 发布于未知
这个帖子只是给追踪修复存档问题提供了一个思路,实际上很多有关泰拉瑞亚的问题都能通过追踪来解决(比如游戏打不开)
因为懒得码字所以一些涉及编程语言的术语我没有给出解释,中间也省略了一些不必要的操作说明,
实在有疑问的可以私下跟我交流
i_f25.png
留一个Q群120565010
 

TheLastPrism

Lv6
管理成员
版主
创意家
LV
0
 
IP属地
湖北省
2019/10/25
1,027
341
勋章
5
  • · 发布于未知
图片炸了
1574083101955.png
 

小太

Lv6
管理成员
管理员
LV
0
 
IP属地
湖北省
2015/08/26
254
160
勋章
9
  • · 发布于未知
一气呵成 :evil:
 

dcfhft

Lv4
管理成员
版主
LV
0
 
IP属地
未知
2018/08/28
142
38
勋章
4
  • · 发布于未知
给力,支持!
 

实弑RK

Lv3
LV
0
 
IP属地
未知
2019/08/27
35
14
勋章
3
  • · 发布于未知
厉害了,支持一下
 

* 这是一则由 Google AdSense 自动推荐的广告,与本站无关,不对其真实性与可靠性负责

顶部