Skip to content

Instantly share code, notes, and snippets.

@executionunit
Last active October 1, 2020 17:01
Show Gist options
  • Save executionunit/b1f0acc10dd60ce364da8fba9b1e6708 to your computer and use it in GitHub Desktop.
Save executionunit/b1f0acc10dd60ce364da8fba9b1e6708 to your computer and use it in GitHub Desktop.
Windows Python 3+ script to dump the contents of an Unreal PAK file to CSV. Uses latest UnrealPak.exe installed or you can pass the path to UnrealPak.exe as a command line options.
#script to parse the output on UnrealPak to create a CSV file so the contents of a pak
#file can be checked.
#
# example: py -3 pak2csv.py -f D:\TheGame\Saved\StagedBuilds\IOS\cookeddata\TheGame\content\paks\pakchunk0-ios.pak
#
from optparse import OptionParser
from pathlib import PurePath
from os.path import exists
import re
import subprocess
UPAKPATH = "Engine/Binaries/Win64/UnrealPak.exe"
UPAKOPTS = "-List"
def dopakfile(filepath, unrealbasepath):
upak = PurePath(unrealbasepath, UPAKPATH)
# print out a header for the CSV
print("Path, Offset, size(B), size(K), size(MB), sha1, compression")
app = subprocess.Popen([upak, filepath, UPAKOPTS], stdout = subprocess.PIPE, universal_newlines = True)
for line in app.stdout:
regex = r"LogPakFile: Display: \"([\w\/\.]*)\"\s*offset:\s*(\d*),\s*size:\s*(\d*)\s*bytes,\ssha1:\s([\dABCDEF]*),\scompression:\s*(.*)"
match = re.match(regex, line, re.MULTILINE)
if match:
bytesize = int(match.groups()[2])
kilobytes = bytesize/1024
megabytes = kilobytes/1024
print("{}, {}, {}, {}, {}, {}, {}".format(match.groups()[0], match.groups()[1], bytesize, kilobytes, megabytes, match.groups()[3], match.groups()[4] ))
def findunreal():
"""iterate through the registry keys looking for the latest version of Unreal Engine that is installed"""
import winreg
#connecting to key in registry
access_registry = winreg.ConnectRegistry(None,winreg.HKEY_LOCAL_MACHINE)
access_key = winreg.OpenKey(access_registry,r"SOFTWARE\EpicGames\Unreal Engine")
lastpath = None
n = 0
while True:
try:
subkeyname = winreg.EnumKey(access_key,n)
subkey = winreg.OpenKey(access_key, subkeyname)
val, valtype = winreg.QueryValueEx(subkey, "InstalledDirectory")
path = PurePath(val, UPAKPATH)
if exists(path):
lastpath = val
n = n + 1
except OSError as e:
break
return lastpath
if __name__ == "__main__":
usage = """%prog <pakfile path> to dump the contents of a pak file to stdout as CSV. If no unreal
path is pecified then the code will search in the registry for the laest Unreal installation.
"""
parser = OptionParser(usage=usage)
parser.add_option("-f", "--file", dest="filename", help="pakfile to interogate")
parser.add_option("-u", "--unreal", dest="unrealpath", help="quoted path to unreal install eg \"C:/Program Files/Epic Games/UE_4.25\"")
(options, args) = parser.parse_args()
unrealpath = options.unrealpath or findunreal()
if unrealpath == None:
print("ERROR: failed to find unreal in the registry")
exit(1)
if options.filename == None:
parser.print_help()
print("\nERROR: -f argument required: it's the path to the pak file to interogate\n")
exit(1)
if not exists(options.filename):
print("\nERROR: input file {} does not exist\n".format(options.filename))
exit(1)
dopakfile(options.filename, unrealpath)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment