def read_field(self, reader: ByteIO): count = self.count if count == 0: count = 1 exit_point = 0 if self.indirection_bytes: if self.indirection_level > 1: raise NotImplementedError( 'More than one indirection, not yet handled') if self.count > 0: raise NotImplementedError( 'Indirection.Count > 0 && field.Count > 0') indir = self.indirection_bytes[0] entry = reader.tell() offset = reader.read_uint32() if indir == 0x03: pass if not offset: return None exit_point = reader.tell() # with reader.save_current_pos(): # reader.seek(entry+offset) # return self.read_field_data(reader) elif indir == 0x04: # data = [] count = reader.read_uint32() exit_point = reader.tell() # if count>0: # with reader.save_current_pos(): # reader.seek(entry + offset) # for _ in range(count): # data.append(self.read_field(reader)) # return data else: raise NotImplementedError("Unknown indirection. ({0})".format( hex(indir))) if self.count > 0 and self.indirection_level > 0: array = [] with reader.save_current_pos(): reader.seek(entry + offset) for _ in range(count): data = self.read_field_data(reader) array.append(data) if exit_point: reader.seek(exit_point) return array else: array = [] with reader.save_current_pos(): reader.seek(entry + offset) for _ in range(count): data = self.read_field_data(reader) array.append(data) if exit_point: reader.seek(exit_point) return array else: if exit_point: reader.seek(exit_point) return self.read_field_data(reader)
def read(self, reader: ByteIO): entry = reader.tell() self.vertex_count = reader.read_uint32() self.vertex_offset = reader.read_uint32() self.index_count = reader.read_uint32() self.index_offset = reader.read_uint32() self.strip_count = reader.read_uint32() self.strip_offset = reader.read_uint32() self.flags = StripGroupFlags(reader.read_uint8()) global extra_8 if extra_8: self.topology_indices_count = reader.read_uint32() self.topology_offset = reader.read_uint32() with reader.save_current_pos(): reader.seek(entry + self.index_offset) for _ in range(self.index_count): self.vtx_indexes.append(reader.read_uint16()) reader.seek(entry + self.vertex_offset) for _ in range(self.vertex_count): SourceVtxVertex().read(reader, self) reader.seek(entry + self.strip_offset) for _ in range(self.strip_count): SourceVtxStrip().read(reader, self) if extra_8: reader.seek(entry + self.topology_offset) # for _ in range(self.topology_indices_count): self.topology = (reader.read_bytes(self.topology_indices_count * 2)) return self
def read(self, reader: ByteIO): entry = reader.tell() self.lodCount, self.lodOffset = reader.read_fmt('ii') with reader.save_current_pos(): if self.lodCount > 0 and self.lodOffset != 0: reader.seek(entry + self.lodOffset) for _ in range(self.lodCount): self.vtx_model_lods.append(SourceVtxModelLod().read(reader, self)) return self
def read(self, reader: ByteIO): entry = reader.tell() self.model_count, self.model_offset = reader.read_fmt('II') with reader.save_current_pos(): reader.seek(entry + self.model_offset) for _ in range(self.model_count): self.vtx_models.append(SourceVtxModel().read(reader)) return self
def read(self, reader: ByteIO): entry = reader.tell() self.scale = [reader.read_uint32() for _ in range(6)] self.offset = [reader.read_uint32() for _ in range(6)] for offset in self.offset: with reader.save_current_pos(): reader.seek(entry + offset) self.theAnimValues.append(SourceMdlAnimationValue(reader.read_uint16())) return self
def read(self, reader: ByteIO): entry = reader.tell() self.replacements_count = reader.read_int32() self.replacement_offset = reader.read_int32() with reader.save_current_pos(): reader.seek(entry + self.replacement_offset) for _ in range(self.replacements_count): mat = MaterialReplacement() mat.read(reader) self.replacements.append(mat) return self
def read(self, reader: ByteIO, block_info: InfoBlock = None): self.info_block = block_info with reader.save_current_pos(): fourcc = reader.read_bytes(4) if tuple(fourcc) == (0x56, 0x4B, 0x56, 0x03): kv = BinaryKeyValue(self.info_block) kv.read(reader) self.data = kv.kv else: for struct in self.valve_file.nrto.structs[:1]: self.data[struct.name] = struct.read_struct(reader)
def read(self, reader: ByteIO, block_info: InfoBlock = None): self.info_block = block_info entry = reader.tell() self.vertex_offset = reader.read_uint32() self.vertex_count = reader.read_uint32() with reader.save_current_pos(): reader.seek(entry + self.vertex_offset) for _ in range(self.vertex_count): v_buffer = VertexBuffer() v_buffer.read(reader) self.vertex_buffer.append(v_buffer) entry = reader.tell() self.index_offset = reader.read_uint32() self.index_count = reader.read_uint32() with reader.save_current_pos(): reader.seek(entry + self.index_offset) for _ in range(self.index_count): i_buffer = IndexBuffer() i_buffer.read(reader) self.index_buffer.append(i_buffer)
def read(self, reader: ByteIO): entry = reader.tell() self.strip_group_count = reader.read_uint32() self.strip_group_offset = reader.read_uint32() self.flags = reader.read_uint8() with reader.save_current_pos(): if self.strip_group_offset > 0: reader.seek(entry + self.strip_group_offset) for _ in range(self.strip_group_count): self.vtx_strip_groups.append(SourceVtxStripGroup().read(reader)) return self
def read(self, reader: ByteIO, block_info: InfoBlock = None): self.info_block = block_info self.entry = reader.tell() self.resource_entry_offset = reader.read_int32() self.resource_count = reader.read_int32() with reader.save_current_pos(): reader.seek(self.entry + self.resource_entry_offset) for n in range(self.resource_count): resource = RERLResource() resource.read(reader) self.resources.append(resource)
def read(self, reader: ByteIO, block_info: InfoBlock = None): self.info_block = block_info self.introspection_version = reader.read_int32() entry = reader.tell() self.struct_offset = reader.read_int32() self.struct_count = reader.read_int32() with reader.save_current_pos(): reader.seek(entry + self.struct_offset) for n in range(self.struct_count): struct = NTROStruct(self) struct.read(reader) self.structs.append(struct) entry = reader.tell() self.enum_offset = reader.read_int32() self.enum_count = reader.read_int32() with reader.save_current_pos(): reader.seek(entry + self.enum_offset) for n in range(self.enum_count): enum = NTROEnum(self) enum.read(reader) self.enums.append(enum)
def read(self, reader: ByteIO, model: SourceVtxModel): entry = reader.tell() self.lod = len(model.vtx_model_lods) self.meshCount = reader.read_uint32() self.meshOffset = reader.read_uint32() self.switchPoint = reader.read_float() with reader.save_current_pos(): if self.meshOffset > 0: reader.seek(entry + self.meshOffset) for _ in range(self.meshCount): self.vtx_meshes.append(SourceVtxMesh().read(reader)) return self
def read(self, reader: ByteIO): self.count = reader.read_uint32() self.size = reader.read_uint32() entry = reader.tell() self.attributes_offset = reader.read_uint32() self.attributes_count = reader.read_uint32() with reader.save_current_pos(): reader.seek(entry + self.attributes_offset) for _ in range(self.attributes_count): v_attrib = VertexAttribute() v_attrib.read(reader) self.attributes.append(v_attrib) entry = reader.tell() self.offset = reader.read_uint32() self.total_size = reader.read_uint32() with reader.save_current_pos(): reader.seek(entry + self.offset) assert self.total_size == self.size * self.count self.buffer = ByteIO(byte_object=reader.read_bytes(self.count * self.size)) self.read_buffer()
def read(self, reader: ByteIO): self.count = reader.read_uint32() self.size = reader.read_uint32() self.unk1 = reader.read_uint32() self.unk2 = reader.read_uint32() entry = reader.tell() self.offset = reader.read_uint32() self.total_size = reader.read_uint32() with reader.save_current_pos(): reader.seek(entry + self.offset) assert self.total_size == self.size * self.count self.buffer = ByteIO(byte_object=reader.read_bytes(self.count * self.size)) self.read_buffer()
def read(self, reader: ByteIO): entry = reader.tell() self.boneIndex = reader.read_uint32() self.boneNewParentIndex = reader.read_uint32() self.startInfluence = reader.read_float() self.peakInfluence = reader.read_float() self.tailInfluence = reader.read_float() self.endInfluence = reader.read_float() self.startFrameIndex = reader.read_uint32() self.localAnimOffset = reader.read_uint32() if self.localAnimOffset != 0: with reader.save_current_pos(): reader.seek(entry + self.localAnimOffset) self.theLocalAnims.read(reader) self.unused = [reader.read_uint32() for _ in range(4)] return self
def read(self, reader: ByteIO, block_info: InfoBlock = None): self.info_block = block_info entry = reader.tell() self.name_offset = reader.read_int32() self.name = reader.read_from_offset(entry + self.name_offset, reader.read_ascii_string) self.count = reader.read_int16() self.on_disc_size = reader.read_int16() entry = reader.tell() self.indirection_bytes_offset = reader.read_int32() self.indirection_level = reader.read_int32() with reader.save_current_pos(): reader.seek(entry + self.indirection_bytes_offset) indir_level = self.indirection_level if self.indirection_level < 10 else 10 for _ in range(indir_level): self.indirection_bytes.append(reader.read_int8()) self.data_type = reader.read_int32() self.type = KeyValueDataType(reader.read_int16()) reader.skip(2)
def read(self, reader: ByteIO): self.introspection_version = reader.read_int32() self.s_id = reader.read_int32() entry = reader.tell() self.name_offset = reader.read_int32() self.name = reader.read_from_offset(entry + self.name_offset, reader.read_ascii_string) self.disc_crc = reader.read_int32() self.user_version = reader.read_uint32() entry = reader.tell() self.field_offset = reader.read_int32() self.field_count = reader.read_int32() with reader.save_current_pos(): if self.field_count > 0: reader.seek(entry + self.field_offset) for n in range(self.field_count): field = NTROEnumField(self) field.read(reader) self.fields.append(field)
def read(self,reader:ByteIO,mdl:SourceMdlFileData): entry = reader.tell() self.baseHeaderOffset = reader.read_int32() self.nameOffset = reader.read_uint32() self.theName = reader.read_from_offset(entry+self.nameOffset,reader.read_ascii_string) self.activityNameOffset = reader.read_uint32() self.theActivityName = reader.read_from_offset(entry+self.activityNameOffset,reader.read_ascii_string) self.flags = reader.read_uint32() self.activity = reader.read_int32() self.activityWeight = reader.read_uint32() self.eventCount = reader.read_uint32() self.eventOffset = reader.read_uint32() self.bbMin.read(reader) self.bbMax.read(reader) self.blendCount = reader.read_uint32() self.animIndexOffset = reader.read_uint32() self.movementIndex = reader.read_uint32() self.groupSize = [reader.read_uint32() for _ in range(2)] self.paramIndex = [reader.read_int32() for _ in range(2)] self.paramStart = [reader.read_uint32() for _ in range(2)] self.paramEnd = [reader.read_uint32() for _ in range(2)] self.paramParent = reader.read_uint32() self.fadeInTime = reader.read_float() self.fadeOutTime = reader.read_float() self.localEntryNodeIndex = reader.read_uint32() self.localExitNodeIndex = reader.read_uint32() self.nodeFlags = reader.read_uint32() self.entryPhase = reader.read_float() self.exitPhase = reader.read_float() self.lastFrame = reader.read_float() self.nextSeq = reader.read_uint32() self.pose = reader.read_uint32() self.ikRuleCount = reader.read_uint32() self.autoLayerCount = reader.read_uint32() self.autoLayerOffset = reader.read_uint32() self.weightOffset = reader.read_uint32() self.poseKeyOffset = reader.read_uint32() self.ikLockCount = reader.read_uint32() self.ikLockOffset = reader.read_uint32() self.keyValueOffset = reader.read_uint32() self.keyValueSize = reader.read_uint32() self.cyclePoseIndex = reader.read_uint32() if mdl.version == 49: self.activityModifierOffset = reader.read_int32() self.activityModifierCount = reader.read_uint32() self.unused = [reader.read_uint32() for _ in range(5)] else: self.unused = [reader.read_uint32() for _ in range(7)] if self.groupSize[0] > 1 and self.groupSize[1] > 1 and self.poseKeyOffset !=0: with reader.save_current_pos(): reader.seek(entry+self.poseKeyOffset) for _ in range(self.groupSize[0]+self.groupSize[1]): self.thePoseKeys.append(reader.read_float()) if self.eventCount > 0 and self.eventOffset!=0: with reader.save_current_pos(): reader.seek(entry+self.eventOffset) for _ in range(self.eventCount): self.theEvents.append(SourceMdlEvent().read(reader)) return self
class ValveFile: def __init__(self, filepath): try: from Source2.Blocks.NTRO import NTRO from Source2.Blocks.REDI import REDI from Source2.Blocks.RERP import RERL from Source2.Blocks.VBIB import VBIB from Source2.Blocks.DATA import DATA except: from .Blocks.NTRO import NTRO from .Blocks.REDI import REDI from .Blocks.RERP import RERL from .Blocks.VBIB import VBIB from .Blocks.DATA import DATA print('Reading {}'.format(filepath)) self.reader = ByteIO( path=filepath, copy_data_from_handle=False, ) self.filepath = Path(filepath) self.filename = self.filepath.stem self.filepath = os.path.abspath(os.path.dirname(filepath)) self.header = CompiledHeader() self.header.read(self.reader) self.blocks_info = [] # type: List[InfoBlock] self.rerl = RERL(self) self.nrto = NTRO(self) self.redi = REDI(self) self.vbib = VBIB(self) self.data = DATA(self) self.available_resources = {} def read_block_info(self): for n in range(self.header.block_count): block_info = InfoBlock() block_info.read(self.reader) self.blocks_info.append(block_info) print(block_info) if block_info.block_name == 'RERL': with self.reader.save_current_pos(): self.reader.seek(block_info.entry + block_info.block_offset) self.rerl.read(self.reader, block_info) # print(self.rerl) if block_info.block_name == 'NTRO': with self.reader.save_current_pos(): self.reader.seek(block_info.entry + block_info.block_offset) self.nrto.read(self.reader, block_info) if block_info.block_name == 'REDI': with self.reader.save_current_pos(): self.reader.seek(block_info.entry + block_info.block_offset) self.redi.read(self.reader, block_info) # print(self.redi) if block_info.block_name == 'VBIB': with self.reader.save_current_pos(): self.reader.seek(block_info.entry + block_info.block_offset) self.vbib.read(self.reader, block_info) # print(self.vbib) if block_info.block_name == 'DATA': with self.reader.save_current_pos(): self.reader.seek(block_info.entry + block_info.block_offset) self.data.read(self.reader, block_info) # pprint(self.data.data) def dump_structs(self, file: TextIO): file.write('''struct vector2 { float x,y } struct vector3 { float x,y,z } struct vector4 { float x,y,z,w } struct quaternion { float x,y,z,w } struct RGB { byte r,g,b } ''') for struct in self.nrto.structs: # print(struct) # for mem in struct.fields: # print('\t', mem) file.write(struct.as_c_struct()) # print(struct.as_c_struct()) for enum in self.nrto.enums: # print(enum) # for mem in enum.fields: # print('\t', mem) file.write(enum.as_c_enum()) # print(struct.as_c_struct()) def dump_resources(self): for block in self.rerl.resources: pass # print(block) # for block in self.redi.blocks: # print(block) # for dep in block.container: # print('\t',dep) # print(block) # for block in self.vbib.vertex_buffer: # for vert in block.vertexes: # print(vert.boneWeight) # print(block) def check_external_resources(self): for block in self.rerl.resources: name = os.path.basename(block.resource_name) if os.path.exists(os.path.join(self.filepath, name + '_c')): self.available_resources[name] = os.path.abspath( os.path.join(self.filepath, name + '_c')) print('Found', name) else: print('Can\'t find', name)
def read(self, frame_count, anim_section, mdl: SourceMdlFileData, reader: ByteIO): anim_entry = reader.tell() self.boneIndex = reader.read_uint8() print('BoneIndex:',self.boneIndex) try: self.bone_name = mdl.bones[self.boneIndex].name except: self.bone_name = "ERROR" print('BoneName:',self.bone_name) if self.boneIndex == 255: reader.skip(3) return self, 0 if self.boneIndex >= mdl.bone_count: print('Bone index out of range {} - {}'.format(self.boneIndex, mdl.bone_count)) return self, 0 self.flags = reader.read_uint8() self.sflags = self.STUDIO_ANIM.get_flags(self.flags) self.nextSourceMdlAnimationOffset = reader.read_int16() pdata = reader.tell() print('Seq flag',self.flags,self.sflags) if (self.flags & self.STUDIO_ANIM.RAWROT2) > 0: with reader.save_current_pos(): reader.seek(pdata) self.theRot64bits.read(reader) print('Rot 64',self.theRot64bits) if (self.flags & self.STUDIO_ANIM.RAWROT) > 0: with reader.save_current_pos(): reader.seek(pdata) self.theRot48bits.read(reader) print('Rot 48', self.theRot48bits) if (self.flags & self.STUDIO_ANIM.RAWPOS) > 0: with reader.save_current_pos(): reader.seek(pdata+(((self.flags & self.STUDIO_ANIM.RAWROT) != 0)*6) + ((self.flags & self.STUDIO_ANIM.RAWROT2) != 0)*8) self.thePos.read(reader) print('Pos', self.thePos) if (self.flags & self.STUDIO_ANIM.ANIMROT) > 0: with reader.save_current_pos(): rotV_entry = reader.tell() reader.seek(pdata) self.theRotV.read(reader) self.theRotV.read_values(rotV_entry, frame_count, reader) print('Rot V', self.theRotV) if (self.flags & self.STUDIO_ANIM.ANIMPOS) > 0: with reader.save_current_pos(): reader.seek(((self.flags & self.STUDIO_ANIM.ANIMPOS)!=0) + pdata) posV_entry = reader.tell() self.thePosV.read(reader) self.thePosV.read_values(posV_entry, frame_count, reader) print('Pos V', self.thePosV) print('\n') pprint(self.__dict__) print('\n') if self.nextSourceMdlAnimationOffset == 0: print('DONE WITH ANIMATIONS') reader.seek(pdata) return self, -1 else: nextAnimationInputFileStreamPosition = anim_entry + self.nextSourceMdlAnimationOffset if nextAnimationInputFileStreamPosition < reader.tell(): print('PROBLEM! Should not be going backwards in file.') # raise BufferError('PROBLEM! Should not be going backwards in file.') reader.seek(nextAnimationInputFileStreamPosition) anim_section.append(self) return self, 1