def send_packet(self, ident, data=""): """ Sends a packet """ if self.closed: return self.log_packet("# send", ident) # Prepend ident data = Buffer.pack_varint(ident) + data if self.compression_enabled: # Compress data and prepend uncompressed data length if len(data) >= self.compression_threshold: data = Buffer.pack_varint(len(data)) + zlib.compress(data) else: data = Buffer.pack_varint(0) + data # Prepend packet length data = self.buff_type.pack_varint(len(data)) + data # Encrypt data = self.cipher.encrypt(data) # Send self.transport.write(data)
def data_received(self, data): # Decrypt data data = self.cipher.decrypt(data) # Add it to our buffer self.recv_buff.add(data) # Read some packets while not self.closed: # Save the buffer, in case we read an incomplete packet self.recv_buff.save() # Try to read a packet try: packet_length = self.recv_buff.unpack_varint() packet_body = self.recv_buff.unpack_raw(packet_length) # Incomplete packet read, restore the buffer. except BufferUnderrun: self.recv_buff.restore() break # Load the packet body into a buffer packet_buff = self.buff_type() packet_buff.add(packet_body) try: # Catch protocol errors try: # Catch buffer overrun/underrun if self.compression_enabled: uncompressed_length = packet_buff.unpack_varint() if uncompressed_length > 0: data = zlib.decompress(packet_buff.unpack_all()) packet_buff = Buffer() packet_buff.add(data) ident = packet_buff.unpack_varint() self.packet_received(packet_buff, ident) except BufferUnderrun: raise ProtocolError("Packet is too short!") if packet_buff.length() > 0: raise ProtocolError("Packet is too long!") except ProtocolError as e: self.protocol_error(e) break # We've read a complete packet, so reset the inactivity timeout self.connection_timer.restart()