使用CheatEngine锁定《侠隐阁》中的游戏时间/游戏回合数

侠隐阁锁回合后,妈妈再也不用担心我泡不全妹纸。


原理分析

从一般角度来说,侠隐阁养成模式下的游戏回合其实不是特别好用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 TypeGrouped。下面是这几个变量的实际含义。

  1. currentYear,当前年数。如第一年则为1。
  2. currentMonth,当前月份,取值范围为1~12。如二月则为2。
  3. currentRoundOfMonth,当前回合为当月的第几旬,取值范围为1~5,分别对应月初上旬中旬下旬月底。如下旬则为4。
  4. currentTime,表示白天还是晚上,取值范围为1~2,1表示白天,2表示晚上。
  5. currentRound,一个总的回合数,计算公式为(currentYear - 1) * 60 + (currentMont - 1) * 5 + currentRoundOfMonth

实践

实际运行时发现,currentYear、currentMonth、currentRoundOfMonth、currentTime这4个变量是连续存储的,然后隔了1个四字节的变量(猜测是目前版本没用到currentWeather,等于常值1),然后是currentRound。这里给出两个方案:

  1. 通过currentYear、currentMonth、currentRoundOfMonth、currentTime四个值的联合搜索一般可以2次筛选定位到一个唯一的内存地址。
  2. 通过currentYear、currentMonth、currentRoundOfMonth、currentTime、currentRound五个值的联合搜索一般可以1次定位到一个唯一的内存地址。

下面来实践一下第2个方案。首先随便载入一个存档。

这里游戏时间为第一年四月上旬的白天,参照前面,容易得到currentYear=1,currentMonth=4,currentRoundOfMonth=2,currentTime=1,currentRound=(currentYear-1)*60 + (currentMont-1)*5 + currentRoundOfMonth=17。然后在CheatEngine中,设置Value Type为Grouped,搜索

4:1 4:4 4:2 4:1 w:4 4:17

前面四个a:b均表示a字节长的变量其值为b,这四个表示对应currentYear、currentMonth、currentRoundOfMonth和currentTime的值;然后紧跟一个w:4,跳过可能表示currentWeather的变量,我们不能保证其值在今后具体是多少;最后是4:17,表示4字节长的变量currentRound的值为17,搜索下来然后一般可以定位到唯一结果

而要锁定回合数,最简单的方法就是固定currentTime为1,也就是时间永远停留在当前回合的白天。双击刚才的联合搜索结果,然后锁定第四个变量为1

然后回到游戏,不论练功还是睡觉,时间都会定格在第一年四月上旬的白天。

称谓(*)
邮箱
留言(*)