I cannot believe I was unbelievably stupid to not check the archives themselves for the dictionary. After looking more closely at the syntax for the p3a_tool, there is the option "info". So:
Code:
CMD> p3a_tool.exe info scene.p3a
PH3 archive scene.p3a: 916 files, v1200
Extended header available: 16 bytes, 304 bytes per index entry
compression stats: none:0 lz4:0 zStd:0 zStdDict:916
compressed size: 89239105 (15%)
uncompressed size: 578417191
Has dictionary, 112640 bytes
From this info, we learn that the dictionary used in the archive scene.p3a is 112640 bytes in size.
The
ZSTD dictionary compression format tells us that the magic number for a ZSTD dictionary is 0xEC30A437 (little endian).
So, by searching for this magic number in HXD, sure enough we have our dictionary beginning at location 0x44000 for scene.p3a. Next, select a block and set the length to the dictionary length from earlier - 112640 bytes.
Copy the select bytes and dump them to a new file, I called it scene.zdict.
Now, if you unpack scene.p3a with:
Code:
CMD> p3a_tool extract scene.p3a
and then run:
Code:
CMD> p3a_tool archive scene.MSQ scene --comp=zstd --dictionary=scene.zdict --
We yield a CRC identical P3A archive:
Code:
File: scene.MSQ
CRC-32: 04492de2
MD5: b2c8a40571e8673ed3682df82544281d
SHA-1: 95d40b6e693641ef8c7692531370fecd0378290c
BLAKE3: 79c13b93a662d4789949c228e116a52ac10a47d91562bd39023a61cabd09d0ca
File: scene.p3a
CRC-32: 04492de2
MD5: b2c8a40571e8673ed3682df82544281d
SHA-1: 95d40b6e693641ef8c7692531370fecd0378290c
BLAKE3: 79c13b93a662d4789949c228e116a52ac10a47d91562bd39023a61cabd09d0ca
So there you go, that's how to repack this game.