from __future__ import print_function, unicode_literals
import io, sys, struct, os
def sanitize(name):
	components = []
	while True:
		head, tail = os.path.split(name)
		if tail == '.':
			tail = '_'
		if tail == '..':
			tail = '__'
		components.append(tail)
		if not head or name == head:
			break
	# if name == head is non-empty, it is an absolute path; drop the first component
	return os.path.join(*reversed(components))
with io.open(sys.argv[1], 'rb') as f:
	if f.read(8) != b'MPK\0\0\0\2\0':
		print("Invalid magic")
		sys.exit(1)
	numFiles, = struct.unpack('<I', f.read(4))
	if f.read(0x38) != b'\0' * 0x38:
		print("Expected zeroes in header")
		sys.exit(1)
	files = []
	for _ in range(numFiles):
		id_, offset, size1, size2, name = struct.unpack('<IQQQ228s', f.read(0x100))
		if id_ != _:
			print("Unexpected id_: %d for %d" % (id_, _))
		if size1 != size2:
			print("Size mismatch: %d != %d" % (size1, size2))
		name = name.rstrip(b'\0').decode('ascii')
		#print(name, offset, size1)
		if name != '':
			files.append((sanitize(name), offset, size1))
	for _ in files:
		with io.open(_[0], 'wb') as g:
			f.seek(_[1])
			g.write(f.read(_[2]))
