diff options
author | itsme <itsme@xs4all.nl> | 2021-07-07 12:25:09 +0200 |
---|---|---|
committer | itsme <itsme@xs4all.nl> | 2021-07-07 12:25:09 +0200 |
commit | a8824d8041a975d6304106dbb33d547a97ada4a1 (patch) | |
tree | f6426458cc9bef4c8082becd5a9f3339ffa46c90 | |
parent | bb1e9b68213b74d5c777425bbd8a3a1216b4c4b8 (diff) |
crodump: the --struonly option now prints detailed info on tables and fields
-rw-r--r-- | crodump.py | 108 |
1 files changed, 88 insertions, 20 deletions
@@ -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 | ||
136 | def 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 | |||
160 | def 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 | |||
178 | def 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 | ||
137 | class Database: | 206 | class 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 | ||
185 | def incdata(data, s): | 266 | def 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 | ||
285 | def main(): | 351 | def 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() |