summaryrefslogtreecommitdiff
path: root/crodump.py
diff options
context:
space:
mode:
Diffstat (limited to 'crodump.py')
-rw-r--r--crodump.py56
1 files changed, 46 insertions, 10 deletions
diff --git a/crodump.py b/crodump.py
index d668915..d0cd67c 100644
--- a/crodump.py
+++ b/crodump.py
@@ -87,6 +87,9 @@ class Datafile:
87 return self.dat.read(size) 87 return self.dat.read(size)
88 88
89 def readrec(self, idx): 89 def readrec(self, idx):
90 """
91 extract and decode a single record.
92 """
90 ofs, ln, chk = self.tadidx[idx-1] 93 ofs, ln, chk = self.tadidx[idx-1]
91 if ln==0xFFFFFFFF: 94 if ln==0xFFFFFFFF:
92 # deleted record 95 # deleted record
@@ -120,6 +123,9 @@ class Datafile:
120 123
121 124
122 def dump(self, args): 125 def dump(self, args):
126 """
127 dump decodes all references data, and optionally will print out all unused bytes in the .dat file.
128 """
123 print("hdr: %-6s dat: %04x %s enc:%04x bs:%04x, tad: %08x %08x" % (self.name, self.hdrunk, self.version, self.encoding, self.blocksize, self.nrdeleted, self.firstdeleted)) 129 print("hdr: %-6s dat: %04x %s enc:%04x bs:%04x, tad: %08x %08x" % (self.name, self.hdrunk, self.version, self.encoding, self.blocksize, self.nrdeleted, self.firstdeleted))
124 ranges = [] # keep track of used bytes in the .dat file. 130 ranges = [] # keep track of used bytes in the .dat file.
125 for i, (ofs, ln, chk) in enumerate(self.tadidx): 131 for i, (ofs, ln, chk) in enumerate(self.tadidx):
@@ -183,20 +189,31 @@ class Datafile:
183 print("%08x-%08x: %s" % (o, o+l, toout(args, dat))) 189 print("%08x-%08x: %s" % (o, o+l, toout(args, dat)))
184 190
185 def iscompressed(self, data): 191 def iscompressed(self, data):
192 """
193 Note that the compression header uses big-endian numbers.
194 """
186 if len(data)<11: 195 if len(data)<11:
187 return 196 return
188 size, flag = struct.unpack_from(">HH", data, 0)
189 if size+5 != len(data):
190 return
191 if flag!=0x800:
192 return
193 if data[-3:] != b"\x00\x00\x02": 197 if data[-3:] != b"\x00\x00\x02":
194 return 198 return
199 o = 0
200 while o < len(data)-3:
201 size, flag = struct.unpack_from(">HH", data, o)
202 if flag!=0x800 and flag!=0x008:
203 return
204 o += size + 2
195 return True 205 return True
196 206
197 def decompress(self, data): 207 def decompress(self, data):
198 C = zlib.decompressobj(-15) 208 result = b""
199 return C.decompress(data[8:-3]) 209 o = 0
210 while o < len(data)-3:
211 size, flag, crc = struct.unpack_from(">HHL", data, o)
212 C = zlib.decompressobj(-15)
213 result += C.decompress(data[o+8:o+8+size])
214 o += size + 2
215 return result
216
200 217
201def dump_bank_definition(args, bankdict): 218def dump_bank_definition(args, bankdict):
202 """ 219 """
@@ -222,9 +239,9 @@ def decode_field(data):
222 unk4 = rd.readdword() # Always 0x00000009 or 0x0001000d 239 unk4 = rd.readdword() # Always 0x00000009 or 0x0001000d
223 remain = rd.readbytes() 240 remain = rd.readbytes()
224 241
225 print("Type: %d (%02d/%02d) %04x,(%d-%d),%04x - '%s' -- %s" % (typ, idx1, idx2, unk1, unk2, unk3, unk4, name, tohex(remain))) 242 print("Type: %2d (%2d/%2d) %04x,(%d-%4d),%04x - '%s' -- %s" % (typ, idx1, idx2, unk1, unk2, unk3, unk4, name, tohex(remain)))
226 else: 243 else:
227 print("Type: %d %2d %d,%d - '%s'" % (typ, idx1, unk1, unk2, name)) 244 print("Type: %2d %2d %d,%d - '%s'" % (typ, idx1, unk1, unk2, name))
228 245
229""" 246"""
230 2 Base000 - 000001 050001 000000000000000546696c657302464c01000000010000001b000000000000000fd1e8f1f2e5ecedfbe920edeeece5f0010000000000000000010000000000000000 247 2 Base000 - 000001 050001 000000000000000546696c657302464c01000000010000001b000000000000000fd1e8f1f2e5ecedfbe920edeeece5f0010000000000000000010000000000000000
@@ -272,7 +289,11 @@ def destruct_base_definition(args, data):
272 abbrev = rd.readname() 289 abbrev = rd.readname()
273 unk7 = rd.readdword() 290 unk7 = rd.readdword()
274 nrfields = rd.readdword() 291 nrfields = rd.readdword()
292
293 if args.verbose:
294 print("table: %s" % tohex(data[:rd.o]))
275 print("%d,%d,%d,%d,%d,%d %d,%d '%s' '%s'" % (unk1, version, unk2, unk3, unk4, unk5, unk7, nrfields, tablename, abbrev)) 295 print("%d,%d,%d,%d,%d,%d %d,%d '%s' '%s'" % (unk1, version, unk2, unk3, unk4, unk5, unk7, nrfields, tablename, abbrev))
296
276 fields = [] 297 fields = []
277 for _ in range(nrfields): 298 for _ in range(nrfields):
278 l = rd.readword() 299 l = rd.readword()
@@ -396,12 +417,20 @@ class Database:
396 if not self.bank: 417 if not self.bank:
397 print("No CroBank.dat found") 418 print("No CroBank.dat found")
398 return 419 return
420 if args.skipencrypted and self.bank.encoding==3:
421 print("Skipping encrypted CroBank")
422 return
399 nerr = 0 423 nerr = 0
400 xref = defaultdict(int) 424 xref = defaultdict(int)
401 for i in range(args.maxrecs): 425 for i in range(args.maxrecs):
402 try: 426 try:
403 data = self.bank.readrec(i) 427 data = self.bank.readrec(i)
404 if not args.stats: 428 if args.find1d:
429 if data and (data.find(b"\x1d")>0 or data.find(b"\x1b")>0):
430 print("%d -> %s" % (i, b2a_hex(data)))
431 break
432
433 elif not args.stats:
405 if data is None: 434 if data is None:
406 print("%5d: <deleted>" % i) 435 print("%5d: <deleted>" % i)
407 else: 436 else:
@@ -426,6 +455,11 @@ class Database:
426 for k, v in xref.items(): 455 for k, v in xref.items():
427 print("%5d * %s" % (v, k)) 456 print("%5d * %s" % (v, k))
428 457
458 def readrec(self, sysnum):
459 data = self.bank.readrec(sysnum)
460 tabnum, = struct.unpack_from("<B", data, 0)
461 fields = data[1:].split(b"\x1e")
462
429def incdata(data, s): 463def incdata(data, s):
430 """ 464 """
431 add 's' to each byte. 465 add 's' to each byte.
@@ -576,6 +610,8 @@ def main():
576 p.add_argument('--verbose', '-v', action='store_true') 610 p.add_argument('--verbose', '-v', action='store_true')
577 p.add_argument('--ascdump', '-a', action='store_true') 611 p.add_argument('--ascdump', '-a', action='store_true')
578 p.add_argument('--maxrecs', '-n', type=str, help="max nr or recots to output") 612 p.add_argument('--maxrecs', '-n', type=str, help="max nr or recots to output")
613 p.add_argument('--find1d', action='store_true')
614 p.add_argument('--inclencrypted', action='store_false', dest='skipencrypted', default='true', help='include encrypted records in the output')
579 p.add_argument('--stats', action='store_true', help='calc table stats from the first byte of each record') 615 p.add_argument('--stats', action='store_true', help='calc table stats from the first byte of each record')
580 p.add_argument('dbdir', type=str) 616 p.add_argument('dbdir', type=str)
581 p.set_defaults(handler=bank_dump) 617 p.set_defaults(handler=bank_dump)