def getIds(fileName=None): """Gets fids and returns as a set. Primarily for analysis of Fallout3.esm. NOTE: Does a low level read and hence can read fids of ALL records in all groups. Including CELLs WRLDs, etc.""" def getRecordReader(ins, flags, size): """Decompress record data as needed.""" if not bosh.MreRecord.flags1(flags).compressed: return (ins, ins.tell() + size) else: import zlib sizeCheck, = struct.unpack("I", ins.read(4)) decomp = zlib.decompress(ins.read(size - 4)) if len(decomp) != sizeCheck: raise ModError(self.inName, _("Mis-sized compressed data. Expected %d, got %d.") % (size, len(decomp))) reader = bosh.ModReader(fileName, cStringIO.StringIO(decomp)) return (reader, sizeCheck) init(2) modInfo = bosh.modInfos[GPath(fileName)] ins = bosh.ModReader(fileName, modInfo.getPath().open("rb")) group_records = {} records = group_records["TES4"] = [] while not ins.atEnd(): (type, size, str0, fid, uint2) = ins.unpackRecHeader() print ">>", type, size, fid if type == "GRUP": records = group_records.setdefault(str0, []) if str0 in ("CELL", "WRLD"): ins.seek(size - 20, 1) elif type != "GRUP": eid = "" nextRecord = ins.tell() + size recs, endRecs = getRecordReader(ins, str0, size) while recs.tell() < endRecs: (type, size) = recs.unpackSubHeader() if type == "EDID": eid = recs.readString(size) break ins.seek(size, 1) records.append((fid, eid)) ins.seek(nextRecord) ins.close() # --Report del group_records["TES4"] for group in sorted(group_records): # print print group for fid, eid in sorted(group_records[group], key=lambda a: a[1].lower()): print " ", bosh.strFid(fid), eid
def mine(record): return False def put_stats(record): print(" weaponType: %s\n animationType: %s\n damage: %d\n isAutomatic: %d\n projectileCount: %d\n resistType: %s" % (weaponType[record.etype], animationType[record.animationType], record.damage, record.dnamFlags1.isAutomatic, record.projectileCount, registType[record.resistType])) for record in patchFile.WEAP.records: name = record.full print "%s:%s" % (name, bosh.strFid(record.fid)) put_stats(record) func = (biggun,energy,smallgun,melee,unarmed,thrown,mine)[record.etype] if func(record): print " >> patched!!" else: print " >> skip" # postprocess patchFile.tes4.masters = patchFile.getMastersUsed() patchFile.convertToShortFids() numRecords = sum([x.getNumRecords(False) for x in patchFile.tops.values()]) patchFile.tes4.description = "{{BASH:NoMerge,Stats}}\nUpdated: %s\n\nRecords Changed: %d" % (formatDate(time.time()),numRecords) patchFile.safeSave() print "\nWrote to '%s'..." % opts.outfile
def readRecord(record, melSet=0, skipLabel=0): global longest global indent indent += 2 if isinstance(record, bosh.MobCell): melSet = ["cell", "persistent", "distant", "temp", "land", "pgrd"] elif isinstance(record, bosh.MobWorld): melSet = ["cellBlocks", "world", "road", "worldCellBlock"] elif hasattr(record, "melSet"): melSet = record.melSet.getSlotsUsed() if record.recType == "DIAL": melSet += ["infoStamp", "infos"] elif hasattr(record, "__slots__"): melSet = getattr(record, "__slots__") elif hasattr(record, "__dict__"): melSet = getattr(record, "__dict__").keys() if hasattr(record, "setChanged"): record.setChanged() if hasattr(record, "getHeader"): if 6 > longest: longest = 6 attr = "flags" print " " * indent + attr.ljust(longest) + " :", record.flags1.hex(), record.flags1.getTrueAttrs() attr = "formID" print " " * indent + attr.ljust(longest) + " : " + bosh.strFid(record.fid) attr = "unk" print " " * indent + attr.ljust(longest) + " : %08X" % record.flags2 for attr in melSet: if len(attr) > longest: longest = len(attr) for attr in melSet: if hasattr(record, attr): item = getattr(record, attr) else: item = record if attr == "references": if isinstance(item, tuple): if item[0] is True: attr = "scro" item = item[1] else: attr = "scrv" item = item[1] if skipLabel == 0: report = " " * indent + attr.ljust(longest) + " :" else: report = " " * indent + " ".rjust(longest) if item == None: print report, "None" elif isinstance(item, list) or isinstance(item, tuple): itemList = item if len(itemList) == 0: print report, "Empty" continue print report for item in itemList: readRecord(item, [attr]) elif isinstance(item, bolt.Flags): print report, item.hex(), item.getTrueAttrs() elif attr[-2:] == "_p" or attr == "pgrd": print report, "Packed Data" elif attr[-2:] == "Id": print report, bosh.strFid(item) elif attr[:6] == "unused": pass elif attr == "scro": print report, "%08X" % int(item) elif attr in ["param1", "param2"]: if record.form12[int(attr[-1]) - 1] == "I": print bosh.strFid(item) else: print report, item elif attr == "land": print "land ", item print type(item) print dir(item) ## sys.exit() elif isinstance(item, int): print report, item elif isinstance(item, long): print report, item elif isinstance(item, float): print report, round(item, 6) elif attr in ["unk1", "unk2", "unk3", "unk4", "unk5", "unk6"]: if sum(struct.unpack(str(len(item)) + "b", item)) == 0: print report, "Null" else: print report, struct.unpack(str(len(item)) + "b", item) elif isinstance(item, basestring): if len(item.splitlines()) > 1: item = item.splitlines() print report for line in item: readRecord(line, [attr], 1) else: if sum(struct.unpack(str(len(item)) + "b", item)) == 0: print report, "" else: print report, item else: print report readRecord(item) indent -= 2 if indent == 0: longest = 0 print ""