爱相随 iM/iR/iN 追加服装解锁

追加服装

爱相随 iM/iR/iN 的 1.7.5 版本更新了外出模式(おでかけモード),在新模式中和女友一起出行,在抵达设定的目标点后,会结算出行的里程并获得外出点数(おでかけポイント)。3000 外出点数可以兑换一套服装,可供解锁的追加服装共有 15 套。在打开应用服装(コスチュームの適用)开关之后,就会在满足条件时随机更换已解锁的服装。

由于外出模式中的地图数据无法加载,即便用虚拟定位抵达了目标点,外出模式也不会进入结算,因此已经无法获得外出点数,也就无法解锁服装。

参考资料

解决方法

这里以爱相随 iR 为例,使用数据线把 iPhone 连接到 PC,使用爱思助手进行文件编辑操作。

如果 iPhone 上安装有 Filza 或类似的文件管理器的话,也可以直接在手机上进行文件编辑操作。

首次运行应用程序并设置生日后,会在应用程序目录的 /Library/Preferences/ 里生成 jp.konami.loveplus.ar.rinko.plist 文件。

在爱思助手中直接打开该文件,它的内容如下。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>setting_vol_sound_effect</key>
    <integer>64</integer>
    <key>birthsetting_day</key>
    <integer>28</integer>
    <key>birthsetting_year</key>
    <integer>2004</integer>
    <key>birthsetting_month</key>
    <integer>5</integer>
    <key>setting_from_ver01</key>
    <true/>
</dict>
</plist>

可以发现里面只保存了生日和一些设置信息。如果我们调整了应用程序设置里的选项,这里也会保存更多设置信息。

然后添加以下的内容进去。

<key>setting_rdp</key>
<integer>99999999</integer>

这样会把外出点数修改为 99999999,当然也可以换成其他任意数字,购买全部 15 套服装只需要 15 × 3000 = 45000 外出点数就足够了。

如果不想手动购买服装,也可以添加以下的内容进去。

<key>setting_costume</key>
<array>
    <integer>32767</integer>
</array>

这样会直接解锁全部 15 套服装。

为什么是 32767?

这个值是位掩码(BitMask),为了让 15 套服装全部解锁,需要让 15 位 Bit 的值全部为 1(111111111111111),然后再把二进制值转换为十进制值,也就是 2^15 - 1 = 32767。同理,如果希望只解锁前 8 套服装(11111111),需要把值改为 2^8 - 1 = 255

完成修改后,不要忘记点击保存

过程记录

虽然推断出外出点数数量和服装解锁信息应该和其他设置信息一样,都会被存在 plist 里,但在外出点数为 0 和没有解锁任何服装的情况下,应用程序不会往 plist 里写相关的信息,不知道键的名字和数据类型,还是没法修改。

在 PC 上用 SSH 连接安装了 OpenSSH 的 iPhone,使用终端操作 Cycript,附加到爱相随 iR 的应用程序进程上进行调试。

首先使用 strings 提取应用程序的可执行文件中的所有字符串,从中查找包含 Costume 的字段。

+[SettingsCtrl LoadCostumeFlag]
+[SettingsCtrl SaveCostumeFlag:]

找到了这样看起来像是对象和函数的组合,负责加载和保存服装 Flag,字面意思就是解锁标志。

操作应用程序进入服装购买界面,用 Cycript 调用 LoadCostumeFlag,返回了一个空的数组,毕竟我们一套衣服都没有。

cy# [SettingsCtrl LoadCostumeFlag]
@[]

创建一个只有一个 1 的数组,调用 SaveCostumeFlag 把它存进去。

cy# var flag = [@[] mutableCopy]

cy# [flag addObject:@1]

cy# [SettingsCtrl SaveCostumeFlag:flag]

这时候 plist 文件里就出现了服装解锁的信息,第一件服装也被解锁了。

<key>setting_costume</key>
<array>
    <real>1</real>
</array>

只解锁了第 1 套服装,下面做一些修改实验。

<key>setting_costume</key>
<array>
    <real>1</real>
    <real>1</real>
    ...
    <real>1</real>
    <real>1</real>
</array>

还是只解锁了第 1 套服装。

<key>setting_costume</key>
<array>
    <real>1</real>
    <real>2</real>
</array>

还是只解锁了第 1 套服装。

<key>setting_costume</key>
<array>
    <real>2</real>
    <real>1</real>
</array>

只解锁了第 2 套服装。

通过以上的解锁情况,已经可以推断出来,应用程序只读数组的第一个值,而且这个值应该是个位掩码,用二进制值来控制每套服装的解锁情况。

<key>setting_costume</key>
<array>
    <real>255</real>
</array>

解锁了前 8 套服装,思路正确了。

最后还是把 Real 换成 Integer 了,虽然用起来没差别,但是原本 plist 里都是 Integer,统一一下~

<key>setting_costume</key>
<array>
    <integer>32767</integer>
</array>

再次翻了翻保存所有字符串的文档,发现外出模式相关的函数都叫 RealDate,于是从中查找包含 RealDate 的字段。

+[SettingsCtrl SaveRealDatePoint:]
+[SettingsCtrl LoadRealDatePoint]

这应该就是服装购买界面里负责加载和保存外出点数的函数了。

操作应用程序进入服装购买界面,在 Cycript 里调用 SaveRealDatePoint,直接存个 999999,然后再调用 LoadRealDatePoint 检查一下结果。

果不其然,猜对了。

这时候 plist 里也终于出现负责存储外出点数的键,以后就可以直接改 plist 来修改了。

<key>setting_rdp</key>
<integer>999999</integer>

完成 🎉