update
This commit is contained in:
parent
660cf9e241
commit
46038b77ac
22
extract.py
22
extract.py
@ -48,6 +48,25 @@ def main():
|
|||||||
with fp as bin_file:
|
with fp as bin_file:
|
||||||
byte = bin_file.read(1)
|
byte = bin_file.read(1)
|
||||||
while byte != b"":
|
while byte != b"":
|
||||||
|
angle_y = 0
|
||||||
|
angle_z = 0
|
||||||
|
scale = 1
|
||||||
|
has_extended_angle = False
|
||||||
|
if byte == b'\x46':
|
||||||
|
has_extended_angle = True
|
||||||
|
model = struct.unpack("<L", bin_file.read(4))[0]
|
||||||
|
x = struct.unpack("<f", bin_file.read(4))[0]
|
||||||
|
y = struct.unpack("<f", bin_file.read(4))[0]
|
||||||
|
z = struct.unpack("<f", bin_file.read(4))[0]
|
||||||
|
angle = struct.unpack("<f", bin_file.read(4))[0]
|
||||||
|
if has_extended_angle:
|
||||||
|
angle_y = struct.unpack("<f", bin_file.read(4))[0]
|
||||||
|
angle_z = struct.unpack("<f", bin_file.read(4))[0]
|
||||||
|
unk = struct.unpack("<b", bin_file.read(1))[0]
|
||||||
|
scale = struct.unpack("<f", bin_file.read(4))[0]
|
||||||
|
objects.append(
|
||||||
|
{"model": model, "x": x, "y": y, "z": z, "angle": angle, "angle_y": angle_y, "angle_z": angle_z, "scale": scale})
|
||||||
|
logger.info("Object model=%s x=%s y=%s z=%s angle=%s angley=%s anglez=%s scale=%s", model, x, y, z, angle, angle_y, angle_z, scale)
|
||||||
if byte == b'\x2a': # start object
|
if byte == b'\x2a': # start object
|
||||||
# object is 20 bytes long
|
# object is 20 bytes long
|
||||||
model = struct.unpack("<L", bin_file.read(4))[0]
|
model = struct.unpack("<L", bin_file.read(4))[0]
|
||||||
@ -57,6 +76,9 @@ def main():
|
|||||||
angle = struct.unpack("<f", bin_file.read(4))[0]
|
angle = struct.unpack("<f", bin_file.read(4))[0]
|
||||||
objects.append({"model": model, "x": x, "y": y, "z": z, "angle": angle})
|
objects.append({"model": model, "x": x, "y": y, "z": z, "angle": angle})
|
||||||
logger.info("Object model=%s x=%s y=%s z=%s angle=%s", model, x, y, z, angle)
|
logger.info("Object model=%s x=%s y=%s z=%s angle=%s", model, x, y, z, angle)
|
||||||
|
if byte == b'\x46': # start object too
|
||||||
|
# object is 20 bytes long
|
||||||
|
|
||||||
byte = bin_file.read(1)
|
byte = bin_file.read(1)
|
||||||
if not args.bin:
|
if not args.bin:
|
||||||
zip_file.close()
|
zip_file.close()
|
||||||
|
134
read_gzp.py
Normal file
134
read_gzp.py
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
import logging
|
||||||
|
import argparse
|
||||||
|
import struct
|
||||||
|
import lzss
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
objects = []
|
||||||
|
_ch = logging.StreamHandler()
|
||||||
|
_ch.setLevel("DEBUG")
|
||||||
|
_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||||
|
_ch.setFormatter(_formatter)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
logger.addHandler(_ch)
|
||||||
|
logger.setLevel("DEBUG")
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("gzp_file", help="gzp file to read")
|
||||||
|
args = parser.parse_args()
|
||||||
|
gzp_file = args.gzp_file
|
||||||
|
|
||||||
|
logger.info("Opening "+gzp_file)
|
||||||
|
with open(gzp_file, "rb") as gzp_fp:
|
||||||
|
checksum = read_int(gzp_fp)
|
||||||
|
|
||||||
|
if checksum != 0x6608F101:
|
||||||
|
raise Exception("Invalid GZP checksum")
|
||||||
|
|
||||||
|
logger.info("Checksum OK")
|
||||||
|
|
||||||
|
meta_info_offset = read_int(gzp_fp)
|
||||||
|
|
||||||
|
gzp_fp.seek(meta_info_offset)
|
||||||
|
unk = read_int(gzp_fp)
|
||||||
|
entries_count = read_int(gzp_fp)
|
||||||
|
|
||||||
|
if entries_count == 0:
|
||||||
|
logger.info("No entries found, skipping")
|
||||||
|
return
|
||||||
|
|
||||||
|
logger.info(str(entries_count)+" entries in GZP")
|
||||||
|
|
||||||
|
for index in range(entries_count):
|
||||||
|
logger.info("Reading index "+str(index))
|
||||||
|
compressed_size = read_int(gzp_fp)
|
||||||
|
original_size = read_int(gzp_fp)
|
||||||
|
# original_size = read_int(gzp_fp)
|
||||||
|
file_time = read_int(gzp_fp)
|
||||||
|
content_offset = read_int(gzp_fp) + 16
|
||||||
|
compression = read_byte(gzp_fp) # compression: 1 if compressed else 0
|
||||||
|
name_length = read_byte(gzp_fp)
|
||||||
|
name = read_bytes(gzp_fp, name_length).decode("utf8").strip('\x00')
|
||||||
|
logger.info(name + " compression: "+str(compression) + ", filesize: "+sizeof_fmt(original_size) + ", start: "+str(content_offset))
|
||||||
|
|
||||||
|
curr_pos = gzp_fp.tell()
|
||||||
|
gzp_fp.seek(content_offset)
|
||||||
|
buffer = gzp_fp.read(compressed_size)
|
||||||
|
gzp_fp.seek(curr_pos)
|
||||||
|
|
||||||
|
if compression == 1:
|
||||||
|
logger.info("File is compressed, decompressing it")
|
||||||
|
buffer = decompress(buffer, original_size)
|
||||||
|
|
||||||
|
logger.info("Writing file "+name)
|
||||||
|
with open(name, "wb") as entry_fp:
|
||||||
|
entry_fp.write(buffer)
|
||||||
|
|
||||||
|
# separator = read_byte(gzp_fp)
|
||||||
|
|
||||||
|
|
||||||
|
def sizeof_fmt(num, suffix='B'):
|
||||||
|
for unit in ['','Ki','Mi','Gi','Ti','Pi','Ei','Zi']:
|
||||||
|
if abs(num) < 1024.0:
|
||||||
|
return "%3.1f%s%s" % (num, unit, suffix)
|
||||||
|
num /= 1024.0
|
||||||
|
return "%.1f%s%s" % (num, 'Yi', suffix)
|
||||||
|
|
||||||
|
|
||||||
|
def read_byte(fp):
|
||||||
|
return struct.unpack("<B", fp.read(1))[0]
|
||||||
|
|
||||||
|
|
||||||
|
def read_bytes(fp, num):
|
||||||
|
return bytes(struct.unpack('<'+str(num)+'B', fp.read(num)))
|
||||||
|
|
||||||
|
|
||||||
|
def read_int(fp):
|
||||||
|
return struct.unpack("<L", fp.read(4))[0]
|
||||||
|
|
||||||
|
|
||||||
|
def decompress(buffer, finalsize):
|
||||||
|
i = 0
|
||||||
|
j = 0
|
||||||
|
decByte = 0
|
||||||
|
decBits = 8
|
||||||
|
buffStart = 0xFEE
|
||||||
|
res = bytearray(finalsize)
|
||||||
|
|
||||||
|
if finalsize == 0:
|
||||||
|
return res
|
||||||
|
|
||||||
|
while j < finalsize:
|
||||||
|
if decBits == 8:
|
||||||
|
decByte = buffer[i]
|
||||||
|
i += 1
|
||||||
|
decBits = 0
|
||||||
|
|
||||||
|
if (decByte >> decBits & 1) == 0:
|
||||||
|
decPos = ((buffer[i] + ((buffer[i + 1] & 0xF0) << 4) - buffStart - j) & 0xFFF) - 0x1000 + j
|
||||||
|
decLen = (buffer[i + 1] & 0xF) + 3
|
||||||
|
i += 2
|
||||||
|
|
||||||
|
while decLen > 0:
|
||||||
|
if decPos >= 0:
|
||||||
|
# print("j:" +str(j))
|
||||||
|
# print("decPos: "+str(decPos))
|
||||||
|
res[j] = res[decPos]
|
||||||
|
else:
|
||||||
|
res[j] = 32
|
||||||
|
|
||||||
|
j += 1
|
||||||
|
decPos += 1
|
||||||
|
decLen -= 1
|
||||||
|
else:
|
||||||
|
res[j] = buffer[i]
|
||||||
|
i += 1
|
||||||
|
j += 1
|
||||||
|
|
||||||
|
decBits += 1
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Loading…
Reference in New Issue
Block a user