Beispiel #1
0
 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
Beispiel #2
0
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
Beispiel #3
0
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
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
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
Beispiel #8
0
	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
Beispiel #9
0
	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)
Beispiel #10
0
 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]))
Beispiel #11
0
	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]))
Beispiel #12
0
 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}
Beispiel #13
0
	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()
Beispiel #14
0
    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
Beispiel #15
0
	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()
Beispiel #16
0
 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]))
Beispiel #17
0
	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]))
Beispiel #18
0
 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]))
Beispiel #19
0
	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]))
Beispiel #20
0
	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]))