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
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 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_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