def DecodeFromData(self, stream): ''' Decodes a packet from a data stream. @type stream: Stream (file-like) object @param stream: Stream from which to decode the packet. @raise IncompletePacket: Raised if not enough data is present. @raise CorruptPacket: Raised if the data is invalid. ''' # Read in the header. try: ph_type = BinaryStructs.DeserializeUint16(stream) ph_flags = BinaryStructs.DeserializeUint16(stream) except BinaryStructs.EndOfFile: # Packet seems incomplete raise IncompletePacket # Validate the packet header. if ph_type > MAX_VALID_PACKET: # Unknown type; corrupt packet. raise CorruptPacket("Invalid packet type in header.") # Now try reading the body. compressed = bool(ph_flags & HeaderFlag_zlib) self._GetBodyFromBinary(stream, compressed)
def _Deserialize_CurrentVer(self, fileobj): """ Deserializes a tile in the current map file format. @type fileobj: C{file} @param fileobj: File (or compatible stream) to read from. """ # first: the flags try: flags = BinaryStructs.DeserializeUint32(fileobj) except Exception as e: raise MapError("invalid/corrupt map file", e) # Check for the end-of-tiles flag. if flags & self.EndOfTilesFlag: # End of tiles. raise EndOfSectionException # Read in the rest of the title data. # Validation should happen in the map deserialization (since it has # access to the map header for dimensional validation). Just store # the values for now. try: self.x = BinaryStructs.DeserializeUint32(fileobj) self.y = BinaryStructs.DeserializeUint32(fileobj) self.z = BinaryStructs.DeserializeUint32(fileobj) self.tileid = BinaryStructs.DeserializeUint32(fileobj) except Exception as e: raise MapError("invalid/corrupt map file", e)
def DeserializeBody(self, stream): # Read values. try: self.Salt = BinaryStructs.DeserializeBinary(stream, maxlen=16) self.Challenge = BinaryStructs.DeserializeBinary(stream, maxlen=32) except BinaryStructs.EndOfFile: raise IncompletePacket
def SerializeBody(self): # Implemented from protocol documentation. data = cStringIO.StringIO() BinaryStructs.SerializeUint32(data, self.RequestSerial) BinaryStructs.SerializeUint16(data, self.ReasonCode) retval = data.getvalue() data.close() return retval
def SerializeBody(self): # Write values. data = cStringIO.StringIO() BinaryStructs.SerializeBinary(data, self.Salt, maxlen=16) BinaryStructs.SerializeBinary(data, self.Challenge, maxlen=32) retval = data.getvalue() data.close() return retval
def DeserializeBody(self, stream): # Read data. try: self.RequestSerial = BinaryStructs.DeserializeUint32(stream) self.ChallengeSolution = BinaryStructs.DeserializeBinary(stream, maxlen=32) except BinaryStructs.EndOfFile: raise IncompletePacket
def SerializeBody(self): # Write data. data = cStringIO.StringIO() BinaryStructs.SerializeUint32(data, self.RequestSerial) BinaryStructs.SerializeBinary(data, self.ChallengeSolution, maxlen=32) retval = data.getvalue() data.close() return retval
def DeserializeBody(self, stream): # Read data. try: self.RequestSerial = BinaryStructs.DeserializeUint32(stream) self.Username = BinaryStructs.DeserializeUTF8(stream, maxlen=32) self.Salt = BinaryStructs.DeserializeBinary(stream, maxlen=16) self.PasswordHash = BinaryStructs.DeserializeBinary(stream, 64) self.Email = BinaryStructs.DeserializeUTF8(stream, maxlen=64) except BinaryStructs.EndOfFile: raise IncompletePacket
def SerializeBody(self): # Write data. data = cStringIO.StringIO() BinaryStructs.SerializeUint32(data, self.RequestSerial) BinaryStructs.SerializeUTF8(data, self.Username, maxlen=32) BinaryStructs.SerializeBinary(data, self.Salt, maxlen=16) BinaryStructs.SerializeBinary(data, self.PasswordHash, maxlen=64) BinaryStructs.SerializeUTF8(data, self.Email, maxlen=64) retval = data.getvalue() data.close() return retval
def SerializeBody(self): # Create a stream to work with data = cStringIO.StringIO() # Lots of version info. But first, the protocol signature. data.write(ProtocolSignature) BinaryStructs.SerializeUint16(data, ProtocolRevision) BinaryStructs.SerializeUint16(data, Version.MajorVersion) BinaryStructs.SerializeUint16(data, Version.MinorVersion) # Return the body return data.getvalue()
def DeserializeBody(self, stream): # Read values. try: self.RequestSerial = BinaryStructs.DeserializeUint32(stream) self.ReasonCode = BinaryStructs.DeserializeUint16(stream) except BinaryStructs.EndOfFile: raise IncompletePacket except: msg = "Unhandled exception in DeserializeBody, packet type 4.\n\n" msg += traceback.format_exc() logging.error(msg) raise CorruptPacket
def SerializeBody(self): # Write data. data = cStringIO.StringIO() BinaryStructs.SerializeUint16(data, self.Reason) retval = data.getvalue() data.close() return retval
def Decompress(self, stream): ''' Attempts to decompress a chunk of data. @raise IncompletePacket: Raised if there is not enough data. @raise CorruptPacket: Raised if the data is corrupt. @return: Decompressed chunk of data. ''' # Try to deserialize the data from the stream. try: data = BinaryStructs.DeserializeBinary(stream, maxlen=MaxCompressedSize) except BinaryStructs.EndOfFile: raise IncompletePacket # Attempt to decompress the data try: decompressed = zlib.decompress(data) except: # bad data raise CorruptPacket # Return the data. return decompressed
def SaveToOpenFile(self, fileobj): """ Writes the map to the file object. You should be expecting this method to raise some sort of I/O related error; it is your responsibility to handle these errors. @raise IOError: Not directly raised, but you should expect these to occur and handle them accordingly. @type fileobj: C{file} @param fileobj: An open file object (or compatible stream) to write the map to. """ # write the meta-header mheader = self.MetaheaderStruct.pack(self.MagicNumber, CurrentMapVersion) fileobj.write(mheader) # write the header self.header.Serialize(fileobj) # write the tiles for z in range(self.Depth): for x in range(self.Width): for y in range(self.Height): self.tiles[z][x][y].Serialize(fileobj) # store the end-of-section flag BinaryStructs.SerializeUint32(fileobj, Tile.EndOfTilesFlag)
def DeserializeBody(self, stream): # check the protocol signature signature = stream.read(len(ProtocolSignature)) if len(signature) != len(ProtocolSignature): raise IncompletePacket self.Signature = signature # check the version try: self.Revision = BinaryStructs.DeserializeUint16(stream) self.MajorVersion = BinaryStructs.DeserializeUint16(stream) self.MinorVersion = BinaryStructs.DeserializeUint16(stream) except BinaryStructs.EndOfFile: raise IncompletePacket except: msg = "Unhandled exception while deserializing packet type 0.\n\n" msg += traceback.format_exc() logging.error(msg) raise CorruptPacket
def DeserializeBody(self, stream): # read the values try: flags = BinaryStructs.DeserializeUint8(stream) self.ServerName = BinaryStructs.DeserializeUTF8(stream, 64) self.ServerNewsURL = BinaryStructs.DeserializeUTF8(stream, 256) except BinaryStructs.EndOfFile: raise IncompletePacket except BinaryStructs.MaxLengthExceeded: raise CorruptPacket except: msg = "Unhandled exception in DeserializeBody, packet type 1.\n\n" msg += traceback.format_exc() logging.error(msg) raise CorruptPacket # process the flags if flags & self.Flag_NoRegister: self.RegistrationDisabled = True else: self.RegistrationDisabled = False
def DeserializeBody(self, stream): # Read values. try: self.Username = BinaryStructs.DeserializeUTF8(stream, maxlen=32) except BinaryStructs.EndOfFile: raise IncompletePacket except: msg = "Unhandled exception in DeserializeBody, packet type 6." msg += "\n%s" % traceback.format_exc() logging.error(msg) raise CorruptPacket
def DeserializeBody(self, stream): # Read in the rejection code. try: self.RejectionCode = BinaryStructs.DeserializeUint8(stream) except BinaryStructs.EndOfFile: raise IncompletePacket except: msg = "Unhandled exception in DeserializeBody, packet type 2.\n\n" msg += traceback.format_exc() logging.error(msg) raise CorruptPacket
def SerializeBody(self): # create a buffer data = cStringIO.StringIO() # calculate the login screen flags flags = 0 if self.RegistrationDisabled: flags |= self.Flag_NoRegister BinaryStructs.SerializeUint8(data, flags) # store the other fields try: BinaryStructs.SerializeUTF8(data, self.ServerName) BinaryStructs.SerializeUTF8(data, self.ServerNewsURL) except: raise IncompletePacket # return the packet retval = data.getvalue() data.close() return retval
def GetBinaryForm(self): ''' Encodes the packet to a binary string for network transmission. Do not subclass this method for custom packets; instead, subclass the SerializeBody() interface method. @return: Network-safe binary string containing the packet. ''' # let's figure out what we're sending flags = 0 body = self.SerializeBody() if body: # there's a body that needs to be compressed compressed = self.CompressIfNeeded(body) if compressed != None: bodywriter = cStringIO.StringIO() BinaryStructs.SerializeBinary(bodywriter, compressed, maxlen=MaxCompressedSize) body = bodywriter.getvalue() bodywriter.close() flags |= HeaderFlag_zlib # okay, build the packet packetwriter = cStringIO.StringIO() # first, the header BinaryStructs.SerializeUint16(packetwriter, self.PacketType) BinaryStructs.SerializeUint16(packetwriter, flags) # then the body if body: packetwriter.write(body) # return the packet data retval = packetwriter.getvalue() packetwriter.close() return retval
def Serialize(self, fileobj): """ Outputs a tile to a file using the latest mapfile version. @type fileobj: file @param fileobj: An open file object (or compatible stream) for writing """ # pack all of the flags flags = 0 try: BinaryStructs.SerializeUint32(fileobj, flags) except: msg = "An error occurred while writing to the map file.\n" msg += traceback.format_exc() mainlog.error(msg) raise IOError(msg) # write the coordinates try: BinaryStructs.SerializeUint32(fileobj, self.x) BinaryStructs.SerializeUint32(fileobj, self.y) BinaryStructs.SerializeUint32(fileobj, self.z) except: msg = "An error occurred while writing to the map file.\n" msg += traceback.format_exc() mainlog.error(msg) raise IOError(msg) # write the tile information try: BinaryStructs.SerializeUint32(fileobj, self.tileid) except: msg = "An error occurred while writing to the map file.\n" msg += traceback.format_exc() mainlog.error(msg) raise IOError(msg)
def BuildPacketFromStream(stream, connection): ''' Attempts to build a packet from a data stream. @type stream: file-like object @param stream: Data stream to build packet from. @type connection: Networking.BaseConnectionHandler @param connection: Connection with which to associate the packet. @raise IncompletePacket: Raised if not enough data is present. @raise CorruptPacket: Raised if something is wrong with the data. @return: A Packet object, or an object of a Packet subclass. ''' # try peeking ahead at the packet type startpos = stream.tell() try: type = BinaryStructs.DeserializeUint16(stream) stream.seek(startpos) except: # not enough data, make sure we rewind stream.seek(startpos) raise IncompletePacket # check the type if type < 0 or type > MAX_VALID_PACKET: # packet type is out of bounds raise CorruptPacket # now build up a packet of the appropriate type try: PacketProto = PacketTypes[type] except KeyError: # unrecognized packet type raise CorruptPacket NewPacket = PacketProto(connection) # and now fill in the packet with the data... NewPacket.DecodeFromData(stream) return NewPacket
def Deserialize(self, fileobj, formatver=CurrentMapVersion): """ Reads and decodes the header from a stream (usually a file). @type fileobj: C{file} @param fileobj: File object to read the header from. @type formatver: integer @param formatver: version of the map file format to process """ # which version are we reading from? if formatver == CurrentMapVersion: # latest version of the header format! # again, we're just reading everything in the right order # first up is the basic file information try: self.MapName = BinaryStructs.DeserializeUTF8(fileobj) self.MapName.strip() self.Width = BinaryStructs.DeserializeUint32(fileobj) self.Height = BinaryStructs.DeserializeUint32(fileobj) self.Depth = BinaryStructs.DeserializeUint32(fileobj) self.PlayerDepth = BinaryStructs.DeserializeUint32(fileobj) except: msg = "Map file is invalid/corrupt.\n" msg += traceback.format_exc() mainlog.error(msg) raise # validate the basic file information if self.Width < 1 or self.Height < 1 or self.Depth < 1: # invalid dimensions raise MapError("Map file is invalid/corrupt: dimensions") if self.PlayerDepth < 0 or self.PlayerDepth >= self.Depth: # render depth out of bounds raise MapError("Player/object render depth out of bounds.") # now we read in the links try: self.NorthMap = BinaryStructs.DeserializeUTF8(fileobj) self.NorthMap.strip() self.EastMap = BinaryStructs.DeserializeUTF8(fileobj) self.EastMap.strip() self.SouthMap = BinaryStructs.DeserializeUTF8(fileobj) self.SouthMap.strip() self.WestMap = BinaryStructs.DeserializeUTF8(fileobj) self.WestMap.strip() self.BackgroundImage = BinaryStructs.DeserializeUTF8(fileobj) self.BackgroundImage.strip() except Exception as e: raise MapError("Map file is invalid/corrupt.", e) # and then we read in the content flags... try: contentflags = BinaryStructs.DeserializeUint32(fileobj) except Exception as e: raise MapError("Map file is invalid/corrupt.", e) self.Stripped = contentflags & self.Flag_ContentStripped else: # unrecognized future version raise FutureFormatException("unrecognized format version")
def Serialize(self, fileobj): """ Encodes and writes the header to a stream (usually a file). This will always encode the header as the latest version of the map file format. @type fileobj: C{file} @param fileobj: open file object to serialize to """ # nothing too special, just write everything in the right order try: BinaryStructs.SerializeUTF8(fileobj, self.MapName) BinaryStructs.SerializeUint32(fileobj, self.Width) BinaryStructs.SerializeUint32(fileobj, self.Height) BinaryStructs.SerializeUint32(fileobj, self.Depth) BinaryStructs.SerializeUint32(fileobj, self.PlayerDepth) BinaryStructs.SerializeUTF8(fileobj, self.NorthMap) BinaryStructs.SerializeUTF8(fileobj, self.EastMap) BinaryStructs.SerializeUTF8(fileobj, self.SouthMap) BinaryStructs.SerializeUTF8(fileobj, self.WestMap) BinaryStructs.SerializeUTF8(fileobj, self.BackgroundImage) except Exception as e: raise IOError("error while writing to map file", e) # pack the content flags try: contentFlags = 0 if self.Stripped: contentFlags |= self.Flag_ContentStripped BinaryStructs.SerializeUint32(fileobj, contentFlags) except Exception as e: raise IOError("error while writing to map file", e)
def SerializeBody(self): # All we have to do is write the rejection code... data = cStringIO.StringIO() BinaryStructs.SerializeUint8(data, self.RejectionCode)
def SerializeBody(self): data = cStringIO.StringIO() BinaryStructs.SerializeUTF8(data, self.Username, maxlen=32) retval = data.getvalue() data.close() return retval
def DeserializeBody(self, stream): # Read data. try: self.Reason = BinaryStructs.DeserializeUint16(stream) except BinaryStructs.EndOfFile: raise IncompletePacket