Last active
September 3, 2019 20:43
-
-
Save NWPlayer123/27199c50ae7ee83cb3e3fd06ea4b3d82 to your computer and use it in GitHub Desktop.
Astral Chain pkz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#"pkzl", 0x10000, full_size, ??? | |
#4 vars in each entry, count, decsize, offset, encsize? | |
#!! pip install zstd !! | |
from struct import unpack | |
from zstd import decompress | |
from os.path import exists, splitext | |
from os import makedirs | |
import sys | |
def read16(f): | |
return unpack("<H", f.read(2))[0] | |
def read32(f): | |
return unpack("<I", f.read(4))[0] | |
def getstr(f): | |
ret = b"";char = f.read(1) | |
while char != b"\x00": | |
ret += char | |
char = f.read(1) | |
if f.tell() % 8: #normally don't align but only strings here are | |
f.seek(8 - (f.tell() % 8), 1) | |
return ret | |
with open(sys.argv[1], "rb") as f: | |
outname = sys.argv[1][:-4] | |
assert f.read(4) == b"pkzl" #magic | |
assert read32(f) == 0x10000 #??? version? | |
f.seek(0, 2) | |
full_size = f.tell() | |
f.seek(8) | |
assert read32(f) == full_size #assert file+8 = filesize | |
header = unpack("<5I", f.read(0x14)) #0x20 header | |
entries = [unpack("<4Q", f.read(32)) for i in range(header[1])] #4 lwords | |
assert f.read(16) == b"ZStandard".ljust(16, b"\x00") #always 0x10 afaict | |
filenames = [getstr(f).decode("UTF-8") for i in range(header[1])] | |
#variable length, aligned to 8-byte boundary, "UTF-8" so py3's happy >.> | |
if not exists(outname): #make output folder if it doesn't exist | |
makedirs(outname) | |
for i in range(header[1]): | |
#print("%016X %016X %016X %016X" % entries[i]) | |
if entries[i][1] != 0: #entry_size can be 0, skip those? null zstd header | |
print(filenames[i]) #pretty print | |
with open(outname + "/" + filenames[i], "wb") as o: | |
f.seek(entries[i][2]) #seek to entry_offset | |
o.write(decompress(f.read(entries[i][3]))) #decompress dec_size |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment