def decompile_data(self, remastered=None): remastered = (self.remastered or self.remastered_required() ) if remastered == None else remastered result = '' attrs = BINSMK.ATTR_NAMES longest = sorted(len(n) for n in attrs)[-1] for i, smk in enumerate(self.smks): result += 'SMK %d:\n' % i for attr in attrs: value = getattr(smk, attr) hint = '' if attr == 'overlay_smk' and value != None: value = self.smks.index(value) elif attr == 'filename': value = TBL.decompile_string(value) elif attr == 'flags': value = flags(value, 5) result += '\t%s%s%s%s%s\n' % (attr, ' ' * (longest - len(attr) + 1), value, ' # ' if hint else '', hint) result += '\n' attrs = BINWidget.ATTR_NAMES_REMASTERED if remastered else BINWidget.ATTR_NAMES longest = sorted(len(n) for n in attrs)[-1] for widget in self.widgets: result += 'Widget:\n' for attr in attrs: value = getattr(widget, attr) hint = '' if attr == 'smk' and value != None: value = self.smks.index(value) elif attr == 'string' and value != None: value = TBL.decompile_string(value) elif attr == 'flags': value = flags(value, 27) elif attr == 'type': if value < len(BINWidget.TYPE_NAMES): hint = BINWidget.TYPE_NAMES[value] else: hint = 'Unknown' result += '\t%s%s%s%s%s\n' % (attr, ' ' * (longest - len(attr) + 1), value, ' # ' if hint else '', hint) result += '\n' return result
def type_weaponid(stage, bin, data=None): """WeaponID""" if data == None: return 1 if stage == 1: return (str(data),'%s (%s)' % (DAT.DATA_CACHE['Weapons.txt'][data], TBL.decompile_string(bin.tbl.strings[bin.weaponsdat.get_value(data,'Label')-1][:-1]))) try: v = int(data) if 0 > v or v > DAT.WeaponsDAT.count: raise except: raise PyMSError('Parameter',"Invalid WeaponID value '%s', it must be a number in the range 0 to %s" % (data,DAT.WeaponsDAT.count)) return v
def type_soundid(stage, bin, data=None): """SoundID""" if data == None: return 2 if stage == 1: return (str(data), TBL.decompile_string(bin.sfxdatatbl.strings[bin.soundsdat.get_value(data,'SoundFile')-1][:-1])) try: v = int(data) if 0 > v or v > DAT.SoundsDAT.count: raise except: raise PyMSError('Parameter',"Invalid SoundID value '%s', it must be a number in the range 0 to %s" % (data,DAT.SoundsDAT.count)) return v
def type_flingy(stage, bin, data=None): """FlingyID""" if data == None: return 2 if stage == 1: return (str(data),'%s (%s)' % (DAT.DATA_CACHE['Flingy.txt'][data], TBL.decompile_string(bin.imagestbl.strings[bin.imagesdat.get_value(bin.spritesdat.get_value(bin.flingydat.get_value(data,'Sprite'),'ImageFile'),'GRPFile')-1][:-1]))) try: v = int(data) if 0 > v or v > DAT.FlingyDAT.count: raise except: raise PyMSError('Parameter',"Invalid FlingyID value '%s', it must be a number in the range 0 to %s" % (data,DAT.FlingyDAT.count)) return v
def decompile_data(self): result = '' attrs = BINSMK.ATTR_NAMES longest = sorted(len(n) for n in attrs)[-1] for i,smk in enumerate(self.smks): result += 'SMK %d:\n' % i for attr in attrs: value = getattr(smk, attr) hint = '' if attr == 'overlay_smk' and value != None: value = self.smks.index(value) elif attr == 'filename': value = TBL.decompile_string(value) elif attr == 'flags': value = flags(value, 5) result += '\t%s%s%s%s%s\n' % (attr,' ' * (longest - len(attr) + 1),value,' # ' if hint else '',hint) result += '\n' attrs = BINWidget.ATTR_NAMES longest = sorted(len(n) for n in attrs)[-1] for widget in self.widgets: result += 'Widget:\n' for attr in attrs: value = getattr(widget, attr) hint = '' if attr == 'smk' and value != None: value = self.smks.index(value) elif attr == 'string' and value != None: value = TBL.decompile_string(value) elif attr == 'flags': value = flags(value, 27) elif attr == 'type': if value < len(BINWidget.TYPE_NAMES): hint = BINWidget.TYPE_NAMES[value] else: hint = 'Unknown' result += '\t%s%s%s%s%s\n' % (attr,' ' * (longest - len(attr) + 1),value,' # ' if hint else '',hint) result += '\n' return result
def __init__(self, weaponsdat=None, flingydat=None, imagesdat=None, spritesdat=None, soundsdat=None, stat_txt=None, imagestbl=None, sfxdatatbl=None): if weaponsdat == None: weaponsdat = os.path.join(BASE_DIR, 'Libs', 'MPQ', 'arr', 'weapons.dat') if flingydat == None: flingydat = os.path.join(BASE_DIR, 'Libs', 'MPQ', 'arr', 'flingy.dat') if imagesdat == None: imagesdat = os.path.join(BASE_DIR, 'Libs', 'MPQ', 'arr', 'images.dat') if spritesdat == None: spritesdat = os.path.join(BASE_DIR, 'Libs', 'MPQ', 'arr', 'sprites.dat') if soundsdat == None: soundsdat = os.path.join(BASE_DIR, 'Libs', 'MPQ', 'arr', 'sfxdata.dat') if stat_txt == None: stat_txt = os.path.join(BASE_DIR, 'Libs', 'MPQ', 'rez', 'stat_txt.tbl') if imagestbl == None: imagestbl = os.path.join(BASE_DIR, 'Libs', 'MPQ', 'rez', 'images.tbl') if sfxdatatbl == None: sfxdatatbl = os.path.join(BASE_DIR, 'Libs', 'MPQ', 'rez', 'sfxdata.tbl') self.headers = {} self.offsets = {} self.code = odict() self.extrainfo = {} if isinstance(stat_txt, TBL.TBL): self.tbl = stat_txt else: self.tbl = TBL.TBL() self.tbl.load_file(stat_txt) if isinstance(weaponsdat, DAT.WeaponsDAT): self.weaponsdat = weaponsdat else: self.weaponsdat = DAT.WeaponsDAT(self.tbl) self.weaponsdat.load_file(weaponsdat) if isinstance(flingydat, DAT.FlingyDAT): self.flingydat = flingydat else: self.flingydat = DAT.FlingyDAT(self.tbl) self.flingydat.load_file(flingydat) if isinstance(imagesdat, DAT.ImagesDAT): self.imagesdat = imagesdat else: self.imagesdat = DAT.ImagesDAT(self.tbl) self.imagesdat.load_file(imagesdat) if isinstance(spritesdat, DAT.SpritesDAT): self.spritesdat = spritesdat else: self.spritesdat = DAT.SpritesDAT() self.spritesdat.load_file(spritesdat) if isinstance(soundsdat, DAT.SoundsDAT): self.soundsdat = soundsdat else: self.soundsdat = DAT.SoundsDAT() self.soundsdat.load_file(soundsdat) if isinstance(imagestbl, TBL.TBL): self.imagestbl = imagestbl else: self.imagestbl = TBL.TBL() self.imagestbl.load_file(imagestbl) if isinstance(sfxdatatbl, TBL.TBL): self.sfxdatatbl = sfxdatatbl else: self.sfxdatatbl = TBL.TBL() self.sfxdatatbl.load_file(sfxdatatbl)
def stattxt_value(self, type, value): if value == 65: return '%s in mapdata.tbl, item %s: None' % (type, value) return '%s in mapdata.tbl, item %s: %s' % ( type, value, TBL.decompile_string(self.tbl.strings[value]))
def stattxt_value(self, type, value): if value == 0: return '%s: None' % type return '%s in portdata.tbl, item %s: %s' % (type, value - 1, TBL.decompile_string(self.tbl.strings[value - 1]))
def __init__(self, stat_txt=None): if stat_txt == None: stat_txt = os.path.join(BASE_DIR, 'Libs', 'MPQ', 'rez', 'stat_txt.tbl') if isstr(stat_txt): self.tbl = TBL.TBL() self.tbl.load_file(stat_txt) else: self.tbl = stat_txt self.entries = [[0] * len(self.labels) for _ in range(self.count)] if self.datname == 'units.dat': self.data = [ [[self.dat_value, 'Flingy'], ''], [[self.dat_value, 'Units'], ''], [[self.dat_value, 'Units'], ''], [[self.dat_value, 'Units'], ''], [[self.dat_value, 'Images'], ''], [[None, ''], ''], [[None, ''], ''], [[None, ''], ''], [[None, ''], ''], [[self.info_value, 'ElevationLevels'], ''], [[None, ''], 'Old Movement?: 0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80 (Mine-safe)' ], [[self.stattxt_value, 'Sublabel'], ''], [[self.dat_value, 'Orders'], ''], [[self.dat_value, 'Orders'], ''], [[self.dat_value, 'Orders'], ''], [[self.dat_value, 'Orders'], ''], [[self.dat_value, 'Orders'], ''], [[self.dat_value, 'Weapons'], ''], [[None, ''], ''], [[self.dat_value, 'Weapons'], ''], [[None, ''], ''], [[None, ''], ''], [[None, ''], 'Building,Addon,Flyer,Worker,Subunit,"Flying Building",Hero,"Regenerates HP","Animated Idle(?)",Cloakable,"Two Units in 1 Egg","Single Entity","Resource Depot","Resource Container","Robotic Unit",Detector,"Organic Unit","Requires Creep",Unused(?),"Requires Psi",Burrowable,Spellcaster,"Permanent Cloak","Pickup Item(?)","Ignore Supply Check","Use Medium Overlays","Use Large Overlays","Battle Reactions","Full Auto-Attack",Invincible,"Mechanical Unit","Produces Units(?)"' ], [[None, ''], ''], [[None, ''], 'StarCraft crashes with values above 11'], [[self.dat_value, 'Upgrades'], ''], [[self.info_value, 'UnitSize'], ''], [[None, ''], ''], [[self.info_value, 'Rightclick'], ''], [[self.dat_value, 'Sfxdata'], ''], [[self.dat_value, 'Sfxdata'], ''], [[self.dat_value, 'Sfxdata'], ''], [[self.dat_value, 'Sfxdata'], ''], [[self.dat_value, 'Sfxdata'], ''], [[self.dat_value, 'Sfxdata'], ''], [[self.dat_value, 'Sfxdata'], ''], [[None, ''], ''], [[None, ''], ''], [[None, ''], 'X Position'], [[None, ''], 'Y Position'], [[None, ''], ''], [[None, ''], ''], [[None, ''], ''], [[None, ''], ''], [[self.dat_value, 'Portdata'], ''], [[None, ''], ''], [[None, ''], ''], [[self.time_value, ''], ''], [[None, ''], ''], [[None, ''], 'Zerg,Terran,Protoss,Men,Building,Factory,Independent,Neutral' ], [[None, ''], ''], [[None, ''], ''], [[None, ''], ''], [[None, ''], ''], [[None, ''], ''], [[None, ''], ''], [[None, ''], ''], [[None, ''], ''], [[None, ''], 'Non-Neutral,"Unit Listing&&Palette","Mission Briefing","Player Settings","All Races","Set Doodad State","Non-Location Triggers","Unit&&Hero Settings","Location Triggers","BroodWar Only","Unused (0x400)","Unused (0x800)","Unused (0x1000)","Unused (0x2000)","Unused (0x4000)","Unused (0x8000)"' ] ] self.special = {'HitPoints': self.hitpoints}
def decompile(self, file, reference=False, ids=None): if isstr(file): try: f = AtomicWriter(file, 'w') except: raise PyMSError('Decompile',"Could not load file '%s'" % file, warnings=warnings) else: f = file if ids == None: ids = self.headers.keys() longheader = max([len(h[0]) for h in HEADER] + [13]) + 1 longopcode = max([len(o[0][0]) for o in OPCODES] + [13]) + 1 warnings = [] labels = {} completed = [] def setlabel(o,local,entry): entry = re.sub('[\\/\\(\\)-]','_',entry.replace(' ','').replace("'",'')) f = [] for i in self.offsets[o]: if isinstance(i,list) and i[0] == id: f.append(i[1]) if f: f.sort() labels[o] = entry + HEADER[f[0]][0] return 0 labels[o] = entry + 'Local' + str(local).zfill(2) return 1 def decompile_offset(o,code,local,id): if id in self.extrainfo: entry = self.extrainfo[id].replace(' ','_') elif id < len(DAT.DATA_CACHE['IscriptIDList.txt']): entry = DAT.DATA_CACHE['IscriptIDList.txt'][id] else: entry = 'Unnamed Custom Entry' if not o in completed: completed.append(o) if not o in labels: labels[o] = re.sub('[\\/\\(\\)-]','_',entry.replace(' ','').replace("'",'')) + 'Local%s' % local local += 1 code += labels[o] + ':\n' curcmd = self.code.index(o) # print '\t%s' % o donext = [] while True: # print curcmd co = self.code.getkey(curcmd) # print co if co in self.offsets and not co in labels: local += setlabel(co,local,entry) completed.append(co) code += '%s:\n' % labels[co] cmd = self.code.getitem(curcmd) c = OPCODES[cmd[0]][0][0] if cmd[0] == 7: if not cmd[1] in labels: local += setlabel(cmd[1],local,entry) code += ' %s%s %s\n\n' % (c,' ' * (longopcode-len(c)),labels[cmd[1]]) code,local,curcmd = decompile_offset(cmd[1],code,local,id) break elif cmd[0] in [22,54]: #end,return code += ' %s\n\n' % c break elif cmd[0] in [30,53,57,58,59,60,63]: #randcondjump,call,pwrupcondjmp,trgtrangecondjmp,trgtarccondjmp,curdirectcondjmp,liftoffcondjump if cmd[-1] not in labels: local += setlabel(cmd[-1],local,entry) if not cmd[-1] in donext: donext.append(cmd[-1]) extra = [] code += ' %s%s ' % (c,' ' * (longopcode-len(c))) for v,t in zip(cmd[1:-1],OPCODES[cmd[0]][1][:-1]): p,e = t(1,self,v) if e: extra.append(e) code += p + ' ' code += labels[cmd[-1]] if extra: code = code[:-1] + '\t# ' + ' | '.join(extra) code += '\n' curcmd += 1 else: extra = [] code += ' ' + c if OPCODES[cmd[0]][1]: code += ' ' * (longopcode-len(c)) + '\t' d,o = cmd[1:],OPCODES[cmd[0]][1] if OPCODES[cmd[0]][1][0](0,self) == -1: n = OPCODES[cmd[0]][1][0](1,self,d[0])[0] code += n + ' ' o = [OPCODES[cmd[0]][1][1]] * int(n) del d[0] for v,t in zip(d,o): p,e = t(1,self,v) if e: extra.append(e) code += p + ' ' if extra: code = code[:-1] + '\t# ' + ' | '.join(extra) code += '\n' curcmd += 1 if donext: for d in donext: code,local,curcmd = decompile_offset(d,code,local,id) return (code,local,curcmd) return (code,local,-1) usedby = {} for i in range(DAT.ImagesDAT.count): id = self.imagesdat.get_value(i, 'IscriptID') if id in ids: if not id in usedby: usedby[id] = '# This header is used by images.dat entries:\n' usedby[id] += '# %s %s (%s)\n' % (str(i).zfill(3), DAT.DATA_CACHE['Images.txt'][i], TBL.decompile_string(self.imagestbl.strings[self.imagesdat.get_value(i,'GRPFile')-1][:-1])) invalid = [] unknownid = 0 for id in ids: code = '' local = 0 if not id in self.headers: invalid.append(id) continue type, offset, header = self.headers[id] u = '' if id in usedby: u = usedby[id] f.write('# ----------------------------------------------------------------------------- #\n%s.headerstart\nIsId %s\nType %s\n' % (u, id, type)) for o,l in zip(header,HEADER[:ENTRY_TYPES[type]]): if o == None: label = '[NONE]' elif o in labels: label = labels[o] else: if id in self.extrainfo: entry = self.extrainfo[id].replace(' ','_') elif id < len(DAT.DATA_CACHE['IscriptIDList.txt']): entry = DAT.DATA_CACHE['IscriptIDList.txt'][id] else: entry = 'Unnamed Custom Entry' local += setlabel(o,local,entry) label = labels[o]#'%s%s' % (DAT.DATA_CACHE['IscriptIDList.txt'][id],l[0]) f.write('%s%s %s\n' % (l[0],' ' * (longheader-len(l[0])),label)) if o != None: code,local,curcmd = decompile_offset(o,code,local,id) if id in self.extrainfo: f.write('##Name: %s\n' % self.extrainfo[id]) f.write('.headerend\n# ----------------------------------------------------------------------------- #\n\n' + code) f.close()
def interpret_data(self, data): lines = re.split('(?:\r?\n)+', data) widgets = [] smks = {} backfill_smks = {} working = None remastered = False def get_smk(smk_id): smk = None if smk_id in smks: smk = smks[smk_id] else: if not smk_id in backfill_smks: backfill_smks[smk_id] = [] backfill_smks[smk_id].append(working) return smk for n, raw_line in enumerate(lines): line = raw_line.split('#', 1)[0].strip() if not line: continue if line == 'Widget:': working = BINWidget() widgets.append(working) continue m = re.match('^SMK (\d+):$', line) if m: smk_id = int(m.group(1)) if smk_id in smks: raise PyMSError('Interpreting', "Duplicate definition for SMK '%s'" % attr, n, line) working = BINSMK() if smk_id in backfill_smks: for obj in backfill_smks[smk_id]: if isinstance(obj, BINWidget): obj.smk = working else: obj.overlay_smk = working del backfill_smks[smk_id] smks[smk_id] = working continue if not working: raise PyMSError( 'Interpreting', 'Unexpected line, expected a Widget or SMK header', n, line) m = re.match('^(\S+)(?:\s+(.+))?$', line) attr = m.group(1) value = m.group(2) if isinstance(working, BINWidget): if not attr in BINWidget.ATTR_NAMES_REMASTERED: raise PyMSError( 'Interpreting', "Invalid Widget attribute name '%s'" % attr, n, line) if attr == 'smk': if value == 'None': value = None else: try: smk_id = int(value) except: raise PyMSError( 'Interpreting', "Invalid SMK id '%s', expected an Integer or 'None'" % value, n, line) value = get_smk(smk_id) elif attr == 'string': if value == None: value = '' else: value = TBL.compile_string(value) elif attr == 'flags': # todo: try catch value = flags(value, 27) else: # todo: try catch value = int(value) if attr in BINWidget.ATTR_NAMES_REMASTERED and not attr in BINWidget.ATTR_NAMES: remastered = True else: if not attr in BINSMK.ATTR_NAMES: raise PyMSError('Interpreting', "Invalid SMK attribute name '%s'" % attr, n, line) if attr == 'overlay_smk': if value == 'None': value = None else: try: smk_id = int(value) except: raise PyMSError( 'Interpreting', "Invalid SMK id '%s', expected an Integer or 'None'" % value, n, line) value = get_smk(smk_id) elif attr == 'filename': value = TBL.compile_string(value) elif attr == 'flags': value = flags(value, 5) else: value = int(value) setattr(working, attr, value) if backfill_smks: raise PyMSError('Interpreting', "SMK %s is missing" % backfill_smks.keys()[0]) for i in xrange(len(widgets)): widget = widgets[i] if widget.type == BINWidget.TYPE_DIALOG: del widgets[i] widgets.insert(i, widget) break else: raise PyMSError('Interpreting', 'No dialog found.') self.widgets = widgets self.smks = list( smk for i, smk in sorted(smks.iteritems(), key=lambda s: s[1])) self.remastered = remastered
def decompile(self, file, reference=False, ids=None): if isstr(file): try: f = open(file, 'w') except: raise PyMSError('Decompile',"Could not load file '%s'" % file, warnings=warnings) else: f = file if ids == None: ids = self.header.keys() longheader = max([len(h[0]) for h in HEADER] + [13]) + 1 longopcode = max([len(o[0][0]) for o in OPCODES] + [13]) + 1 warnings = [] labels = {} completed = [] def setlabel(o,local,entry): entry = re.sub('[\\/\\(\\)-]','_',entry.replace(' ','').replace("'",'')) f = [] for i in self.offsets[o]: if isinstance(i,list) and i[0] == id: f.append(i[1]) if f: f.sort() labels[o] = entry + HEADER[f[0]][0] return 0 labels[o] = entry + 'Local' + str(local).zfill(2) return 1 def decompile_offset(o,code,local,id): if id in self.extrainfo: entry = self.extrainfo[id].replace(' ','_') elif id < len(DAT.DATA_CACHE['IscriptIDList.txt']): entry = DAT.DATA_CACHE['IscriptIDList.txt'][id] else: entry = 'Unnamed Custom Entry' if not o in completed: completed.append(o) if not o in labels: labels[o] = re.sub('[\\/\\(\\)-]','_',entry.replace(' ','').replace("'",'')) + 'Local%s' % local local += 1 code += labels[o] + ':\n' curcmd = self.code.index(o) # print '\t%s' % o donext = [] while True: # print curcmd co = self.code.getkey(curcmd) # print co if co in self.offsets and not co in labels: local += setlabel(co,local,entry) completed.append(co) code += '%s:\n' % labels[co] cmd = self.code.getitem(curcmd) c = OPCODES[cmd[0]][0][0] if cmd[0] == 7: if not cmd[1] in labels: local += setlabel(cmd[1],local,entry) code += ' %s%s %s\n\n' % (c,' ' * (longopcode-len(c)),labels[cmd[1]]) code,local,curcmd = decompile_offset(cmd[1],code,local,id) break elif cmd[0] in [22,54]: #end,return code += ' %s\n\n' % c break elif cmd[0] in [30,53,57,58,59,60,63]: #randcondjump,call,pwrupcondjmp,trgtrangecondjmp,trgtarccondjmp,curdirectcondjmp,liftoffcondjump if cmd[-1] not in labels: local += setlabel(cmd[-1],local,entry) if not cmd[-1] in donext: donext.append(cmd[-1]) extra = [] code += ' %s%s ' % (c,' ' * (longopcode-len(c))) for v,t in zip(cmd[1:-1],OPCODES[cmd[0]][1][:-1]): p,e = t(1,self,v) if e: extra.append(e) code += p + ' ' code += labels[cmd[-1]] if extra: code = code[:-1] + '\t# ' + ' | '.join(extra) code += '\n' curcmd += 1 else: extra = [] code += ' ' + c if OPCODES[cmd[0]][1]: code += ' ' * (longopcode-len(c)) + '\t' d,o = cmd[1:],OPCODES[cmd[0]][1] if OPCODES[cmd[0]][1][0](0,self) == -1: n = OPCODES[cmd[0]][1][0](1,self,d[0])[0] code += n + ' ' o = [OPCODES[cmd[0]][1][1]] * int(n) del d[0] for v,t in zip(d,o): p,e = t(1,self,v) if e: extra.append(e) code += p + ' ' if extra: code = code[:-1] + '\t# ' + ' | '.join(extra) code += '\n' curcmd += 1 if donext: for d in donext: code,local,curcmd = decompile_offset(d,code,local,id) return (code,local,curcmd) return (code,local,-1) usedby = {} for i in range(DAT.ImagesDAT.count): id = self.imagesdat.get_value(i, 'IscriptID') if id in ids: if not id in usedby: usedby[id] = '# This header is used by images.dat entries:\n' usedby[id] += '# %s %s (%s)\n' % (str(i).zfill(3), DAT.DATA_CACHE['Images.txt'][i], TBL.decompile_string(self.imagestbl.strings[self.imagesdat.get_value(i,'GRPFile')-1][:-1])) invalid = [] unknownid = 0 for id in ids: code = '' local = 0 if not id in self.headers: invalid.append(id) continue type, offset, header = self.headers[id] u = '' if id in usedby: u = usedby[id] f.write('# ----------------------------------------------------------------------------- #\n%s.headerstart\nIsId %s\nType %s\n' % (u, id, type)) for o,l in zip(header,HEADER[:ENTRY_TYPES[type]]): if o == None: label = '[NONE]' elif o in labels: label = labels[o] else: if id in self.extrainfo: entry = self.extrainfo[id].replace(' ','_') elif id < len(DAT.DATA_CACHE['IscriptIDList.txt']): entry = DAT.DATA_CACHE['IscriptIDList.txt'][id] else: entry = 'Unnamed Custom Entry' local += setlabel(o,local,entry) label = labels[o]#'%s%s' % (DAT.DATA_CACHE['IscriptIDList.txt'][id],l[0]) f.write('%s%s %s\n' % (l[0],' ' * (longheader-len(l[0])),label)) if o != None: code,local,curcmd = decompile_offset(o,code,local,id) if id in self.extrainfo: f.write('##Name: %s\n' % self.extrainfo[id]) f.write('.headerend\n# ----------------------------------------------------------------------------- #\n\n' + code) f.close()
def stattxt_value(self, type, value): if type == 'Sublabel': value += 1301 return '%s in stat_txt.tbl, item %s: %s' % ( type, value, TBL.decompile_string(self.tbl.strings[value]))
def stattxt_value(self, type, value): if type == 'Sublabel': value += 1301 return '%s in stat_txt.tbl, item %s: %s' % (type, value, TBL.decompile_string(self.tbl.strings[value]))
def stattxt_value(self, type, value): if value == 0: return '%s: None' % type return '%s in portdata.tbl, item %s: %s' % ( type, value - 1, TBL.decompile_string(self.tbl.strings[value - 1]))
def stattxt_value(self, type, value): if value == 65: return '%s in mapdata.tbl, item %s: None' % (type, value) return '%s in mapdata.tbl, item %s: %s' % (type, value, TBL.decompile_string(self.tbl.strings[value]))
def interpret_data(self, data): lines = re.split('(?:\r?\n)+', data) widgets = [] smks = {} backfill_smks = {} working = None def get_smk(smk_id): smk = None if smk_id in smks: smk = smks[smk_id] else: if not smk_id in backfill_smks: backfill_smks[smk_id] = [] backfill_smks[smk_id].append(working) return smk for n,raw_line in enumerate(lines): line = raw_line.split('#',1)[0].strip() if not line: continue if line == 'Widget:': working = BINWidget() widgets.append(working) continue m = re.match('^SMK (\d+):$', line) if m: smk_id = int(m.group(1)) if smk_id in smks: raise PyMSError('Interpreting',"Duplicate definition for SMK '%s'" % attr,n,line) working = BINSMK() if smk_id in backfill_smks: for obj in backfill_smks[smk_id]: if isinstance(obj, BINWidget): obj.smk = working else: obj.overlay_smk = working del backfill_smks[smk_id] smks[smk_id] = working continue if not working: raise PyMSError('Interpreting','Unexpected line, expected a Widget or SMK header',n,line) m = re.match('^(\S+)(?:\s+(.+))?$', line) attr = m.group(1) value = m.group(2) if isinstance(working, BINWidget): if not attr in BINWidget.ATTR_NAMES: raise PyMSError('Interpreting',"Invalid Widget attribute name '%s'" % attr,n,line) if attr == 'smk': if value == 'None': value = None else: try: smk_id = int(value) except: raise PyMSError('Interpreting',"Invalid SMK id '%s', expected an Integer or 'None'" % value,n,line) value = get_smk(smk_id) elif attr == 'string': if value == None: value = '' else: value = TBL.compile_string(value) elif attr == 'flags': # todo: try catch value = flags(value, 27) else: # todo: try catch value = int(value) else: if not attr in BINSMK.ATTR_NAMES: raise PyMSError('Interpreting',"Invalid SMK attribute name '%s'" % attr,n,line) if attr == 'overlay_smk': if value == 'None': value = None else: try: smk_id = int(value) except: raise PyMSError('Interpreting',"Invalid SMK id '%s', expected an Integer or 'None'" % value,n,line) value = get_smk(smk_id) elif attr == 'filename': value = TBL.compile_string(value) elif attr == 'flags': value = flags(value, 5) else: value = int(value) setattr(working, attr, value) if backfill_smks: raise PyMSError('Interpreting',"SMK %s is missing" % backfill_smks.keys()[0]) for i in xrange(len(widgets)): widget = widgets[i] if widget.type == BINWidget.TYPE_DIALOG: del widgets[i] widgets.insert(i,widget) break else: raise PyMSError('Interpreting','No dialog found.') self.widgets = widgets self.smks = list(smk for i,smk in sorted(smks.iteritems(),key=lambda s: s[1]))