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: max_bits = 32 if self.protocol_mode == "play" else 21 packet_length = self.recv_buff.unpack_varint(max_bits=max_bits) packet_body = self.recv_buff.read(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.read()) packet_buff = Buffer() packet_buff.add(data) ident = packet_buff.unpack_varint() key = (self.protocol_version, self.protocol_mode, self.recv_direction, ident) try: name = packets.packet_names[key] except KeyError: raise ProtocolError("No name known for packet: %s" % (key, )) self.packet_received(packet_buff, name) except BufferUnderrun: raise ProtocolError("Packet is too short!") if len(packet_buff) > 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()
def test_read(): buffer = Buffer() buffer.add(b"spam") assert buffer.read(2) == b"sp" assert buffer.read(2) == b"am" buffer.add(b"eggs") assert buffer.read() == b"eggs" with pytest.raises(BufferUnderrun): buffer.read(1)
def test_save_discard_restore(): buffer = Buffer() buffer.add(b"spam") buffer.save() assert len(buffer) == 4 buffer.discard() assert len(buffer) == 0 buffer.restore() assert len(buffer) == 4
def test_unpack_chat(): buffer = Buffer() buffer.add(b'\x11["spam", " eggs"]') assert buffer.unpack_chat().to_string() == "spam eggs" buffer.add(b'\x22{"text": "spam", "extra": " eggs"}') assert buffer.unpack_chat().to_string() == "spam eggs" buffer.add(b'\x14{"translate": "foo"}') assert buffer.unpack_chat().to_string() == "foo" buffer.add(b'\x2E{"translate": "foo", "with": ["spam", "eggs"]}') assert buffer.unpack_chat().to_string() == "foo{spam, eggs}"
def load_chunk(self, chunk_x, chunk_z): """ Loads the chunk at the given co-ordinates from the region file. The co-ordinates should range from 0 to 31. Returns a ``TagRoot``. """ buff = Buffer() # Read extent header self.fd.seek(4 * (32 * chunk_z + chunk_x)) buff.add(self.fd.read(4)) entry = buff.unpack('I') chunk_offset, chunk_length = entry >> 8, entry & 0xFF # Read chunk self.fd.seek(4096 * chunk_offset) buff.add(self.fd.read(4096 * chunk_length)) chunk = buff.read(buff.unpack('IB')[0]) chunk = zlib.decompress(chunk) chunk = TagRoot.from_bytes(chunk) return chunk
def load_chunk(self, chunk_x, chunk_z): """ Loads the chunk at the given co-ordinates from the region file. The co-ordinates should range from 0 to 31. Returns a ``TagRoot``. """ buff = Buffer() # Read extent header self.fd.seek(4 * (32 * chunk_z + chunk_x)) buff.add(self.fd.read(4)) entry = buff.unpack('I') chunk_offset, chunk_length = entry >> 8, entry & 0xFF if chunk_offset == 0: raise ValueError((chunk_x, chunk_z)) # Read chunk self.fd.seek(4096 * chunk_offset) buff.add(self.fd.read(4096 * chunk_length)) chunk = buff.read(buff.unpack('IB')[0]) chunk = zlib.decompress(chunk) chunk = TagRoot.from_bytes(chunk) return chunk
def test_unpack_entity_metadata(): buffer = Buffer() for value, data in entity_metadata_vectors: buffer.add(data) assert buffer.unpack_entity_metadata() == value assert len(buffer) == 0
def test_unpack_slot(): buffer = Buffer() for value, data in slot_vectors: buffer.add(data) assert buffer.unpack_slot() == value assert len(buffer) == 0
def test_unpack_uuid(): buffer = Buffer() buffer.add(uuid_vector) assert buffer.unpack_uuid().to_bytes() == uuid_vector
def test_unpack_json(): buffer = Buffer() buffer.add(b'\x10{"spam": "eggs"}') assert buffer.unpack_json() == {"spam": "eggs"}
def test_unpack_string(): buffer = Buffer() buffer.add(b"\x04spam") assert buffer.unpack_string() == "spam"
def test_unpack(): buffer = Buffer() for fmt, data, values in pack_unpack_vectors: buffer.add(data) assert buffer.unpack(fmt) == values
def test_add(): buffer = Buffer() buffer.add(b"spam") assert len(buffer) == 4 assert buffer.read() == b"spam"
def load(cls, path): with gzip.open(path, 'rb') as fd: buff = Buffer() buff.add(fd.read()) return cls(TagRoot.from_buff(buff))
def test_unpack_varint(): buffer = Buffer() for value, data in varint_vectors: buffer.add(data) assert buffer.unpack_varint(signed=True) == value assert len(buffer) == 0