8 个版本
0.3.12 | 2023年10月4日 |
---|---|
0.3.10 | 2022年10月15日 |
0.3.9 | 2021年9月16日 |
0.3.8 | 2020年11月1日 |
0.3.3 | 2019年2月2日 |
#335 in 命令行工具
78KB
2K SLoC
HPK 压缩器,用于 Haemimont Engine 游戏文件
支持的游戏
- Tropico 3-5
- 《第一个圣殿》
- Omerta: City of Gangsters
- Grand Ages: Rome
- Victor Vran
- Surviving Mars
概述
兼容性说明
当 DLC
文件夹中的 hpk 文件包含压缩文件时,Surviving Mars 会停止响应。创建文件时使用 --dont-compress-files
选项。
游戏脚本
Haemimont 使用 Lua 编写他们的游戏脚本。这些脚本只包含编译后的 Lua 字节码,需要使用 unluac 或 luadec 反编译以获取源代码。Victor Vran 从 Lua 5.1
更新到 5.3
,但字节码头缺少两个字节,这使得无法反编译脚本。
Victor Vran 的 Lua 字节码头 | |
---|---|
损坏 | 1B4C7561 5300 19930D0A 1A0A0404 ____ 0878 5600 ... |
有效 | 1B4C7561 5300 19930D0A 1A0A0404 0404 0878 5600 ... |
Surviving Mars 的 Lua 字节码头 | |
---|---|
损坏 | 1B4C7561 5300 19930D0A 1A0A0404 ____ 0878 5600 ... |
有效 | 1B4C7561 5300 19930D0A 1A0A0404 0408 0878 5600 ... |
使用 hpk extract --fix-lua-files ...
在提取时修复脚本。
使用 hpk create --cripple-lua-files ...
在重新打包时更改编译后的 Lua 脚本的字节码头。如果遇到任何问题,游戏也可以加载普通 Lua 文件而不是编译版本。
构建
hpk 用 Rust 编写,因此您需要获取一个 Rust 安装程序 以编译它。构建很简单
$ git clone https://github.com/nickelc/hpk
$ cd hpk
$ cargo build --release
$ ./target/release/hpk --version
hpk 0.3.0
安装
Cargo
$ cargo install hpk
Windows
使用GitHub的版本标签来获取二进制文件。
使用方法
hpk help
$ hpk help
HPK archiver for Haemimont Engine game files (Tropico 3-5, Omerta, Victor Vran, Surviving Mars etc.)
Usage: hpk <COMMAND>
Commands:
create Create a new hpk archive
extract Extract files from a hpk archive
list List the content of a hpk archive
debug-print Print debug information of a hpk archive
help Print this message or the help of the given subcommand(s)
Options:
-h, --help Print help
-V, --version Print version
https://github.com/nickelc/hpk
hpk list
$ hpk list files/omerta/Packs/TextureLists.hpk
entities.lst
fallback.lst
fx.lst
misc.lst
sky.lst
terrains.lst
water.lst
hpk create
$ hpk create -h
Create a new hpk archive
Usage: hpk create [OPTIONS] <dir> <file>
Arguments:
<dir> input directory
<file> hpk output file
Options:
--compress
Compress the whole hpk file
--chunk-size <SIZE>
Default chunk size: 32768
--cripple-lua-files
Cripple bytecode header for Victor Vran or Surviving Mars
--with-filedates
Stores the last modification times in a _filedates file
--filedate-fmt <FORMAT>
Specifies the format of the stored filedates.
default: 'Windows file time' used by Tropico 3 and Grand Ages: Rome
short: 'Windows file time / 2000' used by Tropico 4 and Omerta
--dont-compress-files
No files are compressed. Overrides `--extensions`
--extensions <EXT>...
Specifies the file extensions to be compressed. default: [lst,lua,xml,tga,dds,xtex,bin,csv]
--lz4
Sets LZ4 as encoder
-h, --help
Print help (see more with '--help')
hpk extract
$ hg extract -h
Extract files from a hpk archive
Usage: hpk extract [OPTIONS] <file> <dest> [paths]...
Arguments:
<file> hpk archive
<dest> destination folder
[paths]... An optional list of archive members to be processed, separated by spaces.
Options:
--ignore-filedates Skip processing of a _filedates file and just extract it
--fix-lua-files Fix the bytecode header of Victor Vran's or Surviving Mars' Lua files
--force Force extraction if destination folder is not empty
-v Verbosely list files processed
-h, --help Print help
hpk调试打印
$ hpk debug-print files/omerta/Packs/TextureLists.hpk
reading file: files/omerta/Packs/TextureLists.hpk
header:
data_offset: 0x24
fragments_residual_offset: 0x0
fragments_residual_count: 0
fragments_per_file: 1
fragments_filesystem_offset: 0x1459
fragments_filesystem_length: 64
filesystem entries: 8
filesystem fragments:
0x13D1 len: 136
0x24 len: 3876
0xF48 len: 278
0x105E len: 82
0x10B0 len: 134
0x1136 len: 140
0x11C2 len: 304
0x12F2 len: 223
dir: index=1 depth=0 ""
fragment: 0x13D1 len: 136
file: index=2 depth=1 "entities.lst"
fragment: 0x24 len: 3876
compressed: ZLIB inflated_length=30917 chunk_size=32768 chunks=1
chunks: 0x10 len: 3860
file: index=3 depth=1 "fallback.lst"
fragment: 0xF48 len: 278
compressed: ZLIB inflated_length=2956 chunk_size=32768 chunks=1
chunks: 0x10 len: 262
file: index=4 depth=1 "fx.lst"
fragment: 0x105E len: 82
compressed: ZLIB inflated_length=290 chunk_size=32768 chunks=1
chunks: 0x10 len: 66
file: index=5 depth=1 "misc.lst"
fragment: 0x10B0 len: 134
compressed: ZLIB inflated_length=344 chunk_size=32768 chunks=1
chunks: 0x10 len: 118
file: index=6 depth=1 "sky.lst"
fragment: 0x1136 len: 140
compressed: ZLIB inflated_length=536 chunk_size=32768 chunks=1
chunks: 0x10 len: 124
file: index=7 depth=1 "terrains.lst"
fragment: 0x11C2 len: 304
compressed: ZLIB inflated_length=2268 chunk_size=32768 chunks=1
chunks: 0x10 len: 288
file: index=8 depth=1 "water.lst"
fragment: 0x12F2 len: 223
compressed: ZLIB inflated_length=1978 chunk_size=32768 chunks=1
chunks: 0x10 len: 207
HPK 文件格式
标题
偏移量 | 大小 | 值 |
---|---|---|
0 | 4 | 魔数;0x4C555042 ("BPUL" ) |
4 | 4 | 数据偏移量;0x24 (36 ) |
8 | 4 | 每个文件中的片段数;1 ,8 |
12 | 4 | 未知;0xFFFFFFFF |
16 | 4 | 剩余片段的偏移量(字节) |
20 | 4 | 剩余片段数 |
24 | 4 | 未知;0x1 |
28 | 4 | 文件系统片段的偏移量(字节) |
32 | 4 | 文件系统片段的大小(字节) |
片段(文件系统 & 剩余)
- 片段偏移量相对于文件开始的位置。
- 第一个文件系统片段是根目录。
偏移量 | 大小 | 值 |
---|---|---|
0 | 4 | 片段的偏移量(字节) |
4 | 4 | 片段的大小(字节) |
文件系统条目:目录
偏移量 | 大小 | 值 |
---|---|---|
0 | 4 | 片段索引;索引从1 开始 |
4 | 4 | 条目类型;文件=0x0 目录=0x1 |
8 | 2 | 后续名称的大小(字节) |
10 | ? | 名称数据 |
碎片文件(zlib/lz4/zstd压缩)
压缩块的偏移量相对于片段的开始。
Victor Vran(Steam版本)和Surviving Mars使用LZ4进行压缩。
Surviving Mars的mod编辑器使用ZSTD。
Tropico 5的hpks挑战像碎片文件一样压缩。
偏移量 | 大小 | 值 |
---|---|---|
0 | 4 | 魔数,0x42494C5A ("ZLIB" )0x20345A4C ("LZ4 " )0x4454535A ("ZSTD" ) |
4 | 4 | 膨胀数据的字节大小 |
8 | 4 | 膨胀块大小,0x0800 (32768 ) |
12 | 4 | 块偏移量(字节),一个块为0x10 |
* | 4 | 附加块偏移量(可选) |
_filedates
文件
HPK文件可以包含一个_filedates
文件,其中包含文件和目录的最后修改时间。
每一行由一个路径和一个文件时间组成,用等号分隔。
path/to/file=value
path/to/folder=value
路径是文件的基本路径,但对于Grand Ages: Rome,实际路径前面有
原始HPK文件的基础名(Shaders.hpk "Shaders/Shaders/VertexAnim.fx"
)。
值可以是Windows文件时间("default"
)或Windows文件时间除以2000("short"
)。
格式 | 游戏 |
---|---|
默认 | Grand Ages: Rome, Tropico 3 |
短 | Tropico 4, Omerta |
依赖关系
~7–15MB
~203K SLoC