class ReadPathFile: def __init__(self, filename): self.read = DataReader(filename) self.info = {} self.__work__() def __work__(self): self.info["fileID"] = self.read.charArray(4) #usually MP3W self.info["fileVersion"] = self.read.int() #usually 0 self.info["pathWidth"] = self.read.int() #mapWidth * 4 self.info["pathHeight"] = self.read.int() #mapHeight * 4 self.info["info"] = [] for x in xrange(0,self.info["pathWidth"]): xInfo = [] for y in xrange(0,self.info["pathHeight"]): xInfo.append(self.read.byte()) ''' 0x01: 0 (unused) 0x02: 1=no walk, 0=walk ok 0x04: 1=no fly, 0=fly ok 0x08: 1=no build, 0=build ok 0x10: 0 (unused) 0x20: 1=blight, 0=normal 0x40: 1=no water, 0=water 0x80: 1=unknown, 0=normal ''' self.info["info"].append(xInfo)
def read_MenuMinimap(filehandle): read = DataReader(filehandle) menuMinimapInfo = [] unknown = read.int() count = read.int() for i in xrange(0, count): info = {} info["type"] = read.int() ''' Types: 0: goldmine 1: house 2: player start (cross) ''' info["x"] = read.int() info["y"] = read.int() info["blue"] = read.byte() info["green"] = read.byte() info["red"] = read.byte() info["alpha"] = read.byte() menuMinimapInfo.append(info) return menuMinimapInfo
class ObjectReader(): #These are the file extentions that have more reading OptionalInts = [ "w3d", "w3a", "w3q" ] variableTypes = [] def __init__(self, filename): self.filename = filename self.read = DataReader(filename) self.variableTypes = [ self.read.int, self.read.float, self.read.float, self.read.string ] self.fileVersion = self.read.int() self.originalInfo = self.readTable() self.customInfo = self.readTable() def readMod(self): modInfo = {} modInfo["ID"] = self.read.charArray(4) varType = self.read.int() fileSplit = self.filename.split(".") if fileSplit[len(fileSplit)-1] in self.OptionalInts: modInfo["level"] = self.read.int() modInfo["pointer"] = self.read.int() modInfo["value"] = self.variableTypes[varType]() self.read.int() #verify / end thing return modInfo def readObject(self): objectData = {} objectData["oldID"] = self.read.charArray(4) objectData["newID"] = self.read.charArray(4) modCount = self.read.int() objectData["mods"] = [] for i in xrange(modCount): objectData["mods"].append(self.readMod()) return objectData def readTable(self): tmpLen = self.read.int() tmpInfo = [] if tmpLen > 0: for i in xrange(tmpLen): tmpInfo.append(self.readObject()) return tmpInfo
def read_MenuMinimap(filehandle): read = DataReader(filehandle) menuMinimapInfo = [] unknown = read.int() count = read.int() for i in xrange(0,count): info = {} info["type"] = read.int() ''' Types: 0: goldmine 1: house 2: player start (cross) ''' info["x"] = read.int() info["y"] = read.int() info["blue"] = read.byte() info["green"] = read.byte() info["red"] = read.byte() info["alpha"] = read.byte() menuMinimapInfo.append(info) return menuMinimapInfo
def read_WPM(filehandle): read = DataReader(filehandle) pathInfo = {} pathInfo["fileID"] = read.charArray(4) #usually MP3W pathInfo["fileVersion"] = read.int() #usually 0 pathInfo["pathWidth"] = read.int() #mapWidth * 4 pathInfo["pathHeight"] = read.int() #mapHeight * 4 pathInfo["info"] = [] for x in xrange(pathInfo["pathWidth"]): xInfo = [] for y in xrange(pathInfo["pathHeight"]): xInfo.append(read.byte()) ''' 0x01: 0 (unused) 0x02: 1=no walk, 0=walk ok 0x04: 1=no fly, 0=fly ok 0x08: 1=no build, 0=build ok 0x10: 0 (unused) 0x20: 1=blight, 0=normal 0x40: 1=no water, 0=water 0x80: 1=unknown, 0=normal ''' pathInfo["info"].append(xInfo) return pathInfo
def __read_generic_object__(filehandle, filetype, triggerDB = None): read = DataReader(filehandle) if triggerDB != None: read.load_triggerDB(triggerDB) #variableTypes = [ # read.int, # read.float, # read.float, # read.string #] fileVersion = read.int() originalInfo = __readTable__(read, filetype) customInfo = __readTable__(read, filetype) data = {"fileVersion" : fileVersion, "originalInfo" : originalInfo, "customInfo" : customInfo} return data
def read_WPM(filehandle): read = DataReader(filehandle) pathInfo = {} pathInfo["fileID"] = read.charArray(4) #usually MP3W pathInfo["fileVersion"] = read.int() #usually 0 pathInfo["pathWidth"] = read.int() #mapWidth * 4 pathInfo["pathHeight"] = read.int() #mapHeight * 4 pathInfo["info"] = [] for x in xrange( pathInfo["pathWidth"] ): xInfo = [] for y in xrange( pathInfo["pathHeight"] ): xInfo.append( read.byte() ) ''' 0x01: 0 (unused) 0x02: 1=no walk, 0=walk ok 0x04: 1=no fly, 0=fly ok 0x08: 1=no build, 0=build ok 0x10: 0 (unused) 0x20: 1=blight, 0=normal 0x40: 1=no water, 0=water 0x80: 1=unknown, 0=normal ''' pathInfo["info"].append(xInfo) return pathInfo
def __init__(self, filename): self.filename = filename self.read = DataReader(filename) self.variableTypes = [ self.read.int, self.read.float, self.read.float, self.read.string ] self.fileVersion = self.read.int() self.originalInfo = self.readTable() self.customInfo = self.readTable()
def __read_generic_object__(filehandle, filetype, triggerDB=None): read = DataReader(filehandle) if triggerDB != None: read.load_triggerDB(triggerDB) #variableTypes = [ # read.int, # read.float, # read.float, # read.string #] fileVersion = read.int() originalInfo = __readTable__(read, filetype) customInfo = __readTable__(read, filetype) data = { "fileVersion": fileVersion, "originalInfo": originalInfo, "customInfo": customInfo } return data
def read_doodad(filehandle): read = DataReader(filehandle) doodHeader = __read_header__(read) doodInfo = {} doodInfo["fileID"] = doodHeader[0] doodInfo["version"] = doodHeader[1] doodInfo["subversion"] = doodHeader[2] doodInfo["count"] = doodHeader[3] #print "File ID: {0}, Version: {1}, Subversion: {2}".format(doodInfo["fileID"], # doodInfo["version"], # doodInfo["subversion"]) #print "Reading {0} trees".format(doodInfo["count"]) doodInfo["trees"] = [] for i in xrange(0, doodInfo["count"]): doodInfo["trees"].append(__read_treedata__(read)) doodInfo["special"] = __read_specialdoodads__(read) return doodInfo
def __init__(self, filename): self.read = DataReader(filename)
def __init__(self, filename): self.read = DataReader(filename) self.info = {} self.__work__()
class ReadDoodad: def __init__(self, filename): self.read = DataReader(filename) self.info = self.ReadDoodad() def ReadDoodad(self): doodHeader = self.ReadHeader() doodInfo = {} doodInfo["fileID"] = doodHeader[0] doodInfo["version"] = doodHeader[1] doodInfo["subversion"] = doodHeader[2] doodInfo["count"] = doodHeader[3] print "File ID: {0}, Version: {1}, Subversion: {2}".format(doodInfo["fileID"], doodInfo["version"], doodInfo["subversion"]) print "Reading {0} trees".format(doodInfo["count"]) doodInfo["trees"] = [] for i in xrange(0, doodInfo["count"]): doodInfo["trees"].append(self.ReadTreeData()) doodInfo["special"] = self.ReadSpecialDoodads() return doodInfo def ReadHeader(self): fileID = self.read.charArray(4) version = self.read.int() subversion = self.read.int() count = self.read.int() return fileID, version, subversion, count def ReadTreeData(self): treeInfo = { "treeID" : self.read.charArray(4), "variation" : self.read.int(), "coord" : { "x" : self.read.float(), "y" : self.read.float(), "z" : self.read.float() }, "angle" : self.read.float(), "scale" : { "x" : self.read.float(), "y" : self.read.float(), "z" : self.read.float() }, "flags" : self.read.byte(), "life" : self.read.byte() } treeInfo["itemPoint"] = self.read.int() treeInfo["numberOfItemSets"] = self.read.int() if treeInfo["numberOfItemSets"] > 0: treeInfo["itemSets"] = [] ## Reading Item Set for i in xrange(treeInfo["numberOfItemSets"]): numberOfItems = self.read.int() itemSet = [] ## Each Item Set has a Number of Items for j in xrange(numberOfItems): itemID = self.read.charArray(4) procentualChance = self.read.int() itemSet.append((itemID, procentualChance)) treeInfo["itemSets"].append(itemSet) treeInfo["doodID"] = self.read.int() return treeInfo def ReadSpecialDoodads(self): specialInfo = {} specialInfo["version"] = self.read.int() specialInfo["count"] = self.read.int() specialInfo["info"] = [] print "Reading special doodads. Version: {0}, Count: {1}".format(specialInfo["version"], specialInfo["count"]) for i in xrange(specialInfo["count"]): ID = self.read.charArray(4) z, x, y = self.read.int(), self.read.int(), self.read.int() specialInfo["info"].append({"ID" : ID, "x" : x,"y" : y, "z" : z}) return specialInfo
def __init__(self, filename): self.read = DataReader(filename) self.info = self.ReadDoodad()
class ReadW3E(): def __init__(self, filename): self.read = DataReader(filename) self.mapInfo = self.ReadMap() def ReadMap(self): mapInfo = self.ReadHeader() mapInfo["info"] = [] for i in xrange((mapInfo["width"])*(mapInfo["height"])): mapInfo["info"].append(self.ReadTile()) return mapInfo def ReadHeader(self): data = {} data["fileID"] = self.read.charArray(4) data["formatVersion"] = self.read.int() data["mainTileSet"] = self.read.char() data["customTileSet"] = self.read.int() #actually is a boolean data["groundTileSets"] = self.ReadTileset() data["cliffTileSets"] = self.ReadTileset() data["width"] = self.read.int() data["height"] = self.read.int() data["offsetX"] = self.read.float() data["offsetY"] = self.read.float() return data def ReadTileset(self): length = self.read.int() info = [] for i in range(0,length): info.append(self.read.charArray(4)) return info def ReadTile(self): tmpData = {} tmpData["groundHeight"] = self.read.short() tmpData["waterLevel"] = self.read.short() #bit 15 is used for boundary flag 1 #tmpData["nibble1"] = self.read.byte() tmpData["flags"], tmpData["groundTextureType"] = self.read.nibbles() tmpData["textureDetails"] = self.read.byte() #tmpData["nibble2"] = self.read.byte() tmpData["cliffTextureType"], tmpData["layerHeight"] = self.read.nibbles() return tmpData
def __init__(self, filename): self.read = DataReader(filename) self.mapInfo = self.ReadMap()
def read_W3E(filehandle): read = DataReader(filehandle) mapinfo = __read_map__(read) return mapinfo
def read_W3I(filehandle, triggerStrings = None): # def ReadFile(self): # self.info = {} # self.ReadInfo() read = DataReader(filehandle) if triggerStrings != None: read.load_triggerDB(triggerStrings) info = {} info["version"] = read.int() #print info["version"] info["saveCount"] = read.int() info["editVersion"] = read.int() info["name"] = read.string() info["author"] = read.string() info["description"] = read.string() info["recommendedPlayers"] = read.string() info["cameraBounds"] = [ read.float(), #1 read.float(), #2 read.float(), #3 read.float(), #4 read.float(), #5 read.float(), #6 read.float(), #7 read.float() #8 ] info["cameraComplements"] = [ read.int(), read.int(), read.int(), read.int() ] info["playWidth"] = read.int() info["playHeight"] = read.int() info["flags"] = read.flags() info["groundType"] = read.char() info["backgroundImageID"] = read.int() #-1 == none or custom, info["customLoadingScreen"] = read.string() #empty if none or not custom, info["loadingText"] = read.string() info["loadingTitle"] = read.string() info["loadingSubtitle"] = read.string() info["gameDataSet"] = read.int() #index in the preset list, 0=standard, info["prologuePath"] = read.string() info["prologueText"] = read.string() info["prologueTitle"] = read.string() info["prologueSubtitle"] = read.string() info["useTerrainFog"] = read.int() #0 == not used, >0 = index of terrain fog style dropdown info["fogInfo"] = { "startZ" : read.float(), "endZ" : read.float(), "density" : read.float(), "red" : read.byte(), "green" : read.byte(), "blue" : read.byte(), "alpha" : read.byte() } info["weatherID"] = read.int() #0=none; else = the id is in TerrainArt\Weather.slk info["soundEnvironment"] = read.string() info["tilesetLightID"] = read.char() info["waterInfo"] = { "red" : read.byte(), "green" : read.byte(), "blue" : read.byte(), "alpha" : read.byte() } info["playerData"] = __ReadArray__(read, __readPlayerData__ ) try: info["forceData"] = __ReadArray__(read, __readForceData__ ) except struct.error: info["forceData"] = None try: info["upgradeData"] = __ReadArray__(read, __readUpgradeData__ ) except struct.error: info["upgradeData"] = None try: info["techData"] = __ReadArray__(read, __readTechData__ ) except struct.error: info["techData"] = None try: info["unitData"] = __ReadArray__(read, __readUnitData__ ) except struct.error: info["unitData"] = None #print info["playerData"] #print info["forceData"] #print info["upgradeData"] #print info["techData"] #print info["unitData"] try: info["itemData"] = __ReadArray__(read, __readItemData__ ) except struct.error: info["itemData"] = None return info
def read_header(self): #"""Read the header of a MPQ archive.""" ## Read the header of a WC3 MPQ archive magic = self.file.read(4) self.file.seek(0) #print(magic) if magic == "HM3W": datReader = DataReader(self.file) header = {} ## should be HM3W header["wc3map_magic"] = datReader.charArray(4) ## unknown datReader.int() header["wc3map_mapName"] = datReader.string() print(header["wc3map_mapName"]) """ 0x0001: 1=hide minimap in preview screens 0x0002: 1=modify ally priorities 0x0004: 1=melee map 0x0008: 1=playable map size was large and has never been reduced to medium 0x0010: 1=masked area are partially visible 0x0020: 1=fixed player setting for custom forces 0x0040: 1=use custom forces 0x0080: 1=use custom techtree 0x0100: 1=use custom abilities 0x0200: 1=use custom upgrades 0x0400: 1=map properties menu opened at least once since map creation 0x0800: 1=show water waves on cliff shores 0x1000: 1=show water waves on rolling shores """ header["wc3map_mapFlags"] = datReader.flags() header["wc3map_maxPlayers"] = datReader.int() self.file.seek(512) else: ## If the magic isn't HM3W, we will skip the first 512 bytes of the ## file anyway self.file.seek(512) print(self.file.tell()) magic = self.file.read(4) self.file.seek(512) print( len(magic)) print(magic, hex(ord(magic[3])) ) if magic == b'MPQ\x1a' or self.forceV1 == True: i = 1 while magic != "MPQ\x1a": i += 1 self.file.seek(512*i) magic = self.file.read(4) self.file.seek(512*i) header.update(self.__read_mpq_header__()) header['offset'] = 512*i elif magic == b'MPQ\x1b': user_data_header = self.__read_mpq_user_data_header__() header.update(self.__read_mpq_header__(user_data_header['mpq_header_offset'])) header['offset'] = user_data_header['mpq_header_offset'] header['user_data_header'] = user_data_header else: raise ValueError("Invalid file header.") return header
class WC3Info: def __init__(self, filename): self.read = DataReader(filename) def ReadFile(self): self.info = {} self.ReadInfo() def ReadInfo(self): info = self.info info["version"] = self.read.int() print info["version"] info["saveCount"] = self.read.int() info["editVersion"] = self.read.int() info["name"] = self.read.string() info["author"] = self.read.string() info["description"] = self.read.string() info["recommendedPlayers"] = self.read.string() info["cameraBounds"] = [ self.read.float(), #1 self.read.float(), #2 self.read.float(), #3 self.read.float(), #4 self.read.float(), #5 self.read.float(), #6 self.read.float(), #7 self.read.float() #8 ] info["cameraComplements"] = [ self.read.int(), self.read.int(), self.read.int(), self.read.int() ] info["playWidth"] = self.read.int() info["playHeight"] = self.read.int() info["flags"] = self.read.flags() info["groundType"] = self.read.char() info["backgroundImageID"] = self.read.int() #-1 == none or custom, info["customLoadingScreen"] = self.read.string() #empty if none or not custom, info["loadingText"] = self.read.string() info["loadingTitle"] = self.read.string() info["loadingSubtitle"] = self.read.string() info["gameDataSet"] = self.read.int() #index in the preset list, 0=standard, info["prologuePath"] = self.read.string() info["prologueText"] = self.read.string() info["prologueTitle"] = self.read.string() info["prologueSubtitle"] = self.read.string() info["useTerrainFog"] = self.read.int() #0 == not used, >0 = index of terrain fog style dropdown info["fogInfo"] = { "startZ" : self.read.float(), "endZ" : self.read.float(), "density" : self.read.float(), "red" : self.read.byte(), "green" : self.read.byte(), "blue" : self.read.byte(), "alpha" : self.read.byte() } info["weatherID"] = self.read.int() #0=none, else is the id in TerrainArt\Weather.slk info["soundEnvironment"] = self.read.string() info["tilesetLightID"] = self.read.char() info["waterInfo"] = { "red" : self.read.byte(), "green" : self.read.byte(), "blue" : self.read.byte(), "alpha" : self.read.byte() } info["playerData"] = self.ReadArray(self.readPlayerData) info["forceData"] = self.ReadArray(self.readForceData) info["upgradeData"] = self.ReadArray(self.readUpgradeData) info["techData"] = self.ReadArray(self.readTechData) info["unitData"] = self.ReadArray(self.readUnitData) print info["playerData"] print info["forceData"] print info["upgradeData"] print info["techData"] print info["unitData"] info["itemData"] = self.ReadArray(self.readItemData) def ReadArray(self, func): print "Starting to read an array!" arrayInfo = {} arrayInfo["data"] = [] try: arrayInfo["count"] = self.read.int() except struct.error: arrayInfo["count"] = 0 print "Array does not exist. Function: {0}".format(func.__name__) return arrayInfo else: print "{0} elements in this array. Using {1} for reading.".format(arrayInfo["count"], func.__name__) for i in xrange(arrayInfo["count"]): data = func() arrayInfo["data"].append(data) return arrayInfo def readPlayerData(self): playerData = {} playerData["playerNumber"] = self.read.int() playerData["playerType"] = self.read.int() playerData["race"] = self.read.int() playerData["startPos"] = self.read.int() playerData["name"] = self.read.string() playerData["startX"] = self.read.float() playerData["startY"] = self.read.float() playerData["allyLowFlags"] = self.read.int() playerData["allyHighFlags"] = self.read.int() #print("###PLAYER DATA###") #print("PlayerType: "+str(playerData["playerType"])) #print("Race: "+str(playerData["race"])) #print("startPos "+str(playerData["startPos"])) return playerData def readForceData(self): forceData = {} forceData["flags"] = self.read.flags() forceData["mask"] = self.read.int() forceData["name"] = self.read.string() print(forceData) return forceData def readUpgradeData(self): upgradeData = {} upgradeData["flags"] = self.read.flags() upgradeData["id"] = self.read.charArray(4) upgradeData["level"] = self.read.int() upgradeData["Availability"] = self.read.int() return upgradeData def readTechData(self): techData = {} techData["flags"] = self.read.flags() techData["id"] = self.read.charArray(4) return techData def readUnitData(self): groupCount = self.read.int() for i in xrange(groupCount): groupInfo = {} groupInfo["number"] = self.read.int() groupInfo["name"] = self.read.string() groupInfo["posCount"] = self.read.int() #columns groupInfo["tableTypes"] = [] groupInfo["entities"] = [] for j in xrange(groupInfo["posCount"]): tableType = self.read.int() groupInfo["tableTypes"].append(tableType) groupInfo["unitCount"] = self.read.int() #rows for j in xrange(groupInfo["unitCount"]): entity = {} entity["chance"] = self.read.int() entity["ids"] = [self.read.charArray(4) for k in xrange(groupInfo["posCount"])] groupInfo["entities"].append(entity) return groupInfo def readItemData(self): itemInfo = {} itemInfo["tableCount"] = self.read.int() itemInfo["table"] = [] for i in xrange(itemInfo["tableCount"]): tableInfo = {} tableInfo["tableNumber"] = self.read.int() tableInfo["tableName"] = self.read.string() tableInfo["setCount"] = self.read.int() tableInfo["set"] = [] for j in xrange(tableInfo["setCount"]): setInfo = {} setInfo["itemCount"] = self.read.int() setInfo["items"] = [] for k in xrange(setInfo["itemCount"]): itemData = {} itemData["percentualChance"] = self.read.int() itemData["itemID"] = self.read.charArray(4) setInfo["items"].append(itemData) tableInfo["set"].append(setInfo) itemInfo["table"].append(tableInfo) return itemInfo
def read_W3I(filehandle, triggerStrings=None): # def ReadFile(self): # self.info = {} # self.ReadInfo() read = DataReader(filehandle) if triggerStrings != None: read.load_triggerDB(triggerStrings) info = {} info["version"] = read.int() #print info["version"] info["saveCount"] = read.int() info["editVersion"] = read.int() info["name"] = read.string() info["author"] = read.string() info["description"] = read.string() info["recommendedPlayers"] = read.string() info["cameraBounds"] = [ read.float(), #1 read.float(), #2 read.float(), #3 read.float(), #4 read.float(), #5 read.float(), #6 read.float(), #7 read.float() #8 ] info["cameraComplements"] = [ read.int(), read.int(), read.int(), read.int() ] info["playWidth"] = read.int() info["playHeight"] = read.int() info["flags"] = read.flags() info["groundType"] = read.char() info["backgroundImageID"] = read.int() #-1 == none or custom, info["customLoadingScreen"] = read.string() #empty if none or not custom, info["loadingText"] = read.string() info["loadingTitle"] = read.string() info["loadingSubtitle"] = read.string() info["gameDataSet"] = read.int() #index in the preset list, 0=standard, info["prologuePath"] = read.string() info["prologueText"] = read.string() info["prologueTitle"] = read.string() info["prologueSubtitle"] = read.string() info["useTerrainFog"] = read.int( ) #0 == not used, >0 = index of terrain fog style dropdown info["fogInfo"] = { "startZ": read.float(), "endZ": read.float(), "density": read.float(), "red": read.byte(), "green": read.byte(), "blue": read.byte(), "alpha": read.byte() } info["weatherID"] = read.int( ) #0=none; else = the id is in TerrainArt\Weather.slk info["soundEnvironment"] = read.string() info["tilesetLightID"] = read.char() info["waterInfo"] = { "red": read.byte(), "green": read.byte(), "blue": read.byte(), "alpha": read.byte() } info["playerData"] = __ReadArray__(read, __readPlayerData__) try: info["forceData"] = __ReadArray__(read, __readForceData__) except struct.error: info["forceData"] = None try: info["upgradeData"] = __ReadArray__(read, __readUpgradeData__) except struct.error: info["upgradeData"] = None try: info["techData"] = __ReadArray__(read, __readTechData__) except struct.error: info["techData"] = None try: info["unitData"] = __ReadArray__(read, __readUnitData__) except struct.error: info["unitData"] = None #print info["playerData"] #print info["forceData"] #print info["upgradeData"] #print info["techData"] #print info["unitData"] try: info["itemData"] = __ReadArray__(read, __readItemData__) except struct.error: info["itemData"] = None return info