diff options
-rw-r--r-- | crodump.py | 42 |
1 files changed, 25 insertions, 17 deletions
@@ -78,9 +78,16 @@ class Datafile: | |||
78 | if self.use64bit: | 78 | if self.use64bit: |
79 | # 01.03 has 64 bit file offsets | 79 | # 01.03 has 64 bit file offsets |
80 | self.tadidx = [ struct.unpack_from("<QLL", indexdata, 16*_) for _ in range(len(indexdata)//16) ] | 80 | self.tadidx = [ struct.unpack_from("<QLL", indexdata, 16*_) for _ in range(len(indexdata)//16) ] |
81 | if len(indexdata)%16: | ||
82 | print("WARN: leftover data in .tad") | ||
81 | else: | 83 | else: |
82 | # 01.02 and 01.04 have 32 bit offsets. | 84 | # 01.02 and 01.04 have 32 bit offsets. |
83 | self.tadidx = [ struct.unpack_from("<LLL", indexdata, 12*_) for _ in range(len(indexdata)//12) ] | 85 | self.tadidx = [ struct.unpack_from("<LLL", indexdata, 12*_) for _ in range(len(indexdata)//12) ] |
86 | if len(indexdata)%12: | ||
87 | print("WARN: leftover data in .tad") | ||
88 | |||
89 | def nrofrecords(self): | ||
90 | return len(self.tadidx) | ||
84 | 91 | ||
85 | def readdata(self, ofs, size): | 92 | def readdata(self, ofs, size): |
86 | self.dat.seek(ofs) | 93 | self.dat.seek(ofs) |
@@ -269,14 +276,14 @@ class TableDefinition: | |||
269 | self.version = rd.readbyte() | 276 | self.version = rd.readbyte() |
270 | if self.version > 1: | 277 | if self.version > 1: |
271 | _ = rd.readbyte() # always 0 anyway | 278 | _ = rd.readbyte() # always 0 anyway |
279 | |||
272 | self.unk2 = rd.readbyte() # if this is not 5 (but 9), there's another 4 bytes inserted, this could be a length-byte. | 280 | self.unk2 = rd.readbyte() # if this is not 5 (but 9), there's another 4 bytes inserted, this could be a length-byte. |
273 | self.unk3 = rd.readbyte() | 281 | self.unk3 = rd.readbyte() |
274 | |||
275 | if self.unk2 > 5: # seen only 5 and 9 for now with 9 implying an extra dword | 282 | if self.unk2 > 5: # seen only 5 and 9 for now with 9 implying an extra dword |
276 | _ = rd.readdword() | 283 | _ = rd.readdword() |
284 | self.unk4 = rd.readdword() | ||
277 | 285 | ||
278 | self.tableid = rd.readdword() | 286 | self.tableid = rd.readdword() |
279 | self.unk5 = rd.readdword() | ||
280 | 287 | ||
281 | self.tablename = rd.readname() | 288 | self.tablename = rd.readname() |
282 | self.abbrev = rd.readname() | 289 | self.abbrev = rd.readname() |
@@ -293,10 +300,13 @@ class TableDefinition: | |||
293 | 300 | ||
294 | self.remainingdata = rd.readbytes() | 301 | self.remainingdata = rd.readbytes() |
295 | 302 | ||
303 | def __str__(self): | ||
304 | return "%d,%d<%d,%d,%d>%d %d,%d '%s' '%s'" % ( self.unk1, self.version, self.unk2, self.unk3, self.unk4, self.tableid, self.unk7, len(self.fields), self.tablename, self.abbrev) | ||
296 | def dump(self, args): | 305 | def dump(self, args): |
297 | if args.verbose: | 306 | if args.verbose: |
298 | print("table: %s" % tohex(self.headerdata)) | 307 | print("table: %s" % tohex(self.headerdata)) |
299 | print("%d,%d,%d,%d,%d,%d %d,%d '%s' '%s'" % ( self.unk1, self.version, self.unk2, self.unk3, self.tableid, self.unk5, self.unk7, len(self.fields), self.tablename, self.abbrev)) | 308 | |
309 | print(str(self)) | ||
300 | 310 | ||
301 | for field in self.fields: | 311 | for field in self.fields: |
302 | if args.verbose: | 312 | if args.verbose: |
@@ -345,6 +355,8 @@ class Database: | |||
345 | self.sys = self.getfile("Sys") | 355 | self.sys = self.getfile("Sys") |
346 | # BankTemp, Int | 356 | # BankTemp, Int |
347 | 357 | ||
358 | def nrofrecords(self): | ||
359 | return len(self.bank.tadidx) | ||
348 | 360 | ||
349 | def getfile(self, name): | 361 | def getfile(self, name): |
350 | try: | 362 | try: |
@@ -440,26 +452,26 @@ class Database: | |||
440 | for rec in db.enumerate_records(tab): | 452 | for rec in db.enumerate_records(tab): |
441 | print(sqlformatter(tab, rec)) | 453 | print(sqlformatter(tab, rec)) |
442 | """ | 454 | """ |
443 | for i in range(1, args.maxrecs+1): | 455 | for i in range(self.nrofrecords()): |
444 | data = db.readrec(i) | 456 | data = self.bank.readrec(i+1) |
445 | if data and struct.unpack_from("<B", data, 0) == table.tableid: | 457 | if data and data[0] == table.tableid: |
446 | yield data[1:].split(b"\x1e") | 458 | yield data[1:].split(b"\x1e") |
447 | 459 | ||
448 | 460 | ||
449 | def recdump(self, args): | 461 | def recdump(self, args): |
450 | if args.index: | 462 | if args.index: |
451 | db = self.index | 463 | dbfile = self.index |
452 | elif args.sys: | 464 | elif args.sys: |
453 | db = self.sys | 465 | dbfile = self.sys |
454 | elif args.stru: | 466 | elif args.stru: |
455 | db = self.stru | 467 | dbfile = self.stru |
456 | else: | 468 | else: |
457 | db = self.bank | 469 | dbfile = self.bank |
458 | 470 | ||
459 | if not db: | 471 | if not dbfile: |
460 | print(".dat not found") | 472 | print(".dat not found") |
461 | return | 473 | return |
462 | if args.skipencrypted and db.encoding==3: | 474 | if args.skipencrypted and dbfile.encoding==3: |
463 | print("Skipping encrypted CroBank") | 475 | print("Skipping encrypted CroBank") |
464 | return | 476 | return |
465 | nerr = 0 | 477 | nerr = 0 |
@@ -469,7 +481,7 @@ class Database: | |||
469 | bytexref = [0] * 256 | 481 | bytexref = [0] * 256 |
470 | for i in range(1, args.maxrecs+1): | 482 | for i in range(1, args.maxrecs+1): |
471 | try: | 483 | try: |
472 | data = db.readrec(i) | 484 | data = dbfile.readrec(i) |
473 | if args.find1d: | 485 | if args.find1d: |
474 | if data and (data.find(b"\x1d")>0 or data.find(b"\x1b")>0): | 486 | if data and (data.find(b"\x1d")>0 or data.find(b"\x1b")>0): |
475 | print("%d -> %s" % (i, b2a_hex(data))) | 487 | print("%d -> %s" % (i, b2a_hex(data))) |
@@ -509,10 +521,6 @@ class Database: | |||
509 | if v: | 521 | if v: |
510 | print("%5d * %02x" % (v, k)) | 522 | print("%5d * %02x" % (v, k)) |
511 | 523 | ||
512 | def readrec(self, sysnum): | ||
513 | data = self.bank.readrec(sysnum) | ||
514 | tabnum, = struct.unpack_from("<B", data, 0) | ||
515 | fields = data[1:].split(b"\x1e") | ||
516 | 524 | ||
517 | def incdata(data, s): | 525 | def incdata(data, s): |
518 | """ | 526 | """ |