def resolve(self, packman, dbpf, verbose=False): if self.version != 6 and self.version != 7: targ_descriptor = dbpf.findname(PackedFile.GMND, self.name) if targ_descriptor: if verbose: print("Found target descriptor: %s => %s" % (self.name, str(DecodeDescriptor(targ_descriptor)))) else: print( "Failed to find target descriptor for %s in local name map, checking global" % self.name) targ_descriptor = packman.findname(PackedFile.GMND, self.name) if targ_descriptor: if verbose: print("Found target descriptor: %s => %s" % (self.name, str( DecodeDescriptor(targ_descriptor)))) else: raise ValueError( "Failed to find target descriptor for %s in name maps" % self.name) self.target = packman.GetRCOL(targ_descriptor) if not self.target: resource = sims2crc32(self.name.lower().encode('ascii')) resource_bytes = struct.pack('I', resource) descriptor = b''.join((targ_descriptor, resource_bytes)) self.target = packman.GetRCOL(descriptor) self.target.ResolveAllLinks(packman, verbose)
def GetRCOLByName(self, rcol_type, rcol_name, verbose=False): descriptor = self.findname(rcol_type, rcol_name) rcol = self.GetRCOL(descriptor) if not rcol: if verbose: print("Couldn't locate descriptor: %s" % str(DecodeDescriptor(descriptor))) resource = sims2crc32(rcol_name.lower().encode('ascii')) resource_bytes = struct.pack('I', resource) descriptor = b''.join((descriptor, resource_bytes)) rcol = self.GetRCOL(descriptor) if not rcol: print("Couldn't locate descriptor: %s" % str(DecodeDescriptor(descriptor))) raise RuntimeError("Can't find descriptor in package list") return rcol
def build_namemaps(self, verbose=False): """Construct a namemap from all packed RCOLs""" if verbose: print("Constructing namemap for " + self.file) with open(self.file, 'rb') as fh: self.namemaps = {} self.extract_dircomp(fh) for descriptor, (offset, size, _) in self.index.items(): identifier = DecodeDescriptor(descriptor) if verbose: print("Creating namemap entry for %s" % str(identifier)) decompressed_size = None if descriptor in self.dircomp: decompressed_size = self.dircomp[descriptor] dg = DataGenerator(fh, offset, size, decompressed_size) if identifier.type.is_rcol(): name = RCOL.get_name(dg, identifier).lower() if int(identifier.type) not in self.namemaps: self.namemaps[identifier.type] = {} self.namemaps[identifier.type][name] = descriptor else: if verbose: print ("Skipping non-RCOL type %s" % str(identifier.type))
def get_RCOL(self, descriptor, verbose=False): decompressed_size = None rcol = None if descriptor in self.index: (offset, size, _) = self.index[descriptor] else: descriptor = descriptor[0:12] + bytes.fromhex('00000000') if descriptor in self.index: (offset, size, _) = self.index[descriptor] else: #if verbose: print("Descriptor not found in index: %s" % str(DecodeDescriptor(descriptor))) return rcol #if verbose: if True: print ("Opening " + self.file) with open(self.file, 'rb') as fh: self.extract_dircomp(fh) if descriptor in self.dircomp: decompressed_size = self.dircomp[descriptor] if verbose: print("RCOL is compressed (%d bytes, decompressed %d)" % (size, decompressed_size)) elif verbose: print("RCOL is not compressed ") self.extract_namemaps(fh) identifier = DecodeDescriptor(descriptor) if verbose: print ("Extracting RCOL") rcol = RCOL(fh, identifier, offset, size, decompressed_size, self, verbose) if verbose: print ("Done!") #except ValueError as err: # print("ValueError while processing %s: %s" % (self.file, err)) # print("Descriptor: %s" % str(descriptor)) # rcol = None return rcol
def CheckAllCRES(verbose=True, starting_point=0): packman = PackageManager() AddSims2DirectoriesToPackageManager(packman) packman.ReadDBPFIndices() unsupported = [] creslist = packman.GetRCOLsByType(PackedFile.CRES) index = 0 for cres_descriptor in creslist: if index < starting_point: index += 1 continue if verbose: print("Extracting CRES at index %d: %s" % (index, str(DecodeDescriptor(cres_descriptor)))) cres = packman.GetRCOL(cres_descriptor) cres.ResolveAllLinks(packman) if cres.unsupported: unsupported.extend(cres.unsupported) index += 1 if unsupported: print("Unsupported RCOL formats:") for rcol_type in unsupported: print(" %s" % str(rcol_type)) return index
def dump_index(self): for descriptor in self.index: print(str(DecodeDescriptor(descriptor)))
def ReadDBPFIndices(self, extract_namemaps=False, verbose=False, alert_identifier=None): packfiles = [] # Iterate through directories and get all the .package files for searchdir in self.searchlist: if verbose: print("Searching " + searchdir) for root, _, files in os.walk(searchdir): for file in files: if file.lower().endswith(".package"): packfiles.append(os.path.join(root, file)) if verbose: print("Found " + str(len(packfiles)) + " .package files") # Now iterate through the files and read the DBPFs, building up a hash of parts and a list of CRESs if verbose: typecounts = collections.Counter() self.meta_namemap = {} for file in packfiles: if verbose: print(file) package = DBPF() package.extract(file, index_only=(not extract_namemaps)) self.packages.append(package) for descriptor in package.index: typ = GetTypeFromDescriptor(descriptor) if verbose: typecounts[typ] += 1 self.package_index[descriptor] = package if alert_identifier: if alert_identifier == GetInstanceFromDescriptor(descriptor): print("Found identifier %s, descriptor %s, in file %s \n" % (format(alert_identifier, '#010x'), str(DecodeDescriptor(descriptor)), file)); if extract_namemaps: self.extract_namemap(package) if verbose: total = 0 for typename, count in typecounts.items(): print(str(count) + " " + str(typename) + "s found") total += count print ("Total %d RCOLs" % total)