Exemple #1
0
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["textureDetails"] = self.read.byte()
        tmpData["nibble2"] = self.read.byte()
        
        return tmpData
Exemple #2
0
class ObjectReader():
    from DataReader import DataReader

    #These are the file extentions that have more reading

    #This is to
    OptionalInts = [
            "w3d",
            "w3a",
            "w3q"
    ]
    variableTypes = []
    def __init__(self, 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()
        if filename.split(".")[1] in self.OptionalInts:
            modInfo["level"] = self.read.int()
            modInfo["pointer"] = self.read.int()
        print(varType)
        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
Exemple #3
0
    def read_header(self):
        """Read the header of a MPQ archive."""

        def read_mpq_header(offset=None):
            if offset:
                self.file.seek(offset)
            data = self.file.read(32)
            header = MPQFileHeader._make(
                struct.unpack(MPQFileHeader.struct_format, data))
            header = header._asdict()
            
            if header['format_version'] == 1:
                
                data = self.file.read(12)
                extended_header = MPQFileHeaderExt._make(
                    struct.unpack(MPQFileHeaderExt.struct_format, data))
                header.update(extended_header._asdict())
            return header

        def read_mpq_user_data_header():
            data = self.file.read(16)
            header = MPQUserDataHeader._make(
                struct.unpack(MPQUserDataHeader.struct_format, data))
            header = header._asdict()
            header['content'] = self.file.read(header['user_data_header_size'])
            return header

        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()
            """
            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.read(512 - datReader.index)
            print ("Now position:", self.file.tell())
        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':
            header.update(read_mpq_header())
            header['offset'] = 512
        elif magic == b'MPQ\x1b':
            user_data_header = read_mpq_user_data_header()
            header.update(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