import logging import argparse import struct 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("> 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()