PAK File structure
Int32 - Version
Int32 - Table size
Int32 - Files count
Int32 - Chunk size
Int32 - ????
Int32 - ????
Int32 - Zero
Int32 - Table1 size (LZMA related for files bigger than 0x8000 bytes, so they have more than one LZMA chunks)
Int32 - Table2 size (How many chunks held by compressed LZMA chunk for files not bigger than 0x8000 bytes)
Int32 - Name's offset
Int32 - zero
Int32 - ????
Int32 - One
Array of Files count UInt32 - IDs
Array of Files count File record - File Table
--Int32 - offset
--Int32 - ordinal
--Int32 - size
--Int32 - compression - 0x20000000 bit is triggered if compressed. Other bits points to offsfet in table1 or table2.
Table1. Table1 size times of Int16 values. Each value represents offset of block starting with file offset. 0x8000 bit means end of one sequence and start of another. Also bit was triggered not in the end of sequence, but when chunk is not compressed and takes 0x8000 bytes.
Table2. Table2 size bytes. One byte of flags and one byte for number of chunks taken by compressed stream. Flag is mostly 80. But if it is 81 iirc, there will be two bytes next. One means number of blocks actually taken by stream and second number of blocks taken by size in LZMA chunk info.
Aligned by 4 FF FF FF FF 00 80 00 00 FF FF FF FF FF FF FF FF FF FF FF FF
--DATA--
LZMA:
If chunk is compressed, then there goes next structure: Int16 length of LZMA stream, 5 bytes of LZMA parameters and then compressed LZMA stream.
IGZ Format
Int32 - ASCII Signature
Int32 - Version (?)
Int32 - ID (?)
Int32 - six (wtf)
Few times chunk info, until offset is zero:
--Int32 - Usefull magic
--Int32 - MAGIC
--Int32 - offset
--Int32 - size
...
Offset 0x220: some text, maybe memory pools
...
Fields chunk: meta info. Contains records.
[spoiler=record]Int32 - Type
Int32 - Items count
Int32 - size of whole record (data + header size)
Int32 - size of header
Pair string : TDEP - Items count times pair of null terminated strings aligment to 4 (minimum one byte, never zero if already aligned)
String array : TSTR, TMET - Items count times of null terminated strings aligned to 2 aligment to 4 (minimum one byte, never zero if already aligned)
Int32 array : MTSZ, ROOT (?), ONAM (?)
Pair Int32 array : EXID, EXNM
Something horrible: RVTB, RSTT, ROFS, RPID,REXT, RHND, RNEX - Array of byte values
Info chunk - meta data (generated package, info, etc), sounds, etc:
ONAM has length of chunk + 56 bytes iirc.
16 zeros
Int32 count
Int32 count
Int32 length
Int32 MAGIC
Int32 table_offset
Int32 zero
count times Int32 offset and Int32 zero (of 64 bit offset? Nah)
...
Content
...
Int32 count
Int32 count
Int32 length
Int32 MAGIC
Int32 table_offset
Int32 zero
count times Int64 number Int64 number
Content records:
Sometimes:
Int64 = 1
Int64 = 1
Int32Stream length
Int32Flags?
Int64Offset
It can differ if stream length is zero, like in textures of generated packages.
Unexplored yet
Data chunk: data carried by IGZ, models and skeletons, textures.
Generated packages
Special IGZ files in generated/package folder. Has list of files and their categories in TSTR field.
Info chunk contains info in format:
CAT-PATH. Both are Int64 pointers to string.
I've made extension for IGZ Editor that allows you to edit generated package files, but it's still WIP. We need to find dependencies between structure and ONAM, RSTT, RVTB and ROFS fields.
ONAM - size + 56
RSTT - 3C, files_cnt - 1 times 22, 2C 01 aligned by 4 bytes. If no files it's 4E 00 00 00
RVTB -
0x00 - C0 81 02 00
0x01 - C0 C1 02 00
0x02 - C0 81 03 00
0x03 - C0 C1 03 00
0x04 - C0 81 04 00
0x0C - C0 81 18 00
0x22 - C0 81 2B 00
0x39 - C0 C1 48 00
0x58 - C0 81 5E 00
0xAF - C0 C1 B9 01
As you can see, if files_count is even, it's 81, if odd it's C1.
C0 81(even)/С1(odd) XX XX
ROFS - 18 82 A2/E2 ...
Int32 - Version
Int32 - Table size
Int32 - Files count
Int32 - Chunk size
Int32 - ????
Int32 - ????
Int32 - Zero
Int32 - Table1 size (LZMA related for files bigger than 0x8000 bytes, so they have more than one LZMA chunks)
Int32 - Table2 size (How many chunks held by compressed LZMA chunk for files not bigger than 0x8000 bytes)
Int32 - Name's offset
Int32 - zero
Int32 - ????
Int32 - One
Array of Files count UInt32 - IDs
Array of Files count File record - File Table
--Int32 - offset
--Int32 - ordinal
--Int32 - size
--Int32 - compression - 0x20000000 bit is triggered if compressed. Other bits points to offsfet in table1 or table2.
Table1. Table1 size times of Int16 values. Each value represents offset of block starting with file offset. 0x8000 bit means end of one sequence and start of another. Also bit was triggered not in the end of sequence, but when chunk is not compressed and takes 0x8000 bytes.
Table2. Table2 size bytes. One byte of flags and one byte for number of chunks taken by compressed stream. Flag is mostly 80. But if it is 81 iirc, there will be two bytes next. One means number of blocks actually taken by stream and second number of blocks taken by size in LZMA chunk info.
Aligned by 4 FF FF FF FF 00 80 00 00 FF FF FF FF FF FF FF FF FF FF FF FF
--DATA--
LZMA:
If chunk is compressed, then there goes next structure: Int16 length of LZMA stream, 5 bytes of LZMA parameters and then compressed LZMA stream.
IGZ Format
Int32 - ASCII Signature
Int32 - Version (?)
Int32 - ID (?)
Int32 - six (wtf)
Few times chunk info, until offset is zero:
--Int32 - Usefull magic
--Int32 - MAGIC
--Int32 - offset
--Int32 - size
...
Offset 0x220: some text, maybe memory pools
...
Fields chunk: meta info. Contains records.
[spoiler=record]Int32 - Type
Int32 - Items count
Int32 - size of whole record (data + header size)
Int32 - size of header
Pair string : TDEP - Items count times pair of null terminated strings aligment to 4 (minimum one byte, never zero if already aligned)
String array : TSTR, TMET - Items count times of null terminated strings aligned to 2 aligment to 4 (minimum one byte, never zero if already aligned)
Int32 array : MTSZ, ROOT (?), ONAM (?)
Pair Int32 array : EXID, EXNM
Something horrible: RVTB, RSTT, ROFS, RPID,REXT, RHND, RNEX - Array of byte values
Info chunk - meta data (generated package, info, etc), sounds, etc:
ONAM has length of chunk + 56 bytes iirc.
16 zeros
Int32 count
Int32 count
Int32 length
Int32 MAGIC
Int32 table_offset
Int32 zero
count times Int32 offset and Int32 zero (of 64 bit offset? Nah)
...
Content
...
Int32 count
Int32 count
Int32 length
Int32 MAGIC
Int32 table_offset
Int32 zero
count times Int64 number Int64 number
Content records:
Sometimes:
Int64 = 1
Int64 = 1
Int32Stream length
Int32Flags?
Int64Offset
It can differ if stream length is zero, like in textures of generated packages.
Unexplored yet
Data chunk: data carried by IGZ, models and skeletons, textures.
Generated packages
Special IGZ files in generated/package folder. Has list of files and their categories in TSTR field.
Info chunk contains info in format:
CAT-PATH. Both are Int64 pointers to string.
I've made extension for IGZ Editor that allows you to edit generated package files, but it's still WIP. We need to find dependencies between structure and ONAM, RSTT, RVTB and ROFS fields.
ONAM - size + 56
RSTT - 3C, files_cnt - 1 times 22, 2C 01 aligned by 4 bytes. If no files it's 4E 00 00 00
RVTB -
0x00 - C0 81 02 00
0x01 - C0 C1 02 00
0x02 - C0 81 03 00
0x03 - C0 C1 03 00
0x04 - C0 81 04 00
0x0C - C0 81 18 00
0x22 - C0 81 2B 00
0x39 - C0 C1 48 00
0x58 - C0 81 5E 00
0xAF - C0 C1 B9 01
As you can see, if files_count is even, it's 81, if odd it's C1.
C0 81(even)/С1(odd) XX XX
ROFS - 18 82 A2/E2 ...