Skip to content

Instantly share code, notes, and snippets.

@WitherOrNot
Created January 20, 2022 23:31
Show Gist options
  • Save WitherOrNot/4ff6fdb488ecfb5da192c72133c53bbb to your computer and use it in GitHub Desktop.
Save WitherOrNot/4ff6fdb488ecfb5da192c72133c53bbb to your computer and use it in GitHub Desktop.
nice boat
from struct import unpack, calcsize
from zlib import decompress
from io import BytesIO
from os import makedirs, scandir
from os.path import dirname, join
PACKS_PATH = r"u either know it or u dont"
def readint(f, type="I"):
return unpack(f"<{type}", f.read(calcsize(type)))[0]
def readstc(f, s):
s = "<" + s
sz = calcsize(s)
return unpack(s, f.read(sz))
def decode(s):
CIPHERCODE = [0x82, 0xEE, 0x1D, 0xB3, 0x57, 0xE9, 0x2C, 0xC2, 0x2F, 0x54, 0x7B, 0x10, 0x4C, 0x9A, 0x75, 0x49]
d = []
for i, b in enumerate(s):
d.append(b ^ CIPHERCODE[i % 16])
return bytes(d)
def extract_entry(f, entry, root="./nice_boat"):
f.seek(entry[4])
buf = entry[9] + f.read(entry[5])
if entry[6] == b"DFLT":
buf = decompress(buf)
fpath = join(root, entry[0])
fdir = dirname(fpath)
makedirs(fdir, exist_ok=True)
with open(fpath, "wb") as of:
of.write(buf)
def extract_gpk(gpk_file):
f = open(gpk_file, "rb")
size = f.seek(0, 2)
f.seek(-32, 2)
sig = readstc(f, "12sI16s")
if sig[0] != b"STKFile0PIDX" or sig[2] != b"STKFile0PACKFILE":
raise Exception("Invalid signature")
pidx_size = sig[1]
f.seek(size - 32 - pidx_size)
enc_pidx = f.read(pidx_size)
pidx = decode(enc_pidx)
uc_len = unpack("<I", pidx[:4])[0]
uc = BytesIO(decompress(pidx[4:]))
entries = []
while True:
fn_len = readint(uc, "H")
if fn_len == 0:
break
entry = list(readstc(uc, f"{fn_len*2}sHHHII4sIb"))
entry[0] = entry[0].decode("utf-16")
entry.append(uc.read(entry[8]))
entry = tuple(entry)
entries.append(entry)
print(f"Extracting {entry[0]}...")
extract_entry(f, entry)
if __name__ == "__main__":
for pack in scandir(PACKS_PATH):
extract_gpk(pack.path)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment