def Save(self, cityXPos, cityYPos, heightMap, saveName): """Save a city read all entries create a save file replace the height,city info and region picture entry save all entries """ global generic_saveValue time.sleep(.1) self.heightMap = heightMap xSize = self.heightMap.shape[0] ySize = self.heightMap.shape[1] newData = QFS.encode(struct.pack('H', 0x2) + self.heightMap.tostring()) newData = struct.pack("l", len(newData)) + newData self.indexRecordPosition = 96 self.dateUpdated = int(time.time()) + generic_saveValue * 65535 generic_saveValue += 1 self.header = self.header[0:0x1C] + struct.pack( "I", self.dateUpdated) + self.header[0x1C + 4:0x28] + struct.pack( "l", self.indexRecordPosition) + self.header[0x28 + 4:96] self.sc4 = open(self.fileName, "rb") for entry in self.entries: if entry.IsItThisTGI( (0xA9DD6FF4, 0xE98F9525, 0x00000001)) or entry.IsItThisTGI( (0xCA027EDB, 0xCA027EE1, 0x00000000)): entry.ReadFile(self.sc4, True, True) if entry.rawContent == None: entry.ReadFile(self.sc4, True) self.sc4.close() while 1: try: self.sc4 = open(saveName, "wb") break except IOError: dlg = wx.MessageDialog( None, "file %s seems to be ReadOnly\nDo you want to skip?(Yes)\nOr retry ?(No)" % (saveName), "Warning", wx.YES_NO | wx.ICON_QUESTION) result = dlg.ShowModal() dlg.Destroy() if result == wx.ID_YES: return False self.sc4.write(self.header) self.sc4.truncate(self.indexRecordPosition) self.sc4.seek(self.indexRecordPosition) pos = self.indexRecordPosition + self.indexRecordLength for entry in self.entries: entry.fileLocation = pos newbuffer = entry.buffer[0:0x0C] + struct.pack( "l", entry.fileLocation) + entry.buffer[0x0C + 4:] if entry.IsItThisTGI( (0xA9DD6FF4, 0xE98F9525, 0x00000001)): #heights newbuffer = entry.buffer[0:0x0C] + struct.pack( "l", entry.fileLocation) + struct.pack( "l", len(newData)) + entry.buffer[0x10 + 4:] entry.rawContent = newData entry.compressed = 1 entry.filesize = len(newData) if entry.IsItThisTGI( (0xCA027EDB, 0xCA027EE1, 0x00000000)): #city info v = self.dateUpdated entry.content = entry.content[0:0x04] + struct.pack( "I", cityXPos) + struct.pack( "I", cityYPos) + entry.content[0x0C:39] + struct.pack( "I", v) + entry.content[39 + 4:] newDataCity = entry.rawContent[:] newDataCity = QFS.encode(entry.content) newDataCity = struct.pack("l", len(newDataCity)) + newDataCity newbuffer = entry.buffer[0:0x0C] + struct.pack( "l", entry.fileLocation) + struct.pack( "l", len(newDataCity)) + entry.buffer[0x10 + 4:] entry.rawContent = newDataCity entry.compressed = 1 entry.filesize = len(newDataCity) if entry.IsItThisTGI( (0x8a2482b9, 0x4a2482bb, 0x00000000)): #region view n = os.path.splitext(saveName)[0] png = open(n + ".PNG", "rb") pngData = png.read() png.close() os.unlink(n + ".PNG") newbuffer = entry.buffer[0:0x0C] + struct.pack( "I", entry.fileLocation) + struct.pack( "I", len(pngData)) + entry.buffer[0x10 + 4:] entry.rawContent = pngData entry.compressed = 0 entry.filesize = len(pngData) if entry.IsItThisTGI( (0x8a2482b9, 0x4a2482bb, 0x00000002)): #alpha region view n = os.path.splitext(saveName)[0] png = open(n + "_alpha.PNG", "rb") pngData = png.read() png.close() os.unlink(n + "_alpha.PNG") newbuffer = entry.buffer[0:0x0C] + struct.pack( "I", entry.fileLocation) + struct.pack( "I", len(pngData)) + entry.buffer[0x10 + 4:] entry.rawContent = pngData entry.compressed = 0 entry.filesize = len(pngData) self.sc4.write(newbuffer) pos += entry.filesize for entry in self.entries: self.sc4.write(entry.rawContent) self.sc4.close() return True
def ReadFile( self, sc4, readWhole = True , decompress = False ): self.rawContent = None if readWhole: sc4.seek( self.fileLocation ) self.rawContent = sc4.read( self.filesize ) if decompress: if len( self.rawContent ) >= 8: compress_sig = struct.unpack( "H", self.rawContent[ 0x04:0x04+2 ] )[0] if compress_sig == COMPRESSED_SIG: self.compressed = True if self.compressed: if decompress: print 'Compressed file' uncompress = QFS.decode( self.rawContent[4:] ) self.content = uncompress else: if decompress: print 'Uncompressed file' self.content = self.rawContent
def Save( self, cityXPos, cityYPos, heightMap, saveName ): """Save a city read all entries create a save file replace the height,city info and region picture entry save all entries """ global generic_saveValue time.sleep(.1) self.heightMap = heightMap xSize = self.heightMap.shape[0] ySize = self.heightMap.shape[1] newData = QFS.encode( struct.pack( 'H', 0x2 ) + self.heightMap.tostring() ) newData = struct.pack( "l", len( newData ) ) + newData self.indexRecordPosition = 96 self.dateUpdated = int( time.time() )+generic_saveValue*65535 generic_saveValue += 1 self.header = self.header[0:0x1C]+struct.pack( "I", self.dateUpdated )+self.header[0x1C+4:0x28]+struct.pack( "l", self.indexRecordPosition )+self.header[0x28+4:96] self.sc4 = open( self.fileName,"rb" ) for entry in self.entries: if entry.IsItThisTGI( (0xA9DD6FF4,0xE98F9525,0x00000001) ) or entry.IsItThisTGI( (0xCA027EDB, 0xCA027EE1, 0x00000000) ): entry.ReadFile( self.sc4, True, True ) if entry.rawContent == None: entry.ReadFile( self.sc4, True ) self.sc4.close() while 1: try: self.sc4 = open( saveName,"wb" ) break except IOError: dlg = wx.MessageDialog( None, "file %s seems to be ReadOnly\nDo you want to skip?(Yes)\nOr retry ?(No)"%(saveName),"Warning",wx.YES_NO|wx.ICON_QUESTION) result = dlg.ShowModal() dlg.Destroy() if result == wx.ID_YES: return False self.sc4.write( self.header ) self.sc4.truncate( self.indexRecordPosition ) self.sc4.seek( self.indexRecordPosition ) pos = self.indexRecordPosition + self.indexRecordLength for entry in self.entries: entry.fileLocation = pos newbuffer = entry.buffer[ 0 : 0x0C ] + struct.pack( "l", entry.fileLocation ) + entry.buffer[ 0x0C+4: ] if entry.IsItThisTGI( (0xA9DD6FF4,0xE98F9525,0x00000001) ): #heights newbuffer = entry.buffer[ 0 : 0x0C ] + struct.pack( "l", entry.fileLocation ) + struct.pack( "l", len( newData ) )+ entry.buffer[ 0x10+4: ] entry.rawContent = newData entry.compressed = 1 entry.filesize = len( newData ) if entry.IsItThisTGI( (0xCA027EDB, 0xCA027EE1, 0x00000000) ): #city info v = self.dateUpdated entry.content = entry.content[ 0 : 0x04 ] + struct.pack( "I", cityXPos ) + struct.pack( "I", cityYPos ) + entry.content[ 0x0C:39 ] + struct.pack( "I", v ) + entry.content[ 39+4: ] newDataCity = entry.rawContent[:] newDataCity = QFS.encode( entry.content ) newDataCity = struct.pack( "l", len( newDataCity ) ) + newDataCity newbuffer = entry.buffer[ 0 : 0x0C ] + struct.pack( "l", entry.fileLocation ) + struct.pack( "l", len( newDataCity ) )+ entry.buffer[ 0x10+4: ] entry.rawContent = newDataCity entry.compressed = 1 entry.filesize = len( newDataCity ) if entry.IsItThisTGI( (0x8a2482b9,0x4a2482bb,0x00000000) ): #region view n = os.path.splitext( saveName )[0] png = open( n+".PNG","rb" ) pngData = png.read() png.close() os.unlink( n+".PNG" ) newbuffer = entry.buffer[ 0 : 0x0C ] + struct.pack( "I", entry.fileLocation ) + struct.pack( "I", len( pngData ) )+ entry.buffer[ 0x10+4: ] entry.rawContent = pngData entry.compressed = 0 entry.filesize = len( pngData ) if entry.IsItThisTGI( (0x8a2482b9,0x4a2482bb,0x00000002) ): #alpha region view n = os.path.splitext( saveName )[0] png = open( n+"_alpha.PNG" ,"rb" ) pngData = png.read() png.close() os.unlink( n+"_alpha.PNG" ) newbuffer = entry.buffer[ 0 : 0x0C ] + struct.pack( "I", entry.fileLocation ) + struct.pack( "I", len( pngData ) )+ entry.buffer[ 0x10+4: ] entry.rawContent = pngData entry.compressed = 0 entry.filesize = len( pngData ) self.sc4.write( newbuffer) pos += entry.filesize for entry in self.entries: self.sc4.write( entry.rawContent ) self.sc4.close() return True
def ReadFile(self, sc4, readWhole=True, decompress=False): self.rawContent = None if readWhole: sc4.seek(self.fileLocation) self.rawContent = sc4.read(self.filesize) if decompress: if len(self.rawContent) >= 8: compress_sig = struct.unpack( "H", self.rawContent[0x04:0x04 + 2])[0] if compress_sig == COMPRESSED_SIG: self.compressed = True if self.compressed: if decompress: print 'Compressed file' uncompress = QFS.decode(self.rawContent[4:]) self.content = uncompress else: if decompress: print 'Uncompressed file' self.content = self.rawContent