Palworld存档逆向工程:深度解析palworld-save-tools的技术实现
【免费下载链接】palworld-save-toolsTools for converting Palworld .sav files to JSON and back项目地址: https://gitcode.com/gh_mirrors/pa/palworld-save-tools
在《Palworld》这款备受瞩目的生存游戏中,玩家们的游戏进度和珍贵回忆都存储在神秘的.sav文件中。这些文件采用Unreal Engine的序列化格式,对普通玩家和技术爱好者来说如同黑盒。palworld-save-tools项目通过逆向工程破解了这一难题,实现了.sav文件与JSON格式的双向转换,为游戏数据分析、存档编辑和二次开发打开了技术大门。
技术挑战:Unreal Engine存档的复杂结构解析
Palworld的存档文件采用了Unreal Engine特有的序列化机制,这种机制在游戏开发中广泛使用,但对逆向工程提出了严峻挑战。主要的难点包括:
压缩格式的复杂性:Palworld存档采用自定义的压缩算法,包含单层和双层zlib压缩两种模式,需要精确识别和正确处理。
二进制数据结构的深度嵌套:游戏中的实体如玩家角色、帕鲁、建筑、物品容器等都采用复杂的嵌套结构存储,需要精确解析每个字段的含义。
Unreal Engine特有的数据类型:如GUID(全局唯一标识符)、FString(Unreal字符串)、FTransform(变换矩阵)等特殊数据类型需要特殊处理。
版本兼容性问题:不同游戏版本可能修改数据结构,工具需要保持向前和向后兼容。
解决方案:模块化的逆向工程架构
palworld-save-tools采用了分层架构设计,将复杂的解析任务分解为多个独立的模块:
核心解析引擎:FArchiveReader/FArchiveWriter
项目的核心是FArchiveReader和FArchiveWriter类,它们实现了Unreal Engine序列化格式的读写接口。这两个类提供了完整的二进制数据解析能力:
# 示例:向量数据的读取 def vector(self) -> tuple[Optional[_float], Optional[_float], Optional[_float]]: x = self.float() y = self.float() z = self.float() return (x, y, z)数据类型映射系统
项目通过paltypes.py定义了Palworld特有的数据类型映射,这是逆向工程的核心成果:
# 关键数据结构类型定义 PALWORLD_TYPE_HINTS = { ".worldSaveData.GroupSaveDataMap": "MapProperty", ".worldSaveData.CharacterSaveParameterMap": "MapProperty", ".worldSaveData.MapObjectSaveData": "MapProperty", # ... 更多类型定义 }自定义属性解析器
每个游戏实体都有对应的解析器模块,如character.py处理角色数据,item_container.py处理物品容器:
# 角色数据解析示例 def decode_bytes(parent_reader: FArchiveReader, char_bytes: Sequence[int]) -> dict[str, Any]: """解析角色二进制数据为结构化字典""" reader = parent_reader.internal_copy(bytes(char_bytes), parent_reader.debug) return { "type": reader.fstring(), "properties": reader.properties_until_end(), }技术实现细节:从二进制到JSON的完整流程
1. 压缩层处理
sav文件首先需要解压缩,palworld-save-tools通过palsav.py模块处理这一过程:
def decompress_sav_to_gvas(data: bytes) -> tuple[bytes, int]: # 解析文件头,识别压缩类型 magic_bytes = data[8:11] save_type = data[11] # 支持单层和双层zlib压缩 if save_type == 0x31: uncompressed_data = zlib.decompress(data[data_start_offset:]) elif save_type == 0x32: # 双层压缩需要两次解压 uncompressed_data = zlib.decompress(data[data_start_offset:]) uncompressed_data = zlib.decompress(uncompressed_data) return uncompressed_data, save_type2. GVAS格式解析
解压后的数据是Unreal Engine的GVAS(Game Virtual Address Space)格式,gvas.py模块负责解析这种格式:
class GvasFile: def __init__(self, header: GvasHeader, properties: dict[str, Any]): self.header = header self.properties = properties @classmethod def read(cls, data: bytes, type_hints: dict[str, str] = {}, custom_properties: dict[str, tuple[Callable, Callable]] = {}) -> "GvasFile": # 解析GVAS文件头和数据 reader = FArchiveReader(data, type_hints=type_hints, custom_properties=custom_properties) header = GvasHeader.read(reader) properties = reader.properties_until_end() return cls(header, properties)3. 游戏特定数据解析
这是工具最复杂的部分,需要理解Palworld的游戏逻辑:
# 在character.py中,解析角色属性 def decode(reader: FArchiveReader, type_name: str, size: int, path: str) -> dict[str, Any]: """解析角色保存参数""" if type_name == "StructProperty": struct_type = reader.fstring() if struct_type == "PalCharacterParameterSaveData": # 读取角色特有的属性 return { "struct_type": struct_type, "id": reader.guid(), "unknown_bytes": reader.byte_list(1), "type": reader.fstring(), "raw_data": reader.property("ArrayProperty", size - 49, path), } return None4. JSON序列化与反序列化
json_tools.py模块提供了自定义的JSON编码器,处理特殊数据类型:
class CustomEncoder(json.JSONEncoder): """自定义JSON编码器,处理UUID等特殊类型""" def default(self, obj): if isinstance(obj, UUID): return str(obj) # 处理其他特殊类型 return super().default(obj)实际应用场景与技术价值
存档分析与数据挖掘
通过将.sav文件转换为JSON,技术爱好者可以:
- 分析游戏状态:查看玩家等级、资源数量、帕鲁属性等关键数据
- 统计游戏进度:分析游戏时长、完成度、收集进度等
- 识别游戏模式:区分单人游戏、多人合作、专用服务器等不同模式
存档编辑与自定义
工具的双向转换能力支持:
- 角色属性修改:调整玩家等级、技能、属性点
- 物品管理:添加、删除或修改物品库存
- 世界状态调整:修改游戏时间、天气、难度设置
服务器管理与迁移
对于服务器管理员,工具提供了:
- 存档迁移:在不同服务器实例间迁移玩家数据
- 数据备份:创建存档的快照和备份
- 问题诊断:分析损坏的存档文件,尝试修复
技术亮点与设计哲学
无依赖设计
项目坚持"无额外依赖"的设计原则,仅使用Python标准库:
# pyproject.toml中的配置 [project.optional-dependencies] # 这些是仅用于测试的依赖 # 库的默认使用不能依赖任何外部依赖! tests = [ "parameterized==0.9.0", "mypy==1.8.0" ]正确性优先
开发团队强调转换过程的正确性比性能更重要:
"SAV > JSON > SAV应该产生比特级相同的文件(压缩前)"
模块化架构
每个游戏实体都有独立的解析模块,便于维护和扩展:
palworld_save_tools/ ├── rawdata/ │ ├── character.py # 角色数据 │ ├── item_container.py # 物品容器 │ ├── map_object.py # 地图对象 │ ├── group.py # 组织/公会 │ └── ... # 其他实体性能优化策略
虽然正确性是首要目标,但项目仍包含多项性能优化:
- 选择性解析:通过
--custom-properties参数仅解析需要的部分数据 - JSON最小化:使用
--minify-json减少输出文件大小 - 内存优化:流式处理大文件,避免一次性加载全部数据
开源生态与社区贡献
palworld-save-tools已经形成了一个活跃的开源生态:
- 上游项目:作为基础库被多个工具使用
- 下游应用:如PalEdit(GUI编辑工具)、palworld-server-tool(服务器管理工具)
- 社区协作:通过GitHub Issues和Pull Requests持续改进
技术展望与未来方向
随着Palworld游戏的更新,工具也在不断进化:
- 新数据结构的支持:持续逆向工程新的游戏版本
- 性能优化:改进内存使用和解析速度
- API扩展:提供更丰富的编程接口
- 工具链完善:开发更多辅助工具和可视化界面
结语:开源逆向工程的价值
palworld-save-tools不仅是一个技术工具,更是开源社区协作的典范。它展示了如何通过逆向工程理解复杂的游戏数据格式,为游戏数据分析、存档管理和二次开发提供了技术基础。对于技术爱好者而言,这个项目是学习二进制数据解析、游戏逆向工程和开源协作的绝佳案例。
通过深入理解Palworld存档的结构,开发者可以创建更丰富的工具生态,玩家可以获得更个性化的游戏体验,而整个游戏社区则因为这样的开源项目而更加繁荣。这正是开源软件和逆向工程技术为游戏产业带来的独特价值。
【免费下载链接】palworld-save-toolsTools for converting Palworld .sav files to JSON and back项目地址: https://gitcode.com/gh_mirrors/pa/palworld-save-tools
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考