def rtpc_from_binary(f_raw, rtpc: Optional[Rtpc] = None): if rtpc is None: rtpc = Rtpc() f = ArchiveFile(f_raw) rtpc.magic = f.read_strl(4) if rtpc.magic != b'RTPC': raise Exception('Bad MAGIC {}'.format(rtpc.magic)) rtpc.version = f.read_u32() rtpc.root_node = RtpcNode() rtpc_node_from_binary(f, rtpc.root_node) return rtpc
def deserialize(self, fp, map_typedef=None, process_instances=True): if map_typedef is None: map_typedef = {} header = fp.read(0x40) fh = ArchiveFile(io.BytesIO(header)) if len(header) < 0x40: raise EDecaErrorParse('File Too Short') magic = fh.read_strl(4) if magic != b' FDA': raise EDecaErrorParse('Magic does not match') self.version = fh.read_u32() self.instance_count = fh.read_u32() self.instance_offset = fh.read_u32() self.typedef_count = fh.read_u32() self.typedef_offset = fh.read_u32() self.stringhash_count = fh.read_u32() self.stringhash_offset = fh.read_u32() self.nametable_count = fh.read_u32() self.nametable_offset = fh.read_u32() self.total_size = fh.read_u32() self.unknown = fh.read_u32(5) self.comment = fp.read_strz() # name table self.table_name = [[0, b''] for i in range(self.nametable_count)] fp.seek(self.nametable_offset) for i in range(self.nametable_count): self.table_name[i][0] = fp.read_u8() for i in range(self.nametable_count): self.table_name[i][1] = fp.read(self.table_name[i][0] + 1)[0:-1] # string hash self.table_stringhash = [ StringHash() for i in range(self.stringhash_count) ] self.map_stringhash = {} fp.seek(self.stringhash_offset) for i in range(self.stringhash_count): self.table_stringhash[i].deserialize(fp, self.table_name) self.map_stringhash[ self.table_stringhash[i].value_hash] = self.table_stringhash[i] # typedef self.table_typedef = [TypeDef() for i in range(self.typedef_count)] self.extended_map_typedef = {} for k, v in map_typedef.items(): self.extended_map_typedef[k] = v self.map_typedef = {} fp.seek(self.typedef_offset) for i in range(self.typedef_count): self.table_typedef[i].deserialize(fp, self.table_name) self.map_typedef[ self.table_typedef[i].type_hash] = self.table_typedef[i] self.extended_map_typedef[ self.table_typedef[i].type_hash] = self.table_typedef[i] # print(typedef_map) # instance self.table_instance = [ InstanceEntry() for i in range(self.instance_count) ] self.map_instance = {} fp.seek(self.instance_offset) for i in range(self.instance_count): self.table_instance[i].deserialize(fp, self.table_name) self.map_instance[ self.table_instance[i].name_hash] = self.table_instance[i] self.found_strings = set() self.table_instance_values = [None] * len(self.table_instance) self.table_instance_full_values = [None] * len(self.table_instance) if process_instances: for i in range(len(self.table_instance)): ins = self.table_instance[i] fp.seek(ins.offset) buffer = fp.read(ins.size) n_buffer = len(buffer) buffer_pos = 0 v, buffer_pos = read_instance(buffer, n_buffer, buffer_pos, ins.type_hash, self.extended_map_typedef, self.map_stringhash, ins.offset, found_strings=self.found_strings) self.table_instance_full_values[i] = v self.table_instance_values[i] = adf_value_extract(v)