summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoritsme <itsme@xs4all.nl>2021-07-07 12:25:09 +0200
committeritsme <itsme@xs4all.nl>2021-07-07 12:25:09 +0200
commita8824d8041a975d6304106dbb33d547a97ada4a1 (patch)
treef6426458cc9bef4c8082becd5a9f3339ffa46c90
parentbb1e9b68213b74d5c777425bbd8a3a1216b4c4b8 (diff)
crodump: the --struonly option now prints detailed info on tables and fields
-rw-r--r--crodump.py108
1 files changed, 88 insertions, 20 deletions
diff --git a/crodump.py b/crodump.py
index 46fd969..e311190 100644
--- a/crodump.py
+++ b/crodump.py
@@ -53,7 +53,7 @@ class Datafile:
53 return self.dat.read(size) 53 return self.dat.read(size)
54 54
55 def readrec(self, idx): 55 def readrec(self, idx):
56 ofs, ln, chk = self.tabidx[idx-1] 56 ofs, ln, chk = self.tadidx[idx-1]
57 if ln==0xFFFFFFFF: 57 if ln==0xFFFFFFFF:
58 # deleted record 58 # deleted record
59 return 59 return
@@ -133,6 +133,75 @@ class Datafile:
133 dat = self.readdata(o, l) 133 dat = self.readdata(o, l)
134 print("%08x-%08x: %s" % (o, o+l, toout(args, dat))) 134 print("%08x-%08x: %s" % (o, o+l, toout(args, dat)))
135 135
136def destruct_bank_definition(args, data):
137 """
138 decode the 'bank' / database definition
139 """
140 rd = ByteReader(data)
141
142 version = rd.readbyte()
143 print("bank version: %02x" % version)
144
145 d = dict()
146 while not rd.eof():
147 keyname = rd.readname()
148 if keyname in d:
149 print("WARN: duplicate key: %s" % keyname)
150
151 index_or_length = rd.readdword()
152 if index_or_length >> 31:
153 d[keyname] = rd.readbytes(index_or_length & 0x7FFFFFFF)
154 print("%-20s - %s" % (keyname, toout(args, d[keyname])))
155 else:
156 d[keyname] = index_or_length
157 print("%-20s -> %s" % (keyname, d[keyname]))
158 return d
159
160def decode_field(data):
161 rd = ByteReader(data)
162 typ = rd.readword()
163 idx1 = rd.readdword()
164 name = rd.readname()
165 unk1 = rd.readdword()
166 unk2 = rd.readbyte()
167 if typ:
168 idx2 = rd.readdword()
169 unk3 = rd.readdword()
170 unk4 = rd.readdword()
171 remain = rd.readbytes()
172
173 print("%d %2d/%2d %d,%d,%d,%d - '%s' -- %s" % (typ, idx1, idx2, unk1, unk2, unk3, unk4, name, tohex(remain)))
174 else:
175 print("%d %2d %d,%d - '%s'" % (typ, idx1, unk1, unk2, name))
176
177
178def destruct_base_definition(args, data):
179 """
180 decode the 'base' / table definition
181 """
182 rd = ByteReader(data)
183
184 version = rd.readbyte()
185 print("base version: %02x" % version)
186 unk123 = [rd.readword() for _ in range(3)]
187 unk45 = [rd.readdword() for _ in range(2)]
188 tablename = rd.readname()
189 unkname = rd.readname()
190 unk7 = rd.readdword()
191 nrfields = rd.readdword()
192 print("%d,%d,%d,%d,%d %d,%d '%s' '%s'" % (*unk123, *unk45, unk7, nrfields, tablename, unkname))
193 fields = []
194 for _ in range(nrfields):
195 l = rd.readword()
196 fielddef = rd.readbytes(l)
197 if args.verbose:
198 print("field: @%04x: %04x - %s" % (rd.o, l, tohex(fielddef)))
199 fields.append(decode_field(fielddef))
200 remaining = rd.readbytes()
201
202 print("rem: %s" % tohex(remaining))
203
204
136 205
137class Database: 206class Database:
138 """ represent the entire database, consisting of stru, index and bank files """ 207 """ represent the entire database, consisting of stru, index and bank files """
@@ -170,6 +239,7 @@ class Database:
170 print("stru") 239 print("stru")
171 self.stru.dump(args) 240 self.stru.dump(args)
172 if args.struonly: 241 if args.struonly:
242 self.dumptabledefs(args)
173 return 243 return
174 if self.index: 244 if self.index:
175 print("index") 245 print("index")
@@ -181,6 +251,17 @@ class Database:
181 print("sys") 251 print("sys")
182 self.sys.dump(args) 252 self.sys.dump(args)
183 253
254 def dumptabledefs(self, args):
255 dbinfo = self.stru.readrec(1)
256 dbdef = destruct_bank_definition(args, dbinfo)
257
258 for i in range(1, 100):
259 idx = dbdef.get("Base%03d" % i)
260 if idx:
261 print("== Base%03d ==" % i)
262 tbinfo = self.stru.readrec(idx)
263 tbdef = destruct_base_definition(args, tbinfo)
264
184 265
185def incdata(data, s): 266def incdata(data, s):
186 """ 267 """
@@ -262,25 +343,10 @@ def destruct(args):
262 data = sys.stdin.buffer.read() 343 data = sys.stdin.buffer.read()
263 data = unhex(data) 344 data = unhex(data)
264 345
265 d = dict() 346 if args.type==1:
266 347 destruct_bank_definition(args, data)
267 rd = ByteReader(data) 348 elif args.type==2:
268 349 destruct_base_definition(args, data)
269 o = 0
270 startbyte = rd.readbyte()
271 while not rd.eof():
272 keylen = rd.readbyte()
273 keyname = rd.readbytes(keylen).decode('ascii')
274 if keyname in d:
275 print("duplicate key: %s" % keyname)
276
277 index_or_length = rd.readdword()
278 if index_or_length >> 31:
279 d[keyname] = rd.readbytes(index_or_length & 0x7FFFFFFF)
280 print("%-20s - %s" % (keyname, toout(args, d[keyname])))
281 else:
282 d[keyname] = index_or_length
283 print("%-20s -> %s" % (keyname, d[keyname]))
284 350
285def main(): 351def main():
286 import argparse 352 import argparse
@@ -310,7 +376,9 @@ def main():
310 cro.set_defaults(handler=cro_dump) 376 cro.set_defaults(handler=cro_dump)
311 377
312 des = subparsers.add_parser('destruct', help='Stru dumper') 378 des = subparsers.add_parser('destruct', help='Stru dumper')
379 des.add_argument('--verbose', '-v', action='store_true')
313 des.add_argument('--ascdump', '-a', action='store_true') 380 des.add_argument('--ascdump', '-a', action='store_true')
381 des.add_argument('--type', '-t', type=int, help='what type of record to destruct')
314 des.set_defaults(handler=destruct) 382 des.set_defaults(handler=destruct)
315 383
316 args = parser.parse_args() 384 args = parser.parse_args()