import unittest from minecraft.networking.types import (UUID, VarInt, String, Boolean) from minecraft.networking.packets import PacketBuffer from minecraft.networking.packets.clientbound.play import ( PlayerPositionAndLookPacket, PlayerListItemPacket, MapPacket ) from minecraft.networking.connection import ConnectionContext class PlayerPositionAndLookTest(unittest.TestCase): def test_position_and_look(self): current_position = PlayerPositionAndLookPacket.PositionAndLook( x=999, y=999, z=999, yaw=999, pitch=999) packet = PlayerPositionAndLookPacket() packet.x = 1.0 packet.y = 2.0 packet.z = 3.0 packet.yaw = 4.0 packet.pitch = 5.0 # First do an absolute move to these cordinates packet.flags = 0 packet.apply(current_position) self.assertEqual(current_position.x, 1.0) self.assertEqual(current_position.y, 2.0) self.assertEqual(current_position.z, 3.0) self.assertEqual(current_position.yaw, 4.0) self.assertEqual(current_position.pitch, 5.0) # Now a relative move packet.flags = 0b11111 packet.apply(current_position) self.assertEqual(current_position.x, 2.0) self.assertEqual(current_position.y, 4.0) self.assertEqual(current_position.z, 6.0) self.assertEqual(current_position.yaw, 8.0) self.assertEqual(current_position.pitch, 10.0) class MapPacketTest(unittest.TestCase): @staticmethod def make_map_packet( context, width=2, height=2, offset=(2, 2), pixels=b"this"): packet = MapPacket(context) packet.map_id = 1 packet.scale = 42 packet.is_tracking_position = True packet.is_locked = False packet.icons = [] d_name = u'Marshmallow' if context.protocol_version >= 364 else None packet.icons.append(MapPacket.MapIcon( type=2, direction=2, location=(1, 1), display_name=d_name )) packet.icons.append(MapPacket.MapIcon( type=3, direction=3, location=(3, 3) )) packet.width = width packet.height = height if width else 0 packet.offset = offset if width else None packet.pixels = pixels if width else None return packet 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 test_packet_roundtrip(self): self.packet_roundtrip(ConnectionContext(protocol_version=106)) self.packet_roundtrip(ConnectionContext(protocol_version=107)) self.packet_roundtrip(ConnectionContext(protocol_version=379)) self.packet_roundtrip(ConnectionContext(protocol_version=379), width=0) def test_map_set(self): map_set = MapPacket.MapSet() context = ConnectionContext(protocol_version=107) packet = self.make_map_packet(context) packet.apply_to_map_set(map_set) self.assertEqual(len(map_set.maps_by_id), 1) packet = self.make_map_packet( context, width=1, height=0, offset=(2, 2), pixels=b"x" ) packet.apply_to_map_set(map_set) map = map_set.maps_by_id[1] self.assertIn(b"xh", map.pixels) self.assertIn(b"is", map.pixels) self.assertIsNotNone(str(map_set)) fake_uuid = "12345678-1234-5678-1234-567812345678" class PlayerListItemTest(unittest.TestCase): 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_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) @staticmethod 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_add_player_action(self): player_list = PlayerListItemPacket.PlayerList() packet_buffer = self.make_add_player_packet() packet = PlayerListItemPacket() packet.read(packet_buffer) packet.apply(player_list) self.assertIn(fake_uuid, player_list.players_by_uuid) player = player_list.players_by_uuid[fake_uuid] self.assertEqual(player.name, "player") self.assertEqual(player.properties[0].name, "property1") self.assertIsNone(player.properties[0].signature) self.assertEqual(player.properties[1].value, "value2") self.assertEqual(player.properties[1].signature, "signature") self.assertEqual(player.gamemode, 42) self.assertEqual(player.ping, 69) self.assertEqual(player.display_name, "display") @staticmethod 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 read_and_apply(self, packet_buffer, player_list): packet_buffer.reset_cursor() packet = PlayerListItemPacket() packet.read(packet_buffer) packet.apply(player_list) def test_add_and_others(self): player_list = PlayerListItemPacket.PlayerList() by_uuid = player_list.players_by_uuid packet_buffer = self.make_add_player_packet(display_name=False) self.read_and_apply(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 = self.make_action_base(1) VarInt.send(43, packet_buffer) # gamemode self.read_and_apply(packet_buffer, player_list) self.assertEqual(by_uuid[fake_uuid].gamemode, 43) # Change the ping packet_buffer = self.make_action_base(2) VarInt.send(70, packet_buffer) # ping self.read_and_apply(packet_buffer, player_list) self.assertEqual(by_uuid[fake_uuid].ping, 70) # Change the display name packet_buffer = self.make_action_base(3) Boolean.send(True, packet_buffer) String.send("display2", packet_buffer) self.read_and_apply(packet_buffer, player_list) self.assertEqual(by_uuid[fake_uuid].display_name, "display2") # Remove the display name packet_buffer = self.make_action_base(3) Boolean.send(False, packet_buffer) self.read_and_apply(packet_buffer, player_list) self.assertIsNone(by_uuid[fake_uuid].display_name) # Remove the player packet_buffer = self.make_action_base(4) self.read_and_apply(packet_buffer, player_list) self.assertNotIn(fake_uuid, player_list.players_by_uuid)