def make_add_player_packet(display_name=True): packet_buffer = PacketBuffer() VarInt.send(0, packet_buffer) # action_id VarInt.send(1, packet_buffer) # action count UUID.send(fake_uuid, packet_buffer) # uuid String.send("player", packet_buffer) # player name VarInt.send(2, packet_buffer) # number of properties String.send("property1", packet_buffer) String.send("value1", packet_buffer) Boolean.send(False, packet_buffer) # is signed String.send("property2", packet_buffer) String.send("value2", packet_buffer) Boolean.send(True, packet_buffer) # is signed String.send("signature", packet_buffer) VarInt.send(42, packet_buffer) # game mode VarInt.send(69, packet_buffer) # ping Boolean.send(display_name, packet_buffer) # has display name if display_name: String.send("display", packet_buffer) # display name packet_buffer.reset_cursor() return packet_buffer
def _test_read_write_packet(self, packet_in, context=None, **kwargs): """ If kwargs are specified, the key will be tested against the respective delta value. Useful for testing FixedPointNumbers where there is precision lost in the resulting value. """ if context is None: for protocol_version in TEST_VERSIONS: logging.debug('protocol_version = %r' % protocol_version) context = ConnectionContext(protocol_version=protocol_version) self._test_read_write_packet(packet_in, context) else: packet_in.context = context packet_buffer = PacketBuffer() packet_in.write(packet_buffer) packet_buffer.reset_cursor() VarInt.read(packet_buffer) packet_id = VarInt.read(packet_buffer) self.assertEqual(packet_id, packet_in.id) packet_out = type(packet_in)(context=context) packet_out.read(packet_buffer) self.assertIs(type(packet_in), type(packet_out)) for packet_attr, precision in kwargs.items(): packet_attribute_in = packet_in.__dict__.pop(packet_attr) packet_attribute_out = packet_out.__dict__.pop(packet_attr) self.assertAlmostEqual(packet_attribute_in, packet_attribute_out, delta=precision) self.assertEqual(packet_in.__dict__, packet_out.__dict__)
def make_add_player_packet(self, context, display_name=True): packet_buffer = PacketBuffer() packet = PlayerListItemPacket( context=context, action_type=PlayerListItemPacket.AddPlayerAction, actions=[ PlayerListItemPacket.AddPlayerAction( uuid=fake_uuid, name='goodmonson', properties=[ PlayerListItemPacket.PlayerProperty( name='property1', value='value1', signature=None), PlayerListItemPacket.PlayerProperty( name='property2', value='value2', signature='gm') ], gamemode=42, ping=69, display_name='Goodmonson' if display_name else None ), ], ) if display_name: self.assertEqual( str(packet), "0x%02X PlayerListItemPacket(" "action_type=AddPlayerAction, actions=[AddPlayerAction(" "uuid=%r, name='goodmonson', properties=[PlayerProperty(" "name='property1', value='value1', signature=None), " "PlayerProperty(name='property2', value='value2', " "signature='gm')], gamemode=42, ping=69, " "display_name='Goodmonson')])" % (packet.id, fake_uuid)) packet.write_fields(packet_buffer) packet_buffer.reset_cursor() return packet_buffer
def test_get_writable(self): message = b"hello" packet_buffer = PacketBuffer() packet_buffer.send(message) self.assertEqual(packet_buffer.get_writable(), message)
def packet_roundtrip(self, context, **kwds): packet = self.make_map_packet(context, **kwds) packet_buffer = PacketBuffer() packet.write(packet_buffer) packet_buffer.reset_cursor() # Read the length and packet id VarInt.read(packet_buffer) packet_id = VarInt.read(packet_buffer) self.assertEqual(packet_id, packet.id) p = MapPacket(context) p.read(packet_buffer) self.assertEqual(p.map_id, packet.map_id) self.assertEqual(p.scale, packet.scale) self.assertEqual(p.is_tracking_position, packet.is_tracking_position) self.assertEqual(p.width, packet.width) self.assertEqual(p.height, packet.height) self.assertEqual(p.offset, packet.offset) self.assertEqual(p.pixels, packet.pixels) self.assertEqual(str(p.icons[0]), str(packet.icons[0])) self.assertEqual(str(p.icons[1]), str(packet.icons[1])) self.assertEqual(str(p), str(packet))
def write_read_packet(self, packet, compression_threshold): for protocol_version in SUPPORTED_PROTOCOL_VERSIONS: context = ConnectionContext(protocol_version=protocol_version) packet_buffer = PacketBuffer() packet.write(packet_buffer, compression_threshold) packet_buffer.reset_cursor() VarInt.read(packet_buffer) compressed_size = VarInt.read(packet_buffer) if compressed_size > 0: decompressed = decompress(packet_buffer.read(compressed_size)) packet_buffer.reset() packet_buffer.send(decompressed) packet_buffer.reset_cursor() packet_id = VarInt.read(packet_buffer) self.assertEqual(packet_id, packet.id) deserialized = ChatPacket(context) deserialized.read(packet_buffer) self.assertEqual(packet.message, deserialized.message)
def test_invalid_action(self): packet_buffer = PacketBuffer() VarInt.send(200, packet_buffer) # action_id packet_buffer.reset_cursor() with self.assertRaises(ValueError): PlayerListItemPacket().read(packet_buffer)
def test_serialization(self): for protocol_version in TEST_VERSIONS: context = ConnectionContext(protocol_version=protocol_version) for data_type in Type.__subclasses__(): if data_type in TEST_DATA: test_cases = TEST_DATA[data_type] for test_data in test_cases: packet_buffer = PacketBuffer() data_type.send_with_context( test_data, packet_buffer, context) packet_buffer.reset_cursor() deserialized = data_type.read_with_context( packet_buffer, context) if data_type is FixedPointInteger: self.assertAlmostEqual( test_data, deserialized, delta=1.0/32.0) elif data_type is Angle: self.assertAlmostEqual(test_data % 360, deserialized, delta=360/256) elif data_type is Float or data_type is Double: self.assertAlmostEqual(test_data, deserialized, 3) else: self.assertEqual(test_data, deserialized)
def test_base_action(self): packet_buffer = PacketBuffer() UUID.send(fake_uuid, packet_buffer) packet_buffer.reset_cursor() with self.assertRaises(NotImplementedError): action = PlayerListItemPacket.Action() action.read(packet_buffer)
def test_varint(self): self.assertEqual(VarInt.size(2), 1) self.assertEqual(VarInt.size(1250), 2) packet_buffer = PacketBuffer() VarInt.send(50000, packet_buffer) packet_buffer.reset_cursor() self.assertEqual(VarInt.read(packet_buffer), 50000)
def _test_read_write_packet(self, packet_in): packet_in.context = self.context packet_buffer = PacketBuffer() packet_in.write(packet_buffer) packet_buffer.reset_cursor() VarInt.read(packet_buffer) packet_id = VarInt.read(packet_buffer) self.assertEqual(packet_id, packet_in.id) packet_out = type(packet_in)(context=self.context) packet_out.read(packet_buffer) self.assertIs(type(packet_in), type(packet_out)) self.assertEqual(packet_in.__dict__, packet_out.__dict__)
def test_serialization(self): for data_type in Type.__subclasses__(): if data_type in TEST_DATA: test_cases = TEST_DATA[data_type] for test_data in test_cases: packet_buffer = PacketBuffer() data_type.send(test_data, packet_buffer) packet_buffer.reset_cursor() deserialized = data_type.read(packet_buffer) if data_type is Float or data_type is Double: self.assertAlmostEquals(test_data, deserialized, 3) else: self.assertEqual(test_data, deserialized)
def make_action_base(action_id): packet_buffer = PacketBuffer() VarInt.send(action_id, packet_buffer) VarInt.send(1, packet_buffer) # action count UUID.send(fake_uuid, packet_buffer) return packet_buffer
def write(self, socket, compression_threshold=None): packet_buffer = PacketBuffer() VarInt.send(self.id, packet_buffer) VarInt.send(self.map_id, packet_buffer) Byte.send(self.scale, packet_buffer) if self.context.protocol_version >= 107: Boolean.send(self.is_tracking_position, packet_buffer) VarInt.send(len(self.icons), packet_buffer) for icon in self.icons: type_and_direction = (icon.direction << 4) & 0xF0 type_and_direction |= (icon.type & 0xF) UnsignedByte.send(type_and_direction, packet_buffer) Byte.send(icon.location[0], packet_buffer) Byte.send(icon.location[1], packet_buffer) UnsignedByte.send(self.width, packet_buffer) if self.width: UnsignedByte.send(self.height, packet_buffer) UnsignedByte.send(self.offset[0], packet_buffer) # x UnsignedByte.send(self.offset[1], packet_buffer) # z VarIntPrefixedByteArray.send(self.pixels, packet_buffer) self._write_buffer(socket, packet_buffer, compression_threshold)
def write(self, socket, compression_threshold=None): packet_buffer = PacketBuffer() (x, y, z) = self.location Position.send(x, y, z, packet_buffer) blockData = ((self.blockId << 4) | (self.blockMeta & 0xF)) VarInt.send(blockData) self._write_buffer(socket, packet_buffer, compression_threshold)
def test_packet(self): packet = ChatPacket() packet.message = u"κόσμε" packet_buffer = PacketBuffer() packet.write(packet_buffer) packet_buffer.reset_cursor() # Read the length and packet id VarInt.read(packet_buffer) packet_id = VarInt.read(packet_buffer) self.assertEqual(packet_id, packet.id) deserialized = ChatPacket() deserialized.read(packet_buffer) self.assertEqual(packet.message, deserialized.message)
def test_packet(self): for protocol_version in SUPPORTED_PROTOCOL_VERSIONS: context = ConnectionContext(protocol_version=protocol_version) packet = serverbound.play.ChatPacket(context) packet.message = u"κόσμε" packet_buffer = PacketBuffer() packet.write(packet_buffer) packet_buffer.reset_cursor() # Read the length and packet id VarInt.read(packet_buffer) packet_id = VarInt.read(packet_buffer) self.assertEqual(packet_id, packet.id) deserialized = serverbound.play.ChatPacket(context) deserialized.read(packet_buffer) self.assertEqual(packet.message, deserialized.message)
def test_packet(self): for protocol_version in SUPPORTED_PROTOCOL_VERSIONS: context = ConnectionContext(protocol_version=protocol_version) packet = ChatPacket(context) packet.message = u"κόσμε" packet_buffer = PacketBuffer() packet.write(packet_buffer) packet_buffer.reset_cursor() # Read the length and packet id VarInt.read(packet_buffer) packet_id = VarInt.read(packet_buffer) self.assertEqual(packet_id, packet.id) deserialized = ChatPacket(context) deserialized.read(packet_buffer) self.assertEqual(packet.message, deserialized.message)
def test_exceptions(self): base_type = Type() with self.assertRaises(NotImplementedError): base_type.read(None) with self.assertRaises(NotImplementedError): base_type.send(None, None) empty_socket = PacketBuffer() with self.assertRaises(Exception): VarInt.read(empty_socket)
def write_read_packet(self, packet, compression_threshold): packet_buffer = PacketBuffer() packet.write(packet_buffer, compression_threshold) packet_buffer.reset_cursor() VarInt.read(packet_buffer) compressed_size = VarInt.read(packet_buffer) if compressed_size > 0: decompressed = decompress(packet_buffer.read(compressed_size)) packet_buffer.reset() packet_buffer.send(decompressed) packet_buffer.reset_cursor() packet_id = VarInt.read(packet_buffer) self.assertEqual(packet_id, packet.id) deserialized = ChatPacket() deserialized.read(packet_buffer) self.assertEqual(packet.message, deserialized.message)
def make_add_player_packet(context, display_name=True): packet_buffer = PacketBuffer() PlayerListItemPacket( context=context, action_type=PlayerListItemPacket.AddPlayerAction, actions=[ PlayerListItemPacket.AddPlayerAction( uuid=fake_uuid, name='goodmonson', properties=[ PlayerListItemPacket.PlayerProperty(name='property1', value='value1', signature=None), PlayerListItemPacket.PlayerProperty(name='property2', value='value2', signature='gm') ], gamemode=42, ping=69, display_name='Goodmonson' if display_name else None), ], ).write_fields(packet_buffer) packet_buffer.reset_cursor() return packet_buffer
def test_varint(self): self.assertEqual(VarInt.size(2), 1) self.assertEqual(VarInt.size(1250), 2) with self.assertRaises(ValueError): VarInt.size(2 ** 90) with self.assertRaises(ValueError): packet_buffer = PacketBuffer() VarInt.send(2 ** 49, packet_buffer) packet_buffer.reset_cursor() VarInt.read(packet_buffer) packet_buffer = PacketBuffer() VarInt.send(50000, packet_buffer) packet_buffer.reset_cursor() self.assertEqual(VarInt.read(packet_buffer), 50000)
def decode_chunk_data(self): packet_data = PacketBuffer() packet_data.send(self.data) packet_data.reset_cursor() self.chunks = {} for i in range(16): #0-15 self.chunks[i] = Chunk(self.x, i, self.z) if self.bit_mask_y & (1 << i): self.chunks[i].read(packet_data) for e in self.entities: y = e['y'] self.chunks[floor(y/16)].entities.append(e)
def write_read_packet(self, packet, compression_threshold): for protocol_version in SUPPORTED_PROTOCOL_VERSIONS: context = ConnectionContext(protocol_version=protocol_version) packet_buffer = PacketBuffer() packet.write(packet_buffer, compression_threshold) packet_buffer.reset_cursor() VarInt.read(packet_buffer) compressed_size = VarInt.read(packet_buffer) if compressed_size > 0: decompressed = decompress(packet_buffer.read(compressed_size)) packet_buffer.reset() packet_buffer.send(decompressed) packet_buffer.reset_cursor() packet_id = VarInt.read(packet_buffer) self.assertEqual(packet_id, packet.id) deserialized = serverbound.play.ChatPacket(context) deserialized.read(packet_buffer) self.assertEqual(packet.message, deserialized.message)
def read_data(self, data, dimension): file_object = PacketBuffer() file_object.send(data) file_object.reset_cursor() for i in range(16): if self.bitmask & (1 << i): bits_per_block = UnsignedByte.read(file_object) palette = None if bits_per_block < GLOBAL_BITS_PER_BLOCK: palette_length = VarInt.read(file_object) palette = [] for _ in range(palette_length): palette.append(VarInt.read(file_object)) section = ChunkDataPacket.ChunkSection() data_length = VarInt.read(file_object) data = [] for _ in range(data_length): part = file_object.read(8) data.append(int.from_bytes(part, 'big')) section.data = data section.palette = palette block_mask = (1 << bits_per_block) - 1 # print(i) for y in range(16): for z in range(16): for x in range(16): block_mask = (1 << bits_per_block) - 1 number = (((y << 4) + z) << 4) + x long_number = (number * bits_per_block) >> 6 bit_in_long_number = (number * bits_per_block) & 63 block = (data[long_number] >> bit_in_long_number) & (block_mask) if bit_in_long_number + bits_per_block > 64: block |= (data[long_number + 1] & ( (1 << (bit_in_long_number + bits_per_block - 64)) - 1)) << (64 - bit_in_long_number) if palette: # if block > 0: # print(palette) # print(len(palette)) # print(block) # print(bits_per_block) # print((x, y, z, self.x, self.z)) block = palette[block] if type(block) is float: print(block) section.blocks[x][y][z] = block section.light = file_object.read(2048) if dimension == 0: section.sky_light = file_object.read(2048) self.sections[i] = section self.update_blocks()
def test_basic_read_write(self): message = b"hello" packet_buffer = PacketBuffer() packet_buffer.send(message) packet_buffer.reset_cursor() self.assertEqual(packet_buffer.read(), message) packet_buffer.reset_cursor() self.assertEqual(packet_buffer.recv(), message) packet_buffer.reset() self.assertNotEqual(packet_buffer.read(), message)
def test_add_and_others(self): for protocol_version in TEST_VERSIONS: context = ConnectionContext(protocol_version=protocol_version) player_list = PlayerListItemPacket.PlayerList() by_uuid = player_list.players_by_uuid packet_buffer = self.make_add_player_packet( context, display_name=False) self.read_and_apply(context, packet_buffer, player_list) self.assertEqual(by_uuid[fake_uuid].gamemode, 42) self.assertEqual(by_uuid[fake_uuid].ping, 69) self.assertIsNone(by_uuid[fake_uuid].display_name) # Change the game mode packet_buffer = PacketBuffer() packet = PlayerListItemPacket( context=context, action_type=PlayerListItemPacket.UpdateGameModeAction, actions=[ PlayerListItemPacket.UpdateGameModeAction( uuid=fake_uuid, gamemode=43), ], ) self.assertEqual( str(packet), "0x%02X PlayerListItemPacket(" "action_type=UpdateGameModeAction, actions=[" "UpdateGameModeAction(uuid=%r, gamemode=43)])" % (packet.id, fake_uuid)) packet.write_fields(packet_buffer) self.read_and_apply(context, packet_buffer, player_list) self.assertEqual(by_uuid[fake_uuid].gamemode, 43) # Change the ping packet_buffer = PacketBuffer() packet = PlayerListItemPacket( context=context, action_type=PlayerListItemPacket.UpdateLatencyAction, actions=[ PlayerListItemPacket.UpdateLatencyAction( uuid=fake_uuid, ping=70), ], ) self.assertEqual( str(packet), "0x%02X PlayerListItemPacket(" "action_type=UpdateLatencyAction, actions=[" "UpdateLatencyAction(uuid=%r, ping=70)])" % (packet.id, fake_uuid)) packet.write_fields(packet_buffer) self.read_and_apply(context, packet_buffer, player_list) self.assertEqual(by_uuid[fake_uuid].ping, 70) # Change the display name packet_buffer = PacketBuffer() packet = PlayerListItemPacket( context=context, action_type=PlayerListItemPacket.UpdateDisplayNameAction, actions=[ PlayerListItemPacket.UpdateDisplayNameAction( uuid=fake_uuid, display_name='Badmonson'), ], ) self.assertEqual( str(packet), "0x%02X PlayerListItemPacket(" "action_type=UpdateDisplayNameAction, actions=[" "UpdateDisplayNameAction(uuid=%r, display_name='Badmonson')])" % (packet.id, fake_uuid)) packet.write_fields(packet_buffer) self.read_and_apply(context, packet_buffer, player_list) self.assertEqual(by_uuid[fake_uuid].display_name, 'Badmonson') # Remove the display name packet_buffer = PacketBuffer() PlayerListItemPacket( context=context, action_type=PlayerListItemPacket.UpdateDisplayNameAction, actions=[ PlayerListItemPacket.UpdateDisplayNameAction( uuid=fake_uuid, display_name=None), ], ).write_fields(packet_buffer) self.read_and_apply(context, packet_buffer, player_list) self.assertIsNone(by_uuid[fake_uuid].display_name) # Remove the player packet_buffer = PacketBuffer() packet = PlayerListItemPacket( context=context, action_type=PlayerListItemPacket.RemovePlayerAction, actions=[ PlayerListItemPacket.RemovePlayerAction(uuid=fake_uuid), ], ) self.assertEqual( str(packet), "0x%02X PlayerListItemPacket(" "action_type=RemovePlayerAction, actions=[RemovePlayerAction(" "uuid=%r)])" % (packet.id, fake_uuid)) packet.write_fields(packet_buffer) self.read_and_apply(context, packet_buffer, player_list) self.assertNotIn(fake_uuid, player_list.players_by_uuid)