summaryrefslogtreecommitdiff
path: root/crodump.py
diff options
context:
space:
mode:
Diffstat (limited to 'crodump.py')
-rw-r--r--crodump.py42
1 files changed, 25 insertions, 17 deletions
diff --git a/crodump.py b/crodump.py
index 5b495de..984770f 100644
--- a/crodump.py
+++ b/crodump.py
@@ -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
517def incdata(data, s): 525def incdata(data, s):
518 """ 526 """