原理分析
从一般角度来说,侠之道养成模式下的游戏回合其实不是特别好用CheatEngine定位和修改,直到我再一次用ILSpy反编译了源码,找到游戏回合的相关数据结构。
public class RoundManager
{
private const int maxTotalRound = 180;
private const int maxYearRound = 60;
private const int maxMonthRound = 5;
private const int startRound = 1;
private int currentYear;
private int currentMonth;
private int currentRoundOfMonth;
private int currentTime;
private int currentRound;
// ...
}
上面的5个和回合数据密切相关的4字节整数在内存中是紧密分布的,因此可以很方便地使用CheatEngine的联合搜索,即Value Type为Grouped。下面是这几个变量的实际含义。
- currentYear,当前年数。如第一年则为1。
- currentMonth,当前月份,取值范围为1~12。如二月则为2。
- currentRoundOfMonth,当前回合为当月的第几旬,取值范围为1~5,分别对应月初、上旬、中旬、下旬、月底。如下旬则为4。
- currentTime,表示白天还是晚上,取值范围为1~2,1表示白天,2表示晚上。
- currentRound,一个总的回合数,计算公式为(currentYear - 1) * 60 + (currentMonth - 1) * 5 + currentRoundOfMonth。
实践
实际运行时发现,currentYear、currentMonth、currentRoundOfMonth、currentTime这4个变量是连续存储的,然后隔了1个四字节的变量(猜测是目前版本没用到currentWeather,等于常值1),然后是currentRound。
通过currentYear、currentMonth、currentRoundOfMonth、currentTime、currentRound五个值的联合搜索一般可以1次定位到一个唯一的内存地址。
下面来实践一下。首先随便载入一个存档。
这里游戏时间为第一年四月上旬的白天。通过手动计算可以得到
currentYear |
第一年 | 1 |
currentMonth |
四月 | 4 |
currentRoundOfMonth |
上旬 | 2 |
currentTime |
白天 | 1 |
currentRound |
(1 - 1) * 60 + (4 - 1) * 5 + 2 | 17 |
从而可以得到Cheat Engine联合查询的字符串:
4:1 4:4 4:2 4:1 w:4 4:17
或者你也可以通过脚本快速计算字符串:点击这个链接
我们指定Cheat Engine的Value Type为Grouped,搜索上述字符串,一般可以得到一条唯一结果:
而要锁定回合数,最简单的方法就是固定currentTime为1,也就是时间永远停留在当前回合的白天。双击刚才的联合搜索结果,然后锁定第四个变量为1:
然后回到游戏,不论练功还是睡觉,时间都会定格在第一年四月上旬的白天。
有一说一,红儿立绘更新后真好看。