def test_move_player(self): self.test_login() self.perform_action(ActionType.MOVE_PLAYER, entity_runtime_id=1, position=Vector3(x=257.5, y=64.625, z=254.5), pitch=45.0, yaw=60.0, head_yaw=30.0, mode=MoveMode.NORMAL, on_ground=True, riding_eid=0, need_response=False) actual_event = self.next_event() expected_event = event_factory.create(EventType.PLAYER_MOVED, entity_runtime_id=1, position=Vector3(x=257.5, y=64.625, z=254.5), pitch=45.0, yaw=60.0, head_yaw=30.0, mode=MoveMode.NORMAL, on_ground=True, riding_eid=0, need_response=False) self.assertEqual(expected_event, actual_event)
def put_item(self, east: int, height: int, south: int, item_type: ItemType, item_data: int, face: Face = Face.TOP, click_east: float = 0.5, click_height: float = 0.5, click_south: float = 0.5, hotbar_slot: int = 0, player_eid: Optional[EntityRuntimeID] = None): def revise(value: float, direction: int) -> float: if direction == 1: return 1.0 elif direction == -1: return 0.0 else: return value click_east = revise(click_east, face.direction.x) click_height = revise(click_height, face.direction.y) click_south = revise(click_south, face.direction.z) self.perform_action(ActionType.PUT_ITEM, self._player_eid(player_eid), Vector3(east, height, south).astype(int), Vector3(click_east, click_height, click_south), face, hotbar_slot, Item.create(item_type, 1, item_data))
def test_put_item(self): self.test_equip() self.perform_action(ActionType.PUT_ITEM, entity_runtime_id=1, position=Vector3(x=256, y=62, z=257), click_position=Vector3(0.5, 1.0, 0.5), face=Face.TOP, hotbar_slot=0, item=Item(type=ItemType.DIRT, aux_value=64, nbt=b'', place_on=(), destroy=())) actual_event = self.next_event() expected_event = event_factory.create( EventType.BLOCK_UPDATED, (PlacedBlock(Vector3(x=256, y=63, z=257), Block(type=BlockType.DIRT, aux_value=0)), )) self.assertEqual(expected_event, actual_event) actual_event = self.next_event() expected_event = event_factory.create(EventType.INVENTORY_UPDATED, player_id=self.get_player_id(0), inventory_slot=0, slot_item=Item( type=ItemType.DIRT, aux_value=64, nbt=b'', place_on=(), destroy=())) self.assertEqual(expected_event, actual_event)
def test_break_block(self): self.test_login() self.perform_action(ActionType.BREAK_BLOCK, entity_runtime_id=1, position=Vector3(x=256, y=62, z=257)) actual_event = self.next_event() expected_event = event_factory.create( EventType.BLOCK_UPDATED, (PlacedBlock(Vector3(x=256, y=62, z=257), Block(type=BlockType.AIR, aux_value=0)), )) self.assertEqual(expected_event, actual_event) actual_event = self.next_event() expected_event = event_factory.create(EventType.ITEM_SPAWNED, entity_unique_id=2, entity_runtime_id=2, item=Item(type=ItemType.DIRT, aux_value=1, nbt=b'', place_on=(), destroy=()), position=Vector3(x=256.5, y=62.25, z=257.5), motion=Vector3(x=0.0, y=0.0, z=0.0), metadata=()) self.assertEqual(expected_event, actual_event)
def filter_action(self, action: Action) -> Optional[Action]: if action.type is ActionType.MOVE_PLAYER: position = action.position if position.distance(Vector3(0.0, position.y, 0.0)) > _RANGE: # noinspection PyProtectedMember return action._replace(position=Vector3(0.0, position.y, 0.0), need_response=True) return action
def get_additional_blocks(self, block: Block, linked_blocks: Sequence[Block]) -> Tuple[PlacedBlock, ...]: assert len(linked_blocks) == 2 left_side_lower_block, left_side_upper_block = linked_blocks right_side_mask = 0 if left_side_lower_block.type == block.type and self._get_face(left_side_lower_block) == self._get_face(block): if not self._is_right_side(left_side_upper_block): right_side_mask = self._IS_RIGHT_SIDE_MASK data = self._IS_UPPER_MASK | right_side_mask return PlacedBlock(Vector3(0, 0, 0), block), PlacedBlock(Vector3(0, 1, 0), block.copy(data=data))
def test_neighbour_rail_2(self): linked_blocks = dict(LINKED_BLOCKS) linked_blocks[Vector3(-1, -1, 0)] = RAIL.copy(data=0) blocks = self._get_additional_blocks(RAIL, linked_blocks) self.assertEqual(2, len(blocks)) self.assertEqual(PlacedBlock(Vector3(0, 0, 0), RAIL.copy(data=1)), blocks.pop(0)) self.assertEqual(PlacedBlock(Vector3(-1, -1, 0), RAIL.copy(data=2)), blocks.pop(0))
def test_neighbour_powered_rail_5(self): linked_blocks = dict(LINKED_BLOCKS) linked_blocks[Vector3(0, -1, -1)] = POWERED_RAIL.copy(data=1) blocks = self._get_additional_blocks(POWERED_RAIL, linked_blocks) self.assertEqual(2, len(blocks)) self.assertEqual( PlacedBlock(Vector3(0, 0, 0), POWERED_RAIL.copy(data=0)), blocks.pop(0)) self.assertEqual( PlacedBlock(Vector3(0, -1, -1), POWERED_RAIL.copy(data=5)), blocks.pop(0))
def test_rail_9_and_neighbour_rail_5_3(self): linked_blocks = dict(LINKED_BLOCKS) linked_blocks[Vector3(0, -1, -1)] = RAIL.copy(data=1) linked_blocks[Vector3(1, -1, 0)] = RAIL.copy(data=0) blocks = self._get_additional_blocks(RAIL, linked_blocks) self.assertEqual(3, len(blocks)) self.assertEqual(PlacedBlock(Vector3(0, 0, 0), RAIL.copy(data=9)), blocks.pop(0)) self.assertEqual(PlacedBlock(Vector3(0, -1, -1), RAIL.copy(data=5)), blocks.pop(0)) self.assertEqual(PlacedBlock(Vector3(1, -1, 0), RAIL.copy(data=3)), blocks.pop(0))
def test_break_block(self): self.test_login() self.perform_action(ActionType.BREAK_BLOCK, entity_runtime_id=1, position=Vector3(x=256, y=62, z=257)) actual_event = self.next_event() expected_event = event_factory.create( EventType.BLOCK_UPDATED, (PlacedBlock(Vector3(x=256, y=62, z=257), Block(type=BlockType.AIR, aux_value=0)), )) self.assertEqual(expected_event, actual_event)
def test_break_block(self): chunk = decode_chunk(self.data) base = Vector3(0, 0, 0) height = chunk.get_height(base.x, base.z) for y in range(height): self.assertNotEqual(BlockType.AIR, chunk.get_block(base.copy(y=y)).type) for y in range(height, 127): self.assertEqual(BlockType.AIR, chunk.get_block(base.copy(y=y)).type) chunk.set_block(base.copy(y=height - 1), Block.create(BlockType.AIR, 0)) expected_height = height - 1 height = chunk.get_height(base.x, base.z) self.assertEqual(expected_height, height) self.assertNotEqual(BlockType.AIR, chunk.get_block(base.copy(y=height - 1)).type) for y in range(height, 127): self.assertEqual(BlockType.AIR, chunk.get_block(base.copy(y=y)).type) chunk.set_block(base.copy(y=height - 2), Block.create(BlockType.AIR, 0)) expected_height = height height = chunk.get_height(base.x, base.z) self.assertEqual(expected_height, height) self.assertNotEqual(BlockType.AIR, chunk.get_block(base.copy(y=height - 1)).type) for y in range(height, 127): self.assertEqual(BlockType.AIR, chunk.get_block(base.copy(y=y)).type)
def break_block(self, east: int, height: int, south: int, player_eid: Optional[EntityRuntimeID] = None): self.perform_action(ActionType.BREAK_BLOCK, self._player_eid(player_eid), Vector3(east, height, south).astype(int))
def __init__(self, entity_runtime_id: EntityRuntimeID, name: str) -> None: self._entity_runtime_id = entity_runtime_id self._name = name self._metadata = {} self._position = Vector3(0, 0, 0) self._pitch = 0.0 self._yaw = 0.0 self._head_yaw = 0.0
def update(self, perform_action: PerformAction) -> None: value = GPIO.input(13) if value != self._prev_13pin_state: self._prev_13pin_state = value x = random.randint(-_RANGE, _RANGE) z = random.randint(-_RANGE, _RANGE) perform_action(ActionType.SPAWN_MOB, EntityType.CHICKEN, Vector3(x, 64.0, z), 0.0, 0.0, 'GPIO MOB', None)
def _process_event_mob_spawned(self, event: Event) -> None: res_packet = game_packet_factory.create( GamePacketType.ADD_ENTITY, EXTRA_DATA, event.entity_unique_id, event.entity_runtime_id, event.entity_type, event.position, Vector3(0.0, 0.0, 0.0), event.pitch, event.yaw, tuple(), self._mob_spawned_event_to_metadata(event), tuple()) for addr, player in self._session_manager.find(lambda p: p.is_living): player.monitor_entity(event.entity_runtime_id) self.send_game_packet(res_packet, addr)
def set_data(x: int, z: int) -> None: y = 0 chunk.set_block(Vector3(x, y, z), Block.create(BlockType.BEDROCK, 0)) y += 1 while y < height - 6: chunk.set_block(Vector3(x, y, z), Block.create(BlockType.STONE, 0)) y += 1 while y < height - 1: chunk.set_block(Vector3(x, y, z), Block.create(BlockType.STONE, 0)) y += 1 chunk.set_block(Vector3(x, y, z), Block.create(BlockType.GRASS, 0)) y += 1 assert y == height chunk.set_height(x, z, height) chunk.set_biome_id(x, z, BiomeType.PLAINS)
def get_additional_blocks(self, block: Block, linked_blocks: Sequence[Block]) -> Tuple[PlacedBlock, ...]: network = _RailNetwork(zip(_SURROUNDING, linked_blocks)) data = self._get_block_data(network, block.type == BlockType.RAIL) blocks = [PlacedBlock(Vector3(0, 0, 0), block.copy(data=data))] rail_type = _RAIL_TYPE[data] for connector in rail_type.connector: updated = self._update_neighbour(network, connector) if updated: blocks.append(updated) return tuple(blocks)
def spawn_mob(self, entity_type: EntityType, east: float, height: float, south: float, pitch: float = 0.0, yaw: float = 0.0, name: Optional[str] = None): self.perform_action(ActionType.SPAWN_MOB, entity_type, Vector3(east, height, south), pitch, yaw, name, self.client.entity_runtime_id)
def _get_chunk(self, east: float, height: float, south: float, timeout: float = 0) -> Tuple[Optional[Chunk], Vector3[int]]: position = Vector3(east, height, south).astype(int) position_in_chunk = to_local_position(position) if self._sync_chunk_by_position(position, timeout): return self.client.latest_chunk.chunk, position_in_chunk else: return None, position_in_chunk
def __init__(self, spec: EntitySpec, entity_unique_id: EntityUniqueID, entity_runtime_id: EntityRuntimeID) -> None: self._spec = spec self._entity_unique_id = entity_unique_id self._entity_runtime_id = entity_runtime_id self._spawn_position = Vector3(*get_value(ConfigKey.PLAYER_SPAWN_POSITION)) self._position = None self._pitch = 0.0 self._yaw = 0.0 self._head_yaw = 0.0 self._on_ground = True self._move_actions = [] # type: List[Action]
def move_mob(self, mob_eid: EntityRuntimeID, east: float, height: float, south: float, pitch: float = 0.0, yaw: float = 0.0, head_yaw: float = 0.0, on_ground: bool = True): self.perform_action(ActionType.MOVE_MOB, mob_eid, Vector3(east, height, south), pitch, yaw, head_yaw, on_ground)
def test_request_entity(self): self.test_break_block() self.perform_action(ActionType.REQUEST_ENTITY, player_runtime_id=1) actual_event = self.next_event() expected_event = event_factory.create( EventType.ENTITY_LOADED, player_id=self.get_player_id(0), spawn_events=(event_factory.create(EventType.ITEM_SPAWNED, entity_unique_id=2, entity_runtime_id=2, item=Item(type=ItemType.DIRT, aux_value=1, nbt=b'', place_on=(), destroy=()), position=Vector3(x=256.5, y=62.25, z=257.5), motion=Vector3(x=0.0, y=0.0, z=0.0), metadata=()), )) self.assertEqual(expected_event, actual_event)
def _spawn_player(player: Player, addr: Address, session: SessionManager, send: Callable[[GamePacket, Address], None]) -> None: res_packet = game_packet_factory.create(GamePacketType.PLAY_STATUS, EXTRA_DATA, PlayStatus.PLAYER_SPAWN) send(res_packet, addr) if not player.invisible: text_packet = game_packet_factory.create( GamePacketType.TEXT, EXTRA_DATA, TextType.TRANSLATION, False, None, EscapeSequence.YELLOW.value + '%multiplayer.player.joined', (player.name, ), '') for other_player_addr, p in session: send(text_packet, other_player_addr) new_player_packet = game_packet_factory.create( GamePacketType.ADD_PLAYER, EXTRA_DATA, player.id, player.name, player.entity_unique_id, player.entity_runtime_id, player.bottom_position, Vector3(0.0, 0.0, 0.0), 0.0, player.yaw, 0.0, player.equipped_item, player.metadata, 0, 0, 0, 0, 0, 0, tuple()) for other_player_addr, p in session.excluding(player): p.monitor_entity(player.entity_runtime_id) send(new_player_packet, other_player_addr) for _, p in session.excluding(player): if not p.invisible: other_player_packet = game_packet_factory.create( GamePacketType.ADD_PLAYER, EXTRA_DATA, p.id, p.name, p.entity_unique_id, p.entity_runtime_id, p.bottom_position, Vector3(0.0, 0.0, 0.0), 0.0, p.yaw, 0.0, p.equipped_item, p.metadata, 0, 0, 0, 0, 0, 0, tuple()) player.monitor_entity(p.entity_runtime_id) send(other_player_packet, addr)
def move_player(self, east: float, height: float, south: float, pitch: float = 0.0, yaw: float = 0.0, head_yaw: float = 0.0, on_ground: bool = True, is_teleport: bool = False, player_eid: Optional[EntityRuntimeID] = None): self.perform_action( ActionType.MOVE_PLAYER, self._player_eid(player_eid), Vector3(east, height, south), pitch, yaw, head_yaw, MoveMode.TELEPORT if is_teleport else MoveMode.NORMAL, on_ground, 0, True)
def __init__(self, protocol: int, player_data: PlayerData, client_data: ClientData) -> None: self._protocol = protocol self._player_data = player_data self._client_data = client_data self._entity_unique_id = 0 self._entity_runtime_id = 0 self._position = Vector3(0.0, 0.0, 0.0) self._yaw = 0.0 self._equipped_item = Item(ItemType.AIR, None, None, None, None) self._metadata = None self._chunk_radius = 0 self._near_chunk_radius = _NEAR_CHUNK_RADIUS self._requested_chunk_position = set() # type: Set[ChunkPosition] self._near_chunk_position = set() # type: Set[ChunkPosition] self._is_living = False self._login_sequence = None self._monitored_entities = set() # type: Set[EntityRuntimeID]
def test_rail_8(self): linked_blocks = dict(LINKED_BLOCKS) linked_blocks[Vector3(0, 0, -1)] = RAIL.copy(data=0) linked_blocks[Vector3(-1, 0, 0)] = RAIL.copy(data=1) blocks = self._get_additional_blocks(RAIL, linked_blocks) self.assertEqual(1, len(blocks)) self.assertEqual(PlacedBlock(Vector3(0, 0, 0), RAIL.copy(data=8)), blocks.pop(0)) linked_blocks = dict(LINKED_BLOCKS) linked_blocks[Vector3(0, 0, -1)] = RAIL.copy(data=1) linked_blocks[Vector3(-1, 0, 0)] = RAIL.copy(data=0) blocks = self._get_additional_blocks(RAIL, linked_blocks) self.assertEqual(3, len(blocks)) self.assertEqual(PlacedBlock(Vector3(0, 0, 0), RAIL.copy(data=8)), blocks.pop(0)) self.assertEqual(PlacedBlock(Vector3(0, 0, -1), RAIL.copy(data=0)), blocks.pop(0)) self.assertEqual(PlacedBlock(Vector3(-1, 0, 0), RAIL.copy(data=1)), blocks.pop(0))
def _process_login_player(self, action: Action) -> None: entity_runtime_id = self._entity.load_player(action.player_id, action.is_guest) entity = self._entity.get_player(entity_runtime_id) height = self._space.get_height(entity.spawn_position) if not entity.is_living: entity.spawn(height) self._notify_event( event_factory.create( EventType.PLAYER_LOGGED_IN, entity.player_id, entity.entity_unique_id, entity_runtime_id, self._player_config.get_game_mode(self._game_mode, entity.player_id), entity.position, entity.pitch, entity.yaw, entity.spawn_position, Vector3(0, 0, 0), PlayerPermission.MEMBER, (create_attribute(AttributeType.HEALTH, entity.health), create_attribute(AttributeType.FOLLOW_RANGE, 16.0), create_attribute(AttributeType.KNOCKBACK_RESISTANCE, 0.0), create_attribute(AttributeType.MOVEMENT, 0.10000000149011612), create_attribute(AttributeType.ATTACK_DAMAGE, 1.0), create_attribute(AttributeType.ABSORPTION, 0.0), create_attribute(AttributeType.PLAYER_SATURATION, 10.0), create_attribute(AttributeType.PLAYER_EXHAUSTION, 0.8000399470329285), create_attribute(AttributeType.PLAYER_HUNGER, entity.hunger), create_attribute(AttributeType.PLAYER_LEVEL, 0.0), create_attribute(AttributeType.PLAYER_EXPERIENCE, 0.0)), EntityMetaDataFlagValue.create(always_show_nametag=True, immobile=True, swimmer=True, affected_by_gravity=True, fire_immune=True), self._clock.time)) self._notify_event( event_factory.create(EventType.INVENTORY_LOADED, entity.player_id, (entity.get_inventory(WindowType.INVENTORY), entity.get_inventory(WindowType.ARMOR), entity.get_inventory(WindowType.CREATIVE)))) self._notify_event( event_factory.create(EventType.SLOT_INITIALIZED, entity.player_id, entity.get_inventory_slot(entity.hotbar_slot), entity.hotbar_slot, entity.equipped_item))
def _process_event_entity_loaded(self, event: Event) -> None: addr = self._session_manager.get_address(event.player_id) player = self._session_manager[addr] for e in event.spawn_events: player.monitor_entity(e.entity_runtime_id) if e.type == EventType.ITEM_SPAWNED: res_packet = game_packet_factory.create( GamePacketType.ADD_ITEM_ENTITY, EXTRA_DATA, e.entity_unique_id, e.entity_runtime_id, e.item, e.position, e.motion, e.metadata) self.send_game_packet(res_packet, addr, immediately=False) if e.type == EventType.MOB_SPAWNED: res_packet = game_packet_factory.create( GamePacketType.ADD_ENTITY, EXTRA_DATA, e.entity_unique_id, e.entity_runtime_id, e.entity_type, e.position, Vector3(0.0, 0.0, 0.0), e.pitch, e.yaw, tuple(), self._mob_spawned_event_to_metadata(e), tuple()) self.send_game_packet(res_packet, addr, immediately=False) self.send_waiting_game_packet(addr)
def _test_command_request(self, client: Client): self.assertEqual('§e%multiplayer.player.joined (Taro)', client.next_message()) self.assertEqual(1, client.entity_runtime_id) expected_entities = ( EntityInfo( entity_runtime_id=1, name='Taro', position=Vector3(0.5, 64.625, 0.5), pitch=0.0, yaw=0.0, head_yaw=0.0, owner_runtime_id=None ), ) self.assertEqual(expected_entities, client.entities) client.execute_command('/ban taro') client.wait_response(60) self.assertEqual('ban taro', client.next_message())
def _process_break_block(self, action: Action) -> None: updated_blocks, items = self._space.break_block(action.position) if len(updated_blocks) > 0: self._notify_event( event_factory.create(EventType.BLOCK_UPDATED, tuple(updated_blocks))) if self._game_mode == GameMode.CREATIVE: return for item in items: entity_runtime_id = self._entity.create_item(item) entity = self._entity.get_item(entity_runtime_id) entity.spawn_position = action.position height = self._space.get_height(entity.spawn_position) entity.spawn(height) self._notify_event( event_factory.create(EventType.ITEM_SPAWNED, entity.entity_unique_id, entity_runtime_id, entity.item, entity.position, Vector3(0.0, 0.0, 0.0), tuple()))