荒岛余生1 apk修改技术文档
Island Castaway(荒岛余生)存档修改技术文档
======================================================
适用:com.g5e.islandcastawaypg.android(G5E 版《荒岛余生》)
内容:① 修改珍珠/绿宝石 ② 章节跳关 ③ 地图添加可砍伐枯木
前提:root 设备或模拟器,adb 可用,操作前游戏须完全退出。
一、存档结构与隐藏 CRC(改任何东西前必读)
------------------------------------------------------
1. 存档目录
/data/data/com.g5e.islandcastawaypg.android/files/
下并存 5 套镜像目录,内容相同或轮换:
profiles/ 当前生效档
profiles.bak/ 备份
profiles.succ/ 上次成功存档
profiles.succ.bak/ 同上备份
profiles.broken/ 校验失败被引擎隔离的废档
2. 文件
profileN.xml 第 N 号存档本体
profiles.xml 元数据,记录每个存档的 dwTime
3. 隐藏校验
profiles.xml 的 <Profile dwTime="xxxxxxxx"> 不是时间戳,
而是同目录 profileN.xml 的 CRC-32:
mycrc = zlib.crc32(profileN.xml 全部字节) ^ 0xFF00FF00
改完 profileN.xml 必须同步更新同目录 profiles.xml 里对应的 dwTime,
否则引擎加载时判损坏:静默丢档、回退旧档、甚至开新号。
二、修改珍珠与绿宝石
------------------------------------------------------
1. 字段
<iMoney Value="N"/> 珍珠(账面值)
<iPremiumMoney Value="N"/> 绿宝石(直接存值,无账本)
2. 关键:珍珠 HUD 是实时重算的,不是读 iMoney
存档 <Statistics><Trophys> 分两节:
- 成就节:条目为 fProgressValue/fProgressMaximum(成就进度,勿动)
- 统计节:条目为 fValueGain/fValueSpent(账本,HUD = fValueGain + fValueSpent)
账本形如:
<Pearler>
<fValueGain Value="..."/>
<fValueSpent Value="0"/>
</Pearler>
只改 iMoney 会被引擎重算覆盖。正确改法:
- 所有出现位置的 iMoney 全部改成目标值(可能是负数,正则带 -?)
- 统计节 Pearler 账本:fValueGain=目标值,fValueSpent=0
- 账本块整个不存在时,按引擎原生缩进注入(<Pearler> 4 个 tab,字段 5 个 tab)
3. 改完更新 5 个目录的 dwTime(公式见第一节)。
三、章节跳关(选关)
------------------------------------------------------
1. 机制
- 存档的 ScenarioTopic 块 = 章节模板全量 + ScenarioPlayer 运行时状态
- 章节模板在 OBB 的 .bar 文件里(本质是 7z 压缩包,未加密,任意 7z 工具可读):
res/scenario/topic1.xml ~ topic12.xml(共 12 章)
2. 为什么改节点状态无效
直接改 ScenarioPlayer 里节点 eState=2(Completed)不持久:
引擎加载时 FixStateAfterLoadTopic 按真实任务状态重算,伪造值被重置。
3. 正确做法:整块移植
a. 从 .bar 提取目标章 topicN.xml 模板
b. 用模板重建存档的 ScenarioTopic 块(节点按剧情图 iID 生成,
eState=2=Completed 的保留)
c. 同步存档 iTopicNumber 与 profiles.xml 的 iTopic / iMaxTopicNodeY
d. 更新 5 个目录的 dwTime
4. 副作用(必读)
模板整块替换会把统计节的货币账本抹掉 → 珍珠显示 0。
跳关之后必须重跑第二节的货币补丁。
5. 已知限制
章节号可跳;章内完成度无法伪造(被 FixStateAfterLoadTopic 重置)。
四、地图添加可砍伐枯木
------------------------------------------------------
1. 数据位置
地图数据在 OBB 内 map.xml。编辑后删除 map.cache(及同级 *.cache),
引擎才会重新解析 XML 而不是读二进制缓存;
OBB 大小记录在 assets/fsExtra.manifest,需同步更新,最后重签名 APK。
2. 核心坑:静态残骸 ≠ 可交互资源
- DeadTree_Stump 是静态网格树桩,注进去永远只是个树桩
- 可砍伐的是带 AI 组件的实体:Tree_Resource_Lumber_3(及 _2)
对应预制体 res/entities/objects/plants/trees_resources/dead_wood_3.xml,
内含 AILifeTime CAIDeadTree 交互组件,Normal/Stump 双子实体,
fRespawnTime=60 —— 砍倒变树桩,60 秒后重生
3. 做法:在地图里批量注入 Tree_Resource_Lumber_3(注意对准地形高度),
不要注入 DeadTree_Stump。
五、通用纪律(踩过的坑)
------------------------------------------------------
1. 改档前先 force-stop 游戏,否则内存旧值覆盖你的修改
2. 存档一律二进制读写(Python 'rb'/'wb');文本模式会引入 CRLF 损坏文件
3. 字节级验证只用 adb pull,禁用 adb shell cat ——
文本解码会替换非 UTF-8 字节,造成假 CRC mismatch,误导排查
4. 每次只改一处,拉回设备自验证(字段值 + mycrc == dwTime)再继续
5. 动手前完整备份整个 profiles 目录树
六、工具链
------------------------------------------------------
- 反编译:jadx / apktool(Java 层基本看不到经济系统逻辑,都在 native)
- native 分析:objdump / IDA / radare2,关键函数符号:
ActivateProfile、CalcFileCRC(CRC 算法从这里确认)
- .bar 即 7z:任意 7z 工具可直接浏览提取
- 全部改档流程用 Python 标准库即可完成,无额外依赖
浙公网安备 33010602011771号