mivashinko88-netizen/palworld-pal-extractor

GitHub: mivashinko88-netizen/palworld-pal-extractor

一条从 Palworld 的 UE5.1 .pak 文件中逆向提取并关联所有生物数据、输出为结构化 JSON 的完整逆向工程管道。

Stars: 0 | Forks: 0

# Palworld Pal Extractor 一个逆向工程 pipeline,可以从游戏 **Palworld** 中提取所有已编录的生物("Pal"), 并将其编写为结构化的 JSON,每条记录对应一个 Pal。整个过程 从远程原始下载开始,最终生成一个干净、连接完毕的数据集,且无需安装游戏。 输出结果为 `output/pals.json`(包含 213 个 Pal)。仓库中包含了一个 3 条记录的样本文件 [`output/pals.sample.json`](output/pals.sample.json),这样您无需运行任何程序即可查看其 schema。 ## 为什么这不仅仅是解析一个文件 Palworld 像 Unreal Engine 5 游戏那样发布其数据:作为被打包进大型压缩 `.pak` 归档文件中的 DataTables (`UDataTable` 资产)。磁盘上的任何内容都 无法直接读取,而且一个 Pal 的完整档案分散在十几个表中 (属性在一个表中,名称和描述在按语言划分的文本表中, 技能在另外两个表中,掉落物在又一个表中,依此类推)。这项工作分为三个部分: 1. 无需数十 GB 的磁盘空间用于下载和解压 pak,即可从分发包中提取数据。 2. 解析 UE5.1 pak 和已 cooked 的 `.uasset` DataTables。这意味着需要进行 Oodle 解压缩、处理由 `.usmap` 映射文件驱动的无版本属性, 以及处理原生 Python 解析器无法应对的几项 UE5 序列化变更。 3. 通过 Pal id 连接各个表,并将它们重塑为一个干净的 schema。 ## Pipeline ``` remote .7z archive (HTTP range reads) -> httpfile.py (seekable remote file) | | folder 1 = Pal-Windows.pak (~31.6 GB), one solid LZMA2 block v writepak.py (stream-decompress LZMA2 to disk) -> Pal-Windows.pak | v pyUE4Parse + patches.py (UE5.1) + Mappings.usmap + oo2core (Oodle) | explore.py mounts the pak (zero AES key) and loads assets v extract_pals.py loads ~12 DataTables, joins by Pal id, writes output/pals.json ``` Pipeline 所依赖的工程事实: - 源归档是一个 7-Zip 文件,并且主机支持 HTTP range 请求, 因此只需大约 9 次请求即可读取 7z 索引,而无需下载正文 (`httpfile.py` 将多 GB 的远程文件视为可随机读取的)。 - 游戏数据是一个约 31.6 GB 的 `Pal-Windows.pak` 文件,作为单一的实心 LZMA2 流存储(无法随机访问),因此 `writepak.py` 会将其一次性流式传输到磁盘, 并在断开连接时自动恢复。 - 该 pak 没有经过 AES 加密(使用零密钥即可挂载)。 - Pak 文件记录经过 Oodle 压缩,使用开源的 Oodle 构建版本进行处理。 ### patches.py:让 pyUE4Parse 能够读取 UE5.1 已发布的 `pyUE4Parse` 早于 UE5.1,在处理这些包时会失败。 `patches.py` 在运行时对其进行了 patch,无需修改库本身: | 修复 | 原因 | |-----|--------| | `FPackageFileSummary`:接受 `LegacyFileVersion == -8`,读取 `FileVersionUE5`,读取 UE5 `SoftObjectPaths` 列表,跳过 cooked 包中仅供编辑器使用的 `LocalizationId` | UE5.1 摘要布局 | | `FObjectImport`:读取每个 import 的 `bImportOptional` 字段 | UE5 可选资源 | | `FObjectExport`:移除已删除的 `PackageGuid`,读取 `bGeneratePublicHash` | UE5 export-map 变更 | | `EnumProperty`:为 uint16 支持的 enum 传递真实的 `ReadType`,并使用边界安全的 enum 名称查找 | 解析器 bug,且 usmap 版本略低于此构建版本 | | `FVector`, `FVector2D`, `FVector4`, `FRotator` 读取 double,而不是 float | UE5 Large World Coordinates。这是导致行不同步的主要原因。| ## 快速开始 ``` pip install -r requirements.txt # 将 downloader 指向包含 Pal-Windows.pak 的 7z archive。 # (复制 .env.example,或直接 export) export PAL_DRIVE_FILE_ID= python writepak.py # 1. stream-decompress Pal-Windows.pak from the archive (~17 min) python extract_pals.py # 2. parse the DataTables and write output/pals.json python verify.py # 3. validate against the reference Pal + structural audit ``` `Mappings.usmap` 和 `oo2core_9_win64.dll` 必须位于脚本旁边(请参阅 **设置**)。如果您已经安装了 Palworld,则可以跳过使用 远程下载的步骤,直接将 provider 指向您自己的 `Pal-Windows.pak`。 ## 设置 这两个文件**未提交**(由于授权和体积原因)。请获取它们一次, 并将它们放在脚本旁边: - **`Mappings.usmap`** — Palworld 类型映射,例如来自 `TheNaeem/Unreal-Mappings-Archive` (`Palworld//Mappings.usmap`)。必需, 因为 cooked 的 UE5 资产在序列化属性时没有版本标签。 - **`oo2core_9_win64.dll`** — Oodle 解压缩器。使用来自 `WorkingRobot/OodleUE` 的开源构建版本(`clang-cl-x64-release.zip`,然后是 `bin/oodle-data-shared.dll`, 重命名为 `oo2core_9_win64.dll`)。它导出了 pyUE4Parse 调用的 `OodleLZ_Decompress` 符号。 ## 文件 | 文件 | 作用 | |------|------| | `httpfile.py` | 基于对远程 7z 的 HTTP range 请求支持可随机读取的只读文件 | | `writepak.py` | 将 `Pal-Windows.pak` 流式传输并解压到磁盘,支持断线恢复 | | `patches.py` | 针对 pyUE4Parse 的运行时 UE5.1 支持 patch | | `explore.py` | 构建 file provider 并帮助枚举和加载资产 | | `extract_pals.py` | 加载 DataTables,将它们连接起来,并写入 `output/pals.json` | | `verify.py` | 根据参考 Pal 验证输出并审计所有记录 | | `output/pals.sample.json` | 前 3 条记录,用于展示输出 schema | ## 数据源(已连接的 DataTables) | 表 | 提供 | |-------|----------| | `Character/DT_PalMonsterParameter` | 属性、体型、属、属性、稀有度、工作适应性、速度、食物、价格、培育、行为、Pal 图鉴编号 | | `L10N/en/.../DT_PalNameText_Common` | 显示名称 | | `L10N/en/.../DT_PalLongDescriptionText` | Pal 图鉴描述 | | `Waza/DT_WazaMasterLevel` | Pal 学习的主动技能及其等级 | | `Waza/DT_WazaDataTable` | 每个技能的强度、冷却时间、范围、属性、类别 | | `L10N/en/.../DT_SkillNameText_Common`, `DT_SkillDescText_Common` | 技能和搭档技能的名称和描述 | | `L10N/en/.../DT_PalFirstActivatedInfoText` | 搭档技能描述 | | `Character/DT_PalDropItem` | 掉落物品、几率、数量 | | `UI/DT_PaldexDistributionData` | 用于 `spawnLocations` 的原始野生生成点云(白天和黑夜)| | `L10N/en/.../DT_ItemNameText_Common`, `DT_MapObjectNameText_Common` | 解析富文本标签内的物品和建筑名称 | 内联的富文本标签(``、``、 ``)会被解析为可读名称,而游戏中强制的换行符 会被平整化为干净的纯文本。 `spawnLocations` 是基于 `DT_PaldexDistributionData` 构建的,后者按 Pal 存储了原始的 白天和黑夜野生生成点云(对于 Lamball 约有 1370 个点)。 这些点会被划分到 50,000 个单位的 X/Y 网格中。每个单元成为一个 cluster, 包含平均位置和 `density`(点数),按 density 排序。 ## 假设与决策 - 英语语言环境(`L10N/en`)。其他语言也存在,很容易替换。 - 仅限已编录的 Pal:具有 `IsPal`、Pal 图鉴编号(`ZukanIndex >= 1`) 和本地化名称的行。这排除了仅用于战斗的 `BOSS_`、`RAID_`、`PREDATOR_` 和 `GYM_` 重复行,以及未使用的内部占位行。亚种 (例如 `Kitsunebi_Ice`)作为独立的 Pal 保留(它们有自己的 Pal 图鉴 后缀)。 - 稀有度等级标签(`Common`、`Uncommon`、`Rare`、`Legendary`)由整数的稀有度 值进行分桶。 - 属性名称将内部 enum 映射为游戏内的显示名称:`Normal` 映射为 `Neutral`,`Leaf` 映射为 `Grass`,`Electricity` 映射为 `Electric`,`Earth` 映射为 `Ground`。 - 技能和掉落物的连接是大小写不敏感的,因为游戏本身的表 大小写不一致(`GhostAnglerfish` 与 `GhostAnglerFish`,`DrillGame` 与 `Drillgame`)。 ## 已知限制 - `spawnLocations` 仅涵盖野生生成(213 个 Pal 中的 178 个)。没有该数据的 35 个 是传说级和 boss(Frostallion、Jetragon、Anubis、Xeno 外星人、 Bellanoir 等)以及一些亚种变种。它们从固定的 boss 点、 raids 或蛋中生成,而不是通过野生生成热力图,因此它们在 `DT_PaldexDistributionData` 中没有条目。 - 一小部分主动技能实例具有 `null` 的 `name`/`description`,而 所有数值属性均存在。这些要么是比 usmap 更新的技能 (它们的 id 显示为数字 enum 索引),要么是没有文本条目的内部技能。 - `partnerSkill.icon` 为 `null`。该 icon 位于 `DT_partnerSkillIconDataTable` 中, 以搭档技能类型作为键,仅凭 Pal id 无法进行连接。 - 游戏构建版本略新于 usmap,因此一些 enum 标签会回退到 `EnumName::`。这永远不会影响数值或字节对齐, 因为 enum 的宽度仍然是正确的。 ## 验证 `verify.py` 会根据一个已知正确的参考记录 (Lamball)检查 `output/pals.json`:`name`、`paldexNumber`、`rarity`、`elements`、`size`、`genus`、所有 `stats`、`speed`、`work`、`food`、`breeding`、`behavior`、`price`、`icon`、 `isBoss`、`partnerSkill`、完整的 `activeSkills` 列表以及 `drops`。 跨所有 213 条记录的结构审计确认,每条记录都具有完整的键 集,每个 Pal 图鉴编号都是正整数,每个属性都是整数,每个 主动技能都有强度/属性/等级,并且在每个 `spawnLocations` 块中, cluster 密度总和精确等于 `totalSpawns`。 ## 法律 此代码库仅包含原创工具,授权依据为 [MIT License](LICENSE)。它不提供任何游戏文件:pak、映射、Oodle DLL 和 完整的提取数据集都被排除在外。Palworld 及其所有数据均为 Pocketpair, Inc. 的财产。仅在您有权访问且仅限于个人和教育用途的情况下,针对游戏数据运行此程序。
标签:Homebrew安装, Python, Unreal Engine, 云资产清单, 数据提取, 数据解析, 无后门, 游戏工具, 逆向工具, 逆向工程